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)
298 * Setup basic Orion functions. Need to be called early.
302 orion5x_mpp_conf(dt2_mpp_modes
);
305 * Configure peripherals.
308 orion5x_uart0_init();
309 orion5x_ehci0_init();
310 orion5x_ehci1_init();
312 orion5x_sata_init(&dt2_sata_data
);
315 printk(KERN_INFO
"U-Boot parameters:\n");
316 printk(KERN_INFO
"Sys Clk = %d, Tclk = %d, BoardID = 0x%02x\n", mvSysclk
, mvTclk
, gBoardId
);
318 printk(KERN_INFO
"Serial: %s\n", dt2_eeprom
.fc
.dt2_serial_number
);
319 printk(KERN_INFO
"Revision: %016x\n", dt2_eeprom
.fc
.dt2_revision
);
320 printk(KERN_INFO
"DT2: Using MAC address %pM for port 0\n",
321 dt2_eeprom
.gw
.mac_addr
[0]);
322 printk(KERN_INFO
"DT2: Using MAC address %pM for port 1\n",
323 dt2_eeprom
.gw
.mac_addr
[1]);
325 orion5x_eth_init(&dt2_eth_data
);
326 memcpy(dt2_eth_data
.mac_addr
, dt2_eeprom
.gw
.mac_addr
[0], 6);
327 orion5x_eth_switch_init(&dt2_switch_plat_data
, NO_IRQ
);
329 i2c_register_board_info(0, &dt2_i2c_rtc
, 1);
331 orion5x_setup_dev_boot_win(DT2_NOR_BOOT_BASE
, DT2_NOR_BOOT_SIZE
);
332 platform_device_register(&dt2_nor_flash
);
334 orion5x_setup_dev0_win(DT2_LEDS_BASE
, DT2_LEDS_SIZE
);
335 platform_device_register(&dt2_leds
);
337 if (request_irq(gpio_to_irq(DT2_PIN_GPIO_RESET
), &dt2_reset_handler
,
338 IRQF_DISABLED
| IRQF_TRIGGER_LOW
,
339 "DT2: Reset button", NULL
) < 0) {
341 printk("DT2: Reset Button IRQ %d not available\n",
342 gpio_to_irq(DT2_PIN_GPIO_RESET
));
345 if (request_irq(gpio_to_irq(DT2_PIN_GPIO_POWER
), &dt2_power_handler
,
346 IRQF_DISABLED
| IRQF_TRIGGER_LOW
,
347 "DT2: Power button", NULL
) < 0) {
349 printk(KERN_DEBUG
"DT2: Power Button IRQ %d not available\n",
350 gpio_to_irq(DT2_PIN_GPIO_POWER
));
354 static int __init
parse_tag_dt2_uboot(const struct tag
*t
)
356 struct tag_mv_uboot
*mv_uboot
;
358 // Get pointer to our block
359 mv_uboot
= (struct tag_mv_uboot
*)&t
->u
;
360 mvTclk
= mv_uboot
->tclk
;
361 mvSysclk
= mv_uboot
->sysclk
;
362 mvUbootVer
= mv_uboot
->uboot_version
;
363 mvIsUsbHost
= mv_uboot
->isUsbHost
;
366 if(mvTclk
== 166000000) mvTclk
= 166666667;
367 else if(mvTclk
== 133000000) mvTclk
= 133333333;
368 else if(mvSysclk
== 166000000) mvSysclk
= 166666667;
370 gBoardId
= (mvUbootVer
& 0xff);
373 memcpy(&dt2_eeprom
, mv_uboot
->dt2_eeprom
, sizeof(struct DT2_EEPROM_STRUCT
));
377 __tagtable(ATAG_MV_UBOOT
, parse_tag_dt2_uboot
);
380 * This is OpenWrt specific fixup. It includes code from original "tag_fixup_mem32" to
381 * fixup bogus memory tags and also fixes kernel cmdline by adding " init=/etc/preinit"
382 * at the end. It is important to flash OpenWrt image from original Freecom firmware.
384 * Vanilla kernel should use "tag_fixup_mem32" function.
386 void __init
openwrt_fixup(struct machine_desc
*mdesc
, struct tag
*t
,
387 char **from
, struct meminfo
*meminfo
)
390 static char openwrt_init_tag
[] __initdata
= " init=/etc/preinit";
392 for (; t
->hdr
.size
; t
= tag_next(t
)){
393 /* Locate the Freecom cmdline */
394 if (t
->hdr
.tag
== ATAG_CMDLINE
) {
395 p
= t
->u
.cmdline
.cmdline
;
396 printk("%s(%d): Found cmdline '%s' at 0x%0lx\n",
397 __FUNCTION__
, __LINE__
, p
, (unsigned long)p
);
400 * Many orion-based systems have buggy bootloader implementations.
401 * This is a common fixup for bogus memory tags.
403 if (t
->hdr
.tag
== ATAG_MEM
&&
404 (!t
->u
.mem
.size
|| t
->u
.mem
.size
& ~PAGE_MASK
||
405 t
->u
.mem
.start
& ~PAGE_MASK
)) {
407 "Clearing invalid memory bank %dKB@0x%08x\n",
408 t
->u
.mem
.size
/ 1024, t
->u
.mem
.start
);
413 printk("%s(%d): End of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
415 /* Overwrite the end of the table with a new cmdline tag. */
416 t
->hdr
.tag
= ATAG_CMDLINE
;
418 (sizeof (struct tag_header
) +
419 strlen(p
) + strlen(openwrt_init_tag
) + 1 + 4) >> 2;
421 strlcpy(t
->u
.cmdline
.cmdline
, p
, COMMAND_LINE_SIZE
);
422 strlcpy(t
->u
.cmdline
.cmdline
+ strlen(p
), openwrt_init_tag
,
423 COMMAND_LINE_SIZE
- strlen(p
));
425 printk("%s(%d): New cmdline '%s' at 0x%0lx\n",
426 __FUNCTION__
, __LINE__
,
427 t
->u
.cmdline
.cmdline
, (unsigned long)t
->u
.cmdline
.cmdline
);
431 printk("%s(%d): New end of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
433 t
->hdr
.tag
= ATAG_NONE
;
437 /* Warning: Freecom uses their own custom bootloader with mach-type (=1500) */
438 MACHINE_START(DT2
, "Freecom DataTank Gateway")
439 /* Maintainer: Zintis Petersons <Zintis.Petersons@abcsolutions.lv> */
440 .phys_io
= ORION5X_REGS_PHYS_BASE
,
441 .io_pg_offst
= ((ORION5X_REGS_VIRT_BASE
) >> 18) & 0xFFFC,
442 .boot_params
= 0x00000100,
443 .init_machine
= dt2_init
,
444 .map_io
= orion5x_map_io
,
445 .init_irq
= orion5x_init_irq
,
446 .timer
= &orion5x_timer
,
447 .fixup
= openwrt_fixup
, //tag_fixup_mem32,