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 50static 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 66static 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 72static 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 80static 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 94static struct physmap_flash_data kurobox_pro_nor_flash_data = { 95 .width = 1, 96}; 97 98static 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 104static 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 118static 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 136static 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 143static 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 153subsys_initcall(kurobox_pro_pci_init); 154 155/***************************************************************************** 156 * Ethernet 157 ****************************************************************************/ 158 159static 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 ****************************************************************************/ 166static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = { 167 I2C_BOARD_INFO("rs5c372a", 0x32), 168}; 169 170/***************************************************************************** 171 * SATA 172 ****************************************************************************/ 173static 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 183static 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 206static 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 219static 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 286static 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 ****************************************************************************/ 314static 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 338static 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 380MACHINE_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, 391MACHINE_END 392#endif 393 394#ifdef CONFIG_MACH_LINKSTATION_PRO 395MACHINE_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, 406MACHINE_END 407#endif 408