summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStoica Cosmin-Stefan <cosmin.stoica@nxp.com>2015-06-08 18:55:18 +0300
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 16:28:53 +0800
commit457bcf4d5d802c2b4076e58a18dabff31cce763c (patch)
treee614739eb7240333a1d51e2320decc7662d6bb59
parent46fe72556efe672c53fd593c44036550a91ce0c3 (diff)
clk: Add clk support for S32V234
Add clock framework for Treerunner (S32V234), based on code from the i.MX 3.10.17 codebase[1]. Add clock definitions that are used in the clocks vector (tree). At this point, the only PLL enabled is PERIPH-PLL. [1] https://source.codeaurora.org/external/imx/linux-imx/tree/?h=imx_3.10.17_1.0.0_ga_caf Signed-off-by: Stoica Cosmin-Stefan <cosmin.stoica@nxp.com> Signed-off-by: Larisa Grigore <Larisa.Grigore@nxp.com> Signed-off-by: Stefan-Gabriel Mirea <stefan-gabriel.mirea@nxp.com>
-rw-r--r--arch/arm64/Kconfig.platforms1
-rw-r--r--drivers/clk/Kconfig1
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/s32/Kconfig4
-rw-r--r--drivers/clk/s32/Makefile2
-rw-r--r--drivers/clk/s32/clk-core.c53
-rw-r--r--drivers/clk/s32/clk.h55
-rw-r--r--drivers/clk/s32/s32v234/Makefile1
-rw-r--r--drivers/clk/s32/s32v234/clk-plldig.c240
-rw-r--r--drivers/clk/s32/s32v234/clk.c109
-rw-r--r--drivers/clk/s32/s32v234/clk.h27
-rw-r--r--drivers/clk/s32/s32v234/mc_cgm.h49
-rw-r--r--drivers/clk/s32/s32v234/mc_me.h110
-rw-r--r--drivers/clk/s32/s32v234/pll.h78
-rw-r--r--drivers/clk/s32/s32v234/src.h17
15 files changed, 748 insertions, 0 deletions
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 17f1c34ec750..a94a14bd4e22 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -214,6 +214,7 @@ config ARCH_ROCKCHIP
config ARCH_S32
bool "NXP S32 SoC Family"
+ select ARCH_S32_CLK
help
This enables support for the NXP S32 family of processors.
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c44247d0b83e..580828299b2c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -318,6 +318,7 @@ source "drivers/clk/meson/Kconfig"
source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/renesas/Kconfig"
+source "drivers/clk/s32/Kconfig"
source "drivers/clk/samsung/Kconfig"
source "drivers/clk/sifive/Kconfig"
source "drivers/clk/sprd/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 0138fb14e6f8..0fa07e17db98 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -97,6 +97,7 @@ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
obj-y += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+obj-$(CONFIG_ARCH_S32) += s32/
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
obj-$(CONFIG_CLK_SIFIVE) += sifive/
obj-$(CONFIG_ARCH_SIRF) += sirf/
diff --git a/drivers/clk/s32/Kconfig b/drivers/clk/s32/Kconfig
new file mode 100644
index 000000000000..c28bdbbfaa3a
--- /dev/null
+++ b/drivers/clk/s32/Kconfig
@@ -0,0 +1,4 @@
+config ARCH_S32_CLK
+ bool "Enable S32 CLK Framework"
+ help
+ Support for the Clock Framework on S32 SoCs.
diff --git a/drivers/clk/s32/Makefile b/drivers/clk/s32/Makefile
new file mode 100644
index 000000000000..169b8b5900f9
--- /dev/null
+++ b/drivers/clk/s32/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_S32_CLK) += clk-core.o
+obj-$(CONFIG_ARCH_S32_CLK) += s32v234/
diff --git a/drivers/clk/s32/clk-core.c b/drivers/clk/s32/clk-core.c
new file mode 100644
index 000000000000..a8cca66f7959
--- /dev/null
+++ b/drivers/clk/s32/clk-core.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+void __init s32_check_clocks(struct clk *clks[], unsigned int count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ if (IS_ERR(clks[i]))
+ pr_err("S32 clk %u: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+}
+
+static struct clk * __init s32_obtain_fixed_clock_from_dt(const char *name)
+{
+ struct of_phandle_args phandle;
+ struct clk *clk = ERR_PTR(-ENODEV);
+ char *path;
+
+ path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
+ if (!path)
+ return ERR_PTR(-ENOMEM);
+
+ phandle.np = of_find_node_by_path(path);
+ kfree(path);
+
+ if (phandle.np) {
+ clk = of_clk_get_from_provider(&phandle);
+ of_node_put(phandle.np);
+ }
+ return clk;
+}
+
+struct clk * __init s32_obtain_fixed_clock(
+ const char *name, unsigned long rate)
+{
+ struct clk *clk;
+
+ clk = s32_obtain_fixed_clock_from_dt(name);
+ if (IS_ERR(clk))
+ clk = s32_clk_fixed(name, rate);
+ return clk;
+}
diff --git a/drivers/clk/s32/clk.h b/drivers/clk/s32/clk.h
new file mode 100644
index 000000000000..83100641158f
--- /dev/null
+++ b/drivers/clk/s32/clk.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ */
+
+#ifndef __MACH_S32_CLK_H
+#define __MACH_S32_CLK_H
+
+#include <linux/spinlock.h>
+#include <linux/clk-provider.h>
+
+#define PNAME(x) \
+ static const char *x[] __initconst
+
+void s32_check_clocks(struct clk *clks[], unsigned int count);
+
+struct clk *s32_obtain_fixed_clock(
+ const char *name, unsigned long rate);
+
+static inline struct clk *s32_clk_fixed(const char *name, unsigned long rate)
+{
+ return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
+}
+
+static inline struct clk *s32_clk_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width,
+ spinlock_t *lock)
+{
+ struct clk *tmp_clk = clk_register_divider(NULL, name, parent,
+ CLK_SET_RATE_PARENT,
+ reg, shift, width, 0, lock);
+
+ return tmp_clk;
+}
+
+static inline struct clk *s32_clk_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents,
+ u8 num_parents, spinlock_t *lock)
+{
+ return clk_register_mux(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT, reg, shift,
+ width, 0, lock);
+}
+
+static inline struct clk *s32_clk_fixed_factor(const char *name,
+ const char *parent,
+ unsigned int mult,
+ unsigned int div)
+{
+ return clk_register_fixed_factor(NULL, name, parent,
+ CLK_SET_RATE_PARENT, mult, div);
+}
+
+#endif
diff --git a/drivers/clk/s32/s32v234/Makefile b/drivers/clk/s32/s32v234/Makefile
new file mode 100644
index 000000000000..54f77523dbcd
--- /dev/null
+++ b/drivers/clk/s32/s32v234/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_S32_CLK) += clk.o clk-plldig.o
diff --git a/drivers/clk/s32/s32v234/clk-plldig.c b/drivers/clk/s32/s32v234/clk-plldig.c
new file mode 100644
index 000000000000..6ed23974ee63
--- /dev/null
+++ b/drivers/clk/s32/s32v234/clk-plldig.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include "clk.h"
+
+/*
+ * struct clk_plldig - S32 PLLDIG clock
+ * @clk_hw: clock source
+ * @base: base address of PLL registers
+ * @plldv_mfd: multiplication loop factor divider
+ * @plldv_rfdphi: PHI reduced frequency divider
+ * @plldv_rfdphi1: PHI reduced frequency divider
+ *
+ * PLLDIG clock version 1, found on S32 series.
+ */
+struct clk_plldig {
+ struct clk_hw hw;
+ void __iomem *base;
+ enum s32v234_plldig_type type;
+ u32 plldv_mfd;
+ u32 pllfd_mfn;
+ u32 plldv_rfdphi;
+ u32 plldv_rfdphi1;
+};
+
+#define to_clk_plldig(_hw) container_of(_hw, struct clk_plldig, hw)
+
+static unsigned long get_pllx_max_vco_rate(enum s32v234_plldig_type plltype)
+{
+ switch (plltype) {
+ case S32_PLLDIG_PERIPH:
+ return PERIPHPLL_MAX_VCO_RATE;
+ default:
+ pr_warn("Unsupported PLL.\n");
+ return -EINVAL;
+ }
+}
+
+static unsigned long get_pllx_phiy_max_rate(enum s32v234_plldig_type plltype,
+ unsigned int phino)
+{
+ switch (plltype) {
+ case S32_PLLDIG_PERIPH:
+ switch (phino) {
+ case 0:
+ return PERIPHPLL_MAX_PHI0_MAX_RATE;
+ case 1:
+ return PERIPHPLL_MAX_PHI1_MAX_RATE;
+ default:
+ break;
+ }
+ break;
+ default:
+ pr_warn("Unsupported PLL.\n");
+ break;
+ }
+ return -EINVAL;
+}
+
+static int clk_plldig_prepare(struct clk_hw *hw)
+{
+ return 0;
+}
+
+static void clk_plldig_unprepare(struct clk_hw *hw)
+{
+}
+
+static unsigned long clk_plldig_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_plldig *pll = to_clk_plldig(hw);
+ u32 plldv = readl_relaxed(PLLDIG_PLLDV(pll->base));
+ u32 pllfd = readl_relaxed(PLLDIG_PLLFD(pll->base));
+ u32 prediv, mfd, mfn, vco;
+
+ prediv = (plldv & PLLDIG_PLLDV_PREDIV_MASK)
+ >> PLLDIG_PLLDV_PREDIV_OFFSET;
+ mfd = (plldv & PLLDIG_PLLDV_MFD_MASK);
+
+ mfn = (pllfd & PLLDIG_PLLFD_MFN_MASK);
+
+ if (prediv == 0)
+ prediv = 1;
+
+ /*
+ * This formula is from platform reference manual
+ * (Rev. 1, 6/2015), PLLDIG chapter.
+ */
+ vco = (parent_rate / prediv) * (mfd + mfn / 20480);
+
+ return vco;
+}
+
+static long clk_plldig_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_plldig *pll = to_clk_plldig(hw);
+ unsigned long max_allowed_rate = get_pllx_max_vco_rate(pll->type);
+
+ if (rate > max_allowed_rate)
+ rate = max_allowed_rate;
+ else if (rate < MIN_VCO_RATE)
+ rate = MIN_VCO_RATE;
+
+ return rate;
+}
+
+static int clk_plldig_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_plldig *pll = to_clk_plldig(hw);
+ u32 pllfd, prediv;
+
+ unsigned long max_allowed_rate = get_pllx_max_vco_rate(pll->type);
+ unsigned long phi0_max_rate = get_pllx_phiy_max_rate(pll->type, 0);
+ unsigned long phi1_max_rate = get_pllx_phiy_max_rate(pll->type, 1);
+
+ if (rate < MIN_VCO_RATE || rate > max_allowed_rate)
+ return -EINVAL;
+
+ if (((rate / pll->plldv_rfdphi) > phi0_max_rate) ||
+ ((rate / pll->plldv_rfdphi) > phi1_max_rate))
+ return -EINVAL;
+
+ pllfd = readl_relaxed(PLLDIG_PLLFD(pll->base));
+ prediv = (parent_rate / rate) *
+ (pll->plldv_mfd + pll->pllfd_mfn / 20480);
+
+ writel_relaxed(PLLDIG_PLLDV_RFDPHI1_SET(pll->plldv_rfdphi1) |
+ PLLDIG_PLLDV_RFDPHI_SET(pll->plldv_rfdphi) |
+ PLLDIG_PLLDV_PREDIV_SET(prediv) |
+ PLLDIG_PLLDV_MFD_SET(pll->plldv_mfd),
+ PLLDIG_PLLDV(pll->base));
+
+ writel_relaxed(pllfd | PLLDIG_PLLFD_MFN_SET(pll->pllfd_mfn),
+ PLLDIG_PLLFD(pll->base));
+
+ /*
+ * To be implemented the wait_lock or an equivalent state
+ * return clk_plldig_wait_lock(pll);
+ */
+ return 0;
+}
+
+static const struct clk_ops clk_plldig_ops = {
+ .prepare = clk_plldig_prepare,
+ .unprepare = clk_plldig_unprepare,
+ .recalc_rate = clk_plldig_recalc_rate,
+ .round_rate = clk_plldig_round_rate,
+ .set_rate = clk_plldig_set_rate,
+};
+
+struct clk *s32v234_clk_plldig_phi(enum s32v234_plldig_type type,
+ const char *name, const char *parent,
+ void __iomem *base, u32 phi)
+{
+ u32 plldv, rfd_phi;
+
+ if (!base)
+ return ERR_PTR(-ENOMEM);
+
+ plldv = readl_relaxed(PLLDIG_PLLDV(base));
+
+ switch (phi) {
+ /* PHI0 */
+ case 0:
+ rfd_phi = (plldv & PLLDIG_PLLDV_RFDPHI_MASK)
+ >> PLLDIG_PLLDV_RFDPHI_OFFSET;
+ break;
+ /* PHI1 */
+ case 1:
+ rfd_phi = (plldv & PLLDIG_PLLDV_RFDPHI1_MASK)
+ >> PLLDIG_PLLDV_RFDPHI1_OFFSET;
+
+ if (rfd_phi == 0)
+ rfd_phi = 1;
+
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+
+ return clk_register_fixed_factor(NULL, name, parent,
+ CLK_SET_RATE_PARENT, 1, rfd_phi);
+}
+
+struct clk *s32v234_clk_plldig(enum s32v234_plldig_type type, const char *name,
+ const char *parent_name, void __iomem *base,
+ u32 plldv_mfd, u32 pllfd_mfn,
+ u32 plldv_rfdphi, u32 plldv_rfdphi1)
+{
+ struct clk_plldig *pll;
+ const struct clk_ops *ops;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ if (plldv_rfdphi > PLLDIG_PLLDV_RFDPHI_MAXVALUE)
+ return ERR_PTR(-EINVAL);
+
+ if (plldv_rfdphi1 > PLLDIG_PLLDV_RFDPHI1_MAXVALUE)
+ return ERR_PTR(-EINVAL);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ ops = &clk_plldig_ops;
+
+ pll->base = base;
+ pll->type = type;
+ pll->plldv_mfd = plldv_mfd;
+ pll->pllfd_mfn = pllfd_mfn;
+ pll->plldv_rfdphi = plldv_rfdphi;
+ pll->plldv_rfdphi1 = plldv_rfdphi1;
+
+ init.name = name;
+ init.ops = ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/drivers/clk/s32/s32v234/clk.c b/drivers/clk/s32/s32v234/clk.c
new file mode 100644
index 000000000000..2fd325d92a5d
--- /dev/null
+++ b/drivers/clk/s32/s32v234/clk.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ */
+
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <dt-bindings/clock/s32v234-clock.h>
+
+#include "clk.h"
+
+static void __iomem *mc_cgm0_base;
+static void __iomem *mc_me_base;
+static void __iomem *src_base;
+
+DEFINE_SPINLOCK(s32v234_lock);
+
+/* sources for multiplexer clocks, this is used multiple times */
+PNAME(osc_sels) = {"firc", "fxosc", };
+
+static struct clk *clk[S32V234_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static void __init s32v234_clocks_init(struct device_node *mc_cgm0_node)
+{
+ struct device_node *np;
+
+ clk[S32V234_CLK_DUMMY] = s32_clk_fixed("dummy", 0);
+ clk[S32V234_CLK_FXOSC] = s32_obtain_fixed_clock("fxosc", 0);
+ clk[S32V234_CLK_FIRC] = s32_obtain_fixed_clock("firc", 0);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,s32v234-mc_me");
+ mc_me_base = of_iomap(np, 0);
+ if (WARN_ON(!mc_me_base))
+ return;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,s32v234-src");
+ src_base = of_iomap(np, 0);
+ if (WARN_ON(!src_base))
+ return;
+
+ np = mc_cgm0_node;
+ mc_cgm0_base = of_iomap(np, 0);
+ if (WARN_ON(!mc_cgm0_base))
+ return;
+
+ enable_cpumodes_onperipheralconfig(mc_me_base, MC_ME_RUN_PCn_DRUN |
+ MC_ME_RUN_PCn_RUN0 |
+ MC_ME_RUN_PCn_RUN1 |
+ MC_ME_RUN_PCn_RUN2 |
+ MC_ME_RUN_PCn_RUN3,
+ 0);
+
+ /* turn on XOSC and FIRC */
+ enable_clocks_sources(MC_ME_MODE_MC_MVRON, MC_ME_MODE_MC_XOSCON |
+ MC_ME_MODE_MC_FIRCON,
+ MC_ME_RUNn_MC(mc_me_base, 0));
+
+ /* transition the core to RUN0 mode */
+ entry_to_target_mode(mc_me_base, MC_ME_MCTL_RUN0);
+
+ clk[S32V234_CLK_PERIPHPLL_SRC_SEL] = s32_clk_mux("periphpll_sel",
+ SRC_GPR1, SRC_GPR1_PERIPHPLL_SRC_SEL_OFFSET,
+ SRC_GPR1_XPLL_SRC_SEL_SIZE,
+ osc_sels, ARRAY_SIZE(osc_sels), &s32v234_lock);
+
+ /* PERIPH_PLL */
+ clk[S32V234_CLK_PERIPHPLL_VCO] = s32v234_clk_plldig(S32_PLLDIG_PERIPH,
+ "periphpll_vco", "periphpll_sel",
+ PERIPHPLL_PLLDIG(mc_cgm0_base),
+ PERIPHPLL_PLLDIG_PLLDV_MFD, PERIPHPLL_PLLDIG_PLLDV_MFN,
+ PERIPHPLL_PLLDIG_PLLDV_RFDPHI0,
+ PERIPHPLL_PLLDIG_PLLDV_RFDPHI1);
+
+ clk[S32V234_CLK_PERIPHPLL_PHI0] =
+ s32v234_clk_plldig_phi(S32_PLLDIG_PERIPH,
+ "periphpll_phi0", "periphpll_vco",
+ PERIPHPLL_PLLDIG(mc_cgm0_base), 0);
+
+ clk[S32V234_CLK_PERIPHPLL_PHI1] =
+ s32v234_clk_plldig_phi(S32_PLLDIG_PERIPH,
+ "periphpll_phi1", "periphpll_vco",
+ PERIPHPLL_PLLDIG(mc_cgm0_base), 1);
+
+ clk[S32V234_CLK_PERIPHPLL_PHI0_DIV3] = s32_clk_fixed_factor(
+ "periphpll_phi0_div3", "periphpll_phi0", 1, 3);
+
+ clk[S32V234_CLK_PERIPHPLL_PHI0_DIV5] = s32_clk_fixed_factor(
+ "periphpll_phi0_div5", "periphpll_phi0", 1, 5);
+
+ /* enable PERIPHPLL */
+ enable_clocks_sources(0, MC_ME_MODE_MC_PERIPHPLL,
+ MC_ME_RUNn_MC(mc_me_base, 0));
+
+ /* set the system clock */
+ enable_sysclock(MC_ME_MODE_MC_SYSCLK(0x2),
+ MC_ME_RUNn_MC(mc_me_base, 0));
+
+ /* transition the core to RUN0 mode */
+ entry_to_target_mode(mc_me_base, MC_ME_MCTL_RUN0);
+
+ /* 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(S32V234, "fsl,s32v234-mc_cgm0", s32v234_clocks_init);
diff --git a/drivers/clk/s32/s32v234/clk.h b/drivers/clk/s32/s32v234/clk.h
new file mode 100644
index 000000000000..ea69d13a90b5
--- /dev/null
+++ b/drivers/clk/s32/s32v234/clk.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ */
+
+#ifndef __MACH_S32V234_CLK_H
+#define __MACH_S32V234_CLK_H
+
+#include <linux/spinlock.h>
+#include <linux/clk-provider.h>
+#include "mc_cgm.h"
+#include "mc_me.h"
+#include "pll.h"
+#include "src.h"
+#include "../clk.h"
+
+struct clk *s32v234_clk_plldig(enum s32v234_plldig_type type, const char *name,
+ const char *parent_name, void __iomem *base,
+ u32 plldv_mfd, u32 plldv_mfn,
+ u32 plldv_rfdphi, u32 plldv_rfdphi1);
+
+struct clk *s32v234_clk_plldig_phi(enum s32v234_plldig_type type,
+ const char *name, const char *parent,
+ void __iomem *base, u32 phi);
+
+#endif
diff --git a/drivers/clk/s32/s32v234/mc_cgm.h b/drivers/clk/s32/s32v234/mc_cgm.h
new file mode 100644
index 000000000000..61a5fe61b2d1
--- /dev/null
+++ b/drivers/clk/s32/s32v234/mc_cgm.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP
+ */
+#ifndef _MC_CGM_H
+#define _MC_CGM_H
+
+#define PERIPHPLL_PLLDIG(mc_cgm) ((mc_cgm) + 0x80)
+#define PERIPHPLL_PLLDIG_PLLDV_MFD (30)
+#define PERIPHPLL_PLLDIG_PLLDV_MFN (0)
+#define PERIPHPLL_PLLDIG_PLLDV_RFDPHI0 (0x1)
+#define PERIPHPLL_PLLDIG_PLLDV_RFDPHI1 (0x1)
+
+/* MC_CGM_SC_SS */
+#define CGM_SC_SS(mc_cgm) (((mc_cgm) + 0x7E4))
+
+/* MC_CGM_SC_DCn */
+#define CGM_SC_DCn(mc_cgm, dc) (((mc_cgm) + 0x7E8) + ((dc) * 0x4))
+
+#define MC_CGM_SC_DCn_PREDIV_OFFSET (16)
+#define MC_CGM_SC_DCn_PREDIV_SIZE (3)
+#define MC_CGM_SC_DCn_DE (1 << 31)
+#define MC_CGM_SC_SEL_OFFSET (24)
+#define MC_CGM_SC_SEL_SIZE (4)
+
+/* MC_CGM_ACn_DCm */
+#define CGM_ACn_DCm(mc_cgm, ac, dc) (((mc_cgm) + 0x808) + ((ac) * 0x20)\
+ + ((dc) * 0x4))
+
+#define MC_CGM_ACn_DCm_PREDIV(val) (MC_CGM_ACn_DCm_PREDIV_MASK & \
+ ((val) \
+ << MC_CGM_ACn_DCm_PREDIV_OFFSET))
+#define MC_CGM_ACn_DCm_PREDIV_MASK (0x001F0000)
+#define MC_CGM_ACn_DCm_PREDIV_OFFSET (16)
+#define MC_CGM_ACn_DCm_PREDIV_SIZE (5)
+#define MC_CGM_ACn_DCm_DE (1 << 31)
+
+/* MC_CGM_ACn_SC/MC_CGM_ACn_SS */
+#define CGM_ACn_SC(mc_cgm, ac) (((mc_cgm) + 0x800) + ((ac) * 0x20))
+#define CGM_ACn_SS(mc_cgm, ac) (((mc_cgm) + 0x804) + ((ac) * 0x24))
+#define MC_CGM_ACn_SEL_MASK (0x07000000)
+#define MC_CGM_ACn_SEL_SET(source) (MC_CGM_ACn_SEL_MASK & \
+ (((source) & 0x7) \
+ << MC_CGM_ACn_SEL_OFFSET))
+#define MC_CGM_ACn_SEL_OFFSET (24)
+#define MC_CGM_ACn_SEL_SIZE (4)
+
+#endif
diff --git a/drivers/clk/s32/s32v234/mc_me.h b/drivers/clk/s32/s32v234/mc_me.h
new file mode 100644
index 000000000000..718f1d1a0c30
--- /dev/null
+++ b/drivers/clk/s32/s32v234/mc_me.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP
+ */
+
+#ifndef _MC_ME_H
+#define _MC_ME_H
+
+/* MC_ME registers definitions */
+/* MC_ME_GS */
+ #define MC_ME_GS(mc_me) ((mc_me) + 0x00000000)
+
+/* MC_ME_MCTL */
+#define MC_ME_MCTL(mc_me) ((mc_me) + 0x00000004)
+#define MC_ME_MCTL_RESET (0x0 << 28)
+#define MC_ME_MCTL_TEST (0x1 << 28)
+#define MC_ME_MCTL_DRUN (0x3 << 28)
+#define MC_ME_MCTL_RUN0 (0x4 << 28)
+#define MC_ME_MCTL_RUN1 (0x5 << 28)
+#define MC_ME_MCTL_RUN2 (0x6 << 28)
+#define MC_ME_MCTL_RUN3 (0x7 << 28)
+
+#define MC_ME_GS_S_MTRANS (1 << 27)
+
+#define MC_ME_MCTL_KEY (0x00005AF0)
+#define MC_ME_MCTL_INVERTEDKEY (0x0000A50F)
+
+/*
+ * MC_ME_RESET_MC/MC_ME_TEST_MC
+ * MC_ME_DRUN_MC
+ * MC_ME_RUNn_MC
+ */
+#define MC_ME_RESET_MC(mc_me) ((mc_me) + 0x00000020)
+#define MC_ME_TEST_MC(mc_me) ((mc_me) + 0x00000024)
+#define MC_ME_DRUN_MC(mc_me) ((mc_me) + 0x0000002C)
+#define MC_ME_RUNn_MC(mc_me, n) ((mc_me) + 0x00000030 + 0x4 * (n))
+#define MC_ME_MODE_MC_SYSCLK_OFFSET (0)
+#define MC_ME_MODE_MC_SYSCLK_SIZE (0x3)
+#define MC_ME_MODE_MC_SYSCLK(val) (MC_ME_MODE_MC_SYSCLK_MASK & (val))
+#define MC_ME_MODE_MC_SYSCLK_MASK (0x0000000F)
+#define MC_ME_MODE_MC_FIRCON (1 << 4)
+#define MC_ME_MODE_MC_XOSCON (1 << 5)
+#define MC_ME_MODE_MC_ARMPLL (1 << 6)
+#define MC_ME_MODE_MC_PERIPHPLL (1 << 7)
+#define MC_ME_MODE_MC_ENETPLL (1 << 8)
+#define MC_ME_MODE_MC_DDRPLL (1 << 9)
+#define MC_ME_MODE_MC_VIDEOPLL (1 << 10)
+#define MC_ME_MODE_MC_MVRON (1 << 20)
+
+/* MC_ME_DRUN_SEC_CC_I */
+#define MC_ME_DRUN_SEC_CC_I(mc_me) ((mc_me) + 0x260)
+/* MC_ME_RUNn_SEC_CC_I */
+#define MC_ME_RUNn_SEC_CC_I(mc_me, n) ((mc_me) + 0x270 + (n) * 0x10)
+#define MC_ME_MODE_SEC_CC_I_SYSCLK1_OFFSET (4)
+#define MC_ME_MODE_SEC_CC_I_SYSCLK2_OFFSET (8)
+#define MC_ME_MODE_SEC_CC_I_SYSCLK3_OFFSET (12)
+/* Consider only the defined clocks */
+#define MC_ME_MODE_SEC_CC_I_SYSCLK1_SIZE (0x3)
+#define MC_ME_MODE_SEC_CC_I_SYSCLK2_SIZE (0x3)
+#define MC_ME_MODE_SEC_CC_I_SYSCLK3_SIZE (0x3)
+
+/* MC_ME_RUN_PCn */
+#define MC_ME_RUN_PCn(mc_me, n) (mc_me + 0x00000080 + 0x4 * (n))
+
+#define MC_ME_RUN_PCn_MAX_IDX (7)
+#define MC_ME_RUN_PCn_RESET (1 << 0)
+#define MC_ME_RUN_PCn_TEST (1 << 1)
+#define MC_ME_RUN_PCn_DRUN (1 << 3)
+#define MC_ME_RUN_PCn_RUN0 (1 << 4)
+#define MC_ME_RUN_PCn_RUN1 (1 << 5)
+#define MC_ME_RUN_PCn_RUN2 (1 << 6)
+#define MC_ME_RUN_PCn_RUN3 (1 << 7)
+
+#define MC_ME_PCTLn(mc_me, n) (mc_me + 0xC0 + 4 * (n >> 2) + \
+ (3 - (n) % 4))
+
+static inline void entry_to_target_mode(void __iomem *mc_me, u32 mode)
+{
+ writel_relaxed(mode | MC_ME_MCTL_KEY, MC_ME_MCTL(mc_me));
+ writel_relaxed(mode | MC_ME_MCTL_INVERTEDKEY, MC_ME_MCTL(mc_me));
+ while ((readl_relaxed(MC_ME_GS(mc_me)) &
+ MC_ME_GS_S_MTRANS) != 0x00000000)
+ ;
+}
+
+static inline void enable_cpumodes_onperipheralconfig(void __iomem *mc_me,
+ u32 modes, u32 run_pc_idx)
+{
+ WARN_ON(run_pc_idx > MC_ME_RUN_PCn_MAX_IDX);
+ if (run_pc_idx > MC_ME_RUN_PCn_MAX_IDX)
+ return;
+
+ writel_relaxed(modes, MC_ME_RUN_PCn(mc_me, run_pc_idx));
+}
+
+static inline void enable_clocks_sources(u32 flags, u32 clks,
+ void __iomem *xrun_mc_addr)
+{
+ writel_relaxed(readl_relaxed(xrun_mc_addr) | flags | clks,
+ xrun_mc_addr);
+}
+
+static inline void enable_sysclock(u32 clk, void __iomem *xrun_mc_addr)
+{
+ writel_relaxed(readl_relaxed(xrun_mc_addr) & clk,
+ xrun_mc_addr);
+}
+
+#endif
diff --git a/drivers/clk/s32/s32v234/pll.h b/drivers/clk/s32/s32v234/pll.h
new file mode 100644
index 000000000000..b7bcc50f0a22
--- /dev/null
+++ b/drivers/clk/s32/s32v234/pll.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017-2018 NXP
+ */
+#ifndef _PLL_S32V234_H
+#define _PLL_S32V234_H
+
+/* PLLDIG PLL Divider Register (PLLDIG_PLLDV) */
+#define PLLDIG_PLLDV(base) ((base) + 0x00000028)
+#define PLLDIG_PLLDV_MFD_SET(val) (PLLDIG_PLLDV_MFD_MASK & (val))
+#define PLLDIG_PLLDV_MFD_MASK (0x000000FF)
+
+#define PLLDIG_PLLDV_RFDPHI_SET(val) (PLLDIG_PLLDV_RFDPHI_MASK & \
+ (((val) & \
+ PLLDIG_PLLDV_RFDPHI_MAXVALUE) \
+ << PLLDIG_PLLDV_RFDPHI_OFFSET))
+#define PLLDIG_PLLDV_RFDPHI_MASK (0x003F0000)
+#define PLLDIG_PLLDV_RFDPHI_MAXVALUE (0x3F)
+
+#define PLLDIG_PLLDV_RFDPHI_OFFSET (16)
+
+#define PLLDIG_PLLDV_RFDPHI1_SET(val) (PLLDIG_PLLDV_RFDPHI1_MASK & \
+ (((val) & \
+ PLLDIG_PLLDV_RFDPHI1_MAXVALUE) \
+ << PLLDIG_PLLDV_RFDPHI1_OFFSET))
+#define PLLDIG_PLLDV_RFDPHI1_MASK (0x7E000000)
+#define PLLDIG_PLLDV_RFDPHI1_MAXVALUE (0x3F)
+#define PLLDIG_PLLDV_RFDPHI1_OFFSET (25)
+
+#define PLLDIG_PLLDV_PREDIV_SET(val) (PLLDIG_PLLDV_PREDIV_MASK & \
+ (((val) & \
+ PLLDIG_PLLDV_PREDIV_MAXVALUE) \
+ << PLLDIG_PLLDV_PREDIV_OFFSET))
+#define PLLDIG_PLLDV_PREDIV_MASK (0x00007000)
+#define PLLDIG_PLLDV_PREDIV_MAXVALUE (0x7)
+#define PLLDIG_PLLDV_PREDIV_OFFSET (12)
+
+/* PLLDIG PLL Fractional Divide Register (PLLDIG_PLLFD) */
+#define PLLDIG_PLLFD(base) ((base) + 0x00000030)
+#define PLLDIG_PLLFD_MFN_SET(val) (PLLDIG_PLLFD_MFN_MASK & (val))
+#define PLLDIG_PLLFD_MFN_MASK (0x00007FFF)
+
+/* PLL Calibration Register 1 (PLLDIG_PLLCAL1) */
+#define PLLDIG_PLLCAL1(base) ((base) + 0x00000038)
+#define PLLDIG_PLLCAL1_NDAC1_SET(val) (PLLDIG_PLLCAL1_NDAC1_MASK & \
+ ((val) \
+ << PLLDIG_PLLCAL1_NDAC1_OFFSET))
+#define PLLDIG_PLLCAL1_NDAC1_OFFSET (24)
+#define PLLDIG_PLLCAL1_NDAC1_MASK (0x7F000000)
+
+/* Naming convention for PLL:
+ * ARMPLL - PLL0
+ * PERIPHPLL - PLL1
+ * ENETPLL - PLL2
+ * DDRPLL - PLL3
+ * VIDEOPLL - PLL4
+ */
+/* The min,max values for PLL VCO (Hz) */
+#define PERIPHPLL_MAX_VCO_RATE (1200000000)
+
+/* The min,max values for PLL PHI0 and PHI1 outputs (Hz) */
+#define PERIPHPLL_MAX_PHI0_MAX_RATE (400000000)
+#define PERIPHPLL_MAX_PHI1_MAX_RATE (100000000)
+
+/* The maximum value for PLL VCO according to data sheet */
+#define MAX_VCO_RATE (1300000000)
+#define MIN_VCO_RATE (650000000)
+
+enum s32v234_plldig_type {
+ S32_PLLDIG_ARM,
+ S32_PLLDIG_PERIPH,
+ S32_PLLDIG_ENET,
+ S32_PLLDIG_DDR,
+ S32_PLLDIG_VIDEO,
+};
+
+#endif
diff --git a/drivers/clk/s32/s32v234/src.h b/drivers/clk/s32/s32v234/src.h
new file mode 100644
index 000000000000..39fa973b7c3c
--- /dev/null
+++ b/drivers/clk/s32/s32v234/src.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ */
+#ifndef _SRC_H
+#define _SRC_H
+
+/* Source Reset Control: General Purpose Register 1 */
+#define SRC_GPR1 (src_base + 0x100)
+#define SRC_GPR1_ARMPLL_SRC_SEL_OFFSET (27)
+#define SRC_GPR1_ENETPLL_SRC_SEL_OFFSET (28)
+#define SRC_GPR1_DDRPLL_SRC_SEL_OFFSET (29)
+#define SRC_GPR1_PERIPHPLL_SRC_SEL_OFFSET (30)
+#define SRC_GPR1_VIDEOPLL_SRC_SEL_OFFSET (31)
+#define SRC_GPR1_XPLL_SRC_SEL_SIZE (1)
+
+#endif