*
*/
+#include "qemu/osdep.h"
#include "hw/timer/imx_gpt.h"
#include "hw/misc/imx_ccm.h"
#include "qemu/main-loop.h"
+#include "qemu/log.h"
#ifndef DEBUG_IMX_GPT
#define DEBUG_IMX_GPT 0
};
static const IMXClk imx_gpt_clocks[] = {
- NOCLK, /* 000 No clock source */
- IPG, /* 001 ipg_clk, 532MHz*/
- IPG, /* 010 ipg_clk_highfreq */
- NOCLK, /* 011 not defined */
- CLK_32k, /* 100 ipg_clk_32k */
- NOCLK, /* 101 not defined */
- NOCLK, /* 110 not defined */
- NOCLK, /* 111 not defined */
+ CLK_NONE, /* 000 No clock source */
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
+ CLK_NONE, /* 011 not defined */
+ CLK_32k, /* 100 ipg_clk_32k */
+ CLK_NONE, /* 101 not defined */
+ CLK_NONE, /* 110 not defined */
+ CLK_NONE, /* 111 not defined */
};
static void imx_gpt_set_freq(IMXGPTState *s)
{
uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
- uint32_t freq = imx_clock_frequency(s->ccm, imx_gpt_clocks[clksrc])
- / (1 + s->pr);
- s->freq = freq;
- DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, freq);
+ s->freq = imx_ccm_get_clock_frequency(s->ccm,
+ imx_gpt_clocks[clksrc]) / (1 + s->pr);
- if (freq) {
- ptimer_set_freq(s->timer, freq);
+ DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
+
+ if (s->freq) {
+ ptimer_set_freq(s->timer, s->freq);
}
}
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)) {
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 */