1/* 2 * arch/arm/mach-orion5x/dt2-setup.c 3 * 4 * Freecom DataTank Gateway Setup 5 * 6 * Copyright (C) 2009 Zintis Petersons <Zintis.Petersons@abcsolutions.lv> 7 * 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. 11 */ 12 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> 22#include <net/dsa.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> 28#include <asm/gpio.h> 29#include <asm/leds.h> 30#include <asm/mach/arch.h> 31#include <asm/mach/pci.h> 32#include <mach/orion5x.h> 33#include "common.h" 34#include "mpp.h" 35 36/***************************************************************************** 37 * DT2 local 38 ****************************************************************************/ 39#include <asm/setup.h> 40#include "dt2-common.h" 41 42u32 mvUbootVer = 0; 43u32 mvTclk = 166666667; 44u32 mvSysclk = 200000000; 45u32 mvIsUsbHost = 1; 46u32 overEthAddr = 0; 47u32 gBoardId = -1; 48struct DT2_EEPROM_STRUCT dt2_eeprom; 49 50/***************************************************************************** 51 * DT2 Info 52 ****************************************************************************/ 53/* 54 * PCI 55 */ 56 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 60 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 66 67#define DT2_NOR_BOOT_BASE 0xf4000000 68#define DT2_NOR_BOOT_SIZE SZ_512K 69 70#define DT2_LEDS_BASE 0xfa000000 71#define DT2_LEDS_SIZE SZ_1K 72 73/***************************************************************************** 74 * 512K NOR Flash on Device bus Boot CS 75 ****************************************************************************/ 76 77static struct mtd_partition dt2_partitions[] = { 78 { 79 .name = "u-boot", 80 .size = 0x00080000, 81 .offset = 0, 82 }, 83}; 84 85static 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) 89}; 90 91static 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, 95}; 96 97static struct platform_device dt2_nor_flash = { 98 .name = "physmap-flash", 99 .id = 0, 100 .dev = { 101 .platform_data = &dt2_nor_flash_data, 102 }, 103 .resource = &dt2_nor_flash_resource, 104 .num_resources = 1, 105}; 106 107/***************************************************************************** 108 * PCI 109 ****************************************************************************/ 110 111void __init dt2_pci_preinit(void) 112{ 113 int pin, irq; 114 115 /* 116 * Configure PCI GPIO IRQ pins 117 */ 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 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); 123 printk (KERN_INFO "PCI IntA IRQ: %d\n", irq); 124 } else { 125 printk(KERN_ERR "dt2_pci_preinit failed to " 126 "irq_set_irq_type pin %d\n", pin); 127 gpio_free(pin); 128 } 129 } else { 130 printk(KERN_ERR "dt2_pci_preinit failed to request gpio %d\n", pin); 131 } 132 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 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); 138 printk (KERN_INFO "PCI IntB IRQ: %d\n", irq); 139 } else { 140 printk(KERN_ERR "dt2_pci_preinit failed to " 141 "irq_set_irq_type pin %d\n", pin); 142 gpio_free(pin); 143 } 144 } else { 145 printk(KERN_ERR "dt2_pci_preinit failed to gpio_request %d\n", pin); 146 } 147} 148 149static int __init dt2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 150{ 151 int irq; 152 153 /* 154 * Check for devices with hard-wired IRQs. 155 */ 156 irq = orion5x_pci_map_irq(dev, slot, pin); 157 if (irq != -1){ 158 printk(KERN_INFO "orion5x_pci_map_irq: %d\n", irq); 159 return irq; 160 } 161 162 /* 163 * PCI IRQs are connected via GPIOs 164 */ 165 switch (slot - DT2_PCI_SLOT0_OFFS) { 166 case 0: 167 if (pin == 1){ 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); 170 } 171 else { 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); 174 } 175 default: 176 irq = -1; 177 printk(KERN_INFO "dt2_pci_map_irq IRQ: %d\n", irq); 178 } 179 180 return irq; 181} 182 183static struct hw_pci dt2_pci __initdata = { 184 .nr_controllers = 2, 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, 190}; 191 192static int __init dt2_pci_init(void) 193{ 194 if (machine_is_dt2()) 195 pci_common_init(&dt2_pci); 196 197 return 0; 198} 199 200subsys_initcall(dt2_pci_init); 201 202/***************************************************************************** 203 * Ethernet 204 ****************************************************************************/ 205 206static struct mv643xx_eth_platform_data dt2_eth_data = { 207 .phy_addr = MV643XX_ETH_PHY_NONE, 208 .speed = SPEED_1000, 209 .duplex = DUPLEX_FULL, 210}; 211 212static 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", 219}; 220 221static struct dsa_platform_data dt2_switch_plat_data = { 222 .nr_chips = 1, 223 .chip = &dt2_switch_chip_data, 224}; 225 226/***************************************************************************** 227 * RTC ISL1208 on I2C bus 228 ****************************************************************************/ 229static struct i2c_board_info __initdata dt2_i2c_rtc = { 230 I2C_BOARD_INFO("isl1208", 0x6F), 231}; 232 233/***************************************************************************** 234 * Sata 235 ****************************************************************************/ 236static struct mv_sata_platform_data dt2_sata_data = { 237 .n_ports = 2, 238}; 239 240/***************************************************************************** 241 * General Setup 242 ****************************************************************************/ 243static unsigned int dt2_mpp_modes[] __initdata = { 244 MPP0_GPIO, // RTC interrupt 245 MPP1_GPIO, // 88e6131 interrupt 246 MPP2_GPIO, // PCI_intB 247 MPP3_GPIO, // PCI_intA 248 MPP4_GPIO, // reset button switch 249 MPP5_GPIO, 250 MPP6_GPIO, 251 MPP7_GPIO, 252 MPP8_GPIO, 253 MPP9_GIGE, /* GE_RXERR */ 254 MPP10_GPIO, // usb 255 MPP11_GPIO, // usb 256 MPP12_GIGE, // GE_TXD[4] 257 MPP13_GIGE, // GE_TXD[5] 258 MPP14_GIGE, // GE_TXD[6] 259 MPP15_GIGE, // GE_TXD[7] 260 MPP16_GIGE, // GE_RXD[4] 261 MPP17_GIGE, // GE_RXD[5] 262 MPP18_GIGE, // GE_RXD[6] 263 MPP19_GIGE, // GE_RXD[7] 264 0, 265}; 266 267/***************************************************************************** 268 * LEDS 269 ****************************************************************************/ 270static struct platform_device dt2_leds = { 271 .name = "dt2-led", 272 .id = -1, 273}; 274 275/**************************************************************************** 276 * GPIO key 277 ****************************************************************************/ 278static irqreturn_t dt2_reset_handler(int irq, void *dev_id) 279{ 280 /* This is the paper-clip reset which does an emergency reboot. */ 281 printk(KERN_INFO "Restarting system.\n"); 282 machine_restart(NULL); 283 284 /* This should never be reached. */ 285 return IRQ_HANDLED; 286} 287 288static irqreturn_t dt2_power_handler(int irq, void *dev_id) 289{ 290 printk(KERN_INFO "Shutting down system.\n"); 291 machine_power_off(); 292 return IRQ_HANDLED; 293} 294 295static void __init dt2_init(void) 296{ 297 /* 298 * Setup basic Orion functions. Need to be called early. 299 */ 300 orion5x_init(); 301 302 orion5x_mpp_conf(dt2_mpp_modes); 303 304 /* 305 * Configure peripherals. 306 */ 307 308 orion5x_uart0_init(); 309 orion5x_ehci0_init(); 310 orion5x_ehci1_init(); 311 orion5x_i2c_init(); 312 orion5x_sata_init(&dt2_sata_data); 313 orion5x_xor_init(); 314 315 printk(KERN_INFO "U-Boot parameters:\n"); 316 printk(KERN_INFO "Sys Clk = %d, Tclk = %d, BoardID = 0x%02x\n", mvSysclk, mvTclk, gBoardId); 317 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]); 324 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); 328 329 i2c_register_board_info(0, &dt2_i2c_rtc, 1); 330 331 orion5x_setup_dev_boot_win(DT2_NOR_BOOT_BASE, DT2_NOR_BOOT_SIZE); 332 platform_device_register(&dt2_nor_flash); 333 334 orion5x_setup_dev0_win(DT2_LEDS_BASE, DT2_LEDS_SIZE); 335 platform_device_register(&dt2_leds); 336 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) { 340 341 printk("DT2: Reset Button IRQ %d not available\n", 342 gpio_to_irq(DT2_PIN_GPIO_RESET)); 343 } 344 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) { 348 349 printk(KERN_DEBUG "DT2: Power Button IRQ %d not available\n", 350 gpio_to_irq(DT2_PIN_GPIO_POWER)); 351 } 352} 353 354static int __init parse_tag_dt2_uboot(const struct tag *t) 355{ 356 struct tag_mv_uboot *mv_uboot; 357 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; 364 365 // Some clock fixups 366 if(mvTclk == 166000000) mvTclk = 166666667; 367 else if(mvTclk == 133000000) mvTclk = 133333333; 368 else if(mvSysclk == 166000000) mvSysclk = 166666667; 369 370 gBoardId = (mvUbootVer & 0xff); 371 372 //DT2 specific data 373 memcpy(&dt2_eeprom, mv_uboot->dt2_eeprom, sizeof(struct DT2_EEPROM_STRUCT)); 374 375 return 0; 376} 377__tagtable(ATAG_MV_UBOOT, parse_tag_dt2_uboot); 378 379/* 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. 383 * 384 * Vanilla kernel should use "tag_fixup_mem32" function. 385 */ 386void __init openwrt_fixup(struct machine_desc *mdesc, struct tag *t, 387 char **from, struct meminfo *meminfo) 388{ 389 char *p = NULL; 390 static char openwrt_init_tag[] __initdata = " init=/etc/preinit"; 391 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); 398 } 399 /* 400 * Many orion-based systems have buggy bootloader implementations. 401 * This is a common fixup for bogus memory tags. 402 */ 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)) { 406 printk(KERN_WARNING 407 "Clearing invalid memory bank %dKB@0x%08x\n", 408 t->u.mem.size / 1024, t->u.mem.start); 409 t->hdr.tag = 0; 410 } 411 } 412 413 printk("%s(%d): End of table at 0x%0lx\n", __FUNCTION__, __LINE__, (unsigned long)t); 414 415 /* Overwrite the end of the table with a new cmdline tag. */ 416 t->hdr.tag = ATAG_CMDLINE; 417 t->hdr.size = 418 (sizeof (struct tag_header) + 419 strlen(p) + strlen(openwrt_init_tag) + 1 + 4) >> 2; 420 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)); 424 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); 428 429 t = tag_next(t); 430 431 printk("%s(%d): New end of table at 0x%0lx\n", __FUNCTION__, __LINE__, (unsigned long)t); 432 433 t->hdr.tag = ATAG_NONE; 434 t->hdr.size = 0; 435} 436 437/* Warning: Freecom uses their own custom bootloader with mach-type (=1500) */ 438MACHINE_START(DT2, "Freecom DataTank Gateway") 439 /* Maintainer: Zintis Petersons <Zintis.Petersons@abcsolutions.lv> */ 440 .boot_params = 0x00000100, 441 .init_machine = dt2_init, 442 .map_io = orion5x_map_io, 443 .init_irq = orion5x_init_irq, 444 .timer = &orion5x_timer, 445 .fixup = openwrt_fixup, //tag_fixup_mem32, 446MACHINE_END 447