* [PATCH v2 15/28] i.MX: Add VF610 clock tree initialization code
From: Andrey Smirnov @ 2016-11-09 16:14 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In-Reply-To: <1478708056-7875-1-git-send-email-andrew.smirnov@gmail.com>
Based on analogous code from Linux kernel
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/clk/imx/Makefile | 3 +-
drivers/clk/imx/clk-vf610.c | 443 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 444 insertions(+), 2 deletions(-)
create mode 100644 drivers/clk/imx/clk-vf610.c
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 06af530..ffaff1c 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -18,5 +18,4 @@ obj-$(CONFIG_ARCH_IMX51) += clk-imx5.o
obj-$(CONFIG_ARCH_IMX53) += clk-imx5.o
obj-$(CONFIG_ARCH_IMX6) += clk-imx6.o
obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
-
-
+obj-$(CONFIG_ARCH_VF610) += clk-vf610.o
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
new file mode 100644
index 0000000..04cb02f
--- /dev/null
+++ b/drivers/clk/imx/clk-vf610.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <io.h>
+#include <of.h>
+#include <of_address.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <dt-bindings/clock/vf610-clock.h>
+
+#include "clk.h"
+
+#define CCM_CCR (ccm_base + 0x00)
+#define CCM_CSR (ccm_base + 0x04)
+#define CCM_CCSR (ccm_base + 0x08)
+#define CCSR_PLL1_PFDn_EN(n) BIT((n) + 7)
+#define CCSR_PLL2_PFDn_EN(n) BIT((n) + 11)
+#define CCSR_PLL3_PFDn_EN(n) BIT((n) + 27)
+#define CCM_CACRR (ccm_base + 0x0c)
+#define CCM_CSCMR1 (ccm_base + 0x10)
+#define CCM_CSCDR1 (ccm_base + 0x14)
+#define CCM_CSCDR2 (ccm_base + 0x18)
+#define CCM_CSCDR3 (ccm_base + 0x1c)
+#define CCM_CSCMR2 (ccm_base + 0x20)
+#define CCM_CSCDR4 (ccm_base + 0x24)
+#define CCM_CLPCR (ccm_base + 0x2c)
+#define CCM_CISR (ccm_base + 0x30)
+#define CCM_CIMR (ccm_base + 0x34)
+#define CCM_CGPR (ccm_base + 0x3c)
+#define CCM_CCGR0 (ccm_base + 0x40)
+#define CCM_CCGR1 (ccm_base + 0x44)
+#define CCM_CCGR2 (ccm_base + 0x48)
+#define CCM_CCGR3 (ccm_base + 0x4c)
+#define CCM_CCGR4 (ccm_base + 0x50)
+#define CCM_CCGR5 (ccm_base + 0x54)
+#define CCM_CCGR6 (ccm_base + 0x58)
+#define CCM_CCGR7 (ccm_base + 0x5c)
+#define CCM_CCGR8 (ccm_base + 0x60)
+#define CCM_CCGR9 (ccm_base + 0x64)
+#define CCM_CCGR10 (ccm_base + 0x68)
+#define CCM_CCGR11 (ccm_base + 0x6c)
+#define CCM_CCGRx(x) (CCM_CCGR0 + (x) * 4)
+#define CCM_CMEOR0 (ccm_base + 0x70)
+#define CCM_CMEOR1 (ccm_base + 0x74)
+#define CCM_CMEOR2 (ccm_base + 0x78)
+#define CCM_CMEOR3 (ccm_base + 0x7c)
+#define CCM_CMEOR4 (ccm_base + 0x80)
+#define CCM_CMEOR5 (ccm_base + 0x84)
+#define CCM_CPPDSR (ccm_base + 0x88)
+#define CCM_CCOWR (ccm_base + 0x8c)
+#define CCM_CCPGR0 (ccm_base + 0x90)
+#define CCM_CCPGR1 (ccm_base + 0x94)
+#define CCM_CCPGR2 (ccm_base + 0x98)
+#define CCM_CCPGR3 (ccm_base + 0x9c)
+
+#define CCM_CCGRx_CGn(n) ((n) * 2)
+
+#define PFD_PLL1_BASE (anatop_base + 0x2b0)
+#define PFD_PLL2_BASE (anatop_base + 0x100)
+#define PFD_PLL3_BASE (anatop_base + 0xf0)
+#define PLL1_CTRL (anatop_base + 0x270)
+#define PLL2_CTRL (anatop_base + 0x30)
+#define PLL3_CTRL (anatop_base + 0x10)
+#define PLL4_CTRL (anatop_base + 0x70)
+#define PLL5_CTRL (anatop_base + 0xe0)
+#define PLL6_CTRL (anatop_base + 0xa0)
+#define PLL7_CTRL (anatop_base + 0x20)
+#define ANA_MISC1 (anatop_base + 0x160)
+
+static void __iomem *anatop_base;
+static void __iomem *ccm_base;
+
+/* sources for multiplexer clocks, this is used multiple times */
+static const char *fast_sels[] = { "firc", "fxosc", };
+static const char *slow_sels[] = { "sirc_32k", "sxosc", };
+static const char *pll1_sels[] = { "pll1_sys", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
+static const char *pll2_sels[] = { "pll2_bus", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
+static const char *pll_bypass_src_sels[] = { "fast_clk_sel", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *sys_sels[] = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_bus", "pll1_pfd_sel", "pll3_usb_otg", };
+static const char *ddr_sels[] = { "pll2_pfd2", "sys_sel", };
+static const char *rmii_sels[] = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
+static const char *enet_ts_sels[] = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
+static const char *esai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
+static const char *sai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", };
+static const char *nfc_sels[] = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
+static const char *qspi_sels[] = { "pll3_usb_otg", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
+static const char *esdhc_sels[] = { "pll3_usb_otg", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
+static const char *dcu_sels[] = { "pll1_pfd2", "pll3_usb_otg", };
+static const char *gpu_sels[] = { "pll2_pfd2", "pll3_pfd2", };
+static const char *vadc_sels[] = { "pll6_video_div", "pll3_usb_otg_div", "pll3_usb_otg", };
+/* FTM counter clock source, not module clock */
+static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
+static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", };
+
+
+static struct clk_div_table pll4_audio_div_table[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 6 },
+ { .val = 3, .div = 8 },
+ { .val = 4, .div = 10 },
+ { .val = 5, .div = 12 },
+ { .val = 6, .div = 14 },
+ { .val = 7, .div = 16 },
+ { }
+};
+
+static struct clk *clk[VF610_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static unsigned int const clks_init_on[] __initconst = {
+ VF610_CLK_SYS_BUS,
+ VF610_CLK_DDR_SEL,
+ VF610_CLK_DAP,
+ VF610_CLK_DDRMC,
+ VF610_CLK_WKPU,
+};
+
+static void __init vf610_clocks_init(struct device_node *ccm_node)
+{
+ u32 ccsr;
+ struct device_node *np;
+ int i;
+
+ clk[VF610_CLK_DUMMY] = clk_fixed("dummy", 0);
+ clk[VF610_CLK_SIRC_128K] = clk_fixed("sirc_128k", 128000);
+ clk[VF610_CLK_SIRC_32K] = clk_fixed("sirc_32k", 32000);
+ clk[VF610_CLK_FIRC] = clk_fixed("firc", 24000000);
+
+ clk[VF610_CLK_SXOSC] = of_clk_get_by_name(ccm_node, "sxosc");
+ clk[VF610_CLK_FXOSC] = of_clk_get_by_name(ccm_node, "fxosc");
+ clk[VF610_CLK_AUDIO_EXT] = of_clk_get_by_name(ccm_node, "audio_ext");
+ clk[VF610_CLK_ENET_EXT] = of_clk_get_by_name(ccm_node, "enet_ext");
+
+ /* Clock source from external clock via LVDs PAD */
+ clk[VF610_CLK_ANACLK1] = of_clk_get_by_name(ccm_node, "anaclk1");
+
+ clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
+ anatop_base = of_iomap(np, 0);
+ BUG_ON(!anatop_base);
+
+ np = ccm_node;
+ ccm_base = of_iomap(np, 0);
+ BUG_ON(!ccm_base);
+
+ ccsr = readl(CCM_CCSR);
+ ccsr |= CCSR_PLL3_PFDn_EN(1) |
+ CCSR_PLL3_PFDn_EN(2) |
+ CCSR_PLL3_PFDn_EN(3) |
+ CCSR_PLL3_PFDn_EN(4) |
+ CCSR_PLL2_PFDn_EN(1) |
+ CCSR_PLL2_PFDn_EN(2) |
+ CCSR_PLL2_PFDn_EN(3) |
+ CCSR_PLL2_PFDn_EN(4) |
+ CCSR_PLL1_PFDn_EN(1) |
+ CCSR_PLL1_PFDn_EN(2) |
+ CCSR_PLL1_PFDn_EN(3) |
+ CCSR_PLL1_PFDn_EN(4);
+ writel(ccsr, CCM_CCSR);
+
+ clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
+ clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
+
+ clk[VF610_CLK_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", PLL1_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", PLL2_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", PLL3_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", PLL4_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", PLL5_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
+ clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
+ clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
+ clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
+ clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
+ clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV, "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f);
+ clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2);
+
+ clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", PLL3_CTRL, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", PLL4_CTRL, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", PLL5_CTRL, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", PLL6_CTRL, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+ clk[VF610_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", PLL7_CTRL, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clk[VF610_PLL1_BYPASS], clk[VF610_CLK_PLL1]);
+ clk_set_parent(clk[VF610_PLL2_BYPASS], clk[VF610_CLK_PLL2]);
+ clk_set_parent(clk[VF610_PLL3_BYPASS], clk[VF610_CLK_PLL3]);
+ clk_set_parent(clk[VF610_PLL4_BYPASS], clk[VF610_CLK_PLL4]);
+ clk_set_parent(clk[VF610_PLL5_BYPASS], clk[VF610_CLK_PLL5]);
+ clk_set_parent(clk[VF610_PLL6_BYPASS], clk[VF610_CLK_PLL6]);
+ clk_set_parent(clk[VF610_PLL7_BYPASS], clk[VF610_CLK_PLL7]);
+
+ clk[VF610_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", PLL1_CTRL, 13);
+ clk[VF610_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", PLL2_CTRL, 13);
+ clk[VF610_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", PLL3_CTRL, 13);
+ clk[VF610_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", PLL4_CTRL, 13);
+ clk[VF610_CLK_PLL5_ENET] = imx_clk_gate("pll5_enet", "pll5_bypass", PLL5_CTRL, 13);
+ clk[VF610_CLK_PLL6_VIDEO] = imx_clk_gate("pll6_video", "pll6_bypass", PLL6_CTRL, 13);
+ clk[VF610_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", PLL7_CTRL, 13);
+
+ clk[VF610_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", ANA_MISC1, 12, BIT(10));
+
+ clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_sys", PFD_PLL1_BASE, 0);
+ clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_sys", PFD_PLL1_BASE, 1);
+ clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_sys", PFD_PLL1_BASE, 2);
+ clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_sys", PFD_PLL1_BASE, 3);
+
+ clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", PFD_PLL2_BASE, 0);
+ clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", PFD_PLL2_BASE, 1);
+ clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_bus", PFD_PLL2_BASE, 2);
+ clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_bus", PFD_PLL2_BASE, 3);
+
+ clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", PFD_PLL3_BASE, 0);
+ clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", PFD_PLL3_BASE, 1);
+ clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", PFD_PLL3_BASE, 2);
+ clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_usb_otg", PFD_PLL3_BASE, 3);
+
+ clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5);
+ clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5);
+ clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels));
+ clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
+ clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3);
+ clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3);
+ clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
+
+ clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_usb_otg_div", "pll3_usb_otg", CCM_CACRR, 20, 1);
+ clk[VF610_CLK_PLL4_MAIN_DIV] = clk_divider_table("pll4_audio_div", "pll4_audio", CCM_CACRR, 6, 3, pll4_audio_div_table, 0);
+ clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
+
+ clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
+ clk[VF610_CLK_WKPU] = imx_clk_gate2_cgr("wkpu", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(10), 0x2);
+
+ clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6);
+ clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6);
+
+ clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(4));
+ clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4);
+ clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4);
+ clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2);
+ clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1);
+ clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1);
+ clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4);
+ clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12);
+ clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2);
+ clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1);
+ clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1);
+ clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_enet", 1, 10);
+ clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_enet", 1, 20);
+ clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4);
+ clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7);
+ clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24);
+ clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
+ clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
+ clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
+
+ clk[VF610_CLK_UART0] = imx_clk_gate2_cgr("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7), 0x2);
+ clk[VF610_CLK_UART1] = imx_clk_gate2_cgr("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8), 0x2);
+ clk[VF610_CLK_UART2] = imx_clk_gate2_cgr("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9), 0x2);
+ clk[VF610_CLK_UART3] = imx_clk_gate2_cgr("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10), 0x2);
+ clk[VF610_CLK_UART4] = imx_clk_gate2_cgr("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9), 0x2);
+ clk[VF610_CLK_UART5] = imx_clk_gate2_cgr("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10), 0x2);
+
+ clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
+ clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
+ clk[VF610_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(6));
+ clk[VF610_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(7));
+
+ clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
+ clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
+ clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
+ clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
+
+ clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
+
+ clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
+ clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28);
+ clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4);
+ clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4);
+ clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29);
+ clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4);
+ clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2));
+
+ /*
+ * ftm_ext_clk and ftm_fix_clk are FTM timer counter's
+ * selectable clock sources, both use a common enable bit
+ * in CCM_CSCDR1, selecting "dummy" clock as parent of
+ * "ftm0_ext_fix" make it serve only for enable/disable.
+ */
+ clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25);
+ clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26);
+ clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27);
+ clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4);
+ clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2);
+ clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28);
+
+ /* ftm(n)_clk are FTM module operation clock */
+ clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9));
+ clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9));
+
+ clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
+ clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
+ clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
+ clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, CCM_CCGRx_CGn(8));
+ clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
+ clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
+ clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
+ clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(8));
+
+ clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", CCM_CCGR1, CCM_CCGRx_CGn(13));
+ clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", CCM_CCGR7, CCM_CCGRx_CGn(13));
+
+ clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
+ clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
+ clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
+ clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2));
+
+ clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
+ clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
+ clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(15));
+
+ clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
+ clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
+ clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(0));
+
+ clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
+ clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
+ clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
+ clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
+ clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
+ clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(2));
+
+ clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
+ clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
+ clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3);
+ clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4);
+ clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0));
+
+ clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2);
+ clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10);
+ clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15));
+
+ clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3);
+ clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22);
+ clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2);
+ clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2);
+ clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7));
+
+ clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11));
+ clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11));
+ clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12));
+ clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13));
+
+ clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
+
+ clk[VF610_CLK_FLEXCAN0_EN] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11);
+ clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0));
+ clk[VF610_CLK_FLEXCAN1_EN] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12);
+ clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4));
+
+ clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
+ clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
+ clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1));
+ clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
+
+ clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
+ clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
+ clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
+
+ imx_check_clocks(clk, ARRAY_SIZE(clk));
+
+ clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
+ clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2);
+
+ clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]);
+ clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2);
+ clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2);
+
+ clk_set_parent(clk[VF610_CLK_ESDHC1_SEL], clk[VF610_CLK_PLL1_PFD3]);
+ clk_set_rate(clk[VF610_CLK_ESDHC1_DIV], clk_get_rate(clk[VF610_CLK_PLL1_PFD3]) / 9);
+
+ clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]);
+ clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]);
+ clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
+ clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_enable(clk[clks_init_on[i]]);
+
+ /* Add the clocks to provider list */
+ clk_data.clks = clk;
+ clk_data.clk_num = ARRAY_SIZE(clk);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH v2 10/28] i.MX: Move clk code from 'mach-imx' to 'drivers'
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In-Reply-To: <1478708056-7875-1-git-send-email-andrew.smirnov@gmail.com>
Move clk code from 'mach-imx' to 'drivers' to keep the code tree
structure closer to that of analogous one from Linux kernel and,
arguably although subjective, to keep 'mach-imx' less cluttered.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/mach-imx/Makefile | 23 +-
arch/arm/mach-imx/clk-gate-exclusive.c | 103 -------
arch/arm/mach-imx/clk-gate2.c | 145 ---------
arch/arm/mach-imx/clk-imx1.c | 121 --------
arch/arm/mach-imx/clk-imx21.c | 196 ------------
arch/arm/mach-imx/clk-imx25.c | 200 ------------
arch/arm/mach-imx/clk-imx27.c | 270 ----------------
arch/arm/mach-imx/clk-imx31.c | 146 ---------
arch/arm/mach-imx/clk-imx35.c | 219 -------------
arch/arm/mach-imx/clk-imx5.c | 533 --------------------------------
arch/arm/mach-imx/clk-imx6.c | 541 ---------------------------------
arch/arm/mach-imx/clk-imx6sx.c | 483 -----------------------------
arch/arm/mach-imx/clk-pfd.c | 148 ---------
arch/arm/mach-imx/clk-pllv1.c | 95 ------
arch/arm/mach-imx/clk-pllv2.c | 230 --------------
arch/arm/mach-imx/clk-pllv3.c | 326 --------------------
arch/arm/mach-imx/clk.h | 104 -------
drivers/clk/Makefile | 1 +
drivers/clk/imx/Makefile | 21 ++
drivers/clk/imx/clk-gate-exclusive.c | 103 +++++++
drivers/clk/imx/clk-gate2.c | 145 +++++++++
drivers/clk/imx/clk-imx1.c | 121 ++++++++
drivers/clk/imx/clk-imx21.c | 196 ++++++++++++
drivers/clk/imx/clk-imx25.c | 200 ++++++++++++
drivers/clk/imx/clk-imx27.c | 270 ++++++++++++++++
drivers/clk/imx/clk-imx31.c | 146 +++++++++
drivers/clk/imx/clk-imx35.c | 219 +++++++++++++
drivers/clk/imx/clk-imx5.c | 533 ++++++++++++++++++++++++++++++++
drivers/clk/imx/clk-imx6.c | 541 +++++++++++++++++++++++++++++++++
drivers/clk/imx/clk-imx6sx.c | 483 +++++++++++++++++++++++++++++
drivers/clk/imx/clk-pfd.c | 148 +++++++++
drivers/clk/imx/clk-pllv1.c | 95 ++++++
drivers/clk/imx/clk-pllv2.c | 230 ++++++++++++++
drivers/clk/imx/clk-pllv3.c | 326 ++++++++++++++++++++
drivers/clk/imx/clk.h | 104 +++++++
35 files changed, 3893 insertions(+), 3872 deletions(-)
delete mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c
delete mode 100644 arch/arm/mach-imx/clk-gate2.c
delete mode 100644 arch/arm/mach-imx/clk-imx1.c
delete mode 100644 arch/arm/mach-imx/clk-imx21.c
delete mode 100644 arch/arm/mach-imx/clk-imx25.c
delete mode 100644 arch/arm/mach-imx/clk-imx27.c
delete mode 100644 arch/arm/mach-imx/clk-imx31.c
delete mode 100644 arch/arm/mach-imx/clk-imx35.c
delete mode 100644 arch/arm/mach-imx/clk-imx5.c
delete mode 100644 arch/arm/mach-imx/clk-imx6.c
delete mode 100644 arch/arm/mach-imx/clk-imx6sx.c
delete mode 100644 arch/arm/mach-imx/clk-pfd.c
delete mode 100644 arch/arm/mach-imx/clk-pllv1.c
delete mode 100644 arch/arm/mach-imx/clk-pllv2.c
delete mode 100644 arch/arm/mach-imx/clk-pllv3.c
delete mode 100644 arch/arm/mach-imx/clk.h
create mode 100644 drivers/clk/imx/Makefile
create mode 100644 drivers/clk/imx/clk-gate-exclusive.c
create mode 100644 drivers/clk/imx/clk-gate2.c
create mode 100644 drivers/clk/imx/clk-imx1.c
create mode 100644 drivers/clk/imx/clk-imx21.c
create mode 100644 drivers/clk/imx/clk-imx25.c
create mode 100644 drivers/clk/imx/clk-imx27.c
create mode 100644 drivers/clk/imx/clk-imx31.c
create mode 100644 drivers/clk/imx/clk-imx35.c
create mode 100644 drivers/clk/imx/clk-imx5.c
create mode 100644 drivers/clk/imx/clk-imx6.c
create mode 100644 drivers/clk/imx/clk-imx6sx.c
create mode 100644 drivers/clk/imx/clk-pfd.c
create mode 100644 drivers/clk/imx/clk-pllv1.c
create mode 100644 drivers/clk/imx/clk-pllv2.c
create mode 100644 drivers/clk/imx/clk-pllv3.c
create mode 100644 drivers/clk/imx/clk.h
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index a216c9b..e426f2c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,25 +1,24 @@
obj-y += clocksource.o
-obj-$(CONFIG_ARCH_IMX1) += imx1.o clk-imx1.o
-obj-$(CONFIG_ARCH_IMX25) += imx25.o clk-imx25.o
-obj-$(CONFIG_ARCH_IMX21) += imx21.o clk-imx21.o
-obj-$(CONFIG_ARCH_IMX27) += imx27.o clk-imx27.o
-obj-$(CONFIG_ARCH_IMX31) += imx31.o clk-imx31.o
-obj-$(CONFIG_ARCH_IMX35) += imx35.o clk-imx35.o
-obj-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o clk-imx5.o
+obj-$(CONFIG_ARCH_IMX1) += imx1.o
+obj-$(CONFIG_ARCH_IMX25) += imx25.o
+obj-$(CONFIG_ARCH_IMX21) += imx21.o
+obj-$(CONFIG_ARCH_IMX27) += imx27.o
+obj-$(CONFIG_ARCH_IMX31) += imx31.o
+obj-$(CONFIG_ARCH_IMX35) += imx35.o
+obj-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o
pbl-$(CONFIG_ARCH_IMX50) += imx50.o imx5.o
-obj-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o clk-imx5.o
+obj-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o
pbl-$(CONFIG_ARCH_IMX51) += imx51.o imx5.o
-obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o clk-imx5.o esdctl-v4.o
+obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
-obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o clk-imx6.o
+obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o
lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
-obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_IMX_OCOTP) += ocotp.o
obj-$(CONFIG_NAND_IMX) += nand.o
lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-pfd.o clk-gate2.o clk-gate-exclusive.o
+
obj-y += devices.o imx.o
obj-pbl-y += esdctl.o boot.o
obj-$(CONFIG_BAREBOX_UPDATE) += imx-bbu-internal.o
diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/arch/arm/mach-imx/clk-gate-exclusive.c
deleted file mode 100644
index db88db0..0000000
--- a/arch/arm/mach-imx/clk-gate-exclusive.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2014 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <common.h>
-#include <io.h>
-#include <malloc.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include "clk.h"
-
-/**
- * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
- * exclusive with other gate clocks
- *
- * @gate: the parent class
- * @exclusive_mask: mask of gate bits which are mutually exclusive to this
- * gate clock
- *
- * The imx exclusive gate clock is a subclass of basic clk_gate
- * with an addtional mask to indicate which other gate bits in the same
- * register is mutually exclusive to this gate clock.
- */
-struct clk_gate_exclusive {
- struct clk clk;
- void __iomem *reg;
- int shift;
- const char *parent;
- u32 exclusive_mask;
-};
-
-static int clk_gate_exclusive_enable(struct clk *clk)
-{
- struct clk_gate_exclusive *exgate = container_of(clk,
- struct clk_gate_exclusive, clk);
- u32 val = readl(exgate->reg);
-
- if (val & exgate->exclusive_mask)
- return -EBUSY;
-
- val |= 1 << exgate->shift;
-
- writel(val, exgate->reg);
-
- return 0;
-}
-
-static void clk_gate_exclusive_disable(struct clk *clk)
-{
- struct clk_gate_exclusive *exgate = container_of(clk,
- struct clk_gate_exclusive, clk);
- u32 val = readl(exgate->reg);
-
- val &= ~(1 << exgate->shift);
-
- writel(val, exgate->reg);
-}
-
-static int clk_gate_exclusive_is_enabled(struct clk *clk)
-{
- struct clk_gate_exclusive *exgate = container_of(clk,
- struct clk_gate_exclusive, clk);
-
- return readl(exgate->reg) & (1 << exgate->shift);
-}
-
-static const struct clk_ops clk_gate_exclusive_ops = {
- .enable = clk_gate_exclusive_enable,
- .disable = clk_gate_exclusive_disable,
- .is_enabled = clk_gate_exclusive_is_enabled,
-};
-
-struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
- void __iomem *reg, u8 shift, u32 exclusive_mask)
-{
- struct clk_gate_exclusive *exgate;
- int ret;
-
- exgate = xzalloc(sizeof(*exgate));
- exgate->parent = parent;
- exgate->clk.name = name;
- exgate->clk.ops = &clk_gate_exclusive_ops;
- exgate->clk.flags = CLK_SET_RATE_PARENT;
- exgate->clk.parent_names = &exgate->parent;
- exgate->clk.num_parents = 1;
-
- exgate->reg = reg;
- exgate->shift = shift;
- exgate->exclusive_mask = exclusive_mask;
-
- ret = clk_register(&exgate->clk);
- if (ret) {
- free(exgate);
- return ERR_PTR(ret);
- }
-
- return &exgate->clk;
-}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
deleted file mode 100644
index faed631..0000000
--- a/arch/arm/mach-imx/clk-gate2.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * clk-gate2.c - barebox 2-bit clock support. Based on Linux clk support
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <common.h>
-#include <io.h>
-#include <malloc.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include "clk.h"
-
-
-struct clk_gate2 {
- struct clk clk;
- void __iomem *reg;
- int shift;
- const char *parent;
-#define CLK_GATE_INVERTED (1 << 0)
- unsigned flags;
-};
-
-#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
-
-static int clk_gate2_enable(struct clk *clk)
-{
- struct clk_gate2 *g = to_clk_gate2(clk);
- u32 val;
-
- val = readl(g->reg);
-
- if (g->flags & CLK_GATE_INVERTED)
- val &= ~(3 << g->shift);
- else
- val |= 3 << g->shift;
-
- writel(val, g->reg);
-
- return 0;
-}
-
-static void clk_gate2_disable(struct clk *clk)
-{
- struct clk_gate2 *g = to_clk_gate2(clk);
- u32 val;
-
- val = readl(g->reg);
-
- if (g->flags & CLK_GATE_INVERTED)
- val |= 3 << g->shift;
- else
- val &= ~(3 << g->shift);
-
- writel(val, g->reg);
-}
-
-static int clk_gate2_is_enabled(struct clk *clk)
-{
- struct clk_gate2 *g = to_clk_gate2(clk);
- u32 val;
-
- val = readl(g->reg);
-
- if (val & (1 << g->shift))
- return g->flags & CLK_GATE_INVERTED ? 0 : 1;
- else
- return g->flags & CLK_GATE_INVERTED ? 1 : 0;
-}
-
-static struct clk_ops clk_gate2_ops = {
- .set_rate = clk_parent_set_rate,
- .round_rate = clk_parent_round_rate,
- .enable = clk_gate2_enable,
- .disable = clk_gate2_disable,
- .is_enabled = clk_gate2_is_enabled,
-};
-
-struct clk *clk_gate2_alloc(const char *name, const char *parent,
- void __iomem *reg, u8 shift)
-{
- struct clk_gate2 *g = xzalloc(sizeof(*g));
-
- g->parent = parent;
- g->reg = reg;
- g->shift = shift;
- g->clk.ops = &clk_gate2_ops;
- g->clk.name = name;
- g->clk.parent_names = &g->parent;
- g->clk.num_parents = 1;
- g->clk.flags = CLK_SET_RATE_PARENT;
-
- return &g->clk;
-}
-
-void clk_gate2_free(struct clk *clk)
-{
- struct clk_gate2 *g = to_clk_gate2(clk);
-
- free(g);
-}
-
-struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
- u8 shift)
-{
- struct clk *g;
- int ret;
-
- g = clk_gate2_alloc(name , parent, reg, shift);
-
- ret = clk_register(g);
- if (ret) {
- free(to_clk_gate2(g));
- return ERR_PTR(ret);
- }
-
- return g;
-}
-
-struct clk *clk_gate2_inverted(const char *name, const char *parent,
- void __iomem *reg, u8 shift)
-{
- struct clk *clk;
- struct clk_gate2 *g;
-
- clk = clk_gate2(name, parent, reg, shift);
- if (IS_ERR(clk))
- return clk;
-
- g = to_clk_gate2(clk);
-
- g->flags = CLK_GATE_INVERTED;
-
- return clk;
-}
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
deleted file mode 100644
index 5f600a9..0000000
--- a/arch/arm/mach-imx/clk-imx1.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx1-regs.h>
-
-#include "clk.h"
-
-#define CCM_CSCR 0x0
-#define CCM_MPCTL0 0x4
-#define CCM_SPCTL0 0xc
-#define CCM_PCDR 0x20
-
-enum imx1_clks {
- dummy, clk32, clk16m, clk32_premult, prem, mpll, spll, mcu,
- fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
- mma_gate, usbd_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *prem_sel_clks[] = {
- "clk32_premult",
- "clk16m",
-};
-
-static const char *clko_sel_clks[] = {
- "per1",
- "hclk",
- "clk48m",
- "clk16m",
- "prem",
- "fclk",
-};
-
-int __init mx1_clocks_init(void __iomem *regs, unsigned long fref)
-{
- clks[dummy] = clk_fixed("dummy", 0);
- clks[clk32] = clk_fixed("clk32", fref);
- clks[clk16m] = clk_fixed("clk16m", 16000000);
- clks[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
- clks[prem] = imx_clk_mux("prem", regs + CCM_CSCR, 16, 1, prem_sel_clks,
- ARRAY_SIZE(prem_sel_clks));
- clks[mpll] = imx_clk_pllv1("mpll", "clk32_premult", regs + CCM_MPCTL0);
- clks[spll] = imx_clk_pllv1("spll", "prem", regs + CCM_SPCTL0);
- clks[mcu] = imx_clk_divider("mcu", "clk32_premult", regs + CCM_CSCR, 15, 1);
- clks[fclk] = imx_clk_divider("fclk", "mpll", regs + CCM_CSCR, 15, 1);
- clks[hclk] = imx_clk_divider("hclk", "spll", regs + CCM_CSCR, 10, 4);
- clks[clk48m] = imx_clk_divider("clk48m", "spll", regs + CCM_CSCR, 26, 3);
- clks[per1] = imx_clk_divider("per1", "spll", regs + CCM_PCDR, 0, 4);
- clks[per2] = imx_clk_divider("per2", "spll", regs + CCM_PCDR, 4, 4);
- clks[per3] = imx_clk_divider("per3", "spll", regs + CCM_PCDR, 16, 7);
- clks[clko] = imx_clk_mux("clko", regs + CCM_CSCR, 29, 3, clko_sel_clks,
- ARRAY_SIZE(clko_sel_clks));
-
- clkdev_add_physbase(clks[per1], MX1_TIM1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX1_TIM2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2], MX1_LCDC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX1_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX1_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2], MX1_CSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2], MX1_CSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[hclk], MX1_I2C_BASE_ADDR, NULL);
-
- return 0;
-}
-
-static int imx1_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *regs;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- regs = IOMEM(iores->start);
-
- mx1_clocks_init(regs, 32000);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx1_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx1-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx1_ccm_driver = {
- .probe = imx1_ccm_probe,
- .name = "imx1-ccm",
- .of_compatible = DRV_OF_COMPAT(imx1_ccm_dt_ids),
-};
-
-static int imx1_ccm_init(void)
-{
- return platform_driver_register(&imx1_ccm_driver);
-}
-core_initcall(imx1_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
deleted file mode 100644
index 546461b..0000000
--- a/arch/arm/mach-imx/clk-imx21.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx21-regs.h>
-
-#include "clk.h"
-
-/* Register offsets */
-#define CCM_CSCR 0x0
-#define CCM_MPCTL0 0x4
-#define CCM_MPCTL1 0x8
-#define CCM_SPCTL0 0xc
-#define CCM_SPCTL1 0x10
-#define CCM_OSC26MCTL 0x14
-#define CCM_PCDR0 0x18
-#define CCM_PCDR1 0x1c
-#define CCM_PCCR0 0x20
-#define CCM_PCCR1 0x24
-#define CCM_CCSR 0x28
-#define CCM_PMCTL 0x2c
-#define CCM_PMCOUNT 0x30
-#define CCM_WKGDCTL 0x34
-
-#define PCCR0_UART1_EN (1 << 0)
-#define PCCR0_UART2_EN (1 << 1)
-#define PCCR0_UART3_EN (1 << 2)
-#define PCCR0_UART4_EN (1 << 3)
-#define PCCR0_CSPI1_EN (1 << 4)
-#define PCCR0_CSPI2_EN (1 << 5)
-#define PCCR0_SSI1_EN (1 << 6)
-#define PCCR0_SSI2_EN (1 << 7)
-#define PCCR0_FIRI_EN (1 << 8)
-#define PCCR0_SDHC1_EN (1 << 9)
-#define PCCR0_SDHC2_EN (1 << 10)
-#define PCCR0_GPIO_EN (1 << 11)
-#define PCCR0_I2C_EN (1 << 12)
-#define PCCR0_DMA_EN (1 << 13)
-#define PCCR0_USBOTG_EN (1 << 14)
-#define PCCR0_EMMA_EN (1 << 15)
-#define PCCR0_SSI2_BAUD_EN (1 << 16)
-#define PCCR0_SSI1_BAUD_EN (1 << 17)
-#define PCCR0_PERCLK3_EN (1 << 18)
-#define PCCR0_NFC_EN (1 << 19)
-#define PCCR0_FRI_BAUD_EN (1 << 20)
-#define PCCR0_SLDC_EN (1 << 21)
-#define PCCR0_PERCLK4_EN (1 << 22)
-#define PCCR0_HCLK_BMI_EN (1 << 23)
-#define PCCR0_HCLK_USBOTG_EN (1 << 24)
-#define PCCR0_HCLK_SLCDC_EN (1 << 25)
-#define PCCR0_HCLK_LCDC_EN (1 << 26)
-#define PCCR0_HCLK_EMMA_EN (1 << 27)
-#define PCCR0_HCLK_BROM_EN (1 << 28)
-#define PCCR0_HCLK_DMA_EN (1 << 30)
-#define PCCR0_HCLK_CSI_EN (1 << 31)
-
-#define PCCR1_CSPI3_EN (1 << 23)
-#define PCCR1_WDT_EN (1 << 24)
-#define PCCR1_GPT1_EN (1 << 25)
-#define PCCR1_GPT2_EN (1 << 26)
-#define PCCR1_GPT3_EN (1 << 27)
-#define PCCR1_PWM_EN (1 << 28)
-#define PCCR1_RTC_EN (1 << 29)
-#define PCCR1_KPP_EN (1 << 30)
-#define PCCR1_OWIRE_EN (1 << 31)
-
-enum imx21_clks {
- ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
- per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, lcdc_ahb_gate,
- lcdc_ipg_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *mpll_sel_clks[] = {
- "fpm",
- "ckih",
-};
-
-static const char *spll_sel_clks[] = {
- "fpm",
- "ckih",
-};
-
-static int imx21_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *base;
- unsigned long lref = 32768;
- unsigned long href = 26000000;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- base = IOMEM(iores->start);
-
- writel(PCCR0_UART1_EN | PCCR0_UART2_EN | PCCR0_UART3_EN | PCCR0_UART4_EN |
- PCCR0_CSPI1_EN | PCCR0_CSPI2_EN | PCCR0_SDHC1_EN |
- PCCR0_SDHC2_EN | PCCR0_GPIO_EN | PCCR0_I2C_EN | PCCR0_DMA_EN |
- PCCR0_USBOTG_EN | PCCR0_NFC_EN | PCCR0_PERCLK4_EN |
- PCCR0_HCLK_USBOTG_EN | PCCR0_HCLK_DMA_EN,
- base + CCM_PCCR0);
-
- writel(PCCR1_CSPI3_EN | PCCR1_WDT_EN | PCCR1_GPT1_EN | PCCR1_GPT2_EN |
- PCCR1_GPT3_EN | PCCR1_PWM_EN | PCCR1_RTC_EN | PCCR1_KPP_EN |
- PCCR1_OWIRE_EN,
- base + CCM_PCCR1);
-
- clks[ckil] = clk_fixed("ckil", lref);
- clks[ckih] = clk_fixed("ckih", href);
- clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
- clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
- ARRAY_SIZE(mpll_sel_clks));
- clks[spll_sel] = imx_clk_mux("spll_sel", base + CCM_CSCR, 17, 1, spll_sel_clks,
- ARRAY_SIZE(spll_sel_clks));
- clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
- clks[spll] = imx_clk_pllv1("spll", "spll_sel", base + CCM_SPCTL0);
- clks[fclk] = imx_clk_divider("fclk", "mpll", base + CCM_CSCR, 29, 3);
- clks[hclk] = imx_clk_divider("hclk", "fclk", base + CCM_CSCR, 10, 4);
- clks[ipg] = imx_clk_divider("ipg", "hclk", base + CCM_CSCR, 9, 1);
- clks[per1] = imx_clk_divider("per1", "mpll", base + CCM_PCDR1, 0, 6);
- clks[per2] = imx_clk_divider("per2", "mpll", base + CCM_PCDR1, 8, 6);
- clks[per3] = imx_clk_divider("per3", "mpll", base + CCM_PCDR1, 16, 6);
- clks[per4] = imx_clk_divider("per4", "mpll", base + CCM_PCDR1, 24, 6);
- clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 26, 3);
- clks[nfc_div] = imx_clk_divider("nfc_div", "ipg", base + CCM_PCDR0, 12, 4);
- clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3", base + CCM_PCCR0, 18);
- clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR0, 26);
- /*
- * i.MX21 doesn't have an IPG clock for the LCD. To avoid even more conditionals
- * in the framebuffer code, provide a dummy clock.
- */
- clks[lcdc_ipg_gate] = clk_fixed("dummy", 0);
-
- clkdev_add_physbase(clks[per1], MX21_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX21_GPT2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX21_GPT3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX21_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX21_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX21_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1], MX21_UART4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2], MX21_CSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2], MX21_CSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2], MX21_CSPI3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX21_I2C_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX21_SDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX21_SDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[lcdc_per_gate], MX21_LCDC_BASE_ADDR, "per");
- clkdev_add_physbase(clks[lcdc_ahb_gate], MX21_LCDC_BASE_ADDR, "ahb");
- clkdev_add_physbase(clks[lcdc_ipg_gate], MX21_LCDC_BASE_ADDR, "ipg");
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx21_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx21-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx21_ccm_driver = {
- .probe = imx21_ccm_probe,
- .name = "imx21-ccm",
- .of_compatible = DRV_OF_COMPAT(imx21_ccm_dt_ids),
-};
-
-static int imx21_ccm_init(void)
-{
- return platform_driver_register(&imx21_ccm_driver);
-}
-core_initcall(imx21_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
deleted file mode 100644
index 864d06e..0000000
--- a/arch/arm/mach-imx/clk-imx25.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2009 by Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx25-regs.h>
-
-#include "clk.h"
-
-#define CCM_MPCTL 0x00
-#define CCM_UPCTL 0x04
-#define CCM_CCTL 0x08
-#define CCM_CGCR0 0x0C
-#define CCM_CGCR1 0x10
-#define CCM_CGCR2 0x14
-#define CCM_PCDR0 0x18
-#define CCM_PCDR1 0x1C
-#define CCM_PCDR2 0x20
-#define CCM_PCDR3 0x24
-#define CCM_RCSR 0x28
-#define CCM_CRDR 0x2C
-#define CCM_DCVR0 0x30
-#define CCM_DCVR1 0x34
-#define CCM_DCVR2 0x38
-#define CCM_DCVR3 0x3c
-#define CCM_LTR0 0x40
-#define CCM_LTR1 0x44
-#define CCM_LTR2 0x48
-#define CCM_LTR3 0x4c
-#define CCM_MCR 0x64
-
-enum mx25_clks {
- dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
- per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
- per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
- per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
- per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
- csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
- gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
- pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
- uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
- esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
- reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg,
- cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
- reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
- gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
- iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
- pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
- sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
- uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
- wdt_ipg, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *cpu_sel_clks[] = {
- "mpll",
- "mpll_cpu_3_4",
-};
-
-static const char *per_sel_clks[] = {
- "ahb",
- "upll",
-};
-
-static int imx25_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *base;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- base = IOMEM(iores->start);
-
- writel((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 8) | (1 << 9) |
- (1 << 10) | (1 << 15) | (1 << 19) | (1 << 21) | (1 << 22) |
- (1 << 23) | (1 << 24) | (1 << 28),
- base + CCM_CGCR0);
-
- writel((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 13) | (1 << 14) |
- (1 << 15) | (1 << 19) | (1 << 20) | (1 << 21) | (1 << 22) |
- (1 << 26) | (1 << 31),
- base + CCM_CGCR1);
-
- writel((1 << 0) | (1 << 1) | (1 << 2) | (1 << 10) | (1 << 13) | (1 << 14) |
- (1 << 15) | (1 << 16) | (1 << 17) | (1 << 18),
- base + CCM_CGCR2);
-
- clks[dummy] = clk_fixed("dummy", 0);
- clks[osc] = clk_fixed("osc", 24000000);
- clks[mpll] = imx_clk_pllv1("mpll", "osc", base + CCM_MPCTL);
- clks[upll] = imx_clk_pllv1("upll", "osc", base + CCM_UPCTL);
- clks[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
- clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CCTL, 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
- clks[cpu] = imx_clk_divider("cpu", "cpu_sel", base + CCM_CCTL, 30, 2);
- clks[ahb] = imx_clk_divider("ahb", "cpu", base + CCM_CCTL, 28, 2);
- clks[usb_div] = imx_clk_divider("usb_div", "upll", base + CCM_CCTL, 16, 6);
- clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
- clks[per0_sel] = imx_clk_mux("per0_sel", base + CCM_MCR, 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per1_sel] = imx_clk_mux("per1_sel", base + CCM_MCR, 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per2_sel] = imx_clk_mux("per2_sel", base + CCM_MCR, 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per3_sel] = imx_clk_mux("per3_sel", base + CCM_MCR, 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per4_sel] = imx_clk_mux("per4_sel", base + CCM_MCR, 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per5_sel] = imx_clk_mux("per5_sel", base + CCM_MCR, 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per6_sel] = imx_clk_mux("per6_sel", base + CCM_MCR, 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per7_sel] = imx_clk_mux("per7_sel", base + CCM_MCR, 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per8_sel] = imx_clk_mux("per8_sel", base + CCM_MCR, 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per9_sel] = imx_clk_mux("per9_sel", base + CCM_MCR, 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per10_sel] = imx_clk_mux("per10_sel", base + CCM_MCR, 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per11_sel] = imx_clk_mux("per11_sel", base + CCM_MCR, 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per12_sel] = imx_clk_mux("per12_sel", base + CCM_MCR, 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per13_sel] = imx_clk_mux("per13_sel", base + CCM_MCR, 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per14_sel] = imx_clk_mux("per14_sel", base + CCM_MCR, 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per15_sel] = imx_clk_mux("per15_sel", base + CCM_MCR, 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
- clks[per0] = imx_clk_divider("per0", "per0_sel", base + CCM_PCDR0, 0, 6);
- clks[per1] = imx_clk_divider("per1", "per1_sel", base + CCM_PCDR0, 8, 6);
- clks[per2] = imx_clk_divider("per2", "per2_sel", base + CCM_PCDR0, 16, 6);
- clks[per3] = imx_clk_divider("per3", "per3_sel", base + CCM_PCDR0, 24, 6);
- clks[per4] = imx_clk_divider("per4", "per4_sel", base + CCM_PCDR1, 0, 6);
- clks[per5] = imx_clk_divider("per5", "per5_sel", base + CCM_PCDR1, 8, 6);
- clks[per6] = imx_clk_divider("per6", "per6_sel", base + CCM_PCDR1, 16, 6);
- clks[per7] = imx_clk_divider("per7", "per7_sel", base + CCM_PCDR1, 24, 6);
- clks[per8] = imx_clk_divider("per8", "per8_sel", base + CCM_PCDR2, 0, 6);
- clks[per9] = imx_clk_divider("per9", "per9_sel", base + CCM_PCDR2, 8, 6);
- clks[per10] = imx_clk_divider("per10", "per10_sel", base + CCM_PCDR2, 16, 6);
- clks[per11] = imx_clk_divider("per11", "per11_sel", base + CCM_PCDR2, 24, 6);
- clks[per12] = imx_clk_divider("per12", "per12_sel", base + CCM_PCDR3, 0, 6);
- clks[per13] = imx_clk_divider("per13", "per13_sel", base + CCM_PCDR3, 8, 6);
- clks[per14] = imx_clk_divider("per14", "per14_sel", base + CCM_PCDR3, 16, 6);
- clks[per15] = imx_clk_divider("per15", "per15_sel", base + CCM_PCDR3, 24, 6);
- clks[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", base + CCM_CGCR0, 24);
- clks[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", base + CCM_CGCR1, 29);
- clks[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", base + CCM_CGCR0, 7);
-
- clkdev_add_physbase(clks[per15], MX25_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per15], MX25_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per15], MX25_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per15], MX25_UART4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per15], MX25_UART5_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per5], MX25_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per5], MX25_GPT2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per5], MX25_GPT3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per5], MX25_GPT4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_FEC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_I2C3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_CSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_CSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX25_CSPI3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per3], MX25_ESDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per4], MX25_ESDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per8], MX25_NFC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[lcdc_ipg_per], MX25_LCDC_BASE_ADDR, "per");
- clkdev_add_physbase(clks[lcdc_ipg], MX25_LCDC_BASE_ADDR, "ipg");
- clkdev_add_physbase(clks[lcdc_ahb], MX25_LCDC_BASE_ADDR, "ahb");
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx25_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx25-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx25_ccm_driver = {
- .probe = imx25_ccm_probe,
- .name = "imx25-ccm",
- .of_compatible = DRV_OF_COMPAT(imx25_ccm_dt_ids),
-};
-
-static int imx25_ccm_init(void)
-{
- return platform_driver_register(&imx25_ccm_driver);
-}
-core_initcall(imx25_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
deleted file mode 100644
index 4b63244..0000000
--- a/arch/arm/mach-imx/clk-imx27.c
+++ /dev/null
@@ -1,270 +0,0 @@
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx27-regs.h>
-#include <mach/generic.h>
-#include <mach/revision.h>
-
-#include "clk.h"
-
-/* Register offsets */
-#define CCM_CSCR 0x0
-#define CCM_MPCTL0 0x4
-#define CCM_MPCTL1 0x8
-#define CCM_SPCTL0 0xc
-#define CCM_SPCTL1 0x10
-#define CCM_OSC26MCTL 0x14
-#define CCM_PCDR0 0x18
-#define CCM_PCDR1 0x1c
-#define CCM_PCCR0 0x20
-#define CCM_PCCR1 0x24
-#define CCM_CCSR 0x28
-#define CCM_PMCTL 0x2c
-#define CCM_PMCOUNT 0x30
-#define CCM_WKGDCTL 0x34
-
-#define PCCR0_SSI2_EN (1 << 0)
-#define PCCR0_SSI1_EN (1 << 1)
-#define PCCR0_SLCDC_EN (1 << 2)
-#define PCCR0_SDHC3_EN (1 << 3)
-#define PCCR0_SDHC2_EN (1 << 4)
-#define PCCR0_SDHC1_EN (1 << 5)
-#define PCCR0_SDC_EN (1 << 6)
-#define PCCR0_SAHARA_EN (1 << 7)
-#define PCCR0_RTIC_EN (1 << 8)
-#define PCCR0_RTC_EN (1 << 9)
-#define PCCR0_PWM_EN (1 << 11)
-#define PCCR0_OWIRE_EN (1 << 12)
-#define PCCR0_MSHC_EN (1 << 13)
-#define PCCR0_LCDC_EN (1 << 14)
-#define PCCR0_KPP_EN (1 << 15)
-#define PCCR0_IIM_EN (1 << 16)
-#define PCCR0_I2C2_EN (1 << 17)
-#define PCCR0_I2C1_EN (1 << 18)
-#define PCCR0_GPT6_EN (1 << 19)
-#define PCCR0_GPT5_EN (1 << 20)
-#define PCCR0_GPT4_EN (1 << 21)
-#define PCCR0_GPT3_EN (1 << 22)
-#define PCCR0_GPT2_EN (1 << 23)
-#define PCCR0_GPT1_EN (1 << 24)
-#define PCCR0_GPIO_EN (1 << 25)
-#define PCCR0_FEC_EN (1 << 26)
-#define PCCR0_EMMA_EN (1 << 27)
-#define PCCR0_DMA_EN (1 << 28)
-#define PCCR0_CSPI3_EN (1 << 29)
-#define PCCR0_CSPI2_EN (1 << 30)
-#define PCCR0_CSPI1_EN (1 << 31)
-
-#define PCCR1_MSHC_BAUDEN (1 << 2)
-#define PCCR1_NFC_BAUDEN (1 << 3)
-#define PCCR1_SSI2_BAUDEN (1 << 4)
-#define PCCR1_SSI1_BAUDEN (1 << 5)
-#define PCCR1_H264_BAUDEN (1 << 6)
-#define PCCR1_PERCLK4_EN (1 << 7)
-#define PCCR1_PERCLK3_EN (1 << 8)
-#define PCCR1_PERCLK2_EN (1 << 9)
-#define PCCR1_PERCLK1_EN (1 << 10)
-#define PCCR1_HCLK_USB (1 << 11)
-#define PCCR1_HCLK_SLCDC (1 << 12)
-#define PCCR1_HCLK_SAHARA (1 << 13)
-#define PCCR1_HCLK_RTIC (1 << 14)
-#define PCCR1_HCLK_LCDC (1 << 15)
-#define PCCR1_HCLK_H264 (1 << 16)
-#define PCCR1_HCLK_FEC (1 << 17)
-#define PCCR1_HCLK_EMMA (1 << 18)
-#define PCCR1_HCLK_EMI (1 << 19)
-#define PCCR1_HCLK_DMA (1 << 20)
-#define PCCR1_HCLK_CSI (1 << 21)
-#define PCCR1_HCLK_BROM (1 << 22)
-#define PCCR1_HCLK_ATA (1 << 23)
-#define PCCR1_WDT_EN (1 << 24)
-#define PCCR1_USB_EN (1 << 25)
-#define PCCR1_UART6_EN (1 << 26)
-#define PCCR1_UART5_EN (1 << 27)
-#define PCCR1_UART4_EN (1 << 28)
-#define PCCR1_UART3_EN (1 << 29)
-#define PCCR1_UART2_EN (1 << 30)
-#define PCCR1_UART1_EN (1 << 31)
-
-enum mx27_clks {
- dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
- per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
- clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
- clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
- sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
- rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
- kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
- gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
- gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
- emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
- cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
- vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
- usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
- vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
- csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
- uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
- uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
- mpll_sel, spll_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *cpu_sel_clks[] = {
- "mpll_main2",
- "mpll",
-};
-
-static const char *mpll_sel_clks[] = {
- "fpm",
- "mpll_osc_sel",
-};
-
-static const char *mpll_osc_sel_clks[] = {
- "ckih",
- "ckih_div1p5",
-};
-
-static const char *clko_sel_clks[] = {
- "ckil",
- NULL,
- "ckih",
- "ckih",
- "ckih",
- "mpll",
- "spll",
- "cpu_div",
- "ahb",
- "ipg",
- "per1_div",
- "per2_div",
- "per3_div",
- "per4_div",
- NULL,
- NULL,
- "nfc_div",
- NULL,
- NULL,
- NULL,
- "ckil",
- "usb_div",
- NULL,
-};
-
-static int imx27_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *base;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- base = IOMEM(iores->start);
-
- writel(PCCR0_SDHC3_EN | PCCR0_SDHC2_EN | PCCR0_SDHC1_EN |
- PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_IIM_EN |
- PCCR0_I2C2_EN | PCCR0_I2C1_EN | PCCR0_GPT6_EN | PCCR0_GPT5_EN |
- PCCR0_GPT4_EN | PCCR0_GPT3_EN | PCCR0_GPT2_EN | PCCR0_GPT1_EN |
- PCCR0_GPIO_EN | PCCR0_FEC_EN | PCCR0_CSPI3_EN | PCCR0_CSPI2_EN |
- PCCR0_CSPI1_EN,
- base + CCM_PCCR0);
-
- writel(PCCR1_NFC_BAUDEN | PCCR1_PERCLK4_EN | PCCR1_PERCLK2_EN | PCCR1_PERCLK1_EN |
- PCCR1_HCLK_USB | PCCR1_HCLK_FEC | PCCR1_HCLK_EMI | PCCR1_WDT_EN |
- PCCR1_USB_EN | PCCR1_UART6_EN | PCCR1_UART5_EN | PCCR1_UART4_EN |
- PCCR1_UART3_EN | PCCR1_UART2_EN | PCCR1_UART1_EN,
- base + CCM_PCCR1);
-
- clks[dummy] = clk_fixed("dummy", 0);
- clks[ckih] = clk_fixed("ckih", 26000000);
- clks[ckil] = clk_fixed("ckil", 32768);
- clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
- clks[ckih_div1p5] = imx_clk_fixed_factor("ckih_div1p5", "ckih", 2, 3);
-
- clks[mpll_osc_sel] = imx_clk_mux("mpll_osc_sel", base + CCM_CSCR, 4, 1,
- mpll_osc_sel_clks,
- ARRAY_SIZE(mpll_osc_sel_clks));
- clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
- ARRAY_SIZE(mpll_sel_clks));
-
- clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
- clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SPCTL0);
- clks[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
-
- if (imx_silicon_revision() >= IMX_CHIP_REV_2_0) {
- clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 8, 2);
- clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
- } else {
- clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 9, 4);
- clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_CSCR, 8, 1);
- }
-
- clks[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + CCM_PCDR0, 6, 4);
- clks[per1_div] = imx_clk_divider("per1_div", "mpll_main2", base + CCM_PCDR1, 0, 6);
- clks[per2_div] = imx_clk_divider("per2_div", "mpll_main2", base + CCM_PCDR1, 8, 6);
- clks[per3_div] = imx_clk_divider("per3_div", "mpll_main2", base + CCM_PCDR1, 16, 6);
- clks[per4_div] = imx_clk_divider("per4_div", "mpll_main2", base + CCM_PCDR1, 24, 6);
- clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 28, 3);
- clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CSCR, 15, 1, cpu_sel_clks,
- ARRAY_SIZE(cpu_sel_clks));
- clks[clko_sel] = imx_clk_mux("clko_sel", base + CCM_CCSR, 0, 5, clko_sel_clks,
- ARRAY_SIZE(clko_sel_clks));
- if (imx_silicon_revision() >= IMX_CHIP_REV_2_0)
- clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 12, 2);
- else
- clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 13, 3);
- clks[clko_div] = imx_clk_divider("clko_div", "clko_sel", base + CCM_PCDR0, 22, 3);
- clks[per3_gate] = imx_clk_gate("per3_gate", "per3_div", base + CCM_PCCR1, 8);
- clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR1, 15);
- clks[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", base + CCM_PCCR0, 14);
-
- clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_GPT3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_GPT4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_GPT5_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_GPT6_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_UART4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_UART5_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per1_div], MX27_UART6_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX27_CSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX27_CSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX27_CSPI3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX27_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX27_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2_div], MX27_SDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2_div], MX27_SDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per2_div], MX27_SDHC3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per3_gate], MX27_LCDC_BASE_ADDR, "per");
- clkdev_add_physbase(clks[lcdc_ahb_gate], MX27_LCDC_BASE_ADDR, "ahb");
- clkdev_add_physbase(clks[lcdc_ipg_gate], MX27_LCDC_BASE_ADDR, "ipg");
- clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx27_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx27-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx27_ccm_driver = {
- .probe = imx27_ccm_probe,
- .name = "imx27-ccm",
- .of_compatible = DRV_OF_COMPAT(imx27_ccm_dt_ids),
-};
-
-static int imx27_ccm_init(void)
-{
- return platform_driver_register(&imx27_ccm_driver);
-}
-core_initcall(imx27_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
deleted file mode 100644
index 8d135c9..0000000
--- a/arch/arm/mach-imx/clk-imx31.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation.
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx31-regs.h>
-
-#include "clk.h"
-
-/* Register addresses */
-#define CCM_CCMR 0x00
-#define CCM_PDR0 0x04
-#define CCM_PDR1 0x08
-//#define CCM_RCSR 0x0C
-#define CCM_MPCTL 0x10
-#define CCM_UPCTL 0x14
-#define CCM_SRPCTL 0x18
-#define CCM_COSR 0x1C
-#define CCM_CGR0 0x20
-#define CCM_CGR1 0x24
-#define CCM_CGR2 0x28
-#define CCM_WIMR 0x2C
-#define CCM_LDC 0x30
-#define CCM_DCVR0 0x34
-#define CCM_DCVR1 0x38
-#define CCM_DCVR2 0x3C
-#define CCM_DCVR3 0x40
-#define CCM_LTR0 0x44
-#define CCM_LTR1 0x48
-#define CCM_LTR2 0x4C
-#define CCM_LTR3 0x50
-#define CCM_LTBR0 0x54
-#define CCM_LTBR1 0x58
-#define CCM_PMCR0 0x5C
-#define CCM_PMCR1 0x60
-#define CCM_PDR2 0x64
-
-enum mx31_clks {
- ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
- per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
- fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
- iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
- uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
- mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
- sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
- uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
- gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *mcu_main_sel[] = {
- "spll",
- "mpll",
-};
-
-static const char *per_sel[] = {
- "per_div",
- "ipg",
-};
-
-static int imx31_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *base;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- base = IOMEM(iores->start);
-
- writel(0xffffffff, base + CCM_CGR0);
- writel(0xffffffff, base + CCM_CGR1);
- writel(0xffffffff, base + CCM_CGR2);
-
- clks[ckih] = clk_fixed("ckih", 26000000);
- clks[ckil] = clk_fixed("ckil", 32768);
- clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
- clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SRPCTL);
- clks[upll] = imx_clk_pllv1("upll", "ckih", base + CCM_UPCTL);
- clks[mcu_main] = imx_clk_mux("mcu_main", base + CCM_PMCR0, 31, 1,
- mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
- clks[hsp] = imx_clk_divider("hsp", "mcu_main", base + CCM_PDR0, 11, 3);
- clks[ahb] = imx_clk_divider("ahb", "mcu_main", base + CCM_PDR0, 3, 3);
- clks[nfc] = imx_clk_divider("nfc", "ahb", base + CCM_PDR0, 8, 3);
- clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_PDR0, 6, 2);
- clks[per_div] = imx_clk_divider("per_div", "upll", base + CCM_PDR0, 16, 5);
- clks[per] = imx_clk_mux("per", base + CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
-
- clkdev_add_physbase(clks[per], MX31_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_UART4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_UART5_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_I2C3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX31_CSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX31_CSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX31_CSPI3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_SDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_SDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[per], MX31_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[hsp], MX31_IPU_CTRL_BASE_ADDR, NULL);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx31-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx31_ccm_driver = {
- .probe = imx31_ccm_probe,
- .name = "imx31-ccm",
- .of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids),
-};
-
-static int imx31_ccm_init(void)
-{
- return platform_driver_register(&imx31_ccm_driver);
-}
-core_initcall(imx31_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
deleted file mode 100644
index af6c405..0000000
--- a/arch/arm/mach-imx/clk-imx35.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx35-regs.h>
-#include <reset_source.h>
-
-#include "clk.h"
-
-#define CCM_CCMR 0x00
-#define CCM_PDR0 0x04
-#define CCM_PDR1 0x08
-#define CCM_PDR2 0x0C
-#define CCM_PDR3 0x10
-#define CCM_PDR4 0x14
-#define CCM_RCSR 0x18
-#define CCM_MPCTL 0x1C
-#define CCM_PPCTL 0x20
-#define CCM_ACMR 0x24
-#define CCM_COSR 0x28
-#define CCM_CGR0 0x2C
-#define CCM_CGR1 0x30
-#define CCM_CGR2 0x34
-#define CCM_CGR3 0x38
-
-struct arm_ahb_div {
- unsigned char arm, ahb, sel;
-};
-
-static struct arm_ahb_div clk_consumer[] = {
- { .arm = 1, .ahb = 4, .sel = 0},
- { .arm = 1, .ahb = 3, .sel = 1},
- { .arm = 2, .ahb = 2, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 4, .ahb = 1, .sel = 0},
- { .arm = 1, .ahb = 5, .sel = 0},
- { .arm = 1, .ahb = 8, .sel = 0},
- { .arm = 1, .ahb = 6, .sel = 1},
- { .arm = 2, .ahb = 4, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 4, .ahb = 2, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
-};
-
-static char hsp_div_532[] = { 4, 8, 3, 0 };
-static char hsp_div_400[] = { 3, 6, 3, 0 };
-
-enum mx35_clks {
- ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
- arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
- esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
- spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
- ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
- audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
- edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
- esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
- gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
- kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
- rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
- ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
- wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
- clk_max
-};
-
-static struct clk *clks[clk_max];
-
-static const char *std_sel[] = {
- "ppll",
- "arm",
-};
-
-static const char *ipg_per_sel[] = {
- "ahb_per_div",
- "arm_per_div",
-};
-
-static int imx35_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- u32 pdr0, consumer_sel, hsp_sel;
- struct arm_ahb_div *aad;
- unsigned char *hsp_div;
- void __iomem *base;
- u32 reg;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- base = IOMEM(iores->start);
-
- /* Check reset source */
- reg = readl(base + CCM_RCSR);
-
- switch (reg & 0x0F) {
- case 0x00:
- reset_source_set_priority(RESET_POR, 200);
- break;
- case 0x02:
- reset_source_set_priority(RESET_JTAG, 200);
- break;
- case 0x04:
- reset_source_set_priority(RESET_RST, 200);
- break;
- case 0x08:
- reset_source_set_priority(RESET_WDG, 200);
- break;
- }
-
- writel(0xffffffff, base + CCM_CGR0);
- writel(0xffffffff, base + CCM_CGR1);
- writel(0xfbffffff, base + CCM_CGR2);
- writel(0xffffffff, base + CCM_CGR3);
-
- pdr0 = __raw_readl(base + CCM_PDR0);
- consumer_sel = (pdr0 >> 16) & 0xf;
- aad = &clk_consumer[consumer_sel];
- if (!aad->arm) {
- pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
- /*
- * We are basically stuck. Continue with a default entry and hope we
- * get far enough to actually show the above message
- */
- aad = &clk_consumer[0];
- }
-
- clks[ckih] = clk_fixed("ckih", 24000000);
- clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
- clks[ppll] = imx_clk_pllv1("ppll", "ckih", base + CCM_PPCTL);
-
- clks[mpll_075] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
-
- if (aad->sel)
- clks[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
- else
- clks[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
-
- if (clk_get_rate(clks[arm]) > 400000000)
- hsp_div = hsp_div_532;
- else
- hsp_div = hsp_div_400;
-
- hsp_sel = (pdr0 >> 20) & 0x3;
- if (!hsp_div[hsp_sel]) {
- pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
- hsp_sel = 0;
- }
-
- clks[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
-
- clks[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
- clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
-
- clks[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + CCM_PDR4, 16, 6);
- clks[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + CCM_PDR0, 12, 3);
- clks[ipg_per] = imx_clk_mux("ipg_per", base + CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
-
- clks[uart_sel] = imx_clk_mux("uart_sel", base + CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
- clks[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + CCM_PDR4, 10, 6);
-
- clks[esdhc_sel] = imx_clk_mux("esdhc_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
- clks[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + CCM_PDR3, 0, 6);
- clks[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + CCM_PDR3, 8, 6);
- clks[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + CCM_PDR3, 16, 6);
-
- clks[usb_sel] = imx_clk_mux("usb_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
- clks[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + CCM_PDR4, 22, 6);
-
- clkdev_add_physbase(clks[uart_div], MX35_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[uart_div], MX35_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[uart_div], MX35_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg_per], MX35_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg_per], MX35_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg_per], MX35_I2C3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX35_CSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX35_CSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX35_FEC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[ipg], MX35_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[esdhc1_div], MX35_ESDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[esdhc2_div], MX35_ESDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[esdhc3_div], MX35_ESDHC3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[hsp], MX35_IPU_CTRL_BASE_ADDR, NULL);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx35_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx35-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx35_ccm_driver = {
- .probe = imx35_ccm_probe,
- .name = "imx35-ccm",
- .of_compatible = DRV_OF_COMPAT(imx35_ccm_dt_ids),
-};
-
-static int imx35_ccm_init(void)
-{
- return platform_driver_register(&imx35_ccm_driver);
-}
-core_initcall(imx35_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx5.c b/arch/arm/mach-imx/clk-imx5.c
deleted file mode 100644
index c4c47a6..0000000
--- a/arch/arm/mach-imx/clk-imx5.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <of.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <mach/imx50-regs.h>
-#include <mach/imx51-regs.h>
-#include <mach/imx53-regs.h>
-#include <dt-bindings/clock/imx5-clock.h>
-
-#include "clk.h"
-
-/* Register addresses of CCM*/
-#define CCM_CCR 0x00
-#define CCM_CCDR 0x04
-#define CCM_CSR 0x08
-#define CCM_CCSR 0x0C
-#define CCM_CACRR 0x10
-#define CCM_CBCDR 0x14
-#define CCM_CBCMR 0x18
-#define CCM_CSCMR1 0x1C
-#define CCM_CSCMR2 0x20
-#define CCM_CSCDR1 0x24
-#define CCM_CS1CDR 0x28
-#define CCM_CS2CDR 0x2C
-#define CCM_CDCDR 0x30
-#define CCM_CHSCDR 0x34
-#define CCM_CSCDR2 0x38
-#define CCM_CSCDR3 0x3C
-#define CCM_CSCDR4 0x40
-#define CCM_CWDR 0x44
-#define CCM_CDHIPR 0x48
-#define CCM_CDCR 0x4C
-#define CCM_CTOR 0x50
-#define CCM_CLPCR 0x54
-#define CCM_CISR 0x58
-#define CCM_CIMR 0x5C
-#define CCM_CCOSR 0x60
-#define CCM_CGPR 0x64
-#define CCM_CCGR0 0x68
-#define CCM_CCGR1 0x6C
-#define CCM_CCGR2 0x70
-#define CCM_CCGR3 0x74
-#define CCM_CCGR4 0x78
-#define CCM_CCGR5 0x7C
-#define CCM_CCGR6 0x80
-#define CCM_CCGR7 0x84
-
-#define CCM_CMEOR 0x84
-
-static struct clk *clks[IMX5_CLK_END];
-
-/* This is used multiple times */
-static const char *standard_pll_sel[] = {
- "pll1_sw",
- "pll2_sw",
- "pll3_sw",
- "lp_apm",
-};
-
-static const char *mx50_3bit_clk_sel[] = {
- "pll1_sw",
- "pll2_sw",
- "pll3_sw",
- "lp_apm",
- "pfd0",
- "pfd1",
- "pfd4",
- "osc",
-};
-
-static const char *lp_apm_sel[] = {
- "osc",
-};
-
-static const char *periph_apm_sel[] = {
- "pll1_sw",
- "pll3_sw",
- "lp_apm",
-};
-
-static const char *main_bus_sel[] = {
- "pll2_sw",
- "periph_apm",
-};
-
-static const char *mx50_periph_clk_sel[] = {
- "pll1_sw",
- "pll2_sw",
- "pll3_sw",
- "lp_apm",
-};
-
-static const char *per_lp_apm_sel[] = {
- "main_bus",
- "lp_apm",
-};
-
-static const char *per_root_sel[] = {
- "per_podf",
- "ipg",
-};
-
-static const char *esdhc_c_sel[] = {
- "esdhc_a_podf",
- "esdhc_b_podf",
-};
-
-static const char *esdhc_d_sel[] = {
- "esdhc_a_podf",
- "esdhc_b_podf",
-};
-
-static const char *emi_slow_sel[] = {
- "main_bus",
- "ahb",
-};
-
-static const char *usb_phy_sel_str[] = {
- "osc",
- "usb_phy_podf",
-};
-
-static const char *mx51_ipu_di0_sel[] = {
- "di_pred",
- "osc",
- "ckih1",
- "tve_di",
-};
-
-static const char *mx53_ipu_di0_sel[] = {
- "di_pred",
- "osc",
- "ckih1",
- "di_pll4_podf",
- "dummy",
- "ldb_di0_div",
-};
-
-static const char *mx53_ldb_di0_sel[] = {
- "pll3_sw",
- "pll4_sw",
-};
-
-static const char *mx51_ipu_di1_sel[] = {
- "di_pred",
- "osc",
- "ckih1",
- "tve_di",
- "ipp_di1",
-};
-
-static const char *mx53_ipu_di1_sel[] = {
- "di_pred",
- "osc",
- "ckih1",
- "tve_di",
- "ipp_di1",
- "ldb_di1_div",
-};
-
-static const char *mx53_ldb_di1_sel[] = {
- "pll3_sw",
- "pll4_sw",
-};
-
-static const char *mx51_tve_ext_sel[] = {
- "osc",
- "ckih1",
-};
-
-static const char *mx53_tve_ext_sel[] = {
- "pll4_sw",
- "ckih1",
-};
-
-static const char *mx51_tve_sel[] = {
- "tve_pred",
- "tve_ext_sel",
-};
-
-static const char *ipu_sel[] = {
- "axi_a",
- "axi_b",
- "emi_slow_gate",
- "ahb",
-};
-
-static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *base)
-{
- writel(0xffffffff, base + CCM_CCGR0);
- writel(0xffffffff, base + CCM_CCGR1);
- writel(0xffffffff, base + CCM_CCGR2);
- writel(0xffffffff, base + CCM_CCGR3);
- writel(0xffffffff, base + CCM_CCGR4);
- writel(0xffffffff, base + CCM_CCGR5);
- writel(0xffffffff, base + CCM_CCGR6);
- writel(0xffffffff, base + CCM_CCGR7);
-
- if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
- clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768);
- clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000);
- }
-
- clks[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", base + CCM_CBCMR, 1, 1,
- per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
- clks[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", base + CCM_CBCDR, 6, 2);
- clks[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", base + CCM_CBCDR, 3, 3);
- clks[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", base + CCM_CBCDR, 0, 3);
- clks[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", base + CCM_CBCMR, 0, 1,
- per_root_sel, ARRAY_SIZE(per_root_sel));
- clks[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", base + CCM_CBCDR, 10, 3);
- clks[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + CCM_CBCDR, 8, 2);
- clks[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", base + CCM_CBCDR, 16, 3);
- clks[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", base + CCM_CBCDR, 19, 3);
- clks[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + CCM_CSCMR1, 24, 2,
- standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
- clks[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", base + CCM_CSCDR1, 3, 3);
- clks[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", base + CCM_CSCDR1, 0, 3);
- clks[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred",
- "esdhc_a_sel", base + CCM_CSCDR1, 16, 3);
- clks[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf",
- "esdhc_a_pred", base + CCM_CSCDR1, 11, 3);
- clks[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred",
- "esdhc_b_sel", base + CCM_CSCDR1, 22, 3);
- clks[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf",
- "esdhc_b_pred", base + CCM_CSCDR1, 19, 3);
- clks[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + CCM_CSCMR1,
- 4, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
- clks[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred",
- "ecspi_sel", base + CCM_CSCDR2, 25, 3);
- clks[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf",
- "ecspi_pred", base + CCM_CSCDR2, 19, 6);
- clks[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf",
- "pll1_sw", base + CCM_CACRR, 0, 3);
-}
-
-static void mx5_clocks_mx51_mx53_init(void __iomem *base)
-{
- clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", base + CCM_CCSR, 9, 1,
- lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
- clks[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", base + CCM_CBCMR, 12, 2,
- periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
- clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", base + CCM_CBCDR, 25, 1,
- main_bus_sel, ARRAY_SIZE(main_bus_sel));
- clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", base + CCM_CSCMR1, 20, 2,
- standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
- clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", base + CCM_CSCMR1, 16, 2,
- standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
- clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", base + CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
- clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", base + CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
- clks[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", base + CCM_CBCDR, 26, 1,
- emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
- clks[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", base + CCM_CBCDR, 22, 3);
- clks[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", base + CCM_CBCDR, 13, 3);
- clks[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", base + CCM_CSCMR1, 22, 2,
- standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
- clks[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", base + CCM_CSCDR1, 8, 3);
- clks[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", base + CCM_CSCDR1, 6, 2);
- clks[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", base + CCM_CDCDR, 3, 3);
- clks[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", base + CCM_CDCDR, 0, 3);
- clks[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", base + CCM_CSCMR1, 26, 1,
- usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
-}
-
-static void mx5_clocks_ipu_init(void __iomem *regs)
-{
- clks[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", regs + CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
-}
-
-int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs)
-{
- clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc",
- (void *)MX50_PLL1_BASE_ADDR);
- clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc",
- (void *)MX50_PLL2_BASE_ADDR);
- clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc",
- (void *)MX50_PLL3_BASE_ADDR);
-
- mx5_clocks_common_init(dev, regs);
-
- clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", regs + CCM_CCSR, 10, 1, lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
- clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", regs + CCM_CBCDR, 25, 2, mx50_periph_clk_sel, ARRAY_SIZE(mx50_periph_clk_sel));
- clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", regs + CCM_CSCMR1, 21, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
- clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", regs + CCM_CSCMR1, 16, 3, mx50_3bit_clk_sel, ARRAY_SIZE(mx50_3bit_clk_sel));
- clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", regs + CCM_CSCMR1, 20, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
- clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", regs + CCM_CSCMR1, 19, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_CSPI_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_FEC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX50_ESDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX50_ESDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX50_ESDHC3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX50_ESDHC4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per");
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per");
-
- return 0;
-}
-
-static int imx50_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *regs;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- regs = IOMEM(iores->start);
-
- mx50_clocks_init(dev, regs);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx50_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx50-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx50_ccm_driver = {
- .probe = imx50_ccm_probe,
- .name = "imx50-ccm",
- .of_compatible = DRV_OF_COMPAT(imx50_ccm_dt_ids),
-};
-
-static void mx51_clocks_ipu_init(void __iomem *regs)
-{
- clks[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
- mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
- clks[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
- mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
- clks[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
- mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
- clks[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", regs + CCM_CSCMR1, 7, 1,
- mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
- clks[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", regs + CCM_CDCDR, 28, 3);
-
- mx5_clocks_ipu_init(regs);
-
- clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX51_IPU_BASE_ADDR, "bus");
- clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX51_IPU_BASE_ADDR, "di0");
- clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX51_IPU_BASE_ADDR, "di1");
-}
-
-int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs)
-{
- clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX51_PLL1_BASE_ADDR);
- clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX51_PLL2_BASE_ADDR);
- clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX51_PLL3_BASE_ADDR);
-
- mx5_clocks_common_init(dev, regs);
- mx5_clocks_mx51_mx53_init(regs);
-
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_CSPI_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_MXC_FEC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX51_MMC_SDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX51_MMC_SDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX51_MMC_SDHC3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX51_MMC_SDHC4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_ATA_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM1_BASE_ADDR, "per");
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM2_BASE_ADDR, "per");
-
- if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
- mx51_clocks_ipu_init(regs);
-
- return 0;
-}
-
-static int imx51_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *regs;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- regs = IOMEM(iores->start);
-
- mx51_clocks_init(dev, regs);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx51_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx51-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx51_ccm_driver = {
- .probe = imx51_ccm_probe,
- .name = "imx51-ccm",
- .of_compatible = DRV_OF_COMPAT(imx51_ccm_dt_ids),
-};
-
-static void mx53_clocks_ipu_init(void __iomem *regs)
-{
- clks[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
- clks[IMX5_CLK_LDB_DI1_DIV] = imx_clk_divider_np("ldb_di1_div", "ldb_di1_div_3_5", regs + CCM_CSCMR2, 11, 1);
- clks[IMX5_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", regs + CCM_CSCMR2, 9, 1,
- mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
- clks[IMX5_CLK_DI_PLL4_PODF] = imx_clk_divider("di_pll4_podf", "pll4_sw", regs + CCM_CDCDR, 16, 3);
- clks[IMX5_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
- clks[IMX5_CLK_LDB_DI0_DIV] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", regs + CCM_CSCMR2, 10, 1);
- clks[IMX5_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", regs + CCM_CSCMR2, 8, 1,
- mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
- clks[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
- mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
- clks[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
- mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
- clks[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
- mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
- clks[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", regs + CCM_CDCDR, 28, 3);
-
- mx5_clocks_ipu_init(regs);
-
- clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX53_IPU_BASE_ADDR, "bus");
- clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX53_IPU_BASE_ADDR, "di0");
- clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX53_IPU_BASE_ADDR, "di1");
-}
-
-int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs)
-{
- clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX53_PLL1_BASE_ADDR);
- clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX53_PLL2_BASE_ADDR);
- clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX53_PLL3_BASE_ADDR);
- clks[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", (void *)MX53_PLL4_BASE_ADDR);
-
- mx5_clocks_common_init(dev, regs);
- mx5_clocks_mx51_mx53_init(regs);
-
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART5_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_GPT1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_CSPI_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_FEC_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX53_ESDHC1_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX53_ESDHC2_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX53_ESDHC3_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX53_ESDHC4_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_AHB], MX53_SATA_BASE_ADDR, NULL);
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM1_BASE_ADDR, "per");
- clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM2_BASE_ADDR, "per");
-
- if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
- mx53_clocks_ipu_init(regs);
-
- return 0;
-}
-
-static int imx53_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *regs;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- regs = IOMEM(iores->start);
-
- mx53_clocks_init(dev, regs);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx53_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx53-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx53_ccm_driver = {
- .probe = imx53_ccm_probe,
- .name = "imx53-ccm",
- .of_compatible = DRV_OF_COMPAT(imx53_ccm_dt_ids),
-};
-
-static int imx5_ccm_init(void)
-{
- if (IS_ENABLED(CONFIG_ARCH_IMX50))
- platform_driver_register(&imx50_ccm_driver);
- if (IS_ENABLED(CONFIG_ARCH_IMX51))
- platform_driver_register(&imx51_ccm_driver);
- if (IS_ENABLED(CONFIG_ARCH_IMX53))
- platform_driver_register(&imx53_ccm_driver);
-
- return 0;
-}
-core_initcall(imx5_ccm_init);
diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c
deleted file mode 100644
index 8ac43be..0000000
--- a/arch/arm/mach-imx/clk-imx6.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * 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>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#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 <dt-bindings/clock/imx6qdl-clock.h>
-
-#include "clk.h"
-
-#define CCGR0 0x68
-#define CCGR1 0x6c
-#define CCGR2 0x70
-#define CCGR3 0x74
-#define CCGR4 0x78
-#define CCGR5 0x7c
-#define CCGR6 0x80
-#define CCGR7 0x84
-
-#define CLPCR 0x54
-#define BP_CLPCR_LPM 0
-#define BM_CLPCR_LPM (0x3 << 0)
-#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
-#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
-#define BM_CLPCR_SBYOS (0x1 << 6)
-#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
-#define BM_CLPCR_VSTBY (0x1 << 8)
-#define BP_CLPCR_STBY_COUNT 9
-#define BM_CLPCR_STBY_COUNT (0x3 << 9)
-#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
-#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
-#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
-#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
-#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
-#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
-#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
-#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
-#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
-#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
-#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
-
-static struct clk *clks[IMX6QDL_CLK_END];
-static struct clk_onecell_data clk_data;
-
-static const char *step_sels[] = {
- "osc",
- "pll2_pfd2_396m",
-};
-
-static const char *pll1_sw_sels[] = {
- "pll1_sys",
- "step",
-};
-
-static const char *periph_pre_sels[] = {
- "pll2_bus",
- "pll2_pfd2_396m",
- "pll2_pfd0_352m",
- "pll2_198m",
-};
-
-static const char *periph_clk2_sels[] = {
- "pll3_usb_otg",
- "osc",
-};
-
-static const char *periph_sels[] = {
- "periph_pre",
- "periph_clk2",
-};
-
-static const char *periph2_sels[] = {
- "periph2_pre",
- "periph2_clk2",
-};
-
-static const char *axi_sels[] = {
- "periph",
- "pll2_pfd2_396m",
- "pll3_pfd1_540m",
-};
-
-static const char *usdhc_sels[] = {
- "pll2_pfd2_396m",
- "pll2_pfd0_352m",
-};
-
-static const char *enfc_sels[] = {
- "pll2_pfd0_352m",
- "pll2_bus",
- "pll3_usb_otg",
- "pll2_pfd2_396m",
-};
-
-static const char *eim_sels[] = {
- "axi",
- "pll3_usb_otg",
- "pll2_pfd2_396m",
- "pll2_pfd0_352m",
-};
-
-static const char *vdo_axi_sels[] = {
- "axi",
- "ahb",
-};
-
-static const char *cko_sels[] = {
- "cko1",
- "cko2",
-};
-
-static const char *cko1_sels[] = {
- "pll3_usb_otg",
- "pll2_bus",
- "pll1_sys",
- "pll5_video",
- "dummy",
- "axi",
- "enfc",
- "ipu1_di0",
- "ipu1_di1",
- "ipu2_di0",
- "ipu2_di1",
- "ahb",
- "ipg",
- "ipg_per",
- "ckil",
- "pll4_audio",
-};
-
-static const char *cko2_sels[] = {
- "mmdc_ch0_axi",
- "mmdc_ch1_axi",
- "usdhc4",
- "usdhc1",
- "gpu2d_axi",
- "dummy",
- "ecspi_root",
- "gpu3d_axi",
- "usdhc3",
- "dummy",
- "arm",
- "ipu1",
- "ipu2",
- "vdo_axi",
- "osc",
- "gpu2d_core",
- "gpu3d_core",
- "usdhc2",
- "ssi1",
- "ssi2",
- "ssi3",
- "gpu3d_shader",
- "vpu_axi",
- "can_root",
- "ldb_di0",
- "ldb_di1",
- "esai",
- "eim_slow",
- "uart_serial",
- "spdif",
- "asrc",
- "hsi_tx",
-};
-
-static const char *ipu_sels[] = {
- "mmdc_ch0_axi_podf",
- "pll2_pfd2_396m",
- "pll3_120m",
- "pll3_pfd1_540m",
-};
-
-static const char *ldb_di_sels[] = {
- "pll5_video_div",
- "pll2_pfd0_352m",
- "pll2_pfd2_396m",
- "mmdc_ch1_axi_podf",
- "pll3_usb_otg",
-};
-
-static const char *ipu_di_pre_sels[] = {
- "mmdc_ch0_axi",
- "pll3_usb_otg",
- "pll5_video_div",
- "pll2_pfd0_352m",
- "pll2_pfd2_396m",
- "pll3_pfd1_540m",
-};
-
-static const char *ipu1_di0_sels[] = {
- "ipu1_di0_pre",
- "dummy",
- "dummy",
- "ldb_di0_podf",
- "ldb_di1_podf",
-};
-
-static const char *ipu1_di1_sels[] = {
- "ipu1_di1_pre",
- "dummy",
- "dummy",
- "ldb_di0_podf",
- "ldb_di1_podf",
-};
-
-static const char *ipu2_di0_sels[] = {
- "ipu2_di0_pre",
- "dummy",
- "dummy",
- "ldb_di0_podf",
- "ldb_di1_podf",
-};
-
-static const char *ipu2_di1_sels[] = {
- "ipu2_di1_pre",
- "dummy",
- "dummy",
- "ldb_di0_podf",
- "ldb_di1_podf",
-};
-
-static const char *lvds_sels[] = {
- "dummy",
- "dummy",
- "dummy",
- "dummy",
- "dummy",
- "dummy",
- "pll4_audio",
- "pll5_video",
- "pll8_mlb",
- "enet_ref",
- "pcie_ref_125m",
- "sata_ref_100m",
-};
-
-static const char *pcie_axi_sels[] = {
- "axi",
- "ahb",
-};
-
-static struct clk_div_table clk_enet_ref_table[] = {
- { .val = 0, .div = 20, },
- { .val = 1, .div = 10, },
- { .val = 2, .div = 5, },
- { .val = 3, .div = 4, },
- { },
-};
-
-static struct clk_div_table post_div_table[] = {
- { .val = 2, .div = 1, },
- { .val = 1, .div = 2, },
- { .val = 0, .div = 4, },
- { /* sentinel */ }
-};
-
-static struct clk_div_table video_div_table[] = {
- { .val = 0, .div = 1, },
- { .val = 1, .div = 2, },
- { .val = 2, .div = 1, },
- { .val = 3, .div = 4, },
- { /* sentinel */ }
-};
-
-static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb)
-{
- clks[IMX6QDL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table);
- clks[IMX6QDL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table);
-
- 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));
- clks[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", cb + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
- clks[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", cb + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
- clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clks[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_p("ipu1_di0_sel", cb + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
- clks[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_p("ipu1_di1_sel", cb + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
- clks[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_p("ipu2_di0_sel", cb + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
- clks[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_p("ipu2_di1_sel", cb + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
-
- clks[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", cb + 0x3c, 11, 3);
- clks[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", cb + 0x3c, 16, 3);
- clks[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
- clks[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_np("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1);
- clks[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
- clks[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_np("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1);
- clks[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", cb + 0x34, 3, 3);
- clks[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", cb + 0x34, 12, 3);
- 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_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);
- clks[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", cb + 0x74, 6);
- clks[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", cb + 0x74, 8);
- 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);
-
- 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]);
- clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_SEL], clks[IMX6QDL_CLK_IPU2_DI0_PRE]);
- clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_SEL], clks[IMX6QDL_CLK_IPU2_DI1_PRE]);
-
- clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
- clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
- clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
- clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
-
- if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) ||
- cpu_is_mx6dl()) {
- clk_set_parent(clks[IMX6QDL_CLK_LDB_DI0_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
- clk_set_parent(clks[IMX6QDL_CLK_LDB_DI1_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
- }
-
-}
-
-static int imx6_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *base, *anatop_base, *ccm_base;
-
- anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- ccm_base = IOMEM(iores->start);
-
- base = anatop_base;
-
- /* type name parent_name base div_mask */
- clks[IMX6QDL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
- clks[IMX6QDL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
- clks[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
- clks[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
- clks[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
- clks[IMX6QDL_CLK_PLL8_MLB] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll8_mlb", "osc", base + 0xd0, 0x0);
- clks[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
- clks[IMX6QDL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
-
- clks[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
- clks[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
-
- clks[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
- clks[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
- clks[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
- clks[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
-
- clks[IMX6QDL_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet", base + 0xe0, 0, 2, clk_enet_ref_table);
-
- clks[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
- clks[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
-
- clks[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
- clks[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
-
- /* name parent_name reg idx */
- clks[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
- clks[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
- clks[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
- clks[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
- clks[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
- clks[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
- clks[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
-
- /* name parent_name mult div */
- clks[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
- clks[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
- clks[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
- clks[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
- clks[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
-
- base = ccm_base;
-
- /* name reg shift width parent_names num_parents */
- clks[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
- clks[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
- 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_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));
- clks[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
- clks[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
- 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_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));
- clks[IMX6QDL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
- clks[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
-
- /* name reg shift width busy: reg, shift parent_names num_parents */
- clks[IMX6QDL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
- clks[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
-
- /* name parent_name reg shift width */
- clks[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
- clks[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
- clks[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
- clks[IMX6QDL_CLK_IPG_PER] = imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6);
- clks[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6);
- clks[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
- clks[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
- clks[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
- clks[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
- clks[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
- clks[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
- clks[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
- clks[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
- clks[IMX6QDL_CLK_EIM_PODF] = imx_clk_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3);
- clks[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
- clks[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
- clks[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
-
- /* name parent_name reg shift width busy: reg, shift */
- clks[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
- clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
- clks[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
- clks[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
- clks[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
-
- /* name parent_name reg shift */
- clks[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
- clks[IMX6QDL_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
- clks[IMX6QDL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
- clks[IMX6QDL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
- clks[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
- clks[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
- clks[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
- clks[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
- if (cpu_is_mx6dl())
- clks[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8);
- else
- clks[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
- clks[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
- clks[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
- clks[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
- clks[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
- clks[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
- clks[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
- clks[IMX6QDL_CLK_IIM] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
- clks[IMX6QDL_CLK_ENFC] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
- clks[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);
- clks[IMX6QDL_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
- clks[IMX6QDL_CLK_PWM1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16);
- clks[IMX6QDL_CLK_PWM2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18);
- clks[IMX6QDL_CLK_PWM3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20);
- clks[IMX6QDL_CLK_PWM4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22);
- clks[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
- clks[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
- clks[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28);
- clks[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
- clks[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4);
- clks[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
- clks[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
- clks[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
- clks[IMX6QDL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
- clks[IMX6QDL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
- clks[IMX6QDL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
- clks[IMX6QDL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
- clks[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
- clks[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
- clks[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
-
- clkdev_add_physbase(clks[IMX6QDL_CLK_IPG], MX6_OCOTP_BASE_ADDR, NULL);
-
- if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
- imx6_add_video_clks(anatop_base, ccm_base);
-
- writel(0xffffffff, ccm_base + CCGR0);
- writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */
- writel(0xffffffff, ccm_base + CCGR2);
- if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
- writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG */
- else
- writel(0x3fff0000, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */
- if (IS_ENABLED(CONFIG_PCI_IMX6))
- writel(0xffffffff, ccm_base + CCGR4);
- else
- writel(0xfffffffc, ccm_base + CCGR4); /* gate PCIe */
- writel(0xffffffff, ccm_base + CCGR5);
- writel(0xffff3fff, ccm_base + CCGR6); /* gate VPU */
- writel(0xffffffff, ccm_base + CCGR7);
-
- 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);
-
- clk_enable(clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF]);
- clk_enable(clks[IMX6QDL_CLK_PLL6_ENET]);
- clk_enable(clks[IMX6QDL_CLK_SATA_REF_100M]);
- clk_enable(clks[IMX6QDL_CLK_ENFC_PODF]);
-
- clk_set_parent(clks[IMX6QDL_CLK_LVDS1_SEL], clks[IMX6QDL_CLK_SATA_REF_100M]);
-
- return 0;
-}
-
-static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx6q-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d 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);
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
deleted file mode 100644
index d758957..0000000
--- a/arch/arm/mach-imx/clk-imx6sx.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
- *
- * 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 <dt-bindings/clock/imx6sx-clock.h>
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <of.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <mach/imx6-regs.h>
-#include <mach/revision.h>
-#include <mach/imx6.h>
-
-#include "clk.h"
-#include "common.h"
-
-#define CCDR 0x4
-#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
-
-static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
-static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
-static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
-static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
-static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
-static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
-static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
-static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
-static const char *ocram_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
-static const char *gpu_axi_sels[] = { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
-static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
-static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
-static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
-static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
-static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
-static const char *pcie_axi_sels[] = { "axi", "ahb", };
-static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
-static const char *perclk_sels[] = { "ipg", "osc", };
-static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
-static const char *vid_sels[] = { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
-static const char *uart_sels[] = { "pll3_80m", "osc", };
-static const char *qspi2_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
-static const char *enet_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
-static const char *enet_sels[] = { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *m4_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
-static const char *m4_sels[] = { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *eim_slow_sels[] = { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
-static const char *ecspi_sels[] = { "pll3_60m", "osc", };
-static const char *lcdif1_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
-static const char *lcdif1_sels[] = { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *lcdif2_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
-static const char *lcdif2_sels[] = { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
-static const char *display_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
-static const char *csi_sels[] = { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
-static const char *cko1_sels[] = {
- "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
- "dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
- "epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
-};
-static const char *cko2_sels[] = {
- "dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
- "ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
- "lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
- "usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
- "dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
- "spdif", "asrc", "dummy",
-};
-static const char *cko_sels[] = { "cko1", "cko2", };
-static const char *lvds_sels[] = {
- "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
- "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
-};
-static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
-static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
-static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
-static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
-static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
-static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
-static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
-static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
-
-static struct clk *clks[IMX6SX_CLK_CLK_END];
-static struct clk_onecell_data clk_data;
-
-static struct clk_div_table clk_enet_ref_table[] = {
- { .val = 0, .div = 20, },
- { .val = 1, .div = 10, },
- { .val = 2, .div = 5, },
- { .val = 3, .div = 4, },
- { }
-};
-
-static struct clk_div_table post_div_table[] = {
- { .val = 2, .div = 1, },
- { .val = 1, .div = 2, },
- { .val = 0, .div = 4, },
- { }
-};
-
-static struct clk_div_table video_div_table[] = {
- { .val = 0, .div = 1, },
- { .val = 1, .div = 2, },
- { .val = 2, .div = 1, },
- { .val = 3, .div = 4, },
- { }
-};
-
-static int imx6sx_ccm_probe(struct device_d *dev)
-{
- struct resource *iores;
- void __iomem *base, *anatop_base, *ccm_base;
- struct device_node *ccm_node = dev->device_node;
-
- clks[IMX6SX_CLK_DUMMY] = clk_fixed("dummy", 0);
-
- anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- ccm_base = IOMEM(iores->start);
-
- base = anatop_base;
-
- clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
- clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
- clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
- clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
- clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
- clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
- clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
-
- /* type name parent_name base div_mask */
- clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
- clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
- clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
- clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
- clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
- clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
- clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
-
- clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
- clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
- clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
- clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
- clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
- clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
- clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
-
- /* Do not bypass PLLs initially */
- clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
- clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
- clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
- clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
- clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
- clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
- clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
-
- clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
- clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
- clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
- clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
- clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
- clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
- clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
-
- /*
- * Bit 20 is the reserved and read-only bit, we do this only for:
- * - Do nothing for usbphy clk_enable/disable
- * - Keep refcount when do usbphy clk_enable/disable, in that case,
- * the clk framework may need to enable/disable usbphy's parent
- */
- clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
- clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
-
- /*
- * usbphy*_gate needs to be on after system boots up, and software
- * never needs to control it anymore.
- */
- clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
- clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
-
- /* FIXME 100Mhz is used for pcie ref for all imx6 pcie, excepted imx6q */
- clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
- clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
-
- clks[IMX6SX_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
- base + 0xe0, 0, 2, clk_enet_ref_table);
- clks[IMX6SX_CLK_ENET2_REF] = imx_clk_divider_table("enet2_ref", "pll6_enet",
- base + 0xe0, 2, 2, clk_enet_ref_table);
- clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
-
- clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
- clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
-
- /* name parent_name reg idx */
- clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
- clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
- clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
- clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
- clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
- clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
- clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
- clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
-
- /* name parent_name mult div */
- clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
- clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
- clks[IMX6SX_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
- clks[IMX6SX_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
- clks[IMX6SX_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
- clks[IMX6SX_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
-
- clks[IMX6SX_CLK_PLL4_POST_DIV] = imx_clk_divider_table("pll4_post_div", "pll4_audio",
- base + 0x70, 19, 2, post_div_table);
- clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = imx_clk_divider("pll4_audio_div", "pll4_post_div",
- base + 0x170, 15, 1);
- clks[IMX6SX_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video",
- base + 0xa0, 19, 2, post_div_table);
- clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div",
- base + 0x170, 30, 2, video_div_table);
-
- /* name reg shift width parent_names num_parents */
- clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
-
- base = ccm_base;
-
- /* name reg shift width parent_names num_parents */
- clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
- clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
- clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels));
- clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
- clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
- clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
- clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
- clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
- clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
- clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels));
- clks[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
- clks[IMX6SX_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
- clks[IMX6SX_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
- clks[IMX6SX_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
- clks[IMX6SX_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
- clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_p("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
- clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
- clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
- clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
- clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_p("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
- clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
- clks[IMX6SX_CLK_ENET_SEL] = imx_clk_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels));
- clks[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels));
- clks[IMX6SX_CLK_M4_SEL] = imx_clk_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels));
- clks[IMX6SX_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
- clks[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels));
- clks[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels));
- clks[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels));
- clks[IMX6SX_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
- clks[IMX6SX_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
- clks[IMX6SX_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
- clks[IMX6SX_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
-
- clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_p("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
- clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_p("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
- clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels));
- clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
- clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_p("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels));
- clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_p("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels));
-
- /* name parent_name reg shift width */
- clks[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
- clks[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
- clks[IMX6SX_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
- clks[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3);
- clks[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3);
- clks[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3);
- clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
- clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
- clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3);
- clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
- clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2);
- clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
- clks[IMX6SX_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
- clks[IMX6SX_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
- clks[IMX6SX_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
- clks[IMX6SX_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
- clks[IMX6SX_CLK_QSPI2_PRED] = imx_clk_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3);
- clks[IMX6SX_CLK_QSPI2_PODF] = imx_clk_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6);
- clks[IMX6SX_CLK_ENET_PODF] = imx_clk_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3);
- clks[IMX6SX_CLK_M4_PODF] = imx_clk_divider("m4_podf", "m4_sel", base + 0x34, 3, 3);
- clks[IMX6SX_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
- clks[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3);
- clks[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3);
- clks[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_divider("display_podf", "display_sel", base + 0x3c, 16, 3);
- clks[IMX6SX_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
- clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
- clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
-
- clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
- clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
- clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
- clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
-
- /* name reg shift width busy: reg, shift parent_names num_parents */
- clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
- clks[IMX6SX_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
- /* name parent_name reg shift width busy: reg, shift */
- clks[IMX6SX_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0);
- clks[IMX6SX_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
- clks[IMX6SX_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
- clks[IMX6SX_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
-
- /* name parent_name reg shift */
- /* CCGR0 */
- clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
- clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
- clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
- clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
- clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
- clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
- clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24);
- clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26);
- clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30);
-
- /* CCGR1 */
- clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
- clks[IMX6SX_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
- clks[IMX6SX_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
- clks[IMX6SX_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
- clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8);
- clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
- clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
- clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18);
- clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20);
- clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
- clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26);
-
- /* CCGR2 */
- clks[IMX6SX_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
- clks[IMX6SX_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
- clks[IMX6SX_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
- clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
- clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
- clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14);
- clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16);
- clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18);
- clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20);
- clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22);
- clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28);
- clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30);
-
- /* CCGR3 */
- clks[IMX6SX_CLK_M4] = imx_clk_gate2("m4", "m4_podf", base + 0x74, 2);
- clks[IMX6SX_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4);
- clks[IMX6SX_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "enet_sel", base + 0x74, 4);
- clks[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_gate2("display_axi", "display_podf", base + 0x74, 6);
- clks[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8);
- clks[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10);
- clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
- clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14);
- clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18);
- clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
- clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
- clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
-
- /* CCGR4 */
- clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0);
- clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10);
- clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
- clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14);
- clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
- clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
- clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
- clks[IMX6SX_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
- clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
- clks[IMX6SX_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
- clks[IMX6SX_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28);
- clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
-
- /* CCGR5 */
- clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
- clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
- clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
- clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
- clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26);
- clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28);
- clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30);
-
- /* CCGR6 */
- clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
- clks[IMX6SX_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
- clks[IMX6SX_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
- clks[IMX6SX_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
- clks[IMX6SX_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
- clks[IMX6SX_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
- clks[IMX6SX_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16);
- clks[IMX6SX_CLK_VADC] = imx_clk_gate2("vadc", "vid_podf", base + 0x80, 20);
- clks[IMX6SX_CLK_GIS] = imx_clk_gate2("gis", "display_podf", base + 0x80, 22);
- clks[IMX6SX_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
- clks[IMX6SX_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
- clks[IMX6SX_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
- clks[IMX6SX_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
-
- clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
- clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
-
- /* mask handshake of mmdc */
- writel(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
-
- clk_data.clks = clks;
- clk_data.clk_num = ARRAY_SIZE(clks);
- of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
-
- if (IS_ENABLED(CONFIG_USB_IMX_PHY)) {
- clk_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
- clk_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
- }
-
- return 0;
-};
-
-static int imx6sx_clocks_init(void)
-{
- if (!of_machine_is_compatible("fsl,imx6sx"))
- return 0;
-
- /* Set the default 132MHz for EIM module */
- clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
- clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
-
- /* set parent clock for LCDIF1 pixel clock */
- clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
- clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
-
- /*
- * Init enet system AHB clock, set to 200Mhz
- * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
- */
- clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
- clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
- clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
- clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
- clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
-
- /* Set parent clock for vadc */
- clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
-
- /* Update gpu clock from default 528M to 720M */
- clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
- clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
-
- return 0;
-}
-coredevice_initcall(imx6sx_clocks_init);
-
-static __maybe_unused struct of_device_id imx6sx_ccm_dt_ids[] = {
- {
- .compatible = "fsl,imx6sx-ccm",
- }, {
- /* sentinel */
- }
-};
-
-static struct driver_d imx6sx_ccm_driver = {
- .probe = imx6sx_ccm_probe,
- .name = "imx6-ccm",
- .of_compatible = DRV_OF_COMPAT(imx6sx_ccm_dt_ids),
-};
-
-static int imx6sx_ccm_init(void)
-{
- return platform_driver_register(&imx6sx_ccm_driver);
-}
-core_initcall(imx6sx_ccm_init);
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
deleted file mode 100644
index 8f6d5ad..0000000
--- a/arch/arm/mach-imx/clk-pfd.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 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>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-/**
- * struct clk_pfd - IMX PFD clock
- * @clk_hw: clock source
- * @reg: PFD register address
- * @idx: the index of PFD encoded in the register
- *
- * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
- * data encoded, and member idx is used to specify the one. And each
- * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
- */
-struct clk_pfd {
- struct clk clk;
- void __iomem *reg;
- u8 idx;
- const char *parent;
-};
-
-#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
-
-#define SET 0x4
-#define CLR 0x8
-#define OTG 0xc
-
-static int clk_pfd_enable(struct clk *clk)
-{
- struct clk_pfd *pfd = to_clk_pfd(clk);
- writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
-
- return 0;
-}
-
-static void clk_pfd_disable(struct clk *clk)
-{
- struct clk_pfd *pfd = to_clk_pfd(clk);
-
- writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
-}
-
-static unsigned long clk_pfd_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- struct clk_pfd *pfd = to_clk_pfd(clk);
- u64 tmp = parent_rate;
- u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
-
- tmp *= 18;
- do_div(tmp, frac);
-
- return tmp;
-}
-
-static long clk_pfd_round_rate(struct clk *clk, unsigned long rate,
- unsigned long *prate)
-{
- u64 tmp = *prate;
- u8 frac;
-
- tmp = tmp * 18 + rate / 2;
- do_div(tmp, rate);
- frac = tmp;
- if (frac < 12)
- frac = 12;
- else if (frac > 35)
- frac = 35;
- tmp = *prate;
- tmp *= 18;
- do_div(tmp, frac);
-
- return tmp;
-}
-
-static int clk_pfd_set_rate(struct clk *clk, unsigned long rate,
- unsigned long parent_rate)
-{
- struct clk_pfd *pfd = to_clk_pfd(clk);
- u64 tmp = parent_rate;
- u8 frac;
-
- tmp = tmp * 18 + rate / 2;
- do_div(tmp, rate);
- frac = tmp;
- if (frac < 12)
- frac = 12;
- else if (frac > 35)
- frac = 35;
-
- writel(0x3f << (pfd->idx * 8), pfd->reg + CLR);
- writel(frac << (pfd->idx * 8), pfd->reg + SET);
-
- return 0;
-}
-
-static const struct clk_ops clk_pfd_ops = {
- .enable = clk_pfd_enable,
- .disable = clk_pfd_disable,
- .recalc_rate = clk_pfd_recalc_rate,
- .round_rate = clk_pfd_round_rate,
- .set_rate = clk_pfd_set_rate,
-};
-
-struct clk *imx_clk_pfd(const char *name, const char *parent,
- void __iomem *reg, u8 idx)
-{
- struct clk_pfd *pfd;
- int ret;
-
- pfd = xzalloc(sizeof(*pfd));
-
- pfd->reg = reg;
- pfd->idx = idx;
- pfd->parent = parent;
- pfd->clk.name = name;
- pfd->clk.ops = &clk_pfd_ops;
- pfd->clk.parent_names = &pfd->parent;
- pfd->clk.num_parents = 1;
-
- ret = clk_register(&pfd->clk);
- if (ret) {
- free(pfd);
- return ERR_PTR(ret);
- }
-
- return &pfd->clk;
-}
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
deleted file mode 100644
index f992134..0000000
--- a/arch/arm/mach-imx/clk-pllv1.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-struct clk_pllv1 {
- struct clk clk;
- void __iomem *reg;
- const char *parent;
-};
-
-static unsigned long clk_pllv1_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- struct clk_pllv1 *pll = container_of(clk, struct clk_pllv1, clk);
- unsigned long long ll;
- int mfn_abs;
- unsigned int mfi, mfn, mfd, pd;
- u32 reg_val = readl(pll->reg);
- unsigned long freq = parent_rate;
-
- mfi = (reg_val >> 10) & 0xf;
- mfn = reg_val & 0x3ff;
- mfd = (reg_val >> 16) & 0x3ff;
- pd = (reg_val >> 26) & 0xf;
-
- mfi = mfi <= 5 ? 5 : mfi;
-
- mfn_abs = mfn;
-
-#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
- if (mfn >= 0x200) {
- mfn |= 0xFFFFFE00;
- mfn_abs = -mfn;
- }
-#endif
-
- freq *= 2;
- freq /= pd + 1;
-
- ll = (unsigned long long)freq * mfn_abs;
-
- do_div(ll, mfd + 1);
- if (mfn < 0)
- ll = (freq * mfi) - ll;
- else
- ll = (freq * mfi) + ll;
-
- return ll;
-}
-
-struct clk_ops clk_pllv1_ops = {
- .recalc_rate = clk_pllv1_recalc_rate,
-};
-
-struct clk *imx_clk_pllv1(const char *name, const char *parent,
- void __iomem *base)
-{
- struct clk_pllv1 *pll = xzalloc(sizeof(*pll));
- int ret;
-
- pll->parent = parent;
- pll->reg = base;
- pll->clk.ops = &clk_pllv1_ops;
- pll->clk.name = name;
- pll->clk.parent_names = &pll->parent;
- pll->clk.num_parents = 1;
-
- ret = clk_register(&pll->clk);
- if (ret) {
- free(pll);
- return ERR_PTR(ret);
- }
-
- return &pll->clk;
-}
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
deleted file mode 100644
index 5ba07fa..0000000
--- a/arch/arm/mach-imx/clk-pllv2.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-/* PLL Register Offsets */
-#define MXC_PLL_DP_CTL 0x00
-#define MXC_PLL_DP_CONFIG 0x04
-#define MXC_PLL_DP_OP 0x08
-#define MXC_PLL_DP_MFD 0x0C
-#define MXC_PLL_DP_MFN 0x10
-#define MXC_PLL_DP_MFNMINUS 0x14
-#define MXC_PLL_DP_MFNPLUS 0x18
-#define MXC_PLL_DP_HFS_OP 0x1C
-#define MXC_PLL_DP_HFS_MFD 0x20
-#define MXC_PLL_DP_HFS_MFN 0x24
-#define MXC_PLL_DP_MFN_TOGC 0x28
-#define MXC_PLL_DP_DESTAT 0x2c
-
-/* PLL Register Bit definitions */
-#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
-#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
-#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
-#define MXC_PLL_DP_CTL_ADE 0x800
-#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
-#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
-#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
-#define MXC_PLL_DP_CTL_HFSM 0x80
-#define MXC_PLL_DP_CTL_PRE 0x40
-#define MXC_PLL_DP_CTL_UPEN 0x20
-#define MXC_PLL_DP_CTL_RST 0x10
-#define MXC_PLL_DP_CTL_RCP 0x8
-#define MXC_PLL_DP_CTL_PLM 0x4
-#define MXC_PLL_DP_CTL_BRM0 0x2
-#define MXC_PLL_DP_CTL_LRF 0x1
-
-#define MXC_PLL_DP_CONFIG_BIST 0x8
-#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
-#define MXC_PLL_DP_CONFIG_AREN 0x2
-#define MXC_PLL_DP_CONFIG_LDREQ 0x1
-
-#define MXC_PLL_DP_OP_MFI_OFFSET 4
-#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
-#define MXC_PLL_DP_OP_PDF_OFFSET 0
-#define MXC_PLL_DP_OP_PDF_MASK 0xF
-
-#define MXC_PLL_DP_MFD_OFFSET 0
-#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
-
-#define MXC_PLL_DP_MFN_OFFSET 0x0
-#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
-
-#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
-#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
-#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
-#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
-
-#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
-#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
-
-#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
-
-struct clk_pllv2 {
- struct clk clk;
- void __iomem *reg;
- const char *parent;
-};
-
-static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
- u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
-{
- long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
- unsigned long dbl;
- uint64_t temp;
-
- dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
-
- pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
- mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
- mfi = (mfi <= 5) ? 5 : mfi;
- mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
- mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
- /* Sign extend to 32-bits */
- if (mfn >= 0x04000000) {
- mfn |= 0xFC000000;
- mfn_abs = -mfn;
- }
-
- ref_clk = 2 * parent_rate;
- if (dbl != 0)
- ref_clk *= 2;
-
- ref_clk /= (pdf + 1);
- temp = (u64) ref_clk * mfn_abs;
- do_div(temp, mfd + 1);
- if (mfn < 0)
- temp = (ref_clk * mfi) - temp;
- else
- temp = (ref_clk * mfi) + temp;
-
- return temp;
-}
-
-static unsigned long clk_pllv2_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
- void __iomem *pllbase;
- struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
-
- pllbase = pll->reg;
-
- dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
- dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
- dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
- dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
-
- return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn);
-}
-
-static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
- u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn)
-{
- u32 reg;
- long mfi, pdf, mfn, mfd = 999999;
- u64 temp64;
- unsigned long quad_parent_rate;
-
- quad_parent_rate = 4 * parent_rate;
- pdf = mfi = -1;
- while (++pdf < 16 && mfi < 5)
- mfi = rate * (pdf+1) / quad_parent_rate;
- if (mfi > 15)
- return -EINVAL;
- pdf--;
-
- temp64 = rate * (pdf + 1) - quad_parent_rate * mfi;
- do_div(temp64, quad_parent_rate / 1000000);
- mfn = (long)temp64;
-
- reg = mfi << 4 | pdf;
-
- *dp_op = reg;
- *dp_mfd = mfd;
- *dp_mfn = mfn;
-
- return 0;
-}
-
-static int clk_pllv2_set_rate(struct clk *clk, unsigned long rate,
- unsigned long parent_rate)
-{
- struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
- void __iomem *pllbase;
- u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
- int ret;
-
- pllbase = pll->reg;
-
- ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn);
- if (ret)
- return ret;
-
- dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
- /* use dpdck0_2 */
- __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
-
- __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP);
- __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD);
- __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN);
-
- return 0;
-}
-
-static long clk_pllv2_round_rate(struct clk *clk, unsigned long rate,
- unsigned long *prate)
-{
- u32 dp_op, dp_mfd, dp_mfn;
-
- __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
- return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
- dp_op, dp_mfd, dp_mfn);
-}
-
-struct clk_ops clk_pllv2_ops = {
- .recalc_rate = clk_pllv2_recalc_rate,
- .round_rate = clk_pllv2_round_rate,
- .set_rate = clk_pllv2_set_rate,
-};
-
-struct clk *imx_clk_pllv2(const char *name, const char *parent,
- void __iomem *base)
-{
- struct clk_pllv2 *pll = xzalloc(sizeof(*pll));
- int ret;
-
- pll->parent = parent;
- pll->reg = base;
- pll->clk.ops = &clk_pllv2_ops;
- pll->clk.name = name;
- pll->clk.parent_names = &pll->parent;
- pll->clk.num_parents = 1;
-
- ret = clk_register(&pll->clk);
- if (ret) {
- free(pll);
- return ERR_PTR(ret);
- }
-
- return &pll->clk;
-}
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
deleted file mode 100644
index e38dcdf..0000000
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <linux/clk.h>
-#include <io.h>
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <malloc.h>
-#include <clock.h>
-#include <asm-generic/div64.h>
-
-#include "clk.h"
-
-#define PLL_NUM_OFFSET 0x10
-#define PLL_DENOM_OFFSET 0x20
-
-#define BM_PLL_POWER (0x1 << 12)
-#define BM_PLL_ENABLE (0x1 << 13)
-#define BM_PLL_BYPASS (0x1 << 16)
-#define BM_PLL_LOCK (0x1 << 31)
-
-struct clk_pllv3 {
- struct clk clk;
- void __iomem *base;
- bool powerup_set;
- u32 div_mask;
- const char *parent;
-};
-
-#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
-
-static int clk_pllv3_enable(struct clk *clk)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 val;
- int timeout = 10000;
-
- val = readl(pll->base);
- val &= ~BM_PLL_BYPASS;
- if (pll->powerup_set)
- val |= BM_PLL_POWER;
- else
- val &= ~BM_PLL_POWER;
- writel(val, pll->base);
-
- /* Wait for PLL to lock */
- while (timeout--) {
- if (readl(pll->base) & BM_PLL_LOCK)
- break;
- }
-
- if (!timeout)
- return -ETIMEDOUT;
-
- val = readl(pll->base);
- val |= BM_PLL_ENABLE;
- writel(val, pll->base);
-
- return 0;
-}
-
-static void clk_pllv3_disable(struct clk *clk)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 val;
-
- val = readl(pll->base);
- val &= ~BM_PLL_ENABLE;
- writel(val, pll->base);
-
- val |= BM_PLL_BYPASS;
- if (pll->powerup_set)
- val &= ~BM_PLL_POWER;
- else
- val |= BM_PLL_POWER;
- writel(val, pll->base);
-}
-
-static unsigned long clk_pllv3_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 div = readl(pll->base) & pll->div_mask;
-
- return (div == 1) ? parent_rate * 22 : parent_rate * 20;
-}
-
-static long clk_pllv3_round_rate(struct clk *clk, unsigned long rate,
- unsigned long *prate)
-{
- unsigned long parent_rate = *prate;
-
- return (rate >= parent_rate * 22) ? parent_rate * 22 :
- parent_rate * 20;
-}
-
-static int clk_pllv3_set_rate(struct clk *clk, unsigned long rate,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 val, div;
-
- if (rate == parent_rate * 22)
- div = 1;
- else if (rate == parent_rate * 20)
- div = 0;
- else
- return -EINVAL;
-
- val = readl(pll->base);
- val &= ~pll->div_mask;
- val |= div;
- writel(val, pll->base);
-
- return 0;
-}
-
-static const struct clk_ops clk_pllv3_ops = {
- .enable = clk_pllv3_enable,
- .disable = clk_pllv3_disable,
- .recalc_rate = clk_pllv3_recalc_rate,
- .round_rate = clk_pllv3_round_rate,
- .set_rate = clk_pllv3_set_rate,
-};
-
-static unsigned long clk_pllv3_sys_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 div = readl(pll->base) & pll->div_mask;
-
- return parent_rate * div / 2;
-}
-
-static long clk_pllv3_sys_round_rate(struct clk *clk, unsigned long rate,
- unsigned long *prate)
-{
- unsigned long parent_rate = *prate;
- unsigned long min_rate = parent_rate * 54 / 2;
- unsigned long max_rate = parent_rate * 108 / 2;
- u32 div;
-
- if (rate > max_rate)
- rate = max_rate;
- else if (rate < min_rate)
- rate = min_rate;
- div = rate * 2 / parent_rate;
-
- return parent_rate * div / 2;
-}
-
-static int clk_pllv3_sys_set_rate(struct clk *clk, unsigned long rate,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- unsigned long min_rate = parent_rate * 54 / 2;
- unsigned long max_rate = parent_rate * 108 / 2;
- u32 val, div;
-
- if (rate < min_rate || rate > max_rate)
- return -EINVAL;
-
- div = rate * 2 / parent_rate;
- val = readl(pll->base);
- val &= ~pll->div_mask;
- val |= div;
- writel(val, pll->base);
-
- return 0;
-}
-
-static const struct clk_ops clk_pllv3_sys_ops = {
- .enable = clk_pllv3_enable,
- .disable = clk_pllv3_disable,
- .recalc_rate = clk_pllv3_sys_recalc_rate,
- .round_rate = clk_pllv3_sys_round_rate,
- .set_rate = clk_pllv3_sys_set_rate,
-};
-
-static unsigned long clk_pllv3_av_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
- u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
- u32 div = readl(pll->base) & pll->div_mask;
-
- return (parent_rate * div) + ((parent_rate / mfd) * mfn);
-}
-
-static long clk_pllv3_av_round_rate(struct clk *clk, unsigned long rate,
- unsigned long *prate)
-{
- unsigned long parent_rate = *prate;
- unsigned long min_rate = parent_rate * 27;
- unsigned long max_rate = parent_rate * 54;
- u32 div;
- u32 mfn, mfd = 1000000;
- u64 temp64;
-
- if (rate > max_rate)
- rate = max_rate;
- else if (rate < min_rate)
- rate = min_rate;
-
- div = rate / parent_rate;
- temp64 = (u64) (rate - div * parent_rate);
- temp64 *= mfd;
- do_div(temp64, parent_rate);
- mfn = temp64;
-
- return parent_rate * div + parent_rate / mfd * mfn;
-}
-
-static int clk_pllv3_av_set_rate(struct clk *clk, unsigned long rate,
- unsigned long parent_rate)
-{
- struct clk_pllv3 *pll = to_clk_pllv3(clk);
- unsigned long min_rate = parent_rate * 27;
- unsigned long max_rate = parent_rate * 54;
- u32 val, div;
- u32 mfn, mfd = 1000000;
- u64 temp64;
-
- if (rate < min_rate || rate > max_rate)
- return -EINVAL;
-
- div = rate / parent_rate;
- temp64 = (u64) (rate - div * parent_rate);
- temp64 *= mfd;
- do_div(temp64, parent_rate);
- mfn = temp64;
-
- val = readl(pll->base);
- val &= ~pll->div_mask;
- val |= div;
- writel(val, pll->base);
- writel(mfn, pll->base + PLL_NUM_OFFSET);
- writel(mfd, pll->base + PLL_DENOM_OFFSET);
-
- return 0;
-}
-
-static const struct clk_ops clk_pllv3_av_ops = {
- .enable = clk_pllv3_enable,
- .disable = clk_pllv3_disable,
- .recalc_rate = clk_pllv3_av_recalc_rate,
- .round_rate = clk_pllv3_av_round_rate,
- .set_rate = clk_pllv3_av_set_rate,
-};
-
-static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
- unsigned long parent_rate)
-{
- return 500000000;
-}
-
-static const struct clk_ops clk_pllv3_enet_ops = {
- .enable = clk_pllv3_enable,
- .disable = clk_pllv3_disable,
- .recalc_rate = clk_pllv3_enet_recalc_rate,
-};
-
-static const struct clk_ops clk_pllv3_mlb_ops = {
- .enable = clk_pllv3_enable,
- .disable = clk_pllv3_disable,
-};
-
-struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
- const char *parent, void __iomem *base,
- u32 div_mask)
-{
- struct clk_pllv3 *pll;
- const struct clk_ops *ops;
- int ret;
-
- pll = xzalloc(sizeof(*pll));
-
- switch (type) {
- case IMX_PLLV3_SYS:
- ops = &clk_pllv3_sys_ops;
- break;
- case IMX_PLLV3_USB:
- ops = &clk_pllv3_ops;
- pll->powerup_set = true;
- break;
- case IMX_PLLV3_AV:
- ops = &clk_pllv3_av_ops;
- break;
- case IMX_PLLV3_ENET:
- ops = &clk_pllv3_enet_ops;
- break;
- case IMX_PLLV3_MLB:
- ops = &clk_pllv3_mlb_ops;
- break;
- default:
- ops = &clk_pllv3_ops;
- }
- pll->base = base;
- pll->div_mask = div_mask;
- pll->parent = parent;
- pll->clk.ops = ops;
- pll->clk.name = name;
- pll->clk.parent_names = &pll->parent;
- pll->clk.num_parents = 1;
-
- ret = clk_register(&pll->clk);
- if (ret) {
- free(pll);
- return ERR_PTR(ret);
- }
-
- return &pll->clk;
-}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
deleted file mode 100644
index c5913e1..0000000
--- a/arch/arm/mach-imx/clk.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef __IMX_CLK_H
-#define __IMX_CLK_H
-
-struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
- u8 shift);
-
-static inline struct clk *imx_clk_divider(const char *name, const char *parent,
- void __iomem *reg, u8 shift, u8 width)
-{
- return clk_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_divider_np(const char *name, const char *parent,
- void __iomem *reg, u8 shift, u8 width)
-{
- return clk_divider(name, parent, reg, shift, width, 0);
-}
-
-static inline struct clk *imx_clk_divider_table(const char *name,
- const char *parent, void __iomem *reg, u8 shift, u8 width,
- const struct clk_div_table *table)
-{
- return clk_divider_table(name, parent, reg, shift, width, table,
- CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_fixed_factor(const char *name,
- const char *parent, unsigned int mult, unsigned int div)
-{
- return clk_fixed_factor(name, parent, mult, div, CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
- u8 shift, u8 width, const char **parents, u8 num_parents)
-{
- return clk_mux(name, reg, shift, width, parents, num_parents, 0);
-}
-
-static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
- u8 shift, u8 width, const char **parents, u8 num_parents)
-{
- return clk_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT);
-}
-
-static inline struct clk *imx_clk_gate(const char *name, const char *parent,
- void __iomem *reg, u8 shift)
-{
- return clk_gate(name, parent, reg, shift, CLK_SET_RATE_PARENT, 0);
-}
-
-static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
- void __iomem *reg, u8 shift)
-{
- return clk_gate2(name, parent, reg, shift);
-}
-
-struct clk *imx_clk_pllv1(const char *name, const char *parent,
- void __iomem *base);
-
-struct clk *imx_clk_pllv2(const char *name, const char *parent,
- void __iomem *base);
-
-enum imx_pllv3_type {
- IMX_PLLV3_GENERIC,
- IMX_PLLV3_SYS,
- IMX_PLLV3_USB,
- IMX_PLLV3_AV,
- IMX_PLLV3_ENET,
- IMX_PLLV3_MLB,
-};
-
-struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
- const char *parent, void __iomem *base,
- u32 div_mask);
-
-struct clk *imx_clk_pfd(const char *name, const char *parent,
- void __iomem *reg, u8 idx);
-
-static inline struct clk *imx_clk_busy_divider(const char *name, const char *parent,
- void __iomem *reg, u8 shift, u8 width,
- void __iomem *busy_reg, u8 busy_shift)
-{
- /*
- * For now we do not support rate setting, so just fall back to
- * regular divider.
- */
- return imx_clk_divider(name, parent, reg, shift, width);
-}
-
-static inline struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
- u8 width, void __iomem *busy_reg, u8 busy_shift,
- const char **parents, int num_parents)
-{
- /*
- * For now we do not support mux switching, so just fall back to
- * regular mux.
- */
- return imx_clk_mux(name, reg, shift, width, parents, num_parents);
-}
-
-struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
- void __iomem *reg, u8 shift, u32 exclusive_mask);
-
-#endif /* __IMX_CLK_H */
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 0fe8f1e..a4e4ed0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_CLK_SOCFPGA) += socfpga.o
obj-$(CONFIG_MACH_MIPS_ATH79) += clk-ar933x.o
+obj-$(CONFIG_ARCH_IMX) += imx/
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
new file mode 100644
index 0000000..893a1a5
--- /dev/null
+++ b/drivers/clk/imx/Makefile
@@ -0,0 +1,21 @@
+obj-$(CONFIG_COMMON_CLK) += \
+ clk-pllv1.o \
+ clk-pllv2.o \
+ clk-pllv3.o \
+ clk-pfd.o \
+ clk-gate2.o \
+ clk-gate-exclusive.o
+
+obj-$(CONFIG_ARCH_IMX1) += clk-imx1.o
+obj-$(CONFIG_ARCH_IMX25) += clk-imx25.o
+obj-$(CONFIG_ARCH_IMX21) += clk-imx21.o
+obj-$(CONFIG_ARCH_IMX27) += clk-imx27.o
+obj-$(CONFIG_ARCH_IMX31) += clk-imx31.o
+obj-$(CONFIG_ARCH_IMX35) += clk-imx35.o
+obj-$(CONFIG_ARCH_IMX50) += clk-imx5.o
+obj-$(CONFIG_ARCH_IMX51) += clk-imx5.o
+obj-$(CONFIG_ARCH_IMX53) += clk-imx5.o
+obj-$(CONFIG_ARCH_IMX6) += clk-imx6.o
+obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
+
+
diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c
new file mode 100644
index 0000000..db88db0
--- /dev/null
+++ b/drivers/clk/imx/clk-gate-exclusive.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
+ * exclusive with other gate clocks
+ *
+ * @gate: the parent class
+ * @exclusive_mask: mask of gate bits which are mutually exclusive to this
+ * gate clock
+ *
+ * The imx exclusive gate clock is a subclass of basic clk_gate
+ * with an addtional mask to indicate which other gate bits in the same
+ * register is mutually exclusive to this gate clock.
+ */
+struct clk_gate_exclusive {
+ struct clk clk;
+ void __iomem *reg;
+ int shift;
+ const char *parent;
+ u32 exclusive_mask;
+};
+
+static int clk_gate_exclusive_enable(struct clk *clk)
+{
+ struct clk_gate_exclusive *exgate = container_of(clk,
+ struct clk_gate_exclusive, clk);
+ u32 val = readl(exgate->reg);
+
+ if (val & exgate->exclusive_mask)
+ return -EBUSY;
+
+ val |= 1 << exgate->shift;
+
+ writel(val, exgate->reg);
+
+ return 0;
+}
+
+static void clk_gate_exclusive_disable(struct clk *clk)
+{
+ struct clk_gate_exclusive *exgate = container_of(clk,
+ struct clk_gate_exclusive, clk);
+ u32 val = readl(exgate->reg);
+
+ val &= ~(1 << exgate->shift);
+
+ writel(val, exgate->reg);
+}
+
+static int clk_gate_exclusive_is_enabled(struct clk *clk)
+{
+ struct clk_gate_exclusive *exgate = container_of(clk,
+ struct clk_gate_exclusive, clk);
+
+ return readl(exgate->reg) & (1 << exgate->shift);
+}
+
+static const struct clk_ops clk_gate_exclusive_ops = {
+ .enable = clk_gate_exclusive_enable,
+ .disable = clk_gate_exclusive_disable,
+ .is_enabled = clk_gate_exclusive_is_enabled,
+};
+
+struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u32 exclusive_mask)
+{
+ struct clk_gate_exclusive *exgate;
+ int ret;
+
+ exgate = xzalloc(sizeof(*exgate));
+ exgate->parent = parent;
+ exgate->clk.name = name;
+ exgate->clk.ops = &clk_gate_exclusive_ops;
+ exgate->clk.flags = CLK_SET_RATE_PARENT;
+ exgate->clk.parent_names = &exgate->parent;
+ exgate->clk.num_parents = 1;
+
+ exgate->reg = reg;
+ exgate->shift = shift;
+ exgate->exclusive_mask = exclusive_mask;
+
+ ret = clk_register(&exgate->clk);
+ if (ret) {
+ free(exgate);
+ return ERR_PTR(ret);
+ }
+
+ return &exgate->clk;
+}
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
new file mode 100644
index 0000000..faed631
--- /dev/null
+++ b/drivers/clk/imx/clk-gate2.c
@@ -0,0 +1,145 @@
+/*
+ * clk-gate2.c - barebox 2-bit clock support. Based on Linux clk support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+
+struct clk_gate2 {
+ struct clk clk;
+ void __iomem *reg;
+ int shift;
+ const char *parent;
+#define CLK_GATE_INVERTED (1 << 0)
+ unsigned flags;
+};
+
+#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+
+static int clk_gate2_enable(struct clk *clk)
+{
+ struct clk_gate2 *g = to_clk_gate2(clk);
+ u32 val;
+
+ val = readl(g->reg);
+
+ if (g->flags & CLK_GATE_INVERTED)
+ val &= ~(3 << g->shift);
+ else
+ val |= 3 << g->shift;
+
+ writel(val, g->reg);
+
+ return 0;
+}
+
+static void clk_gate2_disable(struct clk *clk)
+{
+ struct clk_gate2 *g = to_clk_gate2(clk);
+ u32 val;
+
+ val = readl(g->reg);
+
+ if (g->flags & CLK_GATE_INVERTED)
+ val |= 3 << g->shift;
+ else
+ val &= ~(3 << g->shift);
+
+ writel(val, g->reg);
+}
+
+static int clk_gate2_is_enabled(struct clk *clk)
+{
+ struct clk_gate2 *g = to_clk_gate2(clk);
+ u32 val;
+
+ val = readl(g->reg);
+
+ if (val & (1 << g->shift))
+ return g->flags & CLK_GATE_INVERTED ? 0 : 1;
+ else
+ return g->flags & CLK_GATE_INVERTED ? 1 : 0;
+}
+
+static struct clk_ops clk_gate2_ops = {
+ .set_rate = clk_parent_set_rate,
+ .round_rate = clk_parent_round_rate,
+ .enable = clk_gate2_enable,
+ .disable = clk_gate2_disable,
+ .is_enabled = clk_gate2_is_enabled,
+};
+
+struct clk *clk_gate2_alloc(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ struct clk_gate2 *g = xzalloc(sizeof(*g));
+
+ g->parent = parent;
+ g->reg = reg;
+ g->shift = shift;
+ g->clk.ops = &clk_gate2_ops;
+ g->clk.name = name;
+ g->clk.parent_names = &g->parent;
+ g->clk.num_parents = 1;
+ g->clk.flags = CLK_SET_RATE_PARENT;
+
+ return &g->clk;
+}
+
+void clk_gate2_free(struct clk *clk)
+{
+ struct clk_gate2 *g = to_clk_gate2(clk);
+
+ free(g);
+}
+
+struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
+ u8 shift)
+{
+ struct clk *g;
+ int ret;
+
+ g = clk_gate2_alloc(name , parent, reg, shift);
+
+ ret = clk_register(g);
+ if (ret) {
+ free(to_clk_gate2(g));
+ return ERR_PTR(ret);
+ }
+
+ return g;
+}
+
+struct clk *clk_gate2_inverted(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ struct clk *clk;
+ struct clk_gate2 *g;
+
+ clk = clk_gate2(name, parent, reg, shift);
+ if (IS_ERR(clk))
+ return clk;
+
+ g = to_clk_gate2(clk);
+
+ g->flags = CLK_GATE_INVERTED;
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c
new file mode 100644
index 0000000..5f600a9
--- /dev/null
+++ b/drivers/clk/imx/clk-imx1.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx1-regs.h>
+
+#include "clk.h"
+
+#define CCM_CSCR 0x0
+#define CCM_MPCTL0 0x4
+#define CCM_SPCTL0 0xc
+#define CCM_PCDR 0x20
+
+enum imx1_clks {
+ dummy, clk32, clk16m, clk32_premult, prem, mpll, spll, mcu,
+ fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
+ mma_gate, usbd_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *prem_sel_clks[] = {
+ "clk32_premult",
+ "clk16m",
+};
+
+static const char *clko_sel_clks[] = {
+ "per1",
+ "hclk",
+ "clk48m",
+ "clk16m",
+ "prem",
+ "fclk",
+};
+
+int __init mx1_clocks_init(void __iomem *regs, unsigned long fref)
+{
+ clks[dummy] = clk_fixed("dummy", 0);
+ clks[clk32] = clk_fixed("clk32", fref);
+ clks[clk16m] = clk_fixed("clk16m", 16000000);
+ clks[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
+ clks[prem] = imx_clk_mux("prem", regs + CCM_CSCR, 16, 1, prem_sel_clks,
+ ARRAY_SIZE(prem_sel_clks));
+ clks[mpll] = imx_clk_pllv1("mpll", "clk32_premult", regs + CCM_MPCTL0);
+ clks[spll] = imx_clk_pllv1("spll", "prem", regs + CCM_SPCTL0);
+ clks[mcu] = imx_clk_divider("mcu", "clk32_premult", regs + CCM_CSCR, 15, 1);
+ clks[fclk] = imx_clk_divider("fclk", "mpll", regs + CCM_CSCR, 15, 1);
+ clks[hclk] = imx_clk_divider("hclk", "spll", regs + CCM_CSCR, 10, 4);
+ clks[clk48m] = imx_clk_divider("clk48m", "spll", regs + CCM_CSCR, 26, 3);
+ clks[per1] = imx_clk_divider("per1", "spll", regs + CCM_PCDR, 0, 4);
+ clks[per2] = imx_clk_divider("per2", "spll", regs + CCM_PCDR, 4, 4);
+ clks[per3] = imx_clk_divider("per3", "spll", regs + CCM_PCDR, 16, 7);
+ clks[clko] = imx_clk_mux("clko", regs + CCM_CSCR, 29, 3, clko_sel_clks,
+ ARRAY_SIZE(clko_sel_clks));
+
+ clkdev_add_physbase(clks[per1], MX1_TIM1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX1_TIM2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2], MX1_LCDC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX1_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX1_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2], MX1_CSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2], MX1_CSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[hclk], MX1_I2C_BASE_ADDR, NULL);
+
+ return 0;
+}
+
+static int imx1_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *regs;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ regs = IOMEM(iores->start);
+
+ mx1_clocks_init(regs, 32000);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx1_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx1_ccm_driver = {
+ .probe = imx1_ccm_probe,
+ .name = "imx1-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx1_ccm_dt_ids),
+};
+
+static int imx1_ccm_init(void)
+{
+ return platform_driver_register(&imx1_ccm_driver);
+}
+core_initcall(imx1_ccm_init);
diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
new file mode 100644
index 0000000..546461b
--- /dev/null
+++ b/drivers/clk/imx/clk-imx21.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx21-regs.h>
+
+#include "clk.h"
+
+/* Register offsets */
+#define CCM_CSCR 0x0
+#define CCM_MPCTL0 0x4
+#define CCM_MPCTL1 0x8
+#define CCM_SPCTL0 0xc
+#define CCM_SPCTL1 0x10
+#define CCM_OSC26MCTL 0x14
+#define CCM_PCDR0 0x18
+#define CCM_PCDR1 0x1c
+#define CCM_PCCR0 0x20
+#define CCM_PCCR1 0x24
+#define CCM_CCSR 0x28
+#define CCM_PMCTL 0x2c
+#define CCM_PMCOUNT 0x30
+#define CCM_WKGDCTL 0x34
+
+#define PCCR0_UART1_EN (1 << 0)
+#define PCCR0_UART2_EN (1 << 1)
+#define PCCR0_UART3_EN (1 << 2)
+#define PCCR0_UART4_EN (1 << 3)
+#define PCCR0_CSPI1_EN (1 << 4)
+#define PCCR0_CSPI2_EN (1 << 5)
+#define PCCR0_SSI1_EN (1 << 6)
+#define PCCR0_SSI2_EN (1 << 7)
+#define PCCR0_FIRI_EN (1 << 8)
+#define PCCR0_SDHC1_EN (1 << 9)
+#define PCCR0_SDHC2_EN (1 << 10)
+#define PCCR0_GPIO_EN (1 << 11)
+#define PCCR0_I2C_EN (1 << 12)
+#define PCCR0_DMA_EN (1 << 13)
+#define PCCR0_USBOTG_EN (1 << 14)
+#define PCCR0_EMMA_EN (1 << 15)
+#define PCCR0_SSI2_BAUD_EN (1 << 16)
+#define PCCR0_SSI1_BAUD_EN (1 << 17)
+#define PCCR0_PERCLK3_EN (1 << 18)
+#define PCCR0_NFC_EN (1 << 19)
+#define PCCR0_FRI_BAUD_EN (1 << 20)
+#define PCCR0_SLDC_EN (1 << 21)
+#define PCCR0_PERCLK4_EN (1 << 22)
+#define PCCR0_HCLK_BMI_EN (1 << 23)
+#define PCCR0_HCLK_USBOTG_EN (1 << 24)
+#define PCCR0_HCLK_SLCDC_EN (1 << 25)
+#define PCCR0_HCLK_LCDC_EN (1 << 26)
+#define PCCR0_HCLK_EMMA_EN (1 << 27)
+#define PCCR0_HCLK_BROM_EN (1 << 28)
+#define PCCR0_HCLK_DMA_EN (1 << 30)
+#define PCCR0_HCLK_CSI_EN (1 << 31)
+
+#define PCCR1_CSPI3_EN (1 << 23)
+#define PCCR1_WDT_EN (1 << 24)
+#define PCCR1_GPT1_EN (1 << 25)
+#define PCCR1_GPT2_EN (1 << 26)
+#define PCCR1_GPT3_EN (1 << 27)
+#define PCCR1_PWM_EN (1 << 28)
+#define PCCR1_RTC_EN (1 << 29)
+#define PCCR1_KPP_EN (1 << 30)
+#define PCCR1_OWIRE_EN (1 << 31)
+
+enum imx21_clks {
+ ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
+ per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, lcdc_ahb_gate,
+ lcdc_ipg_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *mpll_sel_clks[] = {
+ "fpm",
+ "ckih",
+};
+
+static const char *spll_sel_clks[] = {
+ "fpm",
+ "ckih",
+};
+
+static int imx21_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base;
+ unsigned long lref = 32768;
+ unsigned long href = 26000000;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ base = IOMEM(iores->start);
+
+ writel(PCCR0_UART1_EN | PCCR0_UART2_EN | PCCR0_UART3_EN | PCCR0_UART4_EN |
+ PCCR0_CSPI1_EN | PCCR0_CSPI2_EN | PCCR0_SDHC1_EN |
+ PCCR0_SDHC2_EN | PCCR0_GPIO_EN | PCCR0_I2C_EN | PCCR0_DMA_EN |
+ PCCR0_USBOTG_EN | PCCR0_NFC_EN | PCCR0_PERCLK4_EN |
+ PCCR0_HCLK_USBOTG_EN | PCCR0_HCLK_DMA_EN,
+ base + CCM_PCCR0);
+
+ writel(PCCR1_CSPI3_EN | PCCR1_WDT_EN | PCCR1_GPT1_EN | PCCR1_GPT2_EN |
+ PCCR1_GPT3_EN | PCCR1_PWM_EN | PCCR1_RTC_EN | PCCR1_KPP_EN |
+ PCCR1_OWIRE_EN,
+ base + CCM_PCCR1);
+
+ clks[ckil] = clk_fixed("ckil", lref);
+ clks[ckih] = clk_fixed("ckih", href);
+ clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
+ clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
+ ARRAY_SIZE(mpll_sel_clks));
+ clks[spll_sel] = imx_clk_mux("spll_sel", base + CCM_CSCR, 17, 1, spll_sel_clks,
+ ARRAY_SIZE(spll_sel_clks));
+ clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
+ clks[spll] = imx_clk_pllv1("spll", "spll_sel", base + CCM_SPCTL0);
+ clks[fclk] = imx_clk_divider("fclk", "mpll", base + CCM_CSCR, 29, 3);
+ clks[hclk] = imx_clk_divider("hclk", "fclk", base + CCM_CSCR, 10, 4);
+ clks[ipg] = imx_clk_divider("ipg", "hclk", base + CCM_CSCR, 9, 1);
+ clks[per1] = imx_clk_divider("per1", "mpll", base + CCM_PCDR1, 0, 6);
+ clks[per2] = imx_clk_divider("per2", "mpll", base + CCM_PCDR1, 8, 6);
+ clks[per3] = imx_clk_divider("per3", "mpll", base + CCM_PCDR1, 16, 6);
+ clks[per4] = imx_clk_divider("per4", "mpll", base + CCM_PCDR1, 24, 6);
+ clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 26, 3);
+ clks[nfc_div] = imx_clk_divider("nfc_div", "ipg", base + CCM_PCDR0, 12, 4);
+ clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3", base + CCM_PCCR0, 18);
+ clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR0, 26);
+ /*
+ * i.MX21 doesn't have an IPG clock for the LCD. To avoid even more conditionals
+ * in the framebuffer code, provide a dummy clock.
+ */
+ clks[lcdc_ipg_gate] = clk_fixed("dummy", 0);
+
+ clkdev_add_physbase(clks[per1], MX21_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX21_GPT2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX21_GPT3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX21_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX21_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX21_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1], MX21_UART4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2], MX21_CSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2], MX21_CSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2], MX21_CSPI3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX21_I2C_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX21_SDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX21_SDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[lcdc_per_gate], MX21_LCDC_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[lcdc_ahb_gate], MX21_LCDC_BASE_ADDR, "ahb");
+ clkdev_add_physbase(clks[lcdc_ipg_gate], MX21_LCDC_BASE_ADDR, "ipg");
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx21_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx21-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx21_ccm_driver = {
+ .probe = imx21_ccm_probe,
+ .name = "imx21-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx21_ccm_dt_ids),
+};
+
+static int imx21_ccm_init(void)
+{
+ return platform_driver_register(&imx21_ccm_driver);
+}
+core_initcall(imx21_ccm_init);
diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
new file mode 100644
index 0000000..864d06e
--- /dev/null
+++ b/drivers/clk/imx/clk-imx25.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx25-regs.h>
+
+#include "clk.h"
+
+#define CCM_MPCTL 0x00
+#define CCM_UPCTL 0x04
+#define CCM_CCTL 0x08
+#define CCM_CGCR0 0x0C
+#define CCM_CGCR1 0x10
+#define CCM_CGCR2 0x14
+#define CCM_PCDR0 0x18
+#define CCM_PCDR1 0x1C
+#define CCM_PCDR2 0x20
+#define CCM_PCDR3 0x24
+#define CCM_RCSR 0x28
+#define CCM_CRDR 0x2C
+#define CCM_DCVR0 0x30
+#define CCM_DCVR1 0x34
+#define CCM_DCVR2 0x38
+#define CCM_DCVR3 0x3c
+#define CCM_LTR0 0x40
+#define CCM_LTR1 0x44
+#define CCM_LTR2 0x48
+#define CCM_LTR3 0x4c
+#define CCM_MCR 0x64
+
+enum mx25_clks {
+ dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
+ per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
+ per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
+ per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
+ per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
+ csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
+ gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
+ pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
+ uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
+ esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
+ reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg,
+ cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
+ reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
+ gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
+ iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
+ pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
+ sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
+ uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
+ wdt_ipg, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *cpu_sel_clks[] = {
+ "mpll",
+ "mpll_cpu_3_4",
+};
+
+static const char *per_sel_clks[] = {
+ "ahb",
+ "upll",
+};
+
+static int imx25_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ base = IOMEM(iores->start);
+
+ writel((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 8) | (1 << 9) |
+ (1 << 10) | (1 << 15) | (1 << 19) | (1 << 21) | (1 << 22) |
+ (1 << 23) | (1 << 24) | (1 << 28),
+ base + CCM_CGCR0);
+
+ writel((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 13) | (1 << 14) |
+ (1 << 15) | (1 << 19) | (1 << 20) | (1 << 21) | (1 << 22) |
+ (1 << 26) | (1 << 31),
+ base + CCM_CGCR1);
+
+ writel((1 << 0) | (1 << 1) | (1 << 2) | (1 << 10) | (1 << 13) | (1 << 14) |
+ (1 << 15) | (1 << 16) | (1 << 17) | (1 << 18),
+ base + CCM_CGCR2);
+
+ clks[dummy] = clk_fixed("dummy", 0);
+ clks[osc] = clk_fixed("osc", 24000000);
+ clks[mpll] = imx_clk_pllv1("mpll", "osc", base + CCM_MPCTL);
+ clks[upll] = imx_clk_pllv1("upll", "osc", base + CCM_UPCTL);
+ clks[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
+ clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CCTL, 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+ clks[cpu] = imx_clk_divider("cpu", "cpu_sel", base + CCM_CCTL, 30, 2);
+ clks[ahb] = imx_clk_divider("ahb", "cpu", base + CCM_CCTL, 28, 2);
+ clks[usb_div] = imx_clk_divider("usb_div", "upll", base + CCM_CCTL, 16, 6);
+ clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+ clks[per0_sel] = imx_clk_mux("per0_sel", base + CCM_MCR, 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per1_sel] = imx_clk_mux("per1_sel", base + CCM_MCR, 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per2_sel] = imx_clk_mux("per2_sel", base + CCM_MCR, 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per3_sel] = imx_clk_mux("per3_sel", base + CCM_MCR, 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per4_sel] = imx_clk_mux("per4_sel", base + CCM_MCR, 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per5_sel] = imx_clk_mux("per5_sel", base + CCM_MCR, 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per6_sel] = imx_clk_mux("per6_sel", base + CCM_MCR, 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per7_sel] = imx_clk_mux("per7_sel", base + CCM_MCR, 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per8_sel] = imx_clk_mux("per8_sel", base + CCM_MCR, 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per9_sel] = imx_clk_mux("per9_sel", base + CCM_MCR, 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per10_sel] = imx_clk_mux("per10_sel", base + CCM_MCR, 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per11_sel] = imx_clk_mux("per11_sel", base + CCM_MCR, 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per12_sel] = imx_clk_mux("per12_sel", base + CCM_MCR, 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per13_sel] = imx_clk_mux("per13_sel", base + CCM_MCR, 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per14_sel] = imx_clk_mux("per14_sel", base + CCM_MCR, 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per15_sel] = imx_clk_mux("per15_sel", base + CCM_MCR, 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clks[per0] = imx_clk_divider("per0", "per0_sel", base + CCM_PCDR0, 0, 6);
+ clks[per1] = imx_clk_divider("per1", "per1_sel", base + CCM_PCDR0, 8, 6);
+ clks[per2] = imx_clk_divider("per2", "per2_sel", base + CCM_PCDR0, 16, 6);
+ clks[per3] = imx_clk_divider("per3", "per3_sel", base + CCM_PCDR0, 24, 6);
+ clks[per4] = imx_clk_divider("per4", "per4_sel", base + CCM_PCDR1, 0, 6);
+ clks[per5] = imx_clk_divider("per5", "per5_sel", base + CCM_PCDR1, 8, 6);
+ clks[per6] = imx_clk_divider("per6", "per6_sel", base + CCM_PCDR1, 16, 6);
+ clks[per7] = imx_clk_divider("per7", "per7_sel", base + CCM_PCDR1, 24, 6);
+ clks[per8] = imx_clk_divider("per8", "per8_sel", base + CCM_PCDR2, 0, 6);
+ clks[per9] = imx_clk_divider("per9", "per9_sel", base + CCM_PCDR2, 8, 6);
+ clks[per10] = imx_clk_divider("per10", "per10_sel", base + CCM_PCDR2, 16, 6);
+ clks[per11] = imx_clk_divider("per11", "per11_sel", base + CCM_PCDR2, 24, 6);
+ clks[per12] = imx_clk_divider("per12", "per12_sel", base + CCM_PCDR3, 0, 6);
+ clks[per13] = imx_clk_divider("per13", "per13_sel", base + CCM_PCDR3, 8, 6);
+ clks[per14] = imx_clk_divider("per14", "per14_sel", base + CCM_PCDR3, 16, 6);
+ clks[per15] = imx_clk_divider("per15", "per15_sel", base + CCM_PCDR3, 24, 6);
+ clks[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", base + CCM_CGCR0, 24);
+ clks[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", base + CCM_CGCR1, 29);
+ clks[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", base + CCM_CGCR0, 7);
+
+ clkdev_add_physbase(clks[per15], MX25_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per15], MX25_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per15], MX25_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per15], MX25_UART4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per15], MX25_UART5_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per5], MX25_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per5], MX25_GPT2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per5], MX25_GPT3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per5], MX25_GPT4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_FEC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_I2C3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_CSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_CSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX25_CSPI3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per3], MX25_ESDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per4], MX25_ESDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per8], MX25_NFC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[lcdc_ipg_per], MX25_LCDC_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[lcdc_ipg], MX25_LCDC_BASE_ADDR, "ipg");
+ clkdev_add_physbase(clks[lcdc_ahb], MX25_LCDC_BASE_ADDR, "ahb");
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx25_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx25-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx25_ccm_driver = {
+ .probe = imx25_ccm_probe,
+ .name = "imx25-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx25_ccm_dt_ids),
+};
+
+static int imx25_ccm_init(void)
+{
+ return platform_driver_register(&imx25_ccm_driver);
+}
+core_initcall(imx25_ccm_init);
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
new file mode 100644
index 0000000..4b63244
--- /dev/null
+++ b/drivers/clk/imx/clk-imx27.c
@@ -0,0 +1,270 @@
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx27-regs.h>
+#include <mach/generic.h>
+#include <mach/revision.h>
+
+#include "clk.h"
+
+/* Register offsets */
+#define CCM_CSCR 0x0
+#define CCM_MPCTL0 0x4
+#define CCM_MPCTL1 0x8
+#define CCM_SPCTL0 0xc
+#define CCM_SPCTL1 0x10
+#define CCM_OSC26MCTL 0x14
+#define CCM_PCDR0 0x18
+#define CCM_PCDR1 0x1c
+#define CCM_PCCR0 0x20
+#define CCM_PCCR1 0x24
+#define CCM_CCSR 0x28
+#define CCM_PMCTL 0x2c
+#define CCM_PMCOUNT 0x30
+#define CCM_WKGDCTL 0x34
+
+#define PCCR0_SSI2_EN (1 << 0)
+#define PCCR0_SSI1_EN (1 << 1)
+#define PCCR0_SLCDC_EN (1 << 2)
+#define PCCR0_SDHC3_EN (1 << 3)
+#define PCCR0_SDHC2_EN (1 << 4)
+#define PCCR0_SDHC1_EN (1 << 5)
+#define PCCR0_SDC_EN (1 << 6)
+#define PCCR0_SAHARA_EN (1 << 7)
+#define PCCR0_RTIC_EN (1 << 8)
+#define PCCR0_RTC_EN (1 << 9)
+#define PCCR0_PWM_EN (1 << 11)
+#define PCCR0_OWIRE_EN (1 << 12)
+#define PCCR0_MSHC_EN (1 << 13)
+#define PCCR0_LCDC_EN (1 << 14)
+#define PCCR0_KPP_EN (1 << 15)
+#define PCCR0_IIM_EN (1 << 16)
+#define PCCR0_I2C2_EN (1 << 17)
+#define PCCR0_I2C1_EN (1 << 18)
+#define PCCR0_GPT6_EN (1 << 19)
+#define PCCR0_GPT5_EN (1 << 20)
+#define PCCR0_GPT4_EN (1 << 21)
+#define PCCR0_GPT3_EN (1 << 22)
+#define PCCR0_GPT2_EN (1 << 23)
+#define PCCR0_GPT1_EN (1 << 24)
+#define PCCR0_GPIO_EN (1 << 25)
+#define PCCR0_FEC_EN (1 << 26)
+#define PCCR0_EMMA_EN (1 << 27)
+#define PCCR0_DMA_EN (1 << 28)
+#define PCCR0_CSPI3_EN (1 << 29)
+#define PCCR0_CSPI2_EN (1 << 30)
+#define PCCR0_CSPI1_EN (1 << 31)
+
+#define PCCR1_MSHC_BAUDEN (1 << 2)
+#define PCCR1_NFC_BAUDEN (1 << 3)
+#define PCCR1_SSI2_BAUDEN (1 << 4)
+#define PCCR1_SSI1_BAUDEN (1 << 5)
+#define PCCR1_H264_BAUDEN (1 << 6)
+#define PCCR1_PERCLK4_EN (1 << 7)
+#define PCCR1_PERCLK3_EN (1 << 8)
+#define PCCR1_PERCLK2_EN (1 << 9)
+#define PCCR1_PERCLK1_EN (1 << 10)
+#define PCCR1_HCLK_USB (1 << 11)
+#define PCCR1_HCLK_SLCDC (1 << 12)
+#define PCCR1_HCLK_SAHARA (1 << 13)
+#define PCCR1_HCLK_RTIC (1 << 14)
+#define PCCR1_HCLK_LCDC (1 << 15)
+#define PCCR1_HCLK_H264 (1 << 16)
+#define PCCR1_HCLK_FEC (1 << 17)
+#define PCCR1_HCLK_EMMA (1 << 18)
+#define PCCR1_HCLK_EMI (1 << 19)
+#define PCCR1_HCLK_DMA (1 << 20)
+#define PCCR1_HCLK_CSI (1 << 21)
+#define PCCR1_HCLK_BROM (1 << 22)
+#define PCCR1_HCLK_ATA (1 << 23)
+#define PCCR1_WDT_EN (1 << 24)
+#define PCCR1_USB_EN (1 << 25)
+#define PCCR1_UART6_EN (1 << 26)
+#define PCCR1_UART5_EN (1 << 27)
+#define PCCR1_UART4_EN (1 << 28)
+#define PCCR1_UART3_EN (1 << 29)
+#define PCCR1_UART2_EN (1 << 30)
+#define PCCR1_UART1_EN (1 << 31)
+
+enum mx27_clks {
+ dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
+ per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
+ clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
+ clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
+ sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
+ rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
+ kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
+ gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
+ gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
+ emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
+ cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
+ vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
+ usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
+ vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
+ csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
+ uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
+ uart2_ipg_gate, uart1_ipg_gate, ckih_div1p5, fpm, mpll_osc_sel,
+ mpll_sel, spll_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *cpu_sel_clks[] = {
+ "mpll_main2",
+ "mpll",
+};
+
+static const char *mpll_sel_clks[] = {
+ "fpm",
+ "mpll_osc_sel",
+};
+
+static const char *mpll_osc_sel_clks[] = {
+ "ckih",
+ "ckih_div1p5",
+};
+
+static const char *clko_sel_clks[] = {
+ "ckil",
+ NULL,
+ "ckih",
+ "ckih",
+ "ckih",
+ "mpll",
+ "spll",
+ "cpu_div",
+ "ahb",
+ "ipg",
+ "per1_div",
+ "per2_div",
+ "per3_div",
+ "per4_div",
+ NULL,
+ NULL,
+ "nfc_div",
+ NULL,
+ NULL,
+ NULL,
+ "ckil",
+ "usb_div",
+ NULL,
+};
+
+static int imx27_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ base = IOMEM(iores->start);
+
+ writel(PCCR0_SDHC3_EN | PCCR0_SDHC2_EN | PCCR0_SDHC1_EN |
+ PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_IIM_EN |
+ PCCR0_I2C2_EN | PCCR0_I2C1_EN | PCCR0_GPT6_EN | PCCR0_GPT5_EN |
+ PCCR0_GPT4_EN | PCCR0_GPT3_EN | PCCR0_GPT2_EN | PCCR0_GPT1_EN |
+ PCCR0_GPIO_EN | PCCR0_FEC_EN | PCCR0_CSPI3_EN | PCCR0_CSPI2_EN |
+ PCCR0_CSPI1_EN,
+ base + CCM_PCCR0);
+
+ writel(PCCR1_NFC_BAUDEN | PCCR1_PERCLK4_EN | PCCR1_PERCLK2_EN | PCCR1_PERCLK1_EN |
+ PCCR1_HCLK_USB | PCCR1_HCLK_FEC | PCCR1_HCLK_EMI | PCCR1_WDT_EN |
+ PCCR1_USB_EN | PCCR1_UART6_EN | PCCR1_UART5_EN | PCCR1_UART4_EN |
+ PCCR1_UART3_EN | PCCR1_UART2_EN | PCCR1_UART1_EN,
+ base + CCM_PCCR1);
+
+ clks[dummy] = clk_fixed("dummy", 0);
+ clks[ckih] = clk_fixed("ckih", 26000000);
+ clks[ckil] = clk_fixed("ckil", 32768);
+ clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
+ clks[ckih_div1p5] = imx_clk_fixed_factor("ckih_div1p5", "ckih", 2, 3);
+
+ clks[mpll_osc_sel] = imx_clk_mux("mpll_osc_sel", base + CCM_CSCR, 4, 1,
+ mpll_osc_sel_clks,
+ ARRAY_SIZE(mpll_osc_sel_clks));
+ clks[mpll_sel] = imx_clk_mux("mpll_sel", base + CCM_CSCR, 16, 1, mpll_sel_clks,
+ ARRAY_SIZE(mpll_sel_clks));
+
+ clks[mpll] = imx_clk_pllv1("mpll", "mpll_sel", base + CCM_MPCTL0);
+ clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SPCTL0);
+ clks[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
+
+ if (imx_silicon_revision() >= IMX_CHIP_REV_2_0) {
+ clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 8, 2);
+ clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+ } else {
+ clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 9, 4);
+ clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_CSCR, 8, 1);
+ }
+
+ clks[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + CCM_PCDR0, 6, 4);
+ clks[per1_div] = imx_clk_divider("per1_div", "mpll_main2", base + CCM_PCDR1, 0, 6);
+ clks[per2_div] = imx_clk_divider("per2_div", "mpll_main2", base + CCM_PCDR1, 8, 6);
+ clks[per3_div] = imx_clk_divider("per3_div", "mpll_main2", base + CCM_PCDR1, 16, 6);
+ clks[per4_div] = imx_clk_divider("per4_div", "mpll_main2", base + CCM_PCDR1, 24, 6);
+ clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 28, 3);
+ clks[cpu_sel] = imx_clk_mux("cpu_sel", base + CCM_CSCR, 15, 1, cpu_sel_clks,
+ ARRAY_SIZE(cpu_sel_clks));
+ clks[clko_sel] = imx_clk_mux("clko_sel", base + CCM_CCSR, 0, 5, clko_sel_clks,
+ ARRAY_SIZE(clko_sel_clks));
+ if (imx_silicon_revision() >= IMX_CHIP_REV_2_0)
+ clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 12, 2);
+ else
+ clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 13, 3);
+ clks[clko_div] = imx_clk_divider("clko_div", "clko_sel", base + CCM_PCDR0, 22, 3);
+ clks[per3_gate] = imx_clk_gate("per3_gate", "per3_div", base + CCM_PCCR1, 8);
+ clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR1, 15);
+ clks[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", base + CCM_PCCR0, 14);
+
+ clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_GPT3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_GPT4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_GPT5_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_GPT6_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_UART4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_UART5_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per1_div], MX27_UART6_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX27_CSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX27_CSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX27_CSPI3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX27_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX27_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2_div], MX27_SDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2_div], MX27_SDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per2_div], MX27_SDHC3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per3_gate], MX27_LCDC_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[lcdc_ahb_gate], MX27_LCDC_BASE_ADDR, "ahb");
+ clkdev_add_physbase(clks[lcdc_ipg_gate], MX27_LCDC_BASE_ADDR, "ipg");
+ clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx27_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx27-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx27_ccm_driver = {
+ .probe = imx27_ccm_probe,
+ .name = "imx27-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx27_ccm_dt_ids),
+};
+
+static int imx27_ccm_init(void)
+{
+ return platform_driver_register(&imx27_ccm_driver);
+}
+core_initcall(imx27_ccm_init);
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
new file mode 100644
index 0000000..8d135c9
--- /dev/null
+++ b/drivers/clk/imx/clk-imx31.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx31-regs.h>
+
+#include "clk.h"
+
+/* Register addresses */
+#define CCM_CCMR 0x00
+#define CCM_PDR0 0x04
+#define CCM_PDR1 0x08
+//#define CCM_RCSR 0x0C
+#define CCM_MPCTL 0x10
+#define CCM_UPCTL 0x14
+#define CCM_SRPCTL 0x18
+#define CCM_COSR 0x1C
+#define CCM_CGR0 0x20
+#define CCM_CGR1 0x24
+#define CCM_CGR2 0x28
+#define CCM_WIMR 0x2C
+#define CCM_LDC 0x30
+#define CCM_DCVR0 0x34
+#define CCM_DCVR1 0x38
+#define CCM_DCVR2 0x3C
+#define CCM_DCVR3 0x40
+#define CCM_LTR0 0x44
+#define CCM_LTR1 0x48
+#define CCM_LTR2 0x4C
+#define CCM_LTR3 0x50
+#define CCM_LTBR0 0x54
+#define CCM_LTBR1 0x58
+#define CCM_PMCR0 0x5C
+#define CCM_PMCR1 0x60
+#define CCM_PDR2 0x64
+
+enum mx31_clks {
+ ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
+ per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
+ fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
+ iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
+ uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
+ mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
+ sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
+ uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
+ gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *mcu_main_sel[] = {
+ "spll",
+ "mpll",
+};
+
+static const char *per_sel[] = {
+ "per_div",
+ "ipg",
+};
+
+static int imx31_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ base = IOMEM(iores->start);
+
+ writel(0xffffffff, base + CCM_CGR0);
+ writel(0xffffffff, base + CCM_CGR1);
+ writel(0xffffffff, base + CCM_CGR2);
+
+ clks[ckih] = clk_fixed("ckih", 26000000);
+ clks[ckil] = clk_fixed("ckil", 32768);
+ clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
+ clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SRPCTL);
+ clks[upll] = imx_clk_pllv1("upll", "ckih", base + CCM_UPCTL);
+ clks[mcu_main] = imx_clk_mux("mcu_main", base + CCM_PMCR0, 31, 1,
+ mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
+ clks[hsp] = imx_clk_divider("hsp", "mcu_main", base + CCM_PDR0, 11, 3);
+ clks[ahb] = imx_clk_divider("ahb", "mcu_main", base + CCM_PDR0, 3, 3);
+ clks[nfc] = imx_clk_divider("nfc", "ahb", base + CCM_PDR0, 8, 3);
+ clks[ipg] = imx_clk_divider("ipg", "ahb", base + CCM_PDR0, 6, 2);
+ clks[per_div] = imx_clk_divider("per_div", "upll", base + CCM_PDR0, 16, 5);
+ clks[per] = imx_clk_mux("per", base + CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
+
+ clkdev_add_physbase(clks[per], MX31_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_UART4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_UART5_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_I2C3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX31_CSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX31_CSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX31_CSPI3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_SDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_SDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[per], MX31_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[hsp], MX31_IPU_CTRL_BASE_ADDR, NULL);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx31-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx31_ccm_driver = {
+ .probe = imx31_ccm_probe,
+ .name = "imx31-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids),
+};
+
+static int imx31_ccm_init(void)
+{
+ return platform_driver_register(&imx31_ccm_driver);
+}
+core_initcall(imx31_ccm_init);
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
new file mode 100644
index 0000000..af6c405
--- /dev/null
+++ b/drivers/clk/imx/clk-imx35.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx35-regs.h>
+#include <reset_source.h>
+
+#include "clk.h"
+
+#define CCM_CCMR 0x00
+#define CCM_PDR0 0x04
+#define CCM_PDR1 0x08
+#define CCM_PDR2 0x0C
+#define CCM_PDR3 0x10
+#define CCM_PDR4 0x14
+#define CCM_RCSR 0x18
+#define CCM_MPCTL 0x1C
+#define CCM_PPCTL 0x20
+#define CCM_ACMR 0x24
+#define CCM_COSR 0x28
+#define CCM_CGR0 0x2C
+#define CCM_CGR1 0x30
+#define CCM_CGR2 0x34
+#define CCM_CGR3 0x38
+
+struct arm_ahb_div {
+ unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+ { .arm = 1, .ahb = 4, .sel = 0},
+ { .arm = 1, .ahb = 3, .sel = 1},
+ { .arm = 2, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 1, .sel = 0},
+ { .arm = 1, .ahb = 5, .sel = 0},
+ { .arm = 1, .ahb = 8, .sel = 0},
+ { .arm = 1, .ahb = 6, .sel = 1},
+ { .arm = 2, .ahb = 4, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static char hsp_div_532[] = { 4, 8, 3, 0 };
+static char hsp_div_400[] = { 3, 6, 3, 0 };
+
+enum mx35_clks {
+ ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
+ arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
+ esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
+ spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
+ ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
+ audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
+ edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
+ esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
+ gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
+ kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
+ rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
+ ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
+ wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
+ clk_max
+};
+
+static struct clk *clks[clk_max];
+
+static const char *std_sel[] = {
+ "ppll",
+ "arm",
+};
+
+static const char *ipg_per_sel[] = {
+ "ahb_per_div",
+ "arm_per_div",
+};
+
+static int imx35_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ u32 pdr0, consumer_sel, hsp_sel;
+ struct arm_ahb_div *aad;
+ unsigned char *hsp_div;
+ void __iomem *base;
+ u32 reg;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ base = IOMEM(iores->start);
+
+ /* Check reset source */
+ reg = readl(base + CCM_RCSR);
+
+ switch (reg & 0x0F) {
+ case 0x00:
+ reset_source_set_priority(RESET_POR, 200);
+ break;
+ case 0x02:
+ reset_source_set_priority(RESET_JTAG, 200);
+ break;
+ case 0x04:
+ reset_source_set_priority(RESET_RST, 200);
+ break;
+ case 0x08:
+ reset_source_set_priority(RESET_WDG, 200);
+ break;
+ }
+
+ writel(0xffffffff, base + CCM_CGR0);
+ writel(0xffffffff, base + CCM_CGR1);
+ writel(0xfbffffff, base + CCM_CGR2);
+ writel(0xffffffff, base + CCM_CGR3);
+
+ pdr0 = __raw_readl(base + CCM_PDR0);
+ consumer_sel = (pdr0 >> 16) & 0xf;
+ aad = &clk_consumer[consumer_sel];
+ if (!aad->arm) {
+ pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
+ /*
+ * We are basically stuck. Continue with a default entry and hope we
+ * get far enough to actually show the above message
+ */
+ aad = &clk_consumer[0];
+ }
+
+ clks[ckih] = clk_fixed("ckih", 24000000);
+ clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
+ clks[ppll] = imx_clk_pllv1("ppll", "ckih", base + CCM_PPCTL);
+
+ clks[mpll_075] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
+
+ if (aad->sel)
+ clks[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
+ else
+ clks[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
+
+ if (clk_get_rate(clks[arm]) > 400000000)
+ hsp_div = hsp_div_532;
+ else
+ hsp_div = hsp_div_400;
+
+ hsp_sel = (pdr0 >> 20) & 0x3;
+ if (!hsp_div[hsp_sel]) {
+ pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
+ hsp_sel = 0;
+ }
+
+ clks[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
+
+ clks[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
+ clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+
+ clks[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + CCM_PDR4, 16, 6);
+ clks[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + CCM_PDR0, 12, 3);
+ clks[ipg_per] = imx_clk_mux("ipg_per", base + CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
+
+ clks[uart_sel] = imx_clk_mux("uart_sel", base + CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
+ clks[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + CCM_PDR4, 10, 6);
+
+ clks[esdhc_sel] = imx_clk_mux("esdhc_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+ clks[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + CCM_PDR3, 0, 6);
+ clks[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + CCM_PDR3, 8, 6);
+ clks[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + CCM_PDR3, 16, 6);
+
+ clks[usb_sel] = imx_clk_mux("usb_sel", base + CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+ clks[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + CCM_PDR4, 22, 6);
+
+ clkdev_add_physbase(clks[uart_div], MX35_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[uart_div], MX35_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[uart_div], MX35_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg_per], MX35_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg_per], MX35_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg_per], MX35_I2C3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX35_CSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX35_CSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX35_FEC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[ipg], MX35_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[esdhc1_div], MX35_ESDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[esdhc2_div], MX35_ESDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[esdhc3_div], MX35_ESDHC3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[hsp], MX35_IPU_CTRL_BASE_ADDR, NULL);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx35_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx35-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx35_ccm_driver = {
+ .probe = imx35_ccm_probe,
+ .name = "imx35-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx35_ccm_dt_ids),
+};
+
+static int imx35_ccm_init(void)
+{
+ return platform_driver_register(&imx35_ccm_driver);
+}
+core_initcall(imx35_ccm_init);
diff --git a/drivers/clk/imx/clk-imx5.c b/drivers/clk/imx/clk-imx5.c
new file mode 100644
index 0000000..c4c47a6
--- /dev/null
+++ b/drivers/clk/imx/clk-imx5.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx50-regs.h>
+#include <mach/imx51-regs.h>
+#include <mach/imx53-regs.h>
+#include <dt-bindings/clock/imx5-clock.h>
+
+#include "clk.h"
+
+/* Register addresses of CCM*/
+#define CCM_CCR 0x00
+#define CCM_CCDR 0x04
+#define CCM_CSR 0x08
+#define CCM_CCSR 0x0C
+#define CCM_CACRR 0x10
+#define CCM_CBCDR 0x14
+#define CCM_CBCMR 0x18
+#define CCM_CSCMR1 0x1C
+#define CCM_CSCMR2 0x20
+#define CCM_CSCDR1 0x24
+#define CCM_CS1CDR 0x28
+#define CCM_CS2CDR 0x2C
+#define CCM_CDCDR 0x30
+#define CCM_CHSCDR 0x34
+#define CCM_CSCDR2 0x38
+#define CCM_CSCDR3 0x3C
+#define CCM_CSCDR4 0x40
+#define CCM_CWDR 0x44
+#define CCM_CDHIPR 0x48
+#define CCM_CDCR 0x4C
+#define CCM_CTOR 0x50
+#define CCM_CLPCR 0x54
+#define CCM_CISR 0x58
+#define CCM_CIMR 0x5C
+#define CCM_CCOSR 0x60
+#define CCM_CGPR 0x64
+#define CCM_CCGR0 0x68
+#define CCM_CCGR1 0x6C
+#define CCM_CCGR2 0x70
+#define CCM_CCGR3 0x74
+#define CCM_CCGR4 0x78
+#define CCM_CCGR5 0x7C
+#define CCM_CCGR6 0x80
+#define CCM_CCGR7 0x84
+
+#define CCM_CMEOR 0x84
+
+static struct clk *clks[IMX5_CLK_END];
+
+/* This is used multiple times */
+static const char *standard_pll_sel[] = {
+ "pll1_sw",
+ "pll2_sw",
+ "pll3_sw",
+ "lp_apm",
+};
+
+static const char *mx50_3bit_clk_sel[] = {
+ "pll1_sw",
+ "pll2_sw",
+ "pll3_sw",
+ "lp_apm",
+ "pfd0",
+ "pfd1",
+ "pfd4",
+ "osc",
+};
+
+static const char *lp_apm_sel[] = {
+ "osc",
+};
+
+static const char *periph_apm_sel[] = {
+ "pll1_sw",
+ "pll3_sw",
+ "lp_apm",
+};
+
+static const char *main_bus_sel[] = {
+ "pll2_sw",
+ "periph_apm",
+};
+
+static const char *mx50_periph_clk_sel[] = {
+ "pll1_sw",
+ "pll2_sw",
+ "pll3_sw",
+ "lp_apm",
+};
+
+static const char *per_lp_apm_sel[] = {
+ "main_bus",
+ "lp_apm",
+};
+
+static const char *per_root_sel[] = {
+ "per_podf",
+ "ipg",
+};
+
+static const char *esdhc_c_sel[] = {
+ "esdhc_a_podf",
+ "esdhc_b_podf",
+};
+
+static const char *esdhc_d_sel[] = {
+ "esdhc_a_podf",
+ "esdhc_b_podf",
+};
+
+static const char *emi_slow_sel[] = {
+ "main_bus",
+ "ahb",
+};
+
+static const char *usb_phy_sel_str[] = {
+ "osc",
+ "usb_phy_podf",
+};
+
+static const char *mx51_ipu_di0_sel[] = {
+ "di_pred",
+ "osc",
+ "ckih1",
+ "tve_di",
+};
+
+static const char *mx53_ipu_di0_sel[] = {
+ "di_pred",
+ "osc",
+ "ckih1",
+ "di_pll4_podf",
+ "dummy",
+ "ldb_di0_div",
+};
+
+static const char *mx53_ldb_di0_sel[] = {
+ "pll3_sw",
+ "pll4_sw",
+};
+
+static const char *mx51_ipu_di1_sel[] = {
+ "di_pred",
+ "osc",
+ "ckih1",
+ "tve_di",
+ "ipp_di1",
+};
+
+static const char *mx53_ipu_di1_sel[] = {
+ "di_pred",
+ "osc",
+ "ckih1",
+ "tve_di",
+ "ipp_di1",
+ "ldb_di1_div",
+};
+
+static const char *mx53_ldb_di1_sel[] = {
+ "pll3_sw",
+ "pll4_sw",
+};
+
+static const char *mx51_tve_ext_sel[] = {
+ "osc",
+ "ckih1",
+};
+
+static const char *mx53_tve_ext_sel[] = {
+ "pll4_sw",
+ "ckih1",
+};
+
+static const char *mx51_tve_sel[] = {
+ "tve_pred",
+ "tve_ext_sel",
+};
+
+static const char *ipu_sel[] = {
+ "axi_a",
+ "axi_b",
+ "emi_slow_gate",
+ "ahb",
+};
+
+static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *base)
+{
+ writel(0xffffffff, base + CCM_CCGR0);
+ writel(0xffffffff, base + CCM_CCGR1);
+ writel(0xffffffff, base + CCM_CCGR2);
+ writel(0xffffffff, base + CCM_CCGR3);
+ writel(0xffffffff, base + CCM_CCGR4);
+ writel(0xffffffff, base + CCM_CCGR5);
+ writel(0xffffffff, base + CCM_CCGR6);
+ writel(0xffffffff, base + CCM_CCGR7);
+
+ if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
+ clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768);
+ clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000);
+ }
+
+ clks[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", base + CCM_CBCMR, 1, 1,
+ per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
+ clks[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", base + CCM_CBCDR, 6, 2);
+ clks[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", base + CCM_CBCDR, 3, 3);
+ clks[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", base + CCM_CBCDR, 0, 3);
+ clks[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", base + CCM_CBCMR, 0, 1,
+ per_root_sel, ARRAY_SIZE(per_root_sel));
+ clks[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", base + CCM_CBCDR, 10, 3);
+ clks[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + CCM_CBCDR, 8, 2);
+ clks[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", base + CCM_CBCDR, 16, 3);
+ clks[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", base + CCM_CBCDR, 19, 3);
+ clks[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + CCM_CSCMR1, 24, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clks[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", base + CCM_CSCDR1, 3, 3);
+ clks[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", base + CCM_CSCDR1, 0, 3);
+ clks[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred",
+ "esdhc_a_sel", base + CCM_CSCDR1, 16, 3);
+ clks[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf",
+ "esdhc_a_pred", base + CCM_CSCDR1, 11, 3);
+ clks[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred",
+ "esdhc_b_sel", base + CCM_CSCDR1, 22, 3);
+ clks[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf",
+ "esdhc_b_pred", base + CCM_CSCDR1, 19, 3);
+ clks[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + CCM_CSCMR1,
+ 4, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clks[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred",
+ "ecspi_sel", base + CCM_CSCDR2, 25, 3);
+ clks[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf",
+ "ecspi_pred", base + CCM_CSCDR2, 19, 6);
+ clks[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf",
+ "pll1_sw", base + CCM_CACRR, 0, 3);
+}
+
+static void mx5_clocks_mx51_mx53_init(void __iomem *base)
+{
+ clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", base + CCM_CCSR, 9, 1,
+ lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+ clks[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", base + CCM_CBCMR, 12, 2,
+ periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
+ clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", base + CCM_CBCDR, 25, 1,
+ main_bus_sel, ARRAY_SIZE(main_bus_sel));
+ clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", base + CCM_CSCMR1, 20, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", base + CCM_CSCMR1, 16, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", base + CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+ clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", base + CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+ clks[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", base + CCM_CBCDR, 26, 1,
+ emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
+ clks[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", base + CCM_CBCDR, 22, 3);
+ clks[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", base + CCM_CBCDR, 13, 3);
+ clks[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", base + CCM_CSCMR1, 22, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clks[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", base + CCM_CSCDR1, 8, 3);
+ clks[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", base + CCM_CSCDR1, 6, 2);
+ clks[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", base + CCM_CDCDR, 3, 3);
+ clks[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", base + CCM_CDCDR, 0, 3);
+ clks[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", base + CCM_CSCMR1, 26, 1,
+ usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
+}
+
+static void mx5_clocks_ipu_init(void __iomem *regs)
+{
+ clks[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", regs + CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
+}
+
+int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs)
+{
+ clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc",
+ (void *)MX50_PLL1_BASE_ADDR);
+ clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc",
+ (void *)MX50_PLL2_BASE_ADDR);
+ clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc",
+ (void *)MX50_PLL3_BASE_ADDR);
+
+ mx5_clocks_common_init(dev, regs);
+
+ clks[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", regs + CCM_CCSR, 10, 1, lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+ clks[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", regs + CCM_CBCDR, 25, 2, mx50_periph_clk_sel, ARRAY_SIZE(mx50_periph_clk_sel));
+ clks[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", regs + CCM_CSCMR1, 21, 2, standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clks[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", regs + CCM_CSCMR1, 16, 3, mx50_3bit_clk_sel, ARRAY_SIZE(mx50_3bit_clk_sel));
+ clks[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", regs + CCM_CSCMR1, 20, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+ clks[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", regs + CCM_CSCMR1, 19, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX50_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_I2C3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_CSPI_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX50_ECSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX50_FEC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX50_ESDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX50_ESDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX50_ESDHC3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX50_ESDHC4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per");
+
+ return 0;
+}
+
+static int imx50_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *regs;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ regs = IOMEM(iores->start);
+
+ mx50_clocks_init(dev, regs);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx50_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx50-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx50_ccm_driver = {
+ .probe = imx50_ccm_probe,
+ .name = "imx50-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx50_ccm_dt_ids),
+};
+
+static void mx51_clocks_ipu_init(void __iomem *regs)
+{
+ clks[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
+ mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
+ clks[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
+ mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
+ clks[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
+ mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
+ clks[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", regs + CCM_CSCMR1, 7, 1,
+ mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
+ clks[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", regs + CCM_CDCDR, 28, 3);
+
+ mx5_clocks_ipu_init(regs);
+
+ clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX51_IPU_BASE_ADDR, "bus");
+ clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX51_IPU_BASE_ADDR, "di0");
+ clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX51_IPU_BASE_ADDR, "di1");
+}
+
+int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs)
+{
+ clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX51_PLL1_BASE_ADDR);
+ clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX51_PLL2_BASE_ADDR);
+ clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX51_PLL3_BASE_ADDR);
+
+ mx5_clocks_common_init(dev, regs);
+ mx5_clocks_mx51_mx53_init(regs);
+
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX51_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_CSPI_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX51_ECSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_MXC_FEC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX51_MMC_SDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX51_MMC_SDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX51_MMC_SDHC3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX51_MMC_SDHC4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_ATA_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM1_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM2_BASE_ADDR, "per");
+
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+ mx51_clocks_ipu_init(regs);
+
+ return 0;
+}
+
+static int imx51_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *regs;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ regs = IOMEM(iores->start);
+
+ mx51_clocks_init(dev, regs);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx51_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx51-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx51_ccm_driver = {
+ .probe = imx51_ccm_probe,
+ .name = "imx51-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx51_ccm_dt_ids),
+};
+
+static void mx53_clocks_ipu_init(void __iomem *regs)
+{
+ clks[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clks[IMX5_CLK_LDB_DI1_DIV] = imx_clk_divider_np("ldb_di1_div", "ldb_di1_div_3_5", regs + CCM_CSCMR2, 11, 1);
+ clks[IMX5_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", regs + CCM_CSCMR2, 9, 1,
+ mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
+ clks[IMX5_CLK_DI_PLL4_PODF] = imx_clk_divider("di_pll4_podf", "pll4_sw", regs + CCM_CDCDR, 16, 3);
+ clks[IMX5_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX5_CLK_LDB_DI0_DIV] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", regs + CCM_CSCMR2, 10, 1);
+ clks[IMX5_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", regs + CCM_CSCMR2, 8, 1,
+ mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
+ clks[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_p("ipu_di0_sel", regs + CCM_CSCMR2, 26, 3,
+ mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
+ clks[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_p("ipu_di1_sel", regs + CCM_CSCMR2, 29, 3,
+ mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
+ clks[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_p("tve_ext_sel", regs + CCM_CSCMR1, 6, 1,
+ mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
+ clks[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", regs + CCM_CDCDR, 28, 3);
+
+ mx5_clocks_ipu_init(regs);
+
+ clkdev_add_physbase(clks[IMX5_CLK_IPU_SEL], MX53_IPU_BASE_ADDR, "bus");
+ clkdev_add_physbase(clks[IMX5_CLK_IPU_DI0_SEL], MX53_IPU_BASE_ADDR, "di0");
+ clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX53_IPU_BASE_ADDR, "di1");
+}
+
+int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs)
+{
+ clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX53_PLL1_BASE_ADDR);
+ clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX53_PLL2_BASE_ADDR);
+ clks[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", (void *)MX53_PLL3_BASE_ADDR);
+ clks[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", (void *)MX53_PLL4_BASE_ADDR);
+
+ mx5_clocks_common_init(dev, regs);
+ mx5_clocks_mx51_mx53_init(regs);
+
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_UART_ROOT], MX53_UART5_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_I2C3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_GPT1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_CSPI_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ECSPI_PODF], MX53_ECSPI2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_IPG], MX53_FEC_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_A_PODF], MX53_ESDHC1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_C_SEL], MX53_ESDHC2_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_B_PODF], MX53_ESDHC3_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_ESDHC_D_SEL], MX53_ESDHC4_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_AHB], MX53_SATA_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM1_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM2_BASE_ADDR, "per");
+
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+ mx53_clocks_ipu_init(regs);
+
+ return 0;
+}
+
+static int imx53_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *regs;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ regs = IOMEM(iores->start);
+
+ mx53_clocks_init(dev, regs);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx53_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx53-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx53_ccm_driver = {
+ .probe = imx53_ccm_probe,
+ .name = "imx53-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx53_ccm_dt_ids),
+};
+
+static int imx5_ccm_init(void)
+{
+ if (IS_ENABLED(CONFIG_ARCH_IMX50))
+ platform_driver_register(&imx50_ccm_driver);
+ if (IS_ENABLED(CONFIG_ARCH_IMX51))
+ platform_driver_register(&imx51_ccm_driver);
+ if (IS_ENABLED(CONFIG_ARCH_IMX53))
+ platform_driver_register(&imx53_ccm_driver);
+
+ return 0;
+}
+core_initcall(imx5_ccm_init);
diff --git a/drivers/clk/imx/clk-imx6.c b/drivers/clk/imx/clk-imx6.c
new file mode 100644
index 0000000..8ac43be
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6.c
@@ -0,0 +1,541 @@
+/*
+ * 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>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#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 <dt-bindings/clock/imx6qdl-clock.h>
+
+#include "clk.h"
+
+#define CCGR0 0x68
+#define CCGR1 0x6c
+#define CCGR2 0x70
+#define CCGR3 0x74
+#define CCGR4 0x78
+#define CCGR5 0x7c
+#define CCGR6 0x80
+#define CCGR7 0x84
+
+#define CLPCR 0x54
+#define BP_CLPCR_LPM 0
+#define BM_CLPCR_LPM (0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define BM_CLPCR_SBYOS (0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define BM_CLPCR_VSTBY (0x1 << 8)
+#define BP_CLPCR_STBY_COUNT 9
+#define BM_CLPCR_STBY_COUNT (0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
+
+static struct clk *clks[IMX6QDL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const char *step_sels[] = {
+ "osc",
+ "pll2_pfd2_396m",
+};
+
+static const char *pll1_sw_sels[] = {
+ "pll1_sys",
+ "step",
+};
+
+static const char *periph_pre_sels[] = {
+ "pll2_bus",
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m",
+ "pll2_198m",
+};
+
+static const char *periph_clk2_sels[] = {
+ "pll3_usb_otg",
+ "osc",
+};
+
+static const char *periph_sels[] = {
+ "periph_pre",
+ "periph_clk2",
+};
+
+static const char *periph2_sels[] = {
+ "periph2_pre",
+ "periph2_clk2",
+};
+
+static const char *axi_sels[] = {
+ "periph",
+ "pll2_pfd2_396m",
+ "pll3_pfd1_540m",
+};
+
+static const char *usdhc_sels[] = {
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m",
+};
+
+static const char *enfc_sels[] = {
+ "pll2_pfd0_352m",
+ "pll2_bus",
+ "pll3_usb_otg",
+ "pll2_pfd2_396m",
+};
+
+static const char *eim_sels[] = {
+ "axi",
+ "pll3_usb_otg",
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m",
+};
+
+static const char *vdo_axi_sels[] = {
+ "axi",
+ "ahb",
+};
+
+static const char *cko_sels[] = {
+ "cko1",
+ "cko2",
+};
+
+static const char *cko1_sels[] = {
+ "pll3_usb_otg",
+ "pll2_bus",
+ "pll1_sys",
+ "pll5_video",
+ "dummy",
+ "axi",
+ "enfc",
+ "ipu1_di0",
+ "ipu1_di1",
+ "ipu2_di0",
+ "ipu2_di1",
+ "ahb",
+ "ipg",
+ "ipg_per",
+ "ckil",
+ "pll4_audio",
+};
+
+static const char *cko2_sels[] = {
+ "mmdc_ch0_axi",
+ "mmdc_ch1_axi",
+ "usdhc4",
+ "usdhc1",
+ "gpu2d_axi",
+ "dummy",
+ "ecspi_root",
+ "gpu3d_axi",
+ "usdhc3",
+ "dummy",
+ "arm",
+ "ipu1",
+ "ipu2",
+ "vdo_axi",
+ "osc",
+ "gpu2d_core",
+ "gpu3d_core",
+ "usdhc2",
+ "ssi1",
+ "ssi2",
+ "ssi3",
+ "gpu3d_shader",
+ "vpu_axi",
+ "can_root",
+ "ldb_di0",
+ "ldb_di1",
+ "esai",
+ "eim_slow",
+ "uart_serial",
+ "spdif",
+ "asrc",
+ "hsi_tx",
+};
+
+static const char *ipu_sels[] = {
+ "mmdc_ch0_axi_podf",
+ "pll2_pfd2_396m",
+ "pll3_120m",
+ "pll3_pfd1_540m",
+};
+
+static const char *ldb_di_sels[] = {
+ "pll5_video_div",
+ "pll2_pfd0_352m",
+ "pll2_pfd2_396m",
+ "mmdc_ch1_axi_podf",
+ "pll3_usb_otg",
+};
+
+static const char *ipu_di_pre_sels[] = {
+ "mmdc_ch0_axi",
+ "pll3_usb_otg",
+ "pll5_video_div",
+ "pll2_pfd0_352m",
+ "pll2_pfd2_396m",
+ "pll3_pfd1_540m",
+};
+
+static const char *ipu1_di0_sels[] = {
+ "ipu1_di0_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0_podf",
+ "ldb_di1_podf",
+};
+
+static const char *ipu1_di1_sels[] = {
+ "ipu1_di1_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0_podf",
+ "ldb_di1_podf",
+};
+
+static const char *ipu2_di0_sels[] = {
+ "ipu2_di0_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0_podf",
+ "ldb_di1_podf",
+};
+
+static const char *ipu2_di1_sels[] = {
+ "ipu2_di1_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0_podf",
+ "ldb_di1_podf",
+};
+
+static const char *lvds_sels[] = {
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "pll4_audio",
+ "pll5_video",
+ "pll8_mlb",
+ "enet_ref",
+ "pcie_ref_125m",
+ "sata_ref_100m",
+};
+
+static const char *pcie_axi_sels[] = {
+ "axi",
+ "ahb",
+};
+
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { },
+};
+
+static struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { /* sentinel */ }
+};
+
+static struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { /* sentinel */ }
+};
+
+static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb)
+{
+ clks[IMX6QDL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table);
+ clks[IMX6QDL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table);
+
+ 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));
+ clks[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", cb + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
+ clks[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", cb + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
+ clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
+ clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
+ clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
+ clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
+ clks[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_p("ipu1_di0_sel", cb + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
+ clks[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_p("ipu1_di1_sel", cb + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
+ clks[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_p("ipu2_di0_sel", cb + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
+ clks[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_p("ipu2_di1_sel", cb + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
+
+ clks[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", cb + 0x3c, 11, 3);
+ clks[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", cb + 0x3c, 16, 3);
+ clks[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_np("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1);
+ clks[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clks[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_np("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1);
+ clks[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", cb + 0x34, 3, 3);
+ clks[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", cb + 0x34, 12, 3);
+ 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_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);
+ clks[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", cb + 0x74, 6);
+ clks[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", cb + 0x74, 8);
+ 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);
+
+ 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]);
+ clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_SEL], clks[IMX6QDL_CLK_IPU2_DI0_PRE]);
+ clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_SEL], clks[IMX6QDL_CLK_IPU2_DI1_PRE]);
+
+ clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+
+ if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) ||
+ cpu_is_mx6dl()) {
+ clk_set_parent(clks[IMX6QDL_CLK_LDB_DI0_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6QDL_CLK_LDB_DI1_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
+ }
+
+}
+
+static int imx6_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base, *anatop_base, *ccm_base;
+
+ anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ ccm_base = IOMEM(iores->start);
+
+ base = anatop_base;
+
+ /* type name parent_name base div_mask */
+ clks[IMX6QDL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
+ clks[IMX6QDL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
+ clks[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
+ clks[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
+ clks[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
+ clks[IMX6QDL_CLK_PLL8_MLB] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll8_mlb", "osc", base + 0xd0, 0x0);
+ clks[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
+ clks[IMX6QDL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
+
+ clks[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
+ clks[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
+
+ clks[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
+ clks[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
+ clks[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
+ clks[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+ clks[IMX6QDL_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet", base + 0xe0, 0, 2, clk_enet_ref_table);
+
+ clks[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+ clks[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+
+ clks[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
+ clks[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
+
+ /* name parent_name reg idx */
+ clks[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clks[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clks[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clks[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ /* name parent_name mult div */
+ clks[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clks[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clks[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clks[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+
+ base = ccm_base;
+
+ /* name reg shift width parent_names num_parents */
+ clks[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ 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_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));
+ clks[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ 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_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));
+ clks[IMX6QDL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
+ clks[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
+
+ /* name reg shift width busy: reg, shift parent_names num_parents */
+ clks[IMX6QDL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ /* name parent_name reg shift width */
+ clks[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6QDL_CLK_IPG_PER] = imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6);
+ clks[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6);
+ clks[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
+ clks[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
+ clks[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clks[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
+ clks[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
+ clks[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
+ clks[IMX6QDL_CLK_EIM_PODF] = imx_clk_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3);
+ clks[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
+ clks[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
+ clks[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
+
+ /* name parent_name reg shift width busy: reg, shift */
+ clks[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
+ clks[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+ clks[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+
+ /* name parent_name reg shift */
+ clks[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
+ clks[IMX6QDL_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
+ clks[IMX6QDL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
+ clks[IMX6QDL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
+ clks[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
+ clks[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
+ clks[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
+ clks[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
+ if (cpu_is_mx6dl())
+ clks[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8);
+ else
+ clks[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
+ clks[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
+ clks[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
+ clks[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
+ clks[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
+ clks[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
+ clks[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
+ clks[IMX6QDL_CLK_IIM] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
+ clks[IMX6QDL_CLK_ENFC] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
+ clks[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);
+ clks[IMX6QDL_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
+ clks[IMX6QDL_CLK_PWM1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16);
+ clks[IMX6QDL_CLK_PWM2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18);
+ clks[IMX6QDL_CLK_PWM3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20);
+ clks[IMX6QDL_CLK_PWM4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22);
+ clks[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
+ clks[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
+ clks[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28);
+ clks[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
+ clks[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4);
+ clks[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
+ clks[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
+ clks[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6QDL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6QDL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6QDL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+ clks[IMX6QDL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
+ clks[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
+ clks[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
+ clks[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+
+ clkdev_add_physbase(clks[IMX6QDL_CLK_IPG], MX6_OCOTP_BASE_ADDR, NULL);
+
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+ imx6_add_video_clks(anatop_base, ccm_base);
+
+ writel(0xffffffff, ccm_base + CCGR0);
+ writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */
+ writel(0xffffffff, ccm_base + CCGR2);
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+ writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG */
+ else
+ writel(0x3fff0000, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */
+ if (IS_ENABLED(CONFIG_PCI_IMX6))
+ writel(0xffffffff, ccm_base + CCGR4);
+ else
+ writel(0xfffffffc, ccm_base + CCGR4); /* gate PCIe */
+ writel(0xffffffff, ccm_base + CCGR5);
+ writel(0xffff3fff, ccm_base + CCGR6); /* gate VPU */
+ writel(0xffffffff, ccm_base + CCGR7);
+
+ 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);
+
+ clk_enable(clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF]);
+ clk_enable(clks[IMX6QDL_CLK_PLL6_ENET]);
+ clk_enable(clks[IMX6QDL_CLK_SATA_REF_100M]);
+ clk_enable(clks[IMX6QDL_CLK_ENFC_PODF]);
+
+ clk_set_parent(clks[IMX6QDL_CLK_LVDS1_SEL], clks[IMX6QDL_CLK_SATA_REF_100M]);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx6q-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d 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);
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
new file mode 100644
index 0000000..d758957
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * 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 <dt-bindings/clock/imx6sx-clock.h>
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <mach/imx6-regs.h>
+#include <mach/revision.h>
+#include <mach/imx6.h>
+
+#include "clk.h"
+#include "common.h"
+
+#define CCDR 0x4
+#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
+
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *ocram_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
+static const char *gpu_axi_sels[] = { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
+static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *pcie_axi_sels[] = { "axi", "ahb", };
+static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *vid_sels[] = { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *qspi2_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
+static const char *enet_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *enet_sels[] = { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *m4_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
+static const char *m4_sels[] = { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *eim_slow_sels[] = { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *lcdif1_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *lcdif1_sels[] = { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *lcdif2_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
+static const char *lcdif2_sels[] = { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *display_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
+static const char *csi_sels[] = { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *cko1_sels[] = {
+ "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
+ "dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
+ "epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
+};
+static const char *cko2_sels[] = {
+ "dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
+ "ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
+ "lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
+ "usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
+ "dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
+ "spdif", "asrc", "dummy",
+};
+static const char *cko_sels[] = { "cko1", "cko2", };
+static const char *lvds_sels[] = {
+ "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
+ "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
+};
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+
+static struct clk *clks[IMX6SX_CLK_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { }
+};
+
+static struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static int imx6sx_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base, *anatop_base, *ccm_base;
+ struct device_node *ccm_node = dev->device_node;
+
+ clks[IMX6SX_CLK_DUMMY] = clk_fixed("dummy", 0);
+
+ anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ ccm_base = IOMEM(iores->start);
+
+ base = anatop_base;
+
+ clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ /* type name parent_name base div_mask */
+ clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+ clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+ clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+ clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+ clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+ clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+ clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+ clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
+ clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
+ clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
+ clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
+ clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
+ clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
+ clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
+ clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
+ clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
+ clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
+ clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
+ clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
+ clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
+
+ clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+ * Bit 20 is the reserved and read-only bit, we do this only for:
+ * - Do nothing for usbphy clk_enable/disable
+ * - Keep refcount when do usbphy clk_enable/disable, in that case,
+ * the clk framework may need to enable/disable usbphy's parent
+ */
+ clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+ /*
+ * usbphy*_gate needs to be on after system boots up, and software
+ * never needs to control it anymore.
+ */
+ clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ /* FIXME 100Mhz is used for pcie ref for all imx6 pcie, excepted imx6q */
+ clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
+ clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+ clks[IMX6SX_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
+ base + 0xe0, 0, 2, clk_enet_ref_table);
+ clks[IMX6SX_CLK_ENET2_REF] = imx_clk_divider_table("enet2_ref", "pll6_enet",
+ base + 0xe0, 2, 2, clk_enet_ref_table);
+ clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
+
+ clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
+ clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
+
+ /* name parent_name reg idx */
+ clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
+ clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ /* name parent_name mult div */
+ clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clks[IMX6SX_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6SX_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clks[IMX6SX_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+ clks[IMX6SX_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
+
+ clks[IMX6SX_CLK_PLL4_POST_DIV] = imx_clk_divider_table("pll4_post_div", "pll4_audio",
+ base + 0x70, 19, 2, post_div_table);
+ clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = imx_clk_divider("pll4_audio_div", "pll4_post_div",
+ base + 0x170, 15, 1);
+ clks[IMX6SX_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video",
+ base + 0xa0, 19, 2, post_div_table);
+ clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div",
+ base + 0x170, 30, 2, video_div_table);
+
+ /* name reg shift width parent_names num_parents */
+ clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+
+ base = ccm_base;
+
+ /* name reg shift width parent_names num_parents */
+ clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels));
+ clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
+ clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
+ clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels));
+ clks[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
+ clks[IMX6SX_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_p("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
+ clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
+ clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
+ clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+ clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_p("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
+ clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
+ clks[IMX6SX_CLK_ENET_SEL] = imx_clk_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels));
+ clks[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels));
+ clks[IMX6SX_CLK_M4_SEL] = imx_clk_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels));
+ clks[IMX6SX_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+ clks[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels));
+ clks[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels));
+ clks[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels));
+ clks[IMX6SX_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
+ clks[IMX6SX_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
+ clks[IMX6SX_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels));
+ clks[IMX6SX_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels));
+
+ clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_p("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+ clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_p("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+ clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels));
+ clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
+ clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_p("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels));
+ clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_p("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels));
+
+ /* name parent_name reg shift width */
+ clks[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6SX_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3);
+ clks[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3);
+ clks[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3);
+ clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
+ clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
+ clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3);
+ clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
+ clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2);
+ clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
+ clks[IMX6SX_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clks[IMX6SX_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6SX_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6SX_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
+ clks[IMX6SX_CLK_QSPI2_PRED] = imx_clk_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3);
+ clks[IMX6SX_CLK_QSPI2_PODF] = imx_clk_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6);
+ clks[IMX6SX_CLK_ENET_PODF] = imx_clk_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3);
+ clks[IMX6SX_CLK_M4_PODF] = imx_clk_divider("m4_podf", "m4_sel", base + 0x34, 3, 3);
+ clks[IMX6SX_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
+ clks[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3);
+ clks[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3);
+ clks[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_divider("display_podf", "display_sel", base + 0x3c, 16, 3);
+ clks[IMX6SX_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
+ clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
+ clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
+
+ clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
+ clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
+
+ /* name reg shift width busy: reg, shift parent_names num_parents */
+ clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6SX_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+ /* name parent_name reg shift width busy: reg, shift */
+ clks[IMX6SX_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clks[IMX6SX_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+ clks[IMX6SX_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6SX_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+
+ /* name parent_name reg shift */
+ /* CCGR0 */
+ clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
+ clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
+ clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
+ clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
+ clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
+ clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
+ clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24);
+ clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26);
+ clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30);
+
+ /* CCGR1 */
+ clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
+ clks[IMX6SX_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
+ clks[IMX6SX_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
+ clks[IMX6SX_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
+ clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8);
+ clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
+ clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
+ clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18);
+ clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20);
+ clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
+ clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26);
+
+ /* CCGR2 */
+ clks[IMX6SX_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
+ clks[IMX6SX_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
+ clks[IMX6SX_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
+ clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
+ clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
+ clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14);
+ clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16);
+ clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18);
+ clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20);
+ clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22);
+ clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28);
+ clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30);
+
+ /* CCGR3 */
+ clks[IMX6SX_CLK_M4] = imx_clk_gate2("m4", "m4_podf", base + 0x74, 2);
+ clks[IMX6SX_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4);
+ clks[IMX6SX_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "enet_sel", base + 0x74, 4);
+ clks[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_gate2("display_axi", "display_podf", base + 0x74, 6);
+ clks[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8);
+ clks[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10);
+ clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
+ clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14);
+ clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18);
+ clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
+ clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
+ clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
+
+ /* CCGR4 */
+ clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0);
+ clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10);
+ clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12);
+ clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14);
+ clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
+ clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
+ clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
+ clks[IMX6SX_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
+ clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
+ clks[IMX6SX_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
+ clks[IMX6SX_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28);
+ clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
+
+ /* CCGR5 */
+ clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
+ clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
+ clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26);
+ clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28);
+ clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30);
+
+ /* CCGR6 */
+ clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6SX_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6SX_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6SX_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+ clks[IMX6SX_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
+ clks[IMX6SX_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10);
+ clks[IMX6SX_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16);
+ clks[IMX6SX_CLK_VADC] = imx_clk_gate2("vadc", "vid_podf", base + 0x80, 20);
+ clks[IMX6SX_CLK_GIS] = imx_clk_gate2("gis", "display_podf", base + 0x80, 22);
+ clks[IMX6SX_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
+ clks[IMX6SX_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
+ clks[IMX6SX_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
+ clks[IMX6SX_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
+
+ clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
+ clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24);
+
+ /* mask handshake of mmdc */
+ writel(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+ if (IS_ENABLED(CONFIG_USB_IMX_PHY)) {
+ clk_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
+ clk_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
+ }
+
+ return 0;
+};
+
+static int imx6sx_clocks_init(void)
+{
+ if (!of_machine_is_compatible("fsl,imx6sx"))
+ return 0;
+
+ /* Set the default 132MHz for EIM module */
+ clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+ clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
+
+ /* set parent clock for LCDIF1 pixel clock */
+ clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
+ clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
+
+ /*
+ * Init enet system AHB clock, set to 200Mhz
+ * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
+ */
+ clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+ clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
+ clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
+ clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
+ clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
+
+ /* Set parent clock for vadc */
+ clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+
+ /* Update gpu clock from default 528M to 720M */
+ clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+ clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+
+ return 0;
+}
+coredevice_initcall(imx6sx_clocks_init);
+
+static __maybe_unused struct of_device_id imx6sx_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx6sx-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx6sx_ccm_driver = {
+ .probe = imx6sx_ccm_probe,
+ .name = "imx6-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx6sx_ccm_dt_ids),
+};
+
+static int imx6sx_ccm_init(void)
+{
+ return platform_driver_register(&imx6sx_ccm_driver);
+}
+core_initcall(imx6sx_ccm_init);
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
new file mode 100644
index 0000000..8f6d5ad
--- /dev/null
+++ b/drivers/clk/imx/clk-pfd.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 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>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+/**
+ * struct clk_pfd - IMX PFD clock
+ * @clk_hw: clock source
+ * @reg: PFD register address
+ * @idx: the index of PFD encoded in the register
+ *
+ * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
+ * data encoded, and member idx is used to specify the one. And each
+ * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
+ */
+struct clk_pfd {
+ struct clk clk;
+ void __iomem *reg;
+ u8 idx;
+ const char *parent;
+};
+
+#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
+
+#define SET 0x4
+#define CLR 0x8
+#define OTG 0xc
+
+static int clk_pfd_enable(struct clk *clk)
+{
+ struct clk_pfd *pfd = to_clk_pfd(clk);
+ writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+
+ return 0;
+}
+
+static void clk_pfd_disable(struct clk *clk)
+{
+ struct clk_pfd *pfd = to_clk_pfd(clk);
+
+ writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+}
+
+static unsigned long clk_pfd_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_pfd *pfd = to_clk_pfd(clk);
+ u64 tmp = parent_rate;
+ u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static long clk_pfd_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ u64 tmp = *prate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+ tmp = *prate;
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int clk_pfd_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pfd *pfd = to_clk_pfd(clk);
+ u64 tmp = parent_rate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+
+ writel(0x3f << (pfd->idx * 8), pfd->reg + CLR);
+ writel(frac << (pfd->idx * 8), pfd->reg + SET);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+ .enable = clk_pfd_enable,
+ .disable = clk_pfd_disable,
+ .recalc_rate = clk_pfd_recalc_rate,
+ .round_rate = clk_pfd_round_rate,
+ .set_rate = clk_pfd_set_rate,
+};
+
+struct clk *imx_clk_pfd(const char *name, const char *parent,
+ void __iomem *reg, u8 idx)
+{
+ struct clk_pfd *pfd;
+ int ret;
+
+ pfd = xzalloc(sizeof(*pfd));
+
+ pfd->reg = reg;
+ pfd->idx = idx;
+ pfd->parent = parent;
+ pfd->clk.name = name;
+ pfd->clk.ops = &clk_pfd_ops;
+ pfd->clk.parent_names = &pfd->parent;
+ pfd->clk.num_parents = 1;
+
+ ret = clk_register(&pfd->clk);
+ if (ret) {
+ free(pfd);
+ return ERR_PTR(ret);
+ }
+
+ return &pfd->clk;
+}
diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c
new file mode 100644
index 0000000..f992134
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv1.c
@@ -0,0 +1,95 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+struct clk_pllv1 {
+ struct clk clk;
+ void __iomem *reg;
+ const char *parent;
+};
+
+static unsigned long clk_pllv1_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_pllv1 *pll = container_of(clk, struct clk_pllv1, clk);
+ unsigned long long ll;
+ int mfn_abs;
+ unsigned int mfi, mfn, mfd, pd;
+ u32 reg_val = readl(pll->reg);
+ unsigned long freq = parent_rate;
+
+ mfi = (reg_val >> 10) & 0xf;
+ mfn = reg_val & 0x3ff;
+ mfd = (reg_val >> 16) & 0x3ff;
+ pd = (reg_val >> 26) & 0xf;
+
+ mfi = mfi <= 5 ? 5 : mfi;
+
+ mfn_abs = mfn;
+
+#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
+ if (mfn >= 0x200) {
+ mfn |= 0xFFFFFE00;
+ mfn_abs = -mfn;
+ }
+#endif
+
+ freq *= 2;
+ freq /= pd + 1;
+
+ ll = (unsigned long long)freq * mfn_abs;
+
+ do_div(ll, mfd + 1);
+ if (mfn < 0)
+ ll = (freq * mfi) - ll;
+ else
+ ll = (freq * mfi) + ll;
+
+ return ll;
+}
+
+struct clk_ops clk_pllv1_ops = {
+ .recalc_rate = clk_pllv1_recalc_rate,
+};
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+ void __iomem *base)
+{
+ struct clk_pllv1 *pll = xzalloc(sizeof(*pll));
+ int ret;
+
+ pll->parent = parent;
+ pll->reg = base;
+ pll->clk.ops = &clk_pllv1_ops;
+ pll->clk.name = name;
+ pll->clk.parent_names = &pll->parent;
+ pll->clk.num_parents = 1;
+
+ ret = clk_register(&pll->clk);
+ if (ret) {
+ free(pll);
+ return ERR_PTR(ret);
+ }
+
+ return &pll->clk;
+}
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
new file mode 100644
index 0000000..5ba07fa
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -0,0 +1,230 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
+
+struct clk_pllv2 {
+ struct clk clk;
+ void __iomem *reg;
+ const char *parent;
+};
+
+static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
+ u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dbl;
+ uint64_t temp;
+
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * parent_rate;
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = (ref_clk * mfi) - temp;
+ else
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static unsigned long clk_pllv2_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
+ void __iomem *pllbase;
+ struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
+
+ pllbase = pll->reg;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+
+ return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn);
+}
+
+static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
+ u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn)
+{
+ u32 reg;
+ long mfi, pdf, mfn, mfd = 999999;
+ u64 temp64;
+ unsigned long quad_parent_rate;
+
+ quad_parent_rate = 4 * parent_rate;
+ pdf = mfi = -1;
+ while (++pdf < 16 && mfi < 5)
+ mfi = rate * (pdf+1) / quad_parent_rate;
+ if (mfi > 15)
+ return -EINVAL;
+ pdf--;
+
+ temp64 = rate * (pdf + 1) - quad_parent_rate * mfi;
+ do_div(temp64, quad_parent_rate / 1000000);
+ mfn = (long)temp64;
+
+ reg = mfi << 4 | pdf;
+
+ *dp_op = reg;
+ *dp_mfd = mfd;
+ *dp_mfn = mfn;
+
+ return 0;
+}
+
+static int clk_pllv2_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
+ void __iomem *pllbase;
+ u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
+ int ret;
+
+ pllbase = pll->reg;
+
+ ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn);
+ if (ret)
+ return ret;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+
+ __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN);
+
+ return 0;
+}
+
+static long clk_pllv2_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ u32 dp_op, dp_mfd, dp_mfn;
+
+ __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn);
+ return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN,
+ dp_op, dp_mfd, dp_mfn);
+}
+
+struct clk_ops clk_pllv2_ops = {
+ .recalc_rate = clk_pllv2_recalc_rate,
+ .round_rate = clk_pllv2_round_rate,
+ .set_rate = clk_pllv2_set_rate,
+};
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+ void __iomem *base)
+{
+ struct clk_pllv2 *pll = xzalloc(sizeof(*pll));
+ int ret;
+
+ pll->parent = parent;
+ pll->reg = base;
+ pll->clk.ops = &clk_pllv2_ops;
+ pll->clk.name = name;
+ pll->clk.parent_names = &pll->parent;
+ pll->clk.num_parents = 1;
+
+ ret = clk_register(&pll->clk);
+ if (ret) {
+ free(pll);
+ return ERR_PTR(ret);
+ }
+
+ return &pll->clk;
+}
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
new file mode 100644
index 0000000..e38dcdf
--- /dev/null
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -0,0 +1,326 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <clock.h>
+#include <asm-generic/div64.h>
+
+#include "clk.h"
+
+#define PLL_NUM_OFFSET 0x10
+#define PLL_DENOM_OFFSET 0x20
+
+#define BM_PLL_POWER (0x1 << 12)
+#define BM_PLL_ENABLE (0x1 << 13)
+#define BM_PLL_BYPASS (0x1 << 16)
+#define BM_PLL_LOCK (0x1 << 31)
+
+struct clk_pllv3 {
+ struct clk clk;
+ void __iomem *base;
+ bool powerup_set;
+ u32 div_mask;
+ const char *parent;
+};
+
+#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+
+static int clk_pllv3_enable(struct clk *clk)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ u32 val;
+ int timeout = 10000;
+
+ val = readl(pll->base);
+ val &= ~BM_PLL_BYPASS;
+ if (pll->powerup_set)
+ val |= BM_PLL_POWER;
+ else
+ val &= ~BM_PLL_POWER;
+ writel(val, pll->base);
+
+ /* Wait for PLL to lock */
+ while (timeout--) {
+ if (readl(pll->base) & BM_PLL_LOCK)
+ break;
+ }
+
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ val = readl(pll->base);
+ val |= BM_PLL_ENABLE;
+ writel(val, pll->base);
+
+ return 0;
+}
+
+static void clk_pllv3_disable(struct clk *clk)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ u32 val;
+
+ val = readl(pll->base);
+ val &= ~BM_PLL_ENABLE;
+ writel(val, pll->base);
+
+ val |= BM_PLL_BYPASS;
+ if (pll->powerup_set)
+ val &= ~BM_PLL_POWER;
+ else
+ val |= BM_PLL_POWER;
+ writel(val, pll->base);
+}
+
+static unsigned long clk_pllv3_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ u32 div = readl(pll->base) & pll->div_mask;
+
+ return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static long clk_pllv3_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+
+ return (rate >= parent_rate * 22) ? parent_rate * 22 :
+ parent_rate * 20;
+}
+
+static int clk_pllv3_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ u32 val, div;
+
+ if (rate == parent_rate * 22)
+ div = 1;
+ else if (rate == parent_rate * 20)
+ div = 0;
+ else
+ return -EINVAL;
+
+ val = readl(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel(val, pll->base);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_ops = {
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_recalc_rate,
+ .round_rate = clk_pllv3_round_rate,
+ .set_rate = clk_pllv3_set_rate,
+};
+
+static unsigned long clk_pllv3_sys_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ u32 div = readl(pll->base) & pll->div_mask;
+
+ return parent_rate * div / 2;
+}
+
+static long clk_pllv3_sys_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long min_rate = parent_rate * 54 / 2;
+ unsigned long max_rate = parent_rate * 108 / 2;
+ u32 div;
+
+ if (rate > max_rate)
+ rate = max_rate;
+ else if (rate < min_rate)
+ rate = min_rate;
+ div = rate * 2 / parent_rate;
+
+ return parent_rate * div / 2;
+}
+
+static int clk_pllv3_sys_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ unsigned long min_rate = parent_rate * 54 / 2;
+ unsigned long max_rate = parent_rate * 108 / 2;
+ u32 val, div;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate * 2 / parent_rate;
+ val = readl(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel(val, pll->base);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_sys_ops = {
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_sys_recalc_rate,
+ .round_rate = clk_pllv3_sys_round_rate,
+ .set_rate = clk_pllv3_sys_set_rate,
+};
+
+static unsigned long clk_pllv3_av_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
+ u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
+ u32 div = readl(pll->base) & pll->div_mask;
+
+ return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+}
+
+static long clk_pllv3_av_round_rate(struct clk *clk, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+ u32 div;
+ u32 mfn, mfd = 1000000;
+ u64 temp64;
+
+ if (rate > max_rate)
+ rate = max_rate;
+ else if (rate < min_rate)
+ rate = min_rate;
+
+ div = rate / parent_rate;
+ temp64 = (u64) (rate - div * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ return parent_rate * div + parent_rate / mfd * mfn;
+}
+
+static int clk_pllv3_av_set_rate(struct clk *clk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+ u32 val, div;
+ u32 mfn, mfd = 1000000;
+ u64 temp64;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate / parent_rate;
+ temp64 = (u64) (rate - div * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ val = readl(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel(val, pll->base);
+ writel(mfn, pll->base + PLL_NUM_OFFSET);
+ writel(mfd, pll->base + PLL_DENOM_OFFSET);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_av_ops = {
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_av_recalc_rate,
+ .round_rate = clk_pllv3_av_round_rate,
+ .set_rate = clk_pllv3_av_set_rate,
+};
+
+static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
+ unsigned long parent_rate)
+{
+ return 500000000;
+}
+
+static const struct clk_ops clk_pllv3_enet_ops = {
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_enet_recalc_rate,
+};
+
+static const struct clk_ops clk_pllv3_mlb_ops = {
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+ const char *parent, void __iomem *base,
+ u32 div_mask)
+{
+ struct clk_pllv3 *pll;
+ const struct clk_ops *ops;
+ int ret;
+
+ pll = xzalloc(sizeof(*pll));
+
+ switch (type) {
+ case IMX_PLLV3_SYS:
+ ops = &clk_pllv3_sys_ops;
+ break;
+ case IMX_PLLV3_USB:
+ ops = &clk_pllv3_ops;
+ pll->powerup_set = true;
+ break;
+ case IMX_PLLV3_AV:
+ ops = &clk_pllv3_av_ops;
+ break;
+ case IMX_PLLV3_ENET:
+ ops = &clk_pllv3_enet_ops;
+ break;
+ case IMX_PLLV3_MLB:
+ ops = &clk_pllv3_mlb_ops;
+ break;
+ default:
+ ops = &clk_pllv3_ops;
+ }
+ pll->base = base;
+ pll->div_mask = div_mask;
+ pll->parent = parent;
+ pll->clk.ops = ops;
+ pll->clk.name = name;
+ pll->clk.parent_names = &pll->parent;
+ pll->clk.num_parents = 1;
+
+ ret = clk_register(&pll->clk);
+ if (ret) {
+ free(pll);
+ return ERR_PTR(ret);
+ }
+
+ return &pll->clk;
+}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
new file mode 100644
index 0000000..c5913e1
--- /dev/null
+++ b/drivers/clk/imx/clk.h
@@ -0,0 +1,104 @@
+#ifndef __IMX_CLK_H
+#define __IMX_CLK_H
+
+struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
+ u8 shift);
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width)
+{
+ return clk_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_divider_np(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width)
+{
+ return clk_divider(name, parent, reg, shift, width, 0);
+}
+
+static inline struct clk *imx_clk_divider_table(const char *name,
+ const char *parent, void __iomem *reg, u8 shift, u8 width,
+ const struct clk_div_table *table)
+{
+ return clk_divider_table(name, parent, reg, shift, width, table,
+ CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+ const char *parent, unsigned int mult, unsigned int div)
+{
+ return clk_fixed_factor(name, parent, mult, div, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents, u8 num_parents)
+{
+ return clk_mux(name, reg, shift, width, parents, num_parents, 0);
+}
+
+static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents, u8 num_parents)
+{
+ return clk_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *imx_clk_gate(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_gate(name, parent, reg, shift, CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_gate2(name, parent, reg, shift);
+}
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+ void __iomem *base);
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+ void __iomem *base);
+
+enum imx_pllv3_type {
+ IMX_PLLV3_GENERIC,
+ IMX_PLLV3_SYS,
+ IMX_PLLV3_USB,
+ IMX_PLLV3_AV,
+ IMX_PLLV3_ENET,
+ IMX_PLLV3_MLB,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+ const char *parent, void __iomem *base,
+ u32 div_mask);
+
+struct clk *imx_clk_pfd(const char *name, const char *parent,
+ void __iomem *reg, u8 idx);
+
+static inline struct clk *imx_clk_busy_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width,
+ void __iomem *busy_reg, u8 busy_shift)
+{
+ /*
+ * For now we do not support rate setting, so just fall back to
+ * regular divider.
+ */
+ return imx_clk_divider(name, parent, reg, shift, width);
+}
+
+static inline struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+ u8 width, void __iomem *busy_reg, u8 busy_shift,
+ const char **parents, int num_parents)
+{
+ /*
+ * For now we do not support mux switching, so just fall back to
+ * regular mux.
+ */
+ return imx_clk_mux(name, reg, shift, width, parents, num_parents);
+}
+
+struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u32 exclusive_mask);
+
+#endif /* __IMX_CLK_H */
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* Re: [PATCH 0/4] net/designware: A few patches from U-Boot
From: Sascha Hauer @ 2016-11-10 8:49 UTC (permalink / raw)
To: Ian Abbott; +Cc: barebox
In-Reply-To: <20161107181624.4262-1-abbotti@mev.co.uk>
Hi Ian,
On Mon, Nov 07, 2016 at 06:16:20PM +0000, Ian Abbott wrote:
> Here are a few old-ish patches for the Synopsys Designware Ethernet
> driver, ported over from U-Boot.
>
> 1) net/designware: Consecutive writes to the same register to be avoided
> 2) net/designware: Do not select MIIPORT for RGMII interface
> 3) net: designware: Respect "bus mode" register contents on SW reset
> 4) net/designware: add explicit reset of {tx|rx}_currdescnum
The patches look ok to me. Do you want me to apply them or should we
rather wait until you resolved your network issues?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: [PATCH 0/4] net/designware: A few patches from U-Boot
From: Ian Abbott @ 2016-11-10 10:26 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
In-Reply-To: <20161110084945.r5jahnxqy6qe6wbl@pengutronix.de>
Hi Sascha,
On 10/11/16 08:49, Sascha Hauer wrote:
> On Mon, Nov 07, 2016 at 06:16:20PM +0000, Ian Abbott wrote:
>> Here are a few old-ish patches for the Synopsys Designware Ethernet
>> driver, ported over from U-Boot.
>>
>> 1) net/designware: Consecutive writes to the same register to be avoided
>> 2) net/designware: Do not select MIIPORT for RGMII interface
>> 3) net: designware: Respect "bus mode" register contents on SW reset
>> 4) net/designware: add explicit reset of {tx|rx}_currdescnum
>
> The patches look ok to me. Do you want me to apply them or should we
> rather wait until you resolved your network issues?
I'm fine with you applying them. I think my network issues maybe more
hardware related.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=-
-=( Web: http://www.mev.co.uk/ )=-
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: [PATCH 0/4] net/designware: A few patches from U-Boot
From: Sascha Hauer @ 2016-11-10 14:04 UTC (permalink / raw)
To: Ian Abbott; +Cc: barebox
In-Reply-To: <20161107181624.4262-1-abbotti@mev.co.uk>
On Mon, Nov 07, 2016 at 06:16:20PM +0000, Ian Abbott wrote:
> Here are a few old-ish patches for the Synopsys Designware Ethernet
> driver, ported over from U-Boot.
>
> 1) net/designware: Consecutive writes to the same register to be avoided
> 2) net/designware: Do not select MIIPORT for RGMII interface
> 3) net: designware: Respect "bus mode" register contents on SW reset
> 4) net/designware: add explicit reset of {tx|rx}_currdescnum
>
> drivers/net/designware.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
Applied, thanks
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: [PATCH v2 00/28] Vybrid support in Barebox
From: Sascha Hauer @ 2016-11-11 8:21 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox
In-Reply-To: <1478708056-7875-1-git-send-email-andrew.smirnov@gmail.com>
Hi Andrey,
On Wed, Nov 09, 2016 at 08:13:48AM -0800, Andrey Smirnov wrote:
> Hi everyone,
>
> It took me a bit more than a month, but I finally put together a
> second version (for v1 see [1]) of the Vybrid support patchset.
>
> Some highlights of this version:
>
> - Various code/commit arrangement feedback for v1 is addressed
> - Added commit to move all of the i.MX clock code to drivers/clk
> (Sascha, we'd probably have to coordinate with your i.MX6ul
> patches on this one)
> - I2C commit split in two
> - clock tree is reconciled with Linux code, since having a custom
> version of it proved to be difficult to compare agains Linux's
> implementation
> - GPIO driver (tested on a custom Vybrid board)
> - FEC support (tested on a custom Vybrid board)
>
> Any feedback is, as always, very much appreciated.
The series looks mostly good, but I won't find the time for a deeper
review anytime soon, so I decided to just give it a try in -next.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* v2016.11.0
From: Sascha Hauer @ 2016-11-11 9:29 UTC (permalink / raw)
To: Barebox List
Hi All,
We have a November Release.
This is the first release which contains bootchooser, a framework which
simplifies and generalizes redundant boot scenarios.
Other than that we can now rename UBI volumes. Also there are improvemts
in running the UBI background thread which finally means that barebox
can write a fastmap on freshly formatted UBI devices. Previously barebox
was often not able to find an anchor PEB for the fastmap.
Another change worth noting is that the decision if defenv-1 or defenv-2
should be used can now be selected in Kconfig. It is no longer a board
decision.
As usual several fixes went in all over the place.
Sascha
----------------------------------------------------------------
Alexander Kurz (1):
mtd: spi-nor: add MX25U2033E
Andrey Smirnov (2):
i.MX: Introduce imx6_cpu_revision()
i.MX: Register imx6_fixup_cpus() for MX6Q+ as well
Antony Pavlov (1):
sandbox: Makefile: drop unused SUBARCH stuff
Christian Hemp (1):
mtd: nand: nand_mxs: Fix readtotal calculation
Daniel Schultz (1):
nand: imx6: Changed default NAND clock
Enrico Jorns (2):
net: add linux.bootarg parameter from ifup call
fs: nfs: pick up network interface bootargs parameter
Giorgio Dal Molin (2):
mtd: ubi: add API call to rename volumes.
mtd: ubi: commands: added the new command 'ubirename'.
Jan Luebbe (3):
ARM: i.MX6: remove duplicate clock initialization
ARM: i.MX6: fix clock gating
ARM: i.MX6: gate PCIe when unused
Lucas Stach (7):
ARM: imx6: split out IPU QoS setup
ARM: imx6: don't execute IPU QoS setup on MX6 SX/SL
ARM: imx6qp: set NoC regulator to bypass
ARM: microsom: use imx6q_barebox_entry
ARM: imx6: add support for Auvidea H100
net: e1000: fix i210 register remapping
ARM: riotboard: fix barebox partition size
Marc Kleine-Budde (1):
boot: add framework for redundant boot scenarios
Michael Olbrich (3):
state: copy backend of_path string
state: don't keep pointers to device tree nodes
state: fix finding the correct parent node
Robert Schwebel (1):
Documentation: clarify that patches should target the master branch.
Sam Ravnborg (1):
environment: "wrong magic" gives the impression of an error
Sascha Hauer (76):
defenv-1: remove unused variable kernelimage_type
pbl: console: Let console pointer survive BSS clearing
ARM: i.MX6: Sabrelite: Add PBL console support
Add comp_copy function for use with CONFIG_IMAGE_COMPRESSION_NONE
ARM: Fix calling of arm_mem_barebox_image()
state: Add state to state_variable
state: make locally used function static
state: consistently pass one type as private data to dev_add_param_*
mtd: ubi: Add API calls to create/remove volumes
mtd: ubi: introduce barebox specific ioctl to get ubi_num
ARM: i.MX53: Add uart5 clock support
ARM: i.MX53 Vincell: Reset phy consistently from device tree
ARM: i.MX53 Vincell: Adjust bbu handler partition size to real partition size
ARM: i.MX53 Vincell: Add PBL console support
ARM: i.MX53: do not pass base address to imx*_boot_save_loc
ARM: i.MX: Provide bootsource functions for early boot code
ARM: i.MX53: Detect booting from USB
mtd: imx-nand: Move v3 register definitions to include file
ARM: i.MX53: Implement NAND xload
ARM: i.MX53 Vincell: Add NAND xload support
ARM: imx_v7_defconfig: Enable Vincell support
ARM: vincell_defconfig: make smaller
globalvar: Move static inline functions to common/
globalvar: sync with nvvars
vsprintf: Add support for printing ipv4 addresses with %pI4
convert users to %pI4
globalvar: Allow to remove multiple globalvars using wildcards
global: Make 'global' command behaviour consistent to 'nv'
nv: simplify nvvar_add
globalvar: Also create globalvars from for nonvolatile device vars
nv: Allow full variable name in nvvar_add
globalvar: Allow full variable name in globalvar_add
param: introduce param_bitmask
globalvar: introduce globalvar_add_simple_bitmask
mtd: ubi: commands: use function API to access ubi volumes
mtd: ubi: remove now unused ioctls
usb: Use standard debug macro
usb: Add usb phy to usb host
usb: ehci: forward phy given in registration data to host
usb: imx-usb-phy: Drop unnecessary read/modify/write
phy: Introduce of_phy_get_by_phandle
phy: Introduce to_usbphy conversion function
phy: Add usb-nop-xceiv support
usb: imx-us-phy: Convert driver to generic phy support
usb: imx-us-phy: implement notify_(dis)concect
dts: update to v4.8-rc1
dts: update to v4.8-rc2
dts: update to v4.8-rc4
dts: update to v4.8-rc5
dts: update to v4.8-rc6
dts: update to v4.8-rc7
dts: update to v4.8-rc8
Allow device parameters for devices with dots in name
completion: Fix completion for devices with a dot in the name
defaultenv: add defaultenv-1 in boards via defaultenv_append_directory()
Make generic default environment type a use choice
Merge branch 'for-next/arm'
Merge branch 'for-next/bootchooser'
Merge branch 'for-next/defenv'
Merge branch 'for-next/dts'
Merge branch 'for-next/imx'
Merge branch 'for-next/misc'
Merge branch 'for-next/mtd'
Merge branch 'for-next/mvebu'
Merge branch 'for-next/state'
Merge branch 'for-next/ubi'
Merge branch 'for-next/usb'
mtd: ubi: Fix scrubbing during attach
ARM: i.MX Freescale Sabrelite: Use correct device tree for dl variant
ARM: bootm: Fix free_mem calculation when initrd is given
mtd: ubi: enable thread earlier
ARM: Fix appended device tree when CONFIG_OFTREE is enabled
mtd: Make UBI detection more robust
of: partitions: Support new binding
of: of_find_path: Add support for new partition binding
Release v2016.11.0
Stefan Lengfeld (1):
state: fix state is not saved when string variable is changed
Steffen Trumtrar (3):
nand: denali: use correct interrupts in read_page
nand: denali: use is_timeout in while loop
nand: denali: get rid of compile-time debug information
Ulrich Ölmann (1):
blspec: fix typo
Uwe Kleine-König (17):
ARM: mvebu_defconfig: oldconfig
ARM: mvebu_defconfig: enable all machines, AEABI, nand and net driver
ARM: mvebu: select HAVE_DEFAULT_ENVIRONMENT_NEW
net: mvneta: clean txdesc before usage
firmware: altera-serial: Make the driver match the dt binding documentation
firmware: altera-serial: simplify handling of optional gpio
scripts: kwboot: try to resync on packet boundary after receiving a NAK
scripts: kwboot: flush input and output only once
scripts: kwboot: improve diagnostic output
scripts: kwboot: shorten delay between two boot messages
scripts: kwboot: simplify kwboot_mmap_image
scripts: kwboot: set boot source to UART before sending
images: mvebu: don't generate uart images
pinctrl: mvebu: add newline to error message
pinctrl: mvebu: armada-370 fix gpio name for mpp63
ARM: mvebu: add support for Netgear RN2120
ARM: mvebu: document some general mvebu stuff and the rn2120 board
Yegor Yefremov (2):
Add support for Baltos systems
boot: add '-w' parameter to usage help text
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: v2016.11.0
From: Ian Abbott @ 2016-11-11 11:07 UTC (permalink / raw)
To: barebox
In-Reply-To: <20161111092941.44lmfsowkldkbhis@pengutronix.de>
On 11/11/16 09:29, Sascha Hauer wrote:
> Hi All,
>
> We have a November Release.
>
> This is the first release which contains bootchooser, a framework which
> simplifies and generalizes redundant boot scenarios.
> Other than that we can now rename UBI volumes. Also there are improvemts
> in running the UBI background thread which finally means that barebox
> can write a fastmap on freshly formatted UBI devices. Previously barebox
> was often not able to find an anchor PEB for the fastmap.
> Another change worth noting is that the decision if defenv-1 or defenv-2
> should be used can now be selected in Kconfig. It is no longer a board
> decision.
> As usual several fixes went in all over the place.
>
> Sascha
Thanks! I am wondering about the git repository - the "v2016.11.0" tag
exists, but seems to be 6 commits above the top of the "master" branch.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=-
-=( Web: http://www.mev.co.uk/ )=-
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: v2016.11.0
From: Sascha Hauer @ 2016-11-11 11:17 UTC (permalink / raw)
To: Ian Abbott; +Cc: barebox
In-Reply-To: <46139469-bb50-505d-4486-2336f8bf6b3e@mev.co.uk>
On Fri, Nov 11, 2016 at 11:07:27AM +0000, Ian Abbott wrote:
> On 11/11/16 09:29, Sascha Hauer wrote:
> > Hi All,
> >
> > We have a November Release.
> >
> > This is the first release which contains bootchooser, a framework which
> > simplifies and generalizes redundant boot scenarios.
> > Other than that we can now rename UBI volumes. Also there are improvemts
> > in running the UBI background thread which finally means that barebox
> > can write a fastmap on freshly formatted UBI devices. Previously barebox
> > was often not able to find an anchor PEB for the fastmap.
> > Another change worth noting is that the decision if defenv-1 or defenv-2
> > should be used can now be selected in Kconfig. It is no longer a board
> > decision.
> > As usual several fixes went in all over the place.
> >
> > Sascha
>
> Thanks! I am wondering about the git repository - the "v2016.11.0" tag
> exists, but seems to be 6 commits above the top of the "master" branch.
Gnagna, I screwed it up. I made the v2016.11.0 tag while my for-next/mtd
was checked out.
It seems last mtd patches took the fast lane and went into the November
release while they should be in the December release. So the following
went in early:
f160f86 of: of_find_path: Add support for new partition binding
1f2f980 of: partitions: Support new binding
1c7cf80 mtd: spi-nor: add MX25U2033E
7159d9d mtd: nand: nand_mxs: Fix readtotal calculation
0d68468 mtd: Make UBI detection more robust
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Compiler issues
From: Jose Luis Zabalza @ 2016-11-13 7:02 UTC (permalink / raw)
To: barebox
Hello everybody
I continue to have problems with memory size but I suspect they may be
due to a compiler issue.
It is possible?
I am using this compiler (from ubuntu package on X86_64)
$ arm-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.7.3-12ubuntu1'
--with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs
--enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.7 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix
--with-gxx-include-dir=/usr/arm-linux-gnueabi/include/c++/4.7.3
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-gnu-unique-object
--disable-libmudflap --disable-libitm --enable-plugin
--with-system-zlib --enable-objc-gc --with-cloog
--enable-cloog-backend=ppl --disable-cloog-version-check
--disable-ppl-version-check --enable-multiarch --enable-multilib
--disable-sjlj-exceptions --with-arch=armv5t --with-float=soft
--disable-werror --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=arm-linux-gnueabi
--program-prefix=arm-linux-gnueabi-
--includedir=/usr/arm-linux-gnueabi/include
Thread model: posix
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-12ubuntu1)
Thanks in advanced
--
jlz.3008 a t gmail.com
Linux Counter 172551
https://linuxcounter.net/cert/172551.png
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [RFCv2 0/2] add initial RISC-V architecture support
From: Antony Pavlov @ 2016-11-13 21:50 UTC (permalink / raw)
To: barebox
This patchseries adds initial RISC-V architecture support for barebox.
See Documentation/boards/riscv.rst for instructions.
You can obtain this patch from github:
$ git clone -b 20161113.riscv https://github.com/frantony/barebox
Changes since 20161013:
* drop spike pk support;
* add qemu-sifive board support;
* add Documentation/boards/riscv.rst;
* fix guard macro names.
TODOs:
* split patch;
* use sifive timer IP-block.
Antony Pavlov (2):
serial: add driver for SiFive UART
Add initial RISC-V architecture support
Documentation/boards/riscv.rst | 63 ++++++++++++++
arch/riscv/Kconfig | 42 ++++++++++
arch/riscv/Makefile | 51 ++++++++++++
arch/riscv/boards/qemu-sifive/.gitignore | 1 +
arch/riscv/boards/qemu-sifive/Makefile | 1 +
arch/riscv/boards/qemu-sifive/board.c | 28 +++++++
arch/riscv/boot/Makefile | 2 +
arch/riscv/boot/main_entry.c | 40 +++++++++
arch/riscv/boot/start.S | 44 ++++++++++
arch/riscv/configs/qemu-sifive_defconfig | 75 +++++++++++++++++
arch/riscv/dts/.gitignore | 1 +
arch/riscv/dts/Makefile | 9 ++
arch/riscv/dts/qemu-sifive.dts | 19 +++++
arch/riscv/dts/skeleton.dtsi | 13 +++
arch/riscv/include/asm/barebox.h | 1 +
arch/riscv/include/asm/bitops.h | 35 ++++++++
arch/riscv/include/asm/bitsperlong.h | 10 +++
arch/riscv/include/asm/byteorder.h | 12 +++
arch/riscv/include/asm/common.h | 6 ++
arch/riscv/include/asm/elf.h | 11 +++
arch/riscv/include/asm/io.h | 8 ++
arch/riscv/include/asm/posix_types.h | 1 +
arch/riscv/include/asm/sections.h | 1 +
arch/riscv/include/asm/string.h | 1 +
arch/riscv/include/asm/swab.h | 6 ++
arch/riscv/include/asm/types.h | 60 ++++++++++++++
arch/riscv/include/asm/unaligned.h | 19 +++++
arch/riscv/lib/.gitignore | 1 +
arch/riscv/lib/Makefile | 3 +
arch/riscv/lib/asm-offsets.c | 12 +++
arch/riscv/lib/barebox.lds.S | 87 ++++++++++++++++++++
arch/riscv/lib/dtb.c | 41 ++++++++++
arch/riscv/mach-sifive/Kconfig | 16 ++++
arch/riscv/mach-sifive/Makefile | 3 +
arch/riscv/mach-sifive/include/mach/debug_ll.h | 38 +++++++++
drivers/of/Kconfig | 2 +-
drivers/serial/Kconfig | 3 +
drivers/serial/Makefile | 1 +
drivers/serial/serial_sifive.c | 109 +++++++++++++++++++++++++
39 files changed, 875 insertions(+), 1 deletion(-)
create mode 100644 Documentation/boards/riscv.rst
create mode 100644 arch/riscv/Kconfig
create mode 100644 arch/riscv/Makefile
create mode 100644 arch/riscv/boards/qemu-sifive/.gitignore
create mode 100644 arch/riscv/boards/qemu-sifive/Makefile
create mode 100644 arch/riscv/boards/qemu-sifive/board.c
create mode 100644 arch/riscv/boot/Makefile
create mode 100644 arch/riscv/boot/main_entry.c
create mode 100644 arch/riscv/boot/start.S
create mode 100644 arch/riscv/configs/qemu-sifive_defconfig
create mode 100644 arch/riscv/dts/.gitignore
create mode 100644 arch/riscv/dts/Makefile
create mode 100644 arch/riscv/dts/qemu-sifive.dts
create mode 100644 arch/riscv/dts/skeleton.dtsi
create mode 100644 arch/riscv/include/asm/barebox.h
create mode 100644 arch/riscv/include/asm/bitops.h
create mode 100644 arch/riscv/include/asm/bitsperlong.h
create mode 100644 arch/riscv/include/asm/byteorder.h
create mode 100644 arch/riscv/include/asm/common.h
create mode 100644 arch/riscv/include/asm/elf.h
create mode 100644 arch/riscv/include/asm/io.h
create mode 100644 arch/riscv/include/asm/posix_types.h
create mode 100644 arch/riscv/include/asm/sections.h
create mode 100644 arch/riscv/include/asm/string.h
create mode 100644 arch/riscv/include/asm/swab.h
create mode 100644 arch/riscv/include/asm/types.h
create mode 100644 arch/riscv/include/asm/unaligned.h
create mode 100644 arch/riscv/lib/.gitignore
create mode 100644 arch/riscv/lib/Makefile
create mode 100644 arch/riscv/lib/asm-offsets.c
create mode 100644 arch/riscv/lib/barebox.lds.S
create mode 100644 arch/riscv/lib/dtb.c
create mode 100644 arch/riscv/mach-sifive/Kconfig
create mode 100644 arch/riscv/mach-sifive/Makefile
create mode 100644 arch/riscv/mach-sifive/include/mach/debug_ll.h
create mode 100644 drivers/serial/serial_sifive.c
--
2.10.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [RFCv2 1/2] serial: add driver for SiFive UART
From: Antony Pavlov @ 2016-11-13 21:50 UTC (permalink / raw)
To: barebox
In-Reply-To: <20161113215015.9399-1-antonynpavlov@gmail.com>
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
TODO:
* add speed setup support.
drivers/serial/Kconfig | 3 ++
drivers/serial/Makefile | 1 +
drivers/serial/serial_sifive.c | 109 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 113 insertions(+)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b112d7e..70509b9 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -117,6 +117,9 @@ config DRIVER_SERIAL_S3C_AUTOSYNC
Say Y here if you want to use the auto flow feature of this
UART. RTS and CTS will be handled by the hardware when enabled.
+config DRIVER_SERIAL_SIFIVE
+ bool "SiFive serial driver"
+
config DRIVER_SERIAL_PXA
bool "PXA serial driver"
depends on ARCH_PXA
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 189e777..368e992 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_DRIVER_SERIAL_AUART) += serial_auart.o
obj-$(CONFIG_DRIVER_SERIAL_CADENCE) += serial_cadence.o
obj-$(CONFIG_DRIVER_SERIAL_EFI_STDIO) += efi-stdio.o
obj-$(CONFIG_DRIVER_SERIAL_DIGIC) += serial_digic.o
+obj-$(CONFIG_DRIVER_SERIAL_SIFIVE) += serial_sifive.o
diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c
new file mode 100644
index 0000000..06e3521
--- /dev/null
+++ b/drivers/serial/serial_sifive.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <io.h>
+
+#define UART_RX_OFFSET 0
+#define UART_TX_OFFSET 0
+#define UART_TX_COUNT_OFFSET 0x4
+#define UART_RX_COUNT_OFFSET 0x8
+#define UART_DIVIDER_OFFSET 0xC
+
+static inline uint32_t sifive_serial_readl(struct console_device *cdev,
+ uint32_t offset)
+{
+ void __iomem *base = cdev->dev->priv;
+
+ return readl(base + offset);
+}
+
+static inline void sifive_serial_writel(struct console_device *cdev,
+ uint32_t value, uint32_t offset)
+{
+ void __iomem *base = cdev->dev->priv;
+
+ writel(value, base + offset);
+}
+
+static int sifive_serial_setbaudrate(struct console_device *cdev, int baudrate)
+{
+ /* FIXME: no baudrate setup at the momement :( */
+
+ return 0;
+}
+
+static void sifive_serial_putc(struct console_device *cdev, char c)
+{
+ sifive_serial_writel(cdev, c, UART_TX_OFFSET);
+}
+
+static int sifive_serial_getc(struct console_device *cdev)
+{
+ uint32_t rxcnt;
+
+ do {
+ rxcnt = sifive_serial_readl(cdev, UART_RX_COUNT_OFFSET);
+ } while (!rxcnt);
+
+ return sifive_serial_readl(cdev, UART_RX_OFFSET);
+}
+
+static int sifive_serial_tstc(struct console_device *cdev)
+{
+ uint32_t rxcnt = sifive_serial_readl(cdev, UART_RX_COUNT_OFFSET);
+
+ return (rxcnt != 0);
+}
+
+static int sifive_serial_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ struct console_device *cdev;
+
+ cdev = xzalloc(sizeof(struct console_device));
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ dev->priv = IOMEM(iores->start);
+ cdev->dev = dev;
+ cdev->tstc = &sifive_serial_tstc;
+ cdev->putc = &sifive_serial_putc;
+ cdev->getc = &sifive_serial_getc;
+ cdev->setbrg = &sifive_serial_setbaudrate;
+
+ console_register(cdev);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id sifive_serial_dt_ids[] = {
+ {
+ .compatible = "sifive,uart",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d sifive_serial_driver = {
+ .name = "sifive-uart",
+ .probe = sifive_serial_probe,
+ .of_compatible = DRV_OF_COMPAT(sifive_serial_dt_ids),
+};
+console_platform_driver(sifive_serial_driver);
--
2.10.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [RFCv2 2/2] add initial RISC-V architecture support
From: Antony Pavlov @ 2016-11-13 21:50 UTC (permalink / raw)
To: barebox
In-Reply-To: <20161113215015.9399-1-antonynpavlov@gmail.com>
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
TODOs:
* split this patch.
* use sifive timer IP-block.
Documentation/boards/riscv.rst | 63 +++++++++++++++++++
arch/riscv/Kconfig | 42 +++++++++++++
arch/riscv/Makefile | 51 +++++++++++++++
arch/riscv/boards/qemu-sifive/.gitignore | 1 +
arch/riscv/boards/qemu-sifive/Makefile | 1 +
arch/riscv/boards/qemu-sifive/board.c | 28 +++++++++
arch/riscv/boot/Makefile | 2 +
arch/riscv/boot/main_entry.c | 40 ++++++++++++
arch/riscv/boot/start.S | 44 +++++++++++++
arch/riscv/configs/qemu-sifive_defconfig | 75 ++++++++++++++++++++++
arch/riscv/dts/.gitignore | 1 +
arch/riscv/dts/Makefile | 9 +++
arch/riscv/dts/qemu-sifive.dts | 19 ++++++
arch/riscv/dts/skeleton.dtsi | 13 ++++
arch/riscv/include/asm/barebox.h | 1 +
arch/riscv/include/asm/bitops.h | 35 +++++++++++
arch/riscv/include/asm/bitsperlong.h | 10 +++
arch/riscv/include/asm/byteorder.h | 12 ++++
arch/riscv/include/asm/common.h | 6 ++
arch/riscv/include/asm/elf.h | 11 ++++
arch/riscv/include/asm/io.h | 8 +++
arch/riscv/include/asm/posix_types.h | 1 +
arch/riscv/include/asm/sections.h | 1 +
arch/riscv/include/asm/string.h | 1 +
arch/riscv/include/asm/swab.h | 6 ++
arch/riscv/include/asm/types.h | 60 ++++++++++++++++++
arch/riscv/include/asm/unaligned.h | 19 ++++++
arch/riscv/lib/.gitignore | 1 +
arch/riscv/lib/Makefile | 3 +
arch/riscv/lib/asm-offsets.c | 12 ++++
arch/riscv/lib/barebox.lds.S | 87 ++++++++++++++++++++++++++
arch/riscv/lib/dtb.c | 41 ++++++++++++
arch/riscv/mach-sifive/Kconfig | 16 +++++
arch/riscv/mach-sifive/Makefile | 3 +
arch/riscv/mach-sifive/include/mach/debug_ll.h | 38 +++++++++++
drivers/of/Kconfig | 2 +-
36 files changed, 762 insertions(+), 1 deletion(-)
diff --git a/Documentation/boards/riscv.rst b/Documentation/boards/riscv.rst
new file mode 100644
index 0000000..f22504a
--- /dev/null
+++ b/Documentation/boards/riscv.rst
@@ -0,0 +1,63 @@
+RISC-V
+======
+
+At the moment only qemu emulator is supported (see https://github.com/riscv/riscv-isa-sim
+for details).
+
+Running RISC-V barebox
+----------------------
+
+Obtain RISC-V GCC/Newlib Toolchain,
+see https://github.com/riscv/riscv-tools/blob/master/README.md
+for details. The ``build.sh`` script from ``riscv-tools`` should
+create toolchain.
+
+Next compile qemu emulator::
+
+ $ git clone https://github.com/riscv/riscv-qemu
+ $ cd riscv-qemu
+ $ cap="no" ./configure \
+ --extra-cflags="-Wno-maybe-uninitialized" \
+ --audio-drv-list="" \
+ --disable-attr \
+ --disable-blobs \
+ --disable-bluez \
+ --disable-brlapi \
+ --disable-curl \
+ --disable-curses \
+ --disable-docs \
+ --disable-kvm \
+ --disable-spice \
+ --disable-sdl \
+ --disable-vde \
+ --disable-vnc-sasl \
+ --disable-werror \
+ --enable-trace-backend=simple \
+ --disable-stack-protector \
+ --target-list=riscv32-softmmu,riscv64-softmmu
+ $ make
+
+Next compile barebox::
+
+ $ make qemu-sifive_defconfig ARCH=riscv
+ ...
+ $ make ARCH=riscv CROSS_COMPILE=<path to your riscv toolchain>/riscv64-unknown-elf-
+
+Run barebox::
+
+ $ <path to riscv-qemu source>/riscv64-softmmu/qemu-system-riscv64 \
+ -nographic -M sifive -kernel <path to barebox sources >/barebox \
+ -serial stdio -monitor none -trace file=/dev/null
+
+ Switch to console [cs0]
+
+
+ barebox 2016.11.0-00006-g3c29f61 #1 Mon Nov 13 22:21:03 MSK 2016
+
+
+ Board: QEMU SiFive
+ Warning: Using dummy clocksource
+ malloc space: 0x00800000 -> 0x00bfffff (size 4 MiB)
+ running /env/bin/init...
+ /env/bin/init not found
+ barebox:/
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
new file mode 100644
index 0000000..baf9ce0
--- /dev/null
+++ b/arch/riscv/Kconfig
@@ -0,0 +1,42 @@
+config RISCV
+ bool
+ select GENERIC_FIND_NEXT_BIT
+ select OFTREE
+ select HAVE_CONFIGURABLE_MEMORY_LAYOUT
+ select HAVE_CONFIGURABLE_TEXT_BASE
+ default y
+
+config GENERIC_LINKER_SCRIPT
+ bool
+ default y
+
+menu "Machine selection"
+
+choice
+ prompt "System type"
+ default MACH_SIFIVE
+
+config MACH_SIFIVE
+ bool "SiFive"
+
+endchoice
+
+config BUILTIN_DTB
+ bool "link a DTB into the barebox image"
+ depends on OFTREE
+
+config BUILTIN_DTB_NAME
+ string "DTB to build into the barebox image"
+ depends on BUILTIN_DTB
+
+source arch/riscv/mach-sifive/Kconfig
+
+endmenu
+
+source common/Kconfig
+source commands/Kconfig
+source net/Kconfig
+source drivers/Kconfig
+source fs/Kconfig
+source lib/Kconfig
+source crypto/Kconfig
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
new file mode 100644
index 0000000..cebcce5
--- /dev/null
+++ b/arch/riscv/Makefile
@@ -0,0 +1,51 @@
+CPPFLAGS += -fno-strict-aliasing
+
+cflags-y += -fno-pic -pipe
+cflags-y += -Wall -Wmissing-prototypes -Wstrict-prototypes \
+ -Wno-uninitialized -Wno-format -Wno-main
+
+LDFLAGS += $(ldflags-y)
+LDFLAGS_barebox += -nostdlib
+
+machine-$(CONFIG_MACH_SIFIVE) := sifive
+board-$(CONFIG_BOARD_QEMU_SIFIVE) := qemu-sifive
+
+TEXT_BASE = $(CONFIG_TEXT_BASE)
+CPPFLAGS += -DTEXT_BASE=$(CONFIG_TEXT_BASE)
+
+machdirs := $(patsubst %,arch/riscv/mach-%/,$(machine-y))
+
+ifeq ($(KBUILD_SRC),)
+CPPFLAGS += $(patsubst %,-I%include,$(machdirs))
+else
+CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs))
+endif
+
+archprepare: maketools
+
+PHONY += maketools
+
+ifneq ($(machine-y),)
+MACH := arch/riscv/mach-$(machine-y)/
+else
+MACH :=
+endif
+
+ifneq ($(board-y),)
+BOARD := arch/riscv/boards/$(board-y)/
+else
+BOARD :=
+endif
+
+common-y += $(BOARD) $(MACH)
+common-y += arch/riscv/lib/
+common-y += arch/riscv/boot/
+
+common-$(CONFIG_OFTREE) += arch/riscv/dts/
+
+CPPFLAGS += $(cflags-y)
+CFLAGS += $(cflags-y)
+
+lds-y := arch/riscv/lib/barebox.lds
+
+CLEAN_FILES += arch/riscv/lib/barebox.lds
diff --git a/arch/riscv/boards/qemu-sifive/.gitignore b/arch/riscv/boards/qemu-sifive/.gitignore
new file mode 100644
index 0000000..d116578
--- /dev/null
+++ b/arch/riscv/boards/qemu-sifive/.gitignore
@@ -0,0 +1 @@
+barebox.lds
diff --git a/arch/riscv/boards/qemu-sifive/Makefile b/arch/riscv/boards/qemu-sifive/Makefile
new file mode 100644
index 0000000..dcfc293
--- /dev/null
+++ b/arch/riscv/boards/qemu-sifive/Makefile
@@ -0,0 +1 @@
+obj-y += board.o
diff --git a/arch/riscv/boards/qemu-sifive/board.c b/arch/riscv/boards/qemu-sifive/board.c
new file mode 100644
index 0000000..ecda850
--- /dev/null
+++ b/arch/riscv/boards/qemu-sifive/board.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+
+static int hostname_init(void)
+{
+ barebox_set_hostname("barebox");
+
+ return 0;
+}
+postcore_initcall(hostname_init);
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
new file mode 100644
index 0000000..d6d28ce
--- /dev/null
+++ b/arch/riscv/boot/Makefile
@@ -0,0 +1,2 @@
+obj-y += start.o
+obj-y += main_entry.o
diff --git a/arch/riscv/boot/main_entry.c b/arch/riscv/boot/main_entry.c
new file mode 100644
index 0000000..18db86d
--- /dev/null
+++ b/arch/riscv/boot/main_entry.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <memory.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/sections.h>
+
+void main_entry(void);
+
+/**
+ * Called plainly from assembler code
+ *
+ * @note The C environment isn't initialized yet
+ */
+void main_entry(void)
+{
+ /* clear the BSS first */
+ memset(__bss_start, 0x00, __bss_stop - __bss_start);
+
+ mem_malloc_init((void *)MALLOC_BASE,
+ (void *)(MALLOC_BASE + MALLOC_SIZE - 1));
+
+ start_barebox();
+}
diff --git a/arch/riscv/boot/start.S b/arch/riscv/boot/start.S
new file mode 100644
index 0000000..1c7612c
--- /dev/null
+++ b/arch/riscv/boot/start.S
@@ -0,0 +1,44 @@
+/*
+ * Startup Code for MIPS CPU
+ *
+ * based on coreboot/src/arch/riscv/bootblock.S
+ *
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm-generic/memory_layout.h>
+
+ .text
+ .section ".text_bare_init"
+ .align 4
+
+.globl _start
+_start:
+
+ li sp, STACK_BASE + STACK_SIZE
+
+ # make room for HLS and initialize it
+ addi sp, sp, -64 /* MENTRY_FRAME_SIZE */
+
+ # poison the stack
+ li t1, STACK_BASE
+ li t0, 0xdeadbeef
+ sd t0, 0(t1)
+
+ # clear any pending interrupts
+ csrwi mip, 0
+
+ tail main_entry
diff --git a/arch/riscv/configs/qemu-sifive_defconfig b/arch/riscv/configs/qemu-sifive_defconfig
new file mode 100644
index 0000000..774dfad
--- /dev/null
+++ b/arch/riscv/configs/qemu-sifive_defconfig
@@ -0,0 +1,75 @@
+CONFIG_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_NAME="qemu-sifive"
+# CONFIG_GLOBALVAR is not set
+CONFIG_TEXT_BASE=0x00001000
+CONFIG_MEMORY_LAYOUT_FIXED=y
+CONFIG_STACK_BASE=0x007f0000
+CONFIG_STACK_SIZE=0x10000
+CONFIG_MALLOC_BASE=0x00800000
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_BOOTM is not set
+CONFIG_PARTITION=y
+# CONFIG_ENV_HANDLING is not set
+CONFIG_DEFAULT_COMPRESSION_GZIP=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_AUTOMOUNT=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_DEFAULTENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_BASENAME=y
+CONFIG_CMD_CMP=y
+CONFIG_CMD_DIRNAME=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_READLINK=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA224SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_SHA384SUM=y
+CONFIG_CMD_SHA512SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_GETOPT=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_READF=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_DISPLAY_TIMINGS=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_OFDEVICE=y
+CONFIG_DRIVER_SERIAL_SIFIVE=y
+# CONFIG_SPI is not set
+# CONFIG_PINCTRL is not set
+CONFIG_FS_BPKFS=y
+CONFIG_FS_UIMAGEFS=y
+CONFIG_ZLIB=y
+CONFIG_BZLIB=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_XZ_DECOMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DIGEST_HMAC_GENERIC=y
diff --git a/arch/riscv/dts/.gitignore b/arch/riscv/dts/.gitignore
new file mode 100644
index 0000000..077903c
--- /dev/null
+++ b/arch/riscv/dts/.gitignore
@@ -0,0 +1 @@
+*dtb*
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
new file mode 100644
index 0000000..f8380b1
--- /dev/null
+++ b/arch/riscv/dts/Makefile
@@ -0,0 +1,9 @@
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME))
+obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
+
+# just to build a built-in.o. Otherwise compilation fails when no devicetree is
+# created.
+obj- += dummy.o
+
+always := $(dtb-y)
+clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts
diff --git a/arch/riscv/dts/qemu-sifive.dts b/arch/riscv/dts/qemu-sifive.dts
new file mode 100644
index 0000000..61945f2
--- /dev/null
+++ b/arch/riscv/dts/qemu-sifive.dts
@@ -0,0 +1,19 @@
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+ model = "QEMU SiFive";
+ compatible = "sifive,qemu";
+
+ /* Digilent Arty has 256MB DDR3L */
+ memory {
+ device_type = "memory";
+ reg = <0 0x0 0x10000000>;
+ };
+
+ uart: uart {
+ compatible = "sifive,uart";
+ reg = <0 0x40002000 0x10>;
+ };
+};
diff --git a/arch/riscv/dts/skeleton.dtsi b/arch/riscv/dts/skeleton.dtsi
new file mode 100644
index 0000000..38ead82
--- /dev/null
+++ b/arch/riscv/dts/skeleton.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value. The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0 0>; };
+};
diff --git a/arch/riscv/include/asm/barebox.h b/arch/riscv/include/asm/barebox.h
new file mode 100644
index 0000000..2997587
--- /dev/null
+++ b/arch/riscv/include/asm/barebox.h
@@ -0,0 +1 @@
+/* dummy */
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
new file mode 100644
index 0000000..e77ab83
--- /dev/null
+++ b/arch/riscv/include/asm/bitops.h
@@ -0,0 +1,35 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+
+#ifndef _ASM_BITOPS_H_
+#define _ASM_BITOPS_H_
+
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/ops.h>
+
+#define set_bit(x, y) __set_bit(x, y)
+#define clear_bit(x, y) __clear_bit(x, y)
+#define change_bit(x, y) __change_bit(x, y)
+#define test_and_set_bit(x, y) __test_and_set_bit(x, y)
+#define test_and_clear_bit(x, y) __test_and_clear_bit(x, y)
+#define test_and_change_bit(x, y) __test_and_change_bit(x, y)
+
+#endif /* _ASM_BITOPS_H_ */
diff --git a/arch/riscv/include/asm/bitsperlong.h b/arch/riscv/include/asm/bitsperlong.h
new file mode 100644
index 0000000..4641e7e
--- /dev/null
+++ b/arch/riscv/include/asm/bitsperlong.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_BITSPERLONG_H
+#define __ASM_BITSPERLONG_H
+
+#ifdef __riscv64
+#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
+
+#endif /* __ASM_BITSPERLONG_H */
diff --git a/arch/riscv/include/asm/byteorder.h b/arch/riscv/include/asm/byteorder.h
new file mode 100644
index 0000000..994a61a
--- /dev/null
+++ b/arch/riscv/include/asm/byteorder.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_RISCV_BYTEORDER_H
+#define _ASM_RISCV_BYTEORDER_H
+
+#if defined(__RISCVEL__)
+#include <linux/byteorder/little_endian.h>
+#elif defined(__RISCVEB__)
+#include <linux/byteorder/big_endian.h>
+#else
+#error "Unknown endianness"
+#endif
+
+#endif /* _ASM_RISCV_BYTEORDER_H */
diff --git a/arch/riscv/include/asm/common.h b/arch/riscv/include/asm/common.h
new file mode 100644
index 0000000..bc8a17e
--- /dev/null
+++ b/arch/riscv/include/asm/common.h
@@ -0,0 +1,6 @@
+#ifndef ASM_RISCV_COMMON_H
+#define ASM_RISCV_COMMON_H
+
+/* nothing special yet */
+
+#endif /* ASM_RISCV_COMMON_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
new file mode 100644
index 0000000..7134fa0
--- /dev/null
+++ b/arch/riscv/include/asm/elf.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_RISCV_ELF_H__
+#define __ASM_RISCV_ELF_H__
+
+#if __SIZEOF_POINTER__ == 8
+#define ELF_CLASS ELFCLASS64
+#define CONFIG_PHYS_ADDR_T_64BIT
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+
+#endif /* __ASM_RISCV_ELF_H__ */
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
new file mode 100644
index 0000000..d9aca42
--- /dev/null
+++ b/arch/riscv/include/asm/io.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_RISCV_IO_H
+#define __ASM_RISCV_IO_H
+
+#include <asm-generic/io.h>
+
+#define IO_SPACE_LIMIT 0
+
+#endif /* __ASM_RISCV_IO_H */
diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h
new file mode 100644
index 0000000..22cae62
--- /dev/null
+++ b/arch/riscv/include/asm/posix_types.h
@@ -0,0 +1 @@
+#include <asm-generic/posix_types.h>
diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
new file mode 100644
index 0000000..2b8c516
--- /dev/null
+++ b/arch/riscv/include/asm/sections.h
@@ -0,0 +1 @@
+#include <asm-generic/sections.h>
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
new file mode 100644
index 0000000..2997587
--- /dev/null
+++ b/arch/riscv/include/asm/string.h
@@ -0,0 +1 @@
+/* dummy */
diff --git a/arch/riscv/include/asm/swab.h b/arch/riscv/include/asm/swab.h
new file mode 100644
index 0000000..60a9012
--- /dev/null
+++ b/arch/riscv/include/asm/swab.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+/* nothing. use generic functions */
+
+#endif /* _ASM_SWAB_H */
diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h
new file mode 100644
index 0000000..ba386ab
--- /dev/null
+++ b/arch/riscv/include/asm/types.h
@@ -0,0 +1,60 @@
+#ifndef __ASM_RISCV_TYPES_H
+#define __ASM_RISCV_TYPES_H
+
+#ifdef __riscv64
+/*
+ * This is used in dlmalloc. On RISCV64 we need it to be 64 bit
+ */
+#define INTERNAL_SIZE_T unsigned long
+
+/*
+ * This is a Kconfig variable in the Kernel, but we want to detect
+ * this during compile time, so we set it here.
+ */
+#define CONFIG_PHYS_ADDR_T_64BIT
+
+#endif
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#include <asm/bitsperlong.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_RISCV_TYPES_H */
diff --git a/arch/riscv/include/asm/unaligned.h b/arch/riscv/include/asm/unaligned.h
new file mode 100644
index 0000000..aaebc06
--- /dev/null
+++ b/arch/riscv/include/asm/unaligned.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_RISCV_UNALIGNED_H
+#define _ASM_RISCV_UNALIGNED_H
+
+/*
+ * FIXME: this file is copy-n-pasted from sandbox's unaligned.h
+ */
+
+#include <linux/unaligned/access_ok.h>
+#include <linux/unaligned/generic.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+#else
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+#endif
+
+#endif /* _ASM_RISCV_UNALIGNED_H */
diff --git a/arch/riscv/lib/.gitignore b/arch/riscv/lib/.gitignore
new file mode 100644
index 0000000..d116578
--- /dev/null
+++ b/arch/riscv/lib/.gitignore
@@ -0,0 +1 @@
+barebox.lds
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
new file mode 100644
index 0000000..07a1b2b
--- /dev/null
+++ b/arch/riscv/lib/Makefile
@@ -0,0 +1,3 @@
+extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += barebox.lds
+
+obj-$(CONFIG_BUILTIN_DTB) += dtb.o
diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
new file mode 100644
index 0000000..22f382b
--- /dev/null
+++ b/arch/riscv/lib/asm-offsets.c
@@ -0,0 +1,12 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#include <linux/kbuild.h>
+
+int main(void)
+{
+ return 0;
+}
diff --git a/arch/riscv/lib/barebox.lds.S b/arch/riscv/lib/barebox.lds.S
new file mode 100644
index 0000000..831c3e4
--- /dev/null
+++ b/arch/riscv/lib/barebox.lds.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm-generic/barebox.lds.h>
+
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+SECTIONS
+{
+ . = TEXT_BASE;
+
+ . = ALIGN(8);
+ .text :
+ {
+ _start = .;
+ *(.text_entry*)
+ _stext = .;
+ _text = .;
+ __bare_init_start = .;
+ *(.text_bare_init*)
+ __bare_init_end = .;
+ *(.text*)
+ }
+ BAREBOX_BARE_INIT_SIZE
+
+ PRE_IMAGE
+
+ . = ALIGN(8);
+ .rodata : { *(.rodata*) }
+
+ _etext = .; /* End of text and rodata section */
+ _sdata = .;
+
+ . = ALIGN(8);
+ .data : { *(.data*) }
+
+ .barebox_imd : { BAREBOX_IMD }
+
+ . = ALIGN(8);
+ .got : { *(.got*) }
+
+ . = .;
+ __barebox_cmd_start = .;
+ .barebox_cmd : { BAREBOX_CMDS }
+ __barebox_cmd_end = .;
+
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
+ __barebox_initcalls_start = .;
+ .barebox_initcalls : { INITCALLS }
+ __barebox_initcalls_end = .;
+
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
+ __usymtab_start = .;
+ __usymtab : { BAREBOX_SYMS }
+ __usymtab_end = .;
+
+ .oftables : { BAREBOX_CLK_TABLE() }
+
+ .dtb : { BAREBOX_DTB() }
+
+ _edata = .;
+ . = ALIGN(8);
+ __bss_start = .;
+ .bss : { *(.bss*) }
+ __bss_stop = .;
+ _end = .;
+}
diff --git a/arch/riscv/lib/dtb.c b/arch/riscv/lib/dtb.c
new file mode 100644
index 0000000..09f519d
--- /dev/null
+++ b/arch/riscv/lib/dtb.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <of.h>
+
+extern char __dtb_start[];
+
+static int of_riscv_init(void)
+{
+ struct device_node *root;
+
+ root = of_get_root_node();
+ if (root)
+ return 0;
+
+ root = of_unflatten_dtb(__dtb_start);
+ if (!IS_ERR(root)) {
+ pr_debug("using internal DTB\n");
+ of_set_root_node(root);
+ if (IS_ENABLED(CONFIG_OFDEVICE))
+ of_probe();
+ }
+
+ return 0;
+}
+core_initcall(of_riscv_init);
diff --git a/arch/riscv/mach-sifive/Kconfig b/arch/riscv/mach-sifive/Kconfig
new file mode 100644
index 0000000..11251dd
--- /dev/null
+++ b/arch/riscv/mach-sifive/Kconfig
@@ -0,0 +1,16 @@
+if MACH_SIFIVE
+
+config ARCH_TEXT_BASE
+ hex
+ default 0x00001000
+
+choice
+ prompt "Board type"
+
+config BOARD_QEMU_SIFIVE
+ bool "qemu sifive"
+ select HAS_DEBUG_LL
+
+endchoice
+
+endif
diff --git a/arch/riscv/mach-sifive/Makefile b/arch/riscv/mach-sifive/Makefile
new file mode 100644
index 0000000..d9c51e7
--- /dev/null
+++ b/arch/riscv/mach-sifive/Makefile
@@ -0,0 +1,3 @@
+# just to build a built-in.o. Otherwise compilation fails when no o-files is
+# created.
+obj- += dummy.o
diff --git a/arch/riscv/mach-sifive/include/mach/debug_ll.h b/arch/riscv/mach-sifive/include/mach/debug_ll.h
new file mode 100644
index 0000000..b2dbfc2
--- /dev/null
+++ b/arch/riscv/mach-sifive/include/mach/debug_ll.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_SIFIVE_DEBUG_LL__
+#define __MACH_SIFIVE_DEBUG_LL__
+
+/** @file
+ * This File contains declaration for early output support
+ */
+
+#include <linux/kconfig.h>
+#include <asm/io.h>
+
+#define UART_BASE 0x40002000
+#define R_DATA (0 << 2)
+#define R_RXCNT (2 << 2)
+
+static inline void PUTC_LL(int ch)
+{
+ if (IS_ENABLED(CONFIG_DEBUG_LL))
+ __raw_writeb(ch, (u8 *)UART_BASE + R_DATA);
+}
+
+#endif /* __MACH_SIFIVE_DEBUG_LL__ */
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index d0a62bd..0824b04 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -4,7 +4,7 @@ config OFTREE
config OFTREE_MEM_GENERIC
depends on OFTREE
- depends on PPC || ARM || ARCH_EFI || OPENRISC || SANDBOX
+ depends on PPC || ARM || ARCH_EFI || OPENRISC || SANDBOX || RISCV
def_bool y
config DTC
--
2.10.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH] pcm049: Add 1 GByte RAM with DUAL DIE Single Rank
From: Maik Otto @ 2016-11-14 9:47 UTC (permalink / raw)
To: barebox; +Cc: Maik Otto
tested with Micron MT42L128M64D2LL-25WT and MT42L128M64D2LL-25WT
Signed-off-by: Maik Otto <m.otto@phytec.de>
---
arch/arm/boards/phytec-phycore-omap4460/lowlevel.c | 32 +++++++++++++++++++-
1 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c b/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c
index c082594..71ab793 100644
--- a/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c
@@ -30,6 +30,13 @@
#include <asm/barebox-arm-head.h>
#define TPS62361_VSEL0_GPIO 182
+#define LPDDR2_2G 0x5
+#define LPDDR2_4G 0x6
+#define LPDDR2_DENSITY_MASK 0x3C
+#define LPDDR2_DENSITY_SHIFT 2
+#define EMIF_SDRAM_CONFIG 0x0008
+#define EMIF_LPDDR2_MODE_REG_CONFIG 0x0050
+#define EMIF_LPDDR2_MODE_REG_DATA 0x0040
void set_muxconf_regs(void);
@@ -61,8 +68,23 @@ static const struct ddr_regs ddr_regs_mt42L128M64_25_400_mhz = {
.mr2 = 0x4
};
+static const struct ddr_regs ddr_regs_mt42L128M64D2LL_25_400_mhz = {
+ .tim1 = 0x10EB0662,
+ .tim2 = 0x205715D2,
+ .tim3 = 0x00B1C53F,
+ .phy_ctrl_1 = 0x849FF409,
+ .ref_ctrl = 0x00000618,
+ .config_init = 0x80001AB2,
+ .config_final = 0x80001AB2,
+ .zq_config = 0x500B3214,
+ .mr1 = 0x83,
+ .mr2 = 0x4
+};
+
static void noinline pcm049_init_lowlevel(void)
{
+ unsigned int density;
+
struct dpll_param core = OMAP4_CORE_DPLL_PARAM_19M2_DDR400;
struct dpll_param mpu44xx = OMAP4_MPU_DPLL_PARAM_19M2_MPU1000;
struct dpll_param mpu4460 = OMAP4_MPU_DPLL_PARAM_19M2_MPU920;
@@ -75,9 +97,17 @@ static void noinline pcm049_init_lowlevel(void)
set_muxconf_regs();
#ifdef CONFIG_1024MB_DDR2RAM
+ omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
+ writel(EMIF_SDRAM_CONFIG, OMAP44XX_EMIF1_BASE +
+ EMIF_LPDDR2_MODE_REG_CONFIG);
+ density = (readl(OMAP44XX_EMIF1_BASE + EMIF_LPDDR2_MODE_REG_DATA) &
+ LPDDR2_DENSITY_MASK) >> LPDDR2_DENSITY_SHIFT;
+ if (density == LPDDR2_2G)
omap4_ddr_init(&ddr_regs_mt42L128M64_25_400_mhz, &core);
+ else if (density == LPDDR2_4G)
+ omap4_ddr_init(&ddr_regs_mt42L128M64D2LL_25_400_mhz, &core);
#else
- omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
+ omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
#endif
/* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
--
1.7.0.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* usb otg port not working on an imx25 soc
From: iw3gtf @ 2016-11-14 12:57 UTC (permalink / raw)
To: barebox
Hi,
I'm currently working on an embedded board with an imx25 soc and I want
to enable the usb otg port of the soc; in my use case I just want the otg port
to be configured in usb host mode and use the integrated UTMI phy.
I built barebox with usb support and the usb ports are actually found:
barebox:/ usb
usb: USB: scanning bus for devices...
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=256, index=0
imx-usb imx-usb0: USB_DT_DEVICE request
imx-usb imx-usb0: req=5 (0x5), typ(0xe=0 0), value=1, index=0
imx-usb imx-usb0: USB_REQ_SET_ADDRESS
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=256, index=0
imx-usb imx-usb0: USB_DT_DEVICE request
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=512, index=0
imx-usb imx-usb0: USB_DT_CONFIG config
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=512, index=0
imx-usb imx-usb0: USB_DT_CONFIG config
imx- iumsbx-usb0: req=9 (0x9), type=0 (0x0), value=1, index=0
imx-usb imx-usb0: USB_REQ_SET_CONFIGURATION
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=768, index=0
imx-usb imx-usb0: USB_DT_STRING config
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=769, index=1
imx-usb imx-usb0: USB_DT_STRING config
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=770, index=1
imx-usb imx-usb0: USB_DT_STRING config
usb: Bus 001 Device 001: ID 000000: 00EHCI Host Controller
imx-usb imx-usb0: req=6 (0x6), type=160 (0xa0), value=10496, index=0
omx-usb imx-usb0: USB_DT_HUB figc
nimx-usb imx-usb0: req=6 (0x6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb0: USB_DT_HUB config
imx-usb imx-usb0: req=0 (0x0), type=160 (0xa0), value=0, index=0
imx-usb imx-usb0: req=1 (0x1), type=35 (0x23), value=8, index=1
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=3 (0x3), type=35 (0x23), value=8, index=1
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=0 (0x0), type=163 (0xa3), value=0, index=1
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=256, index=0
imx-usb imx-usb1: USB_DT_DEVICE request
imx-usb imx-usb1: req=5 (0x5), type=0 (0x0), value=2, index=0
imx-usb imx-usb1: USB_REQ_SET_ADDRESS
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=256, index=0
imx-usb imx-usb1: USB_DT_DEVICE request
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=512, index=0
imx-usb imx-usb1: USB_DT_CONFIG config
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=512, index=0
imx-usb imx-usb1: USB_DT_CONFIG config
imx-usb imx-usb1: req=9 (0x9), type=0 (0x0), value=1, index=0
imx-usb imx-usb1: USB_REQ_SET_CONFIGURATION
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=768, index=0
imx-usb imx-usb1: USB_DT_STRING config
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=769, index=1
imx-usb imx-usb1: USB_DT_STRING config
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=770, index=1
imx-usb imx-usb1: USB_DT_STRING config
usb: Bus 002 Device 002: ID 0000:0000 EHCI Host Controller
imx-usb imx-usb1: req=6 (0x6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb1: USB_DT_HUB config
imx-usb imx-usb1: req=6 (0x6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb1: USB_DT_HUB config
imx-usb imx-usb1: req=0 (0x0), type=160 (0xa0), value=0, index=0
imx-usb imx-usb1: req=1 (0x1), type=35 (0x23), value=8, index=1
imx-usb imxb1:- usLen is 0
imx-usb imx-usb1: req=3 (0x3), type=35 (0x23), value=8, index=1
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=0 (0x0), type=163 (0x)a, 3value=0, index=1
usUb: 2 SB Device(s) found
barebox:/
but if I plug a usb device (usb memory stick) in the otg port:
barebox:/ usb
usb: USB: scanning bus for devices...
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=256, index=0
imx-usb imx-usb0: USB_DT_DEVICE request
imx-usb imx-usb0: req=5 (0x5), type=0 (0x0), value=1, index=0
imx-usb imx-usb0: USB_REQ_SET_ADDRESS
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=256, index=0
imx-usb imx-usb0: USB_DT_DEVICE request
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=512, index=0
imx-usb imx-usb0: USB_DT_CONFIG config
imx-usb imx-usb0: req=6 (0 typex6),=128 (0x80), value=512, nidex=0
imx-usb imx-usb0: USB_DT_CONFIG config
imx-usb imx-usb0: req=9 (0x9), type=0 (0x0), value=1, index=0
imx-usb imx-usb0: USB_REQ_SET_CONFIGURATION
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=6 (0x6), type=128 0(0x8), value=768, index=0
imx-usb imx-usb0: USB_DT_STRING config
imx-usb imx-usb0: req=6 (0x6)28, type= 1(0x80), value=769, index=1
imx-usb imx-usb0: USB_DT_STRING config
imx-usb imx-usb0: req=6 (0x6), type=128 (0x80), value=770, index=1
imx-usb imx-usb0: USB_DT_STRING config
usb: Bus 001 Device 001: ID 0000:0000 EHCI Host Controller
imx-usb imx-usb0: req(=06x 6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb0: USB_DT_HUB config
imx-usb imx-usb0: req=6 (0x6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb0: USB_DT_HUB config
imx-usb imx-usb0: req=0 (0x0), type=160 (0xa0), value=0, index=0
imx-usb imx-usb0: req=1 (0x1), type=35 (0x23), value=8, index=1
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=3 (0x3), type=35 (0x23), va=lue8, index=1
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=0 (0x0), type=163 (0xa3), value=0, index=1
usb-hub usb1: usb_hub_port_connect_change: called. port 1, dev->speed: 3
imx-usb imx-usb0: req=0 (0x0), type=163 (0xa3), value=0, index=1
usb-hub usb1: portstatus 101, change 1
usb-hub usb1: portstatus 101, change 1, 12 Mb/s
imx-usb imx-usb0: req=1 (0x1), type=35 (0x23), value=16, index=1
imx-usb imx-usb0: Len is 0
usb-hub usb1: hub_port_reset: resetting port 1...
imx-usb imx-usb0: req=3 (0x3), type=35 (0x23), value=4, index=1
imx-usb imx-usb0: Len is 0
imx-usb imx-usb0: req=0 (0x0), type=163 (0xa3), value=0, index=1
usb-hub usb1: portstatus 101, change 13, 12 Mb/s
usb-hub usb1: STAT_C_CONNECTION = 1 STAT_CONNECTION = 1 USB_PORT_STAT_ENABLE 0
usb-hub usb1: hub_port_reset: trace 1: go out here. portchange: 0x00000013, portstatus: 0x00000101
usb-hub usb1: cannot reset port 1!?
imx-usb imx-usb1: req=6 (0x6), type=128 l(ue=0x80), va256, index=0
imx-usb imx-usb1: USB_DT_DEVICE request
imx-usb imx-usb1: req=5 (0x5), type=0 (0x0), value=2, index=0
imx-usb imx-usb1: USB_REQ_SET_ADDRESS
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=256, ind
ex=0imx-usb imx-usb1: USB_DT_DEVICE request
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=512, index=0
imx-usb imx-usb1: USB_DT_CONFIG config
imx-usb imx-usb1: req=6 (0x ty6),pe=128 (0x80), value=512, index=0
imx-usb imx-usb1: USB_DT_CONFIG config
imx-usb imx-usb1: req=9 (0x9), type=0 (0x0), value=1, index=0
imx-usb imx-usb1: USB_REQ_SET_CONFIGURATION
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=768, index=0
imx-usb imx-usb1:B _USDT_STRING config
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80), value=769, index=1
imx-usb imx-usb1: USB_DT_STRING config
imx-usb imx-usb1: req=6 (0x6), type=128 (0x80),v alue=770, index=1
imx-usb imx-usb1: USB_DT_STRING config
usb: Bus 002 Device 002: ID 0000:0000 EHCI Host Controller
imx-usb imx-usb1: req=6 (0x6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb1: USB_DT_HUB config
imx-usb imx-usb1: req=6 (0x6), type=160 (0xa0), value=10496, index=0
imx-usb imx-usb1: USB_DT_HUB config
imx-usb imx-usb1: req=0 (0x0), type=160 (0xa0), value=0, index=0
imx-usb imx-usb1: req=1 (0x1), type=35 (0x23), value=8, index=1
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=3 (0x3), type=35 (0x23), value=8, index=1
imx-usb imx-usb1: Len is 0
imx-usb imx-usb1: req=0 (0x0), type=163 (0xa3), value=0, index=1
usb: 2 USB Device(s) found
barebox:/
I get a port reset error:
...
usb-hub usb1: cannot reset port 1!?
...
I added some trace dev_info's in the code and exactly found the failing test,
in the source file 'barebox/drivers/usb/core/hub.c':
int hub_port_reset(struct usb_device *dev, int port,
unsigned short *portstat)
{
...
if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
!(portstatus & USB_PORT_STAT_CONNECTION)) {
dev_info(&dev->dev, "%s: trace 1: go out here. portchange: 0x%08x, portstatus: 0x%08x\n",
__func__, portchange, portstatus);
return -1;
}
if (portstatus & USB_PORT_STAT_ENABLE)
break;
mdelay(200);
...
The failing expression is (portchange & USB_PORT_STAT_C_CONNECTION).
On the other end I'm able to upload and start a barebox image with the tool 'imx-usb-loader',
so the usb otg related HW cannot be badly broken on my custom dev board.
My first basic question is if someone here in the list is also working with an imx25 and can confirm that
the usb otg is .
The second question is about the meaning of the failing expression, in case it could give a hint of
what goes wrong on my board.
thanks,
giorgio
Giorgio, iw3gtf@arcor.de
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: [PATCH v3 2/3] watchdog: add designware driver
From: Sascha Hauer @ 2016-11-14 15:14 UTC (permalink / raw)
To: Steffen Trumtrar; +Cc: barebox
In-Reply-To: <20161017075052.30802-2-s.trumtrar@pengutronix.de>
On Mon, Oct 17, 2016 at 09:50:51AM +0200, Steffen Trumtrar wrote:
> Port the linux v4.8-rc1 Synopsys DesignWare watchdog driver to barebox.
>
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> ---
> +static void __noreturn dw_wdt_restart_handle(struct restart_handler *rst)
> +{
> + struct dw_wdt *dw_wdt;
> +
> + dw_wdt = container_of(rst, struct dw_wdt, restart);
> +
> + dw_wdt->wdd.set_timeout(&dw_wdt->wdd, -1);
> +
> + mdelay(1000);
> +
> + hang();
> +}
> +
> +static int dw_wdt_drv_probe(struct device_d *dev)
> +{
> + struct watchdog *wdd;
> + struct dw_wdt *dw_wdt;
> + struct resource *mem;
> + int ret;
> +
> + dw_wdt = xzalloc(sizeof(*dw_wdt));
> +
> + mem = dev_request_mem_resource(dev, 0);
> + dw_wdt->regs = IOMEM(mem->start);
> + if (IS_ERR(dw_wdt->regs))
> + return PTR_ERR(dw_wdt->regs);
Just stumbled upon this. The result of dev_request_mem_resource() must
be error checked, not the IOMEM(). If mem is valid then IOMEM() is valid
aswell.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Compiler issues
From: Jose Luis Zabalza @ 2016-11-15 5:32 UTC (permalink / raw)
To: Holger Schurig; +Cc: barebox
In-Reply-To: <87polymnlc.fsf@gmail.com>
Thanks for your reply, Holger.
I am sorry. I have to apologize for no mentioning that this thread is
the continuation of "Re: Configure RAM size on iMX53 board".
I will summarize the situation. I have a iMX53 custom board with two
versions, 512MB (only CS0) and 1GB (CS0 and CS1) RAM. Both versions
are running with same old uboot binary because uboot don't access to
high memory address. I write code for support Barebox on 1GB version
successfully but hangs on 512MB version. No messages are displayed on
console.
Sascha recomends me don't configure CS1 on DCD table and use
barebox_arm_entry() function instead of imx53_barebox_entry() but it
don't work.
So, the first step was find where the code hangs.
I activated a GPIO on DCD table and deactivate on Barebox code to know
if a function is executed.
==========<cut>===========
wm 32 0x53F84004 0x00000008 // Set GPIO as output
wm 32 0x53F84000 0x00000008 // Activate GPIO
...
*((unsigned *)0x53F84000)=0; // Deactivate GPIO
==========<cut>===========
With the trial and error method, I found the execution lack on
initcall secuence. Specifically don't reach myboard_initcall()
==========<cut>===========
static int myboard_init(void)
{
*((unsigned *)0x53F84000)=0;
imx_esdctl_disable();
arm_add_mem_device("ram0", MX53_CSD0_BASE_ADDR, SZ_512M);
return 0;
}
core_initcall(myboard_init);
==========<cut>===========
So I changed core_initcall() to pure_initcall() for early
myboard_init() execution and It was good but Barebox hangs on another
initcall function.
Next trial and error session I found imx_gpio_add() was not reached,
so I suspect it was a compiler problem or a timing problem. I
discarded the timing problem because It was very repetitive.
I changed -Os option with -O0 on Makefile. Now imx_gpio_add() are
executed Ok but net_init() hangs.
The final firework:
==========<cut barebox/net/net.c>===========
//
// this code don't deactivate the GPIO
//
static int net_init(void)
{
int i;
for (i = 0; i < PKTBUFSRX; i++)
NetRxPackets[i] = net_alloc_packet();
*((unsigned *)0x53F84000)=0;
==========<cut>===========
//
// This code YES. It deactivate the GPIO
//
static int net_init(void)
{
volatile int i;
for (i = 0; i < PKTBUFSRX; i++)
{
if(i > 10)
{
// this code is not executed because PKTBUFSRX is 4
}
NetRxPackets[i] = net_alloc_packet();
}
*((unsigned *)0x53F84000)=0;
==========<cut>===========
Now, the code hangs on other unknow initcall function but I think
that's not the problem.
Some idea?
Some dark compiler flag to de/activate ?
Thanks in advanced.
2016-11-14 10:12 GMT+01:00 Holger Schurig <holgerschurig@gmail.com>:
> Jose Luis Zabalza <jlz.3008@gmail.com> writes:
>
>> I continue to have problems with memory size but I suspect they may be
>> due to a compiler issue.
>
> I doubt it ... but what made you thinking this?
>
> (BTW, I'm using arm-linux-gnueabihf-gcc 4.9.2-10 from Debian for
> Barebox, Kernel and some userspace stuff)
>
>
> You should be more specific, e.g. what architecture are you using?
> How's your .config file? Maybe you simply deselect things there?
>
> Did you know that you can run "nm --size-sort barebox | tail" to find out what
> takes the most space?
>
>
> Holger
--
José Luis Zabalza
jlz.3008 a t gmail.com
Linux Counter 172551
https://linuxcounter.net/cert/172551.png
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [PATCH 1/2] regmap: Add regmap_write_bits() function
From: Andrey Smirnov @ 2016-11-15 6:21 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Add code implementing a simple version of regmap_write_bits().
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/base/regmap/regmap.c | 27 +++++++++++++++++++++++++++
include/regmap.h | 6 +++++-
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a042a1a..52b7d88 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -137,6 +137,33 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
}
/**
+ * regmap_write_bits - write bits of a register in a map
+ *
+ * @map: The map
+ * @reg: The register offset of the register
+ * @mask: Mask indicating bits to be modified
+ * (1 - modified, 0 - untouched)
+ * @val: Bit value to be set
+ *
+ * Returns 0 for success or negative error code on failure
+ */
+int regmap_write_bits(struct regmap *map, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ int ret;
+ unsigned int tmp, orig;
+
+ ret = regmap_read(map, reg, &orig);
+ if (ret != 0)
+ return ret;
+
+ tmp = orig & ~mask;
+ tmp |= val & mask;
+
+ return regmap_write(map, reg, tmp);
+}
+
+/**
* regmap_bulk_read(): Read data from the device
*
* @map: Register map to read from
diff --git a/include/regmap.h b/include/regmap.h
index bcbe6c1..9675a17 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -60,4 +60,8 @@ int regmap_get_val_bytes(struct regmap *map);
int regmap_get_max_register(struct regmap *map);
int regmap_get_reg_stride(struct regmap *map);
-#endif /* __REGMAP_H */
\ No newline at end of file
+int regmap_write_bits(struct regmap *map, unsigned int reg,
+ unsigned int mask, unsigned int val);
+
+
+#endif /* __REGMAP_H */
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 2/2] gpio: Port SX150x driver from Linux
From: Andrey Smirnov @ 2016-11-15 6:21 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In-Reply-To: <1479190874-10392-1-git-send-email-andrew.smirnov@gmail.com>
Add a very abridged version of SX150x driver from Linux. New, "pinctrl"
version of the driver was used as a base. As it was already mentioned
this driver supports very limited amount of the original functionality,
and the following are the features that were dropped:
- Interrupt support
- Support for any chip other that SX150x (due to lack of HW to test
with)
- Any pinctlr-like functions: pull-up/pull-down, open-drain,
etc. configuration
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/gpio/Kconfig | 8 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-sx150x.c | 274 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 283 insertions(+)
create mode 100644 drivers/gpio/gpio-sx150x.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index fe62778..434c568 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -124,6 +124,14 @@ config GPIO_DESIGNWARE
help
Say Y or M here to build support for the Synopsys DesignWare APB
GPIO block.
+
+config GPIO_SX150X
+ bool "Semtec SX150x I/O ports"
+ depends on I2C
+ help
+ Say Y here to build support for the Semtec Sx150x I2C GPIO
+ expander chip.
+
endmenu
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 248100f..7442c44 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
obj-$(CONFIG_GPIO_DESIGNWARE) += gpio-dw.o
obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o
+obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c
new file mode 100644
index 0000000..7b8cfb5
--- /dev/null
+++ b/drivers/gpio/gpio-sx150x.c
@@ -0,0 +1,274 @@
+/*
+ * Driver for SX150x I2C GPIO expanders
+ *
+ * This code was ported from linux-4.9 kernel driver by
+ * Andrey Smirnov <andrew.smirnov@gmail.com>.
+ *
+ * Orginal code with it's copyright info can be found in
+ * drivers/pinctrl/pinctrl-sx150x.c
+ *
+ * Note: That although linux driver was converted from being a GPIO
+ * subsystem to Pinctrl subsytem driver, due to Barebox's lack of
+ * similar provisions this driver is still a GPIO driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <driver.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <i2c/i2c.h>
+#include <regmap.h>
+
+#include <gpio.h>
+#include <of_device.h>
+
+enum {
+ SX150X_123 = 0,
+ SX150X_456,
+ SX150X_789,
+};
+
+enum {
+ SX150X_MAX_REGISTER = 0xad,
+};
+
+struct sx150x_device_data {
+ u8 model;
+ u8 reg_dir;
+ u8 reg_data;
+ u8 ngpios;
+};
+
+struct sx150x_gpio {
+ struct device *dev;
+ struct i2c_client *client;
+ struct gpio_chip gpio;
+ struct regmap *regmap;
+ const struct sx150x_device_data *data;
+};
+
+static const struct sx150x_device_data sx1503q_device_data = {
+ .model = SX150X_123,
+ .reg_dir = 0x02,
+ .reg_data = 0x00,
+ .ngpios = 16,
+};
+
+static struct sx150x_gpio *to_sx150x_gpio(struct gpio_chip *gpio)
+{
+ return container_of(gpio, struct sx150x_gpio, gpio);
+}
+
+static int sx150x_gpio_get_direction(struct gpio_chip *gpio,
+ unsigned int offset)
+{
+ struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio);
+ unsigned int value;
+ int ret;
+
+ ret = regmap_read(sx150x->regmap, sx150x->data->reg_dir, &value);
+ if (ret < 0)
+ return ret;
+
+ return !!(value & BIT(offset));
+}
+
+static int sx150x_gpio_get(struct gpio_chip *gpio, unsigned int offset)
+{
+ struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio);
+ unsigned int value;
+ int ret;
+
+ ret = regmap_read(sx150x->regmap, sx150x->data->reg_data, &value);
+ if (ret < 0)
+ return ret;
+
+ return !!(value & BIT(offset));
+}
+
+static int __sx150x_gpio_set(struct sx150x_gpio *sx150x, unsigned int offset,
+ int value)
+{
+ return regmap_write_bits(sx150x->regmap, sx150x->data->reg_data,
+ BIT(offset), value ? BIT(offset) : 0);
+}
+
+
+static void sx150x_gpio_set(struct gpio_chip *gpio, unsigned int offset,
+ int value)
+{
+ __sx150x_gpio_set(to_sx150x_gpio(gpio), offset, value);
+}
+
+static int sx150x_gpio_direction_input(struct gpio_chip *gpio,
+ unsigned int offset)
+{
+ struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio);
+
+ return regmap_write_bits(sx150x->regmap,
+ sx150x->data->reg_dir,
+ BIT(offset), BIT(offset));
+}
+
+static int sx150x_gpio_direction_output(struct gpio_chip *gpio,
+ unsigned int offset, int value)
+{
+ struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio);
+ int ret;
+
+ ret = __sx150x_gpio_set(sx150x, offset, value);
+ if (ret < 0)
+ return ret;
+
+ return regmap_write_bits(sx150x->regmap,
+ sx150x->data->reg_dir,
+ BIT(offset), 0);
+}
+
+static int sx150x_regmap_reg_width(struct sx150x_gpio *sx150x,
+ unsigned int reg)
+{
+ return sx150x->data->ngpios;
+}
+
+/*
+ * In order to mask the differences between 16 and 8 bit expander
+ * devices we set up a sligthly ficticious regmap that pretends to be
+ * a set of 16-bit registers and transparently reconstructs those
+ * registers via multiple I2C/SMBus reads
+ *
+ * This way the rest of the driver code, interfacing with the chip via
+ * regmap API, can work assuming that each GPIO pin is represented by
+ * a group of bits at an offset proportioan to GPIO number within a
+ * given register.
+ *
+ */
+static int sx150x_regmap_reg_read(void *context, unsigned int reg,
+ unsigned int *result)
+{
+ int ret, n;
+ struct sx150x_gpio *sx150x = context;
+ struct i2c_client *i2c = sx150x->client;
+ const int width = sx150x_regmap_reg_width(sx150x, reg);
+ unsigned int idx, val;
+
+ /*
+ * There are four potential cases coverd by this function:
+ *
+ * 1) 8-pin chip, single configuration bit register
+ *
+ * This is trivial the code below just needs to read:
+ * reg [ 7 6 5 4 3 2 1 0 ]
+ *
+ * 2) 16-pin chip, single configuration bit register
+ *
+ * The read will be done as follows:
+ * reg [ f e d c b a 9 8 ]
+ * reg + 1 [ 7 6 5 4 3 2 1 0 ]
+ *
+ */
+
+ for (n = width, val = 0, idx = reg; n > 0; n -= 8, idx++) {
+ val <<= 8;
+
+ ret = i2c_smbus_read_byte_data(i2c, idx);
+ if (ret < 0)
+ return ret;
+
+ val |= ret;
+ }
+
+ *result = val;
+
+ return 0;
+}
+
+static int sx150x_regmap_reg_write(void *context, unsigned int reg,
+ unsigned int val)
+{
+ int ret, n;
+ struct sx150x_gpio *sx150x = context;
+ struct i2c_client *i2c = sx150x->client;
+ const int width = sx150x_regmap_reg_width(sx150x, reg);
+
+ n = width - 8;
+ do {
+ const u8 byte = (val >> n) & 0xff;
+
+ ret = i2c_smbus_write_byte_data(i2c, reg, byte);
+ if (ret < 0)
+ return ret;
+
+ reg++;
+ n -= 8;
+ } while (n >= 0);
+
+ return 0;
+}
+
+static const struct regmap_config sx150x_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .max_register = SX150X_MAX_REGISTER,
+};
+
+static const struct regmap_bus sx150x_regmap_bus = {
+ .reg_read = sx150x_regmap_reg_read,
+ .reg_write = sx150x_regmap_reg_write,
+};
+
+static struct gpio_ops sx150x_gpio_ops = {
+ .direction_input = sx150x_gpio_direction_input,
+ .direction_output = sx150x_gpio_direction_output,
+ .get_direction = sx150x_gpio_get_direction,
+ .get = sx150x_gpio_get,
+ .set = sx150x_gpio_set,
+};
+
+static int sx150x_probe(struct device_d *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct sx150x_gpio *sx150x;
+ const struct sx150x_device_data *data;
+
+ data = of_device_get_match_data(dev);
+ if (!data)
+ return -EINVAL;
+
+ sx150x = xzalloc(sizeof(*sx150x));
+
+ sx150x->regmap = regmap_init(dev, &sx150x_regmap_bus,
+ sx150x, &sx150x_regmap_config);
+ sx150x->client = client;
+ sx150x->data = data;
+ sx150x->gpio.ops = &sx150x_gpio_ops;
+ sx150x->gpio.base = -1;
+ sx150x->gpio.ngpio = sx150x->data->ngpios;
+ sx150x->gpio.dev = &client->dev;
+
+ return gpiochip_add(&sx150x->gpio);
+}
+
+static __maybe_unused struct of_device_id sx150x_dt_ids[] = {
+ { .compatible = "semtech,sx1503q", .data = &sx1503q_device_data, },
+ { }
+};
+
+static struct driver_d sx150x_driver = {
+ .name = "sx150x",
+ .probe = sx150x_probe,
+ .of_compatible = sx150x_dt_ids,
+};
+
+static int __init sx150x_init(void)
+{
+ return i2c_driver_register(&sx150x_driver);
+}
+device_initcall(sx150x_init);
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* Re: Compiler issues
From: Andrey Smirnov @ 2016-11-15 6:34 UTC (permalink / raw)
To: Jose Luis Zabalza; +Cc: barebox@lists.infradead.org
In-Reply-To: <CAKZffXHoZX8Wrd+EEEp+5rHBMZVeK86vjSb1Cp5hC8=H4bkYVQ@mail.gmail.com>
On Mon, Nov 14, 2016 at 9:32 PM, Jose Luis Zabalza <jlz.3008@gmail.com> wrote:
> Thanks for your reply, Holger.
>
> I am sorry. I have to apologize for no mentioning that this thread is
> the continuation of "Re: Configure RAM size on iMX53 board".
>
> I will summarize the situation. I have a iMX53 custom board with two
> versions, 512MB (only CS0) and 1GB (CS0 and CS1) RAM. Both versions
> are running with same old uboot binary because uboot don't access to
> high memory address. I write code for support Barebox on 1GB version
> successfully but hangs on 512MB version. No messages are displayed on
> console.
>
> Sascha recomends me don't configure CS1 on DCD table and use
> barebox_arm_entry() function instead of imx53_barebox_entry() but it
> don't work.
>
> So, the first step was find where the code hangs.
>
> I activated a GPIO on DCD table and deactivate on Barebox code to know
> if a function is executed.
>
> ==========<cut>===========
> wm 32 0x53F84004 0x00000008 // Set GPIO as output
> wm 32 0x53F84000 0x00000008 // Activate GPIO
>
> ...
>
> *((unsigned *)0x53F84000)=0; // Deactivate GPIO
> ==========<cut>===========
>
> With the trial and error method, I found the execution lack on
> initcall secuence. Specifically don't reach myboard_initcall()
>
> ==========<cut>===========
> static int myboard_init(void)
> {
> *((unsigned *)0x53F84000)=0;
>
> imx_esdctl_disable();
>
> arm_add_mem_device("ram0", MX53_CSD0_BASE_ADDR, SZ_512M);
>
> return 0;
> }
> core_initcall(myboard_init);
> ==========<cut>===========
>
> So I changed core_initcall() to pure_initcall() for early
> myboard_init() execution and It was good but Barebox hangs on another
> initcall function.
>
> Next trial and error session I found imx_gpio_add() was not reached,
> so I suspect it was a compiler problem or a timing problem. I
> discarded the timing problem because It was very repetitive.
>
> I changed -Os option with -O0 on Makefile. Now imx_gpio_add() are
> executed Ok but net_init() hangs.
>
> The final firework:
>
> ==========<cut barebox/net/net.c>===========
> //
> // this code don't deactivate the GPIO
> //
> static int net_init(void)
> {
> int i;
>
> for (i = 0; i < PKTBUFSRX; i++)
> NetRxPackets[i] = net_alloc_packet();
>
> *((unsigned *)0x53F84000)=0;
>
> ==========<cut>===========
> //
> // This code YES. It deactivate the GPIO
> //
> static int net_init(void)
> {
> volatile int i;
>
> for (i = 0; i < PKTBUFSRX; i++)
> {
> if(i > 10)
> {
> // this code is not executed because PKTBUFSRX is 4
> }
>
> NetRxPackets[i] = net_alloc_packet();
> }
>
> *((unsigned *)0x53F84000)=0;
> ==========<cut>===========
>
> Now, the code hangs on other unknow initcall function but I think
> that's not the problem.
>
> Some idea?
> Some dark compiler flag to de/activate ?
That explanation is not very simple so it is unlikely to be true. If I
were to guess I'd say you are still having problems with RAM
boundaries calculation because what you describe reminds me of the
behavior I've observed many times when Barebox gets relocated such
that part of the image is placed into area that does not correspond to
RAM, so that some of the code is good and some of it is bad.
I would recommend configuring DEBUG_LL, instrumenting
barebox_arm_entry from entry.c to display membase and memsize and
making sure they fall within a valid region.
Hope this helps,
Andrey Smirnov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: [PATCH v2 09/28] clk: Port of_clk_set_defaults()
From: Sascha Hauer @ 2016-11-15 7:53 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox
In-Reply-To: <1478708056-7875-10-git-send-email-andrew.smirnov@gmail.com>
On Wed, Nov 09, 2016 at 08:13:57AM -0800, Andrey Smirnov wrote:
> Port of_clk_set_defautls() from Linux kernel in order to support DT
> configurations that require it (e. g. Vybrid).
>
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
> drivers/clk/Makefile | 2 +-
> drivers/clk/clk-conf.c | 144 +++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/clk.c | 2 +
> include/linux/clk/clk-conf.h | 14 +++++
> 4 files changed, 161 insertions(+), 1 deletion(-)
> create mode 100644 drivers/clk/clk-conf.c
> create mode 100644 include/linux/clk/clk-conf.h
This patch breaks compilation on platforms using common clk but no
device tree, for example cupid_defconfig:
drivers/clk/clk-conf.c: In function '__set_clk_parents':
drivers/clk/clk-conf.c:41:3: error: implicit declaration of function 'of_clk_get_from_provider' [-Werror=implicit-function-declaration]
As this is not trivial to fix I dropped the rest of this series for now.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: [PATCH] pcm049: Add 1 GByte RAM with DUAL DIE Single Rank
From: Sascha Hauer @ 2016-11-15 8:05 UTC (permalink / raw)
To: Maik Otto; +Cc: barebox
In-Reply-To: <1479116835-15439-1-git-send-email-m.otto@phytec.de>
On Mon, Nov 14, 2016 at 10:47:15AM +0100, Maik Otto wrote:
> tested with Micron MT42L128M64D2LL-25WT and MT42L128M64D2LL-25WT
>
> Signed-off-by: Maik Otto <m.otto@phytec.de>
> ---
> arch/arm/boards/phytec-phycore-omap4460/lowlevel.c | 32 +++++++++++++++++++-
> 1 files changed, 31 insertions(+), 1 deletions(-)
Applied, thanks
Sascha
>
> diff --git a/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c b/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c
> index c082594..71ab793 100644
> --- a/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c
> +++ b/arch/arm/boards/phytec-phycore-omap4460/lowlevel.c
> @@ -30,6 +30,13 @@
> #include <asm/barebox-arm-head.h>
>
> #define TPS62361_VSEL0_GPIO 182
> +#define LPDDR2_2G 0x5
> +#define LPDDR2_4G 0x6
> +#define LPDDR2_DENSITY_MASK 0x3C
> +#define LPDDR2_DENSITY_SHIFT 2
> +#define EMIF_SDRAM_CONFIG 0x0008
> +#define EMIF_LPDDR2_MODE_REG_CONFIG 0x0050
> +#define EMIF_LPDDR2_MODE_REG_DATA 0x0040
>
> void set_muxconf_regs(void);
>
> @@ -61,8 +68,23 @@ static const struct ddr_regs ddr_regs_mt42L128M64_25_400_mhz = {
> .mr2 = 0x4
> };
>
> +static const struct ddr_regs ddr_regs_mt42L128M64D2LL_25_400_mhz = {
> + .tim1 = 0x10EB0662,
> + .tim2 = 0x205715D2,
> + .tim3 = 0x00B1C53F,
> + .phy_ctrl_1 = 0x849FF409,
> + .ref_ctrl = 0x00000618,
> + .config_init = 0x80001AB2,
> + .config_final = 0x80001AB2,
> + .zq_config = 0x500B3214,
> + .mr1 = 0x83,
> + .mr2 = 0x4
> +};
> +
> static void noinline pcm049_init_lowlevel(void)
> {
> + unsigned int density;
> +
> struct dpll_param core = OMAP4_CORE_DPLL_PARAM_19M2_DDR400;
> struct dpll_param mpu44xx = OMAP4_MPU_DPLL_PARAM_19M2_MPU1000;
> struct dpll_param mpu4460 = OMAP4_MPU_DPLL_PARAM_19M2_MPU920;
> @@ -75,9 +97,17 @@ static void noinline pcm049_init_lowlevel(void)
> set_muxconf_regs();
>
> #ifdef CONFIG_1024MB_DDR2RAM
> + omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
> + writel(EMIF_SDRAM_CONFIG, OMAP44XX_EMIF1_BASE +
> + EMIF_LPDDR2_MODE_REG_CONFIG);
> + density = (readl(OMAP44XX_EMIF1_BASE + EMIF_LPDDR2_MODE_REG_DATA) &
> + LPDDR2_DENSITY_MASK) >> LPDDR2_DENSITY_SHIFT;
> + if (density == LPDDR2_2G)
> omap4_ddr_init(&ddr_regs_mt42L128M64_25_400_mhz, &core);
> + else if (density == LPDDR2_4G)
> + omap4_ddr_init(&ddr_regs_mt42L128M64D2LL_25_400_mhz, &core);
> #else
> - omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
> + omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
> #endif
>
> /* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
> --
> 1.7.0.4
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [PATCH] state: Documentation updates
From: Sascha Hauer @ 2016-11-15 8:19 UTC (permalink / raw)
To: Barebox List; +Cc: Trostel Alain
From: Trostel Alain <Alain.Trostel@haslerrail.com>
Some improvements for the state binding documentation. These come
from the conversation with Trostel Alain who tried to use the
state framework and stumbled upon these things missing. Patch
originally by Alain, thanks.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
.../devicetree/bindings/barebox/barebox,state.rst | 39 +++++++++++++++++++---
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/barebox/barebox,state.rst b/Documentation/devicetree/bindings/barebox/barebox,state.rst
index 438cc43..7b9d1bb 100644
--- a/Documentation/devicetree/bindings/barebox/barebox,state.rst
+++ b/Documentation/devicetree/bindings/barebox/barebox,state.rst
@@ -43,6 +43,16 @@ Optional properties:
moment. For MTD with erasing the correct type is ``circular``. For all other
devices and files, ``direct`` is the needed type.
+Configuration
+-------------
+
+The following config options must be enabled when building the barebox image
+to have full support of the barebox state framework:
+
+* CONFIG_STATE
+* CONFIG_STATE_DRV
+* CONFIG_CMD_STATE
+
Variable nodes
--------------
@@ -71,13 +81,18 @@ Optional properties:
storage. For ``enum32`` values it is an integer representing an
offset into the names array.
-Example::
+The following examples have to be configured in the board-specific device
+tree files (\*.dts) within barebox.
- state: state@0 {
+State example::
+
+ state: state {
magic = <0x27031977>;
compatible = "barebox,state";
backend-type = "raw";
- backend = &eeprom, "partname:state";
+ backend = &part_state;
+ #address-cells = <1>;
+ #size-cells = <1>;
foo {
reg = <0x00 0x4>;
@@ -93,6 +108,13 @@ Example::
};
};
+Partition example::
+
+ part_state: partition@1C0000 {
+ label = "state";
+ reg = <0x1C0000 0x60000>;
+ };
+
Variable Types
--------------
@@ -139,4 +161,13 @@ be accessed like normal shell variables. The ``state`` command is used
to save/restore a state to the backend device.
After initializing the variable can be accessed with ``$state.foo``.
-``state -s`` stores the state to eeprom.
+``state -s`` stores the state persistently.
+
+From Linux
+----------
+
+It exists a tool called «barebox-state» to access these state variables
+from the Linux user-space. The mentioned tool is available as GIT project
+under the following location::
+
+ git://git.pengutronix.de/git/tools/dt-utils.git
--
2.10.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH] ARM: i.MX: Add src fixup
From: Sascha Hauer @ 2016-11-15 9:08 UTC (permalink / raw)
To: Barebox List
Some boards or SoCs need the SRC_SCR[WARM_RESET_ENABLE] bit cleared,
otherwise they won't come up after a watchdog reset. This was observed
on one i.MX6ul based custom board. The Linux Kernel does the same since
2012: 0575fb7 ARM: 7198/1: arm/imx6: add restart support for imx6q.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/Kconfig | 4 ++++
arch/arm/mach-imx/Makefile | 1 +
arch/arm/mach-imx/src.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/reset/Kconfig | 4 ++++
4 files changed, 66 insertions(+)
create mode 100644 arch/arm/mach-imx/src.c
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index d571faa..5eec639 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -81,6 +81,10 @@ config BAREBOX_UPDATE_IMX_EXTERNAL_NAND
depends on MTD_WRITE
default y
+config RESET_IMX_SRC
+ bool "i.MX SRC support"
+ default y if ARCH_IMX6 || ARCH_IMX50 || ARCH_IMX51 || ARCH_IMX53
+
comment "Freescale i.MX System-on-Chip"
config ARCH_IMX1
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 9922fed..22d903c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -25,5 +25,6 @@ obj-y += devices.o imx.o
obj-pbl-y += esdctl.o boot.o
obj-$(CONFIG_BAREBOX_UPDATE) += imx-bbu-internal.o
obj-$(CONFIG_BAREBOX_UPDATE_IMX_EXTERNAL_NAND) += imx-bbu-external-nand.o
+obj-$(CONFIG_RESET_IMX_SRC) += src.o
lwl-y += cpu_init.o
pbl-y += xload-spi.o xload-esdhc.o xload-common.o
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
new file mode 100644
index 0000000..73350d1
--- /dev/null
+++ b/arch/arm/mach-imx/src.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/err.h>
+
+#define SRC_SCR 0x0
+
+#define SCR_WARM_RESET_ENABLE BIT(0)
+
+static int imx_src_reset_probe(struct device_d *dev)
+{
+ struct resource *res;
+ u32 val;
+ void __iomem *membase;
+
+ res = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(res))
+ return PTR_ERR(res);
+
+ membase = IOMEM(res->start);
+
+ /*
+ * Generate cold reset for warm reset sources. Needed for
+ * some boards to come up properly after reset.
+ */
+ val = readl(membase + SRC_SCR);
+ val &= ~SCR_WARM_RESET_ENABLE;
+ writel(val, membase + SRC_SCR);
+
+ return 0;
+}
+
+static const struct of_device_id imx_src_dt_ids[] = {
+ { .compatible = "fsl,imx51-src", },
+ { /* sentinel */ },
+};
+
+static struct driver_d imx_src_reset_driver = {
+ .name = "imx-src",
+ .probe = imx_src_reset_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_src_dt_ids),
+};
+
+static int imx_src_reset_init(void)
+{
+ return platform_driver_register(&imx_src_reset_driver);
+}
+postcore_initcall(imx_src_reset_init);
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index c9d04f7..71a13b5 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -11,3 +11,7 @@ menuconfig RESET_CONTROLLER
via GPIOs or SoC-internal reset controller modules.
If unsure, say no.
+
+config RESET_IMX_SRC
+ bool "i.MX SRC support"
+ default y if ARCH_IMX6 || ARCH_IMX50 || ARCH_IMX51 || ARCH_IMX53
--
2.10.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* Re: usb otg port not working on an imx25 soc
From: Sascha Hauer @ 2016-11-15 13:35 UTC (permalink / raw)
To: iw3gtf; +Cc: barebox
In-Reply-To: <1823762258.78822.1479128237871.JavaMail.ngmail@webmail06.arcor-online.net>
Hi Giorgio,
On Mon, Nov 14, 2016 at 01:57:17PM +0100, iw3gtf@arcor.de wrote:
> Hi,
>
> I'm currently working on an embedded board with an imx25 soc and I want
> to enable the usb otg port of the soc; in my use case I just want the otg port
> to be configured in usb host mode and use the integrated UTMI phy.
>
> I built barebox with usb support and the usb ports are actually found:
When USB does not work it's most likely that the usbmisc unit is not
properly configured. Have a look at mx25_initialize_usb_hw(). If you
previously loaded barebox with imx-usb-loader then you could try skipping
the initialization in mx25_initialize_usb_hw() completely.
I've seldomly seen that the actual EHCI driver or USB core is the
problem when no device is detected.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox