Commit 897a54f9 authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'clk-imx-5.16' of...

Merge tag 'clk-imx-5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux into clk-imx

Pull i.MX clk driver changes from Abel Vesa:

 - Remove unused helpers from i.MX specific clock header
 - Rework all clk based helpers to use clk_hw based ones
 - Rework gate/mux/divider wrappers
 - Rework imx_clk_hw_composite and imx_clk_hw_pll14xx wrappers
 - Add i.MX8ULP clock driver and related bindings
 - Update i.MX pllv4 and composite clocks to support i.MX8ULP
 - Disable i.MX7ULP composite clock during initialization
 - Add CLK_SET_RATE_NO_REPARENT flag to the i.MX7ULP composite
 - Disable the pfd when set pfdv2 clock rate
 - Add support for i.MX8ULP in pfdv2
 - Add the pcc reset controller support on i.MX8ULP
 - Fix the build break when clk-imx8ulp is built as module
 - Move csi_sel mux to correct base register in i.MX6UL clock drivr
 - Fix csi clk gate register in i.MX6UL clock driver
 - Fix build bug making CLK_IMX8ULP select MXC_CLK

* tag 'clk-imx-5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux: (21 commits)
  clk: imx: Make CLK_IMX8ULP select MXC_CLK
  clk: imx: imx6ul: Fix csi clk gate register
  clk: imx: imx6ul: Move csi_sel mux to correct base register
  clk: imx: Fix the build break when clk-imx8ulp build as module
  clk: imx: Add the pcc reset controller support on imx8ulp
  clk: imx: Add clock driver for imx8ulp
  clk: imx: Update the pfdv2 for 8ulp specific support
  clk: imx: disable the pfd when set pfdv2 clock rate
  clk: imx: Add 'CLK_SET_RATE_NO_REPARENT' for composite-7ulp
  clk: imx: disable i.mx7ulp composite clock during initialization
  clk: imx: Update the compsite driver to support imx8ulp
  clk: imx: Update the pllv4 to support imx8ulp
  dt-bindings: clock: Add imx8ulp clock support
  clk: imx: Rework imx_clk_hw_pll14xx wrapper
  clk: imx: Rework all imx_clk_hw_composite wrappers
  clk: imx: Rework all clk_hw_register_divider wrappers
  clk: imx: Rework all clk_hw_register_mux wrappers
  clk: imx: Rework all clk_hw_register_gate2 wrappers
  clk: imx: Rework all clk_hw_register_gate wrappers
  clk: imx: Make mux/mux2 clk based helpers use clk_hw based ones
  ...
