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.platform_data = FEC_PDATA, 139 }; 140 141 #ifdef MCFFEC_BASE1 142 static struct resource mcf_fec1_resources[] = { 143 { 144 .start = MCFFEC_BASE1, 145 .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1, 146 .flags = IORESOURCE_MEM, 147 }, 148 { 149 .start = MCF_IRQ_FECRX1, 150 .end = MCF_IRQ_FECRX1, 151 .flags = IORESOURCE_IRQ, 152 }, 153 { 154 .start = MCF_IRQ_FECTX1, 155 .end = MCF_IRQ_FECTX1, 156 .flags = IORESOURCE_IRQ, 157 }, 158 { 159 .start = MCF_IRQ_FECENTC1, 160 .end = MCF_IRQ_FECENTC1, 161 .flags = IORESOURCE_IRQ, 162 }, 163 }; 164 165 static struct platform_device mcf_fec1 = { 166 .name = FEC_NAME, 167 .id = 1, 168 .num_resources = ARRAY_SIZE(mcf_fec1_resources), 169 .resource = mcf_fec1_resources, 170 .dev.platform_data = FEC_PDATA, 171 }; 172 #endif /* MCFFEC_BASE1 */ 173 #endif /* CONFIG_FEC */ 174 175 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) 176 /* 177 * The ColdFire QSPI module is an SPI protocol hardware block used 178 * on a number of different ColdFire CPUs. 179 */ 180 static struct resource mcf_qspi_resources[] = { 181 { 182 .start = MCFQSPI_BASE, 183 .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1, 184 .flags = IORESOURCE_MEM, 185 }, 186 { 187 .start = MCF_IRQ_QSPI, 188 .end = MCF_IRQ_QSPI, 189 .flags = IORESOURCE_IRQ, 190 }, 191 }; 192 193 static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control) 194 { 195 int status; 196 197 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); 198 if (status) { 199 pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); 200 goto fail0; 201 } 202 status = gpio_direction_output(MCFQSPI_CS0, 1); 203 if (status) { 204 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); 205 goto fail1; 206 } 207 208 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); 209 if (status) { 210 pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); 211 goto fail1; 212 } 213 status = gpio_direction_output(MCFQSPI_CS1, 1); 214 if (status) { 215 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); 216 goto fail2; 217 } 218 219 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); 220 if (status) { 221 pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); 222 goto fail2; 223 } 224 status = gpio_direction_output(MCFQSPI_CS2, 1); 225 if (status) { 226 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); 227 goto fail3; 228 } 229 230 #ifdef MCFQSPI_CS3 231 status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); 232 if (status) { 233 pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); 234 goto fail3; 235 } 236 status = gpio_direction_output(MCFQSPI_CS3, 1); 237 if (status) { 238 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); 239 gpio_free(MCFQSPI_CS3); 240 goto fail3; 241 } 242 #endif 243 244 return 0; 245 246 fail3: 247 gpio_free(MCFQSPI_CS2); 248 fail2: 249 gpio_free(MCFQSPI_CS1); 250 fail1: 251 gpio_free(MCFQSPI_CS0); 252 fail0: 253 return status; 254 } 255 256 static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control) 257 { 258 #ifdef MCFQSPI_CS3 259 gpio_free(MCFQSPI_CS3); 260 #endif 261 gpio_free(MCFQSPI_CS2); 262 gpio_free(MCFQSPI_CS1); 263 gpio_free(MCFQSPI_CS0); 264 } 265 266 static void mcf_cs_select(struct mcfqspi_cs_control *cs_control, 267 u8 chip_select, bool cs_high) 268 { 269 switch (chip_select) { 270 case 0: 271 gpio_set_value(MCFQSPI_CS0, cs_high); 272 break; 273 case 1: 274 gpio_set_value(MCFQSPI_CS1, cs_high); 275 break; 276 case 2: 277 gpio_set_value(MCFQSPI_CS2, cs_high); 278 break; 279 #ifdef MCFQSPI_CS3 280 case 3: 281 gpio_set_value(MCFQSPI_CS3, cs_high); 282 break; 283 #endif 284 } 285 } 286 287 static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control, 288 u8 chip_select, bool cs_high) 289 { 290 switch (chip_select) { 291 case 0: 292 gpio_set_value(MCFQSPI_CS0, !cs_high); 293 break; 294 case 1: 295 gpio_set_value(MCFQSPI_CS1, !cs_high); 296 break; 297 case 2: 298 gpio_set_value(MCFQSPI_CS2, !cs_high); 299 break; 300 #ifdef MCFQSPI_CS3 301 case 3: 302 gpio_set_value(MCFQSPI_CS3, !cs_high); 303 break; 304 #endif 305 } 306 } 307 308 static struct mcfqspi_cs_control mcf_cs_control = { 309 .setup = mcf_cs_setup, 310 .teardown = mcf_cs_teardown, 311 .select = mcf_cs_select, 312 .deselect = mcf_cs_deselect, 313 }; 314 315 static struct mcfqspi_platform_data mcf_qspi_data = { 316 .bus_num = 0, 317 .num_chipselect = 4, 318 .cs_control = &mcf_cs_control, 319 }; 320 321 static struct platform_device mcf_qspi = { 322 .name = "mcfqspi", 323 .id = 0, 324 .num_resources = ARRAY_SIZE(mcf_qspi_resources), 325 .resource = mcf_qspi_resources, 326 .dev.platform_data = &mcf_qspi_data, 327 }; 328 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ 329 330 static struct platform_device *mcf_devices[] __initdata = { 331 &mcf_uart, 332 #if IS_ENABLED(CONFIG_FEC) 333 &mcf_fec0, 334 #ifdef MCFFEC_BASE1 335 &mcf_fec1, 336 #endif 337 #endif 338 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) 339 &mcf_qspi, 340 #endif 341 }; 342 343 /* 344 * Some ColdFire UARTs let you set the IRQ line to use. 345 */ 346 static void __init mcf_uart_set_irq(void) 347 { 348 #ifdef MCFUART_UIVR 349 /* UART0 interrupt setup */ 350 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR); 351 writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR); 352 mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0); 353 354 /* UART1 interrupt setup */ 355 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR); 356 writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR); 357 mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1); 358 #endif 359 } 360 361 static int __init mcf_init_devices(void) 362 { 363 mcf_uart_set_irq(); 364 platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices)); 365 return 0; 366 } 367 368 arch_initcall(mcf_init_devices); 369 370