Merge branches 'clk-imx', 'clk-ux500' and 'clk-debugfs' into clk-next
* clk-imx: (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 ... * clk-ux500: clk: ux500: Add driver for the reset portions of PRCC dt-bindings: clock: u8500: Rewrite in YAML and extend * clk-debugfs: clk: use clk_core_get_rate_recalc() in clk_rate_get()
This commit is contained in:
commit
8d741ecd46
@ -0,0 +1,43 @@
|
||||
# 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>;
|
||||
};
|
@ -0,0 +1,50 @@
|
||||
# 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>;
|
||||
};
|
@ -0,0 +1,121 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/stericsson,u8500-clks.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ST-Ericsson DB8500 (U8500) clocks
|
||||
|
||||
maintainers:
|
||||
- Ulf Hansson <ulf.hansson@linaro.org>
|
||||
- Linus Walleij <linus.walleij@linaro.org>
|
||||
|
||||
description: While named "U8500 clocks" these clocks are inside the
|
||||
DB8500 digital baseband system-on-chip and its siblings such as
|
||||
DB8520. These bindings consider the clocks present in the SoC
|
||||
itself, not off-chip clocks. There are four different on-chip
|
||||
clocks - RTC (32 kHz), CPU clock (SMP TWD), PRCMU (power reset and
|
||||
control management unit) clocks and PRCC (peripheral reset and
|
||||
clock controller) clocks. For some reason PRCC 4 does not exist so
|
||||
the itemization can be a bit unintuitive.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- stericsson,u8500-clks
|
||||
- stericsson,u8540-clks
|
||||
- stericsson,u9540-clks
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PRCC 1 register area
|
||||
- description: PRCC 2 register area
|
||||
- description: PRCC 3 register area
|
||||
- description: PRCC 5 register area
|
||||
- description: PRCC 6 register area
|
||||
|
||||
prcmu-clock:
|
||||
description: A subnode with one clock cell for PRCMU (power, reset, control
|
||||
management unit) clocks. The cell indicates which PRCMU clock in the
|
||||
prcmu-clock node the consumer wants to use.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
prcc-periph-clock:
|
||||
description: A subnode with two clock cells for PRCC (peripheral
|
||||
reset and clock controller) peripheral clocks. The first cell indicates
|
||||
which PRCC block the consumer wants to use, possible values are 1, 2, 3,
|
||||
5, 6. The second cell indicates which clock inside the PRCC block it
|
||||
wants, possible values are 0 thru 31.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
prcc-kernel-clock:
|
||||
description: A subnode with two clock cells for PRCC (peripheral reset
|
||||
and clock controller) kernel clocks. The first cell indicates which PRCC
|
||||
block the consumer wants to use, possible values are 1, 2, 3, 5, 6. The
|
||||
second cell indicates which clock inside the PRCC block it wants, possible
|
||||
values are 0 thru 31.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
prcc-reset-controller:
|
||||
description: A subnode with two reset cells for the reset portions of the
|
||||
PRCC (peripheral reset and clock controller). The first cell indicates
|
||||
which PRCC block the consumer wants to use, possible values are 1, 2, 3
|
||||
5 and 6. The second cell indicates which reset line inside the PRCC block
|
||||
it wants to control, possible values are 0 thru 31.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#reset-cells':
|
||||
const: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
rtc32k-clock:
|
||||
description: A subnode with zero clock cells for the 32kHz RTC clock.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
smp-twd-clock:
|
||||
description: A subnode for the ARM SMP Timer Watchdog cluster with zero
|
||||
clock cells.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- prcmu-clock
|
||||
- prcc-periph-clock
|
||||
- prcc-kernel-clock
|
||||
- rtc32k-clock
|
||||
- smp-twd-clock
|
||||
|
||||
additionalProperties: false
|
@ -1,64 +0,0 @@
|
||||
Clock bindings for ST-Ericsson Ux500 clocks
|
||||
|
||||
Required properties :
|
||||
- compatible : shall contain only one of the following:
|
||||
"stericsson,u8500-clks"
|
||||
"stericsson,u8540-clks"
|
||||
"stericsson,u9540-clks"
|
||||
- reg : shall contain base register location and length for
|
||||
CLKRST1, 2, 3, 5, and 6 in an array. Note the absence of
|
||||
CLKRST4, which does not exist.
|
||||
|
||||
Required subnodes:
|
||||
- prcmu-clock: a subnode with one clock cell for PRCMU (power,
|
||||
reset, control unit) clocks. The cell indicates which PRCMU
|
||||
clock in the prcmu-clock node the consumer wants to use.
|
||||
- prcc-periph-clock: a subnode with two clock cells for
|
||||
PRCC (programmable reset- and clock controller) peripheral clocks.
|
||||
The first cell indicates which PRCC block the consumer
|
||||
wants to use, possible values are 1, 2, 3, 5, 6. The second
|
||||
cell indicates which clock inside the PRCC block it wants,
|
||||
possible values are 0 thru 31.
|
||||
- prcc-kernel-clock: a subnode with two clock cells for
|
||||
PRCC (programmable reset- and clock controller) kernel clocks
|
||||
The first cell indicates which PRCC block the consumer
|
||||
wants to use, possible values are 1, 2, 3, 5, 6. The second
|
||||
cell indicates which clock inside the PRCC block it wants,
|
||||
possible values are 0 thru 31.
|
||||
- rtc32k-clock: a subnode with zero clock cells for the 32kHz
|
||||
RTC clock.
|
||||
- smp-twd-clock: a subnode for the ARM SMP Timer Watchdog cluster
|
||||
with zero clock cells.
|
||||
|
||||
Example:
|
||||
|
||||
clocks {
|
||||
compatible = "stericsson,u8500-clks";
|
||||
/*
|
||||
* Registers for the CLKRST block on peripheral
|
||||
* groups 1, 2, 3, 5, 6,
|
||||
*/
|
||||
reg = <0x8012f000 0x1000>, <0x8011f000 0x1000>,
|
||||
<0x8000f000 0x1000>, <0xa03ff000 0x1000>,
|
||||
<0xa03cf000 0x1000>;
|
||||
|
||||
prcmu_clk: prcmu-clock {
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
prcc_pclk: prcc-periph-clock {
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
|
||||
prcc_kclk: prcc-kernel-clock {
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
|
||||
rtc_clk: rtc32k-clock {
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
smp_twd_clk: smp-twd-clock {
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
};
|
@ -29,6 +29,7 @@ menuconfig ARCH_U8500
|
||||
select REGULATOR_DB8500_PRCMU
|
||||
select REGULATOR_FIXED_VOLTAGE
|
||||
select SOC_BUS
|
||||
select RESET_CONTROLLER
|
||||
help
|
||||
Support for ST-Ericsson's Ux500 architecture
|
||||
|
||||
|
@ -3108,7 +3108,10 @@ static int clk_rate_get(void *data, u64 *val)
|
||||
{
|
||||
struct clk_core *core = data;
|
||||
|
||||
*val = core->rate;
|
||||
clk_prepare_lock();
|
||||
*val = clk_core_get_rate_recalc(core);
|
||||
clk_prepare_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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 @@ fail:
|
||||
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);
|
||||
|
569
drivers/clk/imx/clk-imx8ulp.c
Normal file
569
drivers/clk/imx/clk-imx8ulp.c
Normal file
@ -0,0 +1,569 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2021 NXP
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/imx8ulp-clock.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
static const char * const pll_pre_sels[] = { "sosc", "frosc", };
|
||||
static const char * const a35_sels[] = { "frosc", "spll2", "sosc", "lvds", };
|
||||
static const char * const nic_sels[] = { "frosc", "spll3_pfd0", "sosc", "lvds", };
|
||||
static const char * const pcc3_periph_bus_sels[] = { "dummy", "lposc", "sosc_div2",
|
||||
"frosc_div2", "xbar_divbus", "spll3_pfd1_div1",
|
||||
"spll3_pfd0_div2", "spll3_pfd0_div1", };
|
||||
static const char * const pcc4_periph_bus_sels[] = { "dummy", "dummy", "lposc",
|
||||
"sosc_div2", "frosc_div2", "xbar_divbus",
|
||||
"spll3_vcodiv", "spll3_pfd0_div1", };
|
||||
static const char * const pcc4_periph_plat_sels[] = { "dummy", "sosc_div1", "frosc_div1",
|
||||
"spll3_pfd3_div2", "spll3_pfd3_div1",
|
||||
"spll3_pfd2_div2", "spll3_pfd2_div1",
|
||||
"spll3_pfd1_div2", };
|
||||
static const char * const pcc5_periph_bus_sels[] = { "dummy", "dummy", "lposc",
|
||||
"sosc_div2", "frosc_div2", "lpav_bus_clk",
|
||||
"pll4_vcodiv", "pll4_pfd3_div1", };
|
||||
static const char * const pcc5_periph_plat_sels[] = { "dummy", "pll4_pfd3_div2", "pll4_pfd2_div2",
|
||||
"pll4_pfd2_div1", "pll4_pfd1_div2",
|
||||
"pll4_pfd1_div1", "pll4_pfd0_div2",
|
||||
"pll4_pfd0_div1", };
|
||||
static const char * const hifi_sels[] = { "frosc", "pll4", "pll4_pfd0", "sosc",
|
||||
"lvds", "dummy", "dummy", "dummy", };
|
||||
static const char * const ddr_sels[] = { "frosc", "pll4_pfd1", "sosc", "lvds",
|
||||
"pll4", "pll4", "pll4", "pll4", };
|
||||
static const char * const lpav_sels[] = { "frosc", "pll4_pfd1", "sosc", "lvds", };
|
||||
static const char * const sai45_sels[] = { "spll3_pfd1_div1", "aud_clk1", "aud_clk2", "sosc", };
|
||||
static const char * const sai67_sels[] = { "spll1_pfd2_div", "spll3_pfd1_div1", "aud_clk0", "aud_clk1", "aud_clk2", "sosc", "dummy", "dummy", };
|
||||
static const char * const aud_clk1_sels[] = { "ext_aud_mclk2", "sai4_rx_bclk", "sai4_tx_bclk", "sai5_rx_bclk", "sai5_tx_bclk", "dummy", "dummy", "dummy", };
|
||||
static const char * const aud_clk2_sels[] = { "ext_aud_mclk3", "sai6_rx_bclk", "sai6_tx_bclk", "sai7_rx_bclk", "sai7_tx_bclk", "spdif_rx", "dummy", "dummy", };
|
||||
static const char * const enet_ts_sels[] = { "ext_rmii_clk", "ext_ts_clk", "rosc", "ext_aud_mclk", "sosc", "dummy", "dummy", "dummy"};
|
||||
static const char * const xbar_divbus[] = { "xbar_divbus" };
|
||||
static const char * const nic_per_divplat[] = { "nic_per_divplat" };
|
||||
static const char * const lpav_axi_div[] = { "lpav_axi_div" };
|
||||
static const char * const lpav_bus_div[] = { "lpav_bus_div" };
|
||||
|
||||
struct pcc_reset_dev {
|
||||
void __iomem *base;
|
||||
struct reset_controller_dev rcdev;
|
||||
const u32 *resets;
|
||||
/* Set to imx_ccm_lock to protect register access shared with clock control */
|
||||
spinlock_t *lock;
|
||||
};
|
||||
|
||||
#define PCC_SW_RST BIT(28)
|
||||
#define to_pcc_reset_dev(_rcdev) container_of(_rcdev, struct pcc_reset_dev, rcdev)
|
||||
|
||||
static const u32 pcc3_resets[] = {
|
||||
0xa8, 0xac, 0xc8, 0xcc, 0xd0,
|
||||
0xd4, 0xd8, 0xdc, 0xe0, 0xe4,
|
||||
0xe8, 0xec, 0xf0
|
||||
};
|
||||
|
||||
static const u32 pcc4_resets[] = {
|
||||
0x4, 0x8, 0xc, 0x10, 0x14,
|
||||
0x18, 0x1c, 0x20, 0x24, 0x34,
|
||||
0x38, 0x3c, 0x40, 0x44, 0x48,
|
||||
0x4c, 0x54
|
||||
};
|
||||
|
||||
static const u32 pcc5_resets[] = {
|
||||
0xa0, 0xa4, 0xa8, 0xac, 0xb0,
|
||||
0xb4, 0xbc, 0xc0, 0xc8, 0xcc,
|
||||
0xd0, 0xf0, 0xf4, 0xf8
|
||||
};
|
||||
|
||||
static int imx8ulp_pcc_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct pcc_reset_dev *pcc_reset = to_pcc_reset_dev(rcdev);
|
||||
u32 offset = pcc_reset->resets[id];
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(pcc_reset->lock, flags);
|
||||
|
||||
val = readl(pcc_reset->base + offset);
|
||||
val &= ~PCC_SW_RST;
|
||||
writel(val, pcc_reset->base + offset);
|
||||
|
||||
spin_unlock_irqrestore(pcc_reset->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx8ulp_pcc_deassert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct pcc_reset_dev *pcc_reset = to_pcc_reset_dev(rcdev);
|
||||
u32 offset = pcc_reset->resets[id];
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(pcc_reset->lock, flags);
|
||||
|
||||
val = readl(pcc_reset->base + offset);
|
||||
val |= PCC_SW_RST;
|
||||
writel(val, pcc_reset->base + offset);
|
||||
|
||||
spin_unlock_irqrestore(pcc_reset->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct reset_control_ops imx8ulp_pcc_reset_ops = {
|
||||
.assert = imx8ulp_pcc_assert,
|
||||
.deassert = imx8ulp_pcc_deassert,
|
||||
};
|
||||
|
||||
static int imx8ulp_pcc_reset_init(struct platform_device *pdev, void __iomem *base,
|
||||
const u32 *resets, unsigned int nr_resets)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct pcc_reset_dev *pcc_reset;
|
||||
|
||||
pcc_reset = devm_kzalloc(dev, sizeof(*pcc_reset), GFP_KERNEL);
|
||||
if (!pcc_reset)
|
||||
return -ENOMEM;
|
||||
|
||||
pcc_reset->base = base;
|
||||
pcc_reset->lock = &imx_ccm_lock;
|
||||
pcc_reset->resets = resets;
|
||||
pcc_reset->rcdev.owner = THIS_MODULE;
|
||||
pcc_reset->rcdev.nr_resets = nr_resets;
|
||||
pcc_reset->rcdev.ops = &imx8ulp_pcc_reset_ops;
|
||||
pcc_reset->rcdev.of_node = np;
|
||||
|
||||
return devm_reset_controller_register(dev, &pcc_reset->rcdev);
|
||||
}
|
||||
|
||||
static int imx8ulp_clk_cgc1_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
void __iomem *base;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_CGC1_END),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = IMX8ULP_CLK_CGC1_END;
|
||||
clks = clk_data->hws;
|
||||
|
||||
clks[IMX8ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
|
||||
/* CGC1 */
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
return PTR_ERR(base);
|
||||
|
||||
clks[IMX8ULP_CLK_SPLL2_PRE_SEL] = imx_clk_hw_mux_flags("spll2_pre_sel", base + 0x510, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
clks[IMX8ULP_CLK_SPLL3_PRE_SEL] = imx_clk_hw_mux_flags("spll3_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
|
||||
clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll2", "spll2_pre_sel", base + 0x500);
|
||||
clks[IMX8ULP_CLK_SPLL3] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll3", "spll3_pre_sel", base + 0x600);
|
||||
clks[IMX8ULP_CLK_SPLL3_VCODIV] = imx_clk_hw_divider("spll3_vcodiv", "spll3", base + 0x604, 0, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd0", "spll3_vcodiv", base + 0x614, 0);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd1", "spll3_vcodiv", base + 0x614, 1);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd2", "spll3_vcodiv", base + 0x614, 2);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "spll3_pfd3", "spll3_vcodiv", base + 0x614, 3);
|
||||
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD0_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd0_div1_gate", "spll3_pfd0", base + 0x608, 7);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD0_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd0_div2_gate", "spll3_pfd0", base + 0x608, 15);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD1_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd1_div1_gate", "spll3_pfd1", base + 0x608, 23);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD1_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd1_div2_gate", "spll3_pfd1", base + 0x608, 31);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD2_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd2_div1_gate", "spll3_pfd2", base + 0x60c, 7);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD2_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd2_div2_gate", "spll3_pfd2", base + 0x60c, 15);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD3_DIV1_GATE] = imx_clk_hw_gate_dis("spll3_pfd3_div1_gate", "spll3_pfd3", base + 0x60c, 23);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD3_DIV2_GATE] = imx_clk_hw_gate_dis("spll3_pfd3_div2_gate", "spll3_pfd3", base + 0x60c, 31);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD0_DIV1] = imx_clk_hw_divider("spll3_pfd0_div1", "spll3_pfd0_div1_gate", base + 0x608, 0, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD0_DIV2] = imx_clk_hw_divider("spll3_pfd0_div2", "spll3_pfd0_div2_gate", base + 0x608, 8, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD1_DIV1] = imx_clk_hw_divider("spll3_pfd1_div1", "spll3_pfd1_div1_gate", base + 0x608, 16, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD1_DIV2] = imx_clk_hw_divider("spll3_pfd1_div2", "spll3_pfd1_div2_gate", base + 0x608, 24, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD2_DIV1] = imx_clk_hw_divider("spll3_pfd2_div1", "spll3_pfd2_div1_gate", base + 0x60c, 0, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD2_DIV2] = imx_clk_hw_divider("spll3_pfd2_div2", "spll3_pfd2_div2_gate", base + 0x60c, 8, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD3_DIV1] = imx_clk_hw_divider("spll3_pfd3_div1", "spll3_pfd3_div1_gate", base + 0x60c, 16, 6);
|
||||
clks[IMX8ULP_CLK_SPLL3_PFD3_DIV2] = imx_clk_hw_divider("spll3_pfd3_div2", "spll3_pfd3_div2_gate", base + 0x60c, 24, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_A35_SEL] = imx_clk_hw_mux2("a35_sel", base + 0x14, 28, 2, a35_sels, ARRAY_SIZE(a35_sels));
|
||||
clks[IMX8ULP_CLK_A35_DIV] = imx_clk_hw_divider_flags("a35_div", "a35_sel", base + 0x14, 21, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX8ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x34, 28, 2, nic_sels, ARRAY_SIZE(nic_sels));
|
||||
clks[IMX8ULP_CLK_NIC_AD_DIVPLAT] = imx_clk_hw_divider_flags("nic_ad_divplat", "nic_sel", base + 0x34, 21, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_NIC_PER_DIVPLAT] = imx_clk_hw_divider_flags("nic_per_divplat", "nic_ad_divplat", base + 0x34, 14, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_XBAR_AD_DIVPLAT] = imx_clk_hw_divider_flags("xbar_ad_divplat", "nic_ad_divplat", base + 0x38, 14, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_XBAR_DIVBUS] = imx_clk_hw_divider_flags("xbar_divbus", "nic_ad_divplat", base + 0x38, 7, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_XBAR_AD_SLOW] = imx_clk_hw_divider_flags("xbar_ad_slow", "nic_ad_divplat", base + 0x38, 0, 6, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX8ULP_CLK_SOSC_DIV1_GATE] = imx_clk_hw_gate_dis("sosc_div1_gate", "sosc", base + 0x108, 7);
|
||||
clks[IMX8ULP_CLK_SOSC_DIV2_GATE] = imx_clk_hw_gate_dis("sosc_div2_gate", "sosc", base + 0x108, 15);
|
||||
clks[IMX8ULP_CLK_SOSC_DIV3_GATE] = imx_clk_hw_gate_dis("sosc_div3_gate", "sosc", base + 0x108, 23);
|
||||
clks[IMX8ULP_CLK_SOSC_DIV1] = imx_clk_hw_divider("sosc_div1", "sosc_div1_gate", base + 0x108, 0, 6);
|
||||
clks[IMX8ULP_CLK_SOSC_DIV2] = imx_clk_hw_divider("sosc_div2", "sosc_div2_gate", base + 0x108, 8, 6);
|
||||
clks[IMX8ULP_CLK_SOSC_DIV3] = imx_clk_hw_divider("sosc_div3", "sosc_div3_gate", base + 0x108, 16, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_FROSC_DIV1_GATE] = imx_clk_hw_gate_dis("frosc_div1_gate", "frosc", base + 0x208, 7);
|
||||
clks[IMX8ULP_CLK_FROSC_DIV2_GATE] = imx_clk_hw_gate_dis("frosc_div2_gate", "frosc", base + 0x208, 15);
|
||||
clks[IMX8ULP_CLK_FROSC_DIV3_GATE] = imx_clk_hw_gate_dis("frosc_div3_gate", "frosc", base + 0x208, 23);
|
||||
clks[IMX8ULP_CLK_FROSC_DIV1] = imx_clk_hw_divider("frosc_div1", "frosc_div1_gate", base + 0x208, 0, 6);
|
||||
clks[IMX8ULP_CLK_FROSC_DIV2] = imx_clk_hw_divider("frosc_div2", "frosc_div2_gate", base + 0x208, 8, 6);
|
||||
clks[IMX8ULP_CLK_FROSC_DIV3] = imx_clk_hw_divider("frosc_div3", "frosc_div3_gate", base + 0x208, 16, 6);
|
||||
clks[IMX8ULP_CLK_AUD_CLK1] = imx_clk_hw_mux2("aud_clk1", base + 0x900, 0, 3, aud_clk1_sels, ARRAY_SIZE(aud_clk1_sels));
|
||||
clks[IMX8ULP_CLK_SAI4_SEL] = imx_clk_hw_mux2("sai4_sel", base + 0x904, 0, 2, sai45_sels, ARRAY_SIZE(sai45_sels));
|
||||
clks[IMX8ULP_CLK_SAI5_SEL] = imx_clk_hw_mux2("sai5_sel", base + 0x904, 8, 2, sai45_sels, ARRAY_SIZE(sai45_sels));
|
||||
clks[IMX8ULP_CLK_ENET_TS_SEL] = imx_clk_hw_mux2("enet_ts", base + 0x700, 24, 3, enet_ts_sels, ARRAY_SIZE(enet_ts_sels));
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
static int imx8ulp_clk_cgc2_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
void __iomem *base;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_CGC2_END),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = IMX8ULP_CLK_CGC2_END;
|
||||
clks = clk_data->hws;
|
||||
|
||||
/* CGC2 */
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
return PTR_ERR(base);
|
||||
|
||||
clks[IMX8ULP_CLK_PLL4_PRE_SEL] = imx_clk_hw_mux_flags("pll4_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
|
||||
clks[IMX8ULP_CLK_PLL4] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "pll4", "pll4_pre_sel", base + 0x600);
|
||||
clks[IMX8ULP_CLK_PLL4_VCODIV] = imx_clk_hw_divider("pll4_vcodiv", "pll4", base + 0x604, 0, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_HIFI_SEL] = imx_clk_hw_mux_flags("hifi_sel", base + 0x14, 28, 3, hifi_sels, ARRAY_SIZE(hifi_sels), CLK_SET_PARENT_GATE);
|
||||
clks[IMX8ULP_CLK_HIFI_DIVCORE] = imx_clk_hw_divider("hifi_core_div", "hifi_sel", base + 0x14, 21, 6);
|
||||
clks[IMX8ULP_CLK_HIFI_DIVPLAT] = imx_clk_hw_divider("hifi_plat_div", "hifi_core_div", base + 0x14, 14, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x40, 28, 3, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_PARENT_GATE);
|
||||
clks[IMX8ULP_CLK_DDR_DIV] = imx_clk_hw_divider_flags("ddr_div", "ddr_sel", base + 0x40, 21, 6, CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_LPAV_AXI_SEL] = imx_clk_hw_mux("lpav_sel", base + 0x3c, 28, 2, lpav_sels, ARRAY_SIZE(lpav_sels));
|
||||
clks[IMX8ULP_CLK_LPAV_AXI_DIV] = imx_clk_hw_divider_flags("lpav_axi_div", "lpav_sel", base + 0x3c, 21, 6, CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_LPAV_AHB_DIV] = imx_clk_hw_divider_flags("lpav_ahb_div", "lpav_axi_div", base + 0x3c, 14, 6, CLK_IS_CRITICAL);
|
||||
clks[IMX8ULP_CLK_LPAV_BUS_DIV] = imx_clk_hw_divider_flags("lpav_bus_div", "lpav_axi_div", base + 0x3c, 7, 6, CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX8ULP_CLK_PLL4_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd0", "pll4_vcodiv", base + 0x614, 0);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd1", "pll4_vcodiv", base + 0x614, 1);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd2", "pll4_vcodiv", base + 0x614, 2);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX8ULP, "pll4_pfd3", "pll4_vcodiv", base + 0x614, 3);
|
||||
|
||||
clks[IMX8ULP_CLK_PLL4_PFD0_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd0_div1_gate", "pll4_pfd0", base + 0x608, 7);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD0_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd0_div2_gate", "pll4_pfd0", base + 0x608, 15);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD1_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd1_div1_gate", "pll4_pfd1", base + 0x608, 23);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD1_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd1_div2_gate", "pll4_pfd1", base + 0x608, 31);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD2_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd2_div1_gate", "pll4_pfd2", base + 0x60c, 7);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD2_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd2_div2_gate", "pll4_pfd2", base + 0x60c, 15);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD3_DIV1_GATE] = imx_clk_hw_gate_dis("pll4_pfd3_div1_gate", "pll4_pfd3", base + 0x60c, 23);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD3_DIV2_GATE] = imx_clk_hw_gate_dis("pll4_pfd3_div2_gate", "pll4_pfd3", base + 0x60c, 31);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD0_DIV1] = imx_clk_hw_divider("pll4_pfd0_div1", "pll4_pfd0_div1_gate", base + 0x608, 0, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD0_DIV2] = imx_clk_hw_divider("pll4_pfd0_div2", "pll4_pfd0_div2_gate", base + 0x608, 8, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD1_DIV1] = imx_clk_hw_divider("pll4_pfd1_div1", "pll4_pfd1_div1_gate", base + 0x608, 16, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD1_DIV2] = imx_clk_hw_divider("pll4_pfd1_div2", "pll4_pfd1_div2_gate", base + 0x608, 24, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD2_DIV1] = imx_clk_hw_divider("pll4_pfd2_div1", "pll4_pfd2_div1_gate", base + 0x60c, 0, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD2_DIV2] = imx_clk_hw_divider("pll4_pfd2_div2", "pll4_pfd2_div2_gate", base + 0x60c, 8, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD3_DIV1] = imx_clk_hw_divider("pll4_pfd3_div1", "pll4_pfd3_div1_gate", base + 0x60c, 16, 6);
|
||||
clks[IMX8ULP_CLK_PLL4_PFD3_DIV2] = imx_clk_hw_divider("pll4_pfd3_div2", "pll4_pfd3_div2_gate", base + 0x60c, 24, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_CGC2_SOSC_DIV1_GATE] = imx_clk_hw_gate_dis("cgc2_sosc_div1_gate", "sosc", base + 0x108, 7);
|
||||
clks[IMX8ULP_CLK_CGC2_SOSC_DIV2_GATE] = imx_clk_hw_gate_dis("cgc2_sosc_div2_gate", "sosc", base + 0x108, 15);
|
||||
clks[IMX8ULP_CLK_CGC2_SOSC_DIV3_GATE] = imx_clk_hw_gate_dis("cgc2_sosc_div3_gate", "sosc", base + 0x108, 23);
|
||||
clks[IMX8ULP_CLK_CGC2_SOSC_DIV1] = imx_clk_hw_divider("cgc2_sosc_div1", "cgc2_sosc_div1_gate", base + 0x108, 0, 6);
|
||||
clks[IMX8ULP_CLK_CGC2_SOSC_DIV2] = imx_clk_hw_divider("cgc2_sosc_div2", "cgc2_sosc_div2_gate", base + 0x108, 8, 6);
|
||||
clks[IMX8ULP_CLK_CGC2_SOSC_DIV3] = imx_clk_hw_divider("cgc2_sosc_div3", "cgc2_sosc_div3_gate", base + 0x108, 16, 6);
|
||||
|
||||
clks[IMX8ULP_CLK_CGC2_FROSC_DIV1_GATE] = imx_clk_hw_gate_dis("cgc2_frosc_div1_gate", "frosc", base + 0x208, 7);
|
||||
clks[IMX8ULP_CLK_CGC2_FROSC_DIV2_GATE] = imx_clk_hw_gate_dis("cgc2_frosc_div2_gate", "frosc", base + 0x208, 15);
|
||||
clks[IMX8ULP_CLK_CGC2_FROSC_DIV3_GATE] = imx_clk_hw_gate_dis("cgc2_frosc_div3_gate", "frosc", base + 0x208, 23);
|
||||
clks[IMX8ULP_CLK_CGC2_FROSC_DIV1] = imx_clk_hw_divider("cgc2_frosc_div1", "cgc2_frosc_div1_gate", base + 0x208, 0, 6);
|
||||
clks[IMX8ULP_CLK_CGC2_FROSC_DIV2] = imx_clk_hw_divider("cgc2_frosc_div2", "cgc2_frosc_div2_gate", base + 0x208, 8, 6);
|
||||
clks[IMX8ULP_CLK_CGC2_FROSC_DIV3] = imx_clk_hw_divider("cgc2_frosc_div3", "cgc2_frosc_div3_gate", base + 0x208, 16, 6);
|
||||
clks[IMX8ULP_CLK_AUD_CLK2] = imx_clk_hw_mux2("aud_clk2", base + 0x900, 0, 3, aud_clk2_sels, ARRAY_SIZE(aud_clk2_sels));
|
||||
clks[IMX8ULP_CLK_SAI6_SEL] = imx_clk_hw_mux2("sai6_sel", base + 0x904, 0, 3, sai67_sels, ARRAY_SIZE(sai67_sels));
|
||||
clks[IMX8ULP_CLK_SAI7_SEL] = imx_clk_hw_mux2("sai7_sel", base + 0x904, 8, 3, sai67_sels, ARRAY_SIZE(sai67_sels));
|
||||
clks[IMX8ULP_CLK_SPDIF_SEL] = imx_clk_hw_mux2("spdif_sel", base + 0x910, 0, 3, sai67_sels, ARRAY_SIZE(sai67_sels));
|
||||
clks[IMX8ULP_CLK_DSI_PHY_REF] = imx_clk_hw_fixed("dsi_phy_ref", 24000000);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
static int imx8ulp_clk_pcc3_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_PCC3_END),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = IMX8ULP_CLK_PCC3_END;
|
||||
clks = clk_data->hws;
|
||||
|
||||
/* PCC3 */
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
return PTR_ERR(base);
|
||||
|
||||
clks[IMX8ULP_CLK_WDOG3] = imx8ulp_clk_hw_composite("wdog3", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xa8, 1);
|
||||
clks[IMX8ULP_CLK_WDOG4] = imx8ulp_clk_hw_composite("wdog4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xac, 1);
|
||||
clks[IMX8ULP_CLK_LPIT1] = imx8ulp_clk_hw_composite("lpit1", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xc8, 1);
|
||||
clks[IMX8ULP_CLK_TPM4] = imx8ulp_clk_hw_composite("tpm4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xcc, 1);
|
||||
clks[IMX8ULP_CLK_TPM5] = imx8ulp_clk_hw_composite("tpm5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xd0, 1);
|
||||
clks[IMX8ULP_CLK_FLEXIO1] = imx8ulp_clk_hw_composite("flexio1", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xd4, 1);
|
||||
clks[IMX8ULP_CLK_I3C2] = imx8ulp_clk_hw_composite("i3c2", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xd8, 1);
|
||||
clks[IMX8ULP_CLK_LPI2C4] = imx8ulp_clk_hw_composite("lpi2c4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xdc, 1);
|
||||
clks[IMX8ULP_CLK_LPI2C5] = imx8ulp_clk_hw_composite("lpi2c5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xe0, 1);
|
||||
clks[IMX8ULP_CLK_LPUART4] = imx8ulp_clk_hw_composite("lpuart4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xe4, 1);
|
||||
clks[IMX8ULP_CLK_LPUART5] = imx8ulp_clk_hw_composite("lpuart5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xe8, 1);
|
||||
clks[IMX8ULP_CLK_LPSPI4] = imx8ulp_clk_hw_composite("lpspi4", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xec, 1);
|
||||
clks[IMX8ULP_CLK_LPSPI5] = imx8ulp_clk_hw_composite("lpspi5", pcc3_periph_bus_sels, ARRAY_SIZE(pcc3_periph_bus_sels), true, true, true, base + 0xf0, 1);
|
||||
|
||||
clks[IMX8ULP_CLK_DMA1_MP] = imx_clk_hw_gate("pcc_dma1_mp", "xbar_ad_divplat", base + 0x4, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH0] = imx_clk_hw_gate("pcc_dma1_ch0", "xbar_ad_divplat", base + 0x8, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH1] = imx_clk_hw_gate("pcc_dma1_ch1", "xbar_ad_divplat", base + 0xc, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH2] = imx_clk_hw_gate("pcc_dma1_ch2", "xbar_ad_divplat", base + 0x10, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH3] = imx_clk_hw_gate("pcc_dma1_ch3", "xbar_ad_divplat", base + 0x14, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH4] = imx_clk_hw_gate("pcc_dma1_ch4", "xbar_ad_divplat", base + 0x18, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH5] = imx_clk_hw_gate("pcc_dma1_ch5", "xbar_ad_divplat", base + 0x1c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH6] = imx_clk_hw_gate("pcc_dma1_ch6", "xbar_ad_divplat", base + 0x20, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH7] = imx_clk_hw_gate("pcc_dma1_ch7", "xbar_ad_divplat", base + 0x24, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH8] = imx_clk_hw_gate("pcc_dma1_ch8", "xbar_ad_divplat", base + 0x28, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH9] = imx_clk_hw_gate("pcc_dma1_ch9", "xbar_ad_divplat", base + 0x2c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH10] = imx_clk_hw_gate("pcc_dma1_ch10", "xbar_ad_divplat", base + 0x30, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH11] = imx_clk_hw_gate("pcc_dma1_ch11", "xbar_ad_divplat", base + 0x34, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH12] = imx_clk_hw_gate("pcc_dma1_ch12", "xbar_ad_divplat", base + 0x38, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH13] = imx_clk_hw_gate("pcc_dma1_ch13", "xbar_ad_divplat", base + 0x3c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH14] = imx_clk_hw_gate("pcc_dma1_ch14", "xbar_ad_divplat", base + 0x40, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH15] = imx_clk_hw_gate("pcc_dma1_ch15", "xbar_ad_divplat", base + 0x44, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH16] = imx_clk_hw_gate("pcc_dma1_ch16", "xbar_ad_divplat", base + 0x48, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH17] = imx_clk_hw_gate("pcc_dma1_ch17", "xbar_ad_divplat", base + 0x4c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH18] = imx_clk_hw_gate("pcc_dma1_ch18", "xbar_ad_divplat", base + 0x50, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH19] = imx_clk_hw_gate("pcc_dma1_ch19", "xbar_ad_divplat", base + 0x54, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH20] = imx_clk_hw_gate("pcc_dma1_ch20", "xbar_ad_divplat", base + 0x58, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH21] = imx_clk_hw_gate("pcc_dma1_ch21", "xbar_ad_divplat", base + 0x5c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH22] = imx_clk_hw_gate("pcc_dma1_ch22", "xbar_ad_divplat", base + 0x60, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH23] = imx_clk_hw_gate("pcc_dma1_ch23", "xbar_ad_divplat", base + 0x64, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH24] = imx_clk_hw_gate("pcc_dma1_ch24", "xbar_ad_divplat", base + 0x68, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH25] = imx_clk_hw_gate("pcc_dma1_ch25", "xbar_ad_divplat", base + 0x6c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH26] = imx_clk_hw_gate("pcc_dma1_ch26", "xbar_ad_divplat", base + 0x70, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH27] = imx_clk_hw_gate("pcc_dma1_ch27", "xbar_ad_divplat", base + 0x74, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH28] = imx_clk_hw_gate("pcc_dma1_ch28", "xbar_ad_divplat", base + 0x78, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH29] = imx_clk_hw_gate("pcc_dma1_ch29", "xbar_ad_divplat", base + 0x7c, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH30] = imx_clk_hw_gate("pcc_dma1_ch30", "xbar_ad_divplat", base + 0x80, 30);
|
||||
clks[IMX8ULP_CLK_DMA1_CH31] = imx_clk_hw_gate("pcc_dma1_ch31", "xbar_ad_divplat", base + 0x84, 30);
|
||||
clks[IMX8ULP_CLK_MU0_B] = imx_clk_hw_gate("mu0_b", "xbar_ad_divplat", base + 0x88, 30);
|
||||
clks[IMX8ULP_CLK_MU3_A] = imx_clk_hw_gate("mu3_a", "xbar_ad_divplat", base + 0x8c, 30);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
imx_register_uart_clocks(1);
|
||||
|
||||
/* register the pcc3 reset controller */
|
||||
return imx8ulp_pcc_reset_init(pdev, base, pcc3_resets, ARRAY_SIZE(pcc3_resets));
|
||||
}
|
||||
|
||||
static int imx8ulp_clk_pcc4_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_PCC4_END),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = IMX8ULP_CLK_PCC4_END;
|
||||
clks = clk_data->hws;
|
||||
|
||||
/* PCC4 */
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
return PTR_ERR(base);
|
||||
|
||||
clks[IMX8ULP_CLK_FLEXSPI2] = imx8ulp_clk_hw_composite("flexspi2", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, true, true, base + 0x4, 1);
|
||||
clks[IMX8ULP_CLK_TPM6] = imx8ulp_clk_hw_composite("tpm6", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x8, 1);
|
||||
clks[IMX8ULP_CLK_TPM7] = imx8ulp_clk_hw_composite("tpm7", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0xc, 1);
|
||||
clks[IMX8ULP_CLK_LPI2C6] = imx8ulp_clk_hw_composite("lpi2c6", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x10, 1);
|
||||
clks[IMX8ULP_CLK_LPI2C7] = imx8ulp_clk_hw_composite("lpi2c7", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x14, 1);
|
||||
clks[IMX8ULP_CLK_LPUART6] = imx8ulp_clk_hw_composite("lpuart6", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x18, 1);
|
||||
clks[IMX8ULP_CLK_LPUART7] = imx8ulp_clk_hw_composite("lpuart7", pcc4_periph_bus_sels, ARRAY_SIZE(pcc4_periph_bus_sels), true, true, true, base + 0x1c, 1);
|
||||
clks[IMX8ULP_CLK_SAI4] = imx8ulp_clk_hw_composite("sai4", xbar_divbus, 1, false, false, true, base + 0x20, 1); /* sai ipg, NOT from sai sel */
|
||||
clks[IMX8ULP_CLK_SAI5] = imx8ulp_clk_hw_composite("sai5", xbar_divbus, 1, false, false, true, base + 0x24, 1); /* sai ipg */
|
||||
clks[IMX8ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "xbar_divbus", base + 0x28, 30);
|
||||
clks[IMX8ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "xbar_divbus", base + 0x2c, 30);
|
||||
clks[IMX8ULP_CLK_USDHC0] = imx8ulp_clk_hw_composite("usdhc0", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, false, true, base + 0x34, 1);
|
||||
clks[IMX8ULP_CLK_USDHC1] = imx8ulp_clk_hw_composite("usdhc1", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, false, true, base + 0x38, 1);
|
||||
clks[IMX8ULP_CLK_USDHC2] = imx8ulp_clk_hw_composite("usdhc2", pcc4_periph_plat_sels, ARRAY_SIZE(pcc4_periph_plat_sels), true, false, true, base + 0x3c, 1);
|
||||
clks[IMX8ULP_CLK_USB0] = imx8ulp_clk_hw_composite("usb0", nic_per_divplat, 1, false, false, true, base + 0x40, 1);
|
||||
clks[IMX8ULP_CLK_USB0_PHY] = imx8ulp_clk_hw_composite("usb0_phy", xbar_divbus, 1, false, false, true, base + 0x44, 1);
|
||||
clks[IMX8ULP_CLK_USB1] = imx8ulp_clk_hw_composite("usb1", nic_per_divplat, 1, false, false, true, base + 0x48, 1);
|
||||
clks[IMX8ULP_CLK_USB1_PHY] = imx8ulp_clk_hw_composite("usb1_phy", xbar_divbus, 1, false, false, true, base + 0x4c, 1);
|
||||
clks[IMX8ULP_CLK_USB_XBAR] = imx_clk_hw_gate("usb_xbar", "xbar_divbus", base + 0x50, 30);
|
||||
clks[IMX8ULP_CLK_ENET] = imx8ulp_clk_hw_composite("enet", nic_per_divplat, 1, false, false, true, base + 0x54, 1);
|
||||
clks[IMX8ULP_CLK_RGPIOE] = imx_clk_hw_gate("rgpioe", "nic_per_divplat", base + 0x78, 30);
|
||||
clks[IMX8ULP_CLK_RGPIOF] = imx_clk_hw_gate("rgpiof", "nic_per_divplat", base + 0x7c, 30);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* register the pcc4 reset controller */
|
||||
return imx8ulp_pcc_reset_init(pdev, base, pcc4_resets, ARRAY_SIZE(pcc4_resets));
|
||||
|
||||
}
|
||||
|
||||
static int imx8ulp_clk_pcc5_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, IMX8ULP_CLK_PCC5_END),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = IMX8ULP_CLK_PCC5_END;
|
||||
clks = clk_data->hws;
|
||||
|
||||
/* PCC5 */
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
return PTR_ERR(base);
|
||||
|
||||
clks[IMX8ULP_CLK_DMA2_MP] = imx_clk_hw_gate("pcc_dma2_mp", "lpav_axi_div", base + 0x0, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH0] = imx_clk_hw_gate("pcc_dma2_ch0", "lpav_axi_div", base + 0x4, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH1] = imx_clk_hw_gate("pcc_dma2_ch1", "lpav_axi_div", base + 0x8, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH2] = imx_clk_hw_gate("pcc_dma2_ch2", "lpav_axi_div", base + 0xc, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH3] = imx_clk_hw_gate("pcc_dma2_ch3", "lpav_axi_div", base + 0x10, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH4] = imx_clk_hw_gate("pcc_dma2_ch4", "lpav_axi_div", base + 0x14, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH5] = imx_clk_hw_gate("pcc_dma2_ch5", "lpav_axi_div", base + 0x18, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH6] = imx_clk_hw_gate("pcc_dma2_ch6", "lpav_axi_div", base + 0x1c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH7] = imx_clk_hw_gate("pcc_dma2_ch7", "lpav_axi_div", base + 0x20, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH8] = imx_clk_hw_gate("pcc_dma2_ch8", "lpav_axi_div", base + 0x24, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH9] = imx_clk_hw_gate("pcc_dma2_ch9", "lpav_axi_div", base + 0x28, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH10] = imx_clk_hw_gate("pcc_dma2_ch10", "lpav_axi_div", base + 0x2c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH11] = imx_clk_hw_gate("pcc_dma2_ch11", "lpav_axi_div", base + 0x30, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH12] = imx_clk_hw_gate("pcc_dma2_ch12", "lpav_axi_div", base + 0x34, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH13] = imx_clk_hw_gate("pcc_dma2_ch13", "lpav_axi_div", base + 0x38, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH14] = imx_clk_hw_gate("pcc_dma2_ch14", "lpav_axi_div", base + 0x3c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH15] = imx_clk_hw_gate("pcc_dma2_ch15", "lpav_axi_div", base + 0x40, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH16] = imx_clk_hw_gate("pcc_dma2_ch16", "lpav_axi_div", base + 0x44, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH17] = imx_clk_hw_gate("pcc_dma2_ch17", "lpav_axi_div", base + 0x48, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH18] = imx_clk_hw_gate("pcc_dma2_ch18", "lpav_axi_div", base + 0x4c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH19] = imx_clk_hw_gate("pcc_dma2_ch19", "lpav_axi_div", base + 0x50, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH20] = imx_clk_hw_gate("pcc_dma2_ch20", "lpav_axi_div", base + 0x54, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH21] = imx_clk_hw_gate("pcc_dma2_ch21", "lpav_axi_div", base + 0x58, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH22] = imx_clk_hw_gate("pcc_dma2_ch22", "lpav_axi_div", base + 0x5c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH23] = imx_clk_hw_gate("pcc_dma2_ch23", "lpav_axi_div", base + 0x60, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH24] = imx_clk_hw_gate("pcc_dma2_ch24", "lpav_axi_div", base + 0x64, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH25] = imx_clk_hw_gate("pcc_dma2_ch25", "lpav_axi_div", base + 0x68, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH26] = imx_clk_hw_gate("pcc_dma2_ch26", "lpav_axi_div", base + 0x6c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH27] = imx_clk_hw_gate("pcc_dma2_ch27", "lpav_axi_div", base + 0x70, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH28] = imx_clk_hw_gate("pcc_dma2_ch28", "lpav_axi_div", base + 0x74, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH29] = imx_clk_hw_gate("pcc_dma2_ch29", "lpav_axi_div", base + 0x78, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH30] = imx_clk_hw_gate("pcc_dma2_ch30", "lpav_axi_div", base + 0x7c, 30);
|
||||
clks[IMX8ULP_CLK_DMA2_CH31] = imx_clk_hw_gate("pcc_dma2_ch31", "lpav_axi_div", base + 0x80, 30);
|
||||
|
||||
clks[IMX8ULP_CLK_AVD_SIM] = imx_clk_hw_gate("avd_sim", "lpav_bus_div", base + 0x94, 30);
|
||||
clks[IMX8ULP_CLK_TPM8] = imx8ulp_clk_hw_composite("tpm8", pcc5_periph_bus_sels, ARRAY_SIZE(pcc5_periph_bus_sels), true, true, true, base + 0xa0, 1);
|
||||
clks[IMX8ULP_CLK_MU2_B] = imx_clk_hw_gate("mu2_b", "lpav_bus_div", base + 0x84, 30);
|
||||
clks[IMX8ULP_CLK_MU3_B] = imx_clk_hw_gate("mu3_b", "lpav_bus_div", base + 0x88, 30);
|
||||
clks[IMX8ULP_CLK_SAI6] = imx8ulp_clk_hw_composite("sai6", lpav_bus_div, 1, false, false, true, base + 0xa4, 1);
|
||||
clks[IMX8ULP_CLK_SAI7] = imx8ulp_clk_hw_composite("sai7", lpav_bus_div, 1, false, false, true, base + 0xa8, 1);
|
||||
clks[IMX8ULP_CLK_SPDIF] = imx8ulp_clk_hw_composite("spdif", lpav_bus_div, 1, false, false, true, base + 0xac, 1);
|
||||
clks[IMX8ULP_CLK_ISI] = imx8ulp_clk_hw_composite("isi", lpav_axi_div, 1, false, false, true, base + 0xb0, 1);
|
||||
clks[IMX8ULP_CLK_CSI_REGS] = imx8ulp_clk_hw_composite("csi_regs", lpav_bus_div, 1, false, false, true, base + 0xb4, 1);
|
||||
clks[IMX8ULP_CLK_CSI] = imx8ulp_clk_hw_composite("csi", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xbc, 1);
|
||||
clks[IMX8ULP_CLK_DSI] = imx8ulp_clk_hw_composite("dsi", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xc0, 1);
|
||||
clks[IMX8ULP_CLK_WDOG5] = imx8ulp_clk_hw_composite("wdog5", pcc5_periph_bus_sels, ARRAY_SIZE(pcc5_periph_bus_sels), true, true, true, base + 0xc8, 1);
|
||||
clks[IMX8ULP_CLK_EPDC] = imx8ulp_clk_hw_composite("epdc", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xcc, 1);
|
||||
clks[IMX8ULP_CLK_PXP] = imx8ulp_clk_hw_composite("pxp", lpav_axi_div, 1, false, false, true, base + 0xd0, 1);
|
||||
clks[IMX8ULP_CLK_GPU2D] = imx8ulp_clk_hw_composite("gpu2d", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xf0, 1);
|
||||
clks[IMX8ULP_CLK_GPU3D] = imx8ulp_clk_hw_composite("gpu3d", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xf4, 1);
|
||||
clks[IMX8ULP_CLK_DC_NANO] = imx8ulp_clk_hw_composite("dc_nano", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0xf8, 1);
|
||||
clks[IMX8ULP_CLK_CSI_CLK_UI] = imx8ulp_clk_hw_composite("csi_clk_ui", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0x10c, 1);
|
||||
clks[IMX8ULP_CLK_CSI_CLK_ESC] = imx8ulp_clk_hw_composite("csi_clk_esc", pcc5_periph_plat_sels, ARRAY_SIZE(pcc5_periph_plat_sels), true, true, true, base + 0x110, 1);
|
||||
clks[IMX8ULP_CLK_RGPIOD] = imx_clk_hw_gate("rgpiod", "lpav_axi_div", base + 0x114, 30);
|
||||
clks[IMX8ULP_CLK_DSI_TX_ESC] = imx_clk_hw_fixed_factor("mipi_dsi_tx_esc", "dsi", 1, 4);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* register the pcc5 reset controller */
|
||||
return imx8ulp_pcc_reset_init(pdev, base, pcc5_resets, ARRAY_SIZE(pcc5_resets));
|
||||
}
|
||||
|
||||
static int imx8ulp_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
|
||||
probe = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
if (probe)
|
||||
return probe(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id imx8ulp_clk_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx8ulp-pcc3", .data = imx8ulp_clk_pcc3_init },
|
||||
{ .compatible = "fsl,imx8ulp-pcc4", .data = imx8ulp_clk_pcc4_init },
|
||||
{ .compatible = "fsl,imx8ulp-pcc5", .data = imx8ulp_clk_pcc5_init },
|
||||
{ .compatible = "fsl,imx8ulp-cgc2", .data = imx8ulp_clk_cgc2_init },
|
||||
{ .compatible = "fsl,imx8ulp-cgc1", .data = imx8ulp_clk_cgc1_init },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx8ulp_clk_dt_ids);
|
||||
|
||||
static struct platform_driver imx8ulp_clk_driver = {
|
||||
.probe = imx8ulp_clk_probe,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.of_match_table = imx8ulp_clk_dt_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(imx8ulp_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8ULP clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -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);
|
||||
|
@ -42,6 +42,16 @@ enum imx_pll14xx_type {
|
||||
PLL_1443X,
|
||||
};
|
||||
|
||||
enum imx_pllv4_type {
|
||||
IMX_PLLV4_IMX7ULP,
|
||||
IMX_PLLV4_IMX8ULP,
|
||||
};
|
||||
|
||||
enum imx_pfdv2_type {
|
||||
IMX_PFDV2_IMX7ULP,
|
||||
IMX_PFDV2_IMX8ULP,
|
||||
};
|
||||
|
||||
/* NOTE: Rate table should be kept sorted in descending order. */
|
||||
struct imx_pll14xx_rate_table {
|
||||
unsigned int rate;
|
||||
@ -88,9 +98,6 @@ extern struct imx_pll14xx_clk imx_1443x_dram_pll;
|
||||
#define imx_clk_divider(name, parent, reg, shift, width) \
|
||||
to_clk(imx_clk_hw_divider(name, parent, reg, shift, width))
|
||||
|
||||
#define imx_clk_divider2(name, parent, reg, shift, width) \
|
||||
to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width))
|
||||
|
||||
#define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \
|
||||
to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags))
|
||||
|
||||
@ -103,40 +110,93 @@ extern struct imx_pll14xx_clk imx_1443x_dram_pll;
|
||||
#define imx_clk_gate2(name, parent, reg, shift) \
|
||||
to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_gate2_cgr(name, parent, reg, shift, cgr_val) \
|
||||
to_clk(__imx_clk_hw_gate2(name, parent, reg, shift, cgr_val, 0, NULL))
|
||||
|
||||
#define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
|
||||
to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
|
||||
|
||||
#define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
|
||||
to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count))
|
||||
|
||||
#define imx_clk_gate3(name, parent, reg, shift) \
|
||||
to_clk(imx_clk_hw_gate3(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_gate4(name, parent, reg, shift) \
|
||||
to_clk(imx_clk_hw_gate4(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
|
||||
to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
|
||||
|
||||
#define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
|
||||
to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags))
|
||||
|
||||
#define imx_clk_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \
|
||||
to_clk(imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags))
|
||||
|
||||
#define imx_clk_pllv1(type, name, parent, base) \
|
||||
to_clk(imx_clk_hw_pllv1(type, name, parent, base))
|
||||
|
||||
#define imx_clk_pllv2(name, parent, base) \
|
||||
to_clk(imx_clk_hw_pllv2(name, parent, base))
|
||||
|
||||
#define imx_clk_frac_pll(name, parent_name, base) \
|
||||
to_clk(imx_clk_hw_frac_pll(name, parent_name, base))
|
||||
#define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
|
||||
to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags))
|
||||
|
||||
#define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\
|
||||
bypass1, bypass2, base, flags) \
|
||||
to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\
|
||||
bypass1, bypass2, base, flags))
|
||||
#define imx_clk_hw_gate(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate_flags(name, parent, reg, shift, 0)
|
||||
|
||||
struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
|
||||
#define imx_clk_hw_gate2(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate2_flags(name, parent, reg, shift, 0)
|
||||
|
||||
#define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
|
||||
to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
|
||||
#define imx_clk_hw_gate_dis(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate_dis_flags(name, parent, reg, shift, 0)
|
||||
|
||||
#define imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags) \
|
||||
__imx_clk_hw_gate(name, parent, reg, shift, flags, CLK_GATE_SET_TO_DISABLE)
|
||||
|
||||
#define imx_clk_hw_gate_flags(name, parent, reg, shift, flags) \
|
||||
__imx_clk_hw_gate(name, parent, reg, shift, flags, 0)
|
||||
|
||||
#define imx_clk_hw_gate2_flags(name, parent, reg, shift, flags) \
|
||||
__imx_clk_hw_gate2(name, parent, reg, shift, 0x3, flags, NULL)
|
||||
|
||||
#define imx_clk_hw_gate2_shared(name, parent, reg, shift, shared_count) \
|
||||
__imx_clk_hw_gate2(name, parent, reg, shift, 0x3, 0, shared_count)
|
||||
|
||||
#define imx_clk_hw_gate2_shared2(name, parent, reg, shift, shared_count) \
|
||||
__imx_clk_hw_gate2(name, parent, reg, shift, 0x3, CLK_OPS_PARENT_ENABLE, shared_count)
|
||||
|
||||
#define imx_clk_hw_gate3(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate3_flags(name, parent, reg, shift, 0)
|
||||
|
||||
#define imx_clk_hw_gate3_flags(name, parent, reg, shift, flags) \
|
||||
__imx_clk_hw_gate(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE, 0)
|
||||
|
||||
#define imx_clk_hw_gate4(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate4_flags(name, parent, reg, shift, 0)
|
||||
|
||||
#define imx_clk_hw_gate4_flags(name, parent, reg, shift, flags) \
|
||||
imx_clk_hw_gate2_flags(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define imx_clk_hw_mux2(name, reg, shift, width, parents, num_parents) \
|
||||
imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, 0)
|
||||
|
||||
#define imx_clk_hw_mux(name, reg, shift, width, parents, num_parents) \
|
||||
__imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, 0, 0)
|
||||
|
||||
#define imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags) \
|
||||
__imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags, 0)
|
||||
|
||||
#define imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents) \
|
||||
__imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT, CLK_MUX_READ_ONLY)
|
||||
|
||||
#define imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \
|
||||
__imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags | CLK_OPS_PARENT_ENABLE, 0)
|
||||
|
||||
#define imx_clk_hw_divider(name, parent, reg, shift, width) \
|
||||
__imx_clk_hw_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT)
|
||||
|
||||
#define imx_clk_hw_divider2(name, parent, reg, shift, width) \
|
||||
__imx_clk_hw_divider(name, parent, reg, shift, width, \
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags) \
|
||||
__imx_clk_hw_divider(name, parent, reg, shift, width, flags)
|
||||
|
||||
#define imx_clk_hw_pll14xx(name, parent_name, base, pll_clk) \
|
||||
imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk)
|
||||
|
||||
struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
|
||||
const char *parent_name, void __iomem *base,
|
||||
@ -191,8 +251,8 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
.kdiv = (_k), \
|
||||
}
|
||||
|
||||
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_hw *clk_hw_register_gate2(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
@ -215,8 +275,8 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
|
||||
struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx);
|
||||
|
||||
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_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
@ -232,6 +292,12 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
|
||||
bool rate_present, bool gate_present,
|
||||
void __iomem *reg);
|
||||
|
||||
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);
|
||||
|
||||
struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
void (*fixup)(u32 *val));
|
||||
@ -247,27 +313,11 @@ static inline struct clk *to_clk(struct clk_hw *hw)
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base,
|
||||
const struct imx_pll14xx_clk *pll_clk)
|
||||
{
|
||||
return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
|
||||
{
|
||||
return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char * const *parents,
|
||||
int num_parents)
|
||||
{
|
||||
return clk_hw_register_mux(NULL, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg,
|
||||
shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
|
||||
const char *parent, unsigned int mult, unsigned int div)
|
||||
{
|
||||
@ -275,16 +325,7 @@ static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
|
||||
CLK_SET_RATE_PARENT, mult, div);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_divider(const char *name,
|
||||
const char *parent,
|
||||
void __iomem *reg, u8 shift,
|
||||
u8 width)
|
||||
{
|
||||
return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
|
||||
static inline struct clk_hw *__imx_clk_hw_divider(const char *name,
|
||||
const char *parent,
|
||||
void __iomem *reg, u8 shift,
|
||||
u8 width, unsigned long flags)
|
||||
@ -293,237 +334,31 @@ static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width)
|
||||
{
|
||||
return clk_hw_register_divider(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider2_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift, u8 width,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_register_divider(NULL, name, parent,
|
||||
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, unsigned long flags)
|
||||
static inline struct clk_hw *__imx_clk_hw_gate(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift,
|
||||
unsigned long flags,
|
||||
unsigned long clk_gate_flags)
|
||||
{
|
||||
return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0, &imx_ccm_lock);
|
||||
shift, clk_gate_flags, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
|
||||
shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, unsigned long flags)
|
||||
static inline struct clk_hw *__imx_clk_hw_gate2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 cgr_val,
|
||||
unsigned long flags,
|
||||
unsigned int *share_count)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
shift, cgr_val, 0x3, 0, &imx_ccm_lock, share_count);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned int *share_count)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0x3, 0, &imx_ccm_lock, share_count);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned int *share_count)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
|
||||
CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0x3, 0,
|
||||
&imx_ccm_lock, share_count);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev,
|
||||
const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift,
|
||||
unsigned int *share_count)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
|
||||
CLK_OPS_PARENT_ENABLE, reg, shift, 0x1,
|
||||
0x1, 0, &imx_ccm_lock, share_count);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate2_cgr(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, cgr_val, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_hw_register_gate(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_gate(NULL, name, parent,
|
||||
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
#define imx_clk_gate3_flags(name, parent, reg, shift, flags) \
|
||||
to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags))
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_gate2(NULL, name, parent,
|
||||
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
#define imx_clk_gate4_flags(name, parent, reg, shift, flags) \
|
||||
to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags))
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
|
||||
static inline struct clk_hw *__imx_clk_hw_mux(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char * const *parents,
|
||||
int num_parents)
|
||||
int num_parents, unsigned long flags, unsigned long clk_mux_flags)
|
||||
{
|
||||
return clk_hw_register_mux(NULL, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT, reg, shift,
|
||||
width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev,
|
||||
const char *name, void __iomem *reg, u8 shift,
|
||||
u8 width, const char * const *parents, int num_parents)
|
||||
{
|
||||
return clk_hw_register_mux(dev, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char * const *parents,
|
||||
int num_parents)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents)
|
||||
{
|
||||
return clk_hw_register_mux(NULL, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT |
|
||||
CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
const char * const *parents, int num_parents,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
|
||||
&imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents, unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_mux(NULL, name, parents, num_parents,
|
||||
flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux2_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents, unsigned long flags)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
|
||||
void __iomem *reg, u8 shift,
|
||||
u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_mux(NULL, name, parents, num_parents,
|
||||
flags | CLK_SET_RATE_NO_REPARENT,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev,
|
||||
const char *name,
|
||||
void __iomem *reg, u8 shift,
|
||||
u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_mux(dev, name, parents, num_parents,
|
||||
flags | CLK_SET_RATE_NO_REPARENT,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
flags | CLK_SET_RATE_NO_REPARENT, reg, shift,
|
||||
width, clk_mux_flags, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
|
||||
@ -534,65 +369,55 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
|
||||
#define IMX_COMPOSITE_BUS BIT(1)
|
||||
#define IMX_COMPOSITE_FW_MANAGED BIT(2)
|
||||
|
||||
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
|
||||
#define IMX_COMPOSITE_CLK_FLAGS_DEFAULT \
|
||||
(CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
|
||||
#define IMX_COMPOSITE_CLK_FLAGS_CRITICAL \
|
||||
(IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_IS_CRITICAL)
|
||||
#define IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE \
|
||||
(IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_GET_RATE_NOCACHE)
|
||||
#define IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE \
|
||||
(IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE | CLK_IS_CRITICAL)
|
||||
|
||||
struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents,
|
||||
void __iomem *reg,
|
||||
u32 composite_flags,
|
||||
unsigned long flags);
|
||||
|
||||
#define imx8m_clk_hw_composite_bus(name, parent_names, reg) \
|
||||
imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
ARRAY_SIZE(parent_names), reg, \
|
||||
IMX_COMPOSITE_BUS, \
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \
|
||||
imx8m_clk_hw_composite_flags(name, parent_names, ARRAY_SIZE(parent_names), reg, \
|
||||
IMX_COMPOSITE_BUS, \
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_IS_CRITICAL)
|
||||
|
||||
#define imx8m_clk_hw_composite_core(name, parent_names, reg) \
|
||||
imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
ARRAY_SIZE(parent_names), reg, \
|
||||
IMX_COMPOSITE_CORE, \
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \
|
||||
flags) \
|
||||
to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
num_parents, reg, 0, flags))
|
||||
|
||||
#define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \
|
||||
imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
ARRAY_SIZE(parent_names), reg, 0, \
|
||||
flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \
|
||||
imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \
|
||||
flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
|
||||
__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0)
|
||||
|
||||
#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
|
||||
__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL)
|
||||
|
||||
#define __imx8m_clk_composite(name, parent_names, reg, flags) \
|
||||
to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
|
||||
#define _imx8m_clk_hw_composite(name, parent_names, reg, composite_flags, flags) \
|
||||
__imx8m_clk_hw_composite(name, parent_names, \
|
||||
ARRAY_SIZE(parent_names), reg, composite_flags, flags)
|
||||
|
||||
#define imx8m_clk_hw_composite(name, parent_names, reg) \
|
||||
__imx8m_clk_hw_composite(name, parent_names, reg, 0)
|
||||
|
||||
#define imx8m_clk_composite(name, parent_names, reg) \
|
||||
__imx8m_clk_composite(name, parent_names, reg, 0)
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
|
||||
|
||||
#define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
|
||||
__imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL)
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
|
||||
|
||||
#define imx8m_clk_composite_critical(name, parent_names, reg) \
|
||||
__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
|
||||
#define imx8m_clk_hw_composite_bus(name, parent_names, reg) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
|
||||
|
||||
#define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
|
||||
|
||||
#define imx8m_clk_hw_composite_core(name, parent_names, reg) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
|
||||
|
||||
#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_FW_MANAGED, \
|
||||
IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE)
|
||||
|
||||
#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_FW_MANAGED, \
|
||||
IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE)
|
||||
|
||||
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
|
||||
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
|
||||
|
@ -8,6 +8,9 @@ obj-y += clk-prcc.o
|
||||
obj-y += clk-prcmu.o
|
||||
obj-y += clk-sysctrl.o
|
||||
|
||||
# Reset control
|
||||
obj-y += reset-prcc.o
|
||||
|
||||
# Clock definitions
|
||||
obj-y += u8500_of_clk.o
|
||||
|
||||
|
19
drivers/clk/ux500/prcc.h
Normal file
19
drivers/clk/ux500/prcc.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __PRCC_H
|
||||
#define __PRCC_H
|
||||
|
||||
#define PRCC_NUM_PERIPH_CLUSTERS 6
|
||||
#define PRCC_PERIPHS_PER_CLUSTER 32
|
||||
|
||||
/* CLKRST4 is missing making it hard to index things */
|
||||
enum clkrst_index {
|
||||
CLKRST1_INDEX = 0,
|
||||
CLKRST2_INDEX,
|
||||
CLKRST3_INDEX,
|
||||
CLKRST5_INDEX,
|
||||
CLKRST6_INDEX,
|
||||
CLKRST_MAX,
|
||||
};
|
||||
|
||||
#endif
|
181
drivers/clk/ux500/reset-prcc.c
Normal file
181
drivers/clk/ux500/reset-prcc.c
Normal file
@ -0,0 +1,181 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Reset controller portions for the U8500 PRCC
|
||||
* Copyright (C) 2021 Linus Walleij <linus.walleij@linaro.org>
|
||||
*/
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "prcc.h"
|
||||
#include "reset-prcc.h"
|
||||
|
||||
#define to_u8500_prcc_reset(p) container_of((p), struct u8500_prcc_reset, rcdev)
|
||||
|
||||
/* This macro flattens the 2-dimensional PRCC numberspace */
|
||||
#define PRCC_RESET_LINE(prcc_num, bit) \
|
||||
(((prcc_num) * PRCC_PERIPHS_PER_CLUSTER) + (bit))
|
||||
|
||||
/*
|
||||
* Reset registers in each PRCC - the reset lines are active low
|
||||
* so what you need to do is write a bit for the peripheral you
|
||||
* want to put into reset into the CLEAR register, this will assert
|
||||
* the reset by pulling the line low. SET take the device out of
|
||||
* reset. The status reflects the actual state of the line.
|
||||
*/
|
||||
#define PRCC_K_SOFTRST_SET 0x018
|
||||
#define PRCC_K_SOFTRST_CLEAR 0x01c
|
||||
#define PRCC_K_RST_STATUS 0x020
|
||||
|
||||
static int prcc_num_to_index(unsigned int num)
|
||||
{
|
||||
switch (num) {
|
||||
case 1:
|
||||
return CLKRST1_INDEX;
|
||||
case 2:
|
||||
return CLKRST2_INDEX;
|
||||
case 3:
|
||||
return CLKRST3_INDEX;
|
||||
case 5:
|
||||
return CLKRST5_INDEX;
|
||||
case 6:
|
||||
return CLKRST6_INDEX;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __iomem *u8500_prcc_reset_base(struct u8500_prcc_reset *ur,
|
||||
unsigned long id)
|
||||
{
|
||||
unsigned int prcc_num, index;
|
||||
|
||||
prcc_num = id / PRCC_PERIPHS_PER_CLUSTER;
|
||||
index = prcc_num_to_index(prcc_num);
|
||||
|
||||
if (index > ARRAY_SIZE(ur->base))
|
||||
return NULL;
|
||||
|
||||
return ur->base[index];
|
||||
}
|
||||
|
||||
static int u8500_prcc_reset(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev);
|
||||
void __iomem *base = u8500_prcc_reset_base(ur, id);
|
||||
unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER;
|
||||
|
||||
pr_debug("PRCC cycle reset id %lu, bit %u\n", id, bit);
|
||||
|
||||
/*
|
||||
* Assert reset and then release it. The one microsecond
|
||||
* delay is found in the vendor reference code.
|
||||
*/
|
||||
writel(BIT(bit), base + PRCC_K_SOFTRST_CLEAR);
|
||||
udelay(1);
|
||||
writel(BIT(bit), base + PRCC_K_SOFTRST_SET);
|
||||
udelay(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int u8500_prcc_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev);
|
||||
void __iomem *base = u8500_prcc_reset_base(ur, id);
|
||||
unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER;
|
||||
|
||||
pr_debug("PRCC assert reset id %lu, bit %u\n", id, bit);
|
||||
writel(BIT(bit), base + PRCC_K_SOFTRST_CLEAR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int u8500_prcc_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev);
|
||||
void __iomem *base = u8500_prcc_reset_base(ur, id);
|
||||
unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER;
|
||||
|
||||
pr_debug("PRCC deassert reset id %lu, bit %u\n", id, bit);
|
||||
writel(BIT(bit), base + PRCC_K_SOFTRST_SET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int u8500_prcc_reset_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct u8500_prcc_reset *ur = to_u8500_prcc_reset(rcdev);
|
||||
void __iomem *base = u8500_prcc_reset_base(ur, id);
|
||||
unsigned int bit = id % PRCC_PERIPHS_PER_CLUSTER;
|
||||
u32 val;
|
||||
|
||||
pr_debug("PRCC check status on reset line id %lu, bit %u\n", id, bit);
|
||||
val = readl(base + PRCC_K_RST_STATUS);
|
||||
|
||||
/* Active low so return the inverse value of the bit */
|
||||
return !(val & BIT(bit));
|
||||
}
|
||||
|
||||
static const struct reset_control_ops u8500_prcc_reset_ops = {
|
||||
.reset = u8500_prcc_reset,
|
||||
.assert = u8500_prcc_reset_assert,
|
||||
.deassert = u8500_prcc_reset_deassert,
|
||||
.status = u8500_prcc_reset_status,
|
||||
};
|
||||
|
||||
static int u8500_prcc_reset_xlate(struct reset_controller_dev *rcdev,
|
||||
const struct of_phandle_args *reset_spec)
|
||||
{
|
||||
unsigned int prcc_num, bit;
|
||||
|
||||
if (reset_spec->args_count != 2)
|
||||
return -EINVAL;
|
||||
|
||||
prcc_num = reset_spec->args[0];
|
||||
bit = reset_spec->args[1];
|
||||
|
||||
if (prcc_num != 1 && prcc_num != 2 && prcc_num != 3 &&
|
||||
prcc_num != 5 && prcc_num != 6) {
|
||||
pr_err("%s: invalid PRCC %d\n", __func__, prcc_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_debug("located reset line %d at PRCC %d bit %d\n",
|
||||
PRCC_RESET_LINE(prcc_num, bit), prcc_num, bit);
|
||||
|
||||
return PRCC_RESET_LINE(prcc_num, bit);
|
||||
}
|
||||
|
||||
void u8500_prcc_reset_init(struct device_node *np, struct u8500_prcc_reset *ur)
|
||||
{
|
||||
struct reset_controller_dev *rcdev = &ur->rcdev;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CLKRST_MAX; i++) {
|
||||
ur->base[i] = ioremap(ur->phy_base[i], SZ_4K);
|
||||
if (!ur->base[i])
|
||||
pr_err("PRCC failed to remap for reset base %d (%08x)\n",
|
||||
i, ur->phy_base[i]);
|
||||
}
|
||||
|
||||
rcdev->owner = THIS_MODULE;
|
||||
rcdev->ops = &u8500_prcc_reset_ops;
|
||||
rcdev->of_node = np;
|
||||
rcdev->of_reset_n_cells = 2;
|
||||
rcdev->of_xlate = u8500_prcc_reset_xlate;
|
||||
|
||||
ret = reset_controller_register(rcdev);
|
||||
if (ret)
|
||||
pr_err("PRCC failed to register reset controller\n");
|
||||
}
|
23
drivers/clk/ux500/reset-prcc.h
Normal file
23
drivers/clk/ux500/reset-prcc.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __RESET_PRCC_H
|
||||
#define __RESET_PRCC_H
|
||||
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/**
|
||||
* struct u8500_prcc_reset - U8500 PRCC reset controller state
|
||||
* @rcdev: reset controller device
|
||||
* @phy_base: the physical base address for each PRCC block
|
||||
* @base: the remapped PRCC bases
|
||||
*/
|
||||
struct u8500_prcc_reset {
|
||||
struct reset_controller_dev rcdev;
|
||||
u32 phy_base[CLKRST_MAX];
|
||||
void __iomem *base[CLKRST_MAX];
|
||||
};
|
||||
|
||||
void u8500_prcc_reset_init(struct device_node *np, struct u8500_prcc_reset *ur);
|
||||
|
||||
#endif
|
@ -10,10 +10,10 @@
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/dbx500-prcmu.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define PRCC_NUM_PERIPH_CLUSTERS 6
|
||||
#define PRCC_PERIPHS_PER_CLUSTER 32
|
||||
#include "clk.h"
|
||||
#include "prcc.h"
|
||||
#include "reset-prcc.h"
|
||||
|
||||
static struct clk *prcmu_clk[PRCMU_NUM_CLKS];
|
||||
static struct clk *prcc_pclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER];
|
||||
@ -46,16 +46,6 @@ static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec,
|
||||
return PRCC_SHOW(clk_data, base, bit);
|
||||
}
|
||||
|
||||
/* CLKRST4 is missing making it hard to index things */
|
||||
enum clkrst_index {
|
||||
CLKRST1_INDEX = 0,
|
||||
CLKRST2_INDEX,
|
||||
CLKRST3_INDEX,
|
||||
CLKRST5_INDEX,
|
||||
CLKRST6_INDEX,
|
||||
CLKRST_MAX,
|
||||
};
|
||||
|
||||
static void u8500_clk_init(struct device_node *np)
|
||||
{
|
||||
struct prcmu_fw_version *fw_version;
|
||||
@ -63,8 +53,18 @@ static void u8500_clk_init(struct device_node *np)
|
||||
const char *sgaclk_parent = NULL;
|
||||
struct clk *clk, *rtc_clk, *twd_clk;
|
||||
u32 bases[CLKRST_MAX];
|
||||
struct u8500_prcc_reset *rstc;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We allocate the reset controller here so that we can fill in the
|
||||
* base addresses properly and pass to the reset controller init
|
||||
* function later on.
|
||||
*/
|
||||
rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
|
||||
if (!rstc)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bases); i++) {
|
||||
struct resource r;
|
||||
|
||||
@ -73,6 +73,7 @@ static void u8500_clk_init(struct device_node *np)
|
||||
pr_err("failed to get CLKRST %d base address\n",
|
||||
i + 1);
|
||||
bases[i] = r.start;
|
||||
rstc->phy_base[i] = r.start;
|
||||
}
|
||||
|
||||
/* Clock sources */
|
||||
@ -563,6 +564,9 @@ static void u8500_clk_init(struct device_node *np)
|
||||
|
||||
if (of_node_name_eq(child, "smp-twd-clock"))
|
||||
of_clk_add_provider(child, of_clk_src_simple_get, twd_clk);
|
||||
|
||||
if (of_node_name_eq(child, "prcc-reset-controller"))
|
||||
u8500_prcc_reset_init(child, rstc);
|
||||
}
|
||||
}
|
||||
CLK_OF_DECLARE(u8500_clks, "stericsson,u8500-clks", u8500_clk_init);
|
||||
|
258
include/dt-bindings/clock/imx8ulp-clock.h
Normal file
258
include/dt-bindings/clock/imx8ulp-clock.h
Normal file
@ -0,0 +1,258 @@
|
||||
/* 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
|
59
include/dt-bindings/reset/imx8ulp-pcc-reset.h
Normal file
59
include/dt-bindings/reset/imx8ulp-pcc-reset.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* 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 */
|
51
include/dt-bindings/reset/stericsson,db8500-prcc-reset.h
Normal file
51
include/dt-bindings/reset/stericsson,db8500-prcc-reset.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _DT_BINDINGS_STE_PRCC_RESET
|
||||
#define _DT_BINDINGS_STE_PRCC_RESET
|
||||
|
||||
#define DB8500_PRCC_1 1
|
||||
#define DB8500_PRCC_2 2
|
||||
#define DB8500_PRCC_3 3
|
||||
#define DB8500_PRCC_6 6
|
||||
|
||||
/* Reset lines on PRCC 1 */
|
||||
#define DB8500_PRCC_1_RESET_UART0 0
|
||||
#define DB8500_PRCC_1_RESET_UART1 1
|
||||
#define DB8500_PRCC_1_RESET_I2C1 2
|
||||
#define DB8500_PRCC_1_RESET_MSP0 3
|
||||
#define DB8500_PRCC_1_RESET_MSP1 4
|
||||
#define DB8500_PRCC_1_RESET_SDI0 5
|
||||
#define DB8500_PRCC_1_RESET_I2C2 6
|
||||
#define DB8500_PRCC_1_RESET_SPI3 7
|
||||
#define DB8500_PRCC_1_RESET_SLIMBUS0 8
|
||||
#define DB8500_PRCC_1_RESET_I2C4 9
|
||||
#define DB8500_PRCC_1_RESET_MSP3 10
|
||||
#define DB8500_PRCC_1_RESET_PER_MSP3 11
|
||||
#define DB8500_PRCC_1_RESET_PER_MSP1 12
|
||||
#define DB8500_PRCC_1_RESET_PER_MSP0 13
|
||||
#define DB8500_PRCC_1_RESET_PER_SLIMBUS 14
|
||||
|
||||
/* Reset lines on PRCC 2 */
|
||||
#define DB8500_PRCC_2_RESET_I2C3 0
|
||||
#define DB8500_PRCC_2_RESET_PWL 1
|
||||
#define DB8500_PRCC_2_RESET_SDI4 2
|
||||
#define DB8500_PRCC_2_RESET_MSP2 3
|
||||
#define DB8500_PRCC_2_RESET_SDI1 4
|
||||
#define DB8500_PRCC_2_RESET_SDI3 5
|
||||
#define DB8500_PRCC_2_RESET_HSIRX 6
|
||||
#define DB8500_PRCC_2_RESET_HSITX 7
|
||||
#define DB8500_PRCC_1_RESET_PER_MSP2 8
|
||||
|
||||
/* Reset lines on PRCC 3 */
|
||||
#define DB8500_PRCC_3_RESET_SSP0 1
|
||||
#define DB8500_PRCC_3_RESET_SSP1 2
|
||||
#define DB8500_PRCC_3_RESET_I2C0 3
|
||||
#define DB8500_PRCC_3_RESET_SDI2 4
|
||||
#define DB8500_PRCC_3_RESET_SKE 5
|
||||
#define DB8500_PRCC_3_RESET_UART2 6
|
||||
#define DB8500_PRCC_3_RESET_SDI5 7
|
||||
|
||||
/* Reset lines on PRCC 6 */
|
||||
#define DB8500_PRCC_3_RESET_RNG 0
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user