summaryrefslogtreecommitdiff
path: root/hw/timer
diff options
context:
space:
mode:
authorJean-Christophe Dubois <jcd@tribudubois.net>2016-03-16 17:05:59 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-03-16 17:42:18 +0000
commit4833e15f7487440243377250d7d76b96ba4c210c (patch)
tree70d2c624594ec0a418dc514a0da65d44166e4b2a /hw/timer
parent9c94d8e6c9a31a74f18168ca8d74c3e3f7c0e40e (diff)
downloadqemu-4833e15f7487440243377250d7d76b96ba4c210c.zip
i.MX: Allow GPT timer to rollover.
GPT timer need to rollover when it reaches 0xffffffff. It also need to reset to 0 when in "restart mode" and crossing the compare 1 register. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net> Message-id: 6e2b36117a249a78bf822dd59a390368f407136e.1456868959.git.jcd@tribudubois.net Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/timer')
-rw-r--r--hw/timer/imx_gpt.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 5cdc3b3c8d..916577b463 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -134,7 +134,7 @@ static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
{
uint32_t timeout = GPT_TIMER_MAX;
- uint32_t count = 0;
+ uint32_t count;
long long limit;
if (!(s->cr & GPT_CR_EN)) {
@@ -142,20 +142,23 @@ static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
return;
}
- if (event) {
- /* This is a timer event */
+ /* update the count */
+ count = imx_gpt_update_count(s);
- if ((s->cr & GPT_CR_FRR) && (s->next_timeout != GPT_TIMER_MAX)) {
- /*
- * if we are in free running mode and we have not reached
- * the GPT_TIMER_MAX limit, then update the count
+ if (event) {
+ /*
+ * This is an event (the ptimer reached 0 and stopped), and the
+ * timer counter is now equal to s->next_timeout.
+ */
+ if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
+ /* We are in restart mode and we crossed the compare channel 1
+ * value. We need to reset the counter to 0.
*/
- count = imx_gpt_update_count(s);
+ count = s->cnt = s->next_timeout = 0;
+ } else if (count == GPT_TIMER_MAX) {
+ /* We reached GPT_TIMER_MAX so we need to rollover */
+ count = s->cnt = s->next_timeout = 0;
}
- } else {
- /* not a timer event, then just update the count */
-
- count = imx_gpt_update_count(s);
}
/* now, find the next timeout related to count */