several cleanups for ifxmips. removes all code that has not been cleaned up properly
[lede.git] / target / linux / ifxmips / files / arch / mips / ifxmips / board.c
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the Free Software
14  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
15  *
16  *   Copyright (C) 2007 John Crispin <blogic@openwrt.org>
17  */
18
19 #include <linux/autoconf.h>
20 #include <linux/init.h>
21 #include <linux/module.h>
22 #include <linux/types.h>
23 #include <linux/string.h>
24 #include <linux/mtd/physmap.h>
25 #include <linux/kernel.h>
26 #include <linux/reboot.h>
27 #include <linux/platform_device.h>
28 #include <linux/leds.h>
29 #include <linux/etherdevice.h>
30 #include <linux/reboot.h>
31 #include <linux/time.h>
32 #include <linux/io.h>
33 #include <linux/gpio.h>
34 #include <asm/bootinfo.h>
35 #include <asm/irq.h>
36 #include <asm/ifxmips/ifxmips.h>
37 #include <asm/ifxmips/ifxmips_irq.h>
38
39 #define MAX_BOARD_NAME_LEN              32
40 #define MAX_IFXMIPS_DEVS                9
41
42 #define SYSTEM_DANUBE                   "Danube"
43 #define SYSTEM_DANUBE_CHIPID1   0x00129083
44 #define SYSTEM_DANUBE_CHIPID2   0x0012B083
45
46 #define SYSTEM_TWINPASS                 "Twinpass"
47 #define SYSTEM_TWINPASS_CHIPID  0x0012D083
48
49 enum {
50         EASY50712,
51         EASY4010,
52         ARV4519,
53 };
54
55 extern int ifxmips_pci_external_clock;
56
57 static unsigned int chiprev;
58 static int cmdline_mac;
59 char board_name[MAX_BOARD_NAME_LEN + 1] = { 0 };
60
61 struct ifxmips_board {
62         int type;
63         char name[32];
64         unsigned int system_type;
65         struct platform_device **devs;
66         struct resource reset_resource;
67         struct resource gpiodev_resource;
68         struct gpio_led *ifxmips_leds;
69         struct gpio_led *gpio_leds;
70         int pci_external_clock;
71         int num_devs;
72 };
73
74 DEFINE_SPINLOCK(ebu_lock);
75 EXPORT_SYMBOL_GPL(ebu_lock);
76
77 static unsigned char ifxmips_ethaddr[6];
78 static int ifxmips_brn;
79
80 static struct gpio_led_platform_data ifxmips_led_data;
81
82 static struct platform_device ifxmips_led = {
83         .id = 0,
84         .name = "ifxmips_led",
85         .dev = {
86                 .platform_data = (void *) &ifxmips_led_data,
87         }
88 };
89
90 static struct platform_device ifxmips_gpio = {
91         .id = 0,
92         .name = "ifxmips_gpio",
93         .num_resources = 1,
94 };
95
96 static struct platform_device ifxmips_mii = {
97         .id = 0,
98         .name = "ifxmips_mii0",
99         .dev = {
100                 .platform_data = ifxmips_ethaddr,
101         }
102 };
103
104 static struct platform_device ifxmips_wdt = {
105         .id = 0,
106         .name = "ifxmips_wdt",
107 };
108
109 static struct resource ifxmips_mtd_resource = {
110         .start  = IFXMIPS_FLASH_START,
111         .end    = IFXMIPS_FLASH_START + IFXMIPS_FLASH_MAX - 1,
112         .flags  = IORESOURCE_MEM,
113 };
114
115 static struct platform_device ifxmips_mtd = {
116         .id = 0,
117         .name = "ifxmips_mtd",
118         .num_resources  = 1,
119         .resource   = &ifxmips_mtd_resource,
120 };
121
122 static struct platform_device ifxmips_gpio_dev = {
123         .name     = "GPIODEV",
124         .id     = -1,
125         .num_resources    =     1,
126 };
127
128 #ifdef CONFIG_LEDS_GPIO
129 static struct gpio_led arv4519_gpio_leds[] = {
130         { .name = "ifx:green:power", .gpio = 3, .active_low = 1, },
131         { .name = "ifx:red:power", .gpio = 7, .active_low = 1, },
132         { .name = "ifx:green:adsl", .gpio = 4, .active_low = 1, },
133         { .name = "ifx:green:internet", .gpio = 5, .active_low = 1, },
134         { .name = "ifx:red:internet", .gpio = 8, .active_low = 1, },
135         { .name = "ifx:green:wlan", .gpio = 6, .active_low = 1, },
136         { .name = "ifx:green:usbpwr", .gpio = 14, .active_low = 1, },
137         { .name = "ifx:green:usb", .gpio = 19, .active_low = 1, },
138 };
139
140 static struct gpio_led_platform_data ifxmips_gpio_led_data;
141
142 static struct platform_device ifxmips_gpio_leds = {
143         .name = "leds-gpio",
144         .id = -1,
145         .dev = {
146                 .platform_data = (void *) &ifxmips_gpio_led_data,
147         }
148 };
149 #endif
150
151 static struct resource dwc_usb_res[] = {
152         {
153                 .name = "dwc_usb_membase",
154                 .flags = IORESOURCE_MEM,
155                 .start = 0x1E101000,
156                 .end = 0x1E101FFF
157         },
158         {
159                 .name = "dwc_usb_irq",
160                 .flags = IORESOURCE_IRQ,
161                 .start = IFXMIPS_USB_INT,
162         }
163 };
164
165 static struct platform_device dwc_usb =
166 {
167         .id = 0,
168         .name = "dwc_usb",
169         .resource = dwc_usb_res,
170         .num_resources = ARRAY_SIZE(dwc_usb_res),
171 };
172
173 struct platform_device *easy50712_devs[] = {
174         &ifxmips_led, &ifxmips_gpio, &ifxmips_mii,
175         &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev, &dwc_usb
176 };
177
178 struct platform_device *easy4010_devs[] = {
179         &ifxmips_led, &ifxmips_gpio, &ifxmips_mii,
180         &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev, &dwc_usb
181 };
182
183 struct platform_device *arv5419_devs[] = {
184         &ifxmips_gpio, &ifxmips_mii, &ifxmips_mtd,
185         &ifxmips_gpio_dev, &ifxmips_wdt, &dwc_usb,
186 #ifdef CONFIG_LEDS_GPIO
187         &ifxmips_gpio_leds,
188 #endif
189 };
190
191 static struct gpio_led easy50712_leds[] = {
192         { .name = "ifx:green:test0", .gpio = 0,},
193         { .name = "ifx:green:test1", .gpio = 1,},
194         { .name = "ifx:green:test2", .gpio = 2,},
195         { .name = "ifx:green:test3", .gpio = 3,},
196 };
197
198 static struct gpio_led easy4010_leds[] = {
199         { .name = "ifx:green:test0", .gpio = 0,},
200         { .name = "ifx:green:test1", .gpio = 1,},
201         { .name = "ifx:green:test2", .gpio = 2,},
202         { .name = "ifx:green:test3", .gpio = 3,},
203 };
204
205 static struct ifxmips_board boards[] = {
206         {
207                 /* infineon eval kit */
208                 .type = EASY50712,
209                 .name = "EASY50712",
210                 .system_type = SYSTEM_DANUBE_CHIPID1,
211                 .devs = easy50712_devs,
212                 .reset_resource = {.name = "reset", .start = 1, .end = 15,},
213                 .gpiodev_resource = { .name = "gpio",
214                         .start = (1 << 0) | (1 << 1),
215                         .end = (1 << 0) | (1 << 1)},
216                 .ifxmips_leds = easy50712_leds,
217         }, {
218                 /* infineon eval kit */
219                 .type = EASY4010,
220                 .name = "EASY4010",
221                 .system_type = SYSTEM_TWINPASS_CHIPID,
222                 .devs = easy4010_devs,
223                 .reset_resource = {.name = "reset", .start = 1, .end = 15},
224                 .gpiodev_resource = { .name = "gpio",
225                         .start = (1 << 0) | (1 << 1),
226                         .end = (1 << 0) | (1 << 1)},
227                 .ifxmips_leds = easy4010_leds,
228         }, {
229                 /* arcaydian annex-a board used by thompson, airties, ... */
230                 .type = ARV4519,
231                 .name = "ARV4519",
232                 .system_type = SYSTEM_DANUBE_CHIPID2,
233                 .devs = arv5419_devs,
234                 .reset_resource = {.name = "reset", .start = 1, .end = 14},
235                 .pci_external_clock = 1,
236                 .gpio_leds = arv4519_gpio_leds,
237         },
238 };
239
240 const char *get_system_type(void)
241 {
242         chiprev = (ifxmips_r32(IFXMIPS_MPS_CHIPID) & 0x0FFFFFFF);
243
244         switch (chiprev) {
245         case SYSTEM_DANUBE_CHIPID1:
246         case SYSTEM_DANUBE_CHIPID2:
247                 return SYSTEM_DANUBE;
248
249         case SYSTEM_TWINPASS_CHIPID:
250                 return SYSTEM_TWINPASS;
251         }
252
253         return BOARD_SYSTEM_TYPE;
254 }
255
256 static int __init ifxmips_set_board_type(char *str)
257 {
258         str = strchr(str, '=');
259         if (!str)
260                 goto out;
261         str++;
262         if (strlen(str) > MAX_BOARD_NAME_LEN)
263                 goto out;
264         strncpy(board_name, str, MAX_BOARD_NAME_LEN);
265         printk(KERN_INFO "bootloader told us, that this is a %s board\n",
266                 board_name);
267 out:
268         return 1;
269 }
270 __setup("ifxmips_board", ifxmips_set_board_type);
271
272 static int __init ifxmips_set_ethaddr(char *str)
273 {
274 #define IS_HEX(x) \
275         (((x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') \
276                 || (x >= 'A' && x <= 'F')) ? (1) : (0))
277         int i;
278         str = strchr(str, '=');
279         if (!str)
280                 goto out;
281         str++;
282         if (strlen(str) != 17)
283                 goto out;
284         for (i = 0; i < 6; i++) {
285                 if (!IS_HEX(str[3 * i]) || !IS_HEX(str[(3 * i) + 1]))
286                         goto out;
287                 if ((i != 5) && (str[(3 * i) + 2] != ':'))
288                         goto out;
289                 ifxmips_ethaddr[i] = simple_strtoul(&str[3 * i], NULL, 16);
290         }
291         if (is_valid_ether_addr(ifxmips_ethaddr))
292                 cmdline_mac = 1;
293 out:
294         return 1;
295 }
296 __setup("ethaddr", ifxmips_set_ethaddr);
297
298 int ifxmips_find_brn_block(void)
299 {
300         unsigned char temp[8];
301         memcpy_fromio(temp,
302                 (void *)KSEG1ADDR(IFXMIPS_FLASH_START + 0x800000 - 0x10000), 8);
303         if (memcmp(temp, "BRN-BOOT", 8) == 0) {
304                 if (!cmdline_mac)
305                         memcpy_fromio(ifxmips_ethaddr,
306                                 (void *)KSEG1ADDR(IFXMIPS_FLASH_START +
307                                         0x800000 - 0x10000 + 0x16), 6);
308                 if (is_valid_ether_addr(ifxmips_ethaddr))
309                         cmdline_mac = 1;
310                 return 1;
311         } else {
312                 return 0;
313         }
314 }
315
316 int ifxmips_has_brn_block(void)
317 {
318         return ifxmips_brn;
319 }
320 EXPORT_SYMBOL(ifxmips_has_brn_block);
321
322 struct ifxmips_board *ifxmips_find_board(void)
323 {
324         int i;
325         if (!*board_name)
326                 return 0;
327         for (i = 0; i < ARRAY_SIZE(boards); i++)
328                 if ((boards[i].system_type == chiprev) &&
329                     (!strcmp(boards[i].name, board_name)))
330                         return &boards[i];
331         return 0;
332 }
333
334 int __init ifxmips_init_devices(void)
335 {
336         struct ifxmips_board *board = ifxmips_find_board();
337
338         chiprev = (ifxmips_r32(IFXMIPS_MPS_CHIPID) & 0x0FFFFFFF);
339         ifxmips_brn = ifxmips_find_brn_block();
340
341         if (!cmdline_mac)
342                 random_ether_addr(ifxmips_ethaddr);
343
344         if (!board) {
345                 switch (chiprev) {
346                 case SYSTEM_DANUBE_CHIPID1:
347                 case SYSTEM_DANUBE_CHIPID2:
348                 default:
349                         board = &boards[0];
350                         break;
351                 case SYSTEM_TWINPASS_CHIPID:
352                         board = &boards[1];
353                         break;
354                 }
355         }
356
357         switch (board->type) {
358         case EASY50712:
359                 board->num_devs = ARRAY_SIZE(easy50712_devs);
360                 ifxmips_led_data.num_leds = ARRAY_SIZE(easy50712_leds);
361                 break;
362         case EASY4010:
363                 board->num_devs = ARRAY_SIZE(easy4010_devs);
364                 ifxmips_led_data.num_leds = ARRAY_SIZE(easy4010_leds);
365                 break;
366         case ARV4519:
367                 /* set some sane defaults for the gpios */
368                 gpio_set_value(3, 0);
369                 gpio_set_value(4, 0);
370                 gpio_set_value(5, 0);
371                 gpio_set_value(6, 0);
372                 gpio_set_value(7, 1);
373                 gpio_set_value(8, 1);
374                 gpio_set_value(19, 0);
375                 board->num_devs = ARRAY_SIZE(arv5419_devs);
376 #ifdef CONFIG_LEDS_GPIO
377                 ifxmips_gpio_led_data.num_leds = ARRAY_SIZE(arv4519_gpio_leds);
378 #endif
379                 break;
380         }
381 #ifdef CONFIG_LEDS_GPIO
382         ifxmips_gpio_led_data.leds = board->gpio_leds;
383 #endif
384         ifxmips_led_data.leds = board->ifxmips_leds;
385
386         printk(KERN_INFO "%s: adding %d devs\n",
387                 __func__, board->num_devs);
388
389         ifxmips_gpio.resource = &board->reset_resource;
390         ifxmips_gpio_dev.resource = &board->gpiodev_resource;
391         if (board->pci_external_clock)
392                 ifxmips_pci_external_clock = 1;
393         printk(KERN_INFO "using board definition %s\n", board->name);
394         return platform_add_devices(board->devs, board->num_devs);
395 }
396
397 arch_initcall(ifxmips_init_devices);