1/***************************************************************************/ 2 3/* 4 * linux/arch/m68knommu/platform/527x/config.c 5 * 6 * Sub-architcture dependant initialization code for the Freescale 7 * 5270/5271 CPUs. 8 * 9 * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) 10 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) 11 */ 12 13/***************************************************************************/ 14 15#include <linux/kernel.h> 16#include <linux/param.h> 17#include <linux/init.h> 18#include <linux/io.h> 19#include <linux/spi/spi.h> 20#include <linux/gpio.h> 21#include <asm/machdep.h> 22#include <asm/coldfire.h> 23#include <asm/mcfsim.h> 24#include <asm/mcfuart.h> 25#include <asm/mcfqspi.h> 26 27/***************************************************************************/ 28 29static struct mcf_platform_uart m527x_uart_platform[] = { 30 { 31 .mapbase = MCF_MBAR + MCFUART_BASE1, 32 .irq = MCFINT_VECBASE + MCFINT_UART0, 33 }, 34 { 35 .mapbase = MCF_MBAR + MCFUART_BASE2, 36 .irq = MCFINT_VECBASE + MCFINT_UART1, 37 }, 38 { 39 .mapbase = MCF_MBAR + MCFUART_BASE3, 40 .irq = MCFINT_VECBASE + MCFINT_UART2, 41 }, 42 { }, 43}; 44 45static struct platform_device m527x_uart = { 46 .name = "mcfuart", 47 .id = 0, 48 .dev.platform_data = m527x_uart_platform, 49}; 50 51static struct resource m527x_fec0_resources[] = { 52 { 53 .start = MCF_MBAR + 0x1000, 54 .end = MCF_MBAR + 0x1000 + 0x7ff, 55 .flags = IORESOURCE_MEM, 56 }, 57 { 58 .start = 64 + 23, 59 .end = 64 + 23, 60 .flags = IORESOURCE_IRQ, 61 }, 62 { 63 .start = 64 + 27, 64 .end = 64 + 27, 65 .flags = IORESOURCE_IRQ, 66 }, 67 { 68 .start = 64 + 29, 69 .end = 64 + 29, 70 .flags = IORESOURCE_IRQ, 71 }, 72}; 73 74static struct resource m527x_fec1_resources[] = { 75 { 76 .start = MCF_MBAR + 0x1800, 77 .end = MCF_MBAR + 0x1800 + 0x7ff, 78 .flags = IORESOURCE_MEM, 79 }, 80 { 81 .start = 128 + 23, 82 .end = 128 + 23, 83 .flags = IORESOURCE_IRQ, 84 }, 85 { 86 .start = 128 + 27, 87 .end = 128 + 27, 88 .flags = IORESOURCE_IRQ, 89 }, 90 { 91 .start = 128 + 29, 92 .end = 128 + 29, 93 .flags = IORESOURCE_IRQ, 94 }, 95}; 96 97static struct platform_device m527x_fec[] = { 98 { 99 .name = "fec", 100 .id = 0, 101 .num_resources = ARRAY_SIZE(m527x_fec0_resources), 102 .resource = m527x_fec0_resources, 103 }, 104 { 105 .name = "fec", 106 .id = 1, 107 .num_resources = ARRAY_SIZE(m527x_fec1_resources), 108 .resource = m527x_fec1_resources, 109 }, 110}; 111 112#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 113static struct resource m527x_qspi_resources[] = { 114 { 115 .start = MCFQSPI_IOBASE, 116 .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, 117 .flags = IORESOURCE_MEM, 118 }, 119 { 120 .start = MCFINT_VECBASE + MCFINT_QSPI, 121 .end = MCFINT_VECBASE + MCFINT_QSPI, 122 .flags = IORESOURCE_IRQ, 123 }, 124}; 125 126#if defined(CONFIG_M5271) 127#define MCFQSPI_CS0 91 128#define MCFQSPI_CS1 92 129#define MCFQSPI_CS2 99 130#define MCFQSPI_CS3 103 131#elif defined(CONFIG_M5275) 132#define MCFQSPI_CS0 59 133#define MCFQSPI_CS1 60 134#define MCFQSPI_CS2 61 135#define MCFQSPI_CS3 62 136#endif 137 138static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control) 139{ 140 int status; 141 142 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); 143 if (status) { 144 pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); 145 goto fail0; 146 } 147 status = gpio_direction_output(MCFQSPI_CS0, 1); 148 if (status) { 149 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); 150 goto fail1; 151 } 152 153 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); 154 if (status) { 155 pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); 156 goto fail1; 157 } 158 status = gpio_direction_output(MCFQSPI_CS1, 1); 159 if (status) { 160 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); 161 goto fail2; 162 } 163 164 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); 165 if (status) { 166 pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); 167 goto fail2; 168 } 169 status = gpio_direction_output(MCFQSPI_CS2, 1); 170 if (status) { 171 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); 172 goto fail3; 173 } 174 175 status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); 176 if (status) { 177 pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); 178 goto fail3; 179 } 180 status = gpio_direction_output(MCFQSPI_CS3, 1); 181 if (status) { 182 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); 183 goto fail4; 184 } 185 186 return 0; 187 188fail4: 189 gpio_free(MCFQSPI_CS3); 190fail3: 191 gpio_free(MCFQSPI_CS2); 192fail2: 193 gpio_free(MCFQSPI_CS1); 194fail1: 195 gpio_free(MCFQSPI_CS0); 196fail0: 197 return status; 198} 199 200static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control) 201{ 202 gpio_free(MCFQSPI_CS3); 203 gpio_free(MCFQSPI_CS2); 204 gpio_free(MCFQSPI_CS1); 205 gpio_free(MCFQSPI_CS0); 206} 207 208static void m527x_cs_select(struct mcfqspi_cs_control *cs_control, 209 u8 chip_select, bool cs_high) 210{ 211 switch (chip_select) { 212 case 0: 213 gpio_set_value(MCFQSPI_CS0, cs_high); 214 break; 215 case 1: 216 gpio_set_value(MCFQSPI_CS1, cs_high); 217 break; 218 case 2: 219 gpio_set_value(MCFQSPI_CS2, cs_high); 220 break; 221 case 3: 222 gpio_set_value(MCFQSPI_CS3, cs_high); 223 break; 224 } 225} 226 227static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control, 228 u8 chip_select, bool cs_high) 229{ 230 switch (chip_select) { 231 case 0: 232 gpio_set_value(MCFQSPI_CS0, !cs_high); 233 break; 234 case 1: 235 gpio_set_value(MCFQSPI_CS1, !cs_high); 236 break; 237 case 2: 238 gpio_set_value(MCFQSPI_CS2, !cs_high); 239 break; 240 case 3: 241 gpio_set_value(MCFQSPI_CS3, !cs_high); 242 break; 243 } 244} 245 246static struct mcfqspi_cs_control m527x_cs_control = { 247 .setup = m527x_cs_setup, 248 .teardown = m527x_cs_teardown, 249 .select = m527x_cs_select, 250 .deselect = m527x_cs_deselect, 251}; 252 253static struct mcfqspi_platform_data m527x_qspi_data = { 254 .bus_num = 0, 255 .num_chipselect = 4, 256 .cs_control = &m527x_cs_control, 257}; 258 259static struct platform_device m527x_qspi = { 260 .name = "mcfqspi", 261 .id = 0, 262 .num_resources = ARRAY_SIZE(m527x_qspi_resources), 263 .resource = m527x_qspi_resources, 264 .dev.platform_data = &m527x_qspi_data, 265}; 266 267static void __init m527x_qspi_init(void) 268{ 269#if defined(CONFIG_M5271) 270 u16 par; 271 272 /* setup QSPS pins for QSPI with gpio CS control */ 273 writeb(0x1f, MCFGPIO_PAR_QSPI); 274 /* and CS2 & CS3 as gpio */ 275 par = readw(MCFGPIO_PAR_TIMER); 276 par &= 0x3f3f; 277 writew(par, MCFGPIO_PAR_TIMER); 278#elif defined(CONFIG_M5275) 279 /* setup QSPS pins for QSPI with gpio CS control */ 280 writew(0x003e, MCFGPIO_PAR_QSPI); 281#endif 282} 283#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ 284 285static struct platform_device *m527x_devices[] __initdata = { 286 &m527x_uart, 287 &m527x_fec[0], 288#ifdef CONFIG_FEC2 289 &m527x_fec[1], 290#endif 291#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 292 &m527x_qspi, 293#endif 294}; 295 296/***************************************************************************/ 297 298static void __init m527x_uart_init_line(int line, int irq) 299{ 300 u16 sepmask; 301 302 if ((line < 0) || (line > 2)) 303 return; 304 305 /* 306 * External Pin Mask Setting & Enable External Pin for Interface 307 */ 308 sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); 309 if (line == 0) 310 sepmask |= UART0_ENABLE_MASK; 311 else if (line == 1) 312 sepmask |= UART1_ENABLE_MASK; 313 else if (line == 2) 314 sepmask |= UART2_ENABLE_MASK; 315 writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART); 316} 317 318static void __init m527x_uarts_init(void) 319{ 320 const int nrlines = ARRAY_SIZE(m527x_uart_platform); 321 int line; 322 323 for (line = 0; (line < nrlines); line++) 324 m527x_uart_init_line(line, m527x_uart_platform[line].irq); 325} 326 327/***************************************************************************/ 328 329static void __init m527x_fec_init(void) 330{ 331 u16 par; 332 u8 v; 333 334 /* Set multi-function pins to ethernet mode for fec0 */ 335#if defined(CONFIG_M5271) 336 v = readb(MCF_IPSBAR + 0x100047); 337 writeb(v | 0xf0, MCF_IPSBAR + 0x100047); 338#else 339 par = readw(MCF_IPSBAR + 0x100082); 340 writew(par | 0xf00, MCF_IPSBAR + 0x100082); 341 v = readb(MCF_IPSBAR + 0x100078); 342 writeb(v | 0xc0, MCF_IPSBAR + 0x100078); 343#endif 344 345#ifdef CONFIG_FEC2 346 /* Set multi-function pins to ethernet mode for fec1 */ 347 par = readw(MCF_IPSBAR + 0x100082); 348 writew(par | 0xa0, MCF_IPSBAR + 0x100082); 349 v = readb(MCF_IPSBAR + 0x100079); 350 writeb(v | 0xc0, MCF_IPSBAR + 0x100079); 351#endif 352} 353 354/***************************************************************************/ 355 356static void m527x_cpu_reset(void) 357{ 358 local_irq_disable(); 359 __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); 360} 361 362/***************************************************************************/ 363 364void __init config_BSP(char *commandp, int size) 365{ 366 mach_reset = m527x_cpu_reset; 367 m527x_uarts_init(); 368 m527x_fec_init(); 369#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 370 m527x_qspi_init(); 371#endif 372} 373 374/***************************************************************************/ 375 376static int __init init_BSP(void) 377{ 378 platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices)); 379 return 0; 380} 381 382arch_initcall(init_BSP); 383 384/***************************************************************************/ 385