Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-spi into next
[platform/kernel/u-boot.git] / drivers / timer / imx-gpt-timer.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2021
4  * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
5  */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <fdtdec.h>
11 #include <timer.h>
12 #include <dm/device_compat.h>
13
14 #include <asm/io.h>
15
16 #define GPT_CR_EN                       BIT(0)
17 #define GPT_CR_FRR                      BIT(9)
18 #define GPT_CR_EN_24M                   BIT(10)
19 #define GPT_CR_SWR                      BIT(15)
20
21 #define GPT_PR_PRESCALER24M_MASK        0x0000F000
22 #define GPT_PR_PRESCALER24M_SHIFT       12
23 #define GPT_PR_PRESCALER24M_MAX (GPT_PR_PRESCALER24M_MASK >> GPT_PR_PRESCALER24M_SHIFT)
24 #define GPT_PR_PRESCALER_MASK           0x00000FFF
25 #define GPT_PR_PRESCALER_SHIFT          0
26 #define GPT_PR_PRESCALER_MAX            (GPT_PR_PRESCALER_MASK >> GPT_PR_PRESCALER_SHIFT)
27
28 #define GPT_CLKSRC_IPG_CLK              (1 << 6)
29 #define GPT_CLKSRC_IPG_CLK_24M          (5 << 6)
30
31 /* If CONFIG_SYS_HZ_CLOCK not specified et's default to 3Mhz */
32 #ifndef CONFIG_SYS_HZ_CLOCK
33 #define CONFIG_SYS_HZ_CLOCK             3000000
34 #endif
35
36 struct imx_gpt_timer_regs {
37         u32 cr;
38         u32 pr;
39         u32 sr;
40         u32 ir;
41         u32 ocr1;
42         u32 ocr2;
43         u32 ocr3;
44         u32 icr1;
45         u32 icr2;
46         u32 cnt;
47 };
48
49 struct imx_gpt_timer_priv {
50         struct imx_gpt_timer_regs *base;
51 };
52
53 static u64 imx_gpt_timer_get_count(struct udevice *dev)
54 {
55         struct imx_gpt_timer_priv *priv = dev_get_priv(dev);
56         struct imx_gpt_timer_regs *regs = priv->base;
57
58         return timer_conv_64(readl(&regs->cnt));
59 }
60
61 static int imx_gpt_setup(struct imx_gpt_timer_regs *regs, u32 rate)
62 {
63         u32 prescaler = (rate / CONFIG_SYS_HZ_CLOCK) - 1;
64
65         /* Reset the timer */
66         setbits_le32(&regs->cr, GPT_CR_SWR);
67
68         /* Wait for timer to finish reset */
69         while (readl(&regs->cr) & GPT_CR_SWR)
70                 ;
71
72         if (rate == 24000000UL) {
73                 /* Set timer frequency if using 24M clock source */
74                 if (prescaler > GPT_PR_PRESCALER24M_MAX)
75                         return -EINVAL;
76
77                 /* Set 24M prescaler */
78                 writel((prescaler << GPT_PR_PRESCALER24M_SHIFT), &regs->pr);
79                 /* Set Oscillator as clock source, enable 24M input and set gpt
80                  * in free-running mode
81                  */
82                 writel(GPT_CLKSRC_IPG_CLK_24M | GPT_CR_EN_24M | GPT_CR_FRR, &regs->cr);
83         } else {
84                 if (prescaler > GPT_PR_PRESCALER_MAX)
85                         return -EINVAL;
86
87                 /* Set prescaler */
88                 writel((prescaler << GPT_PR_PRESCALER_SHIFT), &regs->pr);
89                 /* Set Peripheral as clock source and set gpt in free-running
90                  * mode
91                  */
92                 writel(GPT_CLKSRC_IPG_CLK | GPT_CR_FRR, &regs->cr);
93         }
94
95         /* Start timer */
96         setbits_le32(&regs->cr, GPT_CR_EN);
97
98         return 0;
99 }
100
101 static int imx_gpt_timer_probe(struct udevice *dev)
102 {
103         struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
104         struct imx_gpt_timer_priv *priv = dev_get_priv(dev);
105         struct imx_gpt_timer_regs *regs;
106         struct clk clk;
107         fdt_addr_t addr;
108         u32 clk_rate;
109         int ret;
110
111         addr = dev_read_addr(dev);
112         if (addr == FDT_ADDR_T_NONE)
113                 return -EINVAL;
114
115         priv->base = (struct imx_gpt_timer_regs *)addr;
116         regs = priv->base;
117
118         ret = clk_get_by_index(dev, 0, &clk);
119         if (ret < 0)
120                 return ret;
121
122         ret = clk_enable(&clk);
123         if (ret) {
124                 dev_err(dev, "Failed to enable clock\n");
125                 return ret;
126         }
127
128         /* Get timer clock rate */
129         clk_rate = clk_get_rate(&clk);
130         if (clk_rate <= 0) {
131                 dev_err(dev, "Could not get clock rate...\n");
132                 return -EINVAL;
133         }
134
135         ret = imx_gpt_setup(regs, clk_rate);
136         if (ret) {
137                 dev_err(dev, "Could not setup timer\n");
138                 return ret;
139         }
140
141         uc_priv->clock_rate = CONFIG_SYS_HZ_CLOCK;
142
143         return 0;
144 }
145
146 static const struct timer_ops imx_gpt_timer_ops = {
147         .get_count = imx_gpt_timer_get_count,
148 };
149
150 static const struct udevice_id imx_gpt_timer_ids[] = {
151         { .compatible = "fsl,imxrt-gpt" },
152         {}
153 };
154
155 U_BOOT_DRIVER(imx_gpt_timer) = {
156         .name = "imx_gpt_timer",
157         .id = UCLASS_TIMER,
158         .of_match = imx_gpt_timer_ids,
159         .priv_auto = sizeof(struct imx_gpt_timer_priv),
160         .probe = imx_gpt_timer_probe,
161         .ops = &imx_gpt_timer_ops,
162 };