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
23#include <asm/addrspace.h>
24
25#include <asm/mach-ralink/rt3883.h>
26#include <asm/mach-ralink/rt3883_regs.h>
27#include <asm/mach-ralink/rt3883_ehci_platform.h>
28#include <asm/mach-ralink/rt3883_ohci_platform.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_use_count = ATOMIC_INIT(0);
127
128static void rt3883_usb_host_start(void)
129{
130    u32 t;
131
132    if (atomic_inc_return(&rt3883_usb_use_count) != 1)
133        return;
134
135    t = rt3883_sysc_rr(RT3883_SYSC_REG_USB_PS);
136
137#if 0
138    /* put the HOST controller into reset */
139    t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
140    t |= RT3883_RSTCTRL_UHST;
141    rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
142#endif
143
144    /* enable clock for port0's and port1's phys */
145    t = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
146    t = t | RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN;
147    rt3883_sysc_wr(t, RT3883_SYSC_REG_CLKCFG1);
148    mdelay(500);
149
150    /* pull USBHOST and USBDEV out from reset */
151    t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
152    t &= ~(RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV);
153    rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
154    mdelay(500);
155
156    /* enable host mode */
157    t = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
158    t |= RT3883_SYSCFG1_USB0_HOST_MODE;
159    rt3883_sysc_wr(t, RT3883_SYSC_REG_SYSCFG1);
160
161    t = rt3883_sysc_rr(RT3883_SYSC_REG_USB_PS);
162}
163
164static void rt3883_usb_host_stop(void)
165{
166    u32 t;
167
168    if (atomic_dec_return(&rt3883_usb_use_count) != 0)
169        return;
170
171    /* put USBHOST and USBDEV into reset */
172    t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
173    t |= RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV;
174    rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
175    udelay(10000);
176
177    /* disable clock for port0's and port1's phys*/
178    t = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
179    t &= ~(RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN);
180    rt3883_sysc_wr(t, RT3883_SYSC_REG_CLKCFG1);
181    udelay(10000);
182}
183
184static struct rt3883_ehci_platform_data rt3883_ehci_data = {
185    .start_hw = rt3883_usb_host_start,
186    .stop_hw = rt3883_usb_host_stop,
187};
188
189static struct resource rt3883_ehci_resources[] = {
190    {
191        .start = RT3883_EHCI_BASE,
192        .end = RT3883_EHCI_BASE + PAGE_SIZE - 1,
193        .flags = IORESOURCE_MEM,
194    }, {
195        .start = RT3883_INTC_IRQ_UHST,
196        .end = RT3883_INTC_IRQ_UHST,
197        .flags = IORESOURCE_IRQ,
198    },
199};
200
201static u64 rt3883_ehci_dmamask = DMA_BIT_MASK(32);
202static struct platform_device rt3883_ehci_device = {
203    .name = "rt3883-ehci",
204    .id = -1,
205    .resource = rt3883_ehci_resources,
206    .num_resources = ARRAY_SIZE(rt3883_ehci_resources),
207    .dev = {
208        .dma_mask = &rt3883_ehci_dmamask,
209        .coherent_dma_mask = DMA_BIT_MASK(32),
210        .platform_data = &rt3883_ehci_data,
211    },
212};
213
214static struct resource rt3883_ohci_resources[] = {
215    {
216        .start = RT3883_OHCI_BASE,
217        .end = RT3883_OHCI_BASE + PAGE_SIZE - 1,
218        .flags = IORESOURCE_MEM,
219    }, {
220        .start = RT3883_INTC_IRQ_UHST,
221        .end = RT3883_INTC_IRQ_UHST,
222        .flags = IORESOURCE_IRQ,
223    },
224};
225
226static struct rt3883_ohci_platform_data rt3883_ohci_data = {
227    .start_hw = rt3883_usb_host_start,
228    .stop_hw = rt3883_usb_host_stop,
229};
230
231static u64 rt3883_ohci_dmamask = DMA_BIT_MASK(32);
232static struct platform_device rt3883_ohci_device = {
233    .name = "rt3883-ohci",
234    .id = -1,
235    .resource = rt3883_ohci_resources,
236    .num_resources = ARRAY_SIZE(rt3883_ohci_resources),
237    .dev = {
238        .dma_mask = &rt3883_ohci_dmamask,
239        .coherent_dma_mask = DMA_BIT_MASK(32),
240        .platform_data = &rt3883_ohci_data,
241    },
242};
243
244void __init rt3883_register_usbhost(void)
245{
246    platform_device_register(&rt3883_ehci_device);
247    platform_device_register(&rt3883_ohci_device);
248}
249
250static void rt3883_fe_reset(void)
251{
252    u32 t;
253
254    t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
255    t |= RT3883_RSTCTRL_FE;
256    rt3883_sysc_wr(t , RT3883_SYSC_REG_RSTCTRL);
257
258    t &= ~RT3883_RSTCTRL_FE;
259    rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
260}
261
262static struct resource rt3883_eth_resources[] = {
263    {
264        .start = RT3883_FE_BASE,
265        .end = RT3883_FE_BASE + PAGE_SIZE - 1,
266        .flags = IORESOURCE_MEM,
267    }, {
268        .start = RT3883_CPU_IRQ_FE,
269        .end = RT3883_CPU_IRQ_FE,
270        .flags = IORESOURCE_IRQ,
271    },
272};
273
274struct ramips_eth_platform_data rt3883_eth_data = {
275    .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
276    .reset_fe = rt3883_fe_reset,
277    .min_pkt_len = 64,
278};
279
280static struct platform_device rt3883_eth_device = {
281    .name = "ramips_eth",
282    .resource = rt3883_eth_resources,
283    .num_resources = ARRAY_SIZE(rt3883_eth_resources),
284    .dev = {
285        .platform_data = &rt3883_eth_data,
286    }
287};
288
289void __init rt3883_register_ethernet(void)
290{
291    struct clk *clk;
292
293    clk = clk_get(NULL, "sys");
294    if (IS_ERR(clk))
295        panic("unable to get SYS clock, err=%ld", PTR_ERR(clk));
296
297    rt3883_eth_data.sys_freq = clk_get_rate(clk);
298
299    platform_device_register(&rt3883_eth_device);
300}
301
302static struct resource rt3883_wlan_resources[] = {
303    {
304        .start = RT3883_WLAN_BASE,
305        .end = RT3883_WLAN_BASE + 0x3FFFF,
306        .flags = IORESOURCE_MEM,
307    }, {
308        .start = RT3883_CPU_IRQ_WLAN,
309        .end = RT3883_CPU_IRQ_WLAN,
310        .flags = IORESOURCE_IRQ,
311    },
312};
313
314struct rt2x00_platform_data rt3883_wlan_data;
315static struct platform_device rt3883_wlan_device = {
316    .name = "rt2800_wmac",
317    .resource = rt3883_wlan_resources,
318    .num_resources = ARRAY_SIZE(rt3883_wlan_resources),
319    .dev = {
320        .platform_data = &rt3883_wlan_data,
321    }
322};
323
324void __init rt3883_register_wlan(void)
325{
326    rt3883_wlan_data.eeprom_file_name = "RT3883.eeprom",
327    platform_device_register(&rt3883_wlan_device);
328}
329
330static struct resource rt3883_wdt_resources[] = {
331    {
332        .start = RT3883_TIMER_BASE,
333        .end = RT3883_TIMER_BASE + RT3883_TIMER_SIZE - 1,
334        .flags = IORESOURCE_MEM,
335    },
336};
337
338static struct platform_device rt3883_wdt_device = {
339    .name = "ramips-wdt",
340    .id = -1,
341    .resource = rt3883_wdt_resources,
342    .num_resources = ARRAY_SIZE(rt3883_wdt_resources),
343};
344
345void __init rt3883_register_wdt(bool enable_reset)
346{
347    if (enable_reset) {
348        u32 t;
349
350        /* enable WDT reset output on GPIO 2 */
351        t = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
352        t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT;
353        rt3883_sysc_wr(t, RT3883_SYSC_REG_SYSCFG1);
354    }
355
356    platform_device_register(&rt3883_wdt_device);
357}
358
359static struct resource rt3883_nand_resources[] = {
360    {
361        .flags = IORESOURCE_MEM,
362        .start = RT3883_NANDC_BASE,
363        .end = RT3883_NANDC_BASE + RT3883_NANDC_SIZE - 1,
364    },
365};
366
367struct ramips_nand_platform_data rt3883_nand_data;
368static struct platform_device rt3883_nand_device = {
369    .name = RAMIPS_NAND_DRIVER_NAME,
370    .id = -1,
371    .resource = rt3883_nand_resources,
372    .num_resources = ARRAY_SIZE(rt3883_nand_resources),
373    .dev = {
374        .platform_data = &rt3883_nand_data,
375    },
376};
377
378void __init rt3883_register_nand(void)
379{
380    platform_device_register(&rt3883_nand_device);
381}
382
383static struct resource rt3883_spi_resources[] = {
384    {
385        .flags = IORESOURCE_MEM,
386        .start = RT3883_SPI_BASE,
387        .end = RT3883_SPI_BASE + RT3883_SPI_SIZE - 1,
388    },
389};
390
391static struct platform_device rt3883_spi_device = {
392    .name = "ramips-spi",
393    .id = 0,
394    .resource = rt3883_spi_resources,
395    .num_resources = ARRAY_SIZE(rt3883_spi_resources),
396};
397
398void __init rt3883_register_spi(struct spi_board_info *info, int n)
399{
400    spi_register_board_info(info, n);
401    platform_device_register(&rt3883_spi_device);
402}
403
404

Archive Download this file



interactive