Root/target/linux/ramips/files/arch/mips/ralink/rt3883/devices.c

1/*
2 * Ralink RT3662/RT3883 SoC platform device registration
3 *
4 * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/mtd/mtd.h>
14#include <linux/mtd/physmap.h>
15#include <linux/mtd/partitions.h>
16#include <linux/dma-mapping.h>
17#include <linux/spi/spi.h>
18#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/clk.h>
21#include <linux/rt2x00_platform.h>
22#include <linux/usb/ehci_pdriver.h>
23#include <linux/usb/ohci_pdriver.h>
24
25#include <asm/addrspace.h>
26
27#include <asm/mach-ralink/rt3883.h>
28#include <asm/mach-ralink/rt3883_regs.h>
29#include <asm/mach-ralink/ramips_nand_platform.h>
30#include "devices.h"
31
32#include <ramips_eth_platform.h>
33
34static struct resource rt3883_flash0_resources[] = {
35    {
36        .flags = IORESOURCE_MEM,
37        .start = RT3883_BOOT_BASE,
38        .end = RT3883_BOOT_BASE + RT3883_BOOT_SIZE - 1,
39    },
40};
41
42struct physmap_flash_data rt3883_flash0_data;
43static struct platform_device rt3883_flash0_device = {
44    .name = "physmap-flash",
45    .resource = rt3883_flash0_resources,
46    .num_resources = ARRAY_SIZE(rt3883_flash0_resources),
47    .dev = {
48        .platform_data = &rt3883_flash0_data,
49    },
50};
51
52static struct resource rt3883_flash1_resources[] = {
53    {
54        .flags = IORESOURCE_MEM,
55        .start = RT3883_SRAM_BASE,
56        .end = RT3883_SRAM_BASE + RT3883_SRAM_SIZE - 1,
57    },
58};
59
60struct physmap_flash_data rt3883_flash1_data;
61static struct platform_device rt3883_flash1_device = {
62    .name = "physmap-flash",
63    .resource = rt3883_flash1_resources,
64    .num_resources = ARRAY_SIZE(rt3883_flash1_resources),
65    .dev = {
66        .platform_data = &rt3883_flash1_data,
67    },
68};
69
70static int rt3883_flash_instance __initdata;
71void __init rt3883_register_pflash(unsigned int id)
72{
73    struct platform_device *pdev;
74    struct physmap_flash_data *pdata;
75    void __iomem *fscc_base;
76    u32 t;
77    int reg;
78
79    switch (id) {
80    case 0:
81        pdev = &rt3883_flash0_device;
82        reg = RT3883_FSCC_REG_FLASH_CFG0;
83        break;
84    case 1:
85        pdev = &rt3883_flash1_device;
86        reg = RT3883_FSCC_REG_FLASH_CFG1;
87        break;
88    default:
89        return;
90    }
91
92    pdata = pdev->dev.platform_data;
93
94    fscc_base = ioremap(RT3883_FSCC_BASE, RT3883_FSCC_SIZE);
95    if (!fscc_base)
96        panic("RT3883: ioremap failed for FSCC");
97
98    t = __raw_readl(fscc_base + reg);
99    iounmap(fscc_base);
100
101    t = (t >> RT3883_FLASH_CFG_WIDTH_SHIFT) & RT3883_FLASH_CFG_WIDTH_MASK;
102    switch (t) {
103    case RT3883_FLASH_CFG_WIDTH_8BIT:
104        pdata->width = 1;
105        break;
106    case RT3883_FLASH_CFG_WIDTH_16BIT:
107        pdata->width = 2;
108        break;
109    case RT3883_FLASH_CFG_WIDTH_32BIT:
110        if (id == 1) {
111            pdata->width = 4;
112            break;
113        }
114        /* fallthrough */
115    default:
116        pr_warn("RT3883: flash bank%d: invalid width detected\n", id);
117        return;
118    }
119
120    pdev->id = rt3883_flash_instance;
121
122    platform_device_register(pdev);
123    rt3883_flash_instance++;
124}
125
126static atomic_t rt3883_usb_pwr_ref = ATOMIC_INIT(0);
127
128static int rt3883_usb_power_on(struct platform_device *pdev)
129{
130
131    if (atomic_inc_return(&rt3883_usb_pwr_ref) == 1) {
132        u32 t;
133
134        t = rt3883_sysc_rr(RT3883_SYSC_REG_USB_PS);
135
136        /* enable clock for port0's and port1's phys */
137        t = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
138        t |= RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN;
139        rt3883_sysc_wr(t, RT3883_SYSC_REG_CLKCFG1);
140        mdelay(500);
141
142        /* pull USBHOST and USBDEV out from reset */
143        t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
144        t &= ~(RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV);
145        rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
146        mdelay(500);
147
148        /* enable host mode */
149        t = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
150        t |= RT3883_SYSCFG1_USB0_HOST_MODE;
151        rt3883_sysc_wr(t, RT3883_SYSC_REG_SYSCFG1);
152
153        t = rt3883_sysc_rr(RT3883_SYSC_REG_USB_PS);
154    }
155
156    return 0;
157}
158
159static void rt3883_usb_power_off(struct platform_device *pdev)
160{
161    if (atomic_dec_return(&rt3883_usb_pwr_ref) == 0) {
162        u32 t;
163
164        /* put USBHOST and USBDEV into reset */
165        t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
166        t |= RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV;
167        rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
168        udelay(10000);
169
170        /* disable clock for port0's and port1's phys*/
171        t = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
172        t &= ~(RT3883_CLKCFG1_UPHY0_CLK_EN |
173               RT3883_CLKCFG1_UPHY1_CLK_EN);
174        rt3883_sysc_wr(t, RT3883_SYSC_REG_CLKCFG1);
175        udelay(10000);
176    }
177}
178
179static struct usb_ehci_pdata rt3883_ehci_data = {
180    .port_power_off = 1,
181    .power_on = rt3883_usb_power_on,
182    .power_off = rt3883_usb_power_off,
183};
184
185static struct resource rt3883_ehci_resources[] = {
186    {
187        .start = RT3883_EHCI_BASE,
188        .end = RT3883_EHCI_BASE + PAGE_SIZE - 1,
189        .flags = IORESOURCE_MEM,
190    }, {
191        .start = RT3883_INTC_IRQ_UHST,
192        .end = RT3883_INTC_IRQ_UHST,
193        .flags = IORESOURCE_IRQ,
194    },
195};
196
197static u64 rt3883_ehci_dmamask = DMA_BIT_MASK(32);
198static struct platform_device rt3883_ehci_device = {
199    .name = "ehci-platform",
200    .id = -1,
201    .resource = rt3883_ehci_resources,
202    .num_resources = ARRAY_SIZE(rt3883_ehci_resources),
203    .dev = {
204        .dma_mask = &rt3883_ehci_dmamask,
205        .coherent_dma_mask = DMA_BIT_MASK(32),
206        .platform_data = &rt3883_ehci_data,
207    },
208};
209
210static struct resource rt3883_ohci_resources[] = {
211    {
212        .start = RT3883_OHCI_BASE,
213        .end = RT3883_OHCI_BASE + PAGE_SIZE - 1,
214        .flags = IORESOURCE_MEM,
215    }, {
216        .start = RT3883_INTC_IRQ_UHST,
217        .end = RT3883_INTC_IRQ_UHST,
218        .flags = IORESOURCE_IRQ,
219    },
220};
221
222static struct usb_ohci_pdata rt3883_ohci_data = {
223    .power_on = rt3883_usb_power_on,
224    .power_off = rt3883_usb_power_off,
225};
226
227static u64 rt3883_ohci_dmamask = DMA_BIT_MASK(32);
228static struct platform_device rt3883_ohci_device = {
229    .name = "ohci-platform",
230    .id = -1,
231    .resource = rt3883_ohci_resources,
232    .num_resources = ARRAY_SIZE(rt3883_ohci_resources),
233    .dev = {
234        .dma_mask = &rt3883_ohci_dmamask,
235        .coherent_dma_mask = DMA_BIT_MASK(32),
236        .platform_data = &rt3883_ohci_data,
237    },
238};
239
240void __init rt3883_register_usbhost(void)
241{
242    platform_device_register(&rt3883_ehci_device);
243    platform_device_register(&rt3883_ohci_device);
244}
245
246static void rt3883_fe_reset(void)
247{
248    u32 t;
249
250    t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
251    t |= RT3883_RSTCTRL_FE;
252    rt3883_sysc_wr(t , RT3883_SYSC_REG_RSTCTRL);
253
254    t &= ~RT3883_RSTCTRL_FE;
255    rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
256}
257
258static struct resource rt3883_eth_resources[] = {
259    {
260        .start = RT3883_FE_BASE,
261        .end = RT3883_FE_BASE + PAGE_SIZE - 1,
262        .flags = IORESOURCE_MEM,
263    }, {
264        .start = RT3883_CPU_IRQ_FE,
265        .end = RT3883_CPU_IRQ_FE,
266        .flags = IORESOURCE_IRQ,
267    },
268};
269
270struct ramips_eth_platform_data rt3883_eth_data = {
271    .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
272    .reset_fe = rt3883_fe_reset,
273    .min_pkt_len = 64,
274};
275
276static struct platform_device rt3883_eth_device = {
277    .name = "ramips_eth",
278    .resource = rt3883_eth_resources,
279    .num_resources = ARRAY_SIZE(rt3883_eth_resources),
280    .dev = {
281        .platform_data = &rt3883_eth_data,
282    }
283};
284
285void __init rt3883_register_ethernet(void)
286{
287    struct clk *clk;
288
289    clk = clk_get(NULL, "sys");
290    if (IS_ERR(clk))
291        panic("unable to get SYS clock, err=%ld", PTR_ERR(clk));
292
293    rt3883_eth_data.sys_freq = clk_get_rate(clk);
294
295    platform_device_register(&rt3883_eth_device);
296}
297
298static struct resource rt3883_wlan_resources[] = {
299    {
300        .start = RT3883_WLAN_BASE,
301        .end = RT3883_WLAN_BASE + 0x3FFFF,
302        .flags = IORESOURCE_MEM,
303    }, {
304        .start = RT3883_CPU_IRQ_WLAN,
305        .end = RT3883_CPU_IRQ_WLAN,
306        .flags = IORESOURCE_IRQ,
307    },
308};
309
310struct rt2x00_platform_data rt3883_wlan_data;
311static struct platform_device rt3883_wlan_device = {
312    .name = "rt2800_wmac",
313    .resource = rt3883_wlan_resources,
314    .num_resources = ARRAY_SIZE(rt3883_wlan_resources),
315    .dev = {
316        .platform_data = &rt3883_wlan_data,
317    }
318};
319
320void __init rt3883_register_wlan(void)
321{
322    rt3883_wlan_data.eeprom_file_name = "soc_wmac.eeprom",
323    platform_device_register(&rt3883_wlan_device);
324}
325
326static struct resource rt3883_wdt_resources[] = {
327    {
328        .start = RT3883_TIMER_BASE,
329        .end = RT3883_TIMER_BASE + RT3883_TIMER_SIZE - 1,
330        .flags = IORESOURCE_MEM,
331    },
332};
333
334static struct platform_device rt3883_wdt_device = {
335    .name = "ramips-wdt",
336    .id = -1,
337    .resource = rt3883_wdt_resources,
338    .num_resources = ARRAY_SIZE(rt3883_wdt_resources),
339};
340
341void __init rt3883_register_wdt(bool enable_reset)
342{
343    if (enable_reset) {
344        u32 t;
345
346        /* enable WDT reset output on GPIO 2 */
347        t = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
348        t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT;
349        rt3883_sysc_wr(t, RT3883_SYSC_REG_SYSCFG1);
350    }
351
352    platform_device_register(&rt3883_wdt_device);
353}
354
355static struct resource rt3883_nand_resources[] = {
356    {
357        .flags = IORESOURCE_MEM,
358        .start = RT3883_NANDC_BASE,
359        .end = RT3883_NANDC_BASE + RT3883_NANDC_SIZE - 1,
360    },
361};
362
363struct ramips_nand_platform_data rt3883_nand_data;
364static struct platform_device rt3883_nand_device = {
365    .name = RAMIPS_NAND_DRIVER_NAME,
366    .id = -1,
367    .resource = rt3883_nand_resources,
368    .num_resources = ARRAY_SIZE(rt3883_nand_resources),
369    .dev = {
370        .platform_data = &rt3883_nand_data,
371    },
372};
373
374void __init rt3883_register_nand(void)
375{
376    platform_device_register(&rt3883_nand_device);
377}
378
379static struct resource rt3883_spi_resources[] = {
380    {
381        .flags = IORESOURCE_MEM,
382        .start = RT3883_SPI_BASE,
383        .end = RT3883_SPI_BASE + RT3883_SPI_SIZE - 1,
384    },
385};
386
387static struct platform_device rt3883_spi_device = {
388    .name = "ramips-spi",
389    .id = 0,
390    .resource = rt3883_spi_resources,
391    .num_resources = ARRAY_SIZE(rt3883_spi_resources),
392};
393
394void __init rt3883_register_spi(struct spi_board_info *info, int n)
395{
396    spi_register_board_info(info, n);
397    platform_device_register(&rt3883_spi_device);
398}
399
400

Archive Download this file



interactive