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>
29 #include <asm/mach/arch.h>
30 #include <asm/mach/pci.h>
31 #include <mach/orion5x.h>
35 /*****************************************************************************
37 ****************************************************************************/
38 #include <asm/setup.h>
39 #include "dt2-common.h"
42 u32 mvTclk
= 166666667;
43 u32 mvSysclk
= 200000000;
47 struct DT2_EEPROM_STRUCT dt2_eeprom
;
49 /*****************************************************************************
51 ****************************************************************************/
56 #define DT2_PCI_SLOT0_OFFS 7
57 #define DT2_PCI_SLOT0_IRQ_A_PIN 3
58 #define DT2_PCI_SLOT0_IRQ_B_PIN 2
60 #define DT2_PIN_GPIO_SYNC 25
61 #define DT2_PIN_GPIO_POWER 24
62 #define DT2_PIN_GPIO_UNPLUG1 23
63 #define DT2_PIN_GPIO_UNPLUG2 22
64 #define DT2_PIN_GPIO_RESET 4
66 #define DT2_NOR_BOOT_BASE 0xf4000000
67 #define DT2_NOR_BOOT_SIZE SZ_512K
69 #define DT2_LEDS_BASE 0xfa000000
70 #define DT2_LEDS_SIZE SZ_1K
72 /*****************************************************************************
73 * 512K NOR Flash on Device bus Boot CS
74 ****************************************************************************/
76 static struct mtd_partition dt2_partitions
[] = {
84 static struct physmap_flash_data dt2_nor_flash_data
= {
85 .width
= 1, /* 8 bit bus width */
86 .parts
= dt2_partitions
,
87 .nr_parts
= ARRAY_SIZE(dt2_partitions
)
90 static struct resource dt2_nor_flash_resource
= {
91 .flags
= IORESOURCE_MEM
,
92 .start
= DT2_NOR_BOOT_BASE
,
93 .end
= DT2_NOR_BOOT_BASE
+ DT2_NOR_BOOT_SIZE
- 1,
96 static struct platform_device dt2_nor_flash
= {
97 .name
= "physmap-flash",
100 .platform_data
= &dt2_nor_flash_data
,
102 .resource
= &dt2_nor_flash_resource
,
106 /*****************************************************************************
108 ****************************************************************************/
110 void __init
dt2_pci_preinit(void)
115 * Configure PCI GPIO IRQ pins
117 pin
= DT2_PCI_SLOT0_IRQ_A_PIN
;
118 if (gpio_request(pin
, "PCI IntA") == 0) {
119 if (gpio_direction_input(pin
) == 0) {
120 irq
= gpio_to_irq(pin
);
121 irq_set_irq_type(irq
, IRQ_TYPE_LEVEL_LOW
);
122 printk (KERN_INFO
"PCI IntA IRQ: %d\n", irq
);
124 printk(KERN_ERR
"dt2_pci_preinit failed to "
125 "irq_set_irq_type pin %d\n", pin
);
129 printk(KERN_ERR
"dt2_pci_preinit failed to request gpio %d\n", pin
);
132 pin
= DT2_PCI_SLOT0_IRQ_B_PIN
;
133 if (gpio_request(pin
, "PCI IntB") == 0) {
134 if (gpio_direction_input(pin
) == 0) {
135 irq
= gpio_to_irq(pin
);
136 irq_set_irq_type(irq
, IRQ_TYPE_LEVEL_LOW
);
137 printk (KERN_INFO
"PCI IntB IRQ: %d\n", irq
);
139 printk(KERN_ERR
"dt2_pci_preinit failed to "
140 "irq_set_irq_type pin %d\n", pin
);
144 printk(KERN_ERR
"dt2_pci_preinit failed to gpio_request %d\n", pin
);
148 static int __init
dt2_pci_map_irq(const struct pci_dev
*dev
, u8 slot
, u8 pin
)
153 * Check for devices with hard-wired IRQs.
155 irq
= orion5x_pci_map_irq(dev
, slot
, pin
);
157 printk(KERN_INFO
"orion5x_pci_map_irq: %d\n", irq
);
162 * PCI IRQs are connected via GPIOs
164 switch (slot
- DT2_PCI_SLOT0_OFFS
) {
167 irq
= gpio_to_irq(DT2_PCI_SLOT0_IRQ_A_PIN
);
168 printk(KERN_INFO
"dt2_pci_map_irq DT2_PCI_SLOT0_IRQ_A_PIN: %d\n", irq
);
171 irq
= gpio_to_irq(DT2_PCI_SLOT0_IRQ_B_PIN
);
172 printk(KERN_INFO
"dt2_pci_map_irq DT2_PCI_SLOT0_IRQ_B_PIN: %d\n", irq
);
176 printk(KERN_INFO
"dt2_pci_map_irq IRQ: %d\n", irq
);
182 static struct hw_pci dt2_pci __initdata
= {
184 .preinit
= dt2_pci_preinit
,
185 .setup
= orion5x_pci_sys_setup
,
186 .scan
= orion5x_pci_sys_scan_bus
,
187 .map_irq
= dt2_pci_map_irq
,
190 static int __init
dt2_pci_init(void)
192 if (machine_is_dt2())
193 pci_common_init(&dt2_pci
);
198 subsys_initcall(dt2_pci_init
);
200 /*****************************************************************************
202 ****************************************************************************/
204 static struct mv643xx_eth_platform_data dt2_eth_data
= {
205 .phy_addr
= MV643XX_ETH_PHY_NONE
,
207 .duplex
= DUPLEX_FULL
,
210 static struct dsa_chip_data dt2_switch_chip_data
= {
211 .port_names
[0] = "wan",
212 .port_names
[1] = "lan1",
213 .port_names
[2] = "lan2",
214 .port_names
[3] = "cpu",
215 .port_names
[4] = "lan3",
216 .port_names
[5] = "lan4",
219 static struct dsa_platform_data dt2_switch_plat_data
= {
221 .chip
= &dt2_switch_chip_data
,
224 /*****************************************************************************
225 * RTC ISL1208 on I2C bus
226 ****************************************************************************/
227 static struct i2c_board_info __initdata dt2_i2c_rtc
= {
228 I2C_BOARD_INFO("isl1208", 0x6F),
231 /*****************************************************************************
233 ****************************************************************************/
234 static struct mv_sata_platform_data dt2_sata_data
= {
238 /*****************************************************************************
240 ****************************************************************************/
241 static unsigned int dt2_mpp_modes
[] __initdata
= {
242 MPP0_GPIO
, // RTC interrupt
243 MPP1_GPIO
, // 88e6131 interrupt
244 MPP2_GPIO
, // PCI_intB
245 MPP3_GPIO
, // PCI_intA
246 MPP4_GPIO
, // reset button switch
251 MPP9_GIGE
, /* GE_RXERR */
254 MPP12_GIGE
, // GE_TXD[4]
255 MPP13_GIGE
, // GE_TXD[5]
256 MPP14_GIGE
, // GE_TXD[6]
257 MPP15_GIGE
, // GE_TXD[7]
258 MPP16_GIGE
, // GE_RXD[4]
259 MPP17_GIGE
, // GE_RXD[5]
260 MPP18_GIGE
, // GE_RXD[6]
261 MPP19_GIGE
, // GE_RXD[7]
265 /*****************************************************************************
267 ****************************************************************************/
268 static struct platform_device dt2_leds
= {
273 /****************************************************************************
275 ****************************************************************************/
276 static irqreturn_t
dt2_reset_handler(int irq
, void *dev_id
)
278 /* This is the paper-clip reset which does an emergency reboot. */
279 printk(KERN_INFO
"Restarting system.\n");
280 machine_restart(NULL
);
282 /* This should never be reached. */
286 static irqreturn_t
dt2_power_handler(int irq
, void *dev_id
)
288 printk(KERN_INFO
"Shutting down system.\n");
293 static void __init
dt2_init(void)
296 * Setup basic Orion functions. Need to be called early.
300 orion5x_mpp_conf(dt2_mpp_modes
);
303 * Configure peripherals.
306 orion5x_uart0_init();
307 orion5x_ehci0_init();
308 orion5x_ehci1_init();
310 orion5x_sata_init(&dt2_sata_data
);
313 printk(KERN_INFO
"U-Boot parameters:\n");
314 printk(KERN_INFO
"Sys Clk = %d, Tclk = %d, BoardID = 0x%02x\n", mvSysclk
, mvTclk
, gBoardId
);
316 printk(KERN_INFO
"Serial: %s\n", dt2_eeprom
.fc
.dt2_serial_number
);
317 printk(KERN_INFO
"Revision: %016x\n", dt2_eeprom
.fc
.dt2_revision
);
318 printk(KERN_INFO
"DT2: Using MAC address %pM for port 0\n",
319 dt2_eeprom
.gw
.mac_addr
[0]);
320 printk(KERN_INFO
"DT2: Using MAC address %pM for port 1\n",
321 dt2_eeprom
.gw
.mac_addr
[1]);
323 orion5x_eth_init(&dt2_eth_data
);
324 memcpy(dt2_eth_data
.mac_addr
, dt2_eeprom
.gw
.mac_addr
[0], 6);
325 orion5x_eth_switch_init(&dt2_switch_plat_data
, NO_IRQ
);
327 i2c_register_board_info(0, &dt2_i2c_rtc
, 1);
329 mvebu_mbus_add_window("devbus-boot", DT2_NOR_BOOT_BASE
,
332 platform_device_register(&dt2_nor_flash
);
334 mvebu_mbus_add_window("devbus-cs0", 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 tag
*t
, char **from
, struct meminfo
*meminfo
)
389 static char openwrt_init_tag
[] __initdata
= " init=/etc/preinit";
391 for (; t
->hdr
.size
; t
= tag_next(t
)){
392 /* Locate the Freecom cmdline */
393 if (t
->hdr
.tag
== ATAG_CMDLINE
) {
394 p
= t
->u
.cmdline
.cmdline
;
395 printk("%s(%d): Found cmdline '%s' at 0x%0lx\n",
396 __FUNCTION__
, __LINE__
, p
, (unsigned long)p
);
399 * Many orion-based systems have buggy bootloader implementations.
400 * This is a common fixup for bogus memory tags.
402 if (t
->hdr
.tag
== ATAG_MEM
&&
403 (!t
->u
.mem
.size
|| t
->u
.mem
.size
& ~PAGE_MASK
||
404 t
->u
.mem
.start
& ~PAGE_MASK
)) {
406 "Clearing invalid memory bank %dKB@0x%08x\n",
407 t
->u
.mem
.size
/ 1024, t
->u
.mem
.start
);
412 printk("%s(%d): End of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
414 /* Overwrite the end of the table with a new cmdline tag. */
415 t
->hdr
.tag
= ATAG_CMDLINE
;
417 (sizeof (struct tag_header
) +
418 strlen(p
) + strlen(openwrt_init_tag
) + 1 + 4) >> 2;
420 strlcpy(t
->u
.cmdline
.cmdline
, p
, COMMAND_LINE_SIZE
);
421 strlcpy(t
->u
.cmdline
.cmdline
+ strlen(p
), openwrt_init_tag
,
422 COMMAND_LINE_SIZE
- strlen(p
));
424 printk("%s(%d): New cmdline '%s' at 0x%0lx\n",
425 __FUNCTION__
, __LINE__
,
426 t
->u
.cmdline
.cmdline
, (unsigned long)t
->u
.cmdline
.cmdline
);
430 printk("%s(%d): New end of table at 0x%0lx\n", __FUNCTION__
, __LINE__
, (unsigned long)t
);
432 t
->hdr
.tag
= ATAG_NONE
;
436 /* Warning: Freecom uses their own custom bootloader with mach-type (=1500) */
437 MACHINE_START(DT2
, "Freecom DataTank Gateway")
438 /* Maintainer: Zintis Petersons <Zintis.Petersons@abcsolutions.lv> */
439 .atag_offset
= 0x100,
440 .init_machine
= dt2_init
,
441 .map_io
= orion5x_map_io
,
442 .init_irq
= orion5x_init_irq
,
443 .init_time
= orion5x_timer_init
,
444 .fixup
= openwrt_fixup
, //tag_fixup_mem32,