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