1 /* 2 * device.c -- common ColdFire SoC device support 3 * 4 * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org> 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/io.h> 14 #include <linux/spi/spi.h> 15 #include <linux/gpio.h> 16 #include <linux/fec.h> 17 #include <asm/traps.h> 18 #include <asm/coldfire.h> 19 #include <asm/mcfsim.h> 20 #include <asm/mcfuart.h> 21 #include <asm/mcfqspi.h> 22 23 /* 24 * All current ColdFire parts contain from 2, 3, 4 or 10 UARTS. 25 */ 26 static struct mcf_platform_uart mcf_uart_platform_data[] = { 27 { 28 .mapbase = MCFUART_BASE0, 29 .irq = MCF_IRQ_UART0, 30 }, 31 { 32 .mapbase = MCFUART_BASE1, 33 .irq = MCF_IRQ_UART1, 34 }, 35 #ifdef MCFUART_BASE2 36 { 37 .mapbase = MCFUART_BASE2, 38 .irq = MCF_IRQ_UART2, 39 }, 40 #endif 41 #ifdef MCFUART_BASE3 42 { 43 .mapbase = MCFUART_BASE3, 44 .irq = MCF_IRQ_UART3, 45 }, 46 #endif 47 #ifdef MCFUART_BASE4 48 { 49 .mapbase = MCFUART_BASE4, 50 .irq = MCF_IRQ_UART4, 51 }, 52 #endif 53 #ifdef MCFUART_BASE5 54 { 55 .mapbase = MCFUART_BASE5, 56 .irq = MCF_IRQ_UART5, 57 }, 58 #endif 59 #ifdef MCFUART_BASE6 60 { 61 .mapbase = MCFUART_BASE6, 62 .irq = MCF_IRQ_UART6, 63 }, 64 #endif 65 #ifdef MCFUART_BASE7 66 { 67 .mapbase = MCFUART_BASE7, 68 .irq = MCF_IRQ_UART7, 69 }, 70 #endif 71 #ifdef MCFUART_BASE8 72 { 73 .mapbase = MCFUART_BASE8, 74 .irq = MCF_IRQ_UART8, 75 }, 76 #endif 77 #ifdef MCFUART_BASE9 78 { 79 .mapbase = MCFUART_BASE9, 80 .irq = MCF_IRQ_UART9, 81 }, 82 #endif 83 { }, 84 }; 85 86 static struct platform_device mcf_uart = { 87 .name = "mcfuart", 88 .id = 0, 89 .dev.platform_data = mcf_uart_platform_data, 90 }; 91 92 #if IS_ENABLED(CONFIG_FEC) 93 94 #ifdef CONFIG_M5441x 95 #define FEC_NAME "enet-fec" 96 static struct fec_platform_data fec_pdata = { 97 .phy = PHY_INTERFACE_MODE_RMII, 98 }; 99 #define FEC_PDATA (&fec_pdata) 100 #else 101 #define FEC_NAME "fec" 102 #define FEC_PDATA NULL 103 #endif 104 105 /* 106 * Some ColdFire cores contain the Fast Ethernet Controller (FEC) 107 * block. It is Freescale's own hardware block. Some ColdFires 108 * have 2 of these. 109 */ 110 static struct resource mcf_fec0_resources[] = { 111 { 112 .start = MCFFEC_BASE0, 113 .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1, 114 .flags = IORESOURCE_MEM, 115 }, 116 { 117 .start = MCF_IRQ_FECRX0, 118 .end = MCF_IRQ_FECRX0, 119 .flags = IORESOURCE_IRQ, 120 }, 121 { 122 .start = MCF_IRQ_FECTX0, 123 .end = MCF_IRQ_FECTX0, 124 .flags = IORESOURCE_IRQ, 125 }, 126 { 127 .start = MCF_IRQ_FECENTC0, 128 .end = MCF_IRQ_FECENTC0, 129 .flags = IORESOURCE_IRQ, 130 }, 131 }; 132 133 static struct platform_device mcf_fec0 = { 134 .name = FEC_NAME, 135 .id = 0, 136 .num_resources = ARRAY_SIZE(mcf_fec0_resources), 137 .resource = mcf_fec0_resources, 138 .dev = { 139 .dma_mask = &mcf_fec0.dev.coherent_dma_mask, 140 .coherent_dma_mask = DMA_BIT_MASK(32), 141 .platform_data = FEC_PDATA, 142 } 143 }; 144 145 #ifdef MCFFEC_BASE1 146 static struct resource mcf_fec1_resources[] = { 147 { 148 .start = MCFFEC_BASE1, 149 .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1, 150 .flags = IORESOURCE_MEM, 151 }, 152 { 153 .start = MCF_IRQ_FECRX1, 154 .end = MCF_IRQ_FECRX1, 155 .flags = IORESOURCE_IRQ, 156 }, 157 { 158 .start = MCF_IRQ_FECTX1, 159 .end = MCF_IRQ_FECTX1, 160 .flags = IORESOURCE_IRQ, 161 }, 162 { 163 .start = MCF_IRQ_FECENTC1, 164 .end = MCF_IRQ_FECENTC1, 165 .flags = IORESOURCE_IRQ, 166 }, 167 }; 168 169 static struct platform_device mcf_fec1 = { 170 .name = FEC_NAME, 171 .id = 1, 172 .num_resources = ARRAY_SIZE(mcf_fec1_resources), 173 .resource = mcf_fec1_resources, 174 .dev = { 175 .dma_mask = &mcf_fec1.dev.coherent_dma_mask, 176 .coherent_dma_mask = DMA_BIT_MASK(32), 177 .platform_data = FEC_PDATA, 178 } 179 }; 180 #endif /* MCFFEC_BASE1 */ 181 #endif /* CONFIG_FEC */ 182 183 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) 184 /* 185 * The ColdFire QSPI module is an SPI protocol hardware block used 186 * on a number of different ColdFire CPUs. 187 */ 188 static struct resource mcf_qspi_resources[] = { 189 { 190 .start = MCFQSPI_BASE, 191 .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1, 192 .flags = IORESOURCE_MEM, 193 }, 194 { 195 .start = MCF_IRQ_QSPI, 196 .end = MCF_IRQ_QSPI, 197 .flags = IORESOURCE_IRQ, 198 }, 199 }; 200 201 static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control) 202 { 203 int status; 204 205 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); 206 if (status) { 207 pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); 208 goto fail0; 209 } 210 status = gpio_direction_output(MCFQSPI_CS0, 1); 211 if (status) { 212 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); 213 goto fail1; 214 } 215 216 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); 217 if (status) { 218 pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); 219 goto fail1; 220 } 221 status = gpio_direction_output(MCFQSPI_CS1, 1); 222 if (status) { 223 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); 224 goto fail2; 225 } 226 227 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); 228 if (status) { 229 pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); 230 goto fail2; 231 } 232 status = gpio_direction_output(MCFQSPI_CS2, 1); 233 if (status) { 234 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); 235 goto fail3; 236 } 237 238 #ifdef MCFQSPI_CS3 239 status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); 240 if (status) { 241 pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); 242 goto fail3; 243 } 244 status = gpio_direction_output(MCFQSPI_CS3, 1); 245 if (status) { 246 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); 247 gpio_free(MCFQSPI_CS3); 248 goto fail3; 249 } 250 #endif 251 252 return 0; 253 254 fail3: 255 gpio_free(MCFQSPI_CS2); 256 fail2: 257 gpio_free(MCFQSPI_CS1); 258 fail1: 259 gpio_free(MCFQSPI_CS0); 260 fail0: 261 return status; 262 } 263 264 static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control) 265 { 266 #ifdef MCFQSPI_CS3 267 gpio_free(MCFQSPI_CS3); 268 #endif 269 gpio_free(MCFQSPI_CS2); 270 gpio_free(MCFQSPI_CS1); 271 gpio_free(MCFQSPI_CS0); 272 } 273 274 static void mcf_cs_select(struct mcfqspi_cs_control *cs_control, 275 u8 chip_select, bool cs_high) 276 { 277 switch (chip_select) { 278 case 0: 279 gpio_set_value(MCFQSPI_CS0, cs_high); 280 break; 281 case 1: 282 gpio_set_value(MCFQSPI_CS1, cs_high); 283 break; 284 case 2: 285 gpio_set_value(MCFQSPI_CS2, cs_high); 286 break; 287 #ifdef MCFQSPI_CS3 288 case 3: 289 gpio_set_value(MCFQSPI_CS3, cs_high); 290 break; 291 #endif 292 } 293 } 294 295 static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control, 296 u8 chip_select, bool cs_high) 297 { 298 switch (chip_select) { 299 case 0: 300 gpio_set_value(MCFQSPI_CS0, !cs_high); 301 break; 302 case 1: 303 gpio_set_value(MCFQSPI_CS1, !cs_high); 304 break; 305 case 2: 306 gpio_set_value(MCFQSPI_CS2, !cs_high); 307 break; 308 #ifdef MCFQSPI_CS3 309 case 3: 310 gpio_set_value(MCFQSPI_CS3, !cs_high); 311 break; 312 #endif 313 } 314 } 315 316 static struct mcfqspi_cs_control mcf_cs_control = { 317 .setup = mcf_cs_setup, 318 .teardown = mcf_cs_teardown, 319 .select = mcf_cs_select, 320 .deselect = mcf_cs_deselect, 321 }; 322 323 static struct mcfqspi_platform_data mcf_qspi_data = { 324 .bus_num = 0, 325 .num_chipselect = 4, 326 .cs_control = &mcf_cs_control, 327 }; 328 329 static struct platform_device mcf_qspi = { 330 .name = "mcfqspi", 331 .id = 0, 332 .num_resources = ARRAY_SIZE(mcf_qspi_resources), 333 .resource = mcf_qspi_resources, 334 .dev.platform_data = &mcf_qspi_data, 335 }; 336 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ 337 338 #if IS_ENABLED(CONFIG_I2C_IMX) 339 static struct resource mcf_i2c0_resources[] = { 340 { 341 .start = MCFI2C_BASE0, 342 .end = MCFI2C_BASE0 + MCFI2C_SIZE0 - 1, 343 .flags = IORESOURCE_MEM, 344 }, 345 { 346 .start = MCF_IRQ_I2C0, 347 .end = MCF_IRQ_I2C0, 348 .flags = IORESOURCE_IRQ, 349 }, 350 }; 351 352 static struct platform_device mcf_i2c0 = { 353 .name = "imx1-i2c", 354 .id = 0, 355 .num_resources = ARRAY_SIZE(mcf_i2c0_resources), 356 .resource = mcf_i2c0_resources, 357 }; 358 #ifdef MCFI2C_BASE1 359 360 static struct resource mcf_i2c1_resources[] = { 361 { 362 .start = MCFI2C_BASE1, 363 .end = MCFI2C_BASE1 + MCFI2C_SIZE1 - 1, 364 .flags = IORESOURCE_MEM, 365 }, 366 { 367 .start = MCF_IRQ_I2C1, 368 .end = MCF_IRQ_I2C1, 369 .flags = IORESOURCE_IRQ, 370 }, 371 }; 372 373 static struct platform_device mcf_i2c1 = { 374 .name = "imx1-i2c", 375 .id = 1, 376 .num_resources = ARRAY_SIZE(mcf_i2c1_resources), 377 .resource = mcf_i2c1_resources, 378 }; 379 380 #endif /* MCFI2C_BASE1 */ 381 382 #ifdef MCFI2C_BASE2 383 384 static struct resource mcf_i2c2_resources[] = { 385 { 386 .start = MCFI2C_BASE2, 387 .end = MCFI2C_BASE2 + MCFI2C_SIZE2 - 1, 388 .flags = IORESOURCE_MEM, 389 }, 390 { 391 .start = MCF_IRQ_I2C2, 392 .end = MCF_IRQ_I2C2, 393 .flags = IORESOURCE_IRQ, 394 }, 395 }; 396 397 static struct platform_device mcf_i2c2 = { 398 .name = "imx1-i2c", 399 .id = 2, 400 .num_resources = ARRAY_SIZE(mcf_i2c2_resources), 401 .resource = mcf_i2c2_resources, 402 }; 403 404 #endif /* MCFI2C_BASE2 */ 405 406 #ifdef MCFI2C_BASE3 407 408 static struct resource mcf_i2c3_resources[] = { 409 { 410 .start = MCFI2C_BASE3, 411 .end = MCFI2C_BASE3 + MCFI2C_SIZE3 - 1, 412 .flags = IORESOURCE_MEM, 413 }, 414 { 415 .start = MCF_IRQ_I2C3, 416 .end = MCF_IRQ_I2C3, 417 .flags = IORESOURCE_IRQ, 418 }, 419 }; 420 421 static struct platform_device mcf_i2c3 = { 422 .name = "imx1-i2c", 423 .id = 3, 424 .num_resources = ARRAY_SIZE(mcf_i2c3_resources), 425 .resource = mcf_i2c3_resources, 426 }; 427 428 #endif /* MCFI2C_BASE3 */ 429 430 #ifdef MCFI2C_BASE4 431 432 static struct resource mcf_i2c4_resources[] = { 433 { 434 .start = MCFI2C_BASE4, 435 .end = MCFI2C_BASE4 + MCFI2C_SIZE4 - 1, 436 .flags = IORESOURCE_MEM, 437 }, 438 { 439 .start = MCF_IRQ_I2C4, 440 .end = MCF_IRQ_I2C4, 441 .flags = IORESOURCE_IRQ, 442 }, 443 }; 444 445 static struct platform_device mcf_i2c4 = { 446 .name = "imx1-i2c", 447 .id = 4, 448 .num_resources = ARRAY_SIZE(mcf_i2c4_resources), 449 .resource = mcf_i2c4_resources, 450 }; 451 452 #endif /* MCFI2C_BASE4 */ 453 454 #ifdef MCFI2C_BASE5 455 456 static struct resource mcf_i2c5_resources[] = { 457 { 458 .start = MCFI2C_BASE5, 459 .end = MCFI2C_BASE5 + MCFI2C_SIZE5 - 1, 460 .flags = IORESOURCE_MEM, 461 }, 462 { 463 .start = MCF_IRQ_I2C5, 464 .end = MCF_IRQ_I2C5, 465 .flags = IORESOURCE_IRQ, 466 }, 467 }; 468 469 static struct platform_device mcf_i2c5 = { 470 .name = "imx1-i2c", 471 .id = 5, 472 .num_resources = ARRAY_SIZE(mcf_i2c5_resources), 473 .resource = mcf_i2c5_resources, 474 }; 475 476 #endif /* MCFI2C_BASE5 */ 477 #endif /* IS_ENABLED(CONFIG_I2C_IMX) */ 478 479 static struct platform_device *mcf_devices[] __initdata = { 480 &mcf_uart, 481 #if IS_ENABLED(CONFIG_FEC) 482 &mcf_fec0, 483 #ifdef MCFFEC_BASE1 484 &mcf_fec1, 485 #endif 486 #endif 487 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) 488 &mcf_qspi, 489 #endif 490 #if IS_ENABLED(CONFIG_I2C_IMX) 491 &mcf_i2c0, 492 #ifdef MCFI2C_BASE1 493 &mcf_i2c1, 494 #endif 495 #ifdef MCFI2C_BASE2 496 &mcf_i2c2, 497 #endif 498 #ifdef MCFI2C_BASE3 499 &mcf_i2c3, 500 #endif 501 #ifdef MCFI2C_BASE4 502 &mcf_i2c4, 503 #endif 504 #ifdef MCFI2C_BASE5 505 &mcf_i2c5, 506 #endif 507 #endif 508 }; 509 510 /* 511 * Some ColdFire UARTs let you set the IRQ line to use. 512 */ 513 static void __init mcf_uart_set_irq(void) 514 { 515 #ifdef MCFUART_UIVR 516 /* UART0 interrupt setup */ 517 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR); 518 writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR); 519 mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0); 520 521 /* UART1 interrupt setup */ 522 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR); 523 writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR); 524 mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1); 525 #endif 526 } 527 528 static int __init mcf_init_devices(void) 529 { 530 mcf_uart_set_irq(); 531 platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices)); 532 return 0; 533 } 534 535 arch_initcall(mcf_init_devices); 536 537