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_platform_data dt2_switch_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 /*****************************************************************************
222 * RTC ISL1208 on I2C bus
223 ****************************************************************************/
224 static struct i2c_board_info __initdata dt2_i2c_rtc
= {
225 I2C_BOARD_INFO("isl1208", 0x6F),
228 /*****************************************************************************
230 ****************************************************************************/
231 static struct mv_sata_platform_data dt2_sata_data
= {
235 /*****************************************************************************
237 ****************************************************************************/
238 static struct orion5x_mpp_mode dt2_mpp_modes
[] __initdata
= {
239 { 0, MPP_GPIO
}, // RTC interrupt
240 { 1, MPP_GPIO
}, // 88e6131 interrupt
241 { 2, MPP_GPIO
}, // PCI_intB
242 { 3, MPP_GPIO
}, // PCI_intA
243 { 4, MPP_GPIO
}, // reset button switch
248 { 9, MPP_GIGE
}, /* GE_RXERR */
249 { 10, MPP_GPIO
}, // usb
250 { 11, MPP_GPIO
}, // usb
251 { 12, MPP_GIGE
}, // GE_TXD[4]
252 { 13, MPP_GIGE
}, // GE_TXD[5]
253 { 14, MPP_GIGE
}, // GE_TXD[6]
254 { 15, MPP_GIGE
}, // GE_TXD[7]
255 { 16, MPP_GIGE
}, // GE_RXD[4]
256 { 17, MPP_GIGE
}, // GE_RXD[5]
257 { 18, MPP_GIGE
}, // GE_RXD[6]
258 { 19, MPP_GIGE
}, // GE_RXD[7]
262 /*****************************************************************************
264 ****************************************************************************/
265 static struct platform_device dt2_leds
= {
270 /****************************************************************************
272 ****************************************************************************/
273 static irqreturn_t
dt2_reset_handler(int irq
, void *dev_id
)
275 /* This is the paper-clip reset which does an emergency reboot. */
276 printk(KERN_INFO
"Restarting system.\n");
277 machine_restart(NULL
);
279 /* This should never be reached. */
283 static irqreturn_t
dt2_power_handler(int irq
, void *dev_id
)
285 printk(KERN_INFO
"Shutting down system.\n");
290 static void __init
dt2_init(void)
292 DECLARE_MAC_BUF(mac_buf
);
294 * Setup basic Orion functions. Need to be called early.
298 orion5x_mpp_conf(dt2_mpp_modes
);
301 * Configure peripherals.
305 orion5x_uart0_init();
306 orion5x_ehci0_init();
307 orion5x_ehci1_init();
309 orion5x_sata_init(&dt2_sata_data
);
312 printk(KERN_INFO
"U-Boot parameters:\n");
313 printk(KERN_INFO
"Sys Clk = %d, Tclk = %d, BoardID = 0x%02x\n", mvSysclk
, mvTclk
, gBoardId
);
315 printk(KERN_INFO
"Serial: %s\n", dt2_eeprom
.fc
.dt2_serial_number
);
316 printk(KERN_INFO
"Revision: %016x\n", dt2_eeprom
.fc
.dt2_revision
);
317 printk(KERN_INFO
"DT2: Using MAC address %s for port 0\n",
318 print_mac(mac_buf
, dt2_eeprom
.gw
.mac_addr
[0]));
319 printk(KERN_INFO
"DT2: Using MAC address %s for port 1\n",
320 print_mac(mac_buf
, dt2_eeprom
.gw
.mac_addr
[1]));
322 orion5x_eth_init(&dt2_eth_data
);
323 memcpy(dt2_eth_data
.mac_addr
, dt2_eeprom
.gw
.mac_addr
[0], 6);
324 orion5x_eth_switch_init(&dt2_switch_data
, NO_IRQ
);
326 i2c_register_board_info(0, &dt2_i2c_rtc
, 1);
328 orion5x_setup_dev_boot_win(DT2_NOR_BOOT_BASE
, DT2_NOR_BOOT_SIZE
);
329 platform_device_register(&dt2_nor_flash
);
331 orion5x_setup_dev0_win(DT2_LEDS_BASE
, DT2_LEDS_SIZE
);
332 platform_device_register(&dt2_leds
);
334 if (request_irq(gpio_to_irq(DT2_PIN_GPIO_RESET
), &dt2_reset_handler
,
335 IRQF_DISABLED
| IRQF_TRIGGER_LOW
,
336 "DT2: Reset button", NULL
) < 0) {
338 printk("DT2: Reset Button IRQ %d not available\n",
339 gpio_to_irq(DT2_PIN_GPIO_RESET
));
342 if (request_irq(gpio_to_irq(DT2_PIN_GPIO_POWER
), &dt2_power_handler
,
343 IRQF_DISABLED
| IRQF_TRIGGER_LOW
,
344 "DT2: Power button", NULL
) < 0) {
346 printk(KERN_DEBUG
"DT2: Power Button IRQ %d not available\n",
347 gpio_to_irq(DT2_PIN_GPIO_POWER
));
351 static int __init
parse_tag_dt2_uboot(const struct tag
*t
)
353 struct tag_mv_uboot
*mv_uboot
;
355 // Get pointer to our block
356 mv_uboot
= (struct tag_mv_uboot
*)&t
->u
;
357 mvTclk
= mv_uboot
->tclk
;
358 mvSysclk
= mv_uboot
->sysclk
;
359 mvUbootVer
= mv_uboot
->uboot_version
;
360 mvIsUsbHost
= mv_uboot
->isUsbHost
;
363 if(mvTclk
== 166000000) mvTclk
= 166666667;
364 else if(mvTclk
== 133000000) mvTclk
= 133333333;
365 else if(mvSysclk
== 166000000) mvSysclk
= 166666667;
367 gBoardId
= (mvUbootVer
& 0xff);
370 memcpy(&dt2_eeprom
, mv_uboot
->dt2_eeprom
, sizeof(struct DT2_EEPROM_STRUCT
));
374 __tagtable(ATAG_MV_UBOOT
, parse_tag_dt2_uboot
);
377 * This is OpenWrt specific fixup. It includes code from original "tag_fixup_mem32" to
378 * fixup bogus memory tags and also fixes kernel cmdline by adding " init=/etc/preinit"
379 * at the end. It is important to flash OpenWrt image from original Freecom firmware.
381 * Vanilla kernel should use "tag_fixup_mem32" function.
383 void __init
openwrt_fixup(struct machine_desc
*mdesc
, struct tag
*t
,
384 char **from
, struct meminfo
*meminfo
)
387 static char openwrt_init_tag
[] __initdata
= " init=/etc/preinit";
389 for (; t
->hdr
.size
; t
= tag_next(t
)){
390 /* Locate the Freecom cmdline */
391 if (t
->hdr
.tag
== ATAG_CMDLINE
) {
392 p
= t
->u
.cmdline
.cmdline
;
393 printk("%s(%d): Found cmdline '%s' at 0x%0lx\n",
394 __FUNCTION__
, __LINE__
, p
, (unsigned long)p
);
397 * Many orion-based systems have buggy bootloader implementations.
398 * This is a common fixup for bogus memory tags.
400 if (t
->hdr
.tag
== ATAG_MEM
&&
401 (!t
->u
.mem
.size
|| t
->u
.mem
.size
& ~PAGE_MASK
||
402 t
->u
.mem
.start
& ~PAGE_MASK
)) {
404 "Clearing invalid memory bank %dKB@0x%08x\n",
405 t
->u
.mem
.size
/ 1024, t
->u
.mem
.start
);
410 printk("%s(%d): End of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
412 /* Overwrite the end of the table with a new cmdline tag. */
413 t
->hdr
.tag
= ATAG_CMDLINE
;
415 (sizeof (struct tag_header
) +
416 strlen(p
) + strlen(openwrt_init_tag
) + 1 + 4) >> 2;
418 strlcpy(t
->u
.cmdline
.cmdline
, p
, COMMAND_LINE_SIZE
);
419 strlcpy(t
->u
.cmdline
.cmdline
+ strlen(p
), openwrt_init_tag
,
420 COMMAND_LINE_SIZE
- strlen(p
));
422 printk("%s(%d): New cmdline '%s' at 0x%0lx\n",
423 __FUNCTION__
, __LINE__
,
424 t
->u
.cmdline
.cmdline
, (unsigned long)t
->u
.cmdline
.cmdline
);
428 printk("%s(%d): New end of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
430 t
->hdr
.tag
= ATAG_NONE
;
434 /* Warning: Freecom uses their own custom bootloader with mach-type (=1500) */
435 MACHINE_START(DT2
, "Freecom DataTank Gateway")
436 /* Maintainer: Zintis Petersons <Zintis.Petersons@abcsolutions.lv> */
437 .phys_io
= ORION5X_REGS_PHYS_BASE
,
438 .io_pg_offst
= ((ORION5X_REGS_VIRT_BASE
) >> 18) & 0xFFFC,
439 .boot_params
= 0x00000100,
440 .init_machine
= dt2_init
,
441 .map_io
= orion5x_map_io
,
442 .init_irq
= orion5x_init_irq
,
443 .timer
= &orion5x_timer
,
444 .fixup
= openwrt_fixup
, //tag_fixup_mem32,