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