mx31pdk.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. #include <linux/types.h>
  19. #include <linux/init.h>
  20. #include <linux/clk.h>
  21. #include <linux/irq.h>
  22. #include <linux/gpio.h>
  23. #include <mach/hardware.h>
  24. #include <asm/mach-types.h>
  25. #include <asm/mach/arch.h>
  26. #include <asm/mach/time.h>
  27. #include <asm/memory.h>
  28. #include <asm/mach/map.h>
  29. #include <mach/common.h>
  30. #include <mach/board-mx31pdk.h>
  31. #include <mach/imx-uart.h>
  32. #include <mach/iomux-mx3.h>
  33. #include "devices.h"
  34. /*!
  35. * @file mx31pdk.c
  36. *
  37. * @brief This file contains the board-specific initialization routines.
  38. *
  39. * @ingroup System
  40. */
  41. static int mx31pdk_pins[] = {
  42. /* UART1 */
  43. MX31_PIN_CTS1__CTS1,
  44. MX31_PIN_RTS1__RTS1,
  45. MX31_PIN_TXD1__TXD1,
  46. MX31_PIN_RXD1__RXD1,
  47. IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
  48. };
  49. static struct imxuart_platform_data uart_pdata = {
  50. .flags = IMXUART_HAVE_RTSCTS,
  51. };
  52. /*
  53. * Routines for the CPLD on the debug board. It contains a CPLD handling
  54. * LEDs, switches, interrupts for Ethernet.
  55. */
  56. static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
  57. {
  58. uint32_t imr_val;
  59. uint32_t int_valid;
  60. uint32_t expio_irq;
  61. imr_val = __raw_readw(CPLD_INT_MASK_REG);
  62. int_valid = __raw_readw(CPLD_INT_STATUS_REG) & ~imr_val;
  63. expio_irq = MXC_EXP_IO_BASE;
  64. for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
  65. if ((int_valid & 1) == 0)
  66. continue;
  67. generic_handle_irq(expio_irq);
  68. }
  69. }
  70. /*
  71. * Disable an expio pin's interrupt by setting the bit in the imr.
  72. * @param irq an expio virtual irq number
  73. */
  74. static void expio_mask_irq(uint32_t irq)
  75. {
  76. uint16_t reg;
  77. uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
  78. /* mask the interrupt */
  79. reg = __raw_readw(CPLD_INT_MASK_REG);
  80. reg |= 1 << expio;
  81. __raw_writew(reg, CPLD_INT_MASK_REG);
  82. }
  83. /*
  84. * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
  85. * @param irq an expanded io virtual irq number
  86. */
  87. static void expio_ack_irq(uint32_t irq)
  88. {
  89. uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
  90. /* clear the interrupt status */
  91. __raw_writew(1 << expio, CPLD_INT_RESET_REG);
  92. __raw_writew(0, CPLD_INT_RESET_REG);
  93. /* mask the interrupt */
  94. expio_mask_irq(irq);
  95. }
  96. /*
  97. * Enable a expio pin's interrupt by clearing the bit in the imr.
  98. * @param irq a expio virtual irq number
  99. */
  100. static void expio_unmask_irq(uint32_t irq)
  101. {
  102. uint16_t reg;
  103. uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
  104. /* unmask the interrupt */
  105. reg = __raw_readw(CPLD_INT_MASK_REG);
  106. reg &= ~(1 << expio);
  107. __raw_writew(reg, CPLD_INT_MASK_REG);
  108. }
  109. static struct irq_chip expio_irq_chip = {
  110. .ack = expio_ack_irq,
  111. .mask = expio_mask_irq,
  112. .unmask = expio_unmask_irq,
  113. };
  114. static int __init mx31pdk_init_expio(void)
  115. {
  116. int i;
  117. int ret;
  118. /* Check if there's a debug board connected */
  119. if ((__raw_readw(CPLD_MAGIC_NUMBER1_REG) != 0xAAAA) ||
  120. (__raw_readw(CPLD_MAGIC_NUMBER2_REG) != 0x5555) ||
  121. (__raw_readw(CPLD_MAGIC_NUMBER3_REG) != 0xCAFE)) {
  122. /* No Debug board found */
  123. return -ENODEV;
  124. }
  125. pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
  126. __raw_readw(CPLD_CODE_VER_REG));
  127. /*
  128. * Configure INT line as GPIO input
  129. */
  130. ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "sms9217-irq");
  131. if (ret)
  132. pr_warning("could not get LAN irq gpio\n");
  133. else
  134. gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
  135. /* Disable the interrupts and clear the status */
  136. __raw_writew(0, CPLD_INT_MASK_REG);
  137. __raw_writew(0xFFFF, CPLD_INT_RESET_REG);
  138. __raw_writew(0, CPLD_INT_RESET_REG);
  139. __raw_writew(0x1F, CPLD_INT_MASK_REG);
  140. for (i = MXC_EXP_IO_BASE;
  141. i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
  142. i++) {
  143. set_irq_chip(i, &expio_irq_chip);
  144. set_irq_handler(i, handle_level_irq);
  145. set_irq_flags(i, IRQF_VALID);
  146. }
  147. set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
  148. set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
  149. return 0;
  150. }
  151. /*
  152. * This structure defines the MX31 memory map.
  153. */
  154. static struct map_desc mx31pdk_io_desc[] __initdata = {
  155. {
  156. .virtual = SPBA0_BASE_ADDR_VIRT,
  157. .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
  158. .length = SPBA0_SIZE,
  159. .type = MT_DEVICE_NONSHARED,
  160. }, {
  161. .virtual = CS5_BASE_ADDR_VIRT,
  162. .pfn = __phys_to_pfn(CS5_BASE_ADDR),
  163. .length = CS5_SIZE,
  164. .type = MT_DEVICE,
  165. },
  166. };
  167. /*
  168. * Set up static virtual mappings.
  169. */
  170. static void __init mx31pdk_map_io(void)
  171. {
  172. mx31_map_io();
  173. iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
  174. }
  175. /*!
  176. * Board specific initialization.
  177. */
  178. static void __init mxc_board_init(void)
  179. {
  180. mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
  181. "mx31pdk");
  182. mxc_register_device(&mxc_uart_device0, &uart_pdata);
  183. mx31pdk_init_expio();
  184. }
  185. static void __init mx31pdk_timer_init(void)
  186. {
  187. mx31_clocks_init(26000000);
  188. }
  189. static struct sys_timer mx31pdk_timer = {
  190. .init = mx31pdk_timer_init,
  191. };
  192. /*
  193. * The following uses standard kernel macros defined in arch.h in order to
  194. * initialize __mach_desc_MX31PDK data structure.
  195. */
  196. MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
  197. /* Maintainer: Freescale Semiconductor, Inc. */
  198. .phys_io = AIPS1_BASE_ADDR,
  199. .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
  200. .boot_params = PHYS_OFFSET + 0x100,
  201. .map_io = mx31pdk_map_io,
  202. .init_irq = mxc_init_irq,
  203. .init_machine = mxc_board_init,
  204. .timer = &mx31pdk_timer,
  205. MACHINE_END