Root/target/linux/lantiq/files/arch/mips/lantiq/svip/devices.c

1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/types.h>
4#include <linux/string.h>
5#include <linux/mtd/physmap.h>
6#include <linux/kernel.h>
7#include <linux/reboot.h>
8#include <linux/platform_device.h>
9#include <linux/leds.h>
10#include <linux/etherdevice.h>
11#include <linux/reboot.h>
12#include <linux/time.h>
13#include <linux/io.h>
14#include <linux/gpio.h>
15#include <linux/leds.h>
16#include <linux/spi/spi.h>
17#include <linux/mtd/nand.h>
18
19#include <asm/bootinfo.h>
20#include <asm/irq.h>
21
22#include <lantiq.h>
23
24#include <base_reg.h>
25#include <sys1_reg.h>
26#include <sys2_reg.h>
27#include <ebu_reg.h>
28
29#include "devices.h"
30
31#include <lantiq_soc.h>
32#include <svip_mux.h>
33#include <svip_pms.h>
34
35/* ASC */
36void __init svip_register_asc(int port)
37{
38    switch (port) {
39    case 0:
40        ltq_register_asc(0);
41        svip_sys1_clk_enable(SYS1_CLKENR_ASC0);
42        break;
43    case 1:
44        ltq_register_asc(1);
45        svip_sys1_clk_enable(SYS1_CLKENR_ASC1);
46        break;
47    default:
48        break;
49    };
50}
51
52/* Ethernet */
53static unsigned char svip_ethaddr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
54
55static struct platform_device ltq_mii = {
56    .name = "ifxmips_mii0",
57    .dev = {
58        .platform_data = svip_ethaddr,
59    },
60};
61
62static int __init svip_set_ethaddr(char *str)
63{
64    sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
65           &svip_ethaddr[0], &svip_ethaddr[1], &svip_ethaddr[2],
66           &svip_ethaddr[3], &svip_ethaddr[4], &svip_ethaddr[5]);
67    return 0;
68}
69__setup("ethaddr=", svip_set_ethaddr);
70
71void __init svip_register_eth(void)
72{
73    if (!is_valid_ether_addr(svip_ethaddr))
74        random_ether_addr(svip_ethaddr);
75
76    platform_device_register(&ltq_mii);
77    svip_sys1_clk_enable(SYS1_CLKENR_ETHSW);
78}
79
80/* Virtual Ethernet */
81static struct platform_device ltq_ve = {
82    .name = "ifxmips_svip_ve",
83};
84
85void __init svip_register_virtual_eth(void)
86{
87    platform_device_register(&ltq_ve);
88}
89
90/* SPI */
91static void __init ltq_register_ssc(int bus_num, unsigned long base, int irq_rx,
92                     int irq_tx, int irq_err, int irq_frm)
93{
94    struct resource res[] = {
95        {
96            .name = "regs",
97            .start = base,
98            .end = base + 0x20 - 1,
99            .flags = IORESOURCE_MEM,
100        }, {
101            .name = "rx",
102            .start = irq_rx,
103            .flags = IORESOURCE_IRQ,
104        }, {
105            .name = "tx",
106            .start = irq_tx,
107            .flags = IORESOURCE_IRQ,
108        }, {
109            .name = "err",
110            .start = irq_err,
111            .flags = IORESOURCE_IRQ,
112        }, {
113            .name = "frm",
114            .start = irq_frm,
115            .flags = IORESOURCE_IRQ,
116        },
117    };
118
119    platform_device_register_simple("ifx_ssc", bus_num, res,
120                    ARRAY_SIZE(res));
121}
122
123static struct spi_board_info bdinfo[] __initdata = {
124    {
125        .modalias = "xt16",
126        .mode = SPI_MODE_3,
127        .irq = INT_NUM_IM5_IRL0 + 28,
128        .max_speed_hz = 1000000,
129        .bus_num = 0,
130        .chip_select = 1,
131    },
132    {
133        .modalias = "xt16",
134        .mode = SPI_MODE_3,
135        .irq = INT_NUM_IM5_IRL0 + 19,
136        .max_speed_hz = 1000000,
137        .bus_num = 0,
138        .chip_select = 2,
139    },
140    {
141        .modalias = "loop",
142        .mode = SPI_MODE_0 | SPI_LOOP,
143        .irq = -1,
144        .max_speed_hz = 10000000,
145        .bus_num = 0,
146        .chip_select = 3,
147    },
148};
149
150void __init svip_register_spi(void)
151{
152
153    ltq_register_ssc(0, LTQ_SSC0_BASE, INT_NUM_IM1_IRL0 + 6,
154              INT_NUM_IM1_IRL0 + 7, INT_NUM_IM1_IRL0 + 8,
155              INT_NUM_IM1_IRL0 + 9);
156
157    ltq_register_ssc(1, LTQ_SSC1_BASE, INT_NUM_IM1_IRL0 + 10,
158              INT_NUM_IM1_IRL0 + 11, INT_NUM_IM1_IRL0 + 12,
159              INT_NUM_IM1_IRL0 + 13);
160
161    spi_register_board_info(bdinfo, ARRAY_SIZE(bdinfo));
162
163    svip_sys1_clk_enable(SYS1_CLKENR_SSC0 | SYS1_CLKENR_SSC1);
164}
165
166void __init svip_register_spi_flash(struct spi_board_info *bdinfo)
167{
168    spi_register_board_info(bdinfo, 1);
169}
170
171/* GPIO */
172static struct platform_device ltq_gpio = {
173    .name = "ifxmips_gpio",
174};
175
176static struct platform_device ltq_gpiodev = {
177    .name = "GPIODEV",
178};
179
180void __init svip_register_gpio(void)
181{
182    platform_device_register(&ltq_gpio);
183    platform_device_register(&ltq_gpiodev);
184}
185
186/* MUX */
187static struct ltq_mux_settings ltq_mux_settings;
188
189static struct platform_device ltq_mux = {
190    .name = "ltq_mux",
191    .dev = {
192        .platform_data = &ltq_mux_settings,
193    }
194};
195
196void __init svip_register_mux(const struct ltq_mux_pin mux_p0[LTQ_MUX_P0_PINS],
197                  const struct ltq_mux_pin mux_p1[LTQ_MUX_P1_PINS],
198                  const struct ltq_mux_pin mux_p2[LTQ_MUX_P2_PINS],
199                  const struct ltq_mux_pin mux_p3[LTQ_MUX_P3_PINS],
200                  const struct ltq_mux_pin mux_p4[LTQ_MUX_P4_PINS])
201{
202    ltq_mux_settings.mux_p0 = mux_p0;
203    ltq_mux_settings.mux_p1 = mux_p1;
204    ltq_mux_settings.mux_p2 = mux_p2;
205    ltq_mux_settings.mux_p3 = mux_p3;
206    ltq_mux_settings.mux_p4 = mux_p4;
207
208    if (mux_p0)
209        svip_sys1_clk_enable(SYS1_CLKENR_PORT0);
210
211    if (mux_p1)
212        svip_sys1_clk_enable(SYS1_CLKENR_PORT1);
213
214    if (mux_p2)
215        svip_sys1_clk_enable(SYS1_CLKENR_PORT2);
216
217    if (mux_p3)
218        svip_sys1_clk_enable(SYS1_CLKENR_PORT3);
219
220    if (mux_p4)
221        svip_sys2_clk_enable(SYS2_CLKENR_PORT4);
222
223    platform_device_register(&ltq_mux);
224}
225
226/* NAND */
227#define NAND_ADDR_REGION_BASE (LTQ_EBU_SEG1_BASE)
228#define NAND_CLE_BIT (1 << 3)
229#define NAND_ALE_BIT (1 << 2)
230
231static struct svip_reg_ebu *const ebu = (struct svip_reg_ebu *)LTQ_EBU_BASE;
232
233static int svip_nand_probe(struct platform_device *pdev)
234{
235    ebu_w32(LTQ_EBU_ADDR_SEL_0_BASE_VAL(CPHYSADDR(NAND_ADDR_REGION_BASE)
236                        >> 12)
237        | LTQ_EBU_ADDR_SEL_0_MASK_VAL(15)
238        | LTQ_EBU_ADDR_SEL_0_MRME_VAL(0)
239        | LTQ_EBU_ADDR_SEL_0_REGEN_VAL(1),
240        addr_sel_0);
241
242    ebu_w32(LTQ_EBU_CON_0_WRDIS_VAL(0)
243        | LTQ_EBU_CON_0_ADSWP_VAL(1)
244        | LTQ_EBU_CON_0_AGEN_VAL(0x00)
245        | LTQ_EBU_CON_0_SETUP_VAL(1)
246        | LTQ_EBU_CON_0_WAIT_VAL(0x00)
247        | LTQ_EBU_CON_0_WINV_VAL(0)
248        | LTQ_EBU_CON_0_PW_VAL(0x00)
249        | LTQ_EBU_CON_0_ALEC_VAL(0)
250        | LTQ_EBU_CON_0_BCGEN_VAL(0x01)
251        | LTQ_EBU_CON_0_WAITWRC_VAL(1)
252        | LTQ_EBU_CON_0_WAITRDC_VAL(1)
253        | LTQ_EBU_CON_0_HOLDC_VAL(1)
254        | LTQ_EBU_CON_0_RECOVC_VAL(0)
255        | LTQ_EBU_CON_0_CMULT_VAL(0x01),
256        con_0);
257
258    /*
259     * ECC disabled
260     * CLE, ALE and CS are pulse, all other signal are latches based
261     * CLE and ALE are active high, PRE, WP, SE and CS/CE are active low
262     * OUT_CS_S is disabled
263     * NAND mode is disabled
264     */
265    ebu_w32(LTQ_EBU_NAND_CON_ECC_ON_VAL(0)
266        | LTQ_EBU_NAND_CON_LAT_EN_VAL(0x38)
267        | LTQ_EBU_NAND_CON_OUT_CS_S_VAL(0)
268        | LTQ_EBU_NAND_CON_IN_CS_S_VAL(0)
269        | LTQ_EBU_NAND_CON_PRE_P_VAL(1)
270        | LTQ_EBU_NAND_CON_WP_P_VAL(1)
271        | LTQ_EBU_NAND_CON_SE_P_VAL(1)
272        | LTQ_EBU_NAND_CON_CS_P_VAL(1)
273        | LTQ_EBU_NAND_CON_CLE_P_VAL(0)
274        | LTQ_EBU_NAND_CON_ALE_P_VAL(0)
275        | LTQ_EBU_NAND_CON_CSMUX_E_VAL(0)
276        | LTQ_EBU_NAND_CON_NANDMODE_VAL(0),
277        nand_con);
278
279    return 0;
280}
281
282static void svip_nand_hwcontrol(struct mtd_info *mtd, int cmd,
283                unsigned int ctrl)
284{
285    struct nand_chip *this = mtd->priv;
286
287    if (ctrl & NAND_CTRL_CHANGE) {
288        unsigned long adr;
289        /* Coming here means to change either the enable state or
290         * the address for controlling ALE or CLE */
291
292        /* NAND_NCE: Select the chip by setting nCE to low.
293         * This is done in CON register */
294        if (ctrl & NAND_NCE)
295            ebu_w32_mask(0, LTQ_EBU_NAND_CON_NANDMODE_VAL(1),
296                     nand_con);
297        else
298            ebu_w32_mask(LTQ_EBU_NAND_CON_NANDMODE_VAL(1),
299                     0, nand_con);
300
301        /* The addressing of CLE or ALE is done via different addresses.
302           We are now changing the address depending on the given action
303           SVIPs NAND_CLE_BIT = (1 << 3), NAND_CLE = 0x02
304           NAND_ALE_BIT = (1 << 2) = NAND_ALE (0x04) */
305        adr = (unsigned long)this->IO_ADDR_W;
306        adr &= ~(NAND_CLE_BIT | NAND_ALE_BIT);
307        adr |= (ctrl & NAND_CLE) << 2 | (ctrl & NAND_ALE);
308        this->IO_ADDR_W = (void __iomem *)adr;
309    }
310
311    if (cmd != NAND_CMD_NONE)
312        writeb(cmd, this->IO_ADDR_W);
313}
314
315static int svip_nand_ready(struct mtd_info *mtd)
316{
317    return (ebu_r32(nand_wait) & 0x01) == 0x01;
318}
319
320static inline void svip_nand_wait(void)
321{
322    static const int nops = 150;
323    int i;
324
325    for (i = 0; i < nops; i++)
326        asm("nop");
327}
328
329static void svip_nand_write_buf(struct mtd_info *mtd,
330                const u_char *buf, int len)
331{
332    int i;
333    struct nand_chip *this = mtd->priv;
334
335    for (i = 0; i < len; i++) {
336        writeb(buf[i], this->IO_ADDR_W);
337        svip_nand_wait();
338    }
339}
340
341static void svip_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
342{
343    int i;
344    struct nand_chip *this = mtd->priv;
345
346    for (i = 0; i < len; i++) {
347        buf[i] = readb(this->IO_ADDR_R);
348        svip_nand_wait();
349    }
350}
351
352static const char *part_probes[] = { "cmdlinepart", NULL };
353
354static struct platform_nand_data svip_flash_nand_data = {
355    .chip = {
356        .nr_chips = 1,
357        .part_probe_types = part_probes,
358    },
359    .ctrl = {
360        .probe = svip_nand_probe,
361        .cmd_ctrl = svip_nand_hwcontrol,
362        .dev_ready = svip_nand_ready,
363        .write_buf = svip_nand_write_buf,
364        .read_buf = svip_nand_read_buf,
365    }
366};
367
368static struct resource svip_nand_resources[] = {
369    MEM_RES("nand", LTQ_FLASH_START, LTQ_FLASH_MAX),
370};
371
372static struct platform_device svip_flash_nand = {
373    .name = "gen_nand",
374    .id = -1,
375    .num_resources = ARRAY_SIZE(svip_nand_resources),
376    .resource = svip_nand_resources,
377    .dev = {
378        .platform_data = &svip_flash_nand_data,
379    },
380};
381
382void __init svip_register_nand(void)
383{
384    platform_device_register(&svip_flash_nand);
385}
386

Archive Download this file



interactive