nrf51_gpio.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * nRF51 System-on-Chip general purpose input/output register definition
  3. *
  4. * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
  5. * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
  6. *
  7. * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
  8. *
  9. * This code is licensed under the GPL version 2 or later. See
  10. * the COPYING file in the top-level directory.
  11. */
  12. #include "qemu/osdep.h"
  13. #include "qemu/log.h"
  14. #include "qemu/module.h"
  15. #include "hw/gpio/nrf51_gpio.h"
  16. #include "hw/irq.h"
  17. #include "migration/vmstate.h"
  18. #include "trace.h"
  19. /*
  20. * Check if the output driver is connected to the direction switch
  21. * given the current configuration and logic level.
  22. * It is not differentiated between standard and "high"(-power) drive modes.
  23. */
  24. static bool is_connected(uint32_t config, uint32_t level)
  25. {
  26. bool state;
  27. uint32_t drive_config = extract32(config, 8, 3);
  28. switch (drive_config) {
  29. case 0 ... 3:
  30. state = true;
  31. break;
  32. case 4 ... 5:
  33. state = level != 0;
  34. break;
  35. case 6 ... 7:
  36. state = level == 0;
  37. break;
  38. default:
  39. g_assert_not_reached();
  40. break;
  41. }
  42. return state;
  43. }
  44. static int pull_value(uint32_t config)
  45. {
  46. int pull = extract32(config, 2, 2);
  47. if (pull == NRF51_GPIO_PULLDOWN) {
  48. return 0;
  49. } else if (pull == NRF51_GPIO_PULLUP) {
  50. return 1;
  51. }
  52. return -1;
  53. }
  54. static void update_output_irq(NRF51GPIOState *s, size_t i,
  55. bool connected, bool level)
  56. {
  57. int64_t irq_level = connected ? level : -1;
  58. bool old_connected = extract32(s->old_out_connected, i, 1);
  59. bool old_level = extract32(s->old_out, i, 1);
  60. if ((old_connected != connected) || (old_level != level)) {
  61. qemu_set_irq(s->output[i], irq_level);
  62. trace_nrf51_gpio_update_output_irq(i, irq_level);
  63. }
  64. s->old_out = deposit32(s->old_out, i, 1, level);
  65. s->old_out_connected = deposit32(s->old_out_connected, i, 1, connected);
  66. }
  67. static void update_state(NRF51GPIOState *s)
  68. {
  69. int pull;
  70. size_t i;
  71. bool connected_out, dir, connected_in, out, in, input;
  72. bool assert_detect = false;
  73. for (i = 0; i < NRF51_GPIO_PINS; i++) {
  74. pull = pull_value(s->cnf[i]);
  75. dir = extract32(s->cnf[i], 0, 1);
  76. connected_in = extract32(s->in_mask, i, 1);
  77. out = extract32(s->out, i, 1);
  78. in = extract32(s->in, i, 1);
  79. input = !extract32(s->cnf[i], 1, 1);
  80. connected_out = is_connected(s->cnf[i], out) && dir;
  81. if (!input) {
  82. if (pull >= 0) {
  83. /* Input buffer disconnected from external drives */
  84. s->in = deposit32(s->in, i, 1, pull);
  85. }
  86. } else {
  87. if (connected_out && connected_in && out != in) {
  88. /* Pin both driven externally and internally */
  89. qemu_log_mask(LOG_GUEST_ERROR,
  90. "GPIO pin %zu short circuited\n", i);
  91. }
  92. if (connected_in) {
  93. uint32_t detect_config = extract32(s->cnf[i], 16, 2);
  94. if ((detect_config == 2) && (in == 1)) {
  95. assert_detect = true;
  96. }
  97. if ((detect_config == 3) && (in == 0)) {
  98. assert_detect = true;
  99. }
  100. } else {
  101. /*
  102. * Floating input: the output stimulates IN if connected,
  103. * otherwise pull-up/pull-down resistors put a value on both
  104. * IN and OUT.
  105. */
  106. if (pull >= 0 && !connected_out) {
  107. connected_out = true;
  108. out = pull;
  109. }
  110. if (connected_out) {
  111. s->in = deposit32(s->in, i, 1, out);
  112. }
  113. }
  114. }
  115. update_output_irq(s, i, connected_out, out);
  116. }
  117. qemu_set_irq(s->detect, assert_detect);
  118. }
  119. /*
  120. * Direction is exposed in both the DIR register and the DIR bit
  121. * of each PINs CNF configuration register. Reflect bits for pins in DIR
  122. * to individual pin configuration registers.
  123. */
  124. static void reflect_dir_bit_in_cnf(NRF51GPIOState *s)
  125. {
  126. size_t i;
  127. uint32_t value = s->dir;
  128. for (i = 0; i < NRF51_GPIO_PINS; i++) {
  129. s->cnf[i] = (s->cnf[i] & ~(1UL)) | ((value >> i) & 0x01);
  130. }
  131. }
  132. static uint64_t nrf51_gpio_read(void *opaque, hwaddr offset, unsigned int size)
  133. {
  134. NRF51GPIOState *s = NRF51_GPIO(opaque);
  135. uint64_t r = 0;
  136. size_t idx;
  137. switch (offset) {
  138. case NRF51_GPIO_REG_OUT ... NRF51_GPIO_REG_OUTCLR:
  139. r = s->out;
  140. break;
  141. case NRF51_GPIO_REG_IN:
  142. r = s->in;
  143. break;
  144. case NRF51_GPIO_REG_DIR ... NRF51_GPIO_REG_DIRCLR:
  145. r = s->dir;
  146. break;
  147. case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
  148. idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
  149. r = s->cnf[idx];
  150. break;
  151. default:
  152. qemu_log_mask(LOG_GUEST_ERROR,
  153. "%s: bad read offset 0x%" HWADDR_PRIx "\n",
  154. __func__, offset);
  155. }
  156. trace_nrf51_gpio_read(offset, r);
  157. return r;
  158. }
  159. static void nrf51_gpio_write(void *opaque, hwaddr offset,
  160. uint64_t value, unsigned int size)
  161. {
  162. NRF51GPIOState *s = NRF51_GPIO(opaque);
  163. size_t idx;
  164. trace_nrf51_gpio_write(offset, value);
  165. switch (offset) {
  166. case NRF51_GPIO_REG_OUT:
  167. s->out = value;
  168. break;
  169. case NRF51_GPIO_REG_OUTSET:
  170. s->out |= value;
  171. break;
  172. case NRF51_GPIO_REG_OUTCLR:
  173. s->out &= ~value;
  174. break;
  175. case NRF51_GPIO_REG_DIR:
  176. s->dir = value;
  177. reflect_dir_bit_in_cnf(s);
  178. break;
  179. case NRF51_GPIO_REG_DIRSET:
  180. s->dir |= value;
  181. reflect_dir_bit_in_cnf(s);
  182. break;
  183. case NRF51_GPIO_REG_DIRCLR:
  184. s->dir &= ~value;
  185. reflect_dir_bit_in_cnf(s);
  186. break;
  187. case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
  188. idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
  189. s->cnf[idx] = value;
  190. /*
  191. * direction is exposed in both the DIR register and the DIR bit
  192. * of each PINs CNF configuration register.
  193. */
  194. s->dir = (s->dir & ~(1UL << idx)) | ((value & 0x01) << idx);
  195. break;
  196. default:
  197. qemu_log_mask(LOG_GUEST_ERROR,
  198. "%s: bad write offset 0x%" HWADDR_PRIx "\n",
  199. __func__, offset);
  200. }
  201. update_state(s);
  202. }
  203. static const MemoryRegionOps gpio_ops = {
  204. .read = nrf51_gpio_read,
  205. .write = nrf51_gpio_write,
  206. .endianness = DEVICE_LITTLE_ENDIAN,
  207. .impl.min_access_size = 4,
  208. .impl.max_access_size = 4,
  209. };
  210. static void nrf51_gpio_set(void *opaque, int line, int value)
  211. {
  212. NRF51GPIOState *s = NRF51_GPIO(opaque);
  213. trace_nrf51_gpio_set(line, value);
  214. assert(line >= 0 && line < NRF51_GPIO_PINS);
  215. s->in_mask = deposit32(s->in_mask, line, 1, value >= 0);
  216. if (value >= 0) {
  217. s->in = deposit32(s->in, line, 1, value != 0);
  218. }
  219. update_state(s);
  220. }
  221. static void nrf51_gpio_reset(DeviceState *dev)
  222. {
  223. NRF51GPIOState *s = NRF51_GPIO(dev);
  224. size_t i;
  225. s->out = 0;
  226. s->old_out = 0;
  227. s->old_out_connected = 0;
  228. s->in = 0;
  229. s->in_mask = 0;
  230. s->dir = 0;
  231. for (i = 0; i < NRF51_GPIO_PINS; i++) {
  232. s->cnf[i] = 0x00000002;
  233. }
  234. }
  235. static const VMStateDescription vmstate_nrf51_gpio = {
  236. .name = TYPE_NRF51_GPIO,
  237. .version_id = 1,
  238. .minimum_version_id = 1,
  239. .fields = (VMStateField[]) {
  240. VMSTATE_UINT32(out, NRF51GPIOState),
  241. VMSTATE_UINT32(in, NRF51GPIOState),
  242. VMSTATE_UINT32(in_mask, NRF51GPIOState),
  243. VMSTATE_UINT32(dir, NRF51GPIOState),
  244. VMSTATE_UINT32_ARRAY(cnf, NRF51GPIOState, NRF51_GPIO_PINS),
  245. VMSTATE_UINT32(old_out, NRF51GPIOState),
  246. VMSTATE_UINT32(old_out_connected, NRF51GPIOState),
  247. VMSTATE_END_OF_LIST()
  248. }
  249. };
  250. static void nrf51_gpio_init(Object *obj)
  251. {
  252. NRF51GPIOState *s = NRF51_GPIO(obj);
  253. memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
  254. TYPE_NRF51_GPIO, NRF51_GPIO_SIZE);
  255. sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
  256. qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
  257. qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
  258. qdev_init_gpio_out_named(DEVICE(s), &s->detect, "detect", 1);
  259. }
  260. static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
  261. {
  262. DeviceClass *dc = DEVICE_CLASS(klass);
  263. dc->vmsd = &vmstate_nrf51_gpio;
  264. dc->reset = nrf51_gpio_reset;
  265. dc->desc = "nRF51 GPIO";
  266. }
  267. static const TypeInfo nrf51_gpio_info = {
  268. .name = TYPE_NRF51_GPIO,
  269. .parent = TYPE_SYS_BUS_DEVICE,
  270. .instance_size = sizeof(NRF51GPIOState),
  271. .instance_init = nrf51_gpio_init,
  272. .class_init = nrf51_gpio_class_init
  273. };
  274. static void nrf51_gpio_register_types(void)
  275. {
  276. type_register_static(&nrf51_gpio_info);
  277. }
  278. type_init(nrf51_gpio_register_types)