2
0

pxa2xx_timer.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. * Intel XScale PXA255/270 OS Timers.
  3. *
  4. * Copyright (c) 2006 Openedhand Ltd.
  5. * Copyright (c) 2006 Thorsten Zitterell
  6. *
  7. * This code is licensed under the GPL.
  8. */
  9. #include "hw.h"
  10. #include "qemu/timer.h"
  11. #include "sysemu/sysemu.h"
  12. #include "pxa.h"
  13. #include "sysbus.h"
  14. #define OSMR0 0x00
  15. #define OSMR1 0x04
  16. #define OSMR2 0x08
  17. #define OSMR3 0x0c
  18. #define OSMR4 0x80
  19. #define OSMR5 0x84
  20. #define OSMR6 0x88
  21. #define OSMR7 0x8c
  22. #define OSMR8 0x90
  23. #define OSMR9 0x94
  24. #define OSMR10 0x98
  25. #define OSMR11 0x9c
  26. #define OSCR 0x10 /* OS Timer Count */
  27. #define OSCR4 0x40
  28. #define OSCR5 0x44
  29. #define OSCR6 0x48
  30. #define OSCR7 0x4c
  31. #define OSCR8 0x50
  32. #define OSCR9 0x54
  33. #define OSCR10 0x58
  34. #define OSCR11 0x5c
  35. #define OSSR 0x14 /* Timer status register */
  36. #define OWER 0x18
  37. #define OIER 0x1c /* Interrupt enable register 3-0 to E3-E0 */
  38. #define OMCR4 0xc0 /* OS Match Control registers */
  39. #define OMCR5 0xc4
  40. #define OMCR6 0xc8
  41. #define OMCR7 0xcc
  42. #define OMCR8 0xd0
  43. #define OMCR9 0xd4
  44. #define OMCR10 0xd8
  45. #define OMCR11 0xdc
  46. #define OSNR 0x20
  47. #define PXA25X_FREQ 3686400 /* 3.6864 MHz */
  48. #define PXA27X_FREQ 3250000 /* 3.25 MHz */
  49. static int pxa2xx_timer4_freq[8] = {
  50. [0] = 0,
  51. [1] = 32768,
  52. [2] = 1000,
  53. [3] = 1,
  54. [4] = 1000000,
  55. /* [5] is the "Externally supplied clock". Assign if necessary. */
  56. [5 ... 7] = 0,
  57. };
  58. typedef struct PXA2xxTimerInfo PXA2xxTimerInfo;
  59. typedef struct {
  60. uint32_t value;
  61. qemu_irq irq;
  62. QEMUTimer *qtimer;
  63. int num;
  64. PXA2xxTimerInfo *info;
  65. } PXA2xxTimer0;
  66. typedef struct {
  67. PXA2xxTimer0 tm;
  68. int32_t oldclock;
  69. int32_t clock;
  70. uint64_t lastload;
  71. uint32_t freq;
  72. uint32_t control;
  73. } PXA2xxTimer4;
  74. struct PXA2xxTimerInfo {
  75. SysBusDevice busdev;
  76. MemoryRegion iomem;
  77. uint32_t flags;
  78. int32_t clock;
  79. int32_t oldclock;
  80. uint64_t lastload;
  81. uint32_t freq;
  82. PXA2xxTimer0 timer[4];
  83. uint32_t events;
  84. uint32_t irq_enabled;
  85. uint32_t reset3;
  86. uint32_t snapshot;
  87. qemu_irq irq4;
  88. PXA2xxTimer4 tm4[8];
  89. };
  90. #define PXA2XX_TIMER_HAVE_TM4 0
  91. static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
  92. {
  93. return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4);
  94. }
  95. static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
  96. {
  97. PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
  98. int i;
  99. uint32_t now_vm;
  100. uint64_t new_qemu;
  101. now_vm = s->clock +
  102. muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec());
  103. for (i = 0; i < 4; i ++) {
  104. new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
  105. get_ticks_per_sec(), s->freq);
  106. qemu_mod_timer(s->timer[i].qtimer, new_qemu);
  107. }
  108. }
  109. static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
  110. {
  111. PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
  112. uint32_t now_vm;
  113. uint64_t new_qemu;
  114. static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
  115. int counter;
  116. if (s->tm4[n].control & (1 << 7))
  117. counter = n;
  118. else
  119. counter = counters[n];
  120. if (!s->tm4[counter].freq) {
  121. qemu_del_timer(s->tm4[n].tm.qtimer);
  122. return;
  123. }
  124. now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
  125. s->tm4[counter].lastload,
  126. s->tm4[counter].freq, get_ticks_per_sec());
  127. new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
  128. get_ticks_per_sec(), s->tm4[counter].freq);
  129. qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
  130. }
  131. static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
  132. unsigned size)
  133. {
  134. PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
  135. int tm = 0;
  136. switch (offset) {
  137. case OSMR3: tm ++;
  138. /* fall through */
  139. case OSMR2: tm ++;
  140. /* fall through */
  141. case OSMR1: tm ++;
  142. /* fall through */
  143. case OSMR0:
  144. return s->timer[tm].value;
  145. case OSMR11: tm ++;
  146. /* fall through */
  147. case OSMR10: tm ++;
  148. /* fall through */
  149. case OSMR9: tm ++;
  150. /* fall through */
  151. case OSMR8: tm ++;
  152. /* fall through */
  153. case OSMR7: tm ++;
  154. /* fall through */
  155. case OSMR6: tm ++;
  156. /* fall through */
  157. case OSMR5: tm ++;
  158. /* fall through */
  159. case OSMR4:
  160. if (!pxa2xx_timer_has_tm4(s))
  161. goto badreg;
  162. return s->tm4[tm].tm.value;
  163. case OSCR:
  164. return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
  165. s->lastload, s->freq, get_ticks_per_sec());
  166. case OSCR11: tm ++;
  167. /* fall through */
  168. case OSCR10: tm ++;
  169. /* fall through */
  170. case OSCR9: tm ++;
  171. /* fall through */
  172. case OSCR8: tm ++;
  173. /* fall through */
  174. case OSCR7: tm ++;
  175. /* fall through */
  176. case OSCR6: tm ++;
  177. /* fall through */
  178. case OSCR5: tm ++;
  179. /* fall through */
  180. case OSCR4:
  181. if (!pxa2xx_timer_has_tm4(s))
  182. goto badreg;
  183. if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
  184. if (s->tm4[tm - 1].freq)
  185. s->snapshot = s->tm4[tm - 1].clock + muldiv64(
  186. qemu_get_clock_ns(vm_clock) -
  187. s->tm4[tm - 1].lastload,
  188. s->tm4[tm - 1].freq, get_ticks_per_sec());
  189. else
  190. s->snapshot = s->tm4[tm - 1].clock;
  191. }
  192. if (!s->tm4[tm].freq)
  193. return s->tm4[tm].clock;
  194. return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) -
  195. s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
  196. case OIER:
  197. return s->irq_enabled;
  198. case OSSR: /* Status register */
  199. return s->events;
  200. case OWER:
  201. return s->reset3;
  202. case OMCR11: tm ++;
  203. /* fall through */
  204. case OMCR10: tm ++;
  205. /* fall through */
  206. case OMCR9: tm ++;
  207. /* fall through */
  208. case OMCR8: tm ++;
  209. /* fall through */
  210. case OMCR7: tm ++;
  211. /* fall through */
  212. case OMCR6: tm ++;
  213. /* fall through */
  214. case OMCR5: tm ++;
  215. /* fall through */
  216. case OMCR4:
  217. if (!pxa2xx_timer_has_tm4(s))
  218. goto badreg;
  219. return s->tm4[tm].control;
  220. case OSNR:
  221. return s->snapshot;
  222. default:
  223. badreg:
  224. hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
  225. }
  226. return 0;
  227. }
  228. static void pxa2xx_timer_write(void *opaque, hwaddr offset,
  229. uint64_t value, unsigned size)
  230. {
  231. int i, tm = 0;
  232. PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
  233. switch (offset) {
  234. case OSMR3: tm ++;
  235. /* fall through */
  236. case OSMR2: tm ++;
  237. /* fall through */
  238. case OSMR1: tm ++;
  239. /* fall through */
  240. case OSMR0:
  241. s->timer[tm].value = value;
  242. pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
  243. break;
  244. case OSMR11: tm ++;
  245. /* fall through */
  246. case OSMR10: tm ++;
  247. /* fall through */
  248. case OSMR9: tm ++;
  249. /* fall through */
  250. case OSMR8: tm ++;
  251. /* fall through */
  252. case OSMR7: tm ++;
  253. /* fall through */
  254. case OSMR6: tm ++;
  255. /* fall through */
  256. case OSMR5: tm ++;
  257. /* fall through */
  258. case OSMR4:
  259. if (!pxa2xx_timer_has_tm4(s))
  260. goto badreg;
  261. s->tm4[tm].tm.value = value;
  262. pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
  263. break;
  264. case OSCR:
  265. s->oldclock = s->clock;
  266. s->lastload = qemu_get_clock_ns(vm_clock);
  267. s->clock = value;
  268. pxa2xx_timer_update(s, s->lastload);
  269. break;
  270. case OSCR11: tm ++;
  271. /* fall through */
  272. case OSCR10: tm ++;
  273. /* fall through */
  274. case OSCR9: tm ++;
  275. /* fall through */
  276. case OSCR8: tm ++;
  277. /* fall through */
  278. case OSCR7: tm ++;
  279. /* fall through */
  280. case OSCR6: tm ++;
  281. /* fall through */
  282. case OSCR5: tm ++;
  283. /* fall through */
  284. case OSCR4:
  285. if (!pxa2xx_timer_has_tm4(s))
  286. goto badreg;
  287. s->tm4[tm].oldclock = s->tm4[tm].clock;
  288. s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock);
  289. s->tm4[tm].clock = value;
  290. pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
  291. break;
  292. case OIER:
  293. s->irq_enabled = value & 0xfff;
  294. break;
  295. case OSSR: /* Status register */
  296. value &= s->events;
  297. s->events &= ~value;
  298. for (i = 0; i < 4; i ++, value >>= 1)
  299. if (value & 1)
  300. qemu_irq_lower(s->timer[i].irq);
  301. if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value)
  302. qemu_irq_lower(s->irq4);
  303. break;
  304. case OWER: /* XXX: Reset on OSMR3 match? */
  305. s->reset3 = value;
  306. break;
  307. case OMCR7: tm ++;
  308. /* fall through */
  309. case OMCR6: tm ++;
  310. /* fall through */
  311. case OMCR5: tm ++;
  312. /* fall through */
  313. case OMCR4:
  314. if (!pxa2xx_timer_has_tm4(s))
  315. goto badreg;
  316. s->tm4[tm].control = value & 0x0ff;
  317. /* XXX Stop if running (shouldn't happen) */
  318. if ((value & (1 << 7)) || tm == 0)
  319. s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
  320. else {
  321. s->tm4[tm].freq = 0;
  322. pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
  323. }
  324. break;
  325. case OMCR11: tm ++;
  326. /* fall through */
  327. case OMCR10: tm ++;
  328. /* fall through */
  329. case OMCR9: tm ++;
  330. /* fall through */
  331. case OMCR8: tm += 4;
  332. if (!pxa2xx_timer_has_tm4(s))
  333. goto badreg;
  334. s->tm4[tm].control = value & 0x3ff;
  335. /* XXX Stop if running (shouldn't happen) */
  336. if ((value & (1 << 7)) || !(tm & 1))
  337. s->tm4[tm].freq =
  338. pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)];
  339. else {
  340. s->tm4[tm].freq = 0;
  341. pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
  342. }
  343. break;
  344. default:
  345. badreg:
  346. hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
  347. }
  348. }
  349. static const MemoryRegionOps pxa2xx_timer_ops = {
  350. .read = pxa2xx_timer_read,
  351. .write = pxa2xx_timer_write,
  352. .endianness = DEVICE_NATIVE_ENDIAN,
  353. };
  354. static void pxa2xx_timer_tick(void *opaque)
  355. {
  356. PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
  357. PXA2xxTimerInfo *i = t->info;
  358. if (i->irq_enabled & (1 << t->num)) {
  359. i->events |= 1 << t->num;
  360. qemu_irq_raise(t->irq);
  361. }
  362. if (t->num == 3)
  363. if (i->reset3 & 1) {
  364. i->reset3 = 0;
  365. qemu_system_reset_request();
  366. }
  367. }
  368. static void pxa2xx_timer_tick4(void *opaque)
  369. {
  370. PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
  371. PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
  372. pxa2xx_timer_tick(&t->tm);
  373. if (t->control & (1 << 3))
  374. t->clock = 0;
  375. if (t->control & (1 << 6))
  376. pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4);
  377. if (i->events & 0xff0)
  378. qemu_irq_raise(i->irq4);
  379. }
  380. static int pxa25x_timer_post_load(void *opaque, int version_id)
  381. {
  382. PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
  383. int64_t now;
  384. int i;
  385. now = qemu_get_clock_ns(vm_clock);
  386. pxa2xx_timer_update(s, now);
  387. if (pxa2xx_timer_has_tm4(s))
  388. for (i = 0; i < 8; i ++)
  389. pxa2xx_timer_update4(s, now, i);
  390. return 0;
  391. }
  392. static int pxa2xx_timer_init(SysBusDevice *dev)
  393. {
  394. int i;
  395. PXA2xxTimerInfo *s;
  396. s = FROM_SYSBUS(PXA2xxTimerInfo, dev);
  397. s->irq_enabled = 0;
  398. s->oldclock = 0;
  399. s->clock = 0;
  400. s->lastload = qemu_get_clock_ns(vm_clock);
  401. s->reset3 = 0;
  402. for (i = 0; i < 4; i ++) {
  403. s->timer[i].value = 0;
  404. sysbus_init_irq(dev, &s->timer[i].irq);
  405. s->timer[i].info = s;
  406. s->timer[i].num = i;
  407. s->timer[i].qtimer = qemu_new_timer_ns(vm_clock,
  408. pxa2xx_timer_tick, &s->timer[i]);
  409. }
  410. if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
  411. sysbus_init_irq(dev, &s->irq4);
  412. for (i = 0; i < 8; i ++) {
  413. s->tm4[i].tm.value = 0;
  414. s->tm4[i].tm.info = s;
  415. s->tm4[i].tm.num = i + 4;
  416. s->tm4[i].freq = 0;
  417. s->tm4[i].control = 0x0;
  418. s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock,
  419. pxa2xx_timer_tick4, &s->tm4[i]);
  420. }
  421. }
  422. memory_region_init_io(&s->iomem, &pxa2xx_timer_ops, s,
  423. "pxa2xx-timer", 0x00001000);
  424. sysbus_init_mmio(dev, &s->iomem);
  425. return 0;
  426. }
  427. static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
  428. .name = "pxa2xx_timer0",
  429. .version_id = 2,
  430. .minimum_version_id = 2,
  431. .minimum_version_id_old = 2,
  432. .fields = (VMStateField[]) {
  433. VMSTATE_UINT32(value, PXA2xxTimer0),
  434. VMSTATE_END_OF_LIST(),
  435. },
  436. };
  437. static const VMStateDescription vmstate_pxa2xx_timer4_regs = {
  438. .name = "pxa2xx_timer4",
  439. .version_id = 1,
  440. .minimum_version_id = 1,
  441. .minimum_version_id_old = 1,
  442. .fields = (VMStateField[]) {
  443. VMSTATE_STRUCT(tm, PXA2xxTimer4, 1,
  444. vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
  445. VMSTATE_INT32(oldclock, PXA2xxTimer4),
  446. VMSTATE_INT32(clock, PXA2xxTimer4),
  447. VMSTATE_UINT64(lastload, PXA2xxTimer4),
  448. VMSTATE_UINT32(freq, PXA2xxTimer4),
  449. VMSTATE_UINT32(control, PXA2xxTimer4),
  450. VMSTATE_END_OF_LIST(),
  451. },
  452. };
  453. static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
  454. {
  455. return pxa2xx_timer_has_tm4(opaque);
  456. }
  457. static const VMStateDescription vmstate_pxa2xx_timer_regs = {
  458. .name = "pxa2xx_timer",
  459. .version_id = 1,
  460. .minimum_version_id = 1,
  461. .minimum_version_id_old = 1,
  462. .post_load = pxa25x_timer_post_load,
  463. .fields = (VMStateField[]) {
  464. VMSTATE_INT32(clock, PXA2xxTimerInfo),
  465. VMSTATE_INT32(oldclock, PXA2xxTimerInfo),
  466. VMSTATE_UINT64(lastload, PXA2xxTimerInfo),
  467. VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1,
  468. vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
  469. VMSTATE_UINT32(events, PXA2xxTimerInfo),
  470. VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo),
  471. VMSTATE_UINT32(reset3, PXA2xxTimerInfo),
  472. VMSTATE_UINT32(snapshot, PXA2xxTimerInfo),
  473. VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8,
  474. pxa2xx_timer_has_tm4_test, 0,
  475. vmstate_pxa2xx_timer4_regs, PXA2xxTimer4),
  476. VMSTATE_END_OF_LIST(),
  477. }
  478. };
  479. static Property pxa25x_timer_dev_properties[] = {
  480. DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
  481. DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
  482. PXA2XX_TIMER_HAVE_TM4, false),
  483. DEFINE_PROP_END_OF_LIST(),
  484. };
  485. static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
  486. {
  487. DeviceClass *dc = DEVICE_CLASS(klass);
  488. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  489. k->init = pxa2xx_timer_init;
  490. dc->desc = "PXA25x timer";
  491. dc->vmsd = &vmstate_pxa2xx_timer_regs;
  492. dc->props = pxa25x_timer_dev_properties;
  493. }
  494. static const TypeInfo pxa25x_timer_dev_info = {
  495. .name = "pxa25x-timer",
  496. .parent = TYPE_SYS_BUS_DEVICE,
  497. .instance_size = sizeof(PXA2xxTimerInfo),
  498. .class_init = pxa25x_timer_dev_class_init,
  499. };
  500. static Property pxa27x_timer_dev_properties[] = {
  501. DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
  502. DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
  503. PXA2XX_TIMER_HAVE_TM4, true),
  504. DEFINE_PROP_END_OF_LIST(),
  505. };
  506. static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
  507. {
  508. DeviceClass *dc = DEVICE_CLASS(klass);
  509. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  510. k->init = pxa2xx_timer_init;
  511. dc->desc = "PXA27x timer";
  512. dc->vmsd = &vmstate_pxa2xx_timer_regs;
  513. dc->props = pxa27x_timer_dev_properties;
  514. }
  515. static const TypeInfo pxa27x_timer_dev_info = {
  516. .name = "pxa27x-timer",
  517. .parent = TYPE_SYS_BUS_DEVICE,
  518. .instance_size = sizeof(PXA2xxTimerInfo),
  519. .class_init = pxa27x_timer_dev_class_init,
  520. };
  521. static void pxa2xx_timer_register_types(void)
  522. {
  523. type_register_static(&pxa25x_timer_dev_info);
  524. type_register_static(&pxa27x_timer_dev_info);
  525. }
  526. type_init(pxa2xx_timer_register_types)