aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/clk-twl6040.c53
-rw-r--r--drivers/clk/imx/Kconfig6
-rw-r--r--drivers/clk/imx/Makefile4
-rw-r--r--drivers/clk/imx/clk-composite-8m.c2
-rw-r--r--drivers/clk/imx/clk-imx51-imx53.c1
-rw-r--r--drivers/clk/imx/clk-imx8mm.c675
-rw-r--r--drivers/clk/imx/clk-imx8mq.c254
-rw-r--r--drivers/clk/imx/clk-imx8qxp.c1
-rw-r--r--drivers/clk/imx/clk-pll14xx.c392
-rw-r--r--drivers/clk/imx/clk-sccg-pll.c514
-rw-r--r--drivers/clk/imx/clk-scu.c123
-rw-r--r--drivers/clk/imx/clk-scu.h16
-rw-r--r--drivers/clk/imx/clk.h38
-rw-r--r--drivers/clk/mmp/clk-of-mmp2.c5
-rw-r--r--drivers/clk/samsung/clk-exynos5-subcmu.c13
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c38
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c2
-rw-r--r--drivers/clk/ti/adpll.c2
-rw-r--r--drivers/clk/ti/apll.c4
-rw-r--r--drivers/clk/ti/autoidle.c101
-rw-r--r--drivers/clk/ti/clk.c72
-rw-r--r--drivers/clk/ti/clkctrl.c2
-rw-r--r--drivers/clk/ti/clock.h5
-rw-r--r--drivers/clk/ti/clockdomain.c2
-rw-r--r--drivers/clk/ti/divider.c2
-rw-r--r--drivers/clk/ti/dpll.c11
-rw-r--r--drivers/clk/ti/dpll3xxx.c2
-rw-r--r--drivers/clk/ti/gate.c2
-rw-r--r--drivers/clk/ti/interface.c4
-rw-r--r--drivers/clk/ti/mux.c2
-rw-r--r--drivers/clk/uniphier/clk-uniphier-cpugear.c2
31 files changed, 2022 insertions, 328 deletions
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
index ea846f77750b..0cad5748bf0e 100644
--- a/drivers/clk/clk-twl6040.c
+++ b/drivers/clk/clk-twl6040.c
@@ -41,6 +41,43 @@ static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
41 return pdmclk->enabled; 41 return pdmclk->enabled;
42} 42}
43 43
44static int twl6040_pdmclk_reset_one_clock(struct twl6040_pdmclk *pdmclk,
45 unsigned int reg)
46{
47 const u8 reset_mask = TWL6040_HPLLRST; /* Same for HPPLL and LPPLL */
48 int ret;
49
50 ret = twl6040_set_bits(pdmclk->twl6040, reg, reset_mask);
51 if (ret < 0)
52 return ret;
53
54 ret = twl6040_clear_bits(pdmclk->twl6040, reg, reset_mask);
55 if (ret < 0)
56 return ret;
57
58 return 0;
59}
60
61/*
62 * TWL6040A2 Phoenix Audio IC erratum #6: "PDM Clock Generation Issue At
63 * Cold Temperature". This affects cold boot and deeper idle states it
64 * seems. The workaround consists of resetting HPPLL and LPPLL.
65 */
66static int twl6040_pdmclk_quirk_reset_clocks(struct twl6040_pdmclk *pdmclk)
67{
68 int ret;
69
70 ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_HPPLLCTL);
71 if (ret)
72 return ret;
73
74 ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_LPPLLCTL);
75 if (ret)
76 return ret;
77
78 return 0;
79}
80
44static int twl6040_pdmclk_prepare(struct clk_hw *hw) 81static int twl6040_pdmclk_prepare(struct clk_hw *hw)
45{ 82{
46 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk, 83 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
@@ -48,8 +85,20 @@ static int twl6040_pdmclk_prepare(struct clk_hw *hw)
48 int ret; 85 int ret;
49 86
50 ret = twl6040_power(pdmclk->twl6040, 1); 87 ret = twl6040_power(pdmclk->twl6040, 1);
51 if (!ret) 88 if (ret)
52 pdmclk->enabled = 1; 89 return ret;
90
91 ret = twl6040_pdmclk_quirk_reset_clocks(pdmclk);
92 if (ret)
93 goto out_err;
94
95 pdmclk->enabled = 1;
96
97 return 0;
98
99out_err:
100 dev_err(pdmclk->dev, "%s: error %i\n", __func__, ret);
101 twl6040_power(pdmclk->twl6040, 0);
53 102
54 return ret; 103 return ret;
55} 104}
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 4aae31a23449..0eaf41848280 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -8,6 +8,12 @@ config MXC_CLK_SCU
8 bool 8 bool
9 depends on IMX_SCU 9 depends on IMX_SCU
10 10
11config CLK_IMX8MM
12 bool "IMX8MM CCM Clock Driver"
13 depends on ARCH_MXC && ARM64
14 help
15 Build the driver for i.MX8MM CCM Clock Driver
16
11config CLK_IMX8MQ 17config CLK_IMX8MQ
12 bool "IMX8MQ CCM Clock Driver" 18 bool "IMX8MQ CCM Clock Driver"
13 depends on ARCH_MXC && ARM64 19 depends on ARCH_MXC && ARM64
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 73119fbfa547..0d5180fbe988 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -18,12 +18,14 @@ obj-$(CONFIG_MXC_CLK) += \
18 clk-pllv2.o \ 18 clk-pllv2.o \
19 clk-pllv3.o \ 19 clk-pllv3.o \
20 clk-pllv4.o \ 20 clk-pllv4.o \
21 clk-sccg-pll.o 21 clk-sccg-pll.o \
22 clk-pll14xx.o
22 23
23obj-$(CONFIG_MXC_CLK_SCU) += \ 24obj-$(CONFIG_MXC_CLK_SCU) += \
24 clk-scu.o \ 25 clk-scu.o \
25 clk-lpcg-scu.o 26 clk-lpcg-scu.o
26 27
28obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
27obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o 29obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
28obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o 30obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
29 31
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
index 527ade1d6933..574fac1a169f 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
123}; 123};
124 124
125struct clk *imx8m_clk_composite_flags(const char *name, 125struct clk *imx8m_clk_composite_flags(const char *name,
126 const char **parent_names, 126 const char * const *parent_names,
127 int num_parents, void __iomem *reg, 127 int num_parents, void __iomem *reg,
128 unsigned long flags) 128 unsigned long flags)
129{ 129{
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index fc8e782d817b..e91c826bce70 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -428,6 +428,7 @@ static void __init mx51_clocks_init(struct device_node *np)
428 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); 428 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
429 clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); 429 clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
430 clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); 430 clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
431 clk[IMX5_CLK_SCC2_IPG_GATE] = imx_clk_gate2("scc2_gate", "ipg", MXC_CCM_CCGR1, 30);
431 clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL); 432 clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL);
432 clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL); 433 clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL);
433 clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL); 434 clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL);
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644
index 000000000000..1ef8438e3d6d
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -0,0 +1,675 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2017-2018 NXP.
4 */
5
6#include <dt-bindings/clock/imx8mm-clock.h>
7#include <linux/clk.h>
8#include <linux/err.h>
9#include <linux/init.h>
10#include <linux/io.h>
11#include <linux/module.h>
12#include <linux/of.h>
13#include <linux/of_address.h>
14#include <linux/platform_device.h>
15#include <linux/types.h>
16
17#include "clk.h"
18
19static u32 share_count_sai1;
20static u32 share_count_sai2;
21static u32 share_count_sai3;
22static u32 share_count_sai4;
23static u32 share_count_sai5;
24static u32 share_count_sai6;
25static u32 share_count_dcss;
26static u32 share_count_pdm;
27static u32 share_count_nand;
28
29#define PLL_1416X_RATE(_rate, _m, _p, _s) \
30 { \
31 .rate = (_rate), \
32 .mdiv = (_m), \
33 .pdiv = (_p), \
34 .sdiv = (_s), \
35 }
36
37#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
38 { \
39 .rate = (_rate), \
40 .mdiv = (_m), \
41 .pdiv = (_p), \
42 .sdiv = (_s), \
43 .kdiv = (_k), \
44 }
45
46static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
47 PLL_1416X_RATE(1800000000U, 225, 3, 0),
48 PLL_1416X_RATE(1600000000U, 200, 3, 0),
49 PLL_1416X_RATE(1200000000U, 300, 3, 1),
50 PLL_1416X_RATE(1000000000U, 250, 3, 1),
51 PLL_1416X_RATE(800000000U, 200, 3, 1),
52 PLL_1416X_RATE(750000000U, 250, 2, 2),
53 PLL_1416X_RATE(700000000U, 350, 3, 2),
54 PLL_1416X_RATE(600000000U, 300, 3, 2),
55};
56
57static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
58 PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
59 PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
60};
61
62static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
63 PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
64 PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
65};
66
67static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
68 PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
69};
70
71static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
72 .type = PLL_1443X,
73 .rate_table = imx8mm_audiopll_tbl,
74 .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl),
75};
76
77static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
78 .type = PLL_1443X,
79 .rate_table = imx8mm_videopll_tbl,
80 .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl),
81};
82
83static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
84 .type = PLL_1443X,
85 .rate_table = imx8mm_drampll_tbl,
86 .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
87};
88
89static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
90 .type = PLL_1416X,
91 .rate_table = imx8mm_pll1416x_tbl,
92 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
93};
94
95static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
96 .type = PLL_1416X,
97 .rate_table = imx8mm_pll1416x_tbl,
98 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
99};
100
101static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
102 .type = PLL_1416X,
103 .rate_table = imx8mm_pll1416x_tbl,
104 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
105};
106
107static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
108 .type = PLL_1416X,
109 .rate_table = imx8mm_pll1416x_tbl,
110 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
111};
112
113static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
114static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
115static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
116static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
117static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
118static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
119static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
120static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
121static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
122static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
123static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
124
125/* CCM ROOT */
126static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
127 "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
128
129static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
130 "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
131
132static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
133 "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
134
135static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
136 "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
137
138static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
139 "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
140
141static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
142 "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
143
144static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
145 "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
146
147static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
148 "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
149
150static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out",
151 "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", };
152
153static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out",
154 "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
155
156static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out",
157 "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
158
159static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
160 "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
161
162static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
163 "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
164
165static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
166 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
167
168static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
169 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
170
171static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
172 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
173
174static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
175 "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
176
177static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
178 "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
179
180static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
181 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
182
183static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
184 "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
185
186static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
187 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
188
189static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
190 "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
191
192static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
193 "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
194
195static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
196 "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
197
198static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
199 "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
200
201static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
202 "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
203
204static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2",
205 "clk_ext3", "clk_ext4", "sys_pll1_400m", };
206
207static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
208 "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
209
210static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
211 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
212
213static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
214 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
215
216static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
217 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
218
219static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
220 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
221
222static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
223 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
224
225static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
226 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
227
228static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
229 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
230
231static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
232 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
233
234static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
235 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
236
237static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
238 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
239
240static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
241 "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
242
243static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
244 "clk_ext3", "clk_ext4", "video_pll1_out", };
245
246static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
247 "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
248
249static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
250 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
251
252static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
253 "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
254
255static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
256 "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
257
258static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
259 "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
260
261static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
262 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
263
264static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
265 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
266
267static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
268 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
269
270static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
271 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
272
273static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
274 "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
275
276static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
277 "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
278
279static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
280 "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
281
282static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
283 "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
284
285static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
286 "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
287
288static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
289 "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
290
291static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
292 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
293
294static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
295 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
296
297static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
298 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
299
300static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
301 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
302
303static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
304 "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
305
306static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
307 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
308
309static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
310 "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
311
312static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
313 "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
314
315static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m",
316 "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
317
318static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
319 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
320
321static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
322 "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
323
324static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
325 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
326
327static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
328 "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
329
330static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
331 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
332
333static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
334 "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
335
336static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
337 "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
338
339static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
340 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
341
342static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
343 "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
344
345static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
346 "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
347
348static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
349 "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
350
351static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1",
352 "clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", };
353
354static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
355 "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
356
357static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
358 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
359
360static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m",
361 "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
362
363static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
364 "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
365
366static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
367
368static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk",
369 "vpu_pll", "sys_pll1_80m", };
370
371static struct clk *clks[IMX8MM_CLK_END];
372static struct clk_onecell_data clk_data;
373
374static struct clk ** const uart_clks[] __initconst = {
375 &clks[IMX8MM_CLK_UART1_ROOT],
376 &clks[IMX8MM_CLK_UART2_ROOT],
377 &clks[IMX8MM_CLK_UART3_ROOT],
378 &clks[IMX8MM_CLK_UART4_ROOT],
379 NULL
380};
381
382static int __init imx8mm_clocks_init(struct device_node *ccm_node)
383{
384 struct device_node *np;
385 void __iomem *base;
386 int ret;
387
388 clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
389 clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m");
390 clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k");
391 clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
392 clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
393 clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
394 clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
395
396 np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
397 base = of_iomap(np, 0);
398 if (WARN_ON(!base))
399 return -ENOMEM;
400
401 clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
402 clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
403 clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
404 clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
405 clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
406 clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
407 clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
408 clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
409 clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
410 clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
411
412 clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
413 clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
414 clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
415 clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
416 clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
417 clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
418 clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
419 clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
420 clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
421 clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
422
423 /* PLL bypass out */
424 clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
425 clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
426 clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
427 clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
428 clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
429 clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
430 clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
431 clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
432 clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
433 clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
434
435 /* unbypass all the plls */
436 clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
437 clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
438 clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
439 clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
440 clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
441 clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
442 clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
443 clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
444 clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
445 clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
446
447 /* PLL out gate */
448 clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
449 clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
450 clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
451 clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
452 clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
453 clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13);
454 clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13);
455 clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13);
456 clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13);
457 clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13);
458
459 /* SYS PLL fixed output */
460 clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
461 clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
462 clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
463 clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
464 clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
465 clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
466 clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
467 clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
468 clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
469
470 clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
471 clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
472 clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
473 clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
474 clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
475 clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
476 clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
477 clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
478 clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
479
480 np = ccm_node;
481 base = of_iomap(np, 0);
482 if (WARN_ON(!base))
483 return -ENOMEM;
484
485 /* Core Slice */
486 clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
487 clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
488 clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
489 clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
490 clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
491 clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
492 clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
493 clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
494 clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
495 clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
496 clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
497 clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
498 clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
499 clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
500 clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
501
502 /* BUS */
503 clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
504 clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
505 clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
506 clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
507 clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
508 clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
509 clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
510 clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
511 clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
512 clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
513 clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
514 clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
515
516 /* AHB */
517 clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
518 clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
519
520 /* IPG */
521 clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
522 clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
523
524 /* IP */
525 clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
526 clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
527 clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
528 clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
529 clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
530 clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
531 clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
532 clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
533 clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
534 clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
535 clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
536 clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
537 clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
538 clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
539 clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
540 clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
541 clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
542 clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
543 clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
544 clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
545 clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
546 clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
547 clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00);
548 clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
549 clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
550 clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
551 clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
552 clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
553 clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
554 clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
555 clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
556 clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
557 clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
558 clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
559 clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
560 clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
561 clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
562 clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
563 clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
564 clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
565 clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
566 clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
567 clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
568 clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
569 clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
570 clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
571 clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
572 clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
573 clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
574 clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
575 clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
576 clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
577 clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
578 clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
579 clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
580 clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
581 clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
582 clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
583 clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
584 clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
585 clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
586 clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
587
588 /* CCGR */
589 clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
590 clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
591 clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
592 clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
593 clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
594 clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
595 clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
596 clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
597 clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
598 clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
599 clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
600 clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
601 clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
602 clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
603 clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
604 clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
605 clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
606 clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
607 clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
608 clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
609 clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
610 clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
611 clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
612 clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
613 clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
614 clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
615 clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
616 clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
617 clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
618 clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
619 clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
620 clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
621 clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
622 clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
623 clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
624 clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
625 clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
626 clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
627 clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
628 clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
629 clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
630 clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
631 clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
632 clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
633 clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
634 clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
635 clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
636 clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
637 clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
638 clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
639 clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
640 clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
641 clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
642 clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
643 clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
644 clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
645 clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
646 clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
647 clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
648 clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
649
650 clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
651
652 clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
653 clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
654
655 clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
656 clks[IMX8MM_CLK_A53_DIV],
657 clks[IMX8MM_CLK_A53_SRC],
658 clks[IMX8MM_ARM_PLL_OUT],
659 clks[IMX8MM_CLK_24M]);
660
661 imx_check_clocks(clks, ARRAY_SIZE(clks));
662
663 clk_data.clks = clks;
664 clk_data.clk_num = ARRAY_SIZE(clks);
665 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
666 if (ret < 0) {
667 pr_err("failed to register clks for i.MX8MM\n");
668 return -EINVAL;
669 }
670
671 imx_register_uart_clocks(uart_clks);
672
673 return 0;
674}
675CLK_OF_DECLARE_DRIVER(imx8mm, "fsl,imx8mm-ccm", imx8mm_clocks_init);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index 26b57f43ccc3..a9b3888aef0c 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -26,246 +26,246 @@ static u32 share_count_nand;
26 26
27static struct clk *clks[IMX8MQ_CLK_END]; 27static struct clk *clks[IMX8MQ_CLK_END];
28 28
29static const char *pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", }; 29static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
30static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; 30static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
31static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; 31static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
32static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; 32static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
33static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; 33static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
34static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; 34static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
35static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; 35static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
36 36
37static const char *sys1_pll1_out_sels[] = {"sys1_pll1", "sys1_pll1_ref_sel", }; 37static const char * const sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", };
38static const char *sys2_pll1_out_sels[] = {"sys2_pll1", "sys1_pll1_ref_sel", }; 38static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", };
39static const char *sys3_pll1_out_sels[] = {"sys3_pll1", "sys3_pll1_ref_sel", }; 39static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", };
40static const char *dram_pll1_out_sels[] = {"dram_pll1", "dram_pll1_ref_sel", }; 40static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", };
41
42static const char *sys1_pll2_out_sels[] = {"sys1_pll2_div", "sys1_pll1_ref_sel", };
43static const char *sys2_pll2_out_sels[] = {"sys2_pll2_div", "sys2_pll1_ref_sel", };
44static const char *sys3_pll2_out_sels[] = {"sys3_pll2_div", "sys2_pll1_ref_sel", };
45static const char *dram_pll2_out_sels[] = {"dram_pll2_div", "dram_pll1_ref_sel", };
46 41
47/* CCM ROOT */ 42/* CCM ROOT */
48static const char *imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", 43static const char * const imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
49 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", }; 44 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", };
50 45
51static const char *imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", 46static const char * const imx8mq_arm_m4_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_250m", "sys1_pll_266m",
47 "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
48
49static const char * const imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
52 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", }; 50 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", };
53 51
54static const char *imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out", 52static const char * const imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
55 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 53 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
56 54
57static const char *imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out", 55static const char * const imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
58 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 56 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
59 57
60static const char *imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m", 58static const char * const imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m",
61 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",}; 59 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",};
62 60
63static const char *imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m", 61static const char * const imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m",
64 "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", }; 62 "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
65 63
66static const char *imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m", 64static const char * const imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m",
67 "sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", }; 65 "sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", };
68 66
69static const char *imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", }; 67static const char * const imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", };
70 68
71static const char *imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", }; 69static const char * const imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
72 70
73static const char *imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", 71static const char * const imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out",
74 "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", }; 72 "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
75 73
76static const char *imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m", 74static const char * const imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m",
77 "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", }; 75 "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
78 76
79static const char *imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m", 77static const char * const imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m",
80 "sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", }; 78 "sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
81 79
82static const char *imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m", 80static const char * const imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
83 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 81 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
84 82
85static const char *imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m", 83static const char * const imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
86 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 84 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
87 85
88static const char *imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m", 86static const char * const imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m",
89 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 87 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
90 88
91static const char *imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m", 89static const char * const imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m",
92 "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", }; 90 "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", };
93 91
94static const char *imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m", 92static const char * const imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m",
95 "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", }; 93 "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
96 94
97static const char *imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m", 95static const char * const imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m",
98 "sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", }; 96 "sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
99 97
100static const char *imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 98static const char * const imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
101 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"}; 99 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"};
102 100
103static const char *imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m", 101static const char * const imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m",
104 "sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", }; 102 "sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", };
105 103
106static const char *imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 104static const char * const imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
107 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 105 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
108 106
109static const char *imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", }; 107static const char * const imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
110 108
111static const char *imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", }; 109static const char * const imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
112 110
113static const char *imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", }; 111static const char * const imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
114 112
115static const char *imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", }; 113static const char * const imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
116 114
117static const char *imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m", 115static const char * const imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
118 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", }; 116 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", };
119 117
120static const char *imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2", 118static const char * const imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2",
121 "clk_ext3", "clk_ext4", }; 119 "clk_ext3", "clk_ext4", };
122 120
123static const char *imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out", 121static const char * const imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out",
124 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", }; 122 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
125 123
126static const char *imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", }; 124static const char * const imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
127 125
128static const char *imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", }; 126static const char * const imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
129 127
130static const char *imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", }; 128static const char * const imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
131 129
132static const char *imx8mq_sai2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", }; 130static const char * const imx8mq_sai2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
133 131
134static const char *imx8mq_sai3_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", }; 132static const char * const imx8mq_sai3_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
135 133
136static const char *imx8mq_sai4_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", }; 134static const char * const imx8mq_sai4_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
137 135
138static const char *imx8mq_sai5_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", }; 136static const char * const imx8mq_sai5_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
139 137
140static const char *imx8mq_sai6_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", }; 138static const char * const imx8mq_sai6_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
141 139
142static const char *imx8mq_spdif1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", }; 140static const char * const imx8mq_spdif1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
143 141
144static const char *imx8mq_spdif2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", }; 142static const char * const imx8mq_spdif2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
145 143
146static const char *imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m", 144static const char * const imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m",
147 "sys1_pll_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; 145 "sys1_pll_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
148 146
149static const char *imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", 147static const char * const imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
150 "clk_ext3", "clk_ext4", "video_pll1_out", }; 148 "clk_ext3", "clk_ext4", "video_pll1_out", };
151 149
152static const char *imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m", 150static const char * const imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m",
153 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 151 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
154 152
155static const char *imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m", 153static const char * const imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m",
156 "audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", }; 154 "audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", };
157 155
158static const char *imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", 156static const char * const imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
159 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", }; 157 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
160 158
161static const char *imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", 159static const char * const imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
162 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", }; 160 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
163 161
164static const char *imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", 162static const char * const imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
165 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", }; 163 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
166 164
167static const char *imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 165static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
168 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 166 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
169 167
170static const char *imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 168static const char * const imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
171 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 169 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
172 170
173static const char *imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 171static const char * const imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
174 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 172 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
175 173
176static const char *imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 174static const char * const imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
177 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 175 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
178 176
179static const char *imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 177static const char * const imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
180 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; 178 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
181 179
182static const char *imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 180static const char * const imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
183 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 181 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
184 182
185static const char *imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 183static const char * const imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
186 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; 184 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
187 185
188static const char *imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 186static const char * const imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
189 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 187 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
190 188
191static const char *imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", 189static const char * const imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
192 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 190 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
193 191
194static const char *imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", 192static const char * const imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
195 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 193 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
196 194
197static const char *imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 195static const char * const imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
198 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 196 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
199 197
200static const char *imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 198static const char * const imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
201 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 199 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
202 200
203static const char *imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 201static const char * const imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
204 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", }; 202 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
205 203
206static const char *imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 204static const char * const imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
207 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", }; 205 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
208 206
209static const char *imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 207static const char * const imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
210 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", }; 208 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
211 209
212static const char *imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 210static const char * const imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
213 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", }; 211 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
214 212
215static const char *imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m", 213static const char * const imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m",
216 "sys1_pll_80m", "audio_pll1_out", "clk_ext1", }; 214 "sys1_pll_80m", "audio_pll1_out", "clk_ext1", };
217 215
218static const char *imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out", 216static const char * const imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out",
219 "sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", }; 217 "sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", };
220 218
221static const char *imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m", 219static const char * const imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m",
222 "sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", }; 220 "sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", };
223 221
224static const char *imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", 222static const char * const imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
225 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 223 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
226 224
227static const char *imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", 225static const char * const imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
228 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; 226 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
229 227
230static const char *imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m", 228static const char * const imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m",
231 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 229 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
232 230
233static const char *imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 231static const char * const imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
234 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", }; 232 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
235 233
236static const char *imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", 234static const char * const imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
237 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 235 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
238 236
239static const char *imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", 237static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
240 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; 238 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
241 239
242static const char *imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 240static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
243 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", }; 241 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
244 242
245static const char *imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", 243static const char * const imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
246 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 244 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
247 245
248static const char *imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", 246static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
249 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; 247 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
250 248
251static const char *imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 249static const char * const imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
252 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", }; 250 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
253 251
254static const char *imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m", 252static const char * const imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
255 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", }; 253 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", };
256 254
257static const char *imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", 255static const char * const imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1",
258 "clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", }; 256 "clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", };
259 257
260static const char *imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out", 258static const char * const imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out",
261 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", }; 259 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
262 260
263static const char *imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 261static const char * const imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
264 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 262 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
265static const char *imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; 263static const char * const imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
266 264
267static const char *imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m", "audio_pll1_out", 265static const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "osc_27m", "sys1_pll_200m",
268 "video_pll1_out", "ckil", }; 266 "audio_pll2_out", "sys2_pll_500m", "vpu_pll_out", "sys1_pll_80m", };
267static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m",
268 "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", "ckil", };
269 269
270static struct clk_onecell_data clk_data; 270static struct clk_onecell_data clk_data;
271 271
@@ -308,10 +308,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
308 clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6); 308 clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
309 clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6); 309 clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
310 clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6); 310 clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
311 clks[IMX8MQ_SYS1_PLL1_REF_DIV] = imx_clk_divider("sys1_pll1_ref_div", "sys1_pll1_ref_sel", base + 0x38, 25, 3);
312 clks[IMX8MQ_SYS2_PLL1_REF_DIV] = imx_clk_divider("sys2_pll1_ref_div", "sys2_pll1_ref_sel", base + 0x44, 25, 3);
313 clks[IMX8MQ_SYS3_PLL1_REF_DIV] = imx_clk_divider("sys3_pll1_ref_div", "sys3_pll1_ref_sel", base + 0x50, 25, 3);
314 clks[IMX8MQ_DRAM_PLL1_REF_DIV] = imx_clk_divider("dram_pll1_ref_div", "dram_pll1_ref_sel", base + 0x68, 25, 3);
315 311
316 clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28); 312 clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
317 clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18); 313 clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
@@ -319,43 +315,15 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
319 clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0); 315 clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
320 clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8); 316 clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
321 clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10); 317 clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
322 clks[IMX8MQ_SYS1_PLL1] = imx_clk_sccg_pll("sys1_pll1", "sys1_pll1_ref_div", base + 0x30, SCCG_PLL1);
323 clks[IMX8MQ_SYS2_PLL1] = imx_clk_sccg_pll("sys2_pll1", "sys2_pll1_ref_div", base + 0x3c, SCCG_PLL1);
324 clks[IMX8MQ_SYS3_PLL1] = imx_clk_sccg_pll("sys3_pll1", "sys3_pll1_ref_div", base + 0x48, SCCG_PLL1);
325 clks[IMX8MQ_DRAM_PLL1] = imx_clk_sccg_pll("dram_pll1", "dram_pll1_ref_div", base + 0x60, SCCG_PLL1);
326
327 clks[IMX8MQ_SYS1_PLL2] = imx_clk_sccg_pll("sys1_pll2", "sys1_pll1_out_div", base + 0x30, SCCG_PLL2);
328 clks[IMX8MQ_SYS2_PLL2] = imx_clk_sccg_pll("sys2_pll2", "sys2_pll1_out_div", base + 0x3c, SCCG_PLL2);
329 clks[IMX8MQ_SYS3_PLL2] = imx_clk_sccg_pll("sys3_pll2", "sys3_pll1_out_div", base + 0x48, SCCG_PLL2);
330 clks[IMX8MQ_DRAM_PLL2] = imx_clk_sccg_pll("dram_pll2", "dram_pll1_out_div", base + 0x60, SCCG_PLL2);
331
332 /* PLL divs */
333 clks[IMX8MQ_SYS1_PLL1_OUT_DIV] = imx_clk_divider("sys1_pll1_out_div", "sys1_pll1_out", base + 0x38, 19, 6);
334 clks[IMX8MQ_SYS2_PLL1_OUT_DIV] = imx_clk_divider("sys2_pll1_out_div", "sys2_pll1_out", base + 0x44, 19, 6);
335 clks[IMX8MQ_SYS3_PLL1_OUT_DIV] = imx_clk_divider("sys3_pll1_out_div", "sys3_pll1_out", base + 0x50, 19, 6);
336 clks[IMX8MQ_DRAM_PLL1_OUT_DIV] = imx_clk_divider("dram_pll1_out_div", "dram_pll1_out", base + 0x68, 19, 6);
337 clks[IMX8MQ_SYS1_PLL2_DIV] = imx_clk_divider("sys1_pll2_div", "sys1_pll2", base + 0x38, 1, 6);
338 clks[IMX8MQ_SYS2_PLL2_DIV] = imx_clk_divider("sys2_pll2_div", "sys2_pll2", base + 0x44, 1, 6);
339 clks[IMX8MQ_SYS3_PLL2_DIV] = imx_clk_divider("sys3_pll2_div", "sys3_pll2", base + 0x50, 1, 6);
340 clks[IMX8MQ_DRAM_PLL2_DIV] = imx_clk_divider("dram_pll2_div", "dram_pll2", base + 0x68, 1, 6);
341 318
342 /* PLL bypass out */ 319 /* PLL bypass out */
343 clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels)); 320 clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
344 clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); 321 clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
345 clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); 322 clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
346 clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); 323 clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
347 clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); 324 clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
348 clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); 325 clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
349 326
350 clks[IMX8MQ_SYS1_PLL1_OUT] = imx_clk_mux("sys1_pll1_out", base + 0x30, 5, 1, sys1_pll1_out_sels, ARRAY_SIZE(sys1_pll1_out_sels));
351 clks[IMX8MQ_SYS2_PLL1_OUT] = imx_clk_mux("sys2_pll1_out", base + 0x3c, 5, 1, sys2_pll1_out_sels, ARRAY_SIZE(sys2_pll1_out_sels));
352 clks[IMX8MQ_SYS3_PLL1_OUT] = imx_clk_mux("sys3_pll1_out", base + 0x48, 5, 1, sys3_pll1_out_sels, ARRAY_SIZE(sys3_pll1_out_sels));
353 clks[IMX8MQ_DRAM_PLL1_OUT] = imx_clk_mux("dram_pll1_out", base + 0x60, 5, 1, dram_pll1_out_sels, ARRAY_SIZE(dram_pll1_out_sels));
354 clks[IMX8MQ_SYS1_PLL2_OUT] = imx_clk_mux("sys1_pll2_out", base + 0x30, 4, 1, sys1_pll2_out_sels, ARRAY_SIZE(sys1_pll2_out_sels));
355 clks[IMX8MQ_SYS2_PLL2_OUT] = imx_clk_mux("sys2_pll2_out", base + 0x3c, 4, 1, sys2_pll2_out_sels, ARRAY_SIZE(sys2_pll2_out_sels));
356 clks[IMX8MQ_SYS3_PLL2_OUT] = imx_clk_mux("sys3_pll2_out", base + 0x48, 4, 1, sys3_pll2_out_sels, ARRAY_SIZE(sys3_pll2_out_sels));
357 clks[IMX8MQ_DRAM_PLL2_OUT] = imx_clk_mux("dram_pll2_out", base + 0x60, 4, 1, dram_pll2_out_sels, ARRAY_SIZE(dram_pll2_out_sels));
358
359 /* PLL OUT GATE */ 327 /* PLL OUT GATE */
360 clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21); 328 clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
361 clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21); 329 clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
@@ -363,11 +331,11 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
363 clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21); 331 clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
364 clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21); 332 clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
365 clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21); 333 clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
366 clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_gate("sys1_pll_out", "sys1_pll2_out", base + 0x30, 9);
367 clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_gate("sys2_pll_out", "sys2_pll2_out", base + 0x3c, 9);
368 clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_gate("sys3_pll_out", "sys3_pll2_out", base + 0x48, 9);
369 clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll2_out", base + 0x60, 9);
370 334
335 clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_sccg_pll("sys1_pll_out", sys1_pll_out_sels, ARRAY_SIZE(sys1_pll_out_sels), 0, 0, 0, base + 0x30, CLK_IS_CRITICAL);
336 clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL);
337 clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL);
338 clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL);
371 /* SYS PLL fixed output */ 339 /* SYS PLL fixed output */
372 clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); 340 clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20);
373 clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); 341 clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10);
@@ -396,15 +364,19 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
396 364
397 /* CORE */ 365 /* CORE */
398 clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); 366 clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
367 clks[IMX8MQ_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels));
399 clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels)); 368 clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
400 clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels)); 369 clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
401 clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels)); 370 clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels));
371
402 clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL); 372 clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
373 clks[IMX8MQ_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
403 clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); 374 clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
404 clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); 375 clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
405 clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); 376 clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
406 377
407 clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); 378 clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
379 clks[IMX8MQ_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
408 clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); 380 clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
409 clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); 381 clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
410 clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); 382 clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
@@ -479,6 +451,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
479 clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580); 451 clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
480 clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900); 452 clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
481 clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980); 453 clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
454 clks[IMX8MQ_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
482 clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80); 455 clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
483 clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00); 456 clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
484 clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80); 457 clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
@@ -500,6 +473,11 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
500 clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); 473 clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
501 clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); 474 clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
502 clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); 475 clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
476 clks[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
477 clks[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
478 clks[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
479 clks[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
480 clks[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
503 clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); 481 clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
504 clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); 482 clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
505 clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); 483 clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
@@ -558,6 +536,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
558 clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8); 536 clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
559 clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4); 537 clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
560 538
539 clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
540 clks[IMX8MQ_CLK_A53_DIV],
541 clks[IMX8MQ_CLK_A53_SRC],
542 clks[IMX8MQ_ARM_PLL_OUT],
543 clks[IMX8MQ_SYS1_PLL_800M]);
544
561 for (i = 0; i < IMX8MQ_CLK_END; i++) 545 for (i = 0; i < IMX8MQ_CLK_END; i++)
562 if (IS_ERR(clks[i])) 546 if (IS_ERR(clks[i]))
563 pr_err("i.MX8mq clk %u register failed with %ld\n", 547 pr_err("i.MX8mq clk %u register failed with %ld\n",
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 83e2ef96d81d..5e2903efc488 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -138,6 +138,7 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
138} 138}
139 139
140static const struct of_device_id imx8qxp_match[] = { 140static const struct of_device_id imx8qxp_match[] = {
141 { .compatible = "fsl,scu-clk", },
141 { .compatible = "fsl,imx8qxp-clk", }, 142 { .compatible = "fsl,imx8qxp-clk", },
142 { /* sentinel */ } 143 { /* sentinel */ }
143}; 144};
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
new file mode 100644
index 000000000000..1acfa3e3cfb4
--- /dev/null
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -0,0 +1,392 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2017-2018 NXP.
4 */
5
6#include <linux/bitops.h>
7#include <linux/clk-provider.h>
8#include <linux/err.h>
9#include <linux/io.h>
10#include <linux/iopoll.h>
11#include <linux/slab.h>
12#include <linux/jiffies.h>
13
14#include "clk.h"
15
16#define GNRL_CTL 0x0
17#define DIV_CTL 0x4
18#define LOCK_STATUS BIT(31)
19#define LOCK_SEL_MASK BIT(29)
20#define CLKE_MASK BIT(11)
21#define RST_MASK BIT(9)
22#define BYPASS_MASK BIT(4)
23#define MDIV_SHIFT 12
24#define MDIV_MASK GENMASK(21, 12)
25#define PDIV_SHIFT 4
26#define PDIV_MASK GENMASK(9, 4)
27#define SDIV_SHIFT 0
28#define SDIV_MASK GENMASK(2, 0)
29#define KDIV_SHIFT 0
30#define KDIV_MASK GENMASK(15, 0)
31
32#define LOCK_TIMEOUT_US 10000
33
34struct clk_pll14xx {
35 struct clk_hw hw;
36 void __iomem *base;
37 enum imx_pll14xx_type type;
38 const struct imx_pll14xx_rate_table *rate_table;
39 int rate_count;
40};
41
42#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
43
44static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
45 struct clk_pll14xx *pll, unsigned long rate)
46{
47 const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
48 int i;
49
50 for (i = 0; i < pll->rate_count; i++)
51 if (rate == rate_table[i].rate)
52 return &rate_table[i];
53
54 return NULL;
55}
56
57static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
58 unsigned long *prate)
59{
60 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
61 const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
62 int i;
63
64 /* Assumming rate_table is in descending order */
65 for (i = 0; i < pll->rate_count; i++)
66 if (rate >= rate_table[i].rate)
67 return rate_table[i].rate;
68
69 /* return minimum supported value */
70 return rate_table[i - 1].rate;
71}
72
73static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75{
76 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
77 u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
78 u64 fvco = parent_rate;
79
80 pll_gnrl = readl_relaxed(pll->base);
81 pll_div = readl_relaxed(pll->base + 4);
82 mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
83 pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
84 sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
85
86 fvco *= mdiv;
87 do_div(fvco, pdiv << sdiv);
88
89 return fvco;
90}
91
92static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
93 unsigned long parent_rate)
94{
95 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
96 u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
97 short int kdiv;
98 u64 fvco = parent_rate;
99
100 pll_gnrl = readl_relaxed(pll->base);
101 pll_div_ctl0 = readl_relaxed(pll->base + 4);
102 pll_div_ctl1 = readl_relaxed(pll->base + 8);
103 mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
104 pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
105 sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
106 kdiv = pll_div_ctl1 & KDIV_MASK;
107
108 /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
109 fvco *= (mdiv * 65536 + kdiv);
110 pdiv *= 65536;
111
112 do_div(fvco, pdiv << sdiv);
113
114 return fvco;
115}
116
117static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
118 u32 pll_div)
119{
120 u32 old_mdiv, old_pdiv;
121
122 old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
123 old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
124
125 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
126}
127
128static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
129 u32 pll_div_ctl0, u32 pll_div_ctl1)
130{
131 u32 old_mdiv, old_pdiv, old_kdiv;
132
133 old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
134 old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
135 old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
136
137 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
138 rate->kdiv != old_kdiv;
139}
140
141static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
142 u32 pll_div_ctl0, u32 pll_div_ctl1)
143{
144 u32 old_mdiv, old_pdiv, old_kdiv;
145
146 old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
147 old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
148 old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
149
150 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
151 rate->kdiv != old_kdiv;
152}
153
154static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
155{
156 u32 val;
157
158 return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0,
159 LOCK_TIMEOUT_US);
160}
161
162static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
163 unsigned long prate)
164{
165 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
166 const struct imx_pll14xx_rate_table *rate;
167 u32 tmp, div_val;
168 int ret;
169
170 rate = imx_get_pll_settings(pll, drate);
171 if (!rate) {
172 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
173 drate, clk_hw_get_name(hw));
174 return -EINVAL;
175 }
176
177 tmp = readl_relaxed(pll->base + 4);
178
179 if (!clk_pll1416x_mp_change(rate, tmp)) {
180 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
181 tmp |= rate->sdiv << SDIV_SHIFT;
182 writel_relaxed(tmp, pll->base + 4);
183
184 return 0;
185 }
186
187 /* Bypass clock and set lock to pll output lock */
188 tmp = readl_relaxed(pll->base);
189 tmp |= LOCK_SEL_MASK;
190 writel_relaxed(tmp, pll->base);
191
192 /* Enable RST */
193 tmp &= ~RST_MASK;
194 writel_relaxed(tmp, pll->base);
195
196 div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
197 (rate->sdiv << SDIV_SHIFT);
198 writel_relaxed(div_val, pll->base + 0x4);
199
200 /*
201 * According to SPEC, t3 - t2 need to be greater than
202 * 1us and 1/FREF, respectively.
203 * FREF is FIN / Prediv, the prediv is [1, 63], so choose
204 * 3us.
205 */
206 udelay(3);
207
208 /* Disable RST */
209 tmp |= RST_MASK;
210 writel_relaxed(tmp, pll->base);
211
212 /* Wait Lock */
213 ret = clk_pll14xx_wait_lock(pll);
214 if (ret)
215 return ret;
216
217 /* Bypass */
218 tmp &= ~BYPASS_MASK;
219 writel_relaxed(tmp, pll->base);
220
221 return 0;
222}
223
224static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
225 unsigned long prate)
226{
227 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
228 const struct imx_pll14xx_rate_table *rate;
229 u32 tmp, div_val;
230 int ret;
231
232 rate = imx_get_pll_settings(pll, drate);
233 if (!rate) {
234 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
235 drate, clk_hw_get_name(hw));
236 return -EINVAL;
237 }
238
239 tmp = readl_relaxed(pll->base + 4);
240 div_val = readl_relaxed(pll->base + 8);
241
242 if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
243 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
244 tmp |= rate->sdiv << SDIV_SHIFT;
245 writel_relaxed(tmp, pll->base + 4);
246
247 return 0;
248 }
249
250 /* Enable RST */
251 tmp = readl_relaxed(pll->base);
252 tmp &= ~RST_MASK;
253 writel_relaxed(tmp, pll->base);
254
255 div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
256 (rate->sdiv << SDIV_SHIFT);
257 writel_relaxed(div_val, pll->base + 0x4);
258 writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
259
260 /*
261 * According to SPEC, t3 - t2 need to be greater than
262 * 1us and 1/FREF, respectively.
263 * FREF is FIN / Prediv, the prediv is [1, 63], so choose
264 * 3us.
265 */
266 udelay(3);
267
268 /* Disable RST */
269 tmp |= RST_MASK;
270 writel_relaxed(tmp, pll->base);
271
272 /* Wait Lock*/
273 ret = clk_pll14xx_wait_lock(pll);
274 if (ret)
275 return ret;
276
277 /* Bypass */
278 tmp &= ~BYPASS_MASK;
279 writel_relaxed(tmp, pll->base);
280
281 return 0;
282}
283
284static int clk_pll14xx_prepare(struct clk_hw *hw)
285{
286 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
287 u32 val;
288
289 /*
290 * RESETB = 1 from 0, PLL starts its normal
291 * operation after lock time
292 */
293 val = readl_relaxed(pll->base + GNRL_CTL);
294 val |= RST_MASK;
295 writel_relaxed(val, pll->base + GNRL_CTL);
296
297 return clk_pll14xx_wait_lock(pll);
298}
299
300static int clk_pll14xx_is_prepared(struct clk_hw *hw)
301{
302 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
303 u32 val;
304
305 val = readl_relaxed(pll->base + GNRL_CTL);
306
307 return (val & RST_MASK) ? 1 : 0;
308}
309
310static void clk_pll14xx_unprepare(struct clk_hw *hw)
311{
312 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
313 u32 val;
314
315 /*
316 * Set RST to 0, power down mode is enabled and
317 * every digital block is reset
318 */
319 val = readl_relaxed(pll->base + GNRL_CTL);
320 val &= ~RST_MASK;
321 writel_relaxed(val, pll->base + GNRL_CTL);
322}
323
324static const struct clk_ops clk_pll1416x_ops = {
325 .prepare = clk_pll14xx_prepare,
326 .unprepare = clk_pll14xx_unprepare,
327 .is_prepared = clk_pll14xx_is_prepared,
328 .recalc_rate = clk_pll1416x_recalc_rate,
329 .round_rate = clk_pll14xx_round_rate,
330 .set_rate = clk_pll1416x_set_rate,
331};
332
333static const struct clk_ops clk_pll1416x_min_ops = {
334 .recalc_rate = clk_pll1416x_recalc_rate,
335};
336
337static const struct clk_ops clk_pll1443x_ops = {
338 .prepare = clk_pll14xx_prepare,
339 .unprepare = clk_pll14xx_unprepare,
340 .is_prepared = clk_pll14xx_is_prepared,
341 .recalc_rate = clk_pll1443x_recalc_rate,
342 .round_rate = clk_pll14xx_round_rate,
343 .set_rate = clk_pll1443x_set_rate,
344};
345
346struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
347 void __iomem *base,
348 const struct imx_pll14xx_clk *pll_clk)
349{
350 struct clk_pll14xx *pll;
351 struct clk *clk;
352 struct clk_init_data init;
353
354 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
355 if (!pll)
356 return ERR_PTR(-ENOMEM);
357
358 init.name = name;
359 init.flags = pll_clk->flags;
360 init.parent_names = &parent_name;
361 init.num_parents = 1;
362
363 switch (pll_clk->type) {
364 case PLL_1416X:
365 if (!pll->rate_table)
366 init.ops = &clk_pll1416x_min_ops;
367 else
368 init.ops = &clk_pll1416x_ops;
369 break;
370 case PLL_1443X:
371 init.ops = &clk_pll1443x_ops;
372 break;
373 default:
374 pr_err("%s: Unknown pll type for pll clk %s\n",
375 __func__, name);
376 };
377
378 pll->base = base;
379 pll->hw.init = &init;
380 pll->type = pll_clk->type;
381 pll->rate_table = pll_clk->rate_table;
382 pll->rate_count = pll_clk->rate_count;
383
384 clk = clk_register(NULL, &pll->hw);
385 if (IS_ERR(clk)) {
386 pr_err("%s: failed to register pll %s %lu\n",
387 __func__, name, PTR_ERR(clk));
388 kfree(pll);
389 }
390
391 return clk;
392}
diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sccg-pll.c
index ee7752bace89..9dfd03a95557 100644
--- a/drivers/clk/imx/clk-sccg-pll.c
+++ b/drivers/clk/imx/clk-sccg-pll.c
@@ -25,87 +25,292 @@
25#define PLL_DIVF2_MASK GENMASK(12, 7) 25#define PLL_DIVF2_MASK GENMASK(12, 7)
26#define PLL_DIVR1_MASK GENMASK(27, 25) 26#define PLL_DIVR1_MASK GENMASK(27, 25)
27#define PLL_DIVR2_MASK GENMASK(24, 19) 27#define PLL_DIVR2_MASK GENMASK(24, 19)
28#define PLL_DIVQ_MASK GENMASK(6, 1)
28#define PLL_REF_MASK GENMASK(2, 0) 29#define PLL_REF_MASK GENMASK(2, 0)
29 30
30#define PLL_LOCK_MASK BIT(31) 31#define PLL_LOCK_MASK BIT(31)
31#define PLL_PD_MASK BIT(7) 32#define PLL_PD_MASK BIT(7)
32 33
33#define OSC_25M 25000000 34/* These are the specification limits for the SSCG PLL */
34#define OSC_27M 27000000 35#define PLL_REF_MIN_FREQ 25000000UL
36#define PLL_REF_MAX_FREQ 235000000UL
35 37
36#define PLL_SCCG_LOCK_TIMEOUT 70 38#define PLL_STAGE1_MIN_FREQ 1600000000UL
39#define PLL_STAGE1_MAX_FREQ 2400000000UL
40
41#define PLL_STAGE1_REF_MIN_FREQ 25000000UL
42#define PLL_STAGE1_REF_MAX_FREQ 54000000UL
43
44#define PLL_STAGE2_MIN_FREQ 1200000000UL
45#define PLL_STAGE2_MAX_FREQ 2400000000UL
46
47#define PLL_STAGE2_REF_MIN_FREQ 54000000UL
48#define PLL_STAGE2_REF_MAX_FREQ 75000000UL
49
50#define PLL_OUT_MIN_FREQ 20000000UL
51#define PLL_OUT_MAX_FREQ 1200000000UL
52
53#define PLL_DIVR1_MAX 7
54#define PLL_DIVR2_MAX 63
55#define PLL_DIVF1_MAX 63
56#define PLL_DIVF2_MAX 63
57#define PLL_DIVQ_MAX 63
58
59#define PLL_BYPASS_NONE 0x0
60#define PLL_BYPASS1 0x2
61#define PLL_BYPASS2 0x1
62
63#define SSCG_PLL_BYPASS1_MASK BIT(5)
64#define SSCG_PLL_BYPASS2_MASK BIT(4)
65#define SSCG_PLL_BYPASS_MASK GENMASK(5, 4)
66
67#define PLL_SCCG_LOCK_TIMEOUT 70
68
69struct clk_sccg_pll_setup {
70 int divr1, divf1;
71 int divr2, divf2;
72 int divq;
73 int bypass;
74
75 uint64_t vco1;
76 uint64_t vco2;
77 uint64_t fout;
78 uint64_t ref;
79 uint64_t ref_div1;
80 uint64_t ref_div2;
81 uint64_t fout_request;
82 int fout_error;
83};
37 84
38struct clk_sccg_pll { 85struct clk_sccg_pll {
39 struct clk_hw hw; 86 struct clk_hw hw;
40 void __iomem *base; 87 const struct clk_ops ops;
88
89 void __iomem *base;
90
91 struct clk_sccg_pll_setup setup;
92
93 u8 parent;
94 u8 bypass1;
95 u8 bypass2;
41}; 96};
42 97
43#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw) 98#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
44 99
45static int clk_pll_wait_lock(struct clk_sccg_pll *pll) 100static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
46{ 101{
47 u32 val; 102 u32 val;
48 103
49 return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK, 0, 104 val = readl_relaxed(pll->base + PLL_CFG0);
50 PLL_SCCG_LOCK_TIMEOUT); 105
106 /* don't wait for lock if all plls are bypassed */
107 if (!(val & SSCG_PLL_BYPASS2_MASK))
108 return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK,
109 0, PLL_SCCG_LOCK_TIMEOUT);
110
111 return 0;
51} 112}
52 113
53static int clk_pll1_is_prepared(struct clk_hw *hw) 114static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
115 struct clk_sccg_pll_setup *temp_setup)
54{ 116{
55 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 117 int new_diff = temp_setup->fout - temp_setup->fout_request;
56 u32 val; 118 int diff = temp_setup->fout_error;
57 119
58 val = readl_relaxed(pll->base + PLL_CFG0); 120 if (abs(diff) > abs(new_diff)) {
59 return (val & PLL_PD_MASK) ? 0 : 1; 121 temp_setup->fout_error = new_diff;
122 memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
123
124 if (temp_setup->fout_request == temp_setup->fout)
125 return 0;
126 }
127 return -1;
60} 128}
61 129
62static unsigned long clk_pll1_recalc_rate(struct clk_hw *hw, 130static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
63 unsigned long parent_rate) 131 struct clk_sccg_pll_setup *temp_setup)
64{ 132{
65 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 133 int ret = -EINVAL;
66 u32 val, divf; 134
135 for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX;
136 temp_setup->divq++) {
137 temp_setup->vco2 = temp_setup->vco1;
138 do_div(temp_setup->vco2, temp_setup->divr2 + 1);
139 temp_setup->vco2 *= 2;
140 temp_setup->vco2 *= temp_setup->divf2 + 1;
141 if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ &&
142 temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) {
143 temp_setup->fout = temp_setup->vco2;
144 do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
145
146 ret = clk_sccg_pll2_check_match(setup, temp_setup);
147 if (!ret) {
148 temp_setup->bypass = PLL_BYPASS1;
149 return ret;
150 }
151 }
152 }
67 153
68 val = readl_relaxed(pll->base + PLL_CFG2); 154 return ret;
69 divf = FIELD_GET(PLL_DIVF1_MASK, val); 155}
156
157static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
158 struct clk_sccg_pll_setup *temp_setup)
159{
160 int ret = -EINVAL;
161
162 for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
163 temp_setup->divf2++) {
164 ret = clk_sccg_divq_lookup(setup, temp_setup);
165 if (!ret)
166 return ret;
167 }
70 168
71 return parent_rate * 2 * (divf + 1); 169 return ret;
72} 170}
73 171
74static long clk_pll1_round_rate(struct clk_hw *hw, unsigned long rate, 172static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
75 unsigned long *prate) 173 struct clk_sccg_pll_setup *temp_setup)
76{ 174{
77 unsigned long parent_rate = *prate; 175 int ret = -EINVAL;
78 u32 div; 176
177 for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX;
178 temp_setup->divr2++) {
179 temp_setup->ref_div2 = temp_setup->vco1;
180 do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
181 if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
182 temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
183 ret = clk_sccg_divf2_lookup(setup, temp_setup);
184 if (!ret)
185 return ret;
186 }
187 }
188
189 return ret;
190}
191
192static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
193 struct clk_sccg_pll_setup *temp_setup,
194 uint64_t ref)
195{
196
197 int ret = -EINVAL;
79 198
80 if (!parent_rate) 199 if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
81 return 0; 200 return ret;
82 201
83 div = rate / (parent_rate * 2); 202 temp_setup->vco1 = ref;
84 203
85 return parent_rate * div * 2; 204 ret = clk_sccg_divr2_lookup(setup, temp_setup);
205 return ret;
86} 206}
87 207
88static int clk_pll1_set_rate(struct clk_hw *hw, unsigned long rate, 208static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
89 unsigned long parent_rate) 209 struct clk_sccg_pll_setup *temp_setup)
90{ 210{
91 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 211 int ret = -EINVAL;
92 u32 val;
93 u32 divf;
94 212
95 if (!parent_rate) 213 for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX;
96 return -EINVAL; 214 temp_setup->divf1++) {
215 uint64_t vco1 = temp_setup->ref;
97 216
98 divf = rate / (parent_rate * 2); 217 do_div(vco1, temp_setup->divr1 + 1);
218 vco1 *= 2;
219 vco1 *= temp_setup->divf1 + 1;
99 220
100 val = readl_relaxed(pll->base + PLL_CFG2); 221 ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
101 val &= ~PLL_DIVF1_MASK; 222 if (!ret) {
102 val |= FIELD_PREP(PLL_DIVF1_MASK, divf - 1); 223 temp_setup->bypass = PLL_BYPASS_NONE;
103 writel_relaxed(val, pll->base + PLL_CFG2); 224 return ret;
225 }
226 }
227
228 return ret;
229}
230
231static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
232 struct clk_sccg_pll_setup *temp_setup)
233{
234 int ret = -EINVAL;
235
236 for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX;
237 temp_setup->divr1++) {
238 temp_setup->ref_div1 = temp_setup->ref;
239 do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
240 if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
241 temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
242 ret = clk_sccg_divf1_lookup(setup, temp_setup);
243 if (!ret)
244 return ret;
245 }
246 }
247
248 return ret;
249}
250
251static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
252 struct clk_sccg_pll_setup *temp_setup,
253 uint64_t ref)
254{
255
256 int ret = -EINVAL;
257
258 if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
259 return ret;
260
261 temp_setup->ref = ref;
262
263 ret = clk_sccg_divr1_lookup(setup, temp_setup);
264
265 return ret;
266}
267
268static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
269 uint64_t prate,
270 uint64_t rate, int try_bypass)
271{
272 struct clk_sccg_pll_setup temp_setup;
273 int ret = -EINVAL;
274
275 memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
276 memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
277
278 temp_setup.fout_error = PLL_OUT_MAX_FREQ;
279 temp_setup.fout_request = rate;
280
281 switch (try_bypass) {
104 282
105 return clk_pll_wait_lock(pll); 283 case PLL_BYPASS2:
284 if (prate == rate) {
285 setup->bypass = PLL_BYPASS2;
286 setup->fout = rate;
287 ret = 0;
288 }
289 break;
290
291 case PLL_BYPASS1:
292 ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
293 break;
294
295 case PLL_BYPASS_NONE:
296 ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
297 break;
298 }
299
300 return ret;
301}
302
303
304static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
305{
306 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
307
308 u32 val = readl_relaxed(pll->base + PLL_CFG0);
309
310 return (val & PLL_PD_MASK) ? 0 : 1;
106} 311}
107 312
108static int clk_pll1_prepare(struct clk_hw *hw) 313static int clk_sccg_pll_prepare(struct clk_hw *hw)
109{ 314{
110 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 315 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
111 u32 val; 316 u32 val;
@@ -114,10 +319,10 @@ static int clk_pll1_prepare(struct clk_hw *hw)
114 val &= ~PLL_PD_MASK; 319 val &= ~PLL_PD_MASK;
115 writel_relaxed(val, pll->base + PLL_CFG0); 320 writel_relaxed(val, pll->base + PLL_CFG0);
116 321
117 return clk_pll_wait_lock(pll); 322 return clk_sccg_pll_wait_lock(pll);
118} 323}
119 324
120static void clk_pll1_unprepare(struct clk_hw *hw) 325static void clk_sccg_pll_unprepare(struct clk_hw *hw)
121{ 326{
122 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 327 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
123 u32 val; 328 u32 val;
@@ -125,121 +330,208 @@ static void clk_pll1_unprepare(struct clk_hw *hw)
125 val = readl_relaxed(pll->base + PLL_CFG0); 330 val = readl_relaxed(pll->base + PLL_CFG0);
126 val |= PLL_PD_MASK; 331 val |= PLL_PD_MASK;
127 writel_relaxed(val, pll->base + PLL_CFG0); 332 writel_relaxed(val, pll->base + PLL_CFG0);
128
129} 333}
130 334
131static unsigned long clk_pll2_recalc_rate(struct clk_hw *hw, 335static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
132 unsigned long parent_rate) 336 unsigned long parent_rate)
133{ 337{
134 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 338 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
135 u32 val, ref, divr1, divf1, divr2, divf2; 339 u32 val, divr1, divf1, divr2, divf2, divq;
136 u64 temp64; 340 u64 temp64;
137 341
138 val = readl_relaxed(pll->base + PLL_CFG0);
139 switch (FIELD_GET(PLL_REF_MASK, val)) {
140 case 0:
141 ref = OSC_25M;
142 break;
143 case 1:
144 ref = OSC_27M;
145 break;
146 default:
147 ref = OSC_25M;
148 break;
149 }
150
151 val = readl_relaxed(pll->base + PLL_CFG2); 342 val = readl_relaxed(pll->base + PLL_CFG2);
152 divr1 = FIELD_GET(PLL_DIVR1_MASK, val); 343 divr1 = FIELD_GET(PLL_DIVR1_MASK, val);
153 divr2 = FIELD_GET(PLL_DIVR2_MASK, val); 344 divr2 = FIELD_GET(PLL_DIVR2_MASK, val);
154 divf1 = FIELD_GET(PLL_DIVF1_MASK, val); 345 divf1 = FIELD_GET(PLL_DIVF1_MASK, val);
155 divf2 = FIELD_GET(PLL_DIVF2_MASK, val); 346 divf2 = FIELD_GET(PLL_DIVF2_MASK, val);
156 347 divq = FIELD_GET(PLL_DIVQ_MASK, val);
157 temp64 = ref * 2; 348
158 temp64 *= (divf1 + 1) * (divf2 + 1); 349 temp64 = parent_rate;
159 350
160 do_div(temp64, (divr1 + 1) * (divr2 + 1)); 351 val = clk_readl(pll->base + PLL_CFG0);
352 if (val & SSCG_PLL_BYPASS2_MASK) {
353 temp64 = parent_rate;
354 } else if (val & SSCG_PLL_BYPASS1_MASK) {
355 temp64 *= divf2;
356 do_div(temp64, (divr2 + 1) * (divq + 1));
357 } else {
358 temp64 *= 2;
359 temp64 *= (divf1 + 1) * (divf2 + 1);
360 do_div(temp64, (divr1 + 1) * (divr2 + 1) * (divq + 1));
361 }
161 362
162 return temp64; 363 return temp64;
163} 364}
164 365
165static long clk_pll2_round_rate(struct clk_hw *hw, unsigned long rate, 366static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
166 unsigned long *prate) 367 unsigned long parent_rate)
167{ 368{
168 u32 div; 369 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
169 unsigned long parent_rate = *prate; 370 struct clk_sccg_pll_setup *setup = &pll->setup;
371 u32 val;
170 372
171 if (!parent_rate) 373 /* set bypass here too since the parent might be the same */
172 return 0; 374 val = clk_readl(pll->base + PLL_CFG0);
375 val &= ~SSCG_PLL_BYPASS_MASK;
376 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
377 clk_writel(val, pll->base + PLL_CFG0);
173 378
174 div = rate / parent_rate; 379 val = readl_relaxed(pll->base + PLL_CFG2);
380 val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
381 val &= ~(PLL_DIVR1_MASK | PLL_DIVR2_MASK | PLL_DIVQ_MASK);
382 val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1);
383 val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2);
384 val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1);
385 val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2);
386 val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
387 writel_relaxed(val, pll->base + PLL_CFG2);
175 388
176 return parent_rate * div; 389 return clk_sccg_pll_wait_lock(pll);
177} 390}
178 391
179static int clk_pll2_set_rate(struct clk_hw *hw, unsigned long rate, 392static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
180 unsigned long parent_rate)
181{ 393{
394 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
182 u32 val; 395 u32 val;
183 u32 divf; 396 u8 ret = pll->parent;
397
398 val = clk_readl(pll->base + PLL_CFG0);
399 if (val & SSCG_PLL_BYPASS2_MASK)
400 ret = pll->bypass2;
401 else if (val & SSCG_PLL_BYPASS1_MASK)
402 ret = pll->bypass1;
403 return ret;
404}
405
406static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
407{
184 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 408 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
409 u32 val;
185 410
186 if (!parent_rate) 411 val = clk_readl(pll->base + PLL_CFG0);
187 return -EINVAL; 412 val &= ~SSCG_PLL_BYPASS_MASK;
413 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
414 clk_writel(val, pll->base + PLL_CFG0);
188 415
189 divf = rate / parent_rate; 416 return clk_sccg_pll_wait_lock(pll);
417}
190 418
191 val = readl_relaxed(pll->base + PLL_CFG2); 419static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
192 val &= ~PLL_DIVF2_MASK; 420 struct clk_rate_request *req,
193 val |= FIELD_PREP(PLL_DIVF2_MASK, divf - 1); 421 uint64_t min,
194 writel_relaxed(val, pll->base + PLL_CFG2); 422 uint64_t max,
423 uint64_t rate,
424 int bypass)
425{
426 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
427 struct clk_sccg_pll_setup *setup = &pll->setup;
428 struct clk_hw *parent_hw = NULL;
429 int bypass_parent_index;
430 int ret = -EINVAL;
431
432 req->max_rate = max;
433 req->min_rate = min;
434
435 switch (bypass) {
436 case PLL_BYPASS2:
437 bypass_parent_index = pll->bypass2;
438 break;
439 case PLL_BYPASS1:
440 bypass_parent_index = pll->bypass1;
441 break;
442 default:
443 bypass_parent_index = pll->parent;
444 break;
445 }
446
447 parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
448 ret = __clk_determine_rate(parent_hw, req);
449 if (!ret) {
450 ret = clk_sccg_pll_find_setup(setup, req->rate,
451 rate, bypass);
452 }
453
454 req->best_parent_hw = parent_hw;
455 req->best_parent_rate = req->rate;
456 req->rate = setup->fout;
195 457
196 return clk_pll_wait_lock(pll); 458 return ret;
197} 459}
198 460
199static const struct clk_ops clk_sccg_pll1_ops = { 461static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
200 .is_prepared = clk_pll1_is_prepared, 462 struct clk_rate_request *req)
201 .recalc_rate = clk_pll1_recalc_rate, 463{
202 .round_rate = clk_pll1_round_rate, 464 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
203 .set_rate = clk_pll1_set_rate, 465 struct clk_sccg_pll_setup *setup = &pll->setup;
204}; 466 uint64_t rate = req->rate;
467 uint64_t min = req->min_rate;
468 uint64_t max = req->max_rate;
469 int ret = -EINVAL;
470
471 if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
472 return ret;
473
474 ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
475 rate, PLL_BYPASS2);
476 if (!ret)
477 return ret;
478
479 ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
480 PLL_STAGE1_REF_MAX_FREQ, rate,
481 PLL_BYPASS1);
482 if (!ret)
483 return ret;
484
485 ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
486 PLL_REF_MAX_FREQ, rate,
487 PLL_BYPASS_NONE);
488 if (!ret)
489 return ret;
490
491 if (setup->fout >= min && setup->fout <= max)
492 ret = 0;
493
494 return ret;
495}
205 496
206static const struct clk_ops clk_sccg_pll2_ops = { 497static const struct clk_ops clk_sccg_pll_ops = {
207 .prepare = clk_pll1_prepare, 498 .prepare = clk_sccg_pll_prepare,
208 .unprepare = clk_pll1_unprepare, 499 .unprepare = clk_sccg_pll_unprepare,
209 .recalc_rate = clk_pll2_recalc_rate, 500 .is_prepared = clk_sccg_pll_is_prepared,
210 .round_rate = clk_pll2_round_rate, 501 .recalc_rate = clk_sccg_pll_recalc_rate,
211 .set_rate = clk_pll2_set_rate, 502 .set_rate = clk_sccg_pll_set_rate,
503 .set_parent = clk_sccg_pll_set_parent,
504 .get_parent = clk_sccg_pll_get_parent,
505 .determine_rate = clk_sccg_pll_determine_rate,
212}; 506};
213 507
214struct clk *imx_clk_sccg_pll(const char *name, 508struct clk *imx_clk_sccg_pll(const char *name,
215 const char *parent_name, 509 const char * const *parent_names,
510 u8 num_parents,
511 u8 parent, u8 bypass1, u8 bypass2,
216 void __iomem *base, 512 void __iomem *base,
217 enum imx_sccg_pll_type pll_type) 513 unsigned long flags)
218{ 514{
219 struct clk_sccg_pll *pll; 515 struct clk_sccg_pll *pll;
220 struct clk_init_data init; 516 struct clk_init_data init;
221 struct clk_hw *hw; 517 struct clk_hw *hw;
222 int ret; 518 int ret;
223 519
224 switch (pll_type) {
225 case SCCG_PLL1:
226 init.ops = &clk_sccg_pll1_ops;
227 break;
228 case SCCG_PLL2:
229 init.ops = &clk_sccg_pll2_ops;
230 break;
231 default:
232 return ERR_PTR(-EINVAL);
233 }
234
235 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 520 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
236 if (!pll) 521 if (!pll)
237 return ERR_PTR(-ENOMEM); 522 return ERR_PTR(-ENOMEM);
238 523
524 pll->parent = parent;
525 pll->bypass1 = bypass1;
526 pll->bypass2 = bypass2;
527
528 pll->base = base;
239 init.name = name; 529 init.name = name;
240 init.flags = 0; 530 init.ops = &clk_sccg_pll_ops;
241 init.parent_names = &parent_name; 531
242 init.num_parents = 1; 532 init.flags = flags;
533 init.parent_names = parent_names;
534 init.num_parents = num_parents;
243 535
244 pll->base = base; 536 pll->base = base;
245 pll->hw.init = &init; 537 pll->hw.init = &init;
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index 7ccf7edfe11c..fbef740704d0 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -4,12 +4,17 @@
4 * Dong Aisheng <aisheng.dong@nxp.com> 4 * Dong Aisheng <aisheng.dong@nxp.com>
5 */ 5 */
6 6
7#include <dt-bindings/firmware/imx/rsrc.h>
8#include <linux/arm-smccc.h>
7#include <linux/clk-provider.h> 9#include <linux/clk-provider.h>
8#include <linux/err.h> 10#include <linux/err.h>
9#include <linux/slab.h> 11#include <linux/slab.h>
10 12
11#include "clk-scu.h" 13#include "clk-scu.h"
12 14
15#define IMX_SIP_CPUFREQ 0xC2000001
16#define IMX_SIP_SET_CPUFREQ 0x00
17
13static struct imx_sc_ipc *ccm_ipc_handle; 18static struct imx_sc_ipc *ccm_ipc_handle;
14 19
15/* 20/*
@@ -66,6 +71,41 @@ struct imx_sc_msg_get_clock_rate {
66}; 71};
67 72
68/* 73/*
74 * struct imx_sc_msg_get_clock_parent - clock get parent protocol
75 * @hdr: SCU protocol header
76 * @req: get parent request protocol
77 * @resp: get parent response protocol
78 *
79 * This structure describes the SCU protocol of clock get parent
80 */
81struct imx_sc_msg_get_clock_parent {
82 struct imx_sc_rpc_msg hdr;
83 union {
84 struct req_get_clock_parent {
85 __le16 resource;
86 u8 clk;
87 } __packed req;
88 struct resp_get_clock_parent {
89 u8 parent;
90 } resp;
91 } data;
92};
93
94/*
95 * struct imx_sc_msg_set_clock_parent - clock set parent protocol
96 * @hdr: SCU protocol header
97 * @req: set parent request protocol
98 *
99 * This structure describes the SCU protocol of clock set parent
100 */
101struct imx_sc_msg_set_clock_parent {
102 struct imx_sc_rpc_msg hdr;
103 __le16 resource;
104 u8 clk;
105 u8 parent;
106} __packed;
107
108/*
69 * struct imx_sc_msg_req_clock_enable - clock gate protocol 109 * struct imx_sc_msg_req_clock_enable - clock gate protocol
70 * @hdr: SCU protocol header 110 * @hdr: SCU protocol header
71 * @resource: clock resource to gate 111 * @resource: clock resource to gate
@@ -145,6 +185,25 @@ static long clk_scu_round_rate(struct clk_hw *hw, unsigned long rate,
145 return rate; 185 return rate;
146} 186}
147 187
188static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate,
189 unsigned long parent_rate)
190{
191 struct clk_scu *clk = to_clk_scu(hw);
192 struct arm_smccc_res res;
193 unsigned long cluster_id;
194
195 if (clk->rsrc_id == IMX_SC_R_A35)
196 cluster_id = 0;
197 else
198 return -EINVAL;
199
200 /* CPU frequency scaling can ONLY be done by ARM-Trusted-Firmware */
201 arm_smccc_smc(IMX_SIP_CPUFREQ, IMX_SIP_SET_CPUFREQ,
202 cluster_id, rate, 0, 0, 0, 0, &res);
203
204 return 0;
205}
206
148/* 207/*
149 * clk_scu_set_rate - Set rate for a SCU clock 208 * clk_scu_set_rate - Set rate for a SCU clock
150 * @hw: clock to change rate for 209 * @hw: clock to change rate for
@@ -173,6 +232,49 @@ static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate,
173 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 232 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
174} 233}
175 234
235static u8 clk_scu_get_parent(struct clk_hw *hw)
236{
237 struct clk_scu *clk = to_clk_scu(hw);
238 struct imx_sc_msg_get_clock_parent msg;
239 struct imx_sc_rpc_msg *hdr = &msg.hdr;
240 int ret;
241
242 hdr->ver = IMX_SC_RPC_VERSION;
243 hdr->svc = IMX_SC_RPC_SVC_PM;
244 hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_PARENT;
245 hdr->size = 2;
246
247 msg.data.req.resource = cpu_to_le16(clk->rsrc_id);
248 msg.data.req.clk = clk->clk_type;
249
250 ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
251 if (ret) {
252 pr_err("%s: failed to get clock parent %d\n",
253 clk_hw_get_name(hw), ret);
254 return 0;
255 }
256
257 return msg.data.resp.parent;
258}
259
260static int clk_scu_set_parent(struct clk_hw *hw, u8 index)
261{
262 struct clk_scu *clk = to_clk_scu(hw);
263 struct imx_sc_msg_set_clock_parent msg;
264 struct imx_sc_rpc_msg *hdr = &msg.hdr;
265
266 hdr->ver = IMX_SC_RPC_VERSION;
267 hdr->svc = IMX_SC_RPC_SVC_PM;
268 hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_PARENT;
269 hdr->size = 2;
270
271 msg.resource = cpu_to_le16(clk->rsrc_id);
272 msg.clk = clk->clk_type;
273 msg.parent = index;
274
275 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
276}
277
176static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, 278static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource,
177 u8 clk, bool enable, bool autog) 279 u8 clk, bool enable, bool autog)
178{ 280{
@@ -228,11 +330,22 @@ static const struct clk_ops clk_scu_ops = {
228 .recalc_rate = clk_scu_recalc_rate, 330 .recalc_rate = clk_scu_recalc_rate,
229 .round_rate = clk_scu_round_rate, 331 .round_rate = clk_scu_round_rate,
230 .set_rate = clk_scu_set_rate, 332 .set_rate = clk_scu_set_rate,
333 .get_parent = clk_scu_get_parent,
334 .set_parent = clk_scu_set_parent,
335 .prepare = clk_scu_prepare,
336 .unprepare = clk_scu_unprepare,
337};
338
339static const struct clk_ops clk_scu_cpu_ops = {
340 .recalc_rate = clk_scu_recalc_rate,
341 .round_rate = clk_scu_round_rate,
342 .set_rate = clk_scu_atf_set_cpu_rate,
231 .prepare = clk_scu_prepare, 343 .prepare = clk_scu_prepare,
232 .unprepare = clk_scu_unprepare, 344 .unprepare = clk_scu_unprepare,
233}; 345};
234 346
235struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type) 347struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
348 int num_parents, u32 rsrc_id, u8 clk_type)
236{ 349{
237 struct clk_init_data init; 350 struct clk_init_data init;
238 struct clk_scu *clk; 351 struct clk_scu *clk;
@@ -248,7 +361,13 @@ struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type)
248 361
249 init.name = name; 362 init.name = name;
250 init.ops = &clk_scu_ops; 363 init.ops = &clk_scu_ops;
251 init.num_parents = 0; 364 if (rsrc_id == IMX_SC_R_A35)
365 init.ops = &clk_scu_cpu_ops;
366 else
367 init.ops = &clk_scu_ops;
368 init.parent_names = parents;
369 init.num_parents = num_parents;
370
252 /* 371 /*
253 * Note on MX8, the clocks are tightly coupled with power domain 372 * Note on MX8, the clocks are tightly coupled with power domain
254 * that once the power domain is off, the clock status may be 373 * that once the power domain is off, the clock status may be
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index 52c1746ec988..2bcfaf06a458 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -10,7 +10,21 @@
10#include <linux/firmware/imx/sci.h> 10#include <linux/firmware/imx/sci.h>
11 11
12int imx_clk_scu_init(void); 12int imx_clk_scu_init(void);
13struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type); 13
14struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
15 int num_parents, u32 rsrc_id, u8 clk_type);
16
17static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id,
18 u8 clk_type)
19{
20 return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type);
21}
22
23static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents,
24 int num_parents, u32 rsrc_id, u8 clk_type)
25{
26 return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type);
27}
14 28
15struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, 29struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
16 unsigned long flags, void __iomem *reg, 30 unsigned long flags, void __iomem *reg,
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 028312de21b8..5748ec8673e4 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -27,6 +27,30 @@ enum imx_sccg_pll_type {
27 SCCG_PLL2, 27 SCCG_PLL2,
28}; 28};
29 29
30enum imx_pll14xx_type {
31 PLL_1416X,
32 PLL_1443X,
33};
34
35/* NOTE: Rate table should be kept sorted in descending order. */
36struct imx_pll14xx_rate_table {
37 unsigned int rate;
38 unsigned int pdiv;
39 unsigned int mdiv;
40 unsigned int sdiv;
41 unsigned int kdiv;
42};
43
44struct imx_pll14xx_clk {
45 enum imx_pll14xx_type type;
46 const struct imx_pll14xx_rate_table *rate_table;
47 int rate_count;
48 int flags;
49};
50
51struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
52 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
53
30struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, 54struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
31 const char *parent, void __iomem *base); 55 const char *parent, void __iomem *base);
32 56
@@ -36,9 +60,12 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
36struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, 60struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
37 void __iomem *base); 61 void __iomem *base);
38 62
39struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name, 63struct clk *imx_clk_sccg_pll(const char *name,
40 void __iomem *base, 64 const char * const *parent_names,
41 enum imx_sccg_pll_type pll_type); 65 u8 num_parents,
66 u8 parent, u8 bypass1, u8 bypass2,
67 void __iomem *base,
68 unsigned long flags);
42 69
43enum imx_pllv3_type { 70enum imx_pllv3_type {
44 IMX_PLLV3_GENERIC, 71 IMX_PLLV3_GENERIC,
@@ -329,7 +356,8 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
329} 356}
330 357
331static inline struct clk *imx_clk_mux2_flags(const char *name, 358static inline struct clk *imx_clk_mux2_flags(const char *name,
332 void __iomem *reg, u8 shift, u8 width, const char **parents, 359 void __iomem *reg, u8 shift, u8 width,
360 const char * const *parents,
333 int num_parents, unsigned long flags) 361 int num_parents, unsigned long flags)
334{ 362{
335 return clk_register_mux(NULL, name, parents, num_parents, 363 return clk_register_mux(NULL, name, parents, num_parents,
@@ -354,7 +382,7 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
354 struct clk *step); 382 struct clk *step);
355 383
356struct clk *imx8m_clk_composite_flags(const char *name, 384struct clk *imx8m_clk_composite_flags(const char *name,
357 const char **parent_names, 385 const char * const *parent_names,
358 int num_parents, void __iomem *reg, 386 int num_parents, void __iomem *reg,
359 unsigned long flags); 387 unsigned long flags);
360 388
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index d083b860f083..a60a1be937ad 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -229,9 +229,10 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
229 {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 229 {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
230 {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 230 {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
231 {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 231 {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
232 {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock}, 232 {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x09, 0x09, 0x0, 0, &disp0_lock},
233 {MMP2_CLK_DISP0_LCDC, "disp0_lcdc_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x12, 0x12, 0x0, 0, &disp0_lock},
233 {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock}, 234 {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
234 {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock}, 235 {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x09, 0x09, 0x0, 0, &disp1_lock},
235 {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock}, 236 {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock},
236 {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock}, 237 {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
237 {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock}, 238 {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.c b/drivers/clk/samsung/clk-exynos5-subcmu.c
index 93306283d764..8ae44b5db4c2 100644
--- a/drivers/clk/samsung/clk-exynos5-subcmu.c
+++ b/drivers/clk/samsung/clk-exynos5-subcmu.c
@@ -136,15 +136,20 @@ static int __init exynos5_clk_register_subcmu(struct device *parent,
136{ 136{
137 struct of_phandle_args genpdspec = { .np = pd_node }; 137 struct of_phandle_args genpdspec = { .np = pd_node };
138 struct platform_device *pdev; 138 struct platform_device *pdev;
139 int ret;
140
141 pdev = platform_device_alloc("exynos5-subcmu", PLATFORM_DEVID_AUTO);
142 if (!pdev)
143 return -ENOMEM;
139 144
140 pdev = platform_device_alloc(info->pd_name, -1);
141 pdev->dev.parent = parent; 145 pdev->dev.parent = parent;
142 pdev->driver_override = "exynos5-subcmu";
143 platform_set_drvdata(pdev, (void *)info); 146 platform_set_drvdata(pdev, (void *)info);
144 of_genpd_add_device(&genpdspec, &pdev->dev); 147 of_genpd_add_device(&genpdspec, &pdev->dev);
145 platform_device_add(pdev); 148 ret = platform_device_add(pdev);
149 if (ret)
150 platform_device_put(pdev);
146 151
147 return 0; 152 return ret;
148} 153}
149 154
150static int __init exynos5_clk_probe(struct platform_device *pdev) 155static int __init exynos5_clk_probe(struct platform_device *pdev)
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 751e2c4fb65b..dae1c96de933 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -559,7 +559,7 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
559 /* ENABLE_ACLK_TOP */ 559 /* ENABLE_ACLK_TOP */
560 GATE(CLK_ACLK_G3D_400, "aclk_g3d_400", "div_aclk_g3d_400", 560 GATE(CLK_ACLK_G3D_400, "aclk_g3d_400", "div_aclk_g3d_400",
561 ENABLE_ACLK_TOP, 30, CLK_IS_CRITICAL, 0), 561 ENABLE_ACLK_TOP, 30, CLK_IS_CRITICAL, 0),
562 GATE(CLK_ACLK_IMEM_SSX_266, "aclk_imem_ssx_266", 562 GATE(CLK_ACLK_IMEM_SSSX_266, "aclk_imem_sssx_266",
563 "div_aclk_imem_sssx_266", ENABLE_ACLK_TOP, 563 "div_aclk_imem_sssx_266", ENABLE_ACLK_TOP,
564 29, CLK_IGNORE_UNUSED, 0), 564 29, CLK_IGNORE_UNUSED, 0),
565 GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400", 565 GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400",
@@ -568,10 +568,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
568 GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400", 568 GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400",
569 ENABLE_ACLK_TOP, 25, 569 ENABLE_ACLK_TOP, 25,
570 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), 570 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
571 GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_266", 571 GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_200",
572 ENABLE_ACLK_TOP, 24, 572 ENABLE_ACLK_TOP, 24,
573 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), 573 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
574 GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_200", 574 GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_266",
575 ENABLE_ACLK_TOP, 23, 575 ENABLE_ACLK_TOP, 23,
576 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), 576 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0),
577 GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b", 577 GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b",
@@ -5467,6 +5467,35 @@ static const struct samsung_cmu_info cam1_cmu_info __initconst = {
5467 .clk_name = "aclk_cam1_400", 5467 .clk_name = "aclk_cam1_400",
5468}; 5468};
5469 5469
5470/*
5471 * Register offset definitions for CMU_IMEM
5472 */
5473#define ENABLE_ACLK_IMEM_SLIMSSS 0x080c
5474#define ENABLE_PCLK_IMEM_SLIMSSS 0x0908
5475
5476static const unsigned long imem_clk_regs[] __initconst = {
5477 ENABLE_ACLK_IMEM_SLIMSSS,
5478 ENABLE_PCLK_IMEM_SLIMSSS,
5479};
5480
5481static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
5482 /* ENABLE_ACLK_IMEM_SLIMSSS */
5483 GATE(CLK_ACLK_SLIMSSS, "aclk_slimsss", "aclk_imem_sssx_266",
5484 ENABLE_ACLK_IMEM_SLIMSSS, 0, CLK_IGNORE_UNUSED, 0),
5485
5486 /* ENABLE_PCLK_IMEM_SLIMSSS */
5487 GATE(CLK_PCLK_SLIMSSS, "pclk_slimsss", "aclk_imem_200",
5488 ENABLE_PCLK_IMEM_SLIMSSS, 0, CLK_IGNORE_UNUSED, 0),
5489};
5490
5491static const struct samsung_cmu_info imem_cmu_info __initconst = {
5492 .gate_clks = imem_gate_clks,
5493 .nr_gate_clks = ARRAY_SIZE(imem_gate_clks),
5494 .nr_clk_ids = IMEM_NR_CLK,
5495 .clk_regs = imem_clk_regs,
5496 .nr_clk_regs = ARRAY_SIZE(imem_clk_regs),
5497 .clk_name = "aclk_imem_200",
5498};
5470 5499
5471struct exynos5433_cmu_data { 5500struct exynos5433_cmu_data {
5472 struct samsung_clk_reg_dump *clk_save; 5501 struct samsung_clk_reg_dump *clk_save;
@@ -5655,6 +5684,9 @@ static const struct of_device_id exynos5433_cmu_of_match[] = {
5655 .compatible = "samsung,exynos5433-cmu-mscl", 5684 .compatible = "samsung,exynos5433-cmu-mscl",
5656 .data = &mscl_cmu_info, 5685 .data = &mscl_cmu_info,
5657 }, { 5686 }, {
5687 .compatible = "samsung,exynos5433-cmu-imem",
5688 .data = &imem_cmu_info,
5689 }, {
5658 }, 5690 },
5659}; 5691};
5660 5692
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index 884067e4f1a1..f38f0e24e3b6 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -389,7 +389,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
389 ARRAY_SIZE(s3c2450_gates)); 389 ARRAY_SIZE(s3c2450_gates));
390 samsung_clk_register_alias(ctx, s3c2450_aliases, 390 samsung_clk_register_alias(ctx, s3c2450_aliases,
391 ARRAY_SIZE(s3c2450_aliases)); 391 ARRAY_SIZE(s3c2450_aliases));
392 /* fall through, as s3c2450 extends the s3c2416 clocks */ 392 /* fall through - as s3c2450 extends the s3c2416 clocks */
393 case S3C2416: 393 case S3C2416:
394 samsung_clk_register_div(ctx, s3c2416_dividers, 394 samsung_clk_register_div(ctx, s3c2416_dividers,
395 ARRAY_SIZE(s3c2416_dividers)); 395 ARRAY_SIZE(s3c2416_dividers));
diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c
index 688e403333b9..0c210984765a 100644
--- a/drivers/clk/ti/adpll.c
+++ b/drivers/clk/ti/adpll.c
@@ -614,7 +614,7 @@ static int ti_adpll_init_clkout(struct ti_adpll_data *d,
614 614
615 init.name = child_name; 615 init.name = child_name;
616 init.ops = ops; 616 init.ops = ops;
617 init.flags = CLK_IS_BASIC; 617 init.flags = 0;
618 co->hw.init = &init; 618 co->hw.init = &init;
619 parent_names[0] = __clk_get_name(clk0); 619 parent_names[0] = __clk_get_name(clk0);
620 parent_names[1] = __clk_get_name(clk1); 620 parent_names[1] = __clk_get_name(clk1);
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 222f68bc3f2a..015a657d3382 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -165,7 +165,7 @@ static void __init omap_clk_register_apll(void *user,
165 165
166 ad->clk_bypass = __clk_get_hw(clk); 166 ad->clk_bypass = __clk_get_hw(clk);
167 167
168 clk = ti_clk_register(NULL, &clk_hw->hw, node->name); 168 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
169 if (!IS_ERR(clk)) { 169 if (!IS_ERR(clk)) {
170 of_clk_add_provider(node, of_clk_src_simple_get, clk); 170 of_clk_add_provider(node, of_clk_src_simple_get, clk);
171 kfree(clk_hw->hw.init->parent_names); 171 kfree(clk_hw->hw.init->parent_names);
@@ -402,7 +402,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
402 if (ret) 402 if (ret)
403 goto cleanup; 403 goto cleanup;
404 404
405 clk = clk_register(NULL, &clk_hw->hw); 405 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
406 if (!IS_ERR(clk)) { 406 if (!IS_ERR(clk)) {
407 of_clk_add_provider(node, of_clk_src_simple_get, clk); 407 of_clk_add_provider(node, of_clk_src_simple_get, clk);
408 kfree(init); 408 kfree(init);
diff --git a/drivers/clk/ti/autoidle.c b/drivers/clk/ti/autoidle.c
index 7bb9afbe4058..1cae226759dd 100644
--- a/drivers/clk/ti/autoidle.c
+++ b/drivers/clk/ti/autoidle.c
@@ -35,7 +35,44 @@ struct clk_ti_autoidle {
35#define AUTOIDLE_LOW 0x1 35#define AUTOIDLE_LOW 0x1
36 36
37static LIST_HEAD(autoidle_clks); 37static LIST_HEAD(autoidle_clks);
38static LIST_HEAD(clk_hw_omap_clocks); 38
39/*
40 * we have some non-atomic read/write
41 * operations behind it, so lets
42 * take one lock for handling autoidle
43 * of all clocks
44 */
45static DEFINE_SPINLOCK(autoidle_spinlock);
46
47static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
48{
49 if (clk->ops && clk->ops->deny_idle) {
50 unsigned long irqflags;
51
52 spin_lock_irqsave(&autoidle_spinlock, irqflags);
53 clk->autoidle_count++;
54 if (clk->autoidle_count == 1)
55 clk->ops->deny_idle(clk);
56
57 spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
58 }
59 return 0;
60}
61
62static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
63{
64 if (clk->ops && clk->ops->allow_idle) {
65 unsigned long irqflags;
66
67 spin_lock_irqsave(&autoidle_spinlock, irqflags);
68 clk->autoidle_count--;
69 if (clk->autoidle_count == 0)
70 clk->ops->allow_idle(clk);
71
72 spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
73 }
74 return 0;
75}
39 76
40/** 77/**
41 * omap2_clk_deny_idle - disable autoidle on an OMAP clock 78 * omap2_clk_deny_idle - disable autoidle on an OMAP clock
@@ -45,12 +82,15 @@ static LIST_HEAD(clk_hw_omap_clocks);
45 */ 82 */
46int omap2_clk_deny_idle(struct clk *clk) 83int omap2_clk_deny_idle(struct clk *clk)
47{ 84{
48 struct clk_hw_omap *c; 85 struct clk_hw *hw = __clk_get_hw(clk);
49 86
50 c = to_clk_hw_omap(__clk_get_hw(clk)); 87 if (omap2_clk_is_hw_omap(hw)) {
51 if (c->ops && c->ops->deny_idle) 88 struct clk_hw_omap *c = to_clk_hw_omap(hw);
52 c->ops->deny_idle(c); 89
53 return 0; 90 return _omap2_clk_deny_idle(c);
91 }
92
93 return -EINVAL;
54} 94}
55 95
56/** 96/**
@@ -61,12 +101,15 @@ int omap2_clk_deny_idle(struct clk *clk)
61 */ 101 */
62int omap2_clk_allow_idle(struct clk *clk) 102int omap2_clk_allow_idle(struct clk *clk)
63{ 103{
64 struct clk_hw_omap *c; 104 struct clk_hw *hw = __clk_get_hw(clk);
65 105
66 c = to_clk_hw_omap(__clk_get_hw(clk)); 106 if (omap2_clk_is_hw_omap(hw)) {
67 if (c->ops && c->ops->allow_idle) 107 struct clk_hw_omap *c = to_clk_hw_omap(hw);
68 c->ops->allow_idle(c); 108
69 return 0; 109 return _omap2_clk_allow_idle(c);
110 }
111
112 return -EINVAL;
70} 113}
71 114
72static void _allow_autoidle(struct clk_ti_autoidle *clk) 115static void _allow_autoidle(struct clk_ti_autoidle *clk)
@@ -168,26 +211,6 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node)
168} 211}
169 212
170/** 213/**
171 * omap2_init_clk_hw_omap_clocks - initialize an OMAP clock
172 * @hw: struct clk_hw * to initialize
173 *
174 * Add an OMAP clock @clk to the internal list of OMAP clocks. Used
175 * temporarily for autoidle handling, until this support can be
176 * integrated into the common clock framework code in some way. No
177 * return value.
178 */
179void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
180{
181 struct clk_hw_omap *c;
182
183 if (clk_hw_get_flags(hw) & CLK_IS_BASIC)
184 return;
185
186 c = to_clk_hw_omap(hw);
187 list_add(&c->node, &clk_hw_omap_clocks);
188}
189
190/**
191 * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that 214 * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that
192 * support it 215 * support it
193 * 216 *
@@ -198,11 +221,11 @@ void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
198 */ 221 */
199int omap2_clk_enable_autoidle_all(void) 222int omap2_clk_enable_autoidle_all(void)
200{ 223{
201 struct clk_hw_omap *c; 224 int ret;
202 225
203 list_for_each_entry(c, &clk_hw_omap_clocks, node) 226 ret = omap2_clk_for_each(_omap2_clk_allow_idle);
204 if (c->ops && c->ops->allow_idle) 227 if (ret)
205 c->ops->allow_idle(c); 228 return ret;
206 229
207 _clk_generic_allow_autoidle_all(); 230 _clk_generic_allow_autoidle_all();
208 231
@@ -220,11 +243,11 @@ int omap2_clk_enable_autoidle_all(void)
220 */ 243 */
221int omap2_clk_disable_autoidle_all(void) 244int omap2_clk_disable_autoidle_all(void)
222{ 245{
223 struct clk_hw_omap *c; 246 int ret;
224 247
225 list_for_each_entry(c, &clk_hw_omap_clocks, node) 248 ret = omap2_clk_for_each(_omap2_clk_deny_idle);
226 if (c->ops && c->ops->deny_idle) 249 if (ret)
227 c->ops->deny_idle(c); 250 return ret;
228 251
229 _clk_generic_deny_autoidle_all(); 252 _clk_generic_deny_autoidle_all();
230 253
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5174f9a91679..ff164a33f67d 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -31,6 +31,7 @@
31#undef pr_fmt 31#undef pr_fmt
32#define pr_fmt(fmt) "%s: " fmt, __func__ 32#define pr_fmt(fmt) "%s: " fmt, __func__
33 33
34static LIST_HEAD(clk_hw_omap_clocks);
34struct ti_clk_ll_ops *ti_clk_ll_ops; 35struct ti_clk_ll_ops *ti_clk_ll_ops;
35static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; 36static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
36 37
@@ -521,3 +522,74 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
521 522
522 return clk; 523 return clk;
523} 524}
525
526/**
527 * ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework
528 * @dev: device for this clock
529 * @hw: hardware clock handle
530 * @con: connection ID for this clock
531 *
532 * Registers a clk_hw_omap clock to the clock framewor, adds a clock alias
533 * for it, and adds the list to the available clk_hw_omap type clocks.
534 * Returns a handle to the registered clock if successful, ERR_PTR value
535 * in failure.
536 */
537struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
538 const char *con)
539{
540 struct clk *clk;
541 struct clk_hw_omap *oclk;
542
543 clk = ti_clk_register(dev, hw, con);
544 if (IS_ERR(clk))
545 return clk;
546
547 oclk = to_clk_hw_omap(hw);
548
549 list_add(&oclk->node, &clk_hw_omap_clocks);
550
551 return clk;
552}
553
554/**
555 * omap2_clk_for_each - call function for each registered clk_hw_omap
556 * @fn: pointer to a callback function
557 *
558 * Call @fn for each registered clk_hw_omap, passing @hw to each
559 * function. @fn must return 0 for success or any other value for
560 * failure. If @fn returns non-zero, the iteration across clocks
561 * will stop and the non-zero return value will be passed to the
562 * caller of omap2_clk_for_each().
563 */
564int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw))
565{
566 int ret;
567 struct clk_hw_omap *hw;
568
569 list_for_each_entry(hw, &clk_hw_omap_clocks, node) {
570 ret = (*fn)(hw);
571 if (ret)
572 break;
573 }
574
575 return ret;
576}
577
578/**
579 * omap2_clk_is_hw_omap - check if the provided clk_hw is OMAP clock
580 * @hw: clk_hw to check if it is an omap clock or not
581 *
582 * Checks if the provided clk_hw is OMAP clock or not. Returns true if
583 * it is, false otherwise.
584 */
585bool omap2_clk_is_hw_omap(struct clk_hw *hw)
586{
587 struct clk_hw_omap *oclk;
588
589 list_for_each_entry(oclk, &clk_hw_omap_clocks, node) {
590 if (&oclk->hw == hw)
591 return true;
592 }
593
594 return false;
595}
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
index 40630eb950fc..bf32d996177f 100644
--- a/drivers/clk/ti/clkctrl.c
+++ b/drivers/clk/ti/clkctrl.c
@@ -276,7 +276,7 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
276 init.parent_names = parents; 276 init.parent_names = parents;
277 init.num_parents = num_parents; 277 init.num_parents = num_parents;
278 init.ops = ops; 278 init.ops = ops;
279 init.flags = CLK_IS_BASIC; 279 init.flags = 0;
280 280
281 clk = ti_clk_register(NULL, clk_hw, init.name); 281 clk = ti_clk_register(NULL, clk_hw, init.name);
282 if (IS_ERR_OR_NULL(clk)) { 282 if (IS_ERR_OR_NULL(clk)) {
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9f312a219510..1c0fac59d809 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,8 @@ typedef void (*ti_of_clk_init_cb_t)(void *, struct device_node *);
203 203
204struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, 204struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
205 const char *con); 205 const char *con);
206struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
207 const char *con);
206int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); 208int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
207void ti_clk_add_aliases(void); 209void ti_clk_add_aliases(void);
208 210
@@ -221,7 +223,6 @@ int ti_clk_retry_init(struct device_node *node, void *user,
221 ti_of_clk_init_cb_t func); 223 ti_of_clk_init_cb_t func);
222int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type); 224int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type);
223 225
224void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw);
225int of_ti_clk_autoidle_setup(struct device_node *node); 226int of_ti_clk_autoidle_setup(struct device_node *node);
226void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); 227void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
227 228
@@ -301,6 +302,8 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
301 unsigned long *parent_rate); 302 unsigned long *parent_rate);
302int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, 303int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
303 struct clk_rate_request *req); 304 struct clk_rate_request *req);
305int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw));
306bool omap2_clk_is_hw_omap(struct clk_hw *hw);
304 307
305extern struct ti_clk_ll_ops *ti_clk_ll_ops; 308extern struct ti_clk_ll_ops *ti_clk_ll_ops;
306 309
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 07a805125e98..423a99b9f10c 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -143,7 +143,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
143 continue; 143 continue;
144 } 144 }
145 clk_hw = __clk_get_hw(clk); 145 clk_hw = __clk_get_hw(clk);
146 if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) { 146 if (!omap2_clk_is_hw_omap(clk_hw)) {
147 pr_warn("can't setup clkdm for basic clk %s\n", 147 pr_warn("can't setup clkdm for basic clk %s\n",
148 __clk_get_name(clk)); 148 __clk_get_name(clk));
149 continue; 149 continue;
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index 0241450f3eb3..4786e0ebc2e8 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -336,7 +336,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
336 336
337 init.name = name; 337 init.name = name;
338 init.ops = &ti_clk_divider_ops; 338 init.ops = &ti_clk_divider_ops;
339 init.flags = flags | CLK_IS_BASIC; 339 init.flags = flags;
340 init.parent_names = (parent_name ? &parent_name : NULL); 340 init.parent_names = (parent_name ? &parent_name : NULL);
341 init.num_parents = (parent_name ? 1 : 0); 341 init.num_parents = (parent_name ? 1 : 0);
342 342
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 6c3329bc116f..659dadb23279 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -192,10 +192,9 @@ static void __init _register_dpll(void *user,
192 dd->clk_bypass = __clk_get_hw(clk); 192 dd->clk_bypass = __clk_get_hw(clk);
193 193
194 /* register the clock */ 194 /* register the clock */
195 clk = ti_clk_register(NULL, &clk_hw->hw, node->name); 195 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
196 196
197 if (!IS_ERR(clk)) { 197 if (!IS_ERR(clk)) {
198 omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
199 of_clk_add_provider(node, of_clk_src_simple_get, clk); 198 of_clk_add_provider(node, of_clk_src_simple_get, clk);
200 kfree(clk_hw->hw.init->parent_names); 199 kfree(clk_hw->hw.init->parent_names);
201 kfree(clk_hw->hw.init); 200 kfree(clk_hw->hw.init);
@@ -265,14 +264,12 @@ static void _register_dpll_x2(struct device_node *node,
265#endif 264#endif
266 265
267 /* register the clock */ 266 /* register the clock */
268 clk = ti_clk_register(NULL, &clk_hw->hw, name); 267 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
269 268
270 if (IS_ERR(clk)) { 269 if (IS_ERR(clk))
271 kfree(clk_hw); 270 kfree(clk_hw);
272 } else { 271 else
273 omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
274 of_clk_add_provider(node, of_clk_src_simple_get, clk); 272 of_clk_add_provider(node, of_clk_src_simple_get, clk);
275 }
276} 273}
277#endif 274#endif
278 275
diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
index 44b6b6403753..3dde6c8c3354 100644
--- a/drivers/clk/ti/dpll3xxx.c
+++ b/drivers/clk/ti/dpll3xxx.c
@@ -731,7 +731,7 @@ static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
731 do { 731 do {
732 do { 732 do {
733 hw = clk_hw_get_parent(hw); 733 hw = clk_hw_get_parent(hw);
734 } while (hw && (clk_hw_get_flags(hw) & CLK_IS_BASIC)); 734 } while (hw && (!omap2_clk_is_hw_omap(hw)));
735 if (!hw) 735 if (!hw)
736 break; 736 break;
737 pclk = to_clk_hw_omap(hw); 737 pclk = to_clk_hw_omap(hw);
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index 1c78fff5513c..504c0e91cdc7 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -123,7 +123,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
123 123
124 init.flags = flags; 124 init.flags = flags;
125 125
126 clk = ti_clk_register(NULL, &clk_hw->hw, name); 126 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
127 127
128 if (IS_ERR(clk)) 128 if (IS_ERR(clk))
129 kfree(clk_hw); 129 kfree(clk_hw);
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index 87e00c2ee957..83e34429d3b1 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -57,12 +57,10 @@ static struct clk *_register_interface(struct device *dev, const char *name,
57 init.num_parents = 1; 57 init.num_parents = 1;
58 init.parent_names = &parent_name; 58 init.parent_names = &parent_name;
59 59
60 clk = ti_clk_register(NULL, &clk_hw->hw, name); 60 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
61 61
62 if (IS_ERR(clk)) 62 if (IS_ERR(clk))
63 kfree(clk_hw); 63 kfree(clk_hw);
64 else
65 omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
66 64
67 return clk; 65 return clk;
68} 66}
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 883bdde94d04..b7f9a4f068bf 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -143,7 +143,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
143 143
144 init.name = name; 144 init.name = name;
145 init.ops = &ti_clk_mux_ops; 145 init.ops = &ti_clk_mux_ops;
146 init.flags = flags | CLK_IS_BASIC; 146 init.flags = flags;
147 init.parent_names = parent_names; 147 init.parent_names = parent_names;
148 init.num_parents = num_parents; 148 init.num_parents = num_parents;
149 149
diff --git a/drivers/clk/uniphier/clk-uniphier-cpugear.c b/drivers/clk/uniphier/clk-uniphier-cpugear.c
index ec11f55594ad..5d2d42b7e182 100644
--- a/drivers/clk/uniphier/clk-uniphier-cpugear.c
+++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c
@@ -47,7 +47,7 @@ static int uniphier_clk_cpugear_set_parent(struct clk_hw *hw, u8 index)
47 return ret; 47 return ret;
48 48
49 ret = regmap_write_bits(gear->regmap, 49 ret = regmap_write_bits(gear->regmap,
50 gear->regbase + UNIPHIER_CLK_CPUGEAR_SET, 50 gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
51 UNIPHIER_CLK_CPUGEAR_UPD_BIT, 51 UNIPHIER_CLK_CPUGEAR_UPD_BIT,
52 UNIPHIER_CLK_CPUGEAR_UPD_BIT); 52 UNIPHIER_CLK_CPUGEAR_UPD_BIT);
53 if (ret) 53 if (ret)