2
0

imx_gpio.c 9.4 KB

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