1 /* 2 * arch/arm/mach-orion5x/kurobox_pro-setup.c 3 * 4 * Maintainer: Ronen Shitrit <rshitrit@marvell.com> 5 * 6 * This file is licensed under the terms of the GNU General Public 7 * License version 2. This program is licensed "as is" without any 8 * warranty of any kind, whether express or implied. 9 */ 10 #include <linux/gpio.h> 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/platform_device.h> 14 #include <linux/pci.h> 15 #include <linux/irq.h> 16 #include <linux/delay.h> 17 #include <linux/mtd/physmap.h> 18 #include <linux/mtd/nand.h> 19 #include <linux/mv643xx_eth.h> 20 #include <linux/i2c.h> 21 #include <linux/serial_reg.h> 22 #include <linux/ata_platform.h> 23 #include <asm/mach-types.h> 24 #include <asm/mach/arch.h> 25 #include <asm/mach/pci.h> 26 #include <mach/orion5x.h> 27 #include <plat/orion_nand.h> 28 #include "common.h" 29 #include "mpp.h" 30 31 /***************************************************************************** 32 * KUROBOX-PRO Info 33 ****************************************************************************/ 34 35 /* 36 * 256K NOR flash Device bus boot chip select 37 */ 38 39 #define KUROBOX_PRO_NOR_BOOT_BASE 0xf4000000 40 #define KUROBOX_PRO_NOR_BOOT_SIZE SZ_256K 41 42 /* 43 * 256M NAND flash on Device bus chip select 1 44 */ 45 46 #define KUROBOX_PRO_NAND_BASE 0xfc000000 47 #define KUROBOX_PRO_NAND_SIZE SZ_2M 48 49 /***************************************************************************** 50 * 256MB NAND Flash on Device bus CS0 51 ****************************************************************************/ 52 53 static struct mtd_partition kurobox_pro_nand_parts[] = { 54 { 55 .name = "uImage", 56 .offset = 0, 57 .size = SZ_4M, 58 }, { 59 .name = "rootfs", 60 .offset = SZ_4M, 61 .size = SZ_64M, 62 }, { 63 .name = "extra", 64 .offset = SZ_4M + SZ_64M, 65 .size = SZ_256M - (SZ_4M + SZ_64M), 66 }, 67 }; 68 69 static struct resource kurobox_pro_nand_resource = { 70 .flags = IORESOURCE_MEM, 71 .start = KUROBOX_PRO_NAND_BASE, 72 .end = KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1, 73 }; 74 75 static struct orion_nand_data kurobox_pro_nand_data = { 76 .parts = kurobox_pro_nand_parts, 77 .nr_parts = ARRAY_SIZE(kurobox_pro_nand_parts), 78 .cle = 0, 79 .ale = 1, 80 .width = 8, 81 }; 82 83 static struct platform_device kurobox_pro_nand_flash = { 84 .name = "orion_nand", 85 .id = -1, 86 .dev = { 87 .platform_data = &kurobox_pro_nand_data, 88 }, 89 .resource = &kurobox_pro_nand_resource, 90 .num_resources = 1, 91 }; 92 93 /***************************************************************************** 94 * 256KB NOR Flash on BOOT Device 95 ****************************************************************************/ 96 97 static struct physmap_flash_data kurobox_pro_nor_flash_data = { 98 .width = 1, 99 }; 100 101 static struct resource kurobox_pro_nor_flash_resource = { 102 .flags = IORESOURCE_MEM, 103 .start = KUROBOX_PRO_NOR_BOOT_BASE, 104 .end = KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1, 105 }; 106 107 static struct platform_device kurobox_pro_nor_flash = { 108 .name = "physmap-flash", 109 .id = 0, 110 .dev = { 111 .platform_data = &kurobox_pro_nor_flash_data, 112 }, 113 .num_resources = 1, 114 .resource = &kurobox_pro_nor_flash_resource, 115 }; 116 117 /***************************************************************************** 118 * PCI 119 ****************************************************************************/ 120 121 static int __init kurobox_pro_pci_map_irq(const struct pci_dev *dev, u8 slot, 122 u8 pin) 123 { 124 int irq; 125 126 /* 127 * Check for devices with hard-wired IRQs. 128 */ 129 irq = orion5x_pci_map_irq(dev, slot, pin); 130 if (irq != -1) 131 return irq; 132 133 /* 134 * PCI isn't used on the Kuro 135 */ 136 return -1; 137 } 138 139 static struct hw_pci kurobox_pro_pci __initdata = { 140 .nr_controllers = 2, 141 .swizzle = pci_std_swizzle, 142 .setup = orion5x_pci_sys_setup, 143 .scan = orion5x_pci_sys_scan_bus, 144 .map_irq = kurobox_pro_pci_map_irq, 145 }; 146 147 static int __init kurobox_pro_pci_init(void) 148 { 149 if (machine_is_kurobox_pro()) { 150 orion5x_pci_disable(); 151 pci_common_init(&kurobox_pro_pci); 152 } 153 154 return 0; 155 } 156 157 subsys_initcall(kurobox_pro_pci_init); 158 159 /***************************************************************************** 160 * Ethernet 161 ****************************************************************************/ 162 163 static struct mv643xx_eth_platform_data kurobox_pro_eth_data = { 164 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 165 }; 166 167 /***************************************************************************** 168 * RTC 5C372a on I2C bus 169 ****************************************************************************/ 170 static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = { 171 I2C_BOARD_INFO("rs5c372a", 0x32), 172 }; 173 174 /***************************************************************************** 175 * SATA 176 ****************************************************************************/ 177 static struct mv_sata_platform_data kurobox_pro_sata_data = { 178 .n_ports = 2, 179 }; 180 181 /***************************************************************************** 182 * Kurobox Pro specific power off method via UART1-attached microcontroller 183 ****************************************************************************/ 184 185 #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) 186 187 static int kurobox_pro_miconread(unsigned char *buf, int count) 188 { 189 int i; 190 int timeout; 191 192 for (i = 0; i < count; i++) { 193 timeout = 10; 194 195 while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) { 196 if (--timeout == 0) 197 break; 198 udelay(1000); 199 } 200 201 if (timeout == 0) 202 break; 203 buf[i] = readl(UART1_REG(RX)); 204 } 205 206 /* return read bytes */ 207 return i; 208 } 209 210 static int kurobox_pro_miconwrite(const unsigned char *buf, int count) 211 { 212 int i = 0; 213 214 while (count--) { 215 while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE)) 216 barrier(); 217 writel(buf[i++], UART1_REG(TX)); 218 } 219 220 return 0; 221 } 222 223 static int kurobox_pro_miconsend(const unsigned char *data, int count) 224 { 225 int i; 226 unsigned char checksum = 0; 227 unsigned char recv_buf[40]; 228 unsigned char send_buf[40]; 229 unsigned char correct_ack[3]; 230 int retry = 2; 231 232 /* Generate checksum */ 233 for (i = 0; i < count; i++) 234 checksum -= data[i]; 235 236 do { 237 /* Send data */ 238 kurobox_pro_miconwrite(data, count); 239 240 /* send checksum */ 241 kurobox_pro_miconwrite(&checksum, 1); 242 243 if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) { 244 printk(KERN_ERR ">%s: receive failed.\n", __func__); 245 246 /* send preamble to clear the receive buffer */ 247 memset(&send_buf, 0xff, sizeof(send_buf)); 248 kurobox_pro_miconwrite(send_buf, sizeof(send_buf)); 249 250 /* make dummy reads */ 251 mdelay(100); 252 kurobox_pro_miconread(recv_buf, sizeof(recv_buf)); 253 } else { 254 /* Generate expected ack */ 255 correct_ack[0] = 0x01; 256 correct_ack[1] = data[1]; 257 correct_ack[2] = 0x00; 258 259 /* checksum Check */ 260 if ((recv_buf[0] + recv_buf[1] + recv_buf[2] + 261 recv_buf[3]) & 0xFF) { 262 printk(KERN_ERR ">%s: Checksum Error : " 263 "Received data[%02x, %02x, %02x, %02x]" 264 "\n", __func__, recv_buf[0], 265 recv_buf[1], recv_buf[2], recv_buf[3]); 266 } else { 267 /* Check Received Data */ 268 if (correct_ack[0] == recv_buf[0] && 269 correct_ack[1] == recv_buf[1] && 270 correct_ack[2] == recv_buf[2]) { 271 /* Interval for next command */ 272 mdelay(10); 273 274 /* Receive ACK */ 275 return 0; 276 } 277 } 278 /* Received NAK or illegal Data */ 279 printk(KERN_ERR ">%s: Error : NAK or Illegal Data " 280 "Received\n", __func__); 281 } 282 } while (retry--); 283 284 /* Interval for next command */ 285 mdelay(10); 286 287 return -1; 288 } 289 290 static void kurobox_pro_power_off(void) 291 { 292 const unsigned char watchdogkill[] = {0x01, 0x35, 0x00}; 293 const unsigned char shutdownwait[] = {0x00, 0x0c}; 294 const unsigned char poweroff[] = {0x00, 0x06}; 295 /* 38400 baud divisor */ 296 const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400)); 297 298 pr_info("%s: triggering power-off...\n", __func__); 299 300 /* hijack uart1 and reset into sane state (38400,8n1,even parity) */ 301 writel(0x83, UART1_REG(LCR)); 302 writel(divisor & 0xff, UART1_REG(DLL)); 303 writel((divisor >> 8) & 0xff, UART1_REG(DLM)); 304 writel(0x1b, UART1_REG(LCR)); 305 writel(0x00, UART1_REG(IER)); 306 writel(0x07, UART1_REG(FCR)); 307 writel(0x00, UART1_REG(MCR)); 308 309 /* Send the commands to shutdown the Kurobox Pro */ 310 kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ; 311 kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ; 312 kurobox_pro_miconsend(poweroff, sizeof(poweroff)); 313 } 314 315 /***************************************************************************** 316 * General Setup 317 ****************************************************************************/ 318 static unsigned int kurobox_pro_mpp_modes[] __initdata = { 319 MPP0_UNUSED, 320 MPP1_UNUSED, 321 MPP2_GPIO, /* GPIO Micon */ 322 MPP3_GPIO, /* GPIO Rtc */ 323 MPP4_UNUSED, 324 MPP5_UNUSED, 325 MPP6_NAND, /* NAND Flash REn */ 326 MPP7_NAND, /* NAND Flash WEn */ 327 MPP8_UNUSED, 328 MPP9_UNUSED, 329 MPP10_UNUSED, 330 MPP11_UNUSED, 331 MPP12_SATA_LED, /* SATA 0 presence */ 332 MPP13_SATA_LED, /* SATA 1 presence */ 333 MPP14_SATA_LED, /* SATA 0 active */ 334 MPP15_SATA_LED, /* SATA 1 active */ 335 MPP16_UART, /* UART1 RXD */ 336 MPP17_UART, /* UART1 TXD */ 337 MPP18_UART, /* UART1 CTSn */ 338 MPP19_UART, /* UART1 RTSn */ 339 0, 340 }; 341 342 static void __init kurobox_pro_init(void) 343 { 344 /* 345 * Setup basic Orion functions. Need to be called early. 346 */ 347 orion5x_init(); 348 349 orion5x_mpp_conf(kurobox_pro_mpp_modes); 350 351 /* 352 * Configure peripherals. 353 */ 354 orion5x_ehci0_init(); 355 orion5x_ehci1_init(); 356 orion5x_eth_init(&kurobox_pro_eth_data); 357 orion5x_i2c_init(); 358 orion5x_sata_init(&kurobox_pro_sata_data); 359 orion5x_uart0_init(); 360 orion5x_uart1_init(); 361 orion5x_xor_init(); 362 363 orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, 364 KUROBOX_PRO_NOR_BOOT_SIZE); 365 platform_device_register(&kurobox_pro_nor_flash); 366 367 if (machine_is_kurobox_pro()) { 368 orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, 369 KUROBOX_PRO_NAND_SIZE); 370 platform_device_register(&kurobox_pro_nand_flash); 371 } 372 373 i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); 374 375 /* register Kurobox Pro specific power-off method */ 376 pm_power_off = kurobox_pro_power_off; 377 } 378 379 #ifdef CONFIG_MACH_KUROBOX_PRO 380 MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro") 381 /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */ 382 .atag_offset = 0x100, 383 .init_machine = kurobox_pro_init, 384 .map_io = orion5x_map_io, 385 .init_early = orion5x_init_early, 386 .init_irq = orion5x_init_irq, 387 .timer = &orion5x_timer, 388 .fixup = tag_fixup_mem32, 389 .restart = orion5x_restart, 390 MACHINE_END 391 #endif 392 393 #ifdef CONFIG_MACH_LINKSTATION_PRO 394 MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live") 395 /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ 396 .atag_offset = 0x100, 397 .init_machine = kurobox_pro_init, 398 .map_io = orion5x_map_io, 399 .init_early = orion5x_init_early, 400 .init_irq = orion5x_init_irq, 401 .timer = &orion5x_timer, 402 .fixup = tag_fixup_mem32, 403 .restart = orion5x_restart, 404 MACHINE_END 405 #endif 406