blob: bfd5dd6c464457af1d9e19344e555a984a36ef2f [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"};
Jonathan Currierc58ac512025-05-07 03:36:21 -0500108static const char * const flexspi1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
109"pll3_pdf0", "pll2_clk", "pll2_pfd2", "pll3_clk"};
Jesse Taube60a71f62022-07-26 01:43:43 -0400110
111static int imxrt1170_clk_probe(struct udevice *dev)
112{
113 void *base;
114
115 /* Anatop clocks */
116 base = (void *)ofnode_get_addr(ofnode_by_compatible(ofnode_null(), "fsl,imxrt-anatop"));
117
Jesse Taube60a71f62022-07-26 01:43:43 -0400118 clk_dm(IMXRT1170_CLK_RCOSC_48M,
Marek Vasutbc0b9372025-03-23 16:58:53 +0100119 imx_clk_fixed_factor(dev, "rcosc48M", "rcosc16M", 3, 1));
Jesse Taube60a71f62022-07-26 01:43:43 -0400120 clk_dm(IMXRT1170_CLK_RCOSC_400M,
Marek Vasutbc0b9372025-03-23 16:58:53 +0100121 imx_clk_fixed_factor(dev, "rcosc400M", "rcosc16M", 25, 1));
Jesse Taube60a71f62022-07-26 01:43:43 -0400122 clk_dm(IMXRT1170_CLK_RCOSC_48M_DIV2,
Marek Vasutbc0b9372025-03-23 16:58:53 +0100123 imx_clk_fixed_factor(dev, "rcosc48M_div2", "rcosc48M", 1, 2));
Jesse Taube60a71f62022-07-26 01:43:43 -0400124
Jesse Taube60a71f62022-07-26 01:43:43 -0400125 clk_dm(IMXRT1170_CLK_PLL_ARM,
Marek Vasut8dd06762025-03-23 16:58:46 +0100126 imx_clk_pllv3(dev, IMX_PLLV3_SYS, "pll_arm", "osc",
Jesse Taube60a71f62022-07-26 01:43:43 -0400127 base + 0x200, 0xff));
128 clk_dm(IMXRT1170_CLK_PLL3,
Marek Vasut8dd06762025-03-23 16:58:46 +0100129 imx_clk_pllv3(dev, IMX_PLLV3_GENERICV2, "pll3_sys", "osc",
Jesse Taube60a71f62022-07-26 01:43:43 -0400130 base + 0x210, 1));
131 clk_dm(IMXRT1170_CLK_PLL2,
Marek Vasut8dd06762025-03-23 16:58:46 +0100132 imx_clk_pllv3(dev, IMX_PLLV3_GENERICV2, "pll2_sys", "osc",
Jesse Taube60a71f62022-07-26 01:43:43 -0400133 base + 0x240, 1));
134
135 clk_dm(IMXRT1170_CLK_PLL3_PFD0,
136 imx_clk_pfd("pll3_pfd0", "pll3_sys", base + 0x230, 0));
137 clk_dm(IMXRT1170_CLK_PLL3_PFD1,
138 imx_clk_pfd("pll3_pfd1", "pll3_sys", base + 0x230, 1));
139 clk_dm(IMXRT1170_CLK_PLL3_PFD2,
140 imx_clk_pfd("pll3_pfd2", "pll3_sys", base + 0x230, 2));
141 clk_dm(IMXRT1170_CLK_PLL3_PFD3,
142 imx_clk_pfd("pll3_pfd3", "pll3_sys", base + 0x230, 3));
143
144 clk_dm(IMXRT1170_CLK_PLL2_PFD0,
145 imx_clk_pfd("pll2_pfd0", "pll2_sys", base + 0x270, 0));
146 clk_dm(IMXRT1170_CLK_PLL2_PFD1,
147 imx_clk_pfd("pll2_pfd1", "pll2_sys", base + 0x270, 1));
148 clk_dm(IMXRT1170_CLK_PLL2_PFD2,
149 imx_clk_pfd("pll2_pfd2", "pll2_sys", base + 0x270, 2));
150 clk_dm(IMXRT1170_CLK_PLL2_PFD3,
151 imx_clk_pfd("pll2_pfd3", "pll2_sys", base + 0x270, 3));
152
153 clk_dm(IMXRT1170_CLK_PLL3_DIV2,
Marek Vasutbc0b9372025-03-23 16:58:53 +0100154 imx_clk_fixed_factor(dev, "pll3_div2", "pll3_sys", 1, 2));
Jesse Taube60a71f62022-07-26 01:43:43 -0400155
156 /* CCM clocks */
157 base = dev_read_addr_ptr(dev);
158 if (base == (void *)FDT_ADDR_T_NONE)
159 return -EINVAL;
160
161 clk_dm(IMXRT1170_CLK_LPUART1_SEL,
Marek Vasut33480a92025-03-23 16:58:34 +0100162 imx_clk_mux(dev, "lpuart1_sel", base + (25 * 0x80), 8, 3,
Jesse Taube60a71f62022-07-26 01:43:43 -0400163 lpuart1_sels, ARRAY_SIZE(lpuart1_sels)));
164 clk_dm(IMXRT1170_CLK_LPUART1,
Marek Vasut40e7edf2025-03-23 16:58:49 +0100165 imx_clk_divider(dev, "lpuart1", "lpuart1_sel",
Jesse Taube60a71f62022-07-26 01:43:43 -0400166 base + (25 * 0x80), 0, 8));
167
Jonathan Currierc58ac512025-05-07 03:36:21 -0500168 clk_dm(IMXRT1170_CLK_FLEXSPI1_SEL,
169 imx_clk_mux(dev, "flexspi1_sel", base + (20 * 0x80), 8, 3,
170 flexspi1_sels, ARRAY_SIZE(flexspi1_sels)));
171 clk_dm(IMXRT1170_CLK_FLEXSPI1,
172 imx_clk_divider(dev, "flexspi1", "flexspi1_sel",
173 base + (20 * 0x80), 0, 8));
174
Jesse Taube60a71f62022-07-26 01:43:43 -0400175 clk_dm(IMXRT1170_CLK_USDHC1_SEL,
Marek Vasut33480a92025-03-23 16:58:34 +0100176 imx_clk_mux(dev, "usdhc1_sel", base + (58 * 0x80), 8, 3,
Jesse Taube60a71f62022-07-26 01:43:43 -0400177 usdhc1_sels, ARRAY_SIZE(usdhc1_sels)));
178 clk_dm(IMXRT1170_CLK_USDHC1,
Marek Vasut40e7edf2025-03-23 16:58:49 +0100179 imx_clk_divider(dev, "usdhc1", "usdhc1_sel",
Jesse Taube60a71f62022-07-26 01:43:43 -0400180 base + (58 * 0x80), 0, 8));
181
182 clk_dm(IMXRT1170_CLK_GPT1_SEL,
Marek Vasut33480a92025-03-23 16:58:34 +0100183 imx_clk_mux(dev, "gpt1_sel", base + (14 * 0x80), 8, 3,
Jesse Taube60a71f62022-07-26 01:43:43 -0400184 gpt1_sels, ARRAY_SIZE(gpt1_sels)));
185 clk_dm(IMXRT1170_CLK_GPT1,
Marek Vasut40e7edf2025-03-23 16:58:49 +0100186 imx_clk_divider(dev, "gpt1", "gpt1_sel",
Jesse Taube60a71f62022-07-26 01:43:43 -0400187 base + (14 * 0x80), 0, 8));
188
189 clk_dm(IMXRT1170_CLK_SEMC_SEL,
Marek Vasut33480a92025-03-23 16:58:34 +0100190 imx_clk_mux(dev, "semc_sel", base + (4 * 0x80), 8, 3,
Jesse Taube60a71f62022-07-26 01:43:43 -0400191 semc_sels, ARRAY_SIZE(semc_sels)));
192 clk_dm(IMXRT1170_CLK_SEMC,
Marek Vasut40e7edf2025-03-23 16:58:49 +0100193 imx_clk_divider(dev, "semc", "semc_sel",
Jesse Taube60a71f62022-07-26 01:43:43 -0400194 base + (4 * 0x80), 0, 8));
195 struct clk *clk, *clk1;
196
197 clk_get_by_id(IMXRT1170_CLK_PLL2_PFD2, &clk);
198
199 clk_get_by_id(IMXRT1170_CLK_SEMC_SEL, &clk1);
200 clk_enable(clk1);
201 clk_set_parent(clk1, clk);
202
203 clk_get_by_id(IMXRT1170_CLK_SEMC, &clk);
204 clk_enable(clk);
205 clk_set_rate(clk, 132000000UL);
206
207 clk_get_by_id(IMXRT1170_CLK_GPT1, &clk);
208 clk_enable(clk);
209 clk_set_rate(clk, 32000000UL);
210
211 return 0;
212}
213
214static const struct udevice_id imxrt1170_clk_ids[] = {
215 { .compatible = "fsl,imxrt1170-ccm" },
216 { },
217};
218
219U_BOOT_DRIVER(imxrt1170_clk) = {
220 .name = "clk_imxrt1170",
221 .id = UCLASS_CLK,
222 .of_match = imxrt1170_clk_ids,
223 .ops = &imxrt1170_clk_ops,
224 .probe = imxrt1170_clk_probe,
225 .flags = DM_FLAG_PRE_RELOC,
226};