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

Archive Download this file



interactive