1/***************************************************************************/ 2 3/* 4 * linux/arch/m68knommu/platform/520x/config.c 5 * 6 * Copyright (C) 2005, Freescale (www.freescale.com) 7 * Copyright (C) 2005, Intec Automation (mike@steroidmicros.com) 8 * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) 9 * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) 10 */ 11 12/***************************************************************************/ 13 14#include <linux/kernel.h> 15#include <linux/param.h> 16#include <linux/init.h> 17#include <linux/io.h> 18#include <linux/spi/spi.h> 19#include <linux/gpio.h> 20#include <asm/machdep.h> 21#include <asm/coldfire.h> 22#include <asm/mcfsim.h> 23#include <asm/mcfuart.h> 24#include <asm/mcfqspi.h> 25 26/***************************************************************************/ 27 28static struct mcf_platform_uart m520x_uart_platform[] = { 29 { 30 .mapbase = MCF_MBAR + MCFUART_BASE1, 31 .irq = MCFINT_VECBASE + MCFINT_UART0, 32 }, 33 { 34 .mapbase = MCF_MBAR + MCFUART_BASE2, 35 .irq = MCFINT_VECBASE + MCFINT_UART1, 36 }, 37 { 38 .mapbase = MCF_MBAR + MCFUART_BASE3, 39 .irq = MCFINT_VECBASE + MCFINT_UART2, 40 }, 41 { }, 42}; 43 44static struct platform_device m520x_uart = { 45 .name = "mcfuart", 46 .id = 0, 47 .dev.platform_data = m520x_uart_platform, 48}; 49 50static struct resource m520x_fec_resources[] = { 51 { 52 .start = MCF_MBAR + 0x30000, 53 .end = MCF_MBAR + 0x30000 + 0x7ff, 54 .flags = IORESOURCE_MEM, 55 }, 56 { 57 .start = 64 + 36, 58 .end = 64 + 36, 59 .flags = IORESOURCE_IRQ, 60 }, 61 { 62 .start = 64 + 40, 63 .end = 64 + 40, 64 .flags = IORESOURCE_IRQ, 65 }, 66 { 67 .start = 64 + 42, 68 .end = 64 + 42, 69 .flags = IORESOURCE_IRQ, 70 }, 71}; 72 73static struct platform_device m520x_fec = { 74 .name = "fec", 75 .id = 0, 76 .num_resources = ARRAY_SIZE(m520x_fec_resources), 77 .resource = m520x_fec_resources, 78}; 79 80#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 81static struct resource m520x_qspi_resources[] = { 82 { 83 .start = MCFQSPI_IOBASE, 84 .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, 85 .flags = IORESOURCE_MEM, 86 }, 87 { 88 .start = MCFINT_VECBASE + MCFINT_QSPI, 89 .end = MCFINT_VECBASE + MCFINT_QSPI, 90 .flags = IORESOURCE_IRQ, 91 }, 92}; 93 94#define MCFQSPI_CS0 62 95#define MCFQSPI_CS1 63 96#define MCFQSPI_CS2 44 97 98static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control) 99{ 100 int status; 101 102 status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); 103 if (status) { 104 pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); 105 goto fail0; 106 } 107 status = gpio_direction_output(MCFQSPI_CS0, 1); 108 if (status) { 109 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); 110 goto fail1; 111 } 112 113 status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); 114 if (status) { 115 pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); 116 goto fail1; 117 } 118 status = gpio_direction_output(MCFQSPI_CS1, 1); 119 if (status) { 120 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); 121 goto fail2; 122 } 123 124 status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); 125 if (status) { 126 pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); 127 goto fail2; 128 } 129 status = gpio_direction_output(MCFQSPI_CS2, 1); 130 if (status) { 131 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); 132 goto fail3; 133 } 134 135 return 0; 136 137fail3: 138 gpio_free(MCFQSPI_CS2); 139fail2: 140 gpio_free(MCFQSPI_CS1); 141fail1: 142 gpio_free(MCFQSPI_CS0); 143fail0: 144 return status; 145} 146 147static void m520x_cs_teardown(struct mcfqspi_cs_control *cs_control) 148{ 149 gpio_free(MCFQSPI_CS2); 150 gpio_free(MCFQSPI_CS1); 151 gpio_free(MCFQSPI_CS0); 152} 153 154static void m520x_cs_select(struct mcfqspi_cs_control *cs_control, 155 u8 chip_select, bool cs_high) 156{ 157 switch (chip_select) { 158 case 0: 159 gpio_set_value(MCFQSPI_CS0, cs_high); 160 break; 161 case 1: 162 gpio_set_value(MCFQSPI_CS1, cs_high); 163 break; 164 case 2: 165 gpio_set_value(MCFQSPI_CS2, cs_high); 166 break; 167 } 168} 169 170static void m520x_cs_deselect(struct mcfqspi_cs_control *cs_control, 171 u8 chip_select, bool cs_high) 172{ 173 switch (chip_select) { 174 case 0: 175 gpio_set_value(MCFQSPI_CS0, !cs_high); 176 break; 177 case 1: 178 gpio_set_value(MCFQSPI_CS1, !cs_high); 179 break; 180 case 2: 181 gpio_set_value(MCFQSPI_CS2, !cs_high); 182 break; 183 } 184} 185 186static struct mcfqspi_cs_control m520x_cs_control = { 187 .setup = m520x_cs_setup, 188 .teardown = m520x_cs_teardown, 189 .select = m520x_cs_select, 190 .deselect = m520x_cs_deselect, 191}; 192 193static struct mcfqspi_platform_data m520x_qspi_data = { 194 .bus_num = 0, 195 .num_chipselect = 3, 196 .cs_control = &m520x_cs_control, 197}; 198 199static struct platform_device m520x_qspi = { 200 .name = "mcfqspi", 201 .id = 0, 202 .num_resources = ARRAY_SIZE(m520x_qspi_resources), 203 .resource = m520x_qspi_resources, 204 .dev.platform_data = &m520x_qspi_data, 205}; 206 207static void __init m520x_qspi_init(void) 208{ 209 u16 par; 210 /* setup Port QS for QSPI with gpio CS control */ 211 writeb(0x3f, MCF_IPSBAR + MCF_GPIO_PAR_QSPI); 212 /* make U1CTS and U2RTS gpio for cs_control */ 213 par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); 214 par &= 0x00ff; 215 writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART); 216} 217#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ 218 219 220static struct platform_device *m520x_devices[] __initdata = { 221 &m520x_uart, 222 &m520x_fec, 223#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 224 &m520x_qspi, 225#endif 226}; 227 228/***************************************************************************/ 229 230static void __init m520x_uart_init_line(int line, int irq) 231{ 232 u16 par; 233 u8 par2; 234 235 switch (line) { 236 case 0: 237 par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); 238 par |= MCF_GPIO_PAR_UART_PAR_UTXD0 | 239 MCF_GPIO_PAR_UART_PAR_URXD0; 240 writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART); 241 break; 242 case 1: 243 par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); 244 par |= MCF_GPIO_PAR_UART_PAR_UTXD1 | 245 MCF_GPIO_PAR_UART_PAR_URXD1; 246 writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART); 247 break; 248 case 2: 249 par2 = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); 250 par2 &= ~0x0F; 251 par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 | 252 MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; 253 writeb(par2, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); 254 break; 255 } 256} 257 258static void __init m520x_uarts_init(void) 259{ 260 const int nrlines = ARRAY_SIZE(m520x_uart_platform); 261 int line; 262 263 for (line = 0; (line < nrlines); line++) 264 m520x_uart_init_line(line, m520x_uart_platform[line].irq); 265} 266 267/***************************************************************************/ 268 269static void __init m520x_fec_init(void) 270{ 271 u8 v; 272 273 /* Set multi-function pins to ethernet mode */ 274 v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC); 275 writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC); 276 277 v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); 278 writeb(v | 0x0f, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); 279} 280 281/***************************************************************************/ 282 283static void m520x_cpu_reset(void) 284{ 285 local_irq_disable(); 286 __raw_writeb(MCF_RCR_SWRESET, MCF_RCR); 287} 288 289/***************************************************************************/ 290 291void __init config_BSP(char *commandp, int size) 292{ 293 mach_reset = m520x_cpu_reset; 294 m520x_uarts_init(); 295 m520x_fec_init(); 296#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) 297 m520x_qspi_init(); 298#endif 299} 300 301/***************************************************************************/ 302 303static int __init init_BSP(void) 304{ 305 platform_add_devices(m520x_devices, ARRAY_SIZE(m520x_devices)); 306 return 0; 307} 308 309arch_initcall(init_BSP); 310 311/***************************************************************************/ 312