diff options
Diffstat (limited to 'drivers')
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 | ||
| 44 | static 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 | */ | ||
| 66 | static 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 | |||
| 44 | static int twl6040_pdmclk_prepare(struct clk_hw *hw) | 81 | static 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 | |||
| 99 | out_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 | ||
| 11 | config 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 | |||
| 11 | config CLK_IMX8MQ | 17 | config 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 | ||
| 23 | obj-$(CONFIG_MXC_CLK_SCU) += \ | 24 | obj-$(CONFIG_MXC_CLK_SCU) += \ |
| 24 | clk-scu.o \ | 25 | clk-scu.o \ |
| 25 | clk-lpcg-scu.o | 26 | clk-lpcg-scu.o |
| 26 | 27 | ||
| 28 | obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o | ||
| 27 | obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o | 29 | obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o |
| 28 | obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o | 30 | obj-$(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 | ||
| 125 | struct clk *imx8m_clk_composite_flags(const char *name, | 125 | struct 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 | |||
| 19 | static u32 share_count_sai1; | ||
| 20 | static u32 share_count_sai2; | ||
| 21 | static u32 share_count_sai3; | ||
| 22 | static u32 share_count_sai4; | ||
| 23 | static u32 share_count_sai5; | ||
| 24 | static u32 share_count_sai6; | ||
| 25 | static u32 share_count_dcss; | ||
| 26 | static u32 share_count_pdm; | ||
| 27 | static 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 | |||
| 46 | static 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 | |||
| 57 | static 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 | |||
| 62 | static 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 | |||
| 67 | static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = { | ||
| 68 | PLL_1443X_RATE(650000000U, 325, 3, 2, 0), | ||
| 69 | }; | ||
| 70 | |||
| 71 | static 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 | |||
| 77 | static 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 | |||
| 83 | static 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 | |||
| 89 | static 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 | |||
| 95 | static 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 | |||
| 101 | static 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 | |||
| 107 | static 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 | |||
| 113 | static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; | ||
| 114 | static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; | ||
| 115 | static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; | ||
| 116 | static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; | ||
| 117 | static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; | ||
| 118 | static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; | ||
| 119 | static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; | ||
| 120 | static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; | ||
| 121 | static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", }; | ||
| 122 | static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; | ||
| 123 | static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; | ||
| 124 | |||
| 125 | /* CCM ROOT */ | ||
| 126 | static 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 | |||
| 129 | static 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 | |||
| 132 | static 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 | |||
| 135 | static 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 | |||
| 138 | static 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 | |||
| 141 | static 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 | |||
| 144 | static 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 | |||
| 147 | static 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 | |||
| 150 | static 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 | |||
| 153 | static 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 | |||
| 156 | static 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 | |||
| 159 | static 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 | |||
| 162 | static 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 | |||
| 165 | static 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 | |||
| 168 | static 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 | |||
| 171 | static 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 | |||
| 174 | static 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 | |||
| 177 | static 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 | |||
| 180 | static 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 | |||
| 183 | static 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 | |||
| 186 | static 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 | |||
| 189 | static 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 | |||
| 192 | static 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 | |||
| 195 | static 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 | |||
| 198 | static 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 | |||
| 201 | static 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 | |||
| 204 | static 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 | |||
| 207 | static 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 | |||
| 210 | static 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 | |||
| 213 | static 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 | |||
| 216 | static 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 | |||
| 219 | static 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 | |||
| 222 | static 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 | |||
| 225 | static 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 | |||
| 228 | static 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 | |||
| 231 | static 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 | |||
| 234 | static 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 | |||
| 237 | static 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 | |||
| 240 | static 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 | |||
| 243 | static 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 | |||
| 246 | static 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 | |||
| 249 | static 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 | |||
| 252 | static 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 | |||
| 255 | static 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 | |||
| 258 | static 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 | |||
| 261 | static 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 | |||
| 264 | static 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 | |||
| 267 | static 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 | |||
| 270 | static 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 | |||
| 273 | static 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 | |||
| 276 | static 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 | |||
| 279 | static 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 | |||
| 282 | static 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 | |||
| 285 | static 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 | |||
| 288 | static 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 | |||
| 291 | static 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 | |||
| 294 | static 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 | |||
| 297 | static 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 | |||
| 300 | static 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 | |||
| 303 | static 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 | |||
| 306 | static 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 | |||
| 309 | static 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 | |||
| 312 | static 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 | |||
| 315 | static 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 | |||
| 318 | static 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 | |||
| 321 | static 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 | |||
| 324 | static 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 | |||
| 327 | static 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 | |||
| 330 | static 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 | |||
| 333 | static 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 | |||
| 336 | static 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 | |||
| 339 | static 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 | |||
| 342 | static 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 | |||
| 345 | static 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 | |||
| 348 | static 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 | |||
| 351 | static 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 | |||
| 354 | static 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 | |||
| 357 | static 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 | |||
| 360 | static 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 | |||
| 363 | static 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 | |||
| 366 | static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; | ||
| 367 | |||
| 368 | static 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 | |||
| 371 | static struct clk *clks[IMX8MM_CLK_END]; | ||
| 372 | static struct clk_onecell_data clk_data; | ||
| 373 | |||
| 374 | static 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 | |||
| 382 | static 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 | } | ||
| 675 | CLK_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 | ||
| 27 | static struct clk *clks[IMX8MQ_CLK_END]; | 27 | static struct clk *clks[IMX8MQ_CLK_END]; |
| 28 | 28 | ||
| 29 | static const char *pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", }; | 29 | static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", }; |
| 30 | static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; | 30 | static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; |
| 31 | static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; | 31 | static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; |
| 32 | static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; | 32 | static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; |
| 33 | static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; | 33 | static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; |
| 34 | static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; | 34 | static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; |
| 35 | static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; | 35 | static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; |
| 36 | 36 | ||
| 37 | static const char *sys1_pll1_out_sels[] = {"sys1_pll1", "sys1_pll1_ref_sel", }; | 37 | static const char * const sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", }; |
| 38 | static const char *sys2_pll1_out_sels[] = {"sys2_pll1", "sys1_pll1_ref_sel", }; | 38 | static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", }; |
| 39 | static const char *sys3_pll1_out_sels[] = {"sys3_pll1", "sys3_pll1_ref_sel", }; | 39 | static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", }; |
| 40 | static const char *dram_pll1_out_sels[] = {"dram_pll1", "dram_pll1_ref_sel", }; | 40 | static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", }; |
| 41 | |||
| 42 | static const char *sys1_pll2_out_sels[] = {"sys1_pll2_div", "sys1_pll1_ref_sel", }; | ||
| 43 | static const char *sys2_pll2_out_sels[] = {"sys2_pll2_div", "sys2_pll1_ref_sel", }; | ||
| 44 | static const char *sys3_pll2_out_sels[] = {"sys3_pll2_div", "sys2_pll1_ref_sel", }; | ||
| 45 | static const char *dram_pll2_out_sels[] = {"dram_pll2_div", "dram_pll1_ref_sel", }; | ||
| 46 | 41 | ||
| 47 | /* CCM ROOT */ | 42 | /* CCM ROOT */ |
| 48 | static const char *imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", | 43 | static 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 | ||
| 51 | static const char *imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", | 46 | static 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 | |||
| 49 | static 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 | ||
| 54 | static const char *imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out", | 52 | static 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 | ||
| 57 | static const char *imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out", | 55 | static 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 | ||
| 60 | static const char *imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m", | 58 | static 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 | ||
| 63 | static const char *imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m", | 61 | static 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 | ||
| 66 | static const char *imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m", | 64 | static 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 | ||
| 69 | static 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", }; | 67 | static 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 | ||
| 71 | static 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", }; | 69 | static 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 | ||
| 73 | static const char *imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", | 71 | static 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 | ||
| 76 | static const char *imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m", | 74 | static 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 | ||
| 79 | static const char *imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m", | 77 | static 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 | ||
| 82 | static const char *imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m", | 80 | static 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 | ||
| 85 | static const char *imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m", | 83 | static 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 | ||
| 88 | static const char *imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m", | 86 | static 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 | ||
| 91 | static const char *imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m", | 89 | static 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 | ||
| 94 | static const char *imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m", | 92 | static 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 | ||
| 97 | static const char *imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m", | 95 | static 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 | ||
| 100 | static const char *imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", | 98 | static 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 | ||
| 103 | static const char *imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m", | 101 | static 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 | ||
| 106 | static const char *imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", | 104 | static 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 | ||
| 109 | static 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", }; | 107 | static 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 | ||
| 111 | static 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", }; | 109 | static 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 | ||
| 113 | static 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", }; | 111 | static 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 | ||
| 115 | static 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", }; | 113 | static 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 | ||
| 117 | static const char *imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m", | 115 | static 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 | ||
| 120 | static const char *imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2", | 118 | static 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 | ||
| 123 | static const char *imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out", | 121 | static 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 | ||
| 126 | static 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", }; | 124 | static 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 | ||
| 128 | static 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", }; | 126 | static 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 | ||
| 130 | static 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", }; | 128 | static 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 | ||
| 132 | static 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", }; | 130 | static 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 | ||
| 134 | static 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", }; | 132 | static 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 | ||
| 136 | static 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", }; | 134 | static 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 | ||
| 138 | static 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", }; | 136 | static 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 | ||
| 140 | static 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", }; | 138 | static 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 | ||
| 142 | static 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", }; | 140 | static 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 | ||
| 144 | static 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", }; | 142 | static 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 | ||
| 146 | static const char *imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m", | 144 | static 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 | ||
| 149 | static const char *imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", | 147 | static 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 | ||
| 152 | static const char *imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m", | 150 | static 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 | ||
| 155 | static const char *imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m", | 153 | static 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 | ||
| 158 | static const char *imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", | 156 | static 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 | ||
| 161 | static const char *imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", | 159 | static 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 | ||
| 164 | static const char *imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", | 162 | static 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 | ||
| 167 | static const char *imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", | 165 | static 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 | ||
| 170 | static const char *imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", | 168 | static 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 | ||
| 173 | static const char *imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", | 171 | static 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 | ||
| 176 | static const char *imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", | 174 | static 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 | ||
| 179 | static const char *imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", | 177 | static 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 | ||
| 182 | static const char *imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", | 180 | static 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 | ||
| 185 | static const char *imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", | 183 | static 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 | ||
| 188 | static const char *imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", | 186 | static 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 | ||
| 191 | static const char *imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", | 189 | static 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 | ||
| 194 | static const char *imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", | 192 | static 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 | ||
| 197 | static const char *imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", | 195 | static 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 | ||
| 200 | static const char *imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", | 198 | static 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 | ||
| 203 | static const char *imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", | 201 | static 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 | ||
| 206 | static const char *imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", | 204 | static 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 | ||
| 209 | static const char *imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", | 207 | static 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 | ||
| 212 | static const char *imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", | 210 | static 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 | ||
| 215 | static const char *imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m", | 213 | static 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 | ||
| 218 | static const char *imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out", | 216 | static 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 | ||
| 221 | static const char *imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m", | 219 | static 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 | ||
| 224 | static const char *imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", | 222 | static 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 | ||
| 227 | static const char *imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", | 225 | static 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 | ||
| 230 | static const char *imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m", | 228 | static 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 | ||
| 233 | static const char *imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", | 231 | static 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 | ||
| 236 | static const char *imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", | 234 | static 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 | ||
| 239 | static const char *imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", | 237 | static 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 | ||
| 242 | static const char *imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", | 240 | static 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 | ||
| 245 | static const char *imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", | 243 | static 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 | ||
| 248 | static const char *imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", | 246 | static 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 | ||
| 251 | static const char *imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", | 249 | static 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 | ||
| 254 | static const char *imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m", | 252 | static 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 | ||
| 257 | static const char *imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", | 255 | static 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 | ||
| 260 | static const char *imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out", | 258 | static 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 | ||
| 263 | static const char *imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", | 261 | static 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", }; |
| 265 | static const char *imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; | 263 | static const char * const imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; |
| 266 | 264 | ||
| 267 | static const char *imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m", "audio_pll1_out", | 265 | static 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", }; |
| 267 | static 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 | ||
| 270 | static struct clk_onecell_data clk_data; | 270 | static 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 | ||
| 140 | static const struct of_device_id imx8qxp_match[] = { | 140 | static 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 | |||
| 34 | struct 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 | |||
| 44 | static 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 | |||
| 57 | static 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 | |||
| 73 | static 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 | |||
| 92 | static 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 | |||
| 117 | static 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 | |||
| 128 | static 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 | |||
| 141 | static 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 | |||
| 154 | static 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 | |||
| 162 | static 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 | |||
| 224 | static 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 | |||
| 284 | static 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 | |||
| 300 | static 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 | |||
| 310 | static 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 | |||
| 324 | static 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 | |||
| 333 | static const struct clk_ops clk_pll1416x_min_ops = { | ||
| 334 | .recalc_rate = clk_pll1416x_recalc_rate, | ||
| 335 | }; | ||
| 336 | |||
| 337 | static 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 | |||
| 346 | struct 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 | |||
| 69 | struct 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 | ||
| 38 | struct clk_sccg_pll { | 85 | struct 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 | ||
| 45 | static int clk_pll_wait_lock(struct clk_sccg_pll *pll) | 100 | static 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 | ||
| 53 | static int clk_pll1_is_prepared(struct clk_hw *hw) | 114 | static 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 | ||
| 62 | static unsigned long clk_pll1_recalc_rate(struct clk_hw *hw, | 130 | static 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 | |||
| 157 | static 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 | ||
| 74 | static long clk_pll1_round_rate(struct clk_hw *hw, unsigned long rate, | 172 | static 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 | |||
| 192 | static 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 | ||
| 88 | static int clk_pll1_set_rate(struct clk_hw *hw, unsigned long rate, | 208 | static 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 | |||
| 231 | static 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 | |||
| 251 | static 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 | |||
| 268 | static 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 | |||
| 304 | static 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 | ||
| 108 | static int clk_pll1_prepare(struct clk_hw *hw) | 313 | static 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 | ||
| 120 | static void clk_pll1_unprepare(struct clk_hw *hw) | 325 | static 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 | ||
| 131 | static unsigned long clk_pll2_recalc_rate(struct clk_hw *hw, | 335 | static 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 | ||
| 165 | static long clk_pll2_round_rate(struct clk_hw *hw, unsigned long rate, | 366 | static 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 | ||
| 179 | static int clk_pll2_set_rate(struct clk_hw *hw, unsigned long rate, | 392 | static 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 | |||
| 406 | static 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); | 419 | static 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 | ||
| 199 | static const struct clk_ops clk_sccg_pll1_ops = { | 461 | static 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 | ||
| 206 | static const struct clk_ops clk_sccg_pll2_ops = { | 497 | static 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 | ||
| 214 | struct clk *imx_clk_sccg_pll(const char *name, | 508 | struct 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 | |||
| 13 | static struct imx_sc_ipc *ccm_ipc_handle; | 18 | static 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 | */ | ||
| 81 | struct 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 | */ | ||
| 101 | struct 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 | ||
| 188 | static 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 | ||
| 235 | static 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 | |||
| 260 | static 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 | |||
| 176 | static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, | 278 | static 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 | |||
| 339 | static 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 | ||
| 235 | struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type) | 347 | struct 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 | ||
| 12 | int imx_clk_scu_init(void); | 12 | int imx_clk_scu_init(void); |
| 13 | struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type); | 13 | |
| 14 | struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, | ||
| 15 | int num_parents, u32 rsrc_id, u8 clk_type); | ||
| 16 | |||
| 17 | static 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 | |||
| 23 | static 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 | ||
| 15 | struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, | 29 | struct 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 | ||
| 30 | enum imx_pll14xx_type { | ||
| 31 | PLL_1416X, | ||
| 32 | PLL_1443X, | ||
| 33 | }; | ||
| 34 | |||
| 35 | /* NOTE: Rate table should be kept sorted in descending order. */ | ||
| 36 | struct 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 | |||
| 44 | struct 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 | |||
| 51 | struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, | ||
| 52 | void __iomem *base, const struct imx_pll14xx_clk *pll_clk); | ||
| 53 | |||
| 30 | struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, | 54 | struct 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, | |||
| 36 | struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, | 60 | struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, |
| 37 | void __iomem *base); | 61 | void __iomem *base); |
| 38 | 62 | ||
| 39 | struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name, | 63 | struct 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 | ||
| 43 | enum imx_pllv3_type { | 70 | enum 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 | ||
| 331 | static inline struct clk *imx_clk_mux2_flags(const char *name, | 358 | static 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 | ||
| 356 | struct clk *imx8m_clk_composite_flags(const char *name, | 384 | struct 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 | ||
| 150 | static int __init exynos5_clk_probe(struct platform_device *pdev) | 155 | static 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 | |||
| 5476 | static const unsigned long imem_clk_regs[] __initconst = { | ||
| 5477 | ENABLE_ACLK_IMEM_SLIMSSS, | ||
| 5478 | ENABLE_PCLK_IMEM_SLIMSSS, | ||
| 5479 | }; | ||
| 5480 | |||
| 5481 | static 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 | |||
| 5491 | static 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 | ||
| 5471 | struct exynos5433_cmu_data { | 5500 | struct 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 | ||
| 37 | static LIST_HEAD(autoidle_clks); | 37 | static LIST_HEAD(autoidle_clks); |
| 38 | static 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 | */ | ||
| 45 | static DEFINE_SPINLOCK(autoidle_spinlock); | ||
| 46 | |||
| 47 | static 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 | |||
| 62 | static 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 | */ |
| 46 | int omap2_clk_deny_idle(struct clk *clk) | 83 | int 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 | */ |
| 62 | int omap2_clk_allow_idle(struct clk *clk) | 102 | int 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 | ||
| 72 | static void _allow_autoidle(struct clk_ti_autoidle *clk) | 115 | static 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 | */ | ||
| 179 | void 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 | */ |
| 199 | int omap2_clk_enable_autoidle_all(void) | 222 | int 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 | */ |
| 221 | int omap2_clk_disable_autoidle_all(void) | 244 | int 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 | ||
| 34 | static LIST_HEAD(clk_hw_omap_clocks); | ||
| 34 | struct ti_clk_ll_ops *ti_clk_ll_ops; | 35 | struct ti_clk_ll_ops *ti_clk_ll_ops; |
| 35 | static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; | 36 | static 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 | */ | ||
| 537 | struct 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 | */ | ||
| 564 | int 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 | */ | ||
| 585 | bool 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 | ||
| 204 | struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, | 204 | struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, |
| 205 | const char *con); | 205 | const char *con); |
| 206 | struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw, | ||
| 207 | const char *con); | ||
| 206 | int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); | 208 | int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); |
| 207 | void ti_clk_add_aliases(void); | 209 | void 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); |
| 222 | int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type); | 224 | int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type); |
| 223 | 225 | ||
| 224 | void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw); | ||
| 225 | int of_ti_clk_autoidle_setup(struct device_node *node); | 226 | int of_ti_clk_autoidle_setup(struct device_node *node); |
| 226 | void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); | 227 | void 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); |
| 302 | int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, | 303 | int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, |
| 303 | struct clk_rate_request *req); | 304 | struct clk_rate_request *req); |
| 305 | int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw)); | ||
| 306 | bool omap2_clk_is_hw_omap(struct clk_hw *hw); | ||
| 304 | 307 | ||
| 305 | extern struct ti_clk_ll_ops *ti_clk_ll_ops; | 308 | extern 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) |
