1 /* SPDX-License-Identifier: BSD-3-Clause */
5 #include <soc/ipq_timer.h>
9 * DGT runs at 25 MHz / 4, or 6.25 ticks per microsecond
11 #define DGT_MHZ_NUM 25
14 #define TIMER_TICKS(us) ((DGT_MHZ_NUM*(us) + (DGT_MHZ_DEN - 1)) / DGT_MHZ_DEN)
15 #define TIMER_USECS(ticks) (DGT_MHZ_DEN*(ticks) / DGT_MHZ_NUM)
17 /* Clock divider values for the timer. */
18 #define DGT_CLK_DIV_1 0
19 #define DGT_CLK_DIV_2 1
20 #define DGT_CLK_DIV_3 2
21 #define DGT_CLK_DIV_4 3
24 * init_timer - initialize timer
29 writel_i(0, DGT_ENABLE
);
31 /* DGT uses TCXO source which is 25MHz.
32 * The timer should run at 1/4th the frequency of TCXO
33 * according to clock plan.
34 * Set clock divider to 4.
36 writel_i(DGT_CLK_DIV_4
, DGT_CLK_CTL
);
39 writel_i(0, DGT_CLEAR
);
40 writel_i(DGT_ENABLE_EN
, DGT_ENABLE
);
44 * udelay - generates micro second delay.
45 * @param usec: delay duration in microseconds
47 void udelay(unsigned int usec
)
52 uint32_t curr_ticks
= 0;
54 /* Calculate number of ticks required. */
55 ticks
= TIMER_TICKS(usec
);
57 /* Obtain the current timer value. */
58 last
= readl_i(DGT_COUNT_VAL
);
60 /* Loop until the right number of ticks. */
61 while (curr_ticks
< ticks
) {
62 now
= readl_i(DGT_COUNT_VAL
);
63 curr_ticks
+= now
- last
;
68 void timer_monotonic_get(struct mono_time
*mt
)
70 mono_time_set_usecs(mt
, TIMER_USECS(readl_i(DGT_COUNT_VAL
)));