pxa2xx_gpio.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /*
  2. * Intel XScale PXA255/270 GPIO controller emulation.
  3. *
  4. * Copyright (c) 2006 Openedhand Ltd.
  5. * Written by Andrzej Zaborowski <balrog@zabor.org>
  6. *
  7. * This code is licensed under the GPL.
  8. */
  9. #include "hw.h"
  10. #include "pxa.h"
  11. #define PXA2XX_GPIO_BANKS 4
  12. struct pxa2xx_gpio_info_s {
  13. qemu_irq *pic;
  14. int lines;
  15. CPUState *cpu_env;
  16. qemu_irq *in;
  17. /* XXX: GNU C vectors are more suitable */
  18. uint32_t ilevel[PXA2XX_GPIO_BANKS];
  19. uint32_t olevel[PXA2XX_GPIO_BANKS];
  20. uint32_t dir[PXA2XX_GPIO_BANKS];
  21. uint32_t rising[PXA2XX_GPIO_BANKS];
  22. uint32_t falling[PXA2XX_GPIO_BANKS];
  23. uint32_t status[PXA2XX_GPIO_BANKS];
  24. uint32_t gpsr[PXA2XX_GPIO_BANKS];
  25. uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
  26. uint32_t prev_level[PXA2XX_GPIO_BANKS];
  27. qemu_irq handler[PXA2XX_GPIO_BANKS * 32];
  28. qemu_irq read_notify;
  29. };
  30. static struct {
  31. enum {
  32. GPIO_NONE,
  33. GPLR,
  34. GPSR,
  35. GPCR,
  36. GPDR,
  37. GRER,
  38. GFER,
  39. GEDR,
  40. GAFR_L,
  41. GAFR_U,
  42. } reg;
  43. int bank;
  44. } pxa2xx_gpio_regs[0x200] = {
  45. [0 ... 0x1ff] = { GPIO_NONE, 0 },
  46. #define PXA2XX_REG(reg, a0, a1, a2, a3) \
  47. [a0] = { reg, 0 }, [a1] = { reg, 1 }, [a2] = { reg, 2 }, [a3] = { reg, 3 },
  48. PXA2XX_REG(GPLR, 0x000, 0x004, 0x008, 0x100)
  49. PXA2XX_REG(GPSR, 0x018, 0x01c, 0x020, 0x118)
  50. PXA2XX_REG(GPCR, 0x024, 0x028, 0x02c, 0x124)
  51. PXA2XX_REG(GPDR, 0x00c, 0x010, 0x014, 0x10c)
  52. PXA2XX_REG(GRER, 0x030, 0x034, 0x038, 0x130)
  53. PXA2XX_REG(GFER, 0x03c, 0x040, 0x044, 0x13c)
  54. PXA2XX_REG(GEDR, 0x048, 0x04c, 0x050, 0x148)
  55. PXA2XX_REG(GAFR_L, 0x054, 0x05c, 0x064, 0x06c)
  56. PXA2XX_REG(GAFR_U, 0x058, 0x060, 0x068, 0x070)
  57. };
  58. static void pxa2xx_gpio_irq_update(struct pxa2xx_gpio_info_s *s)
  59. {
  60. if (s->status[0] & (1 << 0))
  61. qemu_irq_raise(s->pic[PXA2XX_PIC_GPIO_0]);
  62. else
  63. qemu_irq_lower(s->pic[PXA2XX_PIC_GPIO_0]);
  64. if (s->status[0] & (1 << 1))
  65. qemu_irq_raise(s->pic[PXA2XX_PIC_GPIO_1]);
  66. else
  67. qemu_irq_lower(s->pic[PXA2XX_PIC_GPIO_1]);
  68. if ((s->status[0] & ~3) | s->status[1] | s->status[2] | s->status[3])
  69. qemu_irq_raise(s->pic[PXA2XX_PIC_GPIO_X]);
  70. else
  71. qemu_irq_lower(s->pic[PXA2XX_PIC_GPIO_X]);
  72. }
  73. /* Bitmap of pins used as standby and sleep wake-up sources. */
  74. static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
  75. 0x8003fe1b, 0x002001fc, 0xec080000, 0x0012007f,
  76. };
  77. static void pxa2xx_gpio_set(void *opaque, int line, int level)
  78. {
  79. struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
  80. int bank;
  81. uint32_t mask;
  82. if (line >= s->lines) {
  83. printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
  84. return;
  85. }
  86. bank = line >> 5;
  87. mask = 1 << (line & 31);
  88. if (level) {
  89. s->status[bank] |= s->rising[bank] & mask &
  90. ~s->ilevel[bank] & ~s->dir[bank];
  91. s->ilevel[bank] |= mask;
  92. } else {
  93. s->status[bank] |= s->falling[bank] & mask &
  94. s->ilevel[bank] & ~s->dir[bank];
  95. s->ilevel[bank] &= ~mask;
  96. }
  97. if (s->status[bank] & mask)
  98. pxa2xx_gpio_irq_update(s);
  99. /* Wake-up GPIOs */
  100. if (s->cpu_env->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank]))
  101. cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
  102. }
  103. static void pxa2xx_gpio_handler_update(struct pxa2xx_gpio_info_s *s) {
  104. uint32_t level, diff;
  105. int i, bit, line;
  106. for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
  107. level = s->olevel[i] & s->dir[i];
  108. for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
  109. bit = ffs(diff) - 1;
  110. line = bit + 32 * i;
  111. qemu_set_irq(s->handler[line], (level >> bit) & 1);
  112. }
  113. s->prev_level[i] = level;
  114. }
  115. }
  116. static uint32_t pxa2xx_gpio_read(void *opaque, target_phys_addr_t offset)
  117. {
  118. struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
  119. uint32_t ret;
  120. int bank;
  121. if (offset >= 0x200)
  122. return 0;
  123. bank = pxa2xx_gpio_regs[offset].bank;
  124. switch (pxa2xx_gpio_regs[offset].reg) {
  125. case GPDR: /* GPIO Pin-Direction registers */
  126. return s->dir[bank];
  127. case GPSR: /* GPIO Pin-Output Set registers */
  128. printf("%s: Read from a write-only register " REG_FMT "\n",
  129. __FUNCTION__, offset);
  130. return s->gpsr[bank]; /* Return last written value. */
  131. case GPCR: /* GPIO Pin-Output Clear registers */
  132. printf("%s: Read from a write-only register " REG_FMT "\n",
  133. __FUNCTION__, offset);
  134. return 31337; /* Specified as unpredictable in the docs. */
  135. case GRER: /* GPIO Rising-Edge Detect Enable registers */
  136. return s->rising[bank];
  137. case GFER: /* GPIO Falling-Edge Detect Enable registers */
  138. return s->falling[bank];
  139. case GAFR_L: /* GPIO Alternate Function registers */
  140. return s->gafr[bank * 2];
  141. case GAFR_U: /* GPIO Alternate Function registers */
  142. return s->gafr[bank * 2 + 1];
  143. case GPLR: /* GPIO Pin-Level registers */
  144. ret = (s->olevel[bank] & s->dir[bank]) |
  145. (s->ilevel[bank] & ~s->dir[bank]);
  146. qemu_irq_raise(s->read_notify);
  147. return ret;
  148. case GEDR: /* GPIO Edge Detect Status registers */
  149. return s->status[bank];
  150. default:
  151. cpu_abort(cpu_single_env,
  152. "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
  153. }
  154. return 0;
  155. }
  156. static void pxa2xx_gpio_write(void *opaque,
  157. target_phys_addr_t offset, uint32_t value)
  158. {
  159. struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
  160. int bank;
  161. if (offset >= 0x200)
  162. return;
  163. bank = pxa2xx_gpio_regs[offset].bank;
  164. switch (pxa2xx_gpio_regs[offset].reg) {
  165. case GPDR: /* GPIO Pin-Direction registers */
  166. s->dir[bank] = value;
  167. pxa2xx_gpio_handler_update(s);
  168. break;
  169. case GPSR: /* GPIO Pin-Output Set registers */
  170. s->olevel[bank] |= value;
  171. pxa2xx_gpio_handler_update(s);
  172. s->gpsr[bank] = value;
  173. break;
  174. case GPCR: /* GPIO Pin-Output Clear registers */
  175. s->olevel[bank] &= ~value;
  176. pxa2xx_gpio_handler_update(s);
  177. break;
  178. case GRER: /* GPIO Rising-Edge Detect Enable registers */
  179. s->rising[bank] = value;
  180. break;
  181. case GFER: /* GPIO Falling-Edge Detect Enable registers */
  182. s->falling[bank] = value;
  183. break;
  184. case GAFR_L: /* GPIO Alternate Function registers */
  185. s->gafr[bank * 2] = value;
  186. break;
  187. case GAFR_U: /* GPIO Alternate Function registers */
  188. s->gafr[bank * 2 + 1] = value;
  189. break;
  190. case GEDR: /* GPIO Edge Detect Status registers */
  191. s->status[bank] &= ~value;
  192. pxa2xx_gpio_irq_update(s);
  193. break;
  194. default:
  195. cpu_abort(cpu_single_env,
  196. "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
  197. }
  198. }
  199. static CPUReadMemoryFunc *pxa2xx_gpio_readfn[] = {
  200. pxa2xx_gpio_read,
  201. pxa2xx_gpio_read,
  202. pxa2xx_gpio_read
  203. };
  204. static CPUWriteMemoryFunc *pxa2xx_gpio_writefn[] = {
  205. pxa2xx_gpio_write,
  206. pxa2xx_gpio_write,
  207. pxa2xx_gpio_write
  208. };
  209. static void pxa2xx_gpio_save(QEMUFile *f, void *opaque)
  210. {
  211. struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
  212. int i;
  213. qemu_put_be32(f, s->lines);
  214. for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
  215. qemu_put_be32s(f, &s->ilevel[i]);
  216. qemu_put_be32s(f, &s->olevel[i]);
  217. qemu_put_be32s(f, &s->dir[i]);
  218. qemu_put_be32s(f, &s->rising[i]);
  219. qemu_put_be32s(f, &s->falling[i]);
  220. qemu_put_be32s(f, &s->status[i]);
  221. qemu_put_be32s(f, &s->gafr[i * 2 + 0]);
  222. qemu_put_be32s(f, &s->gafr[i * 2 + 1]);
  223. qemu_put_be32s(f, &s->prev_level[i]);
  224. }
  225. }
  226. static int pxa2xx_gpio_load(QEMUFile *f, void *opaque, int version_id)
  227. {
  228. struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
  229. int i;
  230. if (qemu_get_be32(f) != s->lines)
  231. return -EINVAL;
  232. for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
  233. qemu_get_be32s(f, &s->ilevel[i]);
  234. qemu_get_be32s(f, &s->olevel[i]);
  235. qemu_get_be32s(f, &s->dir[i]);
  236. qemu_get_be32s(f, &s->rising[i]);
  237. qemu_get_be32s(f, &s->falling[i]);
  238. qemu_get_be32s(f, &s->status[i]);
  239. qemu_get_be32s(f, &s->gafr[i * 2 + 0]);
  240. qemu_get_be32s(f, &s->gafr[i * 2 + 1]);
  241. qemu_get_be32s(f, &s->prev_level[i]);
  242. }
  243. return 0;
  244. }
  245. struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base,
  246. CPUState *env, qemu_irq *pic, int lines)
  247. {
  248. int iomemtype;
  249. struct pxa2xx_gpio_info_s *s;
  250. s = (struct pxa2xx_gpio_info_s *)
  251. qemu_mallocz(sizeof(struct pxa2xx_gpio_info_s));
  252. memset(s, 0, sizeof(struct pxa2xx_gpio_info_s));
  253. s->pic = pic;
  254. s->lines = lines;
  255. s->cpu_env = env;
  256. s->in = qemu_allocate_irqs(pxa2xx_gpio_set, s, lines);
  257. iomemtype = cpu_register_io_memory(0, pxa2xx_gpio_readfn,
  258. pxa2xx_gpio_writefn, s);
  259. cpu_register_physical_memory(base, 0x00001000, iomemtype);
  260. register_savevm("pxa2xx_gpio", 0, 0,
  261. pxa2xx_gpio_save, pxa2xx_gpio_load, s);
  262. return s;
  263. }
  264. qemu_irq *pxa2xx_gpio_in_get(struct pxa2xx_gpio_info_s *s)
  265. {
  266. return s->in;
  267. }
  268. void pxa2xx_gpio_out_set(struct pxa2xx_gpio_info_s *s,
  269. int line, qemu_irq handler)
  270. {
  271. if (line >= s->lines) {
  272. printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
  273. return;
  274. }
  275. s->handler[line] = handler;
  276. }
  277. /*
  278. * Registers a callback to notify on GPLR reads. This normally
  279. * shouldn't be needed but it is used for the hack on Spitz machines.
  280. */
  281. void pxa2xx_gpio_read_notifier(struct pxa2xx_gpio_info_s *s, qemu_irq handler)
  282. {
  283. s->read_notify = handler;
  284. }