1/*
2 * Copyright 2019, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#include <stdio.h>
14#include <assert.h>
15#include <errno.h>
16#include <stdlib.h>
17#include <stdint.h>
18
19#include <utils/util.h>
20
21#include <platsupport/timer.h>
22#include <platsupport/plat/timer.h>
23
24/* The GPT status register is w1c (write 1 to clear), and there are 6 status bits in the iMX
25   status register, so writing the value 0b111111 = 0x3F will clear it. */
26#define GPT_STATUS_REGISTER_CLEAR 0x3F
27
28#define CLEANUP_FAIL_TEXT "Failed to cleanup the GPT after failing to initialise it"
29
30/* GPT CONTROL REGISTER BITS */
31typedef enum {
32    /*
33     * This bit enables the GPT.
34     */
35    EN = 0,
36
37    /*
38     * When GPT is disabled (EN=0), then
39     * both Main Counter and Prescaler Counter freeze their count at
40     * current count values. The ENMOD bit determines the value of
41     * the GPT counter when Counter is enabled again (if the EN bit is set).
42     *
43     *   If the ENMOD bit is 1, then the Main Counter and Prescaler Counter
44     *   values are reset to 0 after GPT is enabled (EN=1).
45     *
46     *   If the ENMOD bit is 0, then the Main Counter and Prescaler Counter
47     *   restart counting from their frozen values after GPT is enabled (EN=1).
48     *
49     *   If GPT is programmed to be disabled in a low power mode (STOP/WAIT), then
50     *   the Main Counter and Prescaler Counter freeze at their current count
51     *   values when the GPT enters low power mode.
52     *
53     *   When GPT exits low power mode, the Main Counter and Prescaler Counter start
54     *   counting from their frozen values, regardless of the ENMOD bit value.
55     *
56     *   Setting the SWR bit will clear the Main Counter and Prescalar Counter values,
57     *   regardless of the value of EN or ENMOD bits.
58     *
59     *   A hardware reset resets the ENMOD bit.
60     *   A software reset does not affect the ENMOD bit.
61     */
62    ENMOD = 1,
63
64    /*
65     * This read/write control bit enables the operation of the GPT
66     *  during debug mode
67     */
68    DBGEN = 2,
69
70    /*
71     *  This read/write control bit enables the operation of the GPT
72     *  during wait mode
73     */
74    WAITEN = 3,
75
76    /*
77     * This read/write control bit enables the operation of the GPT
78     *  during doze mode
79     */
80    DOZEN = 4,
81
82    /*
83     * This read/write control bit enables the operation of the GPT
84     *  during stop mode
85     */
86    STOPEN = 5,
87
88    /*
89     * bits 6-8 -  These bits selects the clock source for the
90     *  prescaler and subsequently be used to run the GPT counter.
91     *  the following sources are available on i.MX 7 board:
92     *  000: no clock
93     *  001: peripheral clock
94     *  010: high frequency reference clock
95     *  011: external clock (CLKIN)
96     *  100: low frequency reference clock 32 kHZ
97     *  101: crystal oscillator as reference clock 24 MHz
98     *  others: reserved
99     *  by default the peripheral clock is used.
100     *
101     *  For imx6 :
102     *  000: no clock
103     *  001: peripheral clock
104     *  010: high frequency reference clock
105     *  011: external clock (CLKIN)
106     *  100: low frequency reference clock
107     *  101: crystal oscillator divided by 8 as reference clock
108     *  111: crystal osscillator as reference clock
109     */
110    CLKSRC = 6,
111
112    /*
113     * Freerun or Restart mode.
114     *
115     * 0 Restart mode
116     * 1 Freerun mode
117     */
118    FRR = 9,
119
120    /* for i.MX7 only
121     * enable the 24 MHz clock input from crystal
122     * a hardware reset resets the EN_24M bit.
123     * a software reset dose not affect the EN_24M bit.
124     * 0: disabled
125     * 1: enabled
126     */
127    EN_24M = 10,
128
129    /*
130     * Software reset.
131     *
132     * This bit is set when the module is in reset state and is cleared
133     * when the reset procedure is over. Writing a 1 to this bit
134     * produces a single wait state write cycle. Setting this bit
135     * resets all the registers to their default reset values except
136     * for the EN, ENMOD, STOPEN, DOZEN, WAITEN and DBGEN bits in this
137     *  control register.
138     */
139    SWR = 15,
140
141    /* Input capture channel operating modes */
142    IM1 = 16, IM2 = 18,
143
144    /* Output compare channel operating modes */
145    OM1 = 20, OM2 = 23, OM3 = 26,
146
147    /* Force output compare channel bits */
148    FO1 = 29, FO2 = 30, FO3 = 31
149
150} gpt_control_reg;
151
152/* bits in the interrupt/status regiser */
153enum gpt_interrupt_register_bits {
154
155    /* Output compare interrupt enable bits */
156    OF1IE = 0, OF2IE = 1, OF3IE = 2,
157
158    /* Input capture interrupt enable bits */
159    IF1IE = 3, IF2IE = 4,
160
161    /* Rollover interrupt enabled */
162    ROV = 5,
163};
164
165/* Memory map for GPT. */
166struct gpt_map {
167    /* gpt control register */
168    uint32_t gptcr;
169    /* gpt prescaler register */
170    uint32_t gptpr;
171    /* gpt status register */
172    uint32_t gptsr;
173    /* gpt interrupt register */
174    uint32_t gptir;
175    /* gpt output compare register 1 */
176    uint32_t gptcr1;
177    /* gpt output compare register 2 */
178    uint32_t gptcr2;
179    /* gpt output compare register 3 */
180    uint32_t gptcr3;
181    /* gpt input capture register 1 */
182    uint32_t gpticr1;
183    /* gpt input capture register 2 */
184    uint32_t gpticr2;
185    /* gpt counter register */
186    uint32_t gptcnt;
187};
188
189int gpt_start(gpt_t *gpt)
190{
191    gpt->gpt_map->gptcr |= BIT(EN);
192    gpt->high_bits = 0;
193    return 0;
194}
195
196int gpt_stop(gpt_t *gpt)
197{
198    /* Disable timer. */
199    gpt->gpt_map->gptcr &= ~(BIT(EN));
200    gpt->high_bits = 0;
201    return 0;
202}
203
204static void gpt_handle_irq(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void *ack_data)
205{
206    assert(data != NULL);
207    gpt_t *gpt = data;
208    /* we've only set the GPT to interrupt on overflow */
209    if (gpt->gpt_map->gptcr & BIT(FRR)) {
210        /* free-run mode, we should only enable the rollover interrupt */
211        if (gpt->gpt_map->gptsr & BIT(ROV)) {
212            gpt->high_bits++;
213        }
214    }
215    /* clear the interrupt status register */
216    gpt->gpt_map->gptsr = GPT_STATUS_REGISTER_CLEAR;
217    /* acknowledge the interrupt and call the user callback if any */
218    ZF_LOGF_IF(acknowledge_fn(ack_data), "Failed to acknowledge the interrupt from the GPT");
219    if (gpt->user_callback) {
220        gpt->user_callback(gpt->user_callback_token, LTIMER_OVERFLOW_EVENT);
221    }
222}
223
224uint64_t gpt_get_time(gpt_t *gpt)
225{
226    uint32_t low_bits = gpt->gpt_map->gptcnt;
227    uint32_t high_bits = gpt->high_bits;
228    if (gpt->gpt_map->gptsr) {
229        /* irq has come in */
230        high_bits++;
231    }
232
233    uint64_t value = ((uint64_t) high_bits << 32llu) + low_bits;
234    /* convert to ns */
235    uint64_t ns = (value / (uint64_t)GPT_FREQ) * NS_IN_US * (gpt->prescaler + 1);
236    return ns;
237}
238
239static int allocate_register_callback(pmem_region_t pmem, unsigned curr_num, size_t num_regs, void *token)
240{
241    assert(token != NULL);
242    /* Should only be called once. I.e. only one register field */
243    assert(curr_num == 0);
244    gpt_t *gpt = token;
245    gpt->gpt_map = (volatile struct gpt_map *) ps_pmem_map(&gpt->io_ops, pmem, false, PS_MEM_NORMAL);
246    if (!gpt->gpt_map) {
247        ZF_LOGE("Failed to map in registers for the GPT");
248        return EIO;
249    }
250    gpt->timer_pmem = pmem;
251    return 0;
252}
253
254static int allocate_irq_callback(ps_irq_t irq, unsigned curr_num, size_t num_irqs, void *token)
255{
256    assert(token != NULL);
257    /* Should only be called once. I.e. only one interrupt field */
258    assert(curr_num == 0);
259    gpt_t *gpt = token;
260    gpt->irq_id = ps_irq_register(&gpt->io_ops.irq_ops, irq, gpt_handle_irq, gpt);
261    if (gpt->irq_id < 0) {
262        ZF_LOGE("Failed to register the GPT interrupt with the IRQ interface");
263        return EIO;
264    }
265    return 0;
266}
267
268int gpt_init(gpt_t *gpt, gpt_config_t config)
269{
270    /* Initialise the structure */
271    gpt->io_ops = config.io_ops;
272    gpt->user_callback = config.user_callback;
273    gpt->user_callback_token = config.user_callback_token;
274    gpt->irq_id = PS_INVALID_IRQ_ID;
275    gpt->prescaler = config.prescaler;
276
277    /* Read the timer's path in the DTB */
278    ps_fdt_cookie_t *cookie = NULL;
279    int error = ps_fdt_read_path(&gpt->io_ops.io_fdt, &gpt->io_ops.malloc_ops, config.device_path, &cookie);
280    if (error) {
281        ZF_LOGF_IF(ps_fdt_cleanup_cookie(&gpt->io_ops.malloc_ops, cookie), CLEANUP_FAIL_TEXT);
282        ZF_LOGF_IF(gpt_destroy(gpt), CLEANUP_FAIL_TEXT);
283        return ENODEV;
284    }
285
286    /* Walk the registers and allocate them */
287    error = ps_fdt_walk_registers(&gpt->io_ops.io_fdt, cookie, allocate_register_callback, gpt);
288    if (error) {
289        ZF_LOGF_IF(ps_fdt_cleanup_cookie(&gpt->io_ops.malloc_ops, cookie), CLEANUP_FAIL_TEXT);
290        ZF_LOGF_IF(gpt_destroy(gpt), CLEANUP_FAIL_TEXT);
291        return ENODEV;
292    }
293
294    /* Walk the interrupts and allocate the first */
295    error = ps_fdt_walk_irqs(&gpt->io_ops.io_fdt, cookie, allocate_irq_callback, gpt);
296    if (error) {
297        ZF_LOGF_IF(ps_fdt_cleanup_cookie(&gpt->io_ops.malloc_ops, cookie), CLEANUP_FAIL_TEXT);
298        ZF_LOGF_IF(gpt_destroy(gpt), CLEANUP_FAIL_TEXT);
299        return ENODEV;
300    }
301
302    ZF_LOGF_IF(ps_fdt_cleanup_cookie(&gpt->io_ops.malloc_ops, cookie),
303               "Failed to cleanup the FDT cookie after initialising the GPT");
304
305    uint32_t gptcr = 0;
306    if (gpt == NULL) {
307        return EINVAL;
308    }
309
310    /* Disable GPT. */
311    gpt->gpt_map->gptcr = 0;
312    gpt->gpt_map->gptsr = GPT_STATUS_REGISTER_CLEAR;
313
314    /* Configure GPT. */
315    gpt->gpt_map->gptcr = 0 | BIT(SWR); /* Reset the GPT */
316    /* SWR will be 0 when the reset is done */
317    while (gpt->gpt_map->gptcr & BIT(SWR));
318    /* GPT can do more but for this just set it as free running  so we can tell the time */
319    gptcr = BIT(FRR) | BIT(ENMOD);
320
321#ifdef CONFIG_PLAT_IMX7
322    /* eanble the 24MHz source and select the oscillator as CLKSRC */
323    gptcr |= (BIT(EN_24M) | (5u << CLKSRC));
324#else
325    gptcr |= BIT(CLKSRC);
326#endif
327
328    gpt->gpt_map->gptcr = gptcr;
329    gpt->gpt_map->gptir = BIT(ROV); /* Interrupt when the timer overflows */
330
331    /* The prescaler register has two parts when the 24 MHz clocksource is used.
332     * The 24MHz crystal clock is devided by the (the top 15-12 bits + 1) before
333     * it is fed to the CLKSRC field.
334     * The clock selected by the CLKSRC is divided by the (the 11-0 bits + ) again.
335     * For unknown reason, when the prescaler for the 24MHz clock is set to zero, which
336     * is valid according to the manual, the GPTCNT register does not work. So we
337     * set the value at least to 1, using a 12MHz clocksource.
338     */
339
340#ifdef CONFIG_PLAT_IMX7
341    gpt->gpt_map->gptpr = config.prescaler | (1u << 12);
342#else
343    gpt->gpt_map->gptpr = config.prescaler; /* Set the prescaler */
344#endif
345
346    gpt->high_bits = 0;
347
348    return 0;
349}
350
351int gpt_destroy(gpt_t *gpt)
352{
353    if (gpt->gpt_map) {
354        ZF_LOGF_IF(gpt_stop(gpt), "Failed to stop the GPT before de-allocating it");
355        ps_io_unmap(&gpt->io_ops.io_mapper, (void *) gpt->gpt_map, (size_t) gpt->timer_pmem.length);
356    }
357
358    if (gpt->irq_id != PS_INVALID_IRQ_ID) {
359        ZF_LOGF_IF(ps_irq_unregister(&gpt->io_ops.irq_ops, gpt->irq_id), "Failed to unregister IRQ");
360    }
361
362    return 0;
363}
364
365int gpt_set_timeout(gpt_t  *gpt, uint64_t ns, bool periodic)
366{
367    uint32_t gptcr = 0;
368    uint64_t counter_value = (uint64_t)(GPT_FREQ / (gpt->prescaler + 1)) * (ns / 1000ULL);
369    if (counter_value >= (1ULL << 32)) {
370        /* Counter too large to be stored in 32 bits. */
371        ZF_LOGW("ns too high %llu, going to be capping it\n", ns);
372        counter_value = UINT32_MAX;
373    }
374
375    gpt->gpt_map->gptcr = 0;
376    gpt->gpt_map->gptsr = GPT_STATUS_REGISTER_CLEAR;
377    gpt->gpt_map->gptcr = BIT(SWR);
378    while (gpt->gpt_map->gptcr & BIT(SWR));
379    gptcr = (periodic ? 0 : BIT(FRR));
380
381#ifdef CONFIG_PLAT_IMX7
382    gptcr |= BIT(EN_24M) | (5u << CLKSRC);
383#else
384    gptcr |= BIT(CLKSRC);
385#endif
386
387    gpt->gpt_map->gptcr = gptcr;
388    gpt->gpt_map->gptcr1 = (uint32_t)counter_value;
389    while (gpt->gpt_map->gptcr1 != counter_value) {
390        gpt->gpt_map->gptcr1 = (uint32_t)counter_value;
391    }
392
393#ifdef CONFIG_PLAT_IMX7
394    gpt->gpt_map->gptpr = gpt->prescaler | BIT(12);
395#else
396    gpt->gpt_map->gptpr = gpt->prescaler; /* Set the prescaler */
397#endif
398
399    gpt->gpt_map->gptir = 1;
400    gpt->gpt_map->gptcr |= BIT(EN);
401
402    return 0;
403}
404