imx_gpio.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * i.MX processors GPIO emulation.
  3. *
  4. * Copyright (C) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 or
  9. * (at your option) version 3 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include "hw/gpio/imx_gpio.h"
  21. #include "hw/irq.h"
  22. #include "qemu/log.h"
  23. #include "qemu/module.h"
  24. #ifndef DEBUG_IMX_GPIO
  25. #define DEBUG_IMX_GPIO 0
  26. #endif
  27. typedef enum IMXGPIOLevel {
  28. IMX_GPIO_LEVEL_LOW = 0,
  29. IMX_GPIO_LEVEL_HIGH = 1,
  30. } IMXGPIOLevel;
  31. #define DPRINTF(fmt, args...) \
  32. do { \
  33. if (DEBUG_IMX_GPIO) { \
  34. fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPIO, \
  35. __func__, ##args); \
  36. } \
  37. } while (0)
  38. static const char *imx_gpio_reg_name(uint32_t reg)
  39. {
  40. switch (reg) {
  41. case DR_ADDR:
  42. return "DR";
  43. case GDIR_ADDR:
  44. return "GDIR";
  45. case PSR_ADDR:
  46. return "PSR";
  47. case ICR1_ADDR:
  48. return "ICR1";
  49. case ICR2_ADDR:
  50. return "ICR2";
  51. case IMR_ADDR:
  52. return "IMR";
  53. case ISR_ADDR:
  54. return "ISR";
  55. case EDGE_SEL_ADDR:
  56. return "EDGE_SEL";
  57. default:
  58. return "[?]";
  59. }
  60. }
  61. static void imx_gpio_update_int(IMXGPIOState *s)
  62. {
  63. if (s->has_upper_pin_irq) {
  64. qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x0000FFFF) ? 1 : 0);
  65. qemu_set_irq(s->irq[1], (s->isr & s->imr & 0xFFFF0000) ? 1 : 0);
  66. } else {
  67. qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0);
  68. }
  69. }
  70. static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level)
  71. {
  72. /* if this signal isn't configured as an input signal, nothing to do */
  73. if (!extract32(s->gdir, line, 1)) {
  74. return;
  75. }
  76. /* When set, EDGE_SEL overrides the ICR config */
  77. if (extract32(s->edge_sel, line, 1)) {
  78. /* we detect interrupt on rising and falling edge */
  79. if (extract32(s->psr, line, 1) != level) {
  80. /* level changed */
  81. s->isr = deposit32(s->isr, line, 1, 1);
  82. }
  83. } else if (extract64(s->icr, 2*line + 1, 1)) {
  84. /* interrupt is edge sensitive */
  85. if (extract32(s->psr, line, 1) != level) {
  86. /* level changed */
  87. if (extract64(s->icr, 2*line, 1) != level) {
  88. s->isr = deposit32(s->isr, line, 1, 1);
  89. }
  90. }
  91. } else {
  92. /* interrupt is level sensitive */
  93. if (extract64(s->icr, 2*line, 1) == level) {
  94. s->isr = deposit32(s->isr, line, 1, 1);
  95. }
  96. }
  97. }
  98. static void imx_gpio_set(void *opaque, int line, int level)
  99. {
  100. IMXGPIOState *s = IMX_GPIO(opaque);
  101. IMXGPIOLevel imx_level = level ? IMX_GPIO_LEVEL_HIGH : IMX_GPIO_LEVEL_LOW;
  102. imx_gpio_set_int_line(s, line, imx_level);
  103. /* this is an input signal, so set PSR */
  104. s->psr = deposit32(s->psr, line, 1, imx_level);
  105. imx_gpio_update_int(s);
  106. }
  107. static void imx_gpio_set_all_int_lines(IMXGPIOState *s)
  108. {
  109. int i;
  110. for (i = 0; i < IMX_GPIO_PIN_COUNT; i++) {
  111. IMXGPIOLevel imx_level = extract32(s->psr, i, 1);
  112. imx_gpio_set_int_line(s, i, imx_level);
  113. }
  114. imx_gpio_update_int(s);
  115. }
  116. static inline void imx_gpio_set_all_output_lines(IMXGPIOState *s)
  117. {
  118. int i;
  119. for (i = 0; i < IMX_GPIO_PIN_COUNT; i++) {
  120. /*
  121. * if the line is set as output, then forward the line
  122. * level to its user.
  123. */
  124. if (extract32(s->gdir, i, 1) && s->output[i]) {
  125. qemu_set_irq(s->output[i], extract32(s->dr, i, 1));
  126. }
  127. }
  128. }
  129. static uint64_t imx_gpio_read(void *opaque, hwaddr offset, unsigned size)
  130. {
  131. IMXGPIOState *s = IMX_GPIO(opaque);
  132. uint32_t reg_value = 0;
  133. switch (offset) {
  134. case DR_ADDR:
  135. /*
  136. * depending on the "line" configuration, the bit values
  137. * are coming either from DR or PSR
  138. */
  139. reg_value = (s->dr & s->gdir) | (s->psr & ~s->gdir);
  140. break;
  141. case GDIR_ADDR:
  142. reg_value = s->gdir;
  143. break;
  144. case PSR_ADDR:
  145. reg_value = s->psr & ~s->gdir;
  146. break;
  147. case ICR1_ADDR:
  148. reg_value = extract64(s->icr, 0, 32);
  149. break;
  150. case ICR2_ADDR:
  151. reg_value = extract64(s->icr, 32, 32);
  152. break;
  153. case IMR_ADDR:
  154. reg_value = s->imr;
  155. break;
  156. case ISR_ADDR:
  157. reg_value = s->isr;
  158. break;
  159. case EDGE_SEL_ADDR:
  160. if (s->has_edge_sel) {
  161. reg_value = s->edge_sel;
  162. } else {
  163. qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: EDGE_SEL register not "
  164. "present on this version of GPIO device\n",
  165. TYPE_IMX_GPIO, __func__);
  166. }
  167. break;
  168. default:
  169. qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
  170. HWADDR_PRIx "\n", TYPE_IMX_GPIO, __func__, offset);
  171. break;
  172. }
  173. DPRINTF("(%s) = 0x%" PRIx32 "\n", imx_gpio_reg_name(offset), reg_value);
  174. return reg_value;
  175. }
  176. static void imx_gpio_write(void *opaque, hwaddr offset, uint64_t value,
  177. unsigned size)
  178. {
  179. IMXGPIOState *s = IMX_GPIO(opaque);
  180. DPRINTF("(%s, value = 0x%" PRIx32 ")\n", imx_gpio_reg_name(offset),
  181. (uint32_t)value);
  182. switch (offset) {
  183. case DR_ADDR:
  184. s->dr = value;
  185. imx_gpio_set_all_output_lines(s);
  186. break;
  187. case GDIR_ADDR:
  188. s->gdir = value;
  189. imx_gpio_set_all_output_lines(s);
  190. imx_gpio_set_all_int_lines(s);
  191. break;
  192. case ICR1_ADDR:
  193. s->icr = deposit64(s->icr, 0, 32, value);
  194. imx_gpio_set_all_int_lines(s);
  195. break;
  196. case ICR2_ADDR:
  197. s->icr = deposit64(s->icr, 32, 32, value);
  198. imx_gpio_set_all_int_lines(s);
  199. break;
  200. case IMR_ADDR:
  201. s->imr = value;
  202. imx_gpio_update_int(s);
  203. break;
  204. case ISR_ADDR:
  205. s->isr &= ~value;
  206. imx_gpio_set_all_int_lines(s);
  207. break;
  208. case EDGE_SEL_ADDR:
  209. if (s->has_edge_sel) {
  210. s->edge_sel = value;
  211. imx_gpio_set_all_int_lines(s);
  212. } else {
  213. qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: EDGE_SEL register not "
  214. "present on this version of GPIO device\n",
  215. TYPE_IMX_GPIO, __func__);
  216. }
  217. break;
  218. default:
  219. qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
  220. HWADDR_PRIx "\n", TYPE_IMX_GPIO, __func__, offset);
  221. break;
  222. }
  223. return;
  224. }
  225. static const MemoryRegionOps imx_gpio_ops = {
  226. .read = imx_gpio_read,
  227. .write = imx_gpio_write,
  228. .valid.min_access_size = 4,
  229. .valid.max_access_size = 4,
  230. .endianness = DEVICE_NATIVE_ENDIAN,
  231. };
  232. static const VMStateDescription vmstate_imx_gpio = {
  233. .name = TYPE_IMX_GPIO,
  234. .version_id = 1,
  235. .minimum_version_id = 1,
  236. .minimum_version_id_old = 1,
  237. .fields = (VMStateField[]) {
  238. VMSTATE_UINT32(dr, IMXGPIOState),
  239. VMSTATE_UINT32(gdir, IMXGPIOState),
  240. VMSTATE_UINT32(psr, IMXGPIOState),
  241. VMSTATE_UINT64(icr, IMXGPIOState),
  242. VMSTATE_UINT32(imr, IMXGPIOState),
  243. VMSTATE_UINT32(isr, IMXGPIOState),
  244. VMSTATE_BOOL(has_edge_sel, IMXGPIOState),
  245. VMSTATE_UINT32(edge_sel, IMXGPIOState),
  246. VMSTATE_END_OF_LIST()
  247. }
  248. };
  249. static Property imx_gpio_properties[] = {
  250. DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel, true),
  251. DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState, has_upper_pin_irq,
  252. false),
  253. DEFINE_PROP_END_OF_LIST(),
  254. };
  255. static void imx_gpio_reset(DeviceState *dev)
  256. {
  257. IMXGPIOState *s = IMX_GPIO(dev);
  258. s->dr = 0;
  259. s->gdir = 0;
  260. s->psr = 0;
  261. s->icr = 0;
  262. s->imr = 0;
  263. s->isr = 0;
  264. s->edge_sel = 0;
  265. imx_gpio_set_all_output_lines(s);
  266. imx_gpio_update_int(s);
  267. }
  268. static void imx_gpio_realize(DeviceState *dev, Error **errp)
  269. {
  270. IMXGPIOState *s = IMX_GPIO(dev);
  271. memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpio_ops, s,
  272. TYPE_IMX_GPIO, IMX_GPIO_MEM_SIZE);
  273. qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT);
  274. qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT);
  275. sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]);
  276. sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]);
  277. sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
  278. }
  279. static void imx_gpio_class_init(ObjectClass *klass, void *data)
  280. {
  281. DeviceClass *dc = DEVICE_CLASS(klass);
  282. dc->realize = imx_gpio_realize;
  283. dc->reset = imx_gpio_reset;
  284. dc->props = imx_gpio_properties;
  285. dc->vmsd = &vmstate_imx_gpio;
  286. dc->desc = "i.MX GPIO controller";
  287. }
  288. static const TypeInfo imx_gpio_info = {
  289. .name = TYPE_IMX_GPIO,
  290. .parent = TYPE_SYS_BUS_DEVICE,
  291. .instance_size = sizeof(IMXGPIOState),
  292. .class_init = imx_gpio_class_init,
  293. };
  294. static void imx_gpio_register_types(void)
  295. {
  296. type_register_static(&imx_gpio_info);
  297. }
  298. type_init(imx_gpio_register_types)