pxa2xx_timer.c 17 KB

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