blob: 20b9dc315001dc0a614ea1497bd9bcff8157b0da [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
116
117
118 clk_dm(IMXRT1170_CLK_RCOSC_48M,
119 imx_clk_fixed_factor("rcosc48M", "rcosc16M", 3, 1));
120 clk_dm(IMXRT1170_CLK_RCOSC_400M,
121 imx_clk_fixed_factor("rcosc400M", "rcosc16M", 25, 1));
122 clk_dm(IMXRT1170_CLK_RCOSC_48M_DIV2,
123 imx_clk_fixed_factor("rcosc48M_div2", "rcosc48M", 1, 2));
124
125
126 clk_dm(IMXRT1170_CLK_PLL_ARM,
127 imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm", "osc",
128 base + 0x200, 0xff));
129 clk_dm(IMXRT1170_CLK_PLL3,
130 imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll3_sys", "osc",
131 base + 0x210, 1));
132 clk_dm(IMXRT1170_CLK_PLL2,
133 imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll2_sys", "osc",
134 base + 0x240, 1));
135
136 clk_dm(IMXRT1170_CLK_PLL3_PFD0,
137 imx_clk_pfd("pll3_pfd0", "pll3_sys", base + 0x230, 0));
138 clk_dm(IMXRT1170_CLK_PLL3_PFD1,
139 imx_clk_pfd("pll3_pfd1", "pll3_sys", base + 0x230, 1));
140 clk_dm(IMXRT1170_CLK_PLL3_PFD2,
141 imx_clk_pfd("pll3_pfd2", "pll3_sys", base + 0x230, 2));
142 clk_dm(IMXRT1170_CLK_PLL3_PFD3,
143 imx_clk_pfd("pll3_pfd3", "pll3_sys", base + 0x230, 3));
144
145 clk_dm(IMXRT1170_CLK_PLL2_PFD0,
146 imx_clk_pfd("pll2_pfd0", "pll2_sys", base + 0x270, 0));
147 clk_dm(IMXRT1170_CLK_PLL2_PFD1,
148 imx_clk_pfd("pll2_pfd1", "pll2_sys", base + 0x270, 1));
149 clk_dm(IMXRT1170_CLK_PLL2_PFD2,
150 imx_clk_pfd("pll2_pfd2", "pll2_sys", base + 0x270, 2));
151 clk_dm(IMXRT1170_CLK_PLL2_PFD3,
152 imx_clk_pfd("pll2_pfd3", "pll2_sys", base + 0x270, 3));
153
154 clk_dm(IMXRT1170_CLK_PLL3_DIV2,
155 imx_clk_fixed_factor("pll3_div2", "pll3_sys", 1, 2));
156
157 /* CCM clocks */
158 base = dev_read_addr_ptr(dev);
159 if (base == (void *)FDT_ADDR_T_NONE)
160 return -EINVAL;
161
162 clk_dm(IMXRT1170_CLK_LPUART1_SEL,
163 imx_clk_mux("lpuart1_sel", base + (25 * 0x80), 8, 3,
164 lpuart1_sels, ARRAY_SIZE(lpuart1_sels)));
165 clk_dm(IMXRT1170_CLK_LPUART1,
166 imx_clk_divider("lpuart1", "lpuart1_sel",
167 base + (25 * 0x80), 0, 8));
168
169 clk_dm(IMXRT1170_CLK_USDHC1_SEL,
170 imx_clk_mux("usdhc1_sel", base + (58 * 0x80), 8, 3,
171 usdhc1_sels, ARRAY_SIZE(usdhc1_sels)));
172 clk_dm(IMXRT1170_CLK_USDHC1,
173 imx_clk_divider("usdhc1", "usdhc1_sel",
174 base + (58 * 0x80), 0, 8));
175
176 clk_dm(IMXRT1170_CLK_GPT1_SEL,
177 imx_clk_mux("gpt1_sel", base + (14 * 0x80), 8, 3,
178 gpt1_sels, ARRAY_SIZE(gpt1_sels)));
179 clk_dm(IMXRT1170_CLK_GPT1,
180 imx_clk_divider("gpt1", "gpt1_sel",
181 base + (14 * 0x80), 0, 8));
182
183 clk_dm(IMXRT1170_CLK_SEMC_SEL,
184 imx_clk_mux("semc_sel", base + (4 * 0x80), 8, 3,
185 semc_sels, ARRAY_SIZE(semc_sels)));
186 clk_dm(IMXRT1170_CLK_SEMC,
187 imx_clk_divider("semc", "semc_sel",
188 base + (4 * 0x80), 0, 8));
189 struct clk *clk, *clk1;
190
191 clk_get_by_id(IMXRT1170_CLK_PLL2_PFD2, &clk);
192
193 clk_get_by_id(IMXRT1170_CLK_SEMC_SEL, &clk1);
194 clk_enable(clk1);
195 clk_set_parent(clk1, clk);
196
197 clk_get_by_id(IMXRT1170_CLK_SEMC, &clk);
198 clk_enable(clk);
199 clk_set_rate(clk, 132000000UL);
200
201 clk_get_by_id(IMXRT1170_CLK_GPT1, &clk);
202 clk_enable(clk);
203 clk_set_rate(clk, 32000000UL);
204
205 return 0;
206}
207
208static const struct udevice_id imxrt1170_clk_ids[] = {
209 { .compatible = "fsl,imxrt1170-ccm" },
210 { },
211};
212
213U_BOOT_DRIVER(imxrt1170_clk) = {
214 .name = "clk_imxrt1170",
215 .id = UCLASS_CLK,
216 .of_match = imxrt1170_clk_ids,
217 .ops = &imxrt1170_clk_ops,
218 .probe = imxrt1170_clk_probe,
219 .flags = DM_FLAG_PRE_RELOC,
220};