kurobox_pro-setup.c (10832B)
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/rawnand.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 <linux/platform_data/mtd-orion_nand.h> 27#include "common.h" 28#include "mpp.h" 29#include "orion5x.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 53static 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 69static 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 75static 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 83static 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 97static struct physmap_flash_data kurobox_pro_nor_flash_data = { 98 .width = 1, 99}; 100 101static 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 107static 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 121static 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 139static 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 146static 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 156subsys_initcall(kurobox_pro_pci_init); 157 158/***************************************************************************** 159 * Ethernet 160 ****************************************************************************/ 161 162static 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 ****************************************************************************/ 169static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = { 170 I2C_BOARD_INFO("rs5c372a", 0x32), 171}; 172 173/***************************************************************************** 174 * SATA 175 ****************************************************************************/ 176static 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 186static 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 209static 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 222static 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 289static 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 ****************************************************************************/ 317static 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 341static 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 mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET, 363 ORION_MBUS_DEVBUS_BOOT_ATTR, 364 KUROBOX_PRO_NOR_BOOT_BASE, 365 KUROBOX_PRO_NOR_BOOT_SIZE); 366 platform_device_register(&kurobox_pro_nor_flash); 367 368 if (machine_is_kurobox_pro()) { 369 mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0), 370 ORION_MBUS_DEVBUS_ATTR(0), 371 KUROBOX_PRO_NAND_BASE, 372 KUROBOX_PRO_NAND_SIZE); 373 platform_device_register(&kurobox_pro_nand_flash); 374 } 375 376 i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); 377 378 /* register Kurobox Pro specific power-off method */ 379 pm_power_off = kurobox_pro_power_off; 380} 381 382#ifdef CONFIG_MACH_KUROBOX_PRO 383MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro") 384 /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */ 385 .atag_offset = 0x100, 386 .nr_irqs = ORION5X_NR_IRQS, 387 .init_machine = kurobox_pro_init, 388 .map_io = orion5x_map_io, 389 .init_early = orion5x_init_early, 390 .init_irq = orion5x_init_irq, 391 .init_time = orion5x_timer_init, 392 .fixup = tag_fixup_mem32, 393 .restart = orion5x_restart, 394MACHINE_END 395#endif 396 397#ifdef CONFIG_MACH_LINKSTATION_PRO 398MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live") 399 /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ 400 .atag_offset = 0x100, 401 .nr_irqs = ORION5X_NR_IRQS, 402 .init_machine = kurobox_pro_init, 403 .map_io = orion5x_map_io, 404 .init_early = orion5x_init_early, 405 .init_irq = orion5x_init_irq, 406 .init_time = orion5x_timer_init, 407 .fixup = tag_fixup_mem32, 408 .restart = orion5x_restart, 409MACHINE_END 410#endif