1
0
Fork 0

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>
5.4-rM2-2.2.x-imx-squashed
Stoica Cosmin-Stefan 2015-06-08 18:55:18 +03:00 committed by Dong Aisheng
parent 46fe72556e
commit 457bcf4d5d
15 changed files with 748 additions and 0 deletions

View File

@ -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.

View File

@ -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"

View File

@ -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/

View File

@ -0,0 +1,4 @@
config ARCH_S32_CLK
bool "Enable S32 CLK Framework"
help
Support for the Clock Framework on S32 SoCs.

View File

@ -0,0 +1,2 @@
obj-$(CONFIG_ARCH_S32_CLK) += clk-core.o
obj-$(CONFIG_ARCH_S32_CLK) += s32v234/

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1 @@
obj-$(CONFIG_ARCH_S32_CLK) += clk.o clk-plldig.o

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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