common.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * linux/arch/arm/mach-h720x/common.c
  3. *
  4. * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
  5. * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
  6. * 2004 Sascha Hauer <s.hauer@pengutronix.de>
  7. *
  8. * common stuff for Hynix h720x processors
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. *
  14. */
  15. #include <linux/sched.h>
  16. #include <linux/mman.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/io.h>
  20. #include <asm/page.h>
  21. #include <asm/pgtable.h>
  22. #include <asm/dma.h>
  23. #include <mach/hardware.h>
  24. #include <asm/irq.h>
  25. #include <asm/system_misc.h>
  26. #include <asm/mach/irq.h>
  27. #include <asm/mach/map.h>
  28. #include <mach/irqs.h>
  29. #include <asm/mach/dma.h>
  30. #if 0
  31. #define IRQDBG(args...) printk(args)
  32. #else
  33. #define IRQDBG(args...) do {} while(0)
  34. #endif
  35. void __init arch_dma_init(dma_t *dma)
  36. {
  37. }
  38. /*
  39. * Return usecs since last timer reload
  40. * (timercount * (usecs perjiffie)) / (ticks per jiffie)
  41. */
  42. unsigned long h720x_gettimeoffset(void)
  43. {
  44. return (CPU_REG (TIMER_VIRT, TM0_COUNT) * tick_usec) / LATCH;
  45. }
  46. /*
  47. * mask Global irq's
  48. */
  49. static void mask_global_irq(struct irq_data *d)
  50. {
  51. CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << d->irq);
  52. }
  53. /*
  54. * unmask Global irq's
  55. */
  56. static void unmask_global_irq(struct irq_data *d)
  57. {
  58. CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << d->irq);
  59. }
  60. /*
  61. * ack GPIO irq's
  62. * Ack only for edge triggered int's valid
  63. */
  64. static void inline ack_gpio_irq(struct irq_data *d)
  65. {
  66. u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
  67. u32 bit = IRQ_TO_BIT(d->irq);
  68. if ( (CPU_REG (reg_base, GPIO_EDGE) & bit))
  69. CPU_REG (reg_base, GPIO_CLR) = bit;
  70. }
  71. /*
  72. * mask GPIO irq's
  73. */
  74. static void inline mask_gpio_irq(struct irq_data *d)
  75. {
  76. u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
  77. u32 bit = IRQ_TO_BIT(d->irq);
  78. CPU_REG (reg_base, GPIO_MASK) &= ~bit;
  79. }
  80. /*
  81. * unmask GPIO irq's
  82. */
  83. static void inline unmask_gpio_irq(struct irq_data *d)
  84. {
  85. u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
  86. u32 bit = IRQ_TO_BIT(d->irq);
  87. CPU_REG (reg_base, GPIO_MASK) |= bit;
  88. }
  89. static void
  90. h720x_gpio_handler(unsigned int mask, unsigned int irq,
  91. struct irq_desc *desc)
  92. {
  93. IRQDBG("%s irq: %d\n", __func__, irq);
  94. while (mask) {
  95. if (mask & 1) {
  96. IRQDBG("handling irq %d\n", irq);
  97. generic_handle_irq(irq);
  98. }
  99. irq++;
  100. mask >>= 1;
  101. }
  102. }
  103. static void
  104. h720x_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
  105. {
  106. unsigned int mask, irq;
  107. mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT);
  108. irq = IRQ_CHAINED_GPIOA(0);
  109. IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
  110. h720x_gpio_handler(mask, irq, desc);
  111. }
  112. static void
  113. h720x_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
  114. {
  115. unsigned int mask, irq;
  116. mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT);
  117. irq = IRQ_CHAINED_GPIOB(0);
  118. IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
  119. h720x_gpio_handler(mask, irq, desc);
  120. }
  121. static void
  122. h720x_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
  123. {
  124. unsigned int mask, irq;
  125. mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT);
  126. irq = IRQ_CHAINED_GPIOC(0);
  127. IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
  128. h720x_gpio_handler(mask, irq, desc);
  129. }
  130. static void
  131. h720x_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
  132. {
  133. unsigned int mask, irq;
  134. mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT);
  135. irq = IRQ_CHAINED_GPIOD(0);
  136. IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
  137. h720x_gpio_handler(mask, irq, desc);
  138. }
  139. #ifdef CONFIG_CPU_H7202
  140. static void
  141. h720x_gpioe_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
  142. {
  143. unsigned int mask, irq;
  144. mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT);
  145. irq = IRQ_CHAINED_GPIOE(0);
  146. IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
  147. h720x_gpio_handler(mask, irq, desc);
  148. }
  149. #endif
  150. static struct irq_chip h720x_global_chip = {
  151. .irq_ack = mask_global_irq,
  152. .irq_mask = mask_global_irq,
  153. .irq_unmask = unmask_global_irq,
  154. };
  155. static struct irq_chip h720x_gpio_chip = {
  156. .irq_ack = ack_gpio_irq,
  157. .irq_mask = mask_gpio_irq,
  158. .irq_unmask = unmask_gpio_irq,
  159. };
  160. /*
  161. * Initialize IRQ's, mask all, enable multiplexed irq's
  162. */
  163. void __init h720x_init_irq (void)
  164. {
  165. int irq;
  166. /* Mask global irq's */
  167. CPU_REG (IRQC_VIRT, IRQC_IER) = 0x0;
  168. /* Mask all multiplexed irq's */
  169. CPU_REG (GPIO_A_VIRT, GPIO_MASK) = 0x0;
  170. CPU_REG (GPIO_B_VIRT, GPIO_MASK) = 0x0;
  171. CPU_REG (GPIO_C_VIRT, GPIO_MASK) = 0x0;
  172. CPU_REG (GPIO_D_VIRT, GPIO_MASK) = 0x0;
  173. /* Initialize global IRQ's, fast path */
  174. for (irq = 0; irq < NR_GLBL_IRQS; irq++) {
  175. irq_set_chip_and_handler(irq, &h720x_global_chip,
  176. handle_level_irq);
  177. set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
  178. }
  179. /* Initialize multiplexed IRQ's, slow path */
  180. for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) {
  181. irq_set_chip_and_handler(irq, &h720x_gpio_chip,
  182. handle_edge_irq);
  183. set_irq_flags(irq, IRQF_VALID );
  184. }
  185. irq_set_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler);
  186. irq_set_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler);
  187. irq_set_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler);
  188. irq_set_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler);
  189. #ifdef CONFIG_CPU_H7202
  190. for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) {
  191. irq_set_chip_and_handler(irq, &h720x_gpio_chip,
  192. handle_edge_irq);
  193. set_irq_flags(irq, IRQF_VALID );
  194. }
  195. irq_set_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler);
  196. #endif
  197. /* Enable multiplexed irq's */
  198. CPU_REG (IRQC_VIRT, IRQC_IER) = IRQ_ENA_MUX;
  199. }
  200. static struct map_desc h720x_io_desc[] __initdata = {
  201. {
  202. .virtual = IO_VIRT,
  203. .pfn = __phys_to_pfn(IO_PHYS),
  204. .length = IO_SIZE,
  205. .type = MT_DEVICE
  206. },
  207. };
  208. /* Initialize io tables */
  209. void __init h720x_map_io(void)
  210. {
  211. iotable_init(h720x_io_desc,ARRAY_SIZE(h720x_io_desc));
  212. }
  213. void h720x_restart(char mode, const char *cmd)
  214. {
  215. CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET;
  216. }
  217. static void h720x__idle(void)
  218. {
  219. CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
  220. nop();
  221. nop();
  222. CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
  223. nop();
  224. nop();
  225. }
  226. static int __init h720x_idle_init(void)
  227. {
  228. arm_pm_idle = h720x__idle;
  229. return 0;
  230. }
  231. arch_initcall(h720x_idle_init);