2 * arch/arm/mach-orion5x/dt2-setup.c
4 * Freecom DataTank Gateway Setup
6 * Copyright (C) 2009 Zintis Petersons <Zintis.Petersons@abcsolutions.lv>
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/pci.h>
17 #include <linux/irq.h>
18 #include <linux/mtd/physmap.h>
19 #include <linux/mv643xx_eth.h>
20 #include <linux/ethtool.h>
21 #include <linux/if_ether.h>
23 #include <linux/ata_platform.h>
24 #include <linux/i2c.h>
25 #include <linux/reboot.h>
26 #include <linux/interrupt.h>
27 #include <asm/mach-types.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/pci.h>
32 #include <mach/orion5x.h>
36 /*****************************************************************************
38 ****************************************************************************/
39 #include <asm/setup.h>
40 #include "dt2-common.h"
43 u32 mvTclk
= 166666667;
44 u32 mvSysclk
= 200000000;
48 struct DT2_EEPROM_STRUCT dt2_eeprom
;
50 /*****************************************************************************
52 ****************************************************************************/
57 #define DT2_PCI_SLOT0_OFFS 7
58 #define DT2_PCI_SLOT0_IRQ_A_PIN 3
59 #define DT2_PCI_SLOT0_IRQ_B_PIN 2
61 #define DT2_PIN_GPIO_SYNC 25
62 #define DT2_PIN_GPIO_POWER 24
63 #define DT2_PIN_GPIO_UNPLUG1 23
64 #define DT2_PIN_GPIO_UNPLUG2 22
65 #define DT2_PIN_GPIO_RESET 4
67 #define DT2_NOR_BOOT_BASE 0xf4000000
68 #define DT2_NOR_BOOT_SIZE SZ_512K
70 #define DT2_LEDS_BASE 0xfa000000
71 #define DT2_LEDS_SIZE SZ_1K
73 /*****************************************************************************
74 * 512K NOR Flash on Device bus Boot CS
75 ****************************************************************************/
77 static struct mtd_partition dt2_partitions
[] = {
85 static struct physmap_flash_data dt2_nor_flash_data
= {
86 .width
= 1, /* 8 bit bus width */
87 .parts
= dt2_partitions
,
88 .nr_parts
= ARRAY_SIZE(dt2_partitions
)
91 static struct resource dt2_nor_flash_resource
= {
92 .flags
= IORESOURCE_MEM
,
93 .start
= DT2_NOR_BOOT_BASE
,
94 .end
= DT2_NOR_BOOT_BASE
+ DT2_NOR_BOOT_SIZE
- 1,
97 static struct platform_device dt2_nor_flash
= {
98 .name
= "physmap-flash",
101 .platform_data
= &dt2_nor_flash_data
,
103 .resource
= &dt2_nor_flash_resource
,
107 /*****************************************************************************
109 ****************************************************************************/
111 void __init
dt2_pci_preinit(void)
116 * Configure PCI GPIO IRQ pins
118 pin
= DT2_PCI_SLOT0_IRQ_A_PIN
;
119 if (gpio_request(pin
, "PCI IntA") == 0) {
120 if (gpio_direction_input(pin
) == 0) {
121 irq
= gpio_to_irq(pin
);
122 set_irq_type(irq
, IRQ_TYPE_LEVEL_LOW
);
123 printk (KERN_INFO
"PCI IntA IRQ: %d\n", irq
);
125 printk(KERN_ERR
"dt2_pci_preinit failed to "
126 "set_irq_type pin %d\n", pin
);
130 printk(KERN_ERR
"dt2_pci_preinit failed to request gpio %d\n", pin
);
133 pin
= DT2_PCI_SLOT0_IRQ_B_PIN
;
134 if (gpio_request(pin
, "PCI IntB") == 0) {
135 if (gpio_direction_input(pin
) == 0) {
136 irq
= gpio_to_irq(pin
);
137 set_irq_type(irq
, IRQ_TYPE_LEVEL_LOW
);
138 printk (KERN_INFO
"PCI IntB IRQ: %d\n", irq
);
140 printk(KERN_ERR
"dt2_pci_preinit failed to "
141 "set_irq_type pin %d\n", pin
);
145 printk(KERN_ERR
"dt2_pci_preinit failed to gpio_request %d\n", pin
);
149 static int __init
dt2_pci_map_irq(struct pci_dev
*dev
, u8 slot
, u8 pin
)
154 * Check for devices with hard-wired IRQs.
156 irq
= orion5x_pci_map_irq(dev
, slot
, pin
);
158 printk(KERN_INFO
"orion5x_pci_map_irq: %d\n", irq
);
163 * PCI IRQs are connected via GPIOs
165 switch (slot
- DT2_PCI_SLOT0_OFFS
) {
168 irq
= gpio_to_irq(DT2_PCI_SLOT0_IRQ_A_PIN
);
169 printk(KERN_INFO
"dt2_pci_map_irq DT2_PCI_SLOT0_IRQ_A_PIN: %d\n", irq
);
172 irq
= gpio_to_irq(DT2_PCI_SLOT0_IRQ_B_PIN
);
173 printk(KERN_INFO
"dt2_pci_map_irq DT2_PCI_SLOT0_IRQ_B_PIN: %d\n", irq
);
177 printk(KERN_INFO
"dt2_pci_map_irq IRQ: %d\n", irq
);
183 static struct hw_pci dt2_pci __initdata
= {
185 .preinit
= dt2_pci_preinit
,
186 .swizzle
= pci_std_swizzle
,
187 .setup
= orion5x_pci_sys_setup
,
188 .scan
= orion5x_pci_sys_scan_bus
,
189 .map_irq
= dt2_pci_map_irq
,
192 static int __init
dt2_pci_init(void)
194 if (machine_is_dt2())
195 pci_common_init(&dt2_pci
);
200 subsys_initcall(dt2_pci_init
);
202 /*****************************************************************************
204 ****************************************************************************/
206 static struct mv643xx_eth_platform_data dt2_eth_data
= {
207 .phy_addr
= MV643XX_ETH_PHY_NONE
,
209 .duplex
= DUPLEX_FULL
,
212 static struct dsa_chip_data dt2_switch_chip_data
= {
213 .port_names
[0] = "wan",
214 .port_names
[1] = "lan1",
215 .port_names
[2] = "lan2",
216 .port_names
[3] = "cpu",
217 .port_names
[4] = "lan3",
218 .port_names
[5] = "lan4",
221 static struct dsa_platform_data dt2_switch_plat_data
= {
223 .chip
= &dt2_switch_chip_data
,
226 /*****************************************************************************
227 * RTC ISL1208 on I2C bus
228 ****************************************************************************/
229 static struct i2c_board_info __initdata dt2_i2c_rtc
= {
230 I2C_BOARD_INFO("isl1208", 0x6F),
233 /*****************************************************************************
235 ****************************************************************************/
236 static struct mv_sata_platform_data dt2_sata_data
= {
240 /*****************************************************************************
242 ****************************************************************************/
243 static struct orion5x_mpp_mode dt2_mpp_modes
[] __initdata
= {
244 { 0, MPP_GPIO
}, // RTC interrupt
245 { 1, MPP_GPIO
}, // 88e6131 interrupt
246 { 2, MPP_GPIO
}, // PCI_intB
247 { 3, MPP_GPIO
}, // PCI_intA
248 { 4, MPP_GPIO
}, // reset button switch
253 { 9, MPP_GIGE
}, /* GE_RXERR */
254 { 10, MPP_GPIO
}, // usb
255 { 11, MPP_GPIO
}, // usb
256 { 12, MPP_GIGE
}, // GE_TXD[4]
257 { 13, MPP_GIGE
}, // GE_TXD[5]
258 { 14, MPP_GIGE
}, // GE_TXD[6]
259 { 15, MPP_GIGE
}, // GE_TXD[7]
260 { 16, MPP_GIGE
}, // GE_RXD[4]
261 { 17, MPP_GIGE
}, // GE_RXD[5]
262 { 18, MPP_GIGE
}, // GE_RXD[6]
263 { 19, MPP_GIGE
}, // GE_RXD[7]
267 /*****************************************************************************
269 ****************************************************************************/
270 static struct platform_device dt2_leds
= {
275 /****************************************************************************
277 ****************************************************************************/
278 static irqreturn_t
dt2_reset_handler(int irq
, void *dev_id
)
280 /* This is the paper-clip reset which does an emergency reboot. */
281 printk(KERN_INFO
"Restarting system.\n");
282 machine_restart(NULL
);
284 /* This should never be reached. */
288 static irqreturn_t
dt2_power_handler(int irq
, void *dev_id
)
290 printk(KERN_INFO
"Shutting down system.\n");
295 static void __init
dt2_init(void)
297 DECLARE_MAC_BUF(mac_buf
);
299 * Setup basic Orion functions. Need to be called early.
303 orion5x_mpp_conf(dt2_mpp_modes
);
306 * Configure peripherals.
309 orion5x_uart0_init();
310 orion5x_ehci0_init();
311 orion5x_ehci1_init();
313 orion5x_sata_init(&dt2_sata_data
);
316 printk(KERN_INFO
"U-Boot parameters:\n");
317 printk(KERN_INFO
"Sys Clk = %d, Tclk = %d, BoardID = 0x%02x\n", mvSysclk
, mvTclk
, gBoardId
);
319 printk(KERN_INFO
"Serial: %s\n", dt2_eeprom
.fc
.dt2_serial_number
);
320 printk(KERN_INFO
"Revision: %016x\n", dt2_eeprom
.fc
.dt2_revision
);
321 printk(KERN_INFO
"DT2: Using MAC address %s for port 0\n",
322 print_mac(mac_buf
, dt2_eeprom
.gw
.mac_addr
[0]));
323 printk(KERN_INFO
"DT2: Using MAC address %s for port 1\n",
324 print_mac(mac_buf
, dt2_eeprom
.gw
.mac_addr
[1]));
326 orion5x_eth_init(&dt2_eth_data
);
327 memcpy(dt2_eth_data
.mac_addr
, dt2_eeprom
.gw
.mac_addr
[0], 6);
328 orion5x_eth_switch_init(&dt2_switch_plat_data
, NO_IRQ
);
330 i2c_register_board_info(0, &dt2_i2c_rtc
, 1);
332 orion5x_setup_dev_boot_win(DT2_NOR_BOOT_BASE
, DT2_NOR_BOOT_SIZE
);
333 platform_device_register(&dt2_nor_flash
);
335 orion5x_setup_dev0_win(DT2_LEDS_BASE
, DT2_LEDS_SIZE
);
336 platform_device_register(&dt2_leds
);
338 if (request_irq(gpio_to_irq(DT2_PIN_GPIO_RESET
), &dt2_reset_handler
,
339 IRQF_DISABLED
| IRQF_TRIGGER_LOW
,
340 "DT2: Reset button", NULL
) < 0) {
342 printk("DT2: Reset Button IRQ %d not available\n",
343 gpio_to_irq(DT2_PIN_GPIO_RESET
));
346 if (request_irq(gpio_to_irq(DT2_PIN_GPIO_POWER
), &dt2_power_handler
,
347 IRQF_DISABLED
| IRQF_TRIGGER_LOW
,
348 "DT2: Power button", NULL
) < 0) {
350 printk(KERN_DEBUG
"DT2: Power Button IRQ %d not available\n",
351 gpio_to_irq(DT2_PIN_GPIO_POWER
));
355 static int __init
parse_tag_dt2_uboot(const struct tag
*t
)
357 struct tag_mv_uboot
*mv_uboot
;
359 // Get pointer to our block
360 mv_uboot
= (struct tag_mv_uboot
*)&t
->u
;
361 mvTclk
= mv_uboot
->tclk
;
362 mvSysclk
= mv_uboot
->sysclk
;
363 mvUbootVer
= mv_uboot
->uboot_version
;
364 mvIsUsbHost
= mv_uboot
->isUsbHost
;
367 if(mvTclk
== 166000000) mvTclk
= 166666667;
368 else if(mvTclk
== 133000000) mvTclk
= 133333333;
369 else if(mvSysclk
== 166000000) mvSysclk
= 166666667;
371 gBoardId
= (mvUbootVer
& 0xff);
374 memcpy(&dt2_eeprom
, mv_uboot
->dt2_eeprom
, sizeof(struct DT2_EEPROM_STRUCT
));
378 __tagtable(ATAG_MV_UBOOT
, parse_tag_dt2_uboot
);
381 * This is OpenWrt specific fixup. It includes code from original "tag_fixup_mem32" to
382 * fixup bogus memory tags and also fixes kernel cmdline by adding " init=/etc/preinit"
383 * at the end. It is important to flash OpenWrt image from original Freecom firmware.
385 * Vanilla kernel should use "tag_fixup_mem32" function.
387 void __init
openwrt_fixup(struct machine_desc
*mdesc
, struct tag
*t
,
388 char **from
, struct meminfo
*meminfo
)
391 static char openwrt_init_tag
[] __initdata
= " init=/etc/preinit";
393 for (; t
->hdr
.size
; t
= tag_next(t
)){
394 /* Locate the Freecom cmdline */
395 if (t
->hdr
.tag
== ATAG_CMDLINE
) {
396 p
= t
->u
.cmdline
.cmdline
;
397 printk("%s(%d): Found cmdline '%s' at 0x%0lx\n",
398 __FUNCTION__
, __LINE__
, p
, (unsigned long)p
);
401 * Many orion-based systems have buggy bootloader implementations.
402 * This is a common fixup for bogus memory tags.
404 if (t
->hdr
.tag
== ATAG_MEM
&&
405 (!t
->u
.mem
.size
|| t
->u
.mem
.size
& ~PAGE_MASK
||
406 t
->u
.mem
.start
& ~PAGE_MASK
)) {
408 "Clearing invalid memory bank %dKB@0x%08x\n",
409 t
->u
.mem
.size
/ 1024, t
->u
.mem
.start
);
414 printk("%s(%d): End of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
416 /* Overwrite the end of the table with a new cmdline tag. */
417 t
->hdr
.tag
= ATAG_CMDLINE
;
419 (sizeof (struct tag_header
) +
420 strlen(p
) + strlen(openwrt_init_tag
) + 1 + 4) >> 2;
422 strlcpy(t
->u
.cmdline
.cmdline
, p
, COMMAND_LINE_SIZE
);
423 strlcpy(t
->u
.cmdline
.cmdline
+ strlen(p
), openwrt_init_tag
,
424 COMMAND_LINE_SIZE
- strlen(p
));
426 printk("%s(%d): New cmdline '%s' at 0x%0lx\n",
427 __FUNCTION__
, __LINE__
,
428 t
->u
.cmdline
.cmdline
, (unsigned long)t
->u
.cmdline
.cmdline
);
432 printk("%s(%d): New end of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
434 t
->hdr
.tag
= ATAG_NONE
;
438 /* Warning: Freecom uses their own custom bootloader with mach-type (=1500) */
439 MACHINE_START(DT2
, "Freecom DataTank Gateway")
440 /* Maintainer: Zintis Petersons <Zintis.Petersons@abcsolutions.lv> */
441 .phys_io
= ORION5X_REGS_PHYS_BASE
,
442 .io_pg_offst
= ((ORION5X_REGS_VIRT_BASE
) >> 18) & 0xFFFC,
443 .boot_params
= 0x00000100,
444 .init_machine
= dt2_init
,
445 .map_io
= orion5x_map_io
,
446 .init_irq
= orion5x_init_irq
,
447 .timer
= &orion5x_timer
,
448 .fixup
= openwrt_fixup
, //tag_fixup_mem32,