blob: 077dd1bf02d3cbae359f142442fe38fa29694ee4 [file] [log] [blame]
Jesse Taube60a71f62022-07-26 01:43:43 -04001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2022
4 * Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
5 */
6
7#include <common.h>
8#include <clk.h>
9#include <clk-uclass.h>
10#include <dm.h>
11#include <log.h>
12#include <asm/arch/clock.h>
13#include <asm/arch/imx-regs.h>
14#include <dt-bindings/clock/imxrt1170-clock.h>
15
16#include "clk.h"
17
18static ulong imxrt1170_clk_get_rate(struct clk *clk)
19{
20 struct clk *c;
21 int ret;
22
23 debug("%s(#%lu)\n", __func__, clk->id);
24
25 ret = clk_get_by_id(clk->id, &c);
26 if (ret)
27 return ret;
28
29 return clk_get_rate(c);
30}
31
32static ulong imxrt1170_clk_set_rate(struct clk *clk, ulong rate)
33{
34 struct clk *c;
35 int ret;
36
37 debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
38
39 ret = clk_get_by_id(clk->id, &c);
40 if (ret)
41 return ret;
42
43 return clk_set_rate(c, rate);
44}
45
46static int __imxrt1170_clk_enable(struct clk *clk, bool enable)
47{
48 struct clk *c;
49 int ret;
50
51 debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
52
53 ret = clk_get_by_id(clk->id, &c);
54 if (ret)
55 return ret;
56
57 if (enable)
58 ret = clk_enable(c);
59 else
60 ret = clk_disable(c);
61
62 return ret;
63}
64
65static int imxrt1170_clk_disable(struct clk *clk)
66{
67 return __imxrt1170_clk_enable(clk, 0);
68}
69
70static int imxrt1170_clk_enable(struct clk *clk)
71{
72 return __imxrt1170_clk_enable(clk, 1);
73}
74
75static int imxrt1170_clk_set_parent(struct clk *clk, struct clk *parent)
76{
77 struct clk *c, *cp;
78 int ret;
79
80 debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
81
82 ret = clk_get_by_id(clk->id, &c);
83 if (ret)
84 return ret;
85
86 ret = clk_get_by_id(parent->id, &cp);
87 if (ret)
88 return ret;
89
90 return clk_set_parent(c, cp);
91}
92
93static struct clk_ops imxrt1170_clk_ops = {
94 .set_rate = imxrt1170_clk_set_rate,
95 .get_rate = imxrt1170_clk_get_rate,
96 .enable = imxrt1170_clk_enable,
97 .disable = imxrt1170_clk_disable,
98 .set_parent = imxrt1170_clk_set_parent,
99};
100
101static const char * const lpuart1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
102"pll3_div2", "pll1_div5", "pll2_sys", "pll2_pfd3"};
103static const char * const gpt1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
104"pll3_div2", "pll1_div5", "pll3_pfd2", "pll3_pfd3"};
105static const char * const usdhc1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
106"pll2_pfd2", "pll2_pfd0", "pll1_div5", "pll_arm"};
107static const char * const semc_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
108"pll1_div5", "pll2_sys", "pll2_pfd2", "pll3_pfd0"};
109
110static int imxrt1170_clk_probe(struct udevice *dev)
111{
112 void *base;
113
114 /* Anatop clocks */
115 base = (void *)ofnode_get_addr(ofnode_by_compatible(ofnode_null(), "fsl,imxrt-anatop"));
116
117
118
119 clk_dm(IMXRT1170_CLK_RCOSC_48M,
120 imx_clk_fixed_factor("rcosc48M", "rcosc16M", 3, 1));
121 clk_dm(IMXRT1170_CLK_RCOSC_400M,
122 imx_clk_fixed_factor("rcosc400M", "rcosc16M", 25, 1));
123 clk_dm(IMXRT1170_CLK_RCOSC_48M_DIV2,
124 imx_clk_fixed_factor("rcosc48M_div2", "rcosc48M", 1, 2));
125
126
127 clk_dm(IMXRT1170_CLK_PLL_ARM,
128 imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm", "osc",
129 base + 0x200, 0xff));
130 clk_dm(IMXRT1170_CLK_PLL3,
131 imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll3_sys", "osc",
132 base + 0x210, 1));
133 clk_dm(IMXRT1170_CLK_PLL2,
134 imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll2_sys", "osc",
135 base + 0x240, 1));
136
137 clk_dm(IMXRT1170_CLK_PLL3_PFD0,
138 imx_clk_pfd("pll3_pfd0", "pll3_sys", base + 0x230, 0));
139 clk_dm(IMXRT1170_CLK_PLL3_PFD1,
140 imx_clk_pfd("pll3_pfd1", "pll3_sys", base + 0x230, 1));
141 clk_dm(IMXRT1170_CLK_PLL3_PFD2,
142 imx_clk_pfd("pll3_pfd2", "pll3_sys", base + 0x230, 2));
143 clk_dm(IMXRT1170_CLK_PLL3_PFD3,
144 imx_clk_pfd("pll3_pfd3", "pll3_sys", base + 0x230, 3));
145
146 clk_dm(IMXRT1170_CLK_PLL2_PFD0,
147 imx_clk_pfd("pll2_pfd0", "pll2_sys", base + 0x270, 0));
148 clk_dm(IMXRT1170_CLK_PLL2_PFD1,
149 imx_clk_pfd("pll2_pfd1", "pll2_sys", base + 0x270, 1));
150 clk_dm(IMXRT1170_CLK_PLL2_PFD2,
151 imx_clk_pfd("pll2_pfd2", "pll2_sys", base + 0x270, 2));
152 clk_dm(IMXRT1170_CLK_PLL2_PFD3,
153 imx_clk_pfd("pll2_pfd3", "pll2_sys", base + 0x270, 3));
154
155 clk_dm(IMXRT1170_CLK_PLL3_DIV2,
156 imx_clk_fixed_factor("pll3_div2", "pll3_sys", 1, 2));
157
158 /* CCM clocks */
159 base = dev_read_addr_ptr(dev);
160 if (base == (void *)FDT_ADDR_T_NONE)
161 return -EINVAL;
162
163 clk_dm(IMXRT1170_CLK_LPUART1_SEL,
164 imx_clk_mux("lpuart1_sel", base + (25 * 0x80), 8, 3,
165 lpuart1_sels, ARRAY_SIZE(lpuart1_sels)));
166 clk_dm(IMXRT1170_CLK_LPUART1,
167 imx_clk_divider("lpuart1", "lpuart1_sel",
168 base + (25 * 0x80), 0, 8));
169
170 clk_dm(IMXRT1170_CLK_USDHC1_SEL,
171 imx_clk_mux("usdhc1_sel", base + (58 * 0x80), 8, 3,
172 usdhc1_sels, ARRAY_SIZE(usdhc1_sels)));
173 clk_dm(IMXRT1170_CLK_USDHC1,
174 imx_clk_divider("usdhc1", "usdhc1_sel",
175 base + (58 * 0x80), 0, 8));
176
177 clk_dm(IMXRT1170_CLK_GPT1_SEL,
178 imx_clk_mux("gpt1_sel", base + (14 * 0x80), 8, 3,
179 gpt1_sels, ARRAY_SIZE(gpt1_sels)));
180 clk_dm(IMXRT1170_CLK_GPT1,
181 imx_clk_divider("gpt1", "gpt1_sel",
182 base + (14 * 0x80), 0, 8));
183
184 clk_dm(IMXRT1170_CLK_SEMC_SEL,
185 imx_clk_mux("semc_sel", base + (4 * 0x80), 8, 3,
186 semc_sels, ARRAY_SIZE(semc_sels)));
187 clk_dm(IMXRT1170_CLK_SEMC,
188 imx_clk_divider("semc", "semc_sel",
189 base + (4 * 0x80), 0, 8));
190 struct clk *clk, *clk1;
191
192 clk_get_by_id(IMXRT1170_CLK_PLL2_PFD2, &clk);
193
194 clk_get_by_id(IMXRT1170_CLK_SEMC_SEL, &clk1);
195 clk_enable(clk1);
196 clk_set_parent(clk1, clk);
197
198 clk_get_by_id(IMXRT1170_CLK_SEMC, &clk);
199 clk_enable(clk);
200 clk_set_rate(clk, 132000000UL);
201
202 clk_get_by_id(IMXRT1170_CLK_GPT1, &clk);
203 clk_enable(clk);
204 clk_set_rate(clk, 32000000UL);
205
206 return 0;
207}
208
209static const struct udevice_id imxrt1170_clk_ids[] = {
210 { .compatible = "fsl,imxrt1170-ccm" },
211 { },
212};
213
214U_BOOT_DRIVER(imxrt1170_clk) = {
215 .name = "clk_imxrt1170",
216 .id = UCLASS_CLK,
217 .of_match = imxrt1170_clk_ids,
218 .ops = &imxrt1170_clk_ops,
219 .probe = imxrt1170_clk_probe,
220 .flags = DM_FLAG_PRE_RELOC,
221};