1/* 2 * Copyright 2004-2009 Analog Devices Inc. 3 * 2007-2008 HV Sistemas S.L. 4 * Javier Herrero <jherrero@hvsistemas.es> 5 * 2005 National ICT Australia (NICTA) 6 * Aidan Williams <aidan@nicta.com.au> 7 * 8 * Licensed under the GPL-2 or later. 9 */ 10 11#include <linux/device.h> 12#include <linux/platform_device.h> 13#include <linux/mtd/mtd.h> 14#include <linux/mtd/partitions.h> 15#include <linux/spi/spi.h> 16#include <linux/spi/flash.h> 17#if IS_ENABLED(CONFIG_USB_ISP1362_HCD) 18#include <linux/usb/isp1362.h> 19#endif 20#include <linux/irq.h> 21 22#include <asm/dma.h> 23#include <asm/bfin5xx_spi.h> 24#include <asm/reboot.h> 25#include <asm/portmux.h> 26 27/* 28 * Name the Board for the /proc/cpuinfo 29 */ 30const char bfin_board_name[] = "HV Sistemas H8606"; 31 32#if IS_ENABLED(CONFIG_RTC_DRV_BFIN) 33static struct platform_device rtc_device = { 34 .name = "rtc-bfin", 35 .id = -1, 36}; 37#endif 38 39/* 40* Driver needs to know address, irq and flag pin. 41 */ 42#if IS_ENABLED(CONFIG_DM9000) 43static struct resource dm9000_resources[] = { 44 [0] = { 45 .start = 0x20300000, 46 .end = 0x20300002, 47 .flags = IORESOURCE_MEM, 48 }, 49 [1] = { 50 .start = 0x20300004, 51 .end = 0x20300006, 52 .flags = IORESOURCE_MEM, 53 }, 54 [2] = { 55 .start = IRQ_PF10, 56 .end = IRQ_PF10, 57 .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | 58 IORESOURCE_IRQ_SHAREABLE), 59 }, 60}; 61 62static struct platform_device dm9000_device = { 63 .id = 0, 64 .name = "dm9000", 65 .resource = dm9000_resources, 66 .num_resources = ARRAY_SIZE(dm9000_resources), 67}; 68#endif 69 70#if IS_ENABLED(CONFIG_SMC91X) 71#include <linux/smc91x.h> 72 73static struct smc91x_platdata smc91x_info = { 74 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, 75 .leda = RPC_LED_100_10, 76 .ledb = RPC_LED_TX_RX, 77}; 78 79static struct resource smc91x_resources[] = { 80 { 81 .name = "smc91x-regs", 82 .start = 0x20300300, 83 .end = 0x20300300 + 16, 84 .flags = IORESOURCE_MEM, 85 }, { 86 .start = IRQ_PROG_INTB, 87 .end = IRQ_PROG_INTB, 88 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 89 }, { 90 .start = IRQ_PF7, 91 .end = IRQ_PF7, 92 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 93 }, 94}; 95 96static struct platform_device smc91x_device = { 97 .name = "smc91x", 98 .id = 0, 99 .num_resources = ARRAY_SIZE(smc91x_resources), 100 .resource = smc91x_resources, 101 .dev = { 102 .platform_data = &smc91x_info, 103 }, 104}; 105#endif 106 107#if IS_ENABLED(CONFIG_USB_NET2272) 108static struct resource net2272_bfin_resources[] = { 109 { 110 .start = 0x20300000, 111 .end = 0x20300000 + 0x100, 112 .flags = IORESOURCE_MEM, 113 }, { 114 .start = IRQ_PF10, 115 .end = IRQ_PF10, 116 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 117 }, 118}; 119 120static struct platform_device net2272_bfin_device = { 121 .name = "net2272", 122 .id = -1, 123 .num_resources = ARRAY_SIZE(net2272_bfin_resources), 124 .resource = net2272_bfin_resources, 125}; 126#endif 127 128#if IS_ENABLED(CONFIG_SPI_BFIN5XX) 129/* all SPI peripherals info goes here */ 130 131#if IS_ENABLED(CONFIG_MTD_M25P80) 132static struct mtd_partition bfin_spi_flash_partitions[] = { 133 { 134 .name = "bootloader (spi)", 135 .size = 0x40000, 136 .offset = 0, 137 .mask_flags = MTD_CAP_ROM 138 }, { 139 .name = "fpga (spi)", 140 .size = 0x30000, 141 .offset = 0x40000 142 }, { 143 .name = "linux kernel (spi)", 144 .size = 0x150000, 145 .offset = 0x70000 146 }, { 147 .name = "jffs2 root file system (spi)", 148 .size = 0x640000, 149 .offset = 0x1c0000, 150 } 151}; 152 153static struct flash_platform_data bfin_spi_flash_data = { 154 .name = "m25p80", 155 .parts = bfin_spi_flash_partitions, 156 .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), 157 .type = "m25p64", 158}; 159 160/* SPI flash chip (m25p64) */ 161static struct bfin5xx_spi_chip spi_flash_chip_info = { 162 .enable_dma = 0, /* use dma transfer with this chip*/ 163}; 164#endif 165 166/* Notice: for blackfin, the speed_hz is the value of register 167 * SPI_BAUD, not the real baudrate */ 168static struct spi_board_info bfin_spi_board_info[] __initdata = { 169#if IS_ENABLED(CONFIG_MTD_M25P80) 170 { 171 /* the modalias must be the same as spi device driver name */ 172 .modalias = "m25p80", /* Name of spi_driver for this device */ 173 /* this value is the baudrate divisor */ 174 .max_speed_hz = 50000000, /* actual baudrate is SCLK/(2xspeed_hz) */ 175 .bus_num = 0, /* Framework bus number */ 176 .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/ 177 .platform_data = &bfin_spi_flash_data, 178 .controller_data = &spi_flash_chip_info, 179 .mode = SPI_MODE_3, 180 }, 181#endif 182 183#if IS_ENABLED(CONFIG_SND_BF5XX_SOC_AD183X) 184 { 185 .modalias = "ad183x", 186 .max_speed_hz = 16, 187 .bus_num = 1, 188 .chip_select = 4, 189 }, 190#endif 191 192}; 193 194/* SPI (0) */ 195static struct resource bfin_spi0_resource[] = { 196 [0] = { 197 .start = SPI0_REGBASE, 198 .end = SPI0_REGBASE + 0xFF, 199 .flags = IORESOURCE_MEM, 200 }, 201 [1] = { 202 .start = CH_SPI, 203 .end = CH_SPI, 204 .flags = IORESOURCE_DMA, 205 }, 206 [2] = { 207 .start = IRQ_SPI, 208 .end = IRQ_SPI, 209 .flags = IORESOURCE_IRQ, 210 } 211}; 212 213 214/* SPI controller data */ 215static struct bfin5xx_spi_master bfin_spi0_info = { 216 .num_chipselect = 8, 217 .enable_dma = 1, /* master has the ability to do dma transfer */ 218 .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, 219}; 220 221static struct platform_device bfin_spi0_device = { 222 .name = "bfin-spi", 223 .id = 0, /* Bus number */ 224 .num_resources = ARRAY_SIZE(bfin_spi0_resource), 225 .resource = bfin_spi0_resource, 226 .dev = { 227 .platform_data = &bfin_spi0_info, /* Passed to driver */ 228 }, 229}; 230#endif /* spi master and devices */ 231 232#if IS_ENABLED(CONFIG_SERIAL_BFIN) 233#ifdef CONFIG_SERIAL_BFIN_UART0 234static struct resource bfin_uart0_resources[] = { 235 { 236 .start = BFIN_UART_THR, 237 .end = BFIN_UART_GCTL+2, 238 .flags = IORESOURCE_MEM, 239 }, 240 { 241 .start = IRQ_UART0_TX, 242 .end = IRQ_UART0_TX, 243 .flags = IORESOURCE_IRQ, 244 }, 245 { 246 .start = IRQ_UART0_RX, 247 .end = IRQ_UART0_RX, 248 .flags = IORESOURCE_IRQ, 249 }, 250 { 251 .start = IRQ_UART0_ERROR, 252 .end = IRQ_UART0_ERROR, 253 .flags = IORESOURCE_IRQ, 254 }, 255 { 256 .start = CH_UART0_TX, 257 .end = CH_UART0_TX, 258 .flags = IORESOURCE_DMA, 259 }, 260 { 261 .start = CH_UART0_RX, 262 .end = CH_UART0_RX, 263 .flags = IORESOURCE_DMA, 264 }, 265}; 266 267static unsigned short bfin_uart0_peripherals[] = { 268 P_UART0_TX, P_UART0_RX, 0 269}; 270 271static struct platform_device bfin_uart0_device = { 272 .name = "bfin-uart", 273 .id = 0, 274 .num_resources = ARRAY_SIZE(bfin_uart0_resources), 275 .resource = bfin_uart0_resources, 276 .dev = { 277 .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ 278 }, 279}; 280#endif 281#endif 282 283#if IS_ENABLED(CONFIG_BFIN_SIR) 284#ifdef CONFIG_BFIN_SIR0 285static struct resource bfin_sir0_resources[] = { 286 { 287 .start = 0xFFC00400, 288 .end = 0xFFC004FF, 289 .flags = IORESOURCE_MEM, 290 }, 291 { 292 .start = IRQ_UART0_RX, 293 .end = IRQ_UART0_RX+1, 294 .flags = IORESOURCE_IRQ, 295 }, 296 { 297 .start = CH_UART0_RX, 298 .end = CH_UART0_RX+1, 299 .flags = IORESOURCE_DMA, 300 }, 301}; 302 303static struct platform_device bfin_sir0_device = { 304 .name = "bfin_sir", 305 .id = 0, 306 .num_resources = ARRAY_SIZE(bfin_sir0_resources), 307 .resource = bfin_sir0_resources, 308}; 309#endif 310#endif 311 312#if IS_ENABLED(CONFIG_SERIAL_8250) 313 314#include <linux/serial_8250.h> 315#include <linux/serial.h> 316 317/* 318 * Configuration for two 16550 UARTS in FPGA at addresses 0x20200000 and 0x202000010. 319 * running at half system clock, both with interrupt output or-ed to PF8. Change to 320 * suit different FPGA configuration, or to suit real 16550 UARTS connected to the bus 321 */ 322 323static struct plat_serial8250_port serial8250_platform_data [] = { 324 { 325 .membase = (void *)0x20200000, 326 .mapbase = 0x20200000, 327 .irq = IRQ_PF8, 328 .irqflags = IRQF_TRIGGER_HIGH, 329 .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE, 330 .iotype = UPIO_MEM, 331 .regshift = 1, 332 .uartclk = 66666667, 333 }, { 334 .membase = (void *)0x20200010, 335 .mapbase = 0x20200010, 336 .irq = IRQ_PF8, 337 .irqflags = IRQF_TRIGGER_HIGH, 338 .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE, 339 .iotype = UPIO_MEM, 340 .regshift = 1, 341 .uartclk = 66666667, 342 }, { 343 } 344}; 345 346static struct platform_device serial8250_device = { 347 .id = PLAT8250_DEV_PLATFORM, 348 .name = "serial8250", 349 .dev = { 350 .platform_data = serial8250_platform_data, 351 }, 352}; 353 354#endif 355 356#if IS_ENABLED(CONFIG_KEYBOARD_OPENCORES) 357 358/* 359 * Configuration for one OpenCores keyboard controller in FPGA at address 0x20200030, 360 * interrupt output wired to PF9. Change to suit different FPGA configuration 361 */ 362 363static struct resource opencores_kbd_resources[] = { 364 [0] = { 365 .start = 0x20200030, 366 .end = 0x20300030 + 2, 367 .flags = IORESOURCE_MEM, 368 }, 369 [1] = { 370 .start = IRQ_PF9, 371 .end = IRQ_PF9, 372 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 373 }, 374}; 375 376static struct platform_device opencores_kbd_device = { 377 .id = -1, 378 .name = "opencores-kbd", 379 .resource = opencores_kbd_resources, 380 .num_resources = ARRAY_SIZE(opencores_kbd_resources), 381}; 382#endif 383 384static struct platform_device *h8606_devices[] __initdata = { 385#if IS_ENABLED(CONFIG_RTC_DRV_BFIN) 386 &rtc_device, 387#endif 388 389#if IS_ENABLED(CONFIG_DM9000) 390 &dm9000_device, 391#endif 392 393#if IS_ENABLED(CONFIG_SMC91X) 394 &smc91x_device, 395#endif 396 397#if IS_ENABLED(CONFIG_USB_NET2272) 398 &net2272_bfin_device, 399#endif 400 401#if IS_ENABLED(CONFIG_SPI_BFIN5XX) 402 &bfin_spi0_device, 403#endif 404 405#if IS_ENABLED(CONFIG_SERIAL_BFIN) 406#ifdef CONFIG_SERIAL_BFIN_UART0 407 &bfin_uart0_device, 408#endif 409#endif 410 411#if IS_ENABLED(CONFIG_SERIAL_8250) 412 &serial8250_device, 413#endif 414 415#if IS_ENABLED(CONFIG_BFIN_SIR) 416#ifdef CONFIG_BFIN_SIR0 417 &bfin_sir0_device, 418#endif 419#endif 420 421#if IS_ENABLED(CONFIG_KEYBOARD_OPENCORES) 422 &opencores_kbd_device, 423#endif 424}; 425 426static int __init H8606_init(void) 427{ 428 printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n"); 429 printk(KERN_INFO "%s(): registering device resources\n", __func__); 430 platform_add_devices(h8606_devices, ARRAY_SIZE(h8606_devices)); 431#if IS_ENABLED(CONFIG_SPI_BFIN5XX) 432 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 433#endif 434 return 0; 435} 436 437arch_initcall(H8606_init); 438 439static struct platform_device *H8606_early_devices[] __initdata = { 440#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) 441#ifdef CONFIG_SERIAL_BFIN_UART0 442 &bfin_uart0_device, 443#endif 444#endif 445}; 446 447void __init native_machine_early_platform_add_devices(void) 448{ 449 printk(KERN_INFO "register early platform devices\n"); 450 early_platform_add_devices(H8606_early_devices, 451 ARRAY_SIZE(H8606_early_devices)); 452} 453