parents 6880fa6c e8271eff
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/imx8ulp-cgc-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP i.MX8ULP Clock Generation & Control(CGC) Module Binding
maintainers:
- Jacky Bai <ping.bai@nxp.com>
description: |
On i.MX8ULP, The clock sources generation, distribution and management is
under the control of several CGCs & PCCs modules. The CGC modules generate
and distribute clocks on the device.
properties:
compatible:
enum:
- fsl,imx8ulp-cgc1
- fsl,imx8ulp-cgc2
reg:
maxItems: 1
'#clock-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
additionalProperties: false
examples:
# Clock Generation & Control Module node:
- |
clock-controller@292c0000 {
compatible = "fsl,imx8ulp-cgc1";
reg = <0x292c0000 0x10000>;
#clock-cells = <1>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/imx8ulp-pcc-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP i.MX8ULP Peripheral Clock Controller(PCC) Module Binding
maintainers:
- Jacky Bai <ping.bai@nxp.com>
description: |
On i.MX8ULP, The clock sources generation, distribution and management is
under the control of several CGCs & PCCs modules. The PCC modules control
software reset, clock selection, optional division and clock gating mode
for peripherals.
properties:
compatible:
enum:
- fsl,imx8ulp-pcc3
- fsl,imx8ulp-pcc4
- fsl,imx8ulp-pcc5
reg:
maxItems: 1
'#clock-cells':
const: 1
'#reset-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
# Peripheral Clock Control Module node:
- |
clock-controller@292d0000 {
compatible = "fsl,imx8ulp-pcc3";
reg = <0x292d0000 0x10000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
......@@ -98,3 +98,10 @@ config CLK_IMX8QXP
select MXC_CLK_SCU
help
Build the driver for IMX8QXP SCU based clocks.
config CLK_IMX8ULP
tristate "IMX8ULP CCM Clock Driver"
depends on ARCH_MXC || COMPILE_TEST
select MXC_CLK
help
Build the driver for i.MX8ULP CCM Clock Driver
......@@ -31,6 +31,8 @@ clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \
clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o
clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o
obj-$(CONFIG_CLK_IMX1) += clk-imx1.o
obj-$(CONFIG_CLK_IMX25) += clk-imx25.o
obj-$(CONFIG_CLK_IMX27) += clk-imx27.o
......
......@@ -8,6 +8,7 @@
#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/slab.h>
#include "../clk-fractional-divider.h"
......@@ -23,17 +24,61 @@
#define PCG_PCD_WIDTH 3
#define PCG_PCD_MASK 0x7
struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
#define SW_RST BIT(28)
static int pcc_gate_enable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
unsigned long flags;
u32 val;
int ret;
ret = clk_gate_ops.enable(hw);
if (ret)
return ret;
spin_lock_irqsave(gate->lock, flags);
/*
* release the sw reset for peripherals associated with
* with this pcc clock.
*/
val = readl(gate->reg);
val |= SW_RST;
writel(val, gate->reg);
spin_unlock_irqrestore(gate->lock, flags);
return 0;
}
static void pcc_gate_disable(struct clk_hw *hw)
{
clk_gate_ops.disable(hw);
}
static int pcc_gate_is_enabled(struct clk_hw *hw)
{
return clk_gate_ops.is_enabled(hw);
}
static const struct clk_ops pcc_gate_ops = {
.enable = pcc_gate_enable,
.disable = pcc_gate_disable,
.is_enabled = pcc_gate_is_enabled,
};
static struct clk_hw *imx_ulp_clk_hw_composite(const char *name,
const char * const *parent_names,
int num_parents, bool mux_present,
bool rate_present, bool gate_present,
void __iomem *reg)
void __iomem *reg, bool has_swrst)
{
struct clk_hw *mux_hw = NULL, *fd_hw = NULL, *gate_hw = NULL;
struct clk_fractional_divider *fd = NULL;
struct clk_gate *gate = NULL;
struct clk_mux *mux = NULL;
struct clk_hw *hw;
u32 val;
if (mux_present) {
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
......@@ -43,6 +88,8 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
mux->reg = reg;
mux->shift = PCG_PCS_SHIFT;
mux->mask = PCG_PCS_MASK;
if (has_swrst)
mux->lock = &imx_ccm_lock;
}
if (rate_present) {
......@@ -60,6 +107,8 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
fd->nwidth = PCG_PCD_WIDTH;
fd->nmask = PCG_PCD_MASK;
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
if (has_swrst)
fd->lock = &imx_ccm_lock;
}
if (gate_present) {
......@@ -72,13 +121,27 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
gate_hw = &gate->hw;
gate->reg = reg;
gate->bit_idx = PCG_CGC_SHIFT;
if (has_swrst)
gate->lock = &imx_ccm_lock;
/*
* make sure clock is gated during clock tree initialization,
* the HW ONLY allow clock parent/rate changed with clock gated,
* during clock tree initialization, clocks could be enabled
* by bootloader, so the HW status will mismatch with clock tree
* prepare count, then clock core driver will allow parent/rate
* change since the prepare count is zero, but HW actually
* prevent the parent/rate change due to the clock is enabled.
*/
val = readl_relaxed(reg);
val &= ~(1 << PCG_CGC_SHIFT);
writel_relaxed(val, reg);
}
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, &clk_mux_ops, fd_hw,
&clk_fractional_divider_ops, gate_hw,
&clk_gate_ops, CLK_SET_RATE_GATE |
CLK_SET_PARENT_GATE);
has_swrst ? &pcc_gate_ops : &clk_gate_ops, CLK_SET_RATE_GATE |
CLK_SET_PARENT_GATE | CLK_SET_RATE_NO_REPARENT);
if (IS_ERR(hw)) {
kfree(mux);
kfree(fd);
......@@ -87,3 +150,20 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
return hw;
}
struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names,
int num_parents, bool mux_present, bool rate_present,
bool gate_present, void __iomem *reg)
{
return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present,
gate_present, reg, false);
}
struct clk_hw *imx8ulp_clk_hw_composite(const char *name, const char * const *parent_names,
int num_parents, bool mux_present, bool rate_present,
bool gate_present, void __iomem *reg, bool has_swrst)
{
return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present,
gate_present, reg, has_swrst);
}
EXPORT_SYMBOL_GPL(imx8ulp_clk_hw_composite);
......@@ -171,7 +171,7 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = {
.determine_rate = imx8m_clk_composite_mux_determine_rate,
};
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
struct clk_hw *__imx8m_clk_hw_composite(const char *name,
const char * const *parent_names,
int num_parents, void __iomem *reg,
u32 composite_flags,
......@@ -246,4 +246,4 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
kfree(mux);
return ERR_CAST(hw);
}
EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags);
EXPORT_SYMBOL_GPL(__imx8m_clk_hw_composite);
......@@ -161,7 +161,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
hws[IMX6UL_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
hws[IMX6UL_PLL6_BYPASS] = imx_clk_hw_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
hws[IMX6UL_PLL7_BYPASS] = imx_clk_hw_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT);
/* Do not bypass PLLs initially */
clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk);
......@@ -270,6 +269,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
hws[IMX6UL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
hws[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_hw_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT);
hws[IMX6UL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
hws[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
hws[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
......@@ -380,7 +380,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
hws[IMX6ULL_CLK_ESAI_IPG] = imx_clk_hw_gate2_shared("esai_ipg", "ahb", base + 0x70, 0, &share_count_esai);
hws[IMX6ULL_CLK_ESAI_MEM] = imx_clk_hw_gate2_shared("esai_mem", "ahb", base + 0x70, 0, &share_count_esai);
}
hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x70, 2);
hws[IMX6UL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6);
hws[IMX6UL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8);
hws[IMX6UL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10);
......@@ -391,6 +390,12 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
hws[IMX6UL_CLK_PXP] = imx_clk_hw_gate2("pxp", "axi", base + 0x70, 30);
/* CCGR3 */
/*
* Although the imx6ull reference manual lists CCGR2 as the csi clk
* gate register, tests have shown that it is actually the CCGR3
* register bit 0/1, same as for the imx6ul.
*/
hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x74, 0);
hws[IMX6UL_CLK_UART5_IPG] = imx_clk_hw_gate2("uart5_ipg", "ipg", base + 0x74, 2);
hws[IMX6UL_CLK_UART5_SERIAL] = imx_clk_hw_gate2("uart5_serial", "uart_podf", base + 0x74, 2);
if (clk_on_imx6ul()) {
......
......@@ -78,20 +78,20 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
hws[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE);
/* name parent_name base */
hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4("apll", "apll_pre_div", base + 0x500);
hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4("spll", "spll_pre_div", base + 0x600);
hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "apll", "apll_pre_div", base + 0x500);
hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "spll", "spll_pre_div", base + 0x600);
/* APLL PFDs */
hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2("apll_pfd1", "apll", base + 0x50c, 1);
hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2("apll_pfd2", "apll", base + 0x50c, 2);
hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2("apll_pfd3", "apll", base + 0x50c, 3);
hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd0", "apll", base + 0x50c, 0);
hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd1", "apll", base + 0x50c, 1);
hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd2", "apll", base + 0x50c, 2);
hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd3", "apll", base + 0x50c, 3);
/* SPLL PFDs */
hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd0", "spll", base + 0x60C, 0);
hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd1", "spll", base + 0x60C, 1);
hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd2", "spll", base + 0x60C, 2);
hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd3", "spll", base + 0x60C, 3);
/* PLL Mux */
hws[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
......
This diff is collapsed.
......@@ -161,8 +161,17 @@ static int clk_pfdv2_set_rate(struct clk_hw *hw, unsigned long rate,
if (!rate)
return -EINVAL;
/* PFD can NOT change rate without gating */
WARN_ON(clk_pfdv2_is_enabled(hw));
/*
* PFD can NOT change rate without gating.
* as the PFDs may enabled in HW by default but no
* consumer used it, the enable count is '0', so the
* 'SET_RATE_GATE' can NOT help on blocking the set_rate
* ops especially for 'assigned-clock-xxx'. In order
* to simplify the case, just disable the PFD if it is
* enabled in HW but not in SW.
*/
if (clk_pfdv2_is_enabled(hw))
clk_pfdv2_disable(hw);
tmp = tmp * 18 + rate / 2;
do_div(tmp, rate);
......@@ -191,8 +200,8 @@ static const struct clk_ops clk_pfdv2_ops = {
.is_enabled = clk_pfdv2_is_enabled,
};
struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
void __iomem *reg, u8 idx)
struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name,
const char *parent_name, void __iomem *reg, u8 idx)
{
struct clk_init_data init;
struct clk_pfdv2 *pfd;
......@@ -214,7 +223,10 @@ struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
init.ops = &clk_pfdv2_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
if (type == IMX_PFDV2_IMX7ULP)
init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
else
init.flags = CLK_SET_RATE_GATE;
pfd->hw.init = &init;
......@@ -227,3 +239,4 @@ struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
return hw;
}
EXPORT_SYMBOL_GPL(imx_clk_hw_pfdv2);
......@@ -23,14 +23,17 @@
/* PLL Configuration Register (xPLLCFG) */
#define PLL_CFG_OFFSET 0x08
#define IMX8ULP_PLL_CFG_OFFSET 0x10
#define BP_PLL_MULT 16
#define BM_PLL_MULT (0x7f << 16)
/* PLL Numerator Register (xPLLNUM) */
#define PLL_NUM_OFFSET 0x10
#define IMX8ULP_PLL_NUM_OFFSET 0x1c
/* PLL Denominator Register (xPLLDENOM) */
#define PLL_DENOM_OFFSET 0x14
#define IMX8ULP_PLL_DENOM_OFFSET 0x18
#define MAX_MFD 0x3fffffff
#define DEFAULT_MFD 1000000
......@@ -38,6 +41,9 @@
struct clk_pllv4 {
struct clk_hw hw;
void __iomem *base;
u32 cfg_offset;
u32 num_offset;
u32 denom_offset;
};
/* Valid PLL MULT Table */
......@@ -72,12 +78,12 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
u32 mult, mfn, mfd;
u64 temp64;
mult = readl_relaxed(pll->base + PLL_CFG_OFFSET);
mult = readl_relaxed(pll->base + pll->cfg_offset);
mult &= BM_PLL_MULT;
mult >>= BP_PLL_MULT;
mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
mfn = readl_relaxed(pll->base + pll->num_offset);
mfd = readl_relaxed(pll->base + pll->denom_offset);
temp64 = parent_rate;
temp64 *= mfn;
do_div(temp64, mfd);
......@@ -165,13 +171,13 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
do_div(temp64, parent_rate);
mfn = temp64;
val = readl_relaxed(pll->base + PLL_CFG_OFFSET);
val = readl_relaxed(pll->base + pll->cfg_offset);
val &= ~BM_PLL_MULT;
val |= mult << BP_PLL_MULT;
writel_relaxed(val, pll->base + PLL_CFG_OFFSET);
writel_relaxed(val, pll->base + pll->cfg_offset);
writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
writel_relaxed(mfn, pll->base + pll->num_offset);
writel_relaxed(mfd, pll->base + pll->denom_offset);
return 0;
}
......@@ -207,8 +213,8 @@ static const struct clk_ops clk_pllv4_ops = {
.is_prepared = clk_pllv4_is_prepared,
};
struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
void __iomem *base)
struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name,
const char *parent_name, void __iomem *base)
{
struct clk_pllv4 *pll;
struct clk_hw *hw;
......@@ -221,6 +227,16 @@ struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
pll->base = base;
if (type == IMX_PLLV4_IMX8ULP) {
pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET;
pll->num_offset = IMX8ULP_PLL_NUM_OFFSET;
pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET;
} else {
pll->cfg_offset = PLL_CFG_OFFSET;
pll->num_offset = PLL_NUM_OFFSET;
pll->denom_offset = PLL_DENOM_OFFSET;
}
init.name = name;
init.ops = &clk_pllv4_ops;
init.parent_names = &parent_name;
......@@ -238,3 +254,4 @@ struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
return hw;
}
EXPORT_SYMBOL_GPL(imx_clk_hw_pllv4);
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0+ OR MIT */
/*
* Copyright 2021 NXP
*/
#ifndef __DT_BINDINGS_CLOCK_IMX8ULP_H
#define __DT_BINDINGS_CLOCK_IMX8ULP_H
#define IMX8ULP_CLK_DUMMY 0
/* CGC1 */
#define IMX8ULP_CLK_SPLL2 5
#define IMX8ULP_CLK_SPLL3 6
#define IMX8ULP_CLK_A35_SEL 7
#define IMX8ULP_CLK_A35_DIV 8
#define IMX8ULP_CLK_SPLL2_PRE_SEL 9
#define IMX8ULP_CLK_SPLL3_PRE_SEL 10
#define IMX8ULP_CLK_SPLL3_PFD0 11
#define IMX8ULP_CLK_SPLL3_PFD1 12
#define IMX8ULP_CLK_SPLL3_PFD2 13
#define IMX8ULP_CLK_SPLL3_PFD3 14
#define IMX8ULP_CLK_SPLL3_PFD0_DIV1 15
#define IMX8ULP_CLK_SPLL3_PFD0_DIV2 16
#define IMX8ULP_CLK_SPLL3_PFD1_DIV1 17
#define IMX8ULP_CLK_SPLL3_PFD1_DIV2 18
#define IMX8ULP_CLK_SPLL3_PFD2_DIV1 19
#define IMX8ULP_CLK_SPLL3_PFD2_DIV2 20
#define IMX8ULP_CLK_SPLL3_PFD3_DIV1 21
#define IMX8ULP_CLK_SPLL3_PFD3_DIV2 22
#define IMX8ULP_CLK_NIC_SEL 23
#define IMX8ULP_CLK_NIC_AD_DIVPLAT 24
#define IMX8ULP_CLK_NIC_PER_DIVPLAT 25
#define IMX8ULP_CLK_XBAR_SEL 26
#define IMX8ULP_CLK_XBAR_AD_DIVPLAT 27
#define IMX8ULP_CLK_XBAR_DIVBUS 28
#define IMX8ULP_CLK_XBAR_AD_SLOW 29
#define IMX8ULP_CLK_SOSC_DIV1 30
#define IMX8ULP_CLK_SOSC_DIV2 31
#define IMX8ULP_CLK_SOSC_DIV3 32
#define IMX8ULP_CLK_FROSC_DIV1 33
#define IMX8ULP_CLK_FROSC_DIV2 34
#define IMX8ULP_CLK_FROSC_DIV3 35
#define IMX8ULP_CLK_SPLL3_VCODIV 36
#define IMX8ULP_CLK_SPLL3_PFD0_DIV1_GATE 37
#define IMX8ULP_CLK_SPLL3_PFD0_DIV2_GATE 38
#define IMX8ULP_CLK_SPLL3_PFD1_DIV1_GATE 39
#define IMX8ULP_CLK_SPLL3_PFD1_DIV2_GATE 40
#define IMX8ULP_CLK_SPLL3_PFD2_DIV1_GATE 41
#define IMX8ULP_CLK_SPLL3_PFD2_DIV2_GATE 42
#define IMX8ULP_CLK_SPLL3_PFD3_DIV1_GATE 43
#define IMX8ULP_CLK_SPLL3_PFD3_DIV2_GATE 44
#define IMX8ULP_CLK_SOSC_DIV1_GATE 45
#define IMX8ULP_CLK_SOSC_DIV2_GATE 46
#define IMX8ULP_CLK_SOSC_DIV3_GATE 47
#define IMX8ULP_CLK_FROSC_DIV1_GATE 48
#define IMX8ULP_CLK_FROSC_DIV2_GATE 49
#define IMX8ULP_CLK_FROSC_DIV3_GATE 50
#define IMX8ULP_CLK_SAI4_SEL 51
#define IMX8ULP_CLK_SAI5_SEL 52
#define IMX8ULP_CLK_AUD_CLK1 53
#define IMX8ULP_CLK_ARM 54
#define IMX8ULP_CLK_ENET_TS_SEL 55
#define IMX8ULP_CLK_CGC1_END 56
/* CGC2 */
#define IMX8ULP_CLK_PLL4_PRE_SEL 0
#define IMX8ULP_CLK_PLL4 1
#define IMX8ULP_CLK_PLL4_VCODIV 2
#define IMX8ULP_CLK_DDR_SEL 3
#define IMX8ULP_CLK_DDR_DIV 4
#define IMX8ULP_CLK_LPAV_AXI_SEL 5
#define IMX8ULP_CLK_LPAV_AXI_DIV 6
#define IMX8ULP_CLK_LPAV_AHB_DIV 7
#define IMX8ULP_CLK_LPAV_BUS_DIV 8
#define IMX8ULP_CLK_PLL4_PFD0 9
#define IMX8ULP_CLK_PLL4_PFD1 10
#define IMX8ULP_CLK_PLL4_PFD2 11
#define IMX8ULP_CLK_PLL4_PFD3 12
#define IMX8ULP_CLK_PLL4_PFD0_DIV1_GATE 13
#define IMX8ULP_CLK_PLL4_PFD0_DIV2_GATE 14
#define IMX8ULP_CLK_PLL4_PFD1_DIV1_GATE 15
#define IMX8ULP_CLK_PLL4_PFD1_DIV2_GATE 16
#define IMX8ULP_CLK_PLL4_PFD2_DIV1_GATE 17
#define IMX8ULP_CLK_PLL4_PFD2_DIV2_GATE 18
#define IMX8ULP_CLK_PLL4_PFD3_DIV1_GATE 19
#define IMX8ULP_CLK_PLL4_PFD3_DIV2_GATE 20
#define IMX8ULP_CLK_PLL4_PFD0_DIV1 21
#define IMX8ULP_CLK_PLL4_PFD0_DIV2 22
#define IMX8ULP_CLK_PLL4_PFD1_DIV1 23
#define IMX8ULP_CLK_PLL4_PFD1_DIV2 24
#define IMX8ULP_CLK_PLL4_PFD2_DIV1 25
#define IMX8ULP_CLK_PLL4_PFD2_DIV2 26
#define IMX8ULP_CLK_PLL4_PFD3_DIV1 27
#define IMX8ULP_CLK_PLL4_PFD3_DIV2 28
#define IMX8ULP_CLK_CGC2_SOSC_DIV1_GATE 29
#define IMX8ULP_CLK_CGC2_SOSC_DIV2_GATE 30
#define IMX8ULP_CLK_CGC2_SOSC_DIV3_GATE 31
#define IMX8ULP_CLK_CGC2_SOSC_DIV1 32
#define IMX8ULP_CLK_CGC2_SOSC_DIV2 33
#define IMX8ULP_CLK_CGC2_SOSC_DIV3 34
#define IMX8ULP_CLK_CGC2_FROSC_DIV1_GATE 35
#define IMX8ULP_CLK_CGC2_FROSC_DIV2_GATE 36
#define IMX8ULP_CLK_CGC2_FROSC_DIV3_GATE 37
#define IMX8ULP_CLK_CGC2_FROSC_DIV1 38
#define IMX8ULP_CLK_CGC2_FROSC_DIV2 39
#define IMX8ULP_CLK_CGC2_FROSC_DIV3 40
#define IMX8ULP_CLK_AUD_CLK2 41
#define IMX8ULP_CLK_SAI6_SEL 42
#define IMX8ULP_CLK_SAI7_SEL 43
#define IMX8ULP_CLK_SPDIF_SEL 44
#define IMX8ULP_CLK_HIFI_SEL 45
#define IMX8ULP_CLK_HIFI_DIVCORE 46
#define IMX8ULP_CLK_HIFI_DIVPLAT 47
#define IMX8ULP_CLK_DSI_PHY_REF 48
#define IMX8ULP_CLK_CGC2_END 49
/* PCC3 */
#define IMX8ULP_CLK_WDOG3 0
#define IMX8ULP_CLK_WDOG4 1
#define IMX8ULP_CLK_LPIT1 2
#define IMX8ULP_CLK_TPM4 3
#define IMX8ULP_CLK_TPM5 4
#define IMX8ULP_CLK_FLEXIO1 5
#define IMX8ULP_CLK_I3C2 6
#define IMX8ULP_CLK_LPI2C4 7
#define IMX8ULP_CLK_LPI2C5 8
#define IMX8ULP_CLK_LPUART4 9
#define IMX8ULP_CLK_LPUART5 10
#define IMX8ULP_CLK_LPSPI4 11
#define IMX8ULP_CLK_LPSPI5 12
#define IMX8ULP_CLK_DMA1_MP 13
#define IMX8ULP_CLK_DMA1_CH0 14
#define IMX8ULP_CLK_DMA1_CH1 15
#define IMX8ULP_CLK_DMA1_CH2 16
#define IMX8ULP_CLK_DMA1_CH3 17
#define IMX8ULP_CLK_DMA1_CH4 18
#define IMX8ULP_CLK_DMA1_CH5 19
#define IMX8ULP_CLK_DMA1_CH6 20
#define IMX8ULP_CLK_DMA1_CH7 21
#define IMX8ULP_CLK_DMA1_CH8 22
#define IMX8ULP_CLK_DMA1_CH9 23
#define IMX8ULP_CLK_DMA1_CH10 24
#define IMX8ULP_CLK_DMA1_CH11 25
#define IMX8ULP_CLK_DMA1_CH12 26
#define IMX8ULP_CLK_DMA1_CH13 27
#define IMX8ULP_CLK_DMA1_CH14 28
#define IMX8ULP_CLK_DMA1_CH15 29
#define IMX8ULP_CLK_DMA1_CH16 30
#define IMX8ULP_CLK_DMA1_CH17 31
#define IMX8ULP_CLK_DMA1_CH18 32
#define IMX8ULP_CLK_DMA1_CH19 33
#define IMX8ULP_CLK_DMA1_CH20 34
#define IMX8ULP_CLK_DMA1_CH21 35
#define IMX8ULP_CLK_DMA1_CH22 36
#define IMX8ULP_CLK_DMA1_CH23 37
#define IMX8ULP_CLK_DMA1_CH24 38
#define IMX8ULP_CLK_DMA1_CH25 39
#define IMX8ULP_CLK_DMA1_CH26 40
#define IMX8ULP_CLK_DMA1_CH27 41
#define IMX8ULP_CLK_DMA1_CH28 42
#define IMX8ULP_CLK_DMA1_CH29 43
#define IMX8ULP_CLK_DMA1_CH30 44
#define IMX8ULP_CLK_DMA1_CH31 45
#define IMX8ULP_CLK_MU3_A 46
#define IMX8ULP_CLK_MU0_B 47
#define IMX8ULP_CLK_PCC3_END 48
/* PCC4 */
#define IMX8ULP_CLK_FLEXSPI2 0
#define IMX8ULP_CLK_TPM6 1
#define IMX8ULP_CLK_TPM7 2
#define IMX8ULP_CLK_LPI2C6 3
#define IMX8ULP_CLK_LPI2C7 4
#define IMX8ULP_CLK_LPUART6 5
#define IMX8ULP_CLK_LPUART7 6
#define IMX8ULP_CLK_SAI4 7
#define IMX8ULP_CLK_SAI5 8
#define IMX8ULP_CLK_PCTLE 9
#define IMX8ULP_CLK_PCTLF 10
#define IMX8ULP_CLK_USDHC0 11
#define IMX8ULP_CLK_USDHC1 12
#define IMX8ULP_CLK_USDHC2 13
#define IMX8ULP_CLK_USB0 14
#define IMX8ULP_CLK_USB0_PHY 15
#define IMX8ULP_CLK_USB1 16
#define IMX8ULP_CLK_USB1_PHY 17
#define IMX8ULP_CLK_USB_XBAR 18
#define IMX8ULP_CLK_ENET 19
#define IMX8ULP_CLK_SFA1 20
#define IMX8ULP_CLK_RGPIOE 21
#define IMX8ULP_CLK_RGPIOF 22
#define IMX8ULP_CLK_PCC4_END 23
/* PCC5 */
#define IMX8ULP_CLK_TPM8 0
#define IMX8ULP_CLK_SAI6 1
#define IMX8ULP_CLK_SAI7 2
#define IMX8ULP_CLK_SPDIF 3
#define IMX8ULP_CLK_ISI 4
#define IMX8ULP_CLK_CSI_REGS 5
#define IMX8ULP_CLK_PCTLD 6
#define IMX8ULP_CLK_CSI 7
#define IMX8ULP_CLK_DSI 8
#define IMX8ULP_CLK_WDOG5 9
#define IMX8ULP_CLK_EPDC 10
#define IMX8ULP_CLK_PXP 11
#define IMX8ULP_CLK_SFA2 12
#define IMX8ULP_CLK_GPU2D 13
#define IMX8ULP_CLK_GPU3D 14
#define IMX8ULP_CLK_DC_NANO 15
#define IMX8ULP_CLK_CSI_CLK_UI 16
#define IMX8ULP_CLK_CSI_CLK_ESC 17
#define IMX8ULP_CLK_RGPIOD 18
#define IMX8ULP_CLK_DMA2_MP 19
#define IMX8ULP_CLK_DMA2_CH0 20
#define IMX8ULP_CLK_DMA2_CH1 21
#define IMX8ULP_CLK_DMA2_CH2 22
#define IMX8ULP_CLK_DMA2_CH3 23
#define IMX8ULP_CLK_DMA2_CH4 24
#define IMX8ULP_CLK_DMA2_CH5 25
#define IMX8ULP_CLK_DMA2_CH6 26
#define IMX8ULP_CLK_DMA2_CH7 27
#define IMX8ULP_CLK_DMA2_CH8 28
#define IMX8ULP_CLK_DMA2_CH9 29
#define IMX8ULP_CLK_DMA2_CH10 30
#define IMX8ULP_CLK_DMA2_CH11 31
#define IMX8ULP_CLK_DMA2_CH12 32
#define IMX8ULP_CLK_DMA2_CH13 33
#define IMX8ULP_CLK_DMA2_CH14 34
#define IMX8ULP_CLK_DMA2_CH15 35
#define IMX8ULP_CLK_DMA2_CH16 36
#define IMX8ULP_CLK_DMA2_CH17 37
#define IMX8ULP_CLK_DMA2_CH18 38
#define IMX8ULP_CLK_DMA2_CH19 39
#define IMX8ULP_CLK_DMA2_CH20 40
#define IMX8ULP_CLK_DMA2_CH21 41
#define IMX8ULP_CLK_DMA2_CH22 42
#define IMX8ULP_CLK_DMA2_CH23 43
#define IMX8ULP_CLK_DMA2_CH24 44
#define IMX8ULP_CLK_DMA2_CH25 45
#define IMX8ULP_CLK_DMA2_CH26 46
#define IMX8ULP_CLK_DMA2_CH27 47
#define IMX8ULP_CLK_DMA2_CH28 48
#define IMX8ULP_CLK_DMA2_CH29 49
#define IMX8ULP_CLK_DMA2_CH30 50
#define IMX8ULP_CLK_DMA2_CH31 51
#define IMX8ULP_CLK_MU2_B 52
#define IMX8ULP_CLK_MU3_B 53
#define IMX8ULP_CLK_AVD_SIM 54
#define IMX8ULP_CLK_DSI_TX_ESC 55
#define IMX8ULP_CLK_PCC5_END 56
#endif
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright 2021 NXP
*/
#ifndef DT_BINDING_PCC_RESET_IMX8ULP_H
#define DT_BINDING_PCC_RESET_IMX8ULP_H
/* PCC3 */
#define PCC3_WDOG3_SWRST 0
#define PCC3_WDOG4_SWRST 1
#define PCC3_LPIT1_SWRST 2
#define PCC3_TPM4_SWRST 3
#define PCC3_TPM5_SWRST 4
#define PCC3_FLEXIO1_SWRST 5
#define PCC3_I3C2_SWRST 6
#define PCC3_LPI2C4_SWRST 7
#define PCC3_LPI2C5_SWRST 8
#define PCC3_LPUART4_SWRST 9
#define PCC3_LPUART5_SWRST 10
#define PCC3_LPSPI4_SWRST 11
#define PCC3_LPSPI5_SWRST 12
/* PCC4 */
#define PCC4_FLEXSPI2_SWRST 0
#define PCC4_TPM6_SWRST 1
#define PCC4_TPM7_SWRST 2
#define PCC4_LPI2C6_SWRST 3
#define PCC4_LPI2C7_SWRST 4
#define PCC4_LPUART6_SWRST 5
#define PCC4_LPUART7_SWRST 6
#define PCC4_SAI4_SWRST 7
#define PCC4_SAI5_SWRST 8
#define PCC4_USDHC0_SWRST 9
#define PCC4_USDHC1_SWRST 10
#define PCC4_USDHC2_SWRST 11
#define PCC4_USB0_SWRST 12
#define PCC4_USB0_PHY_SWRST 13
#define PCC4_USB1_SWRST 14
#define PCC4_USB1_PHY_SWRST 15
#define PCC4_ENET_SWRST 16
/* PCC5 */
#define PCC5_TPM8_SWRST 0
#define PCC5_SAI6_SWRST 1
#define PCC5_SAI7_SWRST 2
#define PCC5_SPDIF_SWRST 3
#define PCC5_ISI_SWRST 4
#define PCC5_CSI_REGS_SWRST 5
#define PCC5_CSI_SWRST 6
#define PCC5_DSI_SWRST 7
#define PCC5_WDOG5_SWRST 8
#define PCC5_EPDC_SWRST 9
#define PCC5_PXP_SWRST 10
#define PCC5_GPU2D_SWRST 11
#define PCC5_GPU3D_SWRST 12
#define PCC5_DC_NANO_SWRST 13
#endif /*DT_BINDING_RESET_IMX8ULP_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment