1
0
Fork 0

Merge remote-tracking branch 'origin/clock/s32' into clock/next

* origin/clock/s32: (9 commits)
  clk: s32v234: Enable FlexCAN clock
  clk: s32v234: Add definitions for CAN clocks
  clk: s32v234: Initial enet clk support
  clk: s32v234: Add dfs clk
  clk: Enable SDHC clock for S32V234
  ...
5.4-rM2-2.2.x-imx-squashed
Dong Aisheng 2019-12-02 18:00:53 +08:00
commit c8505b1bc2
20 changed files with 1394 additions and 0 deletions

View File

@ -0,0 +1,31 @@
* NXP S32V234 Clock Generation Modules (MC_CGMs)
The SoC supports four Clock Generation Modules, which provide registers for
system and peripherals clock source selection and division. See chapters 22
("Clocking"), 23 ("Clock Generation Module (MC_CGM)") and 69 ("Mode Entry
Module (MC_ME)") in the reference manual[1].
This binding uses the common clock binding:
Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible:
Should be:
- "fsl,s32v234-mc_cgm0" for MC_CGM_0
- "fsl,s32v234-mc_cgm1" for MC_CGM_1
- "fsl,s32v234-mc_cgm2" for MC_CGM_2
- "fsl,s32v234-mc_cgm3" for MC_CGM_3
- reg:
Location and length of the register set
- #clock-cells (only for MC_CGM_0):
Should be <1>. See dt-bindings/clock/s32v234-clock.h for the clock
specifiers allowed in the clocks property of consumers.
Example:
clks: mc_cgm0@4003c000 {
compatible = "fsl,s32v234-mc_cgm0";
reg = <0x0 0x4003C000 0x0 0x1000>;
#clock-cells = <1>;
};
[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM

View File

@ -0,0 +1,16 @@
* NXP S32V234 Mode Entry Module (MC_ME)
See chapters 22 ("Clocking") and 69 ("Mode Entry Module (MC_ME)") in the
reference manual[1].
Required properties:
- compatible: Should be "fsl,s32v234-mc_me"
- reg: Location and length of the register set
Example:
mc_me: mc_me@4004a000 {
compatible = "fsl,s32v234-mc_me";
reg = <0x0 0x4004A000 0x0 0x1000>;
};
[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM

View File

@ -212,6 +212,12 @@ config ARCH_ROCKCHIP
This enables support for the ARMv8 based Rockchip chipsets,
like the RK3368.
config ARCH_S32
bool "NXP S32 SoC Family"
select ARCH_S32_CLK
help
This enables support for the NXP S32 family of processors.
config ARCH_SEATTLE
bool "AMD Seattle SoC Family"
help

View File

@ -328,6 +328,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

@ -98,6 +98,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 clk-dfs.o

View File

@ -0,0 +1,236 @@
/*
* Copyright 2015-2016 Freescale Semiconductor, Inc.
* Copyright 2017-2018 NXP
*
* 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 <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include "clk.h"
/**
* struct clk_dfs - S32 DFS clock
* @clk_hw: clock source
* @reg: DFS register address
* @idx: the index of DFS encoded in the register
*
* DFS clock found on S32 series. Each register for DFS has 4 clk_dfs
* data encoded, and member idx is used to specify the one.
* Only ARMPLL(3 DFS), ENETPLL(4 DFS) and DDRPLL(3 DFS) has DFS outputs.
*/
struct clk_dfs {
struct clk_hw hw;
void __iomem *reg;
enum s32v234_plldig_type plltype;
u8 idx;
u32 mfn;
};
#define to_clk_dfs(_hw) container_of(_hw, struct clk_dfs, hw)
static int get_pllx_dfs_nr(enum s32v234_plldig_type plltype)
{
switch (plltype) {
case S32_PLLDIG_ARM:
return ARMPLL_DFS_NR;
case S32_PLLDIG_ENET:
return ENETPLL_DFS_NR;
case S32_PLLDIG_DDR:
return DDRPLL_DFS_NR;
case S32_PLLDIG_PERIPH:
case S32_PLLDIG_VIDEO:
pr_warn("Current selected PLL has no DFS\n");
break;
}
return -EINVAL;
}
static unsigned long get_pllx_dfsy_max_rate(enum s32v234_plldig_type plltype,
int dfsno)
{
switch (plltype) {
case S32_PLLDIG_ARM:
switch (dfsno) {
case 0:
return ARMPLL_DFS0_MAX_RATE;
case 1:
return ARMPLL_DFS1_MAX_RATE;
case 2:
return ARMPLL_DFS2_MAX_RATE;
}
break;
case S32_PLLDIG_ENET:
switch (dfsno) {
case 0:
return ENETPLL_DFS0_MAX_RATE;
case 1:
return ENETPLL_DFS1_MAX_RATE;
case 2:
return ENETPLL_DFS2_MAX_RATE;
case 3:
return ENETPLL_DFS3_MAX_RATE;
}
break;
case S32_PLLDIG_DDR:
switch (dfsno) {
case 0:
return DDRPLL_DFS0_MAX_RATE;
case 1:
return DDRPLL_DFS1_MAX_RATE;
case 2:
return DDRPLL_DFS2_MAX_RATE;
}
break;
case S32_PLLDIG_PERIPH:
case S32_PLLDIG_VIDEO:
pr_warn("Current selected PLL has no DFS.");
break;
default:
pr_warn("Unsupported PLL. Use %d or %d\n",
S32_PLLDIG_ARM, S32_PLLDIG_VIDEO);
break;
}
return -EINVAL;
}
static int clk_dfs_enable(struct clk_hw *hw)
{
/*
* TODO: When SOC is available, this function
* should be tested and implemented for DFS
* if it is possible
*/
return 0;
}
static void clk_dfs_disable(struct clk_hw *hw)
{
/*
* TODO: When SOC is available, this function
* should be tested and implemented for DFS
* if it is possible
*/
}
static unsigned long clk_dfs_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_dfs *dfs = to_clk_dfs(hw);
u32 mfn, mfi, rate;
u32 dvport = readl_relaxed(DFS_DVPORTn(dfs->reg, dfs->idx));
mfn = (dvport & DFS_DVPORTn_MFN_MASK) >> DFS_DVPORTn_MFN_OFFSET;
mfi = (dvport & DFS_DVPORTn_MFI_MASK) >> DFS_DVPORTn_MFI_OFFSET;
mfi <<= 8;
rate = parent_rate / (mfi + mfn);
rate <<= 8;
return rate;
}
static long clk_dfs_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_dfs *dfs = to_clk_dfs(hw);
unsigned long max_allowed_rate;
max_allowed_rate = get_pllx_dfsy_max_rate(dfs->plltype, dfs->idx);
if (rate > max_allowed_rate)
rate = max_allowed_rate;
return rate;
}
static int clk_dfs_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_dfs *dfs = to_clk_dfs(hw);
u32 mfi;
u32 portreset = readl_relaxed(DFS_PORTRESET(dfs->reg));
writel_relaxed(DFS_CTRL_DLL_RESET, DFS_CTRL(dfs->reg));
writel_relaxed(portreset | ~DFS_PORTRESET_PORTRESET_SET(dfs->idx),
DFS_PORTRESET(dfs->reg));
mfi = parent_rate/rate;
writel_relaxed(DFS_DVPORTn_MFI_SET(mfi) |
DFS_DVPORTn_MFN_SET(dfs->mfn),
DFS_DVPORTn(dfs->reg, dfs->idx));
writel_relaxed(~DFS_CTRL_DLL_RESET, DFS_CTRL(dfs->reg));
while (readl_relaxed(DFS_PORTSR(dfs->reg)) & (1 << (dfs->idx)))
;
return 0;
}
static int clk_dfs_is_enabled(struct clk_hw *hw)
{
struct clk_dfs *dfs = to_clk_dfs(hw);
/* Check if current DFS output port is locked */
if (readl_relaxed(DFS_PORTSR(dfs->reg)) & (1 << (dfs->idx)))
return 0;
return 1;
}
static const struct clk_ops clk_dfs_ops = {
.enable = clk_dfs_enable,
.disable = clk_dfs_disable,
.recalc_rate = clk_dfs_recalc_rate,
.round_rate = clk_dfs_round_rate,
.set_rate = clk_dfs_set_rate,
.is_enabled = clk_dfs_is_enabled,
};
struct clk *s32v234_clk_dfs(enum s32v234_plldig_type type, const char *name,
const char *parent_name, void __iomem *reg,
u8 idx, u32 mfn)
{
struct clk_dfs *dfs;
struct clk *clk;
struct clk_init_data init;
/* PERIPH and VIDEO PLL do not have DFS */
if (type == S32_PLLDIG_PERIPH || type == S32_PLLDIG_VIDEO)
return ERR_PTR(-EINVAL);
/* check if DFS index is valid for current pll */
if (idx >= get_pllx_dfs_nr(type))
return ERR_PTR(-EINVAL);
dfs = kzalloc(sizeof(*dfs), GFP_KERNEL);
if (!dfs)
return ERR_PTR(-ENOMEM);
dfs->reg = reg;
dfs->idx = idx;
dfs->mfn = mfn;
dfs->plltype = type;
init.name = name;
init.ops = &clk_dfs_ops;
init.flags = 0;
init.parent_names = &parent_name;
init.num_parents = 1;
dfs->hw.init = &init;
clk = clk_register(NULL, &dfs->hw);
if (IS_ERR(clk))
kfree(dfs);
return clk;
}

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,299 @@
// 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_cgm1_base;
static void __iomem *mc_cgm2_base;
static void __iomem *mc_cgm3_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", };
PNAME(sys_sels) = {"firc", "fxosc", "armpll_dfs0", };
PNAME(can_sels) = {"firc", "fxosc", "dummy",
"periphpll_phi0_div5", };
PNAME(lin_sels) = {"firc", "fxosc", "dummy",
"periphpll_phi0_div3", "dummy", "dummy",
"dummy", "dummy", "sys6",};
PNAME(sdhc_sels) = {"firc", "fxosc", "dummy",
"enetpll_dfs3",};
PNAME(enet_sels) = {"firc", "fxosc", "dummy",
"dummy", "enetpll_phi0",};
PNAME(enet_time_sels) = {"firc", "fxosc", "dummy",
"dummy", "enetpll_phi0",};
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 = of_find_compatible_node(NULL, NULL, "fsl,s32v234-mc_cgm1");
mc_cgm1_base = of_iomap(np, 0);
if (WARN_ON(!mc_cgm1_base))
return;
np = of_find_compatible_node(NULL, NULL, "fsl,s32v234-mc_cgm2");
mc_cgm2_base = of_iomap(np, 0);
if (WARN_ON(!mc_cgm2_base))
return;
np = of_find_compatible_node(NULL, NULL, "fsl,s32v234-mc_cgm3");
mc_cgm3_base = of_iomap(np, 0);
if (WARN_ON(!mc_cgm3_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_ARMPLL_SRC_SEL] = s32_clk_mux("armpll_sel",
SRC_GPR1, SRC_GPR1_ARMPLL_SRC_SEL_OFFSET,
SRC_GPR1_XPLL_SRC_SEL_SIZE,
osc_sels, ARRAY_SIZE(osc_sels), &s32v234_lock);
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);
clk[S32V234_CLK_ENETPLL_SRC_SEL] = s32_clk_mux("enetpll_sel",
SRC_GPR1, SRC_GPR1_ENETPLL_SRC_SEL_OFFSET,
SRC_GPR1_XPLL_SRC_SEL_SIZE,
osc_sels, ARRAY_SIZE(osc_sels), &s32v234_lock);
/* ARM_PLL */
clk[S32V234_CLK_ARMPLL_VCO] = s32v234_clk_plldig(S32_PLLDIG_ARM,
"armpll_vco", "armpll_sel", ARMPLL_PLLDIG(mc_cgm0_base),
ARMPLL_PLLDIG_PLLDV_MFD, ARMPLL_PLLDIG_PLLDV_MFN,
ARMPLL_PLLDIG_PLLDV_RFDPHI0, ARMPLL_PLLDIG_PLLDV_RFDPHI1);
clk[S32V234_CLK_ARMPLL_PHI0] = s32v234_clk_plldig_phi(S32_PLLDIG_ARM,
"armpll_phi0", "armpll_vco",
ARMPLL_PLLDIG(mc_cgm0_base), 0);
clk[S32V234_CLK_ARMPLL_PHI1] = s32v234_clk_plldig_phi(S32_PLLDIG_ARM,
"armpll_phi1", "armpll_vco",
ARMPLL_PLLDIG(mc_cgm0_base), 1);
clk[S32V234_CLK_ARMPLL_DFS0] = s32v234_clk_dfs(S32_PLLDIG_ARM,
"armpll_dfs0", "armpll_phi1",
ARMPLL_PLLDIG_DFS(mc_cgm0_base), 0,
ARMPLL_PLLDIG_DFS0_MFN);
clk[S32V234_CLK_ARMPLL_DFS1] = s32v234_clk_dfs(S32_PLLDIG_ARM,
"armpll_dfs1", "armpll_phi1",
ARMPLL_PLLDIG_DFS(mc_cgm0_base), 1,
ARMPLL_PLLDIG_DFS1_MFN);
clk[S32V234_CLK_ARMPLL_DFS2] = s32v234_clk_dfs(S32_PLLDIG_ARM,
"armpll_dfs2", "armpll_phi1",
ARMPLL_PLLDIG_DFS(mc_cgm0_base), 2,
ARMPLL_PLLDIG_DFS2_MFN);
clk[S32V234_CLK_SYS_SEL] = s32_clk_mux("sys_sel",
MC_ME_RUNn_MC(mc_me_base, 0),
MC_ME_MODE_MC_SYSCLK_OFFSET,
MC_ME_MODE_MC_SYSCLK_SIZE,
sys_sels, ARRAY_SIZE(sys_sels), &s32v234_lock);
clk[S32V234_CLK_SYS3] = s32_clk_divider("sys3", "sys_sel",
CGM_SC_DCn(mc_cgm0_base, 0), MC_CGM_SC_DCn_PREDIV_OFFSET,
MC_CGM_SC_DCn_PREDIV_SIZE, &s32v234_lock);
clk[S32V234_CLK_SYS6] = s32_clk_divider("sys6", "sys_sel",
CGM_SC_DCn(mc_cgm0_base, 1), MC_CGM_SC_DCn_PREDIV_OFFSET,
MC_CGM_SC_DCn_PREDIV_SIZE, &s32v234_lock);
clk[S32V234_CLK_SYS6_DIV2] = s32_clk_divider("sys6_div2", "sys_sel",
CGM_SC_DCn(mc_cgm0_base, 2), MC_CGM_SC_DCn_PREDIV_OFFSET,
MC_CGM_SC_DCn_PREDIV_SIZE, &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);
clk[S32V234_CLK_CAN_SEL] = s32_clk_mux("can_sel",
CGM_ACn_SC(mc_cgm0_base, 6),
MC_CGM_ACn_SEL_OFFSET,
MC_CGM_ACn_SEL_SIZE,
can_sels, ARRAY_SIZE(can_sels), &s32v234_lock);
/* CAN Clock */
clk[S32V234_CLK_CAN] = s32_clk_divider("can", "can_sel",
CGM_ACn_DCm(mc_cgm0_base, 6, 0),
MC_CGM_ACn_DCm_PREDIV_OFFSET,
MC_CGM_ACn_DCm_PREDIV_SIZE, &s32v234_lock);
/* Lin Clock */
clk[S32V234_CLK_LIN_SEL] = s32_clk_mux("lin_sel",
CGM_ACn_SC(mc_cgm0_base, 3),
MC_CGM_ACn_SEL_OFFSET,
MC_CGM_ACn_SEL_SIZE,
lin_sels, ARRAY_SIZE(lin_sels), &s32v234_lock);
clk[S32V234_CLK_LIN] = s32_clk_divider("lin", "lin_sel",
CGM_ACn_DCm(mc_cgm0_base, 3, 0),
MC_CGM_ACn_DCm_PREDIV_OFFSET,
MC_CGM_ACn_DCm_PREDIV_SIZE, &s32v234_lock);
clk[S32V234_CLK_LIN_IPG] = s32_clk_fixed_factor("lin_ipg",
"lin", 1, 2);
/* enable PERIPHPLL */
enable_clocks_sources(0, MC_ME_MODE_MC_PERIPHPLL,
MC_ME_RUNn_MC(mc_me_base, 0));
/* ENET_PLL */
clk[S32V234_CLK_ENETPLL_VCO] = s32v234_clk_plldig(S32_PLLDIG_ENET,
"enetpll_vco", "enetpll_sel", ENETPLL_PLLDIG(mc_cgm0_base),
ENETPLL_PLLDIG_PLLDV_MFD, ENETPLL_PLLDIG_PLLDV_MFN,
ENETPLL_PLLDIG_PLLDV_RFDPHI0, ENETPLL_PLLDIG_PLLDV_RFDPHI1);
clk[S32V234_CLK_ENETPLL_PHI0] = s32v234_clk_plldig_phi(S32_PLLDIG_ENET,
"enetpll_phi0", "enetpll_vco",
ENETPLL_PLLDIG(mc_cgm0_base), 0);
clk[S32V234_CLK_ENETPLL_PHI1] = s32v234_clk_plldig_phi(S32_PLLDIG_ENET,
"enetpll_phi1", "enetpll_vco",
ENETPLL_PLLDIG(mc_cgm0_base), 1);
clk[S32V234_CLK_ENETPLL_DFS0] = s32v234_clk_dfs(S32_PLLDIG_ENET,
"enetpll_dfs0", "enetpll_phi1",
ENETPLL_PLLDIG_DFS(mc_cgm0_base), 0,
ENETPLL_PLLDIG_DFS0_MFN);
clk[S32V234_CLK_ENETPLL_DFS1] = s32v234_clk_dfs(S32_PLLDIG_ENET,
"enetpll_dfs1", "enetpll_phi1",
ENETPLL_PLLDIG_DFS(mc_cgm0_base), 1,
ENETPLL_PLLDIG_DFS1_MFN);
clk[S32V234_CLK_ENETPLL_DFS2] = s32v234_clk_dfs(S32_PLLDIG_ENET,
"enetpll_dfs2", "enetpll_phi1",
ENETPLL_PLLDIG_DFS(mc_cgm0_base), 2,
ENETPLL_PLLDIG_DFS2_MFN);
clk[S32V234_CLK_ENETPLL_DFS3] = s32v234_clk_dfs(S32_PLLDIG_ENET,
"enetpll_dfs3", "enetpll_phi1",
ENETPLL_PLLDIG_DFS(mc_cgm0_base), 3,
ENETPLL_PLLDIG_DFS3_MFN);
/* ENET Clock */
clk[S32V234_CLK_ENET_SEL] = s32_clk_mux("enet_sel",
CGM_ACn_SC(mc_cgm2_base, 2),
MC_CGM_ACn_SEL_OFFSET,
MC_CGM_ACn_SEL_SIZE,
enet_sels, ARRAY_SIZE(enet_sels), &s32v234_lock);
clk[S32V234_CLK_ENET_TIME_SEL] = s32_clk_mux("enet_time_sel",
CGM_ACn_SC(mc_cgm0_base, 7),
MC_CGM_ACn_SEL_OFFSET,
MC_CGM_ACn_SEL_SIZE,
enet_time_sels, ARRAY_SIZE(enet_time_sels), &s32v234_lock);
clk[S32V234_CLK_ENET] = s32_clk_divider("enet", "enet_sel",
CGM_ACn_DCm(mc_cgm2_base, 2, 0),
MC_CGM_ACn_DCm_PREDIV_OFFSET,
MC_CGM_ACn_DCm_PREDIV_SIZE, &s32v234_lock);
clk[S32V234_CLK_ENET_TIME] = s32_clk_divider("enet_time",
"enet_time_sel",
CGM_ACn_DCm(mc_cgm0_base, 7, 1),
MC_CGM_ACn_DCm_PREDIV_OFFSET,
MC_CGM_ACn_DCm_PREDIV_SIZE, &s32v234_lock);
/* SDHC Clock */
clk[S32V234_CLK_SDHC_SEL] = s32_clk_mux("sdhc_sel",
CGM_ACn_SC(mc_cgm0_base, 15),
MC_CGM_ACn_SEL_OFFSET,
MC_CGM_ACn_SEL_SIZE,
sdhc_sels, ARRAY_SIZE(sdhc_sels), &s32v234_lock);
clk[S32V234_CLK_SDHC] = s32_clk_divider("sdhc", "sdhc_sel",
CGM_ACn_DCm(mc_cgm0_base, 15, 0),
MC_CGM_ACn_DCm_PREDIV_OFFSET,
MC_CGM_ACn_DCm_PREDIV_SIZE, &s32v234_lock);
/* 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,31 @@
/* 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 "dfs.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);
struct clk *s32v234_clk_dfs(enum s32v234_plldig_type type, const char *name,
const char *parent_name,
void __iomem *reg, u8 idx, u32 mfn);
#endif

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2018 NXP
*
* 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.
*/
#ifndef _DFS_S32V234_H
#define _DFS_S32V234_H
/* DFS Control Register (DFS_CTRL) */
#define DFS_CTRL(base) ((base) + 0x00000018)
#define DFS_CTRL_DLL_LOLIE (1 << 0)
#define DFS_CTRL_DLL_RESET (1 << 1)
/* DFS Port Status (DFS_PORTSR) */
#define DFS_PORTSR(base) ((base) + 0x0000000C)
#define DFS_PORTSR_MASK (0x0000000F)
#define DFS_PORTSR_OFFSET (28)
/* DFS Port Reset Register (DFS_PORTRESET) */
#define DFS_PORTRESET(base) ((base) + 0x00000014)
#define DFS_PORTRESET_PORTRESET_SET(val) \
(DFS_PORTRESET_PORTRESET_MASK | \
(((val) & DFS_PORTRESET_PORTRESET_MAXVAL) \
<< DFS_PORTRESET_PORTRESET_OFFSET))
#define DFS_PORTRESET_PORTRESET_MAXVAL (0xF)
#define DFS_PORTRESET_PORTRESET_MASK (0x0000000F)
#define DFS_PORTRESET_PORTRESET_OFFSET (28)
/* DFS Divide Register Portn (DFS_DVPORTn) */
#define DFS_DVPORTn(base, n) ((base) + (0x0000001C + \
((n) * sizeof(u32))))
#define DFS_DVPORTn_MFI_SET(val) (DFS_DVPORTn_MFI_MASK & \
(((val) & DFS_DVPORTn_MFI_MAXVAL) \
<< DFS_DVPORTn_MFI_OFFSET))
#define DFS_DVPORTn_MFN_SET(val) (DFS_DVPORTn_MFN_MASK & \
(((val) & DFS_DVPORTn_MFN_MAXVAL) \
<< DFS_DVPORTn_MFN_OFFSET))
#define DFS_DVPORTn_MFI_MASK (0x0000FF00)
#define DFS_DVPORTn_MFN_MASK (0x000000FF)
#define DFS_DVPORTn_MFI_MAXVAL (0xFF)
#define DFS_DVPORTn_MFN_MAXVAL (0xFF)
#define DFS_DVPORTn_MFI_OFFSET (8)
#define DFS_DVPORTn_MFN_OFFSET (0)
#define DFS_MAXNUMBER (4)
/*
* Naming convention for PLL:
* ARMPLL - PLL0
* PERIPHPLL - PLL1
* ENETPLL - PLL2
* DDRPLL - PLL3
* VIDEOPLL - PLL4
*/
/* The max values for PLL DFS is in Hz */
/* ARMPLL */
#define ARMPLL_DFS0_MAX_RATE (266000000)
#define ARMPLL_DFS1_MAX_RATE (600000000)
#define ARMPLL_DFS2_MAX_RATE (600000000)
/* ENETPLL */
#define ENETPLL_DFS0_MAX_RATE (350000000)
#define ENETPLL_DFS1_MAX_RATE (350000000)
#define ENETPLL_DFS2_MAX_RATE (416000000)
#define ENETPLL_DFS3_MAX_RATE (104000000)
/* DDRPLL */
#define DDRPLL_DFS0_MAX_RATE (500000000)
#define DDRPLL_DFS1_MAX_RATE (500000000)
#define DDRPLL_DFS2_MAX_RATE (350000000)
#define ARMPLL_DFS_NR (3)
#define ENETPLL_DFS_NR (4)
#define DDRPLL_DFS_NR (3)
#endif

