pxa2xx_timer.c 17 KB

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