summaryrefslogtreecommitdiffstats
path: root/drivers/clk/imx/clk-imx6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/imx/clk-imx6.c')
-rw-r--r--drivers/clk/imx/clk-imx6.c74
1 files changed, 42 insertions, 32 deletions
diff --git a/drivers/clk/imx/clk-imx6.c b/drivers/clk/imx/clk-imx6.c
index ed29e8c271..bac0c73d21 100644
--- a/drivers/clk/imx/clk-imx6.c
+++ b/drivers/clk/imx/clk-imx6.c
@@ -1,13 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2011 Freescale Semiconductor, Inc.
* Copyright 2011 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
*/
#include <common.h>
@@ -18,9 +12,9 @@
#include <of.h>
#include <linux/clkdev.h>
#include <linux/err.h>
-#include <mach/imx6-regs.h>
-#include <mach/revision.h>
-#include <mach/imx6.h>
+#include <mach/imx/imx6-regs.h>
+#include <mach/imx/revision.h>
+#include <mach/imx/imx6.h>
#include <dt-bindings/clock/imx6qdl-clock.h>
#include "clk.h"
@@ -66,8 +60,8 @@ static inline int cpu_mx6_is_plus(void)
/* Audio/Video PLL post dividers don't work on i.MX6q revision 1.0 */
static inline int cpu_has_working_video_pll_post_div(void) {
- return !((cpu_is_mx6q() || cpu_is_mx6d()) &&
- imx_silicon_revision() == IMX_CHIP_REV_1_0);
+ return !((cpu_mx6_is_mx6q() || cpu_mx6_is_mx6d()) &&
+ __imx6_cpu_revision() == IMX_CHIP_REV_1_0);
}
/* i.MX6 Quad/Dual/DualLite/Solo are all affected */
@@ -97,6 +91,13 @@ static const char *periph_pre_sels[] = {
static const char *periph_clk2_sels[] = {
"pll3_usb_otg",
"osc",
+ "osc",
+ "dummy",
+};
+
+static const char *periph2_clk2_sels[] = {
+ "pll3_usb_otg",
+ "pll2_bus",
};
static const char *periph_sels[] = {
@@ -112,6 +113,7 @@ static const char *periph2_sels[] = {
static const char *axi_sels[] = {
"periph",
"pll2_pfd2_396m",
+ "periph",
"pll3_pfd1_540m",
};
@@ -137,6 +139,13 @@ static const char *enfc_sels_plus[] = {
};
static const char *eim_sels[] = {
+ "pll2_pfd2_396m",
+ "pll3_usb_otg",
+ "axi",
+ "pll2_pfd0_352m",
+};
+
+static const char *eim_slow_sels[] = {
"axi",
"pll3_usb_otg",
"pll2_pfd2_396m",
@@ -157,8 +166,8 @@ static const char *cko1_sels[] = {
"pll3_usb_otg",
"pll2_bus",
"pll1_sys",
- "pll5_video",
- "dummy",
+ "pll5_video_div",
+ "video_27m",
"axi",
"enfc",
"ipu1_di0",
@@ -169,7 +178,7 @@ static const char *cko1_sels[] = {
"ipg",
"ipg_per",
"ckil",
- "pll4_audio",
+ "pll4_audio_div",
};
static const char *cko2_sels[] = {
@@ -488,9 +497,9 @@ static void init_ldb_clks(struct device_node *np, void __iomem *ccm_base)
of_assigned_ldb_sels(np, &sel[0][3], &sel[1][3]);
for (i = 0; i < 2; i++) {
- /* Warn if a glitch might have been introduced already */
+ /* log if a glitch might have been introduced already */
if (sel[i][0] != LDB_DI_SEL_MMDC_CH1_AXI) {
- pr_warn("ccm: ldb_di%d_sel already changed from reset value: %d\n",
+ pr_debug("ccm: ldb_di%d_sel already changed from reset value: %d\n",
i, sel[i][0]);
}
@@ -579,10 +588,6 @@ static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb, struct dev
clks[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", cb + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
clks[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", cb + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
- disable_anatop_clocks(anab);
-
- imx6q_mmdc_ch1_mask_handshake(cb);
-
if (cpu_mx6_has_err009219()) {
/*
* The LDB_DI0/1_SEL muxes should be read-only due to a hardware
@@ -618,6 +623,8 @@ static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb, struct dev
clks[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", cb + 0x38, 3, 3);
clks[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", cb + 0x38, 12, 3);
+ clks[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", cb + 0x70, 0);
+ clks[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "mipi_core_cfg", cb + 0x70, 4);
clks[IMX6QDL_CLK_IPU1] = imx_clk_gate2("ipu1", "ipu1_podf", cb + 0x74, 0);
clks[IMX6QDL_CLK_IPU1_DI0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", cb + 0x74, 2);
clks[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", cb + 0x74, 4);
@@ -626,6 +633,8 @@ static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb, struct dev
clks[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", cb + 0x74, 12);
clks[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", cb + 0x74, 14);
clks[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", cb + 0x74, 10);
+ clks[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2("mipi_core_cfg", "video_27m", cb + 0x74, 16);
+ clks[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_SEL], clks[IMX6QDL_CLK_IPU1_DI0_PRE]);
clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_SEL], clks[IMX6QDL_CLK_IPU1_DI1_PRE]);
@@ -638,7 +647,7 @@ static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb, struct dev
clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
}
-static int imx6_ccm_probe(struct device_d *dev)
+static int imx6_ccm_probe(struct device *dev)
{
struct resource *iores;
void __iomem *base, *anatop_base, *ccm_base;
@@ -701,7 +710,7 @@ static int imx6_ccm_probe(struct device_d *dev)
clks[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
clks[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
clks[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
- clks[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
clks[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels));
clks[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
@@ -712,7 +721,7 @@ static int imx6_ccm_probe(struct device_d *dev)
else
clks[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
clks[IMX6QDL_CLK_EIM_SEL] = imx_clk_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels));
- clks[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_sels, ARRAY_SIZE(eim_sels));
+ clks[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_sels, ARRAY_SIZE(eim_slow_sels));
clks[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels));
clks[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
clks[IMX6QDL_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
@@ -794,8 +803,12 @@ static int imx6_ccm_probe(struct device_d *dev)
clkdev_add_physbase(clks[IMX6QDL_CLK_IPG], MX6_OCOTP_BASE_ADDR, NULL);
+ disable_anatop_clocks(anatop_base);
+
+ imx6q_mmdc_ch1_mask_handshake(ccm_base);
+
if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
- imx6_add_video_clks(anatop_base, ccm_base, dev->device_node);
+ imx6_add_video_clks(anatop_base, ccm_base, dev->of_node);
writel(0xffffffff, ccm_base + CCGR0);
writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */
@@ -811,7 +824,7 @@ static int imx6_ccm_probe(struct device_d *dev)
clk_data.clks = clks;
clk_data.clk_num = IMX6QDL_CLK_END;
- of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data);
+ of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &clk_data);
clk_enable(clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF]);
clk_enable(clks[IMX6QDL_CLK_PLL6_ENET]);
@@ -836,15 +849,12 @@ static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, imx6_ccm_dt_ids);
-static struct driver_d imx6_ccm_driver = {
+static struct driver imx6_ccm_driver = {
.probe = imx6_ccm_probe,
.name = "imx6-ccm",
.of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids),
};
-static int imx6_ccm_init(void)
-{
- return platform_driver_register(&imx6_ccm_driver);
-}
-core_initcall(imx6_ccm_init);
+core_platform_driver(imx6_ccm_driver);