ramips: properly setup the FEATURES variable
[openwrt.git] / target / linux / ramips / files-3.7 / arch / mips / ralink / rt288x / devices.c
1 /*
2  *  Ralink RT288x SoC platform device registration
3  *
4  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6  *
7  *  This program is free software; you can redistribute it and/or modify it
8  *  under the terms of the GNU General Public License version 2 as published
9  *  by the Free Software Foundation.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/platform_device.h>
14 #include <linux/mtd/mtd.h>
15 #include <linux/mtd/physmap.h>
16 #include <linux/etherdevice.h>
17 #include <linux/err.h>
18 #include <linux/clk.h>
19 #include <linux/rt2x00_platform.h>
20
21 #include <asm/addrspace.h>
22
23 #include <asm/mach-ralink/rt288x.h>
24 #include <asm/mach-ralink/rt288x_regs.h>
25 #include <asm/mach-ralink/ramips_eth_platform.h>
26
27 #include "devices.h"
28
29 static struct resource rt288x_flash0_resources[] = {
30         {
31                 .flags  = IORESOURCE_MEM,
32                 .start  = KSEG1ADDR(RT2880_FLASH0_BASE),
33                 .end    = KSEG1ADDR(RT2880_FLASH0_BASE) +
34                           RT2880_FLASH0_SIZE - 1,
35         },
36 };
37
38 struct physmap_flash_data rt288x_flash0_data;
39 static struct platform_device rt288x_flash0_device = {
40         .name           = "physmap-flash",
41         .resource       = rt288x_flash0_resources,
42         .num_resources  = ARRAY_SIZE(rt288x_flash0_resources),
43         .dev = {
44                 .platform_data = &rt288x_flash0_data,
45         },
46 };
47
48 static struct resource rt288x_flash1_resources[] = {
49         {
50                 .flags  = IORESOURCE_MEM,
51                 .start  = KSEG1ADDR(RT2880_FLASH1_BASE),
52                 .end    = KSEG1ADDR(RT2880_FLASH1_BASE) +
53                           RT2880_FLASH1_SIZE - 1,
54         },
55 };
56
57 struct physmap_flash_data rt288x_flash1_data;
58 static struct platform_device rt288x_flash1_device = {
59         .name           = "physmap-flash",
60         .resource       = rt288x_flash1_resources,
61         .num_resources  = ARRAY_SIZE(rt288x_flash1_resources),
62         .dev = {
63                 .platform_data = &rt288x_flash1_data,
64         },
65 };
66
67 static int rt288x_flash_instance __initdata;
68 void __init rt288x_register_flash(unsigned int id)
69 {
70         struct platform_device *pdev;
71         struct physmap_flash_data *pdata;
72         u32 t;
73         int reg;
74
75         switch (id) {
76         case 0:
77                 pdev = &rt288x_flash0_device;
78                 reg = MEMC_REG_FLASH_CFG0;
79                 break;
80         case 1:
81                 pdev = &rt288x_flash1_device;
82                 reg = MEMC_REG_FLASH_CFG1;
83                 break;
84         default:
85                 return;
86         }
87
88         t = rt288x_memc_rr(reg);
89         t = (t >> FLASH_CFG_WIDTH_SHIFT) & FLASH_CFG_WIDTH_MASK;
90
91         pdata = pdev->dev.platform_data;
92         switch (t) {
93         case FLASH_CFG_WIDTH_8BIT:
94                 pdata->width = 1;
95                 break;
96         case FLASH_CFG_WIDTH_16BIT:
97                 pdata->width = 2;
98                 break;
99         case FLASH_CFG_WIDTH_32BIT:
100                 pdata->width = 4;
101                 break;
102         default:
103                 printk(KERN_ERR "RT288x: flash bank%u witdh is invalid\n", id);
104                 return;
105         }
106
107         pdev->id = rt288x_flash_instance;
108
109         platform_device_register(pdev);
110         rt288x_flash_instance++;
111 }
112
113 static struct resource rt288x_wifi_resources[] = {
114         {
115                 .start  = RT2880_WMAC_BASE,
116                 .end    = RT2880_WMAC_BASE + 0x3FFFF,
117                 .flags  = IORESOURCE_MEM,
118         }, {
119                 .start  = RT288X_CPU_IRQ_WNIC,
120                 .end    = RT288X_CPU_IRQ_WNIC,
121                 .flags  = IORESOURCE_IRQ,
122         },
123 };
124
125 static struct rt2x00_platform_data rt288x_wifi_data;
126 static struct platform_device rt288x_wifi_device = {
127         .name                   = "rt2800_wmac",
128         .resource               = rt288x_wifi_resources,
129         .num_resources  = ARRAY_SIZE(rt288x_wifi_resources),
130         .dev = {
131                 .platform_data = &rt288x_wifi_data,
132         }
133 };
134
135 void __init rt288x_register_wifi(void)
136 {
137         rt288x_wifi_data.eeprom_file_name = "soc_wmac.eeprom";
138         platform_device_register(&rt288x_wifi_device);
139 }
140
141 static void rt288x_fe_reset(void)
142 {
143         rt288x_sysc_wr(RT2880_RESET_FE, SYSC_REG_RESET_CTRL);
144 }
145
146 static struct resource rt288x_eth_resources[] = {
147         {
148                 .start  = RT2880_FE_BASE,
149                 .end    = RT2880_FE_BASE + PAGE_SIZE - 1,
150                 .flags  = IORESOURCE_MEM,
151         }, {
152                 .start  = RT288X_CPU_IRQ_FE,
153                 .end    = RT288X_CPU_IRQ_FE,
154                 .flags  = IORESOURCE_IRQ,
155         },
156 };
157
158 struct ramips_eth_platform_data rt288x_eth_data;
159 static struct platform_device rt288x_eth_device = {
160         .name           = "ramips_eth",
161         .resource       = rt288x_eth_resources,
162         .num_resources  = ARRAY_SIZE(rt288x_eth_resources),
163         .dev = {
164                 .platform_data = &rt288x_eth_data,
165         }
166 };
167
168 void __init rt288x_register_ethernet(void)
169 {
170         struct clk *clk;
171
172         clk = clk_get(NULL, "sys");
173         if (IS_ERR(clk))
174                 panic("unable to get SYS clock, err=%ld", PTR_ERR(clk));
175
176         rt288x_eth_data.sys_freq = clk_get_rate(clk);
177         rt288x_eth_data.reset_fe = rt288x_fe_reset;
178         rt288x_eth_data.min_pkt_len = 64;
179
180         if (!is_valid_ether_addr(rt288x_eth_data.mac))
181                 random_ether_addr(rt288x_eth_data.mac);
182
183         platform_device_register(&rt288x_eth_device);
184 }
185
186 static struct resource rt288x_wdt_resources[] = {
187         {
188                 .start  = RT2880_TIMER_BASE,
189                 .end    = RT2880_TIMER_BASE + RT2880_TIMER_SIZE - 1,
190                 .flags  = IORESOURCE_MEM,
191         },
192 };
193
194 static struct platform_device rt288x_wdt_device = {
195         .name           = "ramips-wdt",
196         .id             = -1,
197         .resource       = rt288x_wdt_resources,
198         .num_resources  = ARRAY_SIZE(rt288x_wdt_resources),
199 };
200
201 void __init rt288x_register_wdt(void)
202 {
203         u32 t;
204
205         /* enable WDT reset output on pin SRAM_CS_N */
206         t = rt288x_sysc_rr(SYSC_REG_CLKCFG);
207         t |= CLKCFG_SRAM_CS_N_WDT;
208         rt288x_sysc_wr(t, SYSC_REG_CLKCFG);
209
210         platform_device_register(&rt288x_wdt_device);
211 }