View File

@ -0,0 +1,70 @@
/* 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 ARMPLL_PLLDIG(mc_cgm) (mc_cgm)
#define ARMPLL_PLLDIG_DFS(mc_cgm) ((mc_cgm) + 0x40)
#define ARMPLL_PLLDIG_PLLDV_MFD (50)
#define ARMPLL_PLLDIG_PLLDV_MFN (0)
#define ARMPLL_PLLDIG_PLLDV_RFDPHI0 (1)
#define ARMPLL_PLLDIG_PLLDV_RFDPHI1 (1)
#define ARMPLL_PLLDIG_DFS0_MFN (195)
#define ARMPLL_PLLDIG_DFS1_MFN (171)
#define ARMPLL_PLLDIG_DFS2_MFN (171)
#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)
#define ENETPLL_PLLDIG(mc_cgm) ((mc_cgm) + 0x100)
#define ENETPLL_PLLDIG_DFS(mc_cgm) ((mc_cgm) + 0x100 + 0x40)
#define ENETPLL_PLLDIG_PLLDV_MFD (50)
#define ENETPLL_PLLDIG_PLLDV_MFN (0)
#define ENETPLL_PLLDIG_PLLDV_RFDPHI0 (0x1)
#define ENETPLL_PLLDIG_PLLDV_RFDPHI1 (0x1)
#define ENETPLL_PLLDIG_DFS0_MFN (220)
#define ENETPLL_PLLDIG_DFS1_MFN (220)
#define ENETPLL_PLLDIG_DFS2_MFN (33)
#define ENETPLL_PLLDIG_DFS3_MFN (1)
/* 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

View File

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
* Copyright (C) 2017 NXP
*/
#ifndef __DT_BINDINGS_CLOCK_S32V234_H
#define __DT_BINDINGS_CLOCK_S32V234_H
#define S32V234_CLK_DUMMY 0
#define S32V234_CLK_FXOSC 1
#define S32V234_CLK_FIRC 2
/* PERIPH PLL */
#define S32V234_CLK_PERIPHPLL_SRC_SEL 3
#define S32V234_CLK_PERIPHPLL_VCO 4
#define S32V234_CLK_PERIPHPLL_PHI0 5
#define S32V234_CLK_PERIPHPLL_PHI0_DIV3 6
#define S32V234_CLK_PERIPHPLL_PHI0_DIV5 7
#define S32V234_CLK_PERIPHPLL_PHI1 8
/* LINFlexD Clock */
#define S32V234_CLK_LIN 9
#define S32V234_CLK_LIN_SEL 10
#define S32V234_CLK_LIN_IPG 11
/* SDHC Clock */
#define S32V234_CLK_SDHC 12
#define S32V234_CLK_SDHC_SEL 13
/* ENET PLL */
#define S32V234_CLK_ENETPLL_SRC_SEL 14
#define S32V234_CLK_ENETPLL_VCO 15
#define S32V234_CLK_ENETPLL_PHI0 16
#define S32V234_CLK_ENETPLL_PHI1 17
#define S32V234_CLK_ENETPLL_DFS0 18
#define S32V234_CLK_ENETPLL_DFS1 19
#define S32V234_CLK_ENETPLL_DFS2 20
#define S32V234_CLK_ENETPLL_DFS3 21
/* System Clock */
#define S32V234_CLK_SYS_SEL 22
#define S32V234_CLK_SYS3 23
#define S32V234_CLK_SYS6 24
#define S32V234_CLK_SYS6_DIV2 25
/* ENET Clock */
#define S32V234_CLK_ENET_TIME_DIV 26
#define S32V234_CLK_ENET_TIME_SEL 27
#define S32V234_CLK_ENET_DIV 28
#define S32V234_CLK_ENET_SEL 29
#define S32V234_CLK_ENET 30
#define S32V234_CLK_ENET_TIME 31
/* ARM PLL */
#define S32V234_CLK_ARMPLL_SRC_SEL 32
#define S32V234_CLK_ARMPLL_VCO 33
#define S32V234_CLK_ARMPLL_PHI0 34
#define S32V234_CLK_ARMPLL_PHI1 35
#define S32V234_CLK_ARMPLL_DFS0 35
#define S32V234_CLK_ARMPLL_DFS1 36
#define S32V234_CLK_ARMPLL_DFS2 37
/* CAN Clock */
#define S32V234_CLK_CAN 38
#define S32V234_CLK_CAN_SEL 39
#define S32V234_CLK_END 40
#endif /* __DT_BINDINGS_CLOCK_S32V234_H */