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