nrf51_timer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * nRF51 System-on-Chip Timer peripheral
  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. * Copyright (c) 2019 Red Hat, Inc.
  9. *
  10. * This code is licensed under the GPL version 2 or later. See
  11. * the COPYING file in the top-level directory.
  12. */
  13. #include "qemu/osdep.h"
  14. #include "qemu/log.h"
  15. #include "qemu/module.h"
  16. #include "hw/arm/nrf51.h"
  17. #include "hw/irq.h"
  18. #include "hw/timer/nrf51_timer.h"
  19. #include "hw/qdev-properties.h"
  20. #include "migration/vmstate.h"
  21. #include "trace.h"
  22. #define TIMER_CLK_FREQ 16000000UL
  23. static uint32_t const bitwidths[] = {16, 8, 24, 32};
  24. static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns)
  25. {
  26. uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
  27. return muldiv64(ns, freq, NANOSECONDS_PER_SECOND);
  28. }
  29. static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks)
  30. {
  31. uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
  32. return muldiv64(ticks, NANOSECONDS_PER_SECOND, freq);
  33. }
  34. /* Returns number of ticks since last call */
  35. static uint32_t update_counter(NRF51TimerState *s, int64_t now)
  36. {
  37. uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
  38. s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
  39. /*
  40. * Only advance the sync time to the timestamp of the last tick,
  41. * not all the way to 'now', so we don't lose time if we do
  42. * multiple resyncs in a single tick.
  43. */
  44. s->update_counter_ns += ticks_to_ns(s, ticks);
  45. return ticks;
  46. }
  47. /* Assumes s->counter is up-to-date */
  48. static void rearm_timer(NRF51TimerState *s, int64_t now)
  49. {
  50. int64_t min_ns = INT64_MAX;
  51. size_t i;
  52. for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
  53. int64_t delta_ns;
  54. if (s->events_compare[i]) {
  55. continue; /* already expired, ignore it for now */
  56. }
  57. if (s->cc[i] <= s->counter) {
  58. delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) -
  59. s->counter + s->cc[i]);
  60. } else {
  61. delta_ns = ticks_to_ns(s, s->cc[i] - s->counter);
  62. }
  63. if (delta_ns < min_ns) {
  64. min_ns = delta_ns;
  65. }
  66. }
  67. if (min_ns != INT64_MAX) {
  68. timer_mod_ns(&s->timer, now + min_ns);
  69. }
  70. }
  71. static void update_irq(NRF51TimerState *s)
  72. {
  73. bool flag = false;
  74. size_t i;
  75. for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
  76. flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1);
  77. }
  78. qemu_set_irq(s->irq, flag);
  79. }
  80. static void timer_expire(void *opaque)
  81. {
  82. NRF51TimerState *s = NRF51_TIMER(opaque);
  83. int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
  84. uint32_t cc_remaining[NRF51_TIMER_REG_COUNT];
  85. bool should_stop = false;
  86. uint32_t ticks;
  87. size_t i;
  88. for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
  89. if (s->cc[i] > s->counter) {
  90. cc_remaining[i] = s->cc[i] - s->counter;
  91. } else {
  92. cc_remaining[i] = BIT(bitwidths[s->bitmode]) -
  93. s->counter + s->cc[i];
  94. }
  95. }
  96. ticks = update_counter(s, now);
  97. for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
  98. if (cc_remaining[i] <= ticks) {
  99. s->events_compare[i] = 1;
  100. if (s->shorts & BIT(i)) {
  101. s->timer_start_ns = now;
  102. s->update_counter_ns = s->timer_start_ns;
  103. s->counter = 0;
  104. }
  105. should_stop |= s->shorts & BIT(i + 8);
  106. }
  107. }
  108. update_irq(s);
  109. if (should_stop) {
  110. s->running = false;
  111. timer_del(&s->timer);
  112. } else {
  113. rearm_timer(s, now);
  114. }
  115. }
  116. static void counter_compare(NRF51TimerState *s)
  117. {
  118. uint32_t counter = s->counter;
  119. size_t i;
  120. for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
  121. if (counter == s->cc[i]) {
  122. s->events_compare[i] = 1;
  123. if (s->shorts & BIT(i)) {
  124. s->counter = 0;
  125. }
  126. }
  127. }
  128. }
  129. static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size)
  130. {
  131. NRF51TimerState *s = NRF51_TIMER(opaque);
  132. uint64_t r = 0;
  133. switch (offset) {
  134. case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
  135. r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4];
  136. break;
  137. case NRF51_TIMER_REG_SHORTS:
  138. r = s->shorts;
  139. break;
  140. case NRF51_TIMER_REG_INTENSET:
  141. r = s->inten;
  142. break;
  143. case NRF51_TIMER_REG_INTENCLR:
  144. r = s->inten;
  145. break;
  146. case NRF51_TIMER_REG_MODE:
  147. r = s->mode;
  148. break;
  149. case NRF51_TIMER_REG_BITMODE:
  150. r = s->bitmode;
  151. break;
  152. case NRF51_TIMER_REG_PRESCALER:
  153. r = s->prescaler;
  154. break;
  155. case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
  156. r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4];
  157. break;
  158. default:
  159. qemu_log_mask(LOG_GUEST_ERROR,
  160. "%s: bad read offset 0x%" HWADDR_PRIx "\n",
  161. __func__, offset);
  162. }
  163. trace_nrf51_timer_read(s->id, offset, r, size);
  164. return r;
  165. }
  166. static void nrf51_timer_write(void *opaque, hwaddr offset,
  167. uint64_t value, unsigned int size)
  168. {
  169. NRF51TimerState *s = NRF51_TIMER(opaque);
  170. uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
  171. size_t idx;
  172. trace_nrf51_timer_write(s->id, offset, value, size);
  173. switch (offset) {
  174. case NRF51_TIMER_TASK_START:
  175. if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) {
  176. s->running = true;
  177. s->timer_start_ns = now - ticks_to_ns(s, s->counter);
  178. s->update_counter_ns = s->timer_start_ns;
  179. rearm_timer(s, now);
  180. }
  181. break;
  182. case NRF51_TIMER_TASK_STOP:
  183. case NRF51_TIMER_TASK_SHUTDOWN:
  184. if (value == NRF51_TRIGGER_TASK) {
  185. s->running = false;
  186. timer_del(&s->timer);
  187. }
  188. break;
  189. case NRF51_TIMER_TASK_COUNT:
  190. if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) {
  191. s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]);
  192. counter_compare(s);
  193. }
  194. break;
  195. case NRF51_TIMER_TASK_CLEAR:
  196. if (value == NRF51_TRIGGER_TASK) {
  197. s->timer_start_ns = now;
  198. s->update_counter_ns = s->timer_start_ns;
  199. s->counter = 0;
  200. if (s->running) {
  201. rearm_timer(s, now);
  202. }
  203. }
  204. break;
  205. case NRF51_TIMER_TASK_CAPTURE_0 ... NRF51_TIMER_TASK_CAPTURE_3:
  206. if (value == NRF51_TRIGGER_TASK) {
  207. if (s->running) {
  208. timer_expire(s); /* update counter and all state */
  209. }
  210. idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4;
  211. s->cc[idx] = s->counter;
  212. trace_nrf51_timer_set_count(s->id, idx, s->counter);
  213. }
  214. break;
  215. case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
  216. if (value == NRF51_EVENT_CLEAR) {
  217. s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0;
  218. if (s->running) {
  219. timer_expire(s); /* update counter and all state */
  220. }
  221. }
  222. break;
  223. case NRF51_TIMER_REG_SHORTS:
  224. s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK;
  225. break;
  226. case NRF51_TIMER_REG_INTENSET:
  227. s->inten |= value & NRF51_TIMER_REG_INTEN_MASK;
  228. break;
  229. case NRF51_TIMER_REG_INTENCLR:
  230. s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK);
  231. break;
  232. case NRF51_TIMER_REG_MODE:
  233. s->mode = value;
  234. break;
  235. case NRF51_TIMER_REG_BITMODE:
  236. if (s->mode == NRF51_TIMER_TIMER && s->running) {
  237. qemu_log_mask(LOG_GUEST_ERROR,
  238. "%s: erroneous change of BITMODE while timer is running\n",
  239. __func__);
  240. }
  241. s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK;
  242. break;
  243. case NRF51_TIMER_REG_PRESCALER:
  244. if (s->mode == NRF51_TIMER_TIMER && s->running) {
  245. qemu_log_mask(LOG_GUEST_ERROR,
  246. "%s: erroneous change of PRESCALER while timer is running\n",
  247. __func__);
  248. }
  249. s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK;
  250. break;
  251. case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
  252. if (s->running) {
  253. timer_expire(s); /* update counter */
  254. }
  255. idx = (offset - NRF51_TIMER_REG_CC0) / 4;
  256. s->cc[idx] = value % BIT(bitwidths[s->bitmode]);
  257. if (s->running) {
  258. rearm_timer(s, now);
  259. }
  260. break;
  261. default:
  262. qemu_log_mask(LOG_GUEST_ERROR,
  263. "%s: bad write offset 0x%" HWADDR_PRIx "\n",
  264. __func__, offset);
  265. }
  266. update_irq(s);
  267. }
  268. static const MemoryRegionOps rng_ops = {
  269. .read = nrf51_timer_read,
  270. .write = nrf51_timer_write,
  271. .endianness = DEVICE_LITTLE_ENDIAN,
  272. .impl.min_access_size = 4,
  273. .impl.max_access_size = 4,
  274. };
  275. static void nrf51_timer_init(Object *obj)
  276. {
  277. NRF51TimerState *s = NRF51_TIMER(obj);
  278. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  279. memory_region_init_io(&s->iomem, obj, &rng_ops, s,
  280. TYPE_NRF51_TIMER, NRF51_PERIPHERAL_SIZE);
  281. sysbus_init_mmio(sbd, &s->iomem);
  282. sysbus_init_irq(sbd, &s->irq);
  283. timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s);
  284. }
  285. static void nrf51_timer_reset(DeviceState *dev)
  286. {
  287. NRF51TimerState *s = NRF51_TIMER(dev);
  288. timer_del(&s->timer);
  289. s->timer_start_ns = 0x00;
  290. s->update_counter_ns = 0x00;
  291. s->counter = 0x00;
  292. s->running = false;
  293. memset(s->events_compare, 0x00, sizeof(s->events_compare));
  294. memset(s->cc, 0x00, sizeof(s->cc));
  295. s->shorts = 0x00;
  296. s->inten = 0x00;
  297. s->mode = 0x00;
  298. s->bitmode = 0x00;
  299. s->prescaler = 0x00;
  300. }
  301. static int nrf51_timer_post_load(void *opaque, int version_id)
  302. {
  303. NRF51TimerState *s = NRF51_TIMER(opaque);
  304. if (s->running && s->mode == NRF51_TIMER_TIMER) {
  305. timer_expire(s);
  306. }
  307. return 0;
  308. }
  309. static const VMStateDescription vmstate_nrf51_timer = {
  310. .name = TYPE_NRF51_TIMER,
  311. .version_id = 1,
  312. .post_load = nrf51_timer_post_load,
  313. .fields = (const VMStateField[]) {
  314. VMSTATE_TIMER(timer, NRF51TimerState),
  315. VMSTATE_INT64(timer_start_ns, NRF51TimerState),
  316. VMSTATE_INT64(update_counter_ns, NRF51TimerState),
  317. VMSTATE_UINT32(counter, NRF51TimerState),
  318. VMSTATE_BOOL(running, NRF51TimerState),
  319. VMSTATE_UINT8_ARRAY(events_compare, NRF51TimerState,
  320. NRF51_TIMER_REG_COUNT),
  321. VMSTATE_UINT32_ARRAY(cc, NRF51TimerState, NRF51_TIMER_REG_COUNT),
  322. VMSTATE_UINT32(shorts, NRF51TimerState),
  323. VMSTATE_UINT32(inten, NRF51TimerState),
  324. VMSTATE_UINT32(mode, NRF51TimerState),
  325. VMSTATE_UINT32(bitmode, NRF51TimerState),
  326. VMSTATE_UINT32(prescaler, NRF51TimerState),
  327. VMSTATE_END_OF_LIST()
  328. }
  329. };
  330. static const Property nrf51_timer_properties[] = {
  331. DEFINE_PROP_UINT8("id", NRF51TimerState, id, 0),
  332. };
  333. static void nrf51_timer_class_init(ObjectClass *klass, void *data)
  334. {
  335. DeviceClass *dc = DEVICE_CLASS(klass);
  336. device_class_set_legacy_reset(dc, nrf51_timer_reset);
  337. dc->vmsd = &vmstate_nrf51_timer;
  338. device_class_set_props(dc, nrf51_timer_properties);
  339. }
  340. static const TypeInfo nrf51_timer_info = {
  341. .name = TYPE_NRF51_TIMER,
  342. .parent = TYPE_SYS_BUS_DEVICE,
  343. .instance_size = sizeof(NRF51TimerState),
  344. .instance_init = nrf51_timer_init,
  345. .class_init = nrf51_timer_class_init
  346. };
  347. static void nrf51_timer_register_types(void)
  348. {
  349. type_register_static(&nrf51_timer_info);
  350. }
  351. type_init(nrf51_timer_register_types)