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 <linux/platform_data/mtd-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 .setup = orion5x_pci_sys_setup, 142 .scan = orion5x_pci_sys_scan_bus, 143 .map_irq = kurobox_pro_pci_map_irq, 144 }; 145 146 static int __init kurobox_pro_pci_init(void) 147 { 148 if (machine_is_kurobox_pro()) { 149 orion5x_pci_disable(); 150 pci_common_init(&kurobox_pro_pci); 151 } 152 153 return 0; 154 } 155 156 subsys_initcall(kurobox_pro_pci_init); 157 158 /***************************************************************************** 159 * Ethernet 160 ****************************************************************************/ 161 162 static struct mv643xx_eth_platform_data kurobox_pro_eth_data = { 163 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 164 }; 165 166 /***************************************************************************** 167 * RTC 5C372a on I2C bus 168 ****************************************************************************/ 169 static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = { 170 I2C_BOARD_INFO("rs5c372a", 0x32), 171 }; 172 173 /***************************************************************************** 174 * SATA 175 ****************************************************************************/ 176 static struct mv_sata_platform_data kurobox_pro_sata_data = { 177 .n_ports = 2, 178 }; 179 180 /***************************************************************************** 181 * Kurobox Pro specific power off method via UART1-attached microcontroller 182 ****************************************************************************/ 183 184 #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) 185 186 static int kurobox_pro_miconread(unsigned char *buf, int count) 187 { 188 int i; 189 int timeout; 190 191 for (i = 0; i < count; i++) { 192 timeout = 10; 193 194 while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) { 195 if (--timeout == 0) 196 break; 197 udelay(1000); 198 } 199 200 if (timeout == 0) 201 break; 202 buf[i] = readl(UART1_REG(RX)); 203 } 204 205 /* return read bytes */ 206 return i; 207 } 208 209 static int kurobox_pro_miconwrite(const unsigned char *buf, int count) 210 { 211 int i = 0; 212 213 while (count--) { 214 while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE)) 215 barrier(); 216 writel(buf[i++], UART1_REG(TX)); 217 } 218 219 return 0; 220 } 221 222 static int kurobox_pro_miconsend(const unsigned char *data, int count) 223 { 224 int i; 225 unsigned char checksum = 0; 226 unsigned char recv_buf[40]; 227 unsigned char send_buf[40]; 228 unsigned char correct_ack[3]; 229 int retry = 2; 230 231 /* Generate checksum */ 232 for (i = 0; i < count; i++) 233 checksum -= data[i]; 234 235 do { 236 /* Send data */ 237 kurobox_pro_miconwrite(data, count); 238 239 /* send checksum */ 240 kurobox_pro_miconwrite(&checksum, 1); 241 242 if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) { 243 printk(KERN_ERR ">%s: receive failed.\n", __func__); 244 245 /* send preamble to clear the receive buffer */ 246 memset(&send_buf, 0xff, sizeof(send_buf)); 247 kurobox_pro_miconwrite(send_buf, sizeof(send_buf)); 248 249 /* make dummy reads */ 250 mdelay(100); 251 kurobox_pro_miconread(recv_buf, sizeof(recv_buf)); 252 } else { 253 /* Generate expected ack */ 254 correct_ack[0] = 0x01; 255 correct_ack[1] = data[1]; 256 correct_ack[2] = 0x00; 257 258 /* checksum Check */ 259 if ((recv_buf[0] + recv_buf[1] + recv_buf[2] + 260 recv_buf[3]) & 0xFF) { 261 printk(KERN_ERR ">%s: Checksum Error : " 262 "Received data[%02x, %02x, %02x, %02x]" 263 "\n", __func__, recv_buf[0], 264 recv_buf[1], recv_buf[2], recv_buf[3]); 265 } else { 266 /* Check Received Data */ 267 if (correct_ack[0] == recv_buf[0] && 268 correct_ack[1] == recv_buf[1] && 269 correct_ack[2] == recv_buf[2]) { 270 /* Interval for next command */ 271 mdelay(10); 272 273 /* Receive ACK */ 274 return 0; 275 } 276 } 277 /* Received NAK or illegal Data */ 278 printk(KERN_ERR ">%s: Error : NAK or Illegal Data " 279 "Received\n", __func__); 280 } 281 } while (retry--); 282 283 /* Interval for next command */ 284 mdelay(10); 285 286 return -1; 287 } 288 289 static void kurobox_pro_power_off(void) 290 { 291 const unsigned char watchdogkill[] = {0x01, 0x35, 0x00}; 292 const unsigned char shutdownwait[] = {0x00, 0x0c}; 293 const unsigned char poweroff[] = {0x00, 0x06}; 294 /* 38400 baud divisor */ 295 const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400)); 296 297 pr_info("%s: triggering power-off...\n", __func__); 298 299 /* hijack uart1 and reset into sane state (38400,8n1,even parity) */ 300 writel(0x83, UART1_REG(LCR)); 301 writel(divisor & 0xff, UART1_REG(DLL)); 302 writel((divisor >> 8) & 0xff, UART1_REG(DLM)); 303 writel(0x1b, UART1_REG(LCR)); 304 writel(0x00, UART1_REG(IER)); 305 writel(0x07, UART1_REG(FCR)); 306 writel(0x00, UART1_REG(MCR)); 307 308 /* Send the commands to shutdown the Kurobox Pro */ 309 kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ; 310 kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ; 311 kurobox_pro_miconsend(poweroff, sizeof(poweroff)); 312 } 313 314 /***************************************************************************** 315 * General Setup 316 ****************************************************************************/ 317 static unsigned int kurobox_pro_mpp_modes[] __initdata = { 318 MPP0_UNUSED, 319 MPP1_UNUSED, 320 MPP2_GPIO, /* GPIO Micon */ 321 MPP3_GPIO, /* GPIO Rtc */ 322 MPP4_UNUSED, 323 MPP5_UNUSED, 324 MPP6_NAND, /* NAND Flash REn */ 325 MPP7_NAND, /* NAND Flash WEn */ 326 MPP8_UNUSED, 327 MPP9_UNUSED, 328 MPP10_UNUSED, 329 MPP11_UNUSED, 330 MPP12_SATA_LED, /* SATA 0 presence */ 331 MPP13_SATA_LED, /* SATA 1 presence */ 332 MPP14_SATA_LED, /* SATA 0 active */ 333 MPP15_SATA_LED, /* SATA 1 active */ 334 MPP16_UART, /* UART1 RXD */ 335 MPP17_UART, /* UART1 TXD */ 336 MPP18_UART, /* UART1 CTSn */ 337 MPP19_UART, /* UART1 RTSn */ 338 0, 339 }; 340 341 static void __init kurobox_pro_init(void) 342 { 343 /* 344 * Setup basic Orion functions. Need to be called early. 345 */ 346 orion5x_init(); 347 348 orion5x_mpp_conf(kurobox_pro_mpp_modes); 349 350 /* 351 * Configure peripherals. 352 */ 353 orion5x_ehci0_init(); 354 orion5x_ehci1_init(); 355 orion5x_eth_init(&kurobox_pro_eth_data); 356 orion5x_i2c_init(); 357 orion5x_sata_init(&kurobox_pro_sata_data); 358 orion5x_uart0_init(); 359 orion5x_uart1_init(); 360 orion5x_xor_init(); 361 362 orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, 363 KUROBOX_PRO_NOR_BOOT_SIZE); 364 platform_device_register(&kurobox_pro_nor_flash); 365 366 if (machine_is_kurobox_pro()) { 367 orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, 368 KUROBOX_PRO_NAND_SIZE); 369 platform_device_register(&kurobox_pro_nand_flash); 370 } 371 372 i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); 373 374 /* register Kurobox Pro specific power-off method */ 375 pm_power_off = kurobox_pro_power_off; 376 } 377 378 #ifdef CONFIG_MACH_KUROBOX_PRO 379 MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro") 380 /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */ 381 .atag_offset = 0x100, 382 .init_machine = kurobox_pro_init, 383 .map_io = orion5x_map_io, 384 .init_early = orion5x_init_early, 385 .init_irq = orion5x_init_irq, 386 .timer = &orion5x_timer, 387 .fixup = tag_fixup_mem32, 388 .restart = orion5x_restart, 389 MACHINE_END 390 #endif 391 392 #ifdef CONFIG_MACH_LINKSTATION_PRO 393 MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live") 394 /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ 395 .atag_offset = 0x100, 396 .init_machine = kurobox_pro_init, 397 .map_io = orion5x_map_io, 398 .init_early = orion5x_init_early, 399 .init_irq = orion5x_init_irq, 400 .timer = &orion5x_timer, 401 .fixup = tag_fixup_mem32, 402 .restart = orion5x_restart, 403 MACHINE_END 404 #endif 405