config.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /***************************************************************************/
  2. /*
  3. * linux/arch/m68knommu/platform/528x/config.c
  4. *
  5. * Sub-architcture dependent initialization code for the Freescale
  6. * 5280, 5281 and 5282 CPUs.
  7. *
  8. * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
  9. * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
  10. */
  11. /***************************************************************************/
  12. #include <linux/kernel.h>
  13. #include <linux/param.h>
  14. #include <linux/init.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/io.h>
  17. #include <linux/spi/spi.h>
  18. #include <linux/gpio.h>
  19. #include <asm/machdep.h>
  20. #include <asm/coldfire.h>
  21. #include <asm/mcfsim.h>
  22. #include <asm/mcfuart.h>
  23. #include <asm/mcfqspi.h>
  24. /***************************************************************************/
  25. static struct mcf_platform_uart m528x_uart_platform[] = {
  26. {
  27. .mapbase = MCFUART_BASE1,
  28. .irq = MCFINT_VECBASE + MCFINT_UART0,
  29. },
  30. {
  31. .mapbase = MCFUART_BASE2,
  32. .irq = MCFINT_VECBASE + MCFINT_UART0 + 1,
  33. },
  34. {
  35. .mapbase = MCFUART_BASE3,
  36. .irq = MCFINT_VECBASE + MCFINT_UART0 + 2,
  37. },
  38. { },
  39. };
  40. static struct platform_device m528x_uart = {
  41. .name = "mcfuart",
  42. .id = 0,
  43. .dev.platform_data = m528x_uart_platform,
  44. };
  45. static struct resource m528x_fec_resources[] = {
  46. {
  47. .start = MCFFEC_BASE,
  48. .end = MCFFEC_BASE + MCFFEC_SIZE - 1,
  49. .flags = IORESOURCE_MEM,
  50. },
  51. {
  52. .start = 64 + 23,
  53. .end = 64 + 23,
  54. .flags = IORESOURCE_IRQ,
  55. },
  56. {
  57. .start = 64 + 27,
  58. .end = 64 + 27,
  59. .flags = IORESOURCE_IRQ,
  60. },
  61. {
  62. .start = 64 + 29,
  63. .end = 64 + 29,
  64. .flags = IORESOURCE_IRQ,
  65. },
  66. };
  67. static struct platform_device m528x_fec = {
  68. .name = "fec",
  69. .id = 0,
  70. .num_resources = ARRAY_SIZE(m528x_fec_resources),
  71. .resource = m528x_fec_resources,
  72. };
  73. #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
  74. static struct resource m528x_qspi_resources[] = {
  75. {
  76. .start = MCFQSPI_IOBASE,
  77. .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
  78. .flags = IORESOURCE_MEM,
  79. },
  80. {
  81. .start = MCFINT_VECBASE + MCFINT_QSPI,
  82. .end = MCFINT_VECBASE + MCFINT_QSPI,
  83. .flags = IORESOURCE_IRQ,
  84. },
  85. };
  86. #define MCFQSPI_CS0 147
  87. #define MCFQSPI_CS1 148
  88. #define MCFQSPI_CS2 149
  89. #define MCFQSPI_CS3 150
  90. static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
  91. {
  92. int status;
  93. status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
  94. if (status) {
  95. pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
  96. goto fail0;
  97. }
  98. status = gpio_direction_output(MCFQSPI_CS0, 1);
  99. if (status) {
  100. pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
  101. goto fail1;
  102. }
  103. status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
  104. if (status) {
  105. pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
  106. goto fail1;
  107. }
  108. status = gpio_direction_output(MCFQSPI_CS1, 1);
  109. if (status) {
  110. pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
  111. goto fail2;
  112. }
  113. status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
  114. if (status) {
  115. pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
  116. goto fail2;
  117. }
  118. status = gpio_direction_output(MCFQSPI_CS2, 1);
  119. if (status) {
  120. pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
  121. goto fail3;
  122. }
  123. status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
  124. if (status) {
  125. pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
  126. goto fail3;
  127. }
  128. status = gpio_direction_output(MCFQSPI_CS3, 1);
  129. if (status) {
  130. pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
  131. goto fail4;
  132. }
  133. return 0;
  134. fail4:
  135. gpio_free(MCFQSPI_CS3);
  136. fail3:
  137. gpio_free(MCFQSPI_CS2);
  138. fail2:
  139. gpio_free(MCFQSPI_CS1);
  140. fail1:
  141. gpio_free(MCFQSPI_CS0);
  142. fail0:
  143. return status;
  144. }
  145. static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
  146. {
  147. gpio_free(MCFQSPI_CS3);
  148. gpio_free(MCFQSPI_CS2);
  149. gpio_free(MCFQSPI_CS1);
  150. gpio_free(MCFQSPI_CS0);
  151. }
  152. static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
  153. u8 chip_select, bool cs_high)
  154. {
  155. gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
  156. }
  157. static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
  158. u8 chip_select, bool cs_high)
  159. {
  160. gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
  161. }
  162. static struct mcfqspi_cs_control m528x_cs_control = {
  163. .setup = m528x_cs_setup,
  164. .teardown = m528x_cs_teardown,
  165. .select = m528x_cs_select,
  166. .deselect = m528x_cs_deselect,
  167. };
  168. static struct mcfqspi_platform_data m528x_qspi_data = {
  169. .bus_num = 0,
  170. .num_chipselect = 4,
  171. .cs_control = &m528x_cs_control,
  172. };
  173. static struct platform_device m528x_qspi = {
  174. .name = "mcfqspi",
  175. .id = 0,
  176. .num_resources = ARRAY_SIZE(m528x_qspi_resources),
  177. .resource = m528x_qspi_resources,
  178. .dev.platform_data = &m528x_qspi_data,
  179. };
  180. static void __init m528x_qspi_init(void)
  181. {
  182. /* setup Port QS for QSPI with gpio CS control */
  183. __raw_writeb(0x07, MCFGPIO_PQSPAR);
  184. }
  185. #endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
  186. static struct platform_device *m528x_devices[] __initdata = {
  187. &m528x_uart,
  188. &m528x_fec,
  189. #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
  190. &m528x_qspi,
  191. #endif
  192. };
  193. /***************************************************************************/
  194. static void __init m528x_uart_init_line(int line, int irq)
  195. {
  196. u8 port;
  197. if ((line < 0) || (line > 2))
  198. return;
  199. /* make sure PUAPAR is set for UART0 and UART1 */
  200. if (line < 2) {
  201. port = readb(MCF5282_GPIO_PUAPAR);
  202. port |= (0x03 << (line * 2));
  203. writeb(port, MCF5282_GPIO_PUAPAR);
  204. }
  205. }
  206. static void __init m528x_uarts_init(void)
  207. {
  208. const int nrlines = ARRAY_SIZE(m528x_uart_platform);
  209. int line;
  210. for (line = 0; (line < nrlines); line++)
  211. m528x_uart_init_line(line, m528x_uart_platform[line].irq);
  212. }
  213. /***************************************************************************/
  214. static void __init m528x_fec_init(void)
  215. {
  216. u16 v16;
  217. /* Set multi-function pins to ethernet mode for fec0 */
  218. v16 = readw(MCF_IPSBAR + 0x100056);
  219. writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
  220. writeb(0xc0, MCF_IPSBAR + 0x100058);
  221. }
  222. /***************************************************************************/
  223. static void m528x_cpu_reset(void)
  224. {
  225. local_irq_disable();
  226. __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
  227. }
  228. /***************************************************************************/
  229. #ifdef CONFIG_WILDFIRE
  230. void wildfire_halt(void)
  231. {
  232. writeb(0, 0x30000007);
  233. writeb(0x2, 0x30000007);
  234. }
  235. #endif
  236. #ifdef CONFIG_WILDFIREMOD
  237. void wildfiremod_halt(void)
  238. {
  239. printk(KERN_INFO "WildFireMod hibernating...\n");
  240. /* Set portE.5 to Digital IO */
  241. MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
  242. /* Make portE.5 an output */
  243. MCF5282_GPIO_DDRE |= (1 << 5);
  244. /* Now toggle portE.5 from low to high */
  245. MCF5282_GPIO_PORTE &= ~(1 << 5);
  246. MCF5282_GPIO_PORTE |= (1 << 5);
  247. printk(KERN_EMERG "Failed to hibernate. Halting!\n");
  248. }
  249. #endif
  250. void __init config_BSP(char *commandp, int size)
  251. {
  252. #ifdef CONFIG_WILDFIRE
  253. mach_halt = wildfire_halt;
  254. #endif
  255. #ifdef CONFIG_WILDFIREMOD
  256. mach_halt = wildfiremod_halt;
  257. #endif
  258. }
  259. /***************************************************************************/
  260. static int __init init_BSP(void)
  261. {
  262. mach_reset = m528x_cpu_reset;
  263. m528x_uarts_init();
  264. m528x_fec_init();
  265. #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
  266. m528x_qspi_init();
  267. #endif
  268. platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
  269. return 0;
  270. }
  271. arch_initcall(init_BSP);
  272. /***************************************************************************/