Commit 58c05c82 authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-imx7ulp', 'clk-imx6-fixes', 'clk-imx-fixes', 'clk-imx8qxp'...

Merge branches 'clk-imx7ulp', 'clk-imx6-fixes', 'clk-imx-fixes', 'clk-imx8qxp' and 'clk-imx8mq' into clk-next

 - NXP i.MX7ULP SoC clock support
 - Support for i.MX8QXP SoC clocks
 - Support for NXP i.MX8MQ clock controllers

* clk-imx7ulp:
  clk: imx: add imx7ulp clk driver
  clk: imx: implement new clk_hw based APIs
  clk: imx: make mux parent strings const
  dt-bindings: clock: add imx7ulp clock binding doc
  clk: imx: add imx7ulp composite clk support
  clk: imx: add pfdv2 support
  clk: imx: add pllv4 support
  clk: fractional-divider: add CLK_FRAC_DIVIDER_ZERO_BASED flag support
  clk: imx: add gatable clock divider support

* clk-imx6-fixes:
  clk: imx6q: handle ENET PLL bypass
  clk: imx6q: optionally get CCM inputs via standard clock handles
  clk: imx6q: reset exclusive gates on init

* clk-imx-fixes:
  clk: imx6q: add DCICx clocks gate
  clk: imx6sl: ensure MMDC CH0 handshake is bypassed
  clk: imx7d: remove UART1 clock setting

* clk-imx8qxp:
  clk: imx: add imx8qxp lpcg driver
  clk: imx: add lpcg clock support
  clk: imx: add imx8qxp clk driver
  clk: imx: add scu clock common part
  clk: imx: add configuration option for mmio clks
  dt-bindings: clock: add imx8qxp lpcg clock binding
  dt-bindings: clock: imx8qxp: add SCU clock IDs
  firmware: imx: add pm svc headfile
  dt-bindings: fsl: scu: update power domain binding
  firmware: imx: remove resource id enums
  dt-bindings: imx: add scu resource id headfile

* clk-imx8mq:
  clk: imx: Make the i.MX8MQ CCM clock driver CLK_IMX8MQ dependant
  clk: imx: remove redundant initialization of ret to zero
  clk: imx: Add SCCG PLL type
  clk: imx: Add fractional PLL output clock
  clk: imx: Add clock driver for i.MX8MQ CCM
  clk: imx: Add imx composite clock
  dt-bindings: Add binding for i.MX8MQ CCM
...@@ -58,19 +58,11 @@ This binding for the SCU power domain providers uses the generic power ...@@ -58,19 +58,11 @@ This binding for the SCU power domain providers uses the generic power
domain binding[2]. domain binding[2].
Required properties: Required properties:
- compatible: Should be "fsl,scu-pd". - compatible: Should be "fsl,imx8qxp-scu-pd".
- #address-cells: Should be 1. - #power-domain-cells: Must be 1. Contains the Resource ID used by
- #size-cells: Should be 0. SCU commands.
Required properties for power domain sub nodes:
- #power-domain-cells: Must be 0.
Optional Properties:
- reg: Resource ID of this power domain.
No exist means uncontrollable by user.
See detailed Resource ID list from: See detailed Resource ID list from:
include/dt-bindings/power/imx-rsrc.h include/dt-bindings/firmware/imx/rsrc.h
- power-domains: phandle pointing to the parent power domain.
Clock bindings based on SCU Message Protocol Clock bindings based on SCU Message Protocol
------------------------------------------------------------ ------------------------------------------------------------
...@@ -152,22 +144,9 @@ firmware { ...@@ -152,22 +144,9 @@ firmware {
... ...
}; };
imx8qx-pm { pd: imx8qx-pd {
compatible = "fsl,scu-pd"; compatible = "fsl,imx8qxp-scu-pd";
#address-cells = <1>; #power-domain-cells = <1>;
#size-cells = <0>;
pd_dma: dma-power-domain {
#power-domain-cells = <0>;
pd_dma_lpuart0: dma-lpuart0@57 {
reg = <SC_R_UART_0>;
#power-domain-cells = <0>;
power-domains = <&pd_dma>;
};
...
};
...
}; };
}; };
}; };
...@@ -179,5 +158,5 @@ serial@5a060000 { ...@@ -179,5 +158,5 @@ serial@5a060000 {
clocks = <&clk IMX8QXP_UART0_CLK>, clocks = <&clk IMX8QXP_UART0_CLK>,
<&clk IMX8QXP_UART0_IPG_CLK>; <&clk IMX8QXP_UART0_IPG_CLK>;
clock-names = "per", "ipg"; clock-names = "per", "ipg";
power-domains = <&pd_dma_lpuart0>; power-domains = <&pd IMX_SC_R_UART_0>;
}; };
...@@ -13,6 +13,9 @@ Optional properties: ...@@ -13,6 +13,9 @@ Optional properties:
management IC (PMIC) triggered via PMIC_STBY_REQ signal. management IC (PMIC) triggered via PMIC_STBY_REQ signal.
Boards that are designed to initiate poweroff on PMIC_ON_REQ signal should Boards that are designed to initiate poweroff on PMIC_ON_REQ signal should
be using "syscon-poweroff" driver instead. be using "syscon-poweroff" driver instead.
- clocks: list of clock specifiers, must contain an entry for each entry
in clock-names
- clock-names: valid names are "osc", "ckil", "ckih1", "anaclk1" and "anaclk2"
The clock consumer should specify the desired clock by having the clock The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx6qdl-clock.h ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx6qdl-clock.h
......
* Clock bindings for Freescale i.MX7ULP
i.MX7ULP Clock functions are under joint control of the System
Clock Generation (SCG) modules, Peripheral Clock Control (PCC)
modules, and Core Mode Controller (CMC)1 blocks
The clocking scheme provides clear separation between M4 domain
and A7 domain. Except for a few clock sources shared between two
domains, such as the System Oscillator clock, the Slow IRC (SIRC),
and and the Fast IRC clock (FIRCLK), clock sources and clock
management are separated and contained within each domain.
M4 clock management consists of SCG0, PCC0, PCC1, and CMC0 modules.
A7 clock management consists of SCG1, PCC2, PCC3, and CMC1 modules.
Note: this binding doc is only for A7 clock domain.
System Clock Generation (SCG) modules:
---------------------------------------------------------------------
The System Clock Generation (SCG) is responsible for clock generation
and distribution across this device. Functions performed by the SCG
include: clock reference selection, generation of clock used to derive
processor, system, peripheral bus and external memory interface clocks,
source selection for peripheral clocks and control of power saving
clock gating mode.
Required properties:
- compatible: Should be "fsl,imx7ulp-scg1".
- reg : Should contain registers location and length.
- #clock-cells: Should be <1>.
- clocks: Should contain the fixed input clocks.
- clock-names: Should contain the following clock names:
"rosc", "sosc", "sirc", "firc", "upll", "mpll".
Peripheral Clock Control (PCC) modules:
---------------------------------------------------------------------
The Peripheral Clock Control (PCC) is responsible for clock selection,
optional division and clock gating mode for peripherals in their
respected power domain
Required properties:
- compatible: Should be one of:
"fsl,imx7ulp-pcc2",
"fsl,imx7ulp-pcc3".
- reg : Should contain registers location and length.
- #clock-cells: Should be <1>.
- clocks: Should contain the fixed input clocks.
- clock-names: Should contain the following clock names:
"nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2",
"apll_pfd1", "apll_pfd0", "upll", "sosc_bus_clk",
"mpll", "firc_bus_clk", "rosc", "spll_bus_clk";
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell.
See include/dt-bindings/clock/imx7ulp-clock.h
for the full list of i.MX7ULP clock IDs of each module.
Examples:
#include <dt-bindings/clock/imx7ulp-clock.h>
scg1: scg1@403e0000 {
compatible = "fsl,imx7ulp-scg1;
reg = <0x403e0000 0x10000>;
clocks = <&rosc>, <&sosc>, <&sirc>,
<&firc>, <&upll>, <&mpll>;
clock-names = "rosc", "sosc", "sirc",
"firc", "upll", "mpll";
#clock-cells = <1>;
};
pcc2: pcc2@403f0000 {
compatible = "fsl,imx7ulp-pcc2";
reg = <0x403f0000 0x10000>;
#clock-cells = <1>;
clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
<&scg1 IMX7ULP_CLK_NIC1_DIV>,
<&scg1 IMX7ULP_CLK_DDR_DIV>,
<&scg1 IMX7ULP_CLK_APLL_PFD2>,
<&scg1 IMX7ULP_CLK_APLL_PFD1>,
<&scg1 IMX7ULP_CLK_APLL_PFD0>,
<&scg1 IMX7ULP_CLK_UPLL>,
<&scg1 IMX7ULP_CLK_SOSC_BUS_CLK>,
<&scg1 IMX7ULP_CLK_MIPI_PLL>,
<&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>,
<&scg1 IMX7ULP_CLK_ROSC>,
<&scg1 IMX7ULP_CLK_SPLL_BUS_CLK>;
clock-names = "nic1_bus_clk", "nic1_clk", "ddr_clk",
"apll_pfd2", "apll_pfd1", "apll_pfd0",
"upll", "sosc_bus_clk", "mpll",
"firc_bus_clk", "rosc", "spll_bus_clk";
};
usdhc1: usdhc@40380000 {
compatible = "fsl,imx7ulp-usdhc";
reg = <0x40380000 0x10000>;
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
<&scg1 IMX7ULP_CLK_NIC1_DIV>,
<&pcc2 IMX7ULP_CLK_USDHC1>;
clock-names ="ipg", "ahb", "per";
bus-width = <4>;
};
* Clock bindings for NXP i.MX8M Quad
Required properties:
- compatible: Should be "fsl,imx8mq-ccm"
- reg: Address and length of the register set
- #clock-cells: Should be <1>
- clocks: list of clock specifiers, must contain an entry for each required
entry in clock-names
- clock-names: should include the following entries:
- "ckil"
- "osc_25m"
- "osc_27m"
- "clk_ext1"
- "clk_ext2"
- "clk_ext3"
- "clk_ext4"
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mq-clock.h
for the full list of i.MX8M Quad clock IDs.
* NXP i.MX8QXP LPCG (Low-Power Clock Gating) Clock bindings
The Low-Power Clock Gate (LPCG) modules contain a local programming
model to control the clock gates for the peripherals. An LPCG module
is used to locally gate the clocks for the associated peripheral.
Note:
This level of clock gating is provided after the clocks are generated
by the SCU resources and clock controls. Thus even if the clock is
enabled by these control bits, it might still not be running based
on the base resource.
Required properties:
- compatible: Should be one of:
"fsl,imx8qxp-lpcg-adma",
"fsl,imx8qxp-lpcg-conn",
"fsl,imx8qxp-lpcg-dc",
"fsl,imx8qxp-lpcg-dsp",
"fsl,imx8qxp-lpcg-gpu",
"fsl,imx8qxp-lpcg-hsio",
"fsl,imx8qxp-lpcg-img",
"fsl,imx8qxp-lpcg-lsio",
"fsl,imx8qxp-lpcg-vpu"
- reg: Address and length of the register set
- #clock-cells: Should be <1>
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell.
See the full list of clock IDs from:
include/dt-bindings/clock/imx8qxp-clock.h
Examples:
#include <dt-bindings/clock/imx8qxp-clock.h>
conn_lpcg: clock-controller@5b200000 {
compatible = "fsl,imx8qxp-lpcg-conn";
reg = <0x5b200000 0xb0000>;
#clock-cells = <1>;
};
usdhc1: mmc@5b010000 {
compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x5b010000 0x10000>;
clocks = <&conn_lpcg IMX8QXP_CONN_LPCG_SDHC0_IPG_CLK>,
<&conn_lpcg IMX8QXP_CONN_LPCG_SDHC0_PER_CLK>,
<&conn_lpcg IMX8QXP_CONN_LPCG_SDHC0_HCLK>;
clock-names = "ipg", "per", "ahb";
};
...@@ -293,7 +293,9 @@ config COMMON_CLK_BD718XX ...@@ -293,7 +293,9 @@ config COMMON_CLK_BD718XX
source "drivers/clk/actions/Kconfig" source "drivers/clk/actions/Kconfig"
source "drivers/clk/bcm/Kconfig" source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/imx/Kconfig"
source "drivers/clk/imgtec/Kconfig" source "drivers/clk/imgtec/Kconfig"
source "drivers/clk/imx/Kconfig"
source "drivers/clk/ingenic/Kconfig" source "drivers/clk/ingenic/Kconfig"
source "drivers/clk/keystone/Kconfig" source "drivers/clk/keystone/Kconfig"
source "drivers/clk/mediatek/Kconfig" source "drivers/clk/mediatek/Kconfig"
......
...@@ -72,7 +72,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ ...@@ -72,7 +72,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += davinci/
obj-$(CONFIG_H8300) += h8300/ obj-$(CONFIG_H8300) += h8300/
obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-$(CONFIG_ARCH_HISI) += hisilicon/
obj-y += imgtec/ obj-y += imgtec/
obj-$(CONFIG_ARCH_MXC) += imx/ obj-y += imx/
obj-y += ingenic/ obj-y += ingenic/
obj-$(CONFIG_ARCH_K3) += keystone/ obj-$(CONFIG_ARCH_K3) += keystone/
obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(CONFIG_ARCH_KEYSTONE) += keystone/
......
...@@ -37,6 +37,11 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, ...@@ -37,6 +37,11 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
m = (val & fd->mmask) >> fd->mshift; m = (val & fd->mmask) >> fd->mshift;
n = (val & fd->nmask) >> fd->nshift; n = (val & fd->nmask) >> fd->nshift;
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
m++;
n++;
}
if (!n || !m) if (!n || !m)
return parent_rate; return parent_rate;
...@@ -100,6 +105,11 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -100,6 +105,11 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
&m, &n); &m, &n);
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
m--;
n--;
}
if (fd->lock) if (fd->lock)
spin_lock_irqsave(fd->lock, flags); spin_lock_irqsave(fd->lock, flags);
else else
......
# SPDX-License-Identifier: GPL-2.0
# common clock support for NXP i.MX SoC family.
config MXC_CLK
bool
def_bool ARCH_MXC
config MXC_CLK_SCU
bool
depends on IMX_SCU
config CLK_IMX8MQ
bool "IMX8MQ CCM Clock Driver"
depends on ARCH_MXC && ARM64
help
Build the driver for i.MX8MQ CCM Clock Driver
config CLK_IMX8QXP
bool "IMX8QXP SCU Clock"
depends on ARCH_MXC && IMX_SCU && ARM64
select MXC_CLK_SCU
help
Build the driver for IMX8QXP SCU based clocks.
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-y += \ obj-$(CONFIG_MXC_CLK) += \
clk.o \ clk.o \
clk-busy.o \ clk-busy.o \
clk-composite-8m.o \
clk-cpu.o \ clk-cpu.o \
clk-composite-7ulp.o \
clk-divider-gate.o \
clk-fixup-div.o \ clk-fixup-div.o \
clk-fixup-mux.o \ clk-fixup-mux.o \
clk-frac-pll.o \
clk-gate-exclusive.o \ clk-gate-exclusive.o \
clk-gate2.o \ clk-gate2.o \
clk-pfd.o \
clk-pfdv2.o \
clk-pllv1.o \ clk-pllv1.o \
clk-pllv2.o \ clk-pllv2.o \
clk-pllv3.o \ clk-pllv3.o \
clk-pfd.o clk-pllv4.o \
clk-sccg-pll.o
obj-$(CONFIG_MXC_CLK_SCU) += \
clk-scu.o \
clk-lpcg-scu.o
obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
obj-$(CONFIG_SOC_IMX1) += clk-imx1.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o
obj-$(CONFIG_SOC_IMX21) += clk-imx21.o obj-$(CONFIG_SOC_IMX21) += clk-imx21.o
...@@ -26,4 +40,5 @@ obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o ...@@ -26,4 +40,5 @@ obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o
obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o
obj-$(CONFIG_SOC_VF610) += clk-vf610.o obj-$(CONFIG_SOC_VF610) += clk-vf610.o
...@@ -154,7 +154,7 @@ static const struct clk_ops clk_busy_mux_ops = { ...@@ -154,7 +154,7 @@ static const struct clk_ops clk_busy_mux_ops = {
struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
u8 width, void __iomem *busy_reg, u8 busy_shift, u8 width, void __iomem *busy_reg, u8 busy_shift,
const char **parent_names, int num_parents) const char * const *parent_names, int num_parents)
{ {
struct clk_busy_mux *busy; struct clk_busy_mux *busy;
struct clk *clk; struct clk *clk;
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017~2018 NXP
*
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/slab.h>
#include "clk.h"
#define PCG_PCS_SHIFT 24
#define PCG_PCS_MASK 0x7
#define PCG_CGC_SHIFT 30
#define PCG_FRAC_SHIFT 3
#define PCG_FRAC_WIDTH 1
#define PCG_FRAC_MASK BIT(3)
#define PCG_PCD_SHIFT 0
#define PCG_PCD_WIDTH 3
#define PCG_PCD_MASK 0x7
struct clk_hw *imx7ulp_clk_composite(const char *name,
const char * const *parent_names,
int num_parents, bool mux_present,
bool rate_present, bool gate_present,
void __iomem *reg)
{
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;
if (mux_present) {
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
return ERR_PTR(-ENOMEM);
mux_hw = &mux->hw;
mux->reg = reg;
mux->shift = PCG_PCS_SHIFT;
mux->mask = PCG_PCS_MASK;
}
if (rate_present) {
fd = kzalloc(sizeof(*fd), GFP_KERNEL);
if (!fd) {
kfree(mux);
return ERR_PTR(-ENOMEM);
}
fd_hw = &fd->hw;
fd->reg = reg;
fd->mshift = PCG_FRAC_SHIFT;
fd->mwidth = PCG_FRAC_WIDTH;
fd->mmask = PCG_FRAC_MASK;
fd->nshift = PCG_PCD_SHIFT;
fd->nwidth = PCG_PCD_WIDTH;
fd->nmask = PCG_PCD_MASK;
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
}
if (gate_present) {
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate) {
kfree(mux);
kfree(fd);
return ERR_PTR(-ENOMEM);
}
gate_hw = &gate->hw;
gate->reg = reg;
gate->bit_idx = PCG_CGC_SHIFT;
}
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);
if (IS_ERR(hw)) {
kfree(mux);
kfree(fd);
kfree(gate);
}
return hw;
}
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2018 NXP
*/
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/clk-provider.h>
#include "clk.h"
#define PCG_PREDIV_SHIFT 16
#define PCG_PREDIV_WIDTH 3
#define PCG_PREDIV_MAX 8
#define PCG_DIV_SHIFT 0
#define PCG_DIV_WIDTH 6
#define PCG_DIV_MAX 64
#define PCG_PCS_SHIFT 24
#define PCG_PCS_MASK 0x7
#define PCG_CGC_SHIFT 28
static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_divider *divider = to_clk_divider(hw);
unsigned long prediv_rate;
unsigned int prediv_value;
unsigned int div_value;
prediv_value = readl(divider->reg) >> divider->shift;
prediv_value &= clk_div_mask(divider->width);
prediv_rate = divider_recalc_rate(hw, parent_rate, prediv_value,
NULL, divider->flags,
divider->width);
div_value = readl(divider->reg) >> PCG_DIV_SHIFT;
div_value &= clk_div_mask(PCG_DIV_WIDTH);
return divider_recalc_rate(hw, prediv_rate, div_value, NULL,
divider->flags, PCG_DIV_WIDTH);
}
static int imx8m_clk_composite_compute_dividers(unsigned long rate,
unsigned long parent_rate,
int *prediv, int *postdiv)
{
int div1, div2;
int error = INT_MAX;
int ret = -EINVAL;
*prediv = 1;
*postdiv = 1;
for (div1 = 1; div1 <= PCG_PREDIV_MAX; div1++) {
for (div2 = 1; div2 <= PCG_DIV_MAX; div2++) {
int new_error = ((parent_rate / div1) / div2) - rate;
if (abs(new_error) < abs(error)) {
*prediv = div1;
*postdiv = div2;
error = new_error;
ret = 0;
}
}
}
return ret;
}
static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long *prate)
{
int prediv_value;
int div_value;
imx8m_clk_composite_compute_dividers(rate, *prate,
&prediv_value, &div_value);
rate = DIV_ROUND_UP(*prate, prediv_value);
return DIV_ROUND_UP(rate, div_value);
}
static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
{
struct clk_divider *divider = to_clk_divider(hw);
unsigned long flags = 0;
int prediv_value;
int div_value;
int ret;
u32 val;
ret = imx8m_clk_composite_compute_dividers(rate, parent_rate,
&prediv_value, &div_value);
if (ret)
return -EINVAL;
spin_lock_irqsave(divider->lock, flags);
val = readl(divider->reg);
val &= ~((clk_div_mask(divider->width) << divider->shift) |
(clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
val |= (u32)(prediv_value - 1) << divider->shift;
val |= (u32)(div_value - 1) << PCG_DIV_SHIFT;
writel(val, divider->reg);
spin_unlock_irqrestore(divider->lock, flags);
return ret;
}
static const struct clk_ops imx8m_clk_composite_divider_ops = {
.recalc_rate = imx8m_clk_composite_divider_recalc_rate,
.round_rate = imx8m_clk_composite_divider_round_rate,
.set_rate = imx8m_clk_composite_divider_set_rate,
};
struct clk *imx8m_clk_composite_flags(const char *name,
const char **parent_names,
int num_parents, void __iomem *reg,
unsigned long flags)
{
struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
struct clk_hw *div_hw, *gate_hw;
struct clk_divider *div = NULL;
struct clk_gate *gate = NULL;
struct clk_mux *mux = NULL;
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
goto fail;
mux_hw = &mux->hw;
mux->reg = reg;
mux->shift = PCG_PCS_SHIFT;
mux->mask = PCG_PCS_MASK;
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
goto fail;
div_hw = &div->hw;
div->reg = reg;
div->shift = PCG_PREDIV_SHIFT;
div->width = PCG_PREDIV_WIDTH;
div->lock = &imx_ccm_lock;
div->flags = CLK_DIVIDER_ROUND_CLOSEST;
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate)
goto fail;
gate_hw = &gate->hw;
gate->reg = reg;
gate->bit_idx = PCG_CGC_SHIFT;
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, &clk_mux_ops, div_hw,
&imx8m_clk_composite_divider_ops,
gate_hw, &clk_gate_ops, flags);
if (IS_ERR(hw))
goto fail;
return hw->clk;
fail:
kfree(gate);
kfree(div);
kfree(mux);
return ERR_CAST(hw);
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP.
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/slab.h>
#include "clk.h"
struct clk_divider_gate {
struct clk_divider divider;
u32 cached_val;
};
static inline struct clk_divider_gate *to_clk_divider_gate(struct clk_hw *hw)
{
struct clk_divider *div = to_clk_divider(hw);
return container_of(div, struct clk_divider_gate, divider);
}
static unsigned long clk_divider_gate_recalc_rate_ro(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_divider *div = to_clk_divider(hw);
unsigned int val;
val = clk_readl(div->reg) >> div->shift;
val &= clk_div_mask(div->width);
if (!val)
return 0;
return divider_recalc_rate(hw, parent_rate, val, div->table,
div->flags, div->width);
}
static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
struct clk_divider *div = to_clk_divider(hw);
unsigned long flags = 0;
unsigned int val;
spin_lock_irqsave(div->lock, flags);
if (!clk_hw_is_enabled(hw)) {
val = div_gate->cached_val;
} else {
val = clk_readl(div->reg) >> div->shift;
val &= clk_div_mask(div->width);
}
spin_unlock_irqrestore(div->lock, flags);
if (!val)
return 0;
return divider_recalc_rate(hw, parent_rate, val, div->table,
div->flags, div->width);
}
static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
return clk_divider_ops.round_rate(hw, rate, prate);
}
static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
struct clk_divider *div = to_clk_divider(hw);
unsigned long flags = 0;
int value;
u32 val;
value = divider_get_val(rate, parent_rate, div->table,
div->width, div->flags);
if (value < 0)
return value;
spin_lock_irqsave(div->lock, flags);
if (clk_hw_is_enabled(hw)) {
val = clk_readl(div->reg);
val &= ~(clk_div_mask(div->width) << div->shift);
val |= (u32)value << div->shift;
clk_writel(val, div->reg);
} else {
div_gate->cached_val = value;
}
spin_unlock_irqrestore(div->lock, flags);
return 0;
}
static int clk_divider_enable(struct clk_hw *hw)
{
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
struct clk_divider *div = to_clk_divider(hw);
unsigned long flags = 0;
u32 val;
if (!div_gate->cached_val) {
pr_err("%s: no valid preset rate\n", clk_hw_get_name(hw));
return -EINVAL;
}
spin_lock_irqsave(div->lock, flags);
/* restore div val */
val = clk_readl(div->reg);
val |= div_gate->cached_val << div->shift;
clk_writel(val, div->reg);
spin_unlock_irqrestore(div->lock, flags);
return 0;
}
static void clk_divider_disable(struct clk_hw *hw)
{
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
struct clk_divider *div = to_clk_divider(hw);
unsigned long flags = 0;
u32 val;
spin_lock_irqsave(div->lock, flags);
/* store the current div val */
val = clk_readl(div->reg) >> div->shift;
val &= clk_div_mask(div->width);
div_gate->cached_val = val;
clk_writel(0, div->reg);
spin_unlock_irqrestore(div->lock, flags);
}
static int clk_divider_is_enabled(struct clk_hw *hw)
{
struct clk_divider *div = to_clk_divider(hw);
u32 val;
val = clk_readl(div->reg) >> div->shift;
val &= clk_div_mask(div->width);
return val ? 1 : 0;
}
static const struct clk_ops clk_divider_gate_ro_ops = {
.recalc_rate = clk_divider_gate_recalc_rate_ro,
.round_rate = clk_divider_round_rate,
};
static const struct clk_ops clk_divider_gate_ops = {
.recalc_rate = clk_divider_gate_recalc_rate,
.round_rate = clk_divider_round_rate,
.set_rate = clk_divider_gate_set_rate,
.enable = clk_divider_enable,
.disable = clk_divider_disable,
.is_enabled = clk_divider_is_enabled,
};
/*
* NOTE: In order to resue the most code from the common divider,
* we also design our divider following the way that provids an extra
* clk_divider_flags, however it's fixed to CLK_DIVIDER_ONE_BASED by
* default as our HW is. Besides that it supports only CLK_DIVIDER_READ_ONLY
* flag which can be specified by user flexibly.
*/
struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg,
u8 shift, u8 width, u8 clk_divider_flags,
const struct clk_div_table *table,
spinlock_t *lock)
{
struct clk_init_data init;
struct clk_divider_gate *div_gate;
struct clk_hw *hw;
u32 val;
int ret;
div_gate = kzalloc(sizeof(*div_gate), GFP_KERNEL);
if (!div_gate)
return ERR_PTR(-ENOMEM);
init.name = name;
if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
init.ops = &clk_divider_gate_ro_ops;
else
init.ops = &clk_divider_gate_ops;
init.flags = flags;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
div_gate->divider.reg = reg;
div_gate->divider.shift = shift;
div_gate->divider.width = width;
div_gate->divider.lock = lock;
div_gate->divider.table = table;
div_gate->divider.hw.init = &init;
div_gate->divider.flags = CLK_DIVIDER_ONE_BASED | clk_divider_flags;
/* cache gate status */
val = clk_readl(reg) >> shift;
val &= clk_div_mask(width);
div_gate->cached_val = val;
hw = &div_gate->divider.hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(div_gate);
hw = ERR_PTR(ret);
}
return hw;
}
...@@ -70,7 +70,7 @@ static const struct clk_ops clk_fixup_mux_ops = { ...@@ -70,7 +70,7 @@ static const struct clk_ops clk_fixup_mux_ops = {
}; };
struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, u8 shift, u8 width, const char * const *parents,
int num_parents, void (*fixup)(u32 *val)) int num_parents, void (*fixup)(u32 *val))
{ {
struct clk_fixup_mux *fixup_mux; struct clk_fixup_mux *fixup_mux;
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2018 NXP.
*
* This driver supports the fractional plls found in the imx8m SOCs
*
* Documentation for this fractional pll can be found at:
* https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf#page=834
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include <linux/bitfield.h>
#include "clk.h"
#define PLL_CFG0 0x0
#define PLL_CFG1 0x4
#define PLL_LOCK_STATUS BIT(31)
#define PLL_PD_MASK BIT(19)
#define PLL_BYPASS_MASK BIT(14)
#define PLL_NEWDIV_VAL BIT(12)
#define PLL_NEWDIV_ACK BIT(11)
#define PLL_FRAC_DIV_MASK GENMASK(30, 7)
#define PLL_INT_DIV_MASK GENMASK(6, 0)
#define PLL_OUTPUT_DIV_MASK GENMASK(4, 0)
#define PLL_FRAC_DENOM 0x1000000
#define PLL_FRAC_LOCK_TIMEOUT 10000
#define PLL_FRAC_ACK_TIMEOUT 500000
struct clk_frac_pll {
struct clk_hw hw;
void __iomem *base;
};
#define to_clk_frac_pll(_hw) container_of(_hw, struct clk_frac_pll, hw)
static int clk_wait_lock(struct clk_frac_pll *pll)
{
u32 val;
return readl_poll_timeout(pll->base, val, val & PLL_LOCK_STATUS, 0,
PLL_FRAC_LOCK_TIMEOUT);
}
static int clk_wait_ack(struct clk_frac_pll *pll)
{
u32 val;
/* return directly if the pll is in powerdown or in bypass */
if (readl_relaxed(pll->base) & (PLL_PD_MASK | PLL_BYPASS_MASK))
return 0;
/* Wait for the pll's divfi and divff to be reloaded */
return readl_poll_timeout(pll->base, val, val & PLL_NEWDIV_ACK, 0,
PLL_FRAC_ACK_TIMEOUT);
}
static int clk_pll_prepare(struct clk_hw *hw)
{
struct clk_frac_pll *pll = to_clk_frac_pll(hw);
u32 val;
val = readl_relaxed(pll->base + PLL_CFG0);
val &= ~PLL_PD_MASK;
writel_relaxed(val, pll->base + PLL_CFG0);
return clk_wait_lock(pll);
}
static void clk_pll_unprepare(struct clk_hw *hw)
{
struct clk_frac_pll *pll = to_clk_frac_pll(hw);
u32 val;
val = readl_relaxed(pll->base + PLL_CFG0);
val |= PLL_PD_MASK;
writel_relaxed(val, pll->base + PLL_CFG0);
}
static int clk_pll_is_prepared(struct clk_hw *hw)
{
struct clk_frac_pll *pll = to_clk_frac_pll(hw);
u32 val;
val = readl_relaxed(pll->base + PLL_CFG0);
return (val & PLL_PD_MASK) ? 0 : 1;
}
static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_frac_pll *pll = to_clk_frac_pll(hw);
u32 val, divff, divfi, divq;
u64 temp64 = parent_rate;
u64 rate;
val = readl_relaxed(pll->base + PLL_CFG0);
divq = (FIELD_GET(PLL_OUTPUT_DIV_MASK, val) + 1) * 2;
val = readl_relaxed(pll->base + PLL_CFG1);
divff = FIELD_GET(PLL_FRAC_DIV_MASK, val);
divfi = FIELD_GET(PLL_INT_DIV_MASK, val);
temp64 *= 8;
temp64 *= divff;
do_div(temp64, PLL_FRAC_DENOM);
do_div(temp64, divq);
rate = parent_rate * 8 * (divfi + 1);
do_div(rate, divq);
rate += temp64;
return rate;
}
static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
u64 parent_rate = *prate;
u32 divff, divfi;
u64 temp64;
parent_rate *= 8;
rate *= 2;
temp64 = rate;
do_div(temp64, parent_rate);
divfi = temp64;
temp64 = rate - divfi * parent_rate;
temp64 *= PLL_FRAC_DENOM;
do_div(temp64, parent_rate);
divff = temp64;
temp64 = parent_rate;
temp64 *= divff;
do_div(temp64, PLL_FRAC_DENOM);
rate = parent_rate * divfi + temp64;
return rate / 2;
}
/*
* To simplify the clock calculation, we can keep the 'PLL_OUTPUT_VAL' at zero
* (means the PLL output will be divided by 2). So the PLL output can use
* the below formula:
* pllout = parent_rate * 8 / 2 * DIVF_VAL;
* where DIVF_VAL = 1 + DIVFI + DIVFF / 2^24.
*/
static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_frac_pll *pll = to_clk_frac_pll(hw);
u32 val, divfi, divff;
u64 temp64 = parent_rate;
int ret;
parent_rate *= 8;
rate *= 2;
divfi = rate / parent_rate;
temp64 *= rate - divfi;
temp64 *= PLL_FRAC_DENOM;
do_div(temp64, parent_rate);
divff = temp64;
val = readl_relaxed(pll->base + PLL_CFG1);
val &= ~(PLL_FRAC_DIV_MASK | PLL_INT_DIV_MASK);
val |= (divff << 7) | (divfi - 1);
writel_relaxed(val, pll->base + PLL_CFG1);
val = readl_relaxed(pll->base + PLL_CFG0);
val &= ~0x1f;
writel_relaxed(val, pll->base + PLL_CFG0);
/* Set the NEV_DIV_VAL to reload the DIVFI and DIVFF */
val = readl_relaxed(pll->base + PLL_CFG0);
val |= PLL_NEWDIV_VAL;
writel_relaxed(val, pll->base + PLL_CFG0);
ret = clk_wait_ack(pll);
/* clear the NEV_DIV_VAL */
val = readl_relaxed(pll->base + PLL_CFG0);
val &= ~PLL_NEWDIV_VAL;
writel_relaxed(val, pll->base + PLL_CFG0);
return ret;
}
static const struct clk_ops clk_frac_pll_ops = {
.prepare = clk_pll_prepare,
.unprepare = clk_pll_unprepare,
.is_prepared = clk_pll_is_prepared,
.recalc_rate = clk_pll_recalc_rate,
.round_rate = clk_pll_round_rate,
.set_rate = clk_pll_set_rate,
};
struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
void __iomem *base)
{
struct clk_init_data init;
struct clk_frac_pll *pll;
struct clk_hw *hw;
int ret;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &clk_frac_pll_ops;
init.flags = 0;
init.parent_names = &parent_name;
init.num_parents = 1;
pll->base = base;
pll->hw.init = &init;
hw = &pll->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(pll);
return ERR_PTR(ret);
}
return hw->clk;
}
...@@ -225,6 +225,41 @@ static void of_assigned_ldb_sels(struct device_node *node, ...@@ -225,6 +225,41 @@ static void of_assigned_ldb_sels(struct device_node *node,
} }
} }
static bool pll6_bypassed(struct device_node *node)
{
int index, ret, num_clocks;
struct of_phandle_args clkspec;
num_clocks = of_count_phandle_with_args(node, "assigned-clocks",
"#clock-cells");
if (num_clocks < 0)
return false;
for (index = 0; index < num_clocks; index++) {
ret = of_parse_phandle_with_args(node, "assigned-clocks",
"#clock-cells", index,
&clkspec);
if (ret < 0)
return false;
if (clkspec.np == node &&
clkspec.args[0] == IMX6QDL_PLL6_BYPASS)
break;
}
/* PLL6 bypass is not part of the assigned clock list */
if (index == num_clocks)
return false;
ret = of_parse_phandle_with_args(node, "assigned-clock-parents",
"#clock-cells", index, &clkspec);
if (clkspec.args[0] != IMX6QDL_CLK_PLL6)
return true;
return false;
}
#define CCM_CCDR 0x04 #define CCM_CCDR 0x04
#define CCM_CCSR 0x0c #define CCM_CCSR 0x0c
#define CCM_CS2CDR 0x2c #define CCM_CS2CDR 0x2c
...@@ -414,12 +449,24 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) ...@@ -414,12 +449,24 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
int ret; int ret;
clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); clk[IMX6QDL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0); if (IS_ERR(clk[IMX6QDL_CLK_CKIL]))
clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
clk[IMX6QDL_CLK_CKIH] = of_clk_get_by_name(ccm_node, "ckih1");
if (IS_ERR(clk[IMX6QDL_CLK_CKIH]))
clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
clk[IMX6QDL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc");
if (IS_ERR(clk[IMX6QDL_CLK_OSC]))
clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
/* Clock source from external clock via CLK1/2 PADs */ /* Clock source from external clock via CLK1/2 PADs */
clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); clk[IMX6QDL_CLK_ANACLK1] = of_clk_get_by_name(ccm_node, "anaclk1");
clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0); if (IS_ERR(clk[IMX6QDL_CLK_ANACLK1]))
clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
clk[IMX6QDL_CLK_ANACLK2] = of_clk_get_by_name(ccm_node, "anaclk2");
if (IS_ERR(clk[IMX6QDL_CLK_ANACLK2]))
clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
anatop_base = base = of_iomap(np, 0); anatop_base = base = of_iomap(np, 0);
...@@ -491,16 +538,32 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) ...@@ -491,16 +538,32 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); clk[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
clk[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); clk[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); /*
clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); * The ENET PLL is special in that is has multiple outputs with
* different post-dividers that are all affected by the single bypass
* bit, so a single mux bit affects 3 independent branches of the clock
* tree. There is no good way to model this in the clock framework and
* dynamically changing the bypass bit, will yield unexpected results.
* So we treat any configuration that bypasses the ENET PLL as
* essentially static with the divider ratios reflecting the bypass
* status.
*
*/
if (!pll6_bypassed(ccm_node)) {
clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
clk[IMX6QDL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
base + 0xe0, 0, 2, 0, clk_enet_ref_table,
&imx_ccm_lock);
} else {
clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 1);
clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 1);
clk[IMX6QDL_CLK_ENET_REF] = imx_clk_fixed_factor("enet_ref", "pll6_enet", 1, 1);
}
clk[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); clk[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
clk[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); clk[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
clk[IMX6QDL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
base + 0xe0, 0, 2, 0, clk_enet_ref_table,
&imx_ccm_lock);
clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
...@@ -508,8 +571,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) ...@@ -508,8 +571,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
* lvds1_gate and lvds2_gate are pseudo-gates. Both can be * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
* independently configured as clock inputs or outputs. We treat * independently configured as clock inputs or outputs. We treat
* the "output_enable" bit as a gate, even though it's really just * the "output_enable" bit as a gate, even though it's really just
* enabling clock output. * enabling clock output. Initially the gate bits are cleared, as
* otherwise the exclusive configuration gets locked in the setup done
* by software running before the clock driver, with no way to change
* it.
*/ */
writel(readl(base + 0x160) & ~0x3c00, base + 0x160);
clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12)); clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12));
clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13)); clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13));
...@@ -737,6 +804,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) ...@@ -737,6 +804,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16); clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20); clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
clk[IMX6QDL_CLK_DCIC1] = imx_clk_gate2("dcic1", "ipu1_podf", base + 0x68, 24);
clk[IMX6QDL_CLK_DCIC2] = imx_clk_gate2("dcic2", "ipu2_podf", base + 0x68, 26);
clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "clk.h" #include "clk.h"
#define CCDR 0x4
#define BM_CCM_CCDR_MMDC_CH0_MASK (1 << 17)
#define CCSR 0xc #define CCSR 0xc
#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2) #define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
#define CACRR 0x10 #define CACRR 0x10
...@@ -411,6 +413,10 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) ...@@ -411,6 +413,10 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
/* Ensure the MMDC CH0 handshake is bypassed */
writel_relaxed(readl_relaxed(base + CCDR) |
BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
imx_check_clocks(clks, ARRAY_SIZE(clks)); imx_check_clocks(clks, ARRAY_SIZE(clks));
clk_data.clks = clks; clk_data.clks = clks;
......
...@@ -886,9 +886,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) ...@@ -886,9 +886,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
/* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
/* set uart module clock's parent clock source that must be great then 80MHz */
clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
/* Set clock rate for USBPHY, the USB_PLL at CCM is from USBOTG2 */ /* Set clock rate for USBPHY, the USB_PLL at CCM is from USBOTG2 */
clks[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb1_main_clk", "osc", 20, 1); clks[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb1_main_clk", "osc", 20, 1);
clks[IMX7D_USB_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb_main_clk", "osc", 20, 1); clks[IMX7D_USB_MAIN_480M_CLK] = imx_clk_fixed_factor("pll_usb_main_clk", "osc", 20, 1);
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017~2018 NXP
*
* Author: Dong Aisheng <aisheng.dong@nxp.com>
*
*/
#include <dt-bindings/clock/imx7ulp-clock.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "clk.h"
static const char * const pll_pre_sels[] = { "sosc", "firc", };
static const char * const spll_pfd_sels[] = { "spll_pfd0", "spll_pfd1", "spll_pfd2", "spll_pfd3", };
static const char * const spll_sels[] = { "spll", "spll_pfd_sel", };
static const char * const apll_pfd_sels[] = { "apll_pfd0", "apll_pfd1", "apll_pfd2", "apll_pfd3", };
static const char * const apll_sels[] = { "apll", "apll_pfd_sel", };
static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "upll", };
static const char * const ddr_sels[] = { "apll_pfd_sel", "upll", };
static const char * const nic_sels[] = { "firc", "ddr_clk", };
static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", };
static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "mpll", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", };
/* used by sosc/sirc/firc/ddr/spll/apll dividers */
static const struct clk_div_table ulp_div_table[] = {
{ .val = 1, .div = 1, },
{ .val = 2, .div = 2, },
{ .val = 3, .div = 4, },
{ .val = 4, .div = 8, },
{ .val = 5, .div = 16, },
{ .val = 6, .div = 32, },
{ .val = 7, .div = 64, },
};
static void __init imx7ulp_clk_scg1_init(struct device_node *np)
{
struct clk_hw_onecell_data *clk_data;
struct clk_hw **clks;
void __iomem *base;
clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
IMX7ULP_CLK_SCG1_END, GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = IMX7ULP_CLK_SCG1_END;
clks = clk_data->hws;
clks[IMX7ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
clks[IMX7ULP_CLK_ROSC] = imx_obtain_fixed_clk_hw(np, "rosc");
clks[IMX7ULP_CLK_SOSC] = imx_obtain_fixed_clk_hw(np, "sosc");
clks[IMX7ULP_CLK_SIRC] = imx_obtain_fixed_clk_hw(np, "sirc");
clks[IMX7ULP_CLK_FIRC] = imx_obtain_fixed_clk_hw(np, "firc");
clks[IMX7ULP_CLK_MIPI_PLL] = imx_obtain_fixed_clk_hw(np, "mpll");
clks[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll");
/* SCG1 */
base = of_iomap(np, 0);
WARN_ON(!base);
/* NOTE: xPLL config can't be changed when xPLL is enabled */
clks[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
clks[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
/* name parent_name reg shift width flags */
clks[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508, 8, 3, CLK_SET_RATE_GATE);
clks[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 */
clks[IMX7ULP_CLK_APLL] = imx_clk_pllv4("apll", "apll_pre_div", base + 0x500);
clks[IMX7ULP_CLK_SPLL] = imx_clk_pllv4("spll", "spll_pre_div", base + 0x600);
/* APLL PFDs */
clks[IMX7ULP_CLK_APLL_PFD0] = imx_clk_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
clks[IMX7ULP_CLK_APLL_PFD1] = imx_clk_pfdv2("apll_pfd1", "apll", base + 0x50c, 1);
clks[IMX7ULP_CLK_APLL_PFD2] = imx_clk_pfdv2("apll_pfd2", "apll", base + 0x50c, 2);
clks[IMX7ULP_CLK_APLL_PFD3] = imx_clk_pfdv2("apll_pfd3", "apll", base + 0x50c, 3);
/* SPLL PFDs */
clks[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
clks[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
clks[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
clks[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
/* PLL Mux */
clks[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);
clks[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
clks[IMX7ULP_CLK_APLL_SEL] = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
clks[IMX7ULP_CLK_SPLL_SEL] = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
clks[IMX7ULP_CLK_SPLL_BUS_CLK] = imx_clk_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock);
/* scs/ddr/nic select different clock source requires that clock to be enabled first */
clks[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
clks[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels));
clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 1, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
clks[IMX7ULP_CLK_DDR_DIV] = imx_clk_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
0, ulp_div_table, &imx_ccm_lock);
clks[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
clks[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
clks[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic1_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
clks[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4);
clks[IMX7ULP_CLK_SOSC_BUS_CLK] = imx_clk_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3,
CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock);
clks[IMX7ULP_CLK_FIRC_BUS_CLK] = imx_clk_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3,
CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock);
imx_check_clk_hws(clks, clk_data->num);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
}
CLK_OF_DECLARE(imx7ulp_clk_scg1, "fsl,imx7ulp-scg1", imx7ulp_clk_scg1_init);
static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
{
struct clk_hw_onecell_data *clk_data;
struct clk_hw **clks;
void __iomem *base;
clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
IMX7ULP_CLK_PCC2_END, GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = IMX7ULP_CLK_PCC2_END;
clks = clk_data->hws;
/* PCC2 */
base = of_iomap(np, 0);
WARN_ON(!base);
clks[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30);
clks[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30);
clks[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30);
clks[IMX7ULP_CLK_SNVS] = imx_clk_hw_gate("snvs", "nic1_bus_clk", base + 0x8c, 30);
clks[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30);
clks[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
clks[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
clks[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_composite("lpit1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
clks[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_composite("lpspi2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4);
clks[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_composite("lpspi3", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8);
clks[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_composite("lpi2c4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac);
clks[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_composite("lpi2c5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0);
clks[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4);
clks[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8);
clks[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4);
clks[IMX7ULP_CLK_USB0] = imx7ulp_clk_composite("usb0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xcc);
clks[IMX7ULP_CLK_USB1] = imx7ulp_clk_composite("usb1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xd0);
clks[IMX7ULP_CLK_USB_PHY] = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30);
clks[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_composite("usdhc0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xdc);
clks[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_composite("usdhc1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xe0);
clks[IMX7ULP_CLK_WDG1] = imx7ulp_clk_composite("wdg1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xf4);
clks[IMX7ULP_CLK_WDG2] = imx7ulp_clk_composite("sdg2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0x10c);
imx_check_clk_hws(clks, clk_data->num);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
}
CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init);
static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
{
struct clk_hw_onecell_data *clk_data;
struct clk_hw **clks;
void __iomem *base;
clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) *
IMX7ULP_CLK_PCC3_END, GFP_KERNEL);
if (!clk_data)
return;
clk_data->num = IMX7ULP_CLK_PCC3_END;
clks = clk_data->hws;
/* PCC3 */
base = of_iomap(np, 0);
WARN_ON(!base);
clks[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_composite("lptpm6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84);
clks[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_composite("lptpm7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88);
clks[IMX7ULP_CLK_MMDC] = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
base + 0xac, 30, 0, &imx_ccm_lock);
clks[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_composite("lpi2c6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90);
clks[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_composite("lpi2c7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
clks[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
clks[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
clks[IMX7ULP_CLK_DSI] = imx7ulp_clk_composite("dsi", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xa4);
clks[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_composite("lcdif", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xa8);
clks[IMX7ULP_CLK_VIU] = imx_clk_hw_gate("viu", "nic1_clk", base + 0xa0, 30);
clks[IMX7ULP_CLK_PCTLC] = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30);
clks[IMX7ULP_CLK_PCTLD] = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30);
clks[IMX7ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30);
clks[IMX7ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30);
clks[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_composite("gpu3d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140);
clks[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_composite("gpu2d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144);
imx_check_clk_hws(clks, clk_data->num);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
}
CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init);
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2018 NXP.
* Copyright (C) 2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
*/
#include <dt-bindings/clock/imx8mq-clock.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include "clk.h"
static u32 share_count_sai1;
static u32 share_count_sai2;
static u32 share_count_sai3;
static u32 share_count_sai4;
static u32 share_count_sai5;
static u32 share_count_sai6;
static u32 share_count_dcss;
static u32 share_count_nand;
static struct clk *clks[IMX8MQ_CLK_END];
static const char *pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
static const char *sys1_pll1_out_sels[] = {"sys1_pll1", "sys1_pll1_ref_sel", };
static const char *sys2_pll1_out_sels[] = {"sys2_pll1", "sys1_pll1_ref_sel", };
static const char *sys3_pll1_out_sels[] = {"sys3_pll1", "sys3_pll1_ref_sel", };
static const char *dram_pll1_out_sels[] = {"dram_pll1", "dram_pll1_ref_sel", };
static const char *sys1_pll2_out_sels[] = {"sys1_pll2_div", "sys1_pll1_ref_sel", };
static const char *sys2_pll2_out_sels[] = {"sys2_pll2_div", "sys2_pll1_ref_sel", };
static const char *sys3_pll2_out_sels[] = {"sys3_pll2_div", "sys2_pll1_ref_sel", };
static const char *dram_pll2_out_sels[] = {"dram_pll2_div", "dram_pll1_ref_sel", };
/* CCM ROOT */
static const char *imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
"sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", };
static const char *imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
"sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", };
static const char *imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
"sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
static const char *imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
"sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
static const char *imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m",
"sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",};
static const char *imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m",
"sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
static const char *imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m",
"sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", };
static const char *imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", };
static const char *imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
static const char *imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out",
"sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
static const char *imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m",
"audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
static const char *imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m",
"sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
static const char *imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
static const char *imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
static const char *imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m",
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
static const char *imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m",
"sys1_pll_800m", "audio_pll1_out", "video_pll1_out", };
static const char *imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m",
"sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
static const char *imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m",
"sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
static const char *imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"};
static const char *imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m",
"sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", };
static const char *imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
"sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
static const char *imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
static const char *imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
static const char *imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
static const char *imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
static const char *imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
"sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", };
static const char *imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2",
"clk_ext3", "clk_ext4", };
static const char *imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out",
"sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
static const char *imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
static const char *imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
static const char *imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
static const char *imx8mq_sai2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
static const char *imx8mq_sai3_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
static const char *imx8mq_sai4_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
static const char *imx8mq_sai5_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
static const char *imx8mq_sai6_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
static const char *imx8mq_spdif1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
static const char *imx8mq_spdif2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
static const char *imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m",
"sys1_pll_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
static const char *imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
"clk_ext3", "clk_ext4", "video_pll1_out", };
static const char *imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m",
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
static const char *imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m",
"audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", };
static const char *imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
"audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
static const char *imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
"audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
static const char *imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
"audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
static const char *imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
"video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
static const char *imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
"video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
static const char *imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
"video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
static const char *imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
"video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
static const char *imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
"sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
static const char *imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
"sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
"sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
static const char *imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
"sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
"sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
"sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
"sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
static const char *imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
"sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
static const char *imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
"sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
static const char *imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
"sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
static const char *imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
"sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
static const char *imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
"sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
static const char *imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m",
"sys1_pll_80m", "audio_pll1_out", "clk_ext1", };
static const char *imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out",
"sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", };
static const char *imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m",
"sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", };
static const char *imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
"sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
"sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
"sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
static const char *imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
"sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
static const char *imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
"sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", };
static const char *imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1",
"clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", };
static const char *imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out",
"sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
static const char *imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
"sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
static const char *imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
static const char *imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m", "audio_pll1_out",
"video_pll1_out", "ckil", };
static struct clk_onecell_data clk_data;
static int imx8mq_clocks_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
void __iomem *base;
int err;
int i;
clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(np, "ckil");
clks[IMX8MQ_CLK_25M] = of_clk_get_by_name(np, "osc_25m");
clks[IMX8MQ_CLK_27M] = of_clk_get_by_name(np, "osc_27m");
clks[IMX8MQ_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
clks[IMX8MQ_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
clks[IMX8MQ_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
clks[IMX8MQ_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop");
base = of_iomap(np, 0);
if (WARN_ON(!base))
return -ENOMEM;
clks[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_SYS1_PLL1_REF_SEL] = imx_clk_mux("sys1_pll1_ref_sel", base + 0x30, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_SYS2_PLL1_REF_SEL] = imx_clk_mux("sys2_pll1_ref_sel", base + 0x3c, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
clks[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6);
clks[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6);
clks[IMX8MQ_VPU_PLL_REF_DIV] = imx_clk_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6);
clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
clks[IMX8MQ_SYS1_PLL1_REF_DIV] = imx_clk_divider("sys1_pll1_ref_div", "sys1_pll1_ref_sel", base + 0x38, 25, 3);
clks[IMX8MQ_SYS2_PLL1_REF_DIV] = imx_clk_divider("sys2_pll1_ref_div", "sys2_pll1_ref_sel", base + 0x44, 25, 3);
clks[IMX8MQ_SYS3_PLL1_REF_DIV] = imx_clk_divider("sys3_pll1_ref_div", "sys3_pll1_ref_sel", base + 0x50, 25, 3);
clks[IMX8MQ_DRAM_PLL1_REF_DIV] = imx_clk_divider("dram_pll1_ref_div", "dram_pll1_ref_sel", base + 0x68, 25, 3);
clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
clks[IMX8MQ_VPU_PLL] = imx_clk_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20);
clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
clks[IMX8MQ_SYS1_PLL1] = imx_clk_sccg_pll("sys1_pll1", "sys1_pll1_ref_div", base + 0x30, SCCG_PLL1);
clks[IMX8MQ_SYS2_PLL1] = imx_clk_sccg_pll("sys2_pll1", "sys2_pll1_ref_div", base + 0x3c, SCCG_PLL1);
clks[IMX8MQ_SYS3_PLL1] = imx_clk_sccg_pll("sys3_pll1", "sys3_pll1_ref_div", base + 0x48, SCCG_PLL1);
clks[IMX8MQ_DRAM_PLL1] = imx_clk_sccg_pll("dram_pll1", "dram_pll1_ref_div", base + 0x60, SCCG_PLL1);
clks[IMX8MQ_SYS1_PLL2] = imx_clk_sccg_pll("sys1_pll2", "sys1_pll1_out_div", base + 0x30, SCCG_PLL2);
clks[IMX8MQ_SYS2_PLL2] = imx_clk_sccg_pll("sys2_pll2", "sys2_pll1_out_div", base + 0x3c, SCCG_PLL2);
clks[IMX8MQ_SYS3_PLL2] = imx_clk_sccg_pll("sys3_pll2", "sys3_pll1_out_div", base + 0x48, SCCG_PLL2);
clks[IMX8MQ_DRAM_PLL2] = imx_clk_sccg_pll("dram_pll2", "dram_pll1_out_div", base + 0x60, SCCG_PLL2);
/* PLL divs */
clks[IMX8MQ_SYS1_PLL1_OUT_DIV] = imx_clk_divider("sys1_pll1_out_div", "sys1_pll1_out", base + 0x38, 19, 6);
clks[IMX8MQ_SYS2_PLL1_OUT_DIV] = imx_clk_divider("sys2_pll1_out_div", "sys2_pll1_out", base + 0x44, 19, 6);
clks[IMX8MQ_SYS3_PLL1_OUT_DIV] = imx_clk_divider("sys3_pll1_out_div", "sys3_pll1_out", base + 0x50, 19, 6);
clks[IMX8MQ_DRAM_PLL1_OUT_DIV] = imx_clk_divider("dram_pll1_out_div", "dram_pll1_out", base + 0x68, 19, 6);
clks[IMX8MQ_SYS1_PLL2_DIV] = imx_clk_divider("sys1_pll2_div", "sys1_pll2", base + 0x38, 1, 6);
clks[IMX8MQ_SYS2_PLL2_DIV] = imx_clk_divider("sys2_pll2_div", "sys2_pll2", base + 0x44, 1, 6);
clks[IMX8MQ_SYS3_PLL2_DIV] = imx_clk_divider("sys3_pll2_div", "sys3_pll2", base + 0x50, 1, 6);
clks[IMX8MQ_DRAM_PLL2_DIV] = imx_clk_divider("dram_pll2_div", "dram_pll2", base + 0x68, 1, 6);
/* PLL bypass out */
clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels));
clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
clks[IMX8MQ_SYS1_PLL1_OUT] = imx_clk_mux("sys1_pll1_out", base + 0x30, 5, 1, sys1_pll1_out_sels, ARRAY_SIZE(sys1_pll1_out_sels));
clks[IMX8MQ_SYS2_PLL1_OUT] = imx_clk_mux("sys2_pll1_out", base + 0x3c, 5, 1, sys2_pll1_out_sels, ARRAY_SIZE(sys2_pll1_out_sels));
clks[IMX8MQ_SYS3_PLL1_OUT] = imx_clk_mux("sys3_pll1_out", base + 0x48, 5, 1, sys3_pll1_out_sels, ARRAY_SIZE(sys3_pll1_out_sels));
clks[IMX8MQ_DRAM_PLL1_OUT] = imx_clk_mux("dram_pll1_out", base + 0x60, 5, 1, dram_pll1_out_sels, ARRAY_SIZE(dram_pll1_out_sels));
clks[IMX8MQ_SYS1_PLL2_OUT] = imx_clk_mux("sys1_pll2_out", base + 0x30, 4, 1, sys1_pll2_out_sels, ARRAY_SIZE(sys1_pll2_out_sels));
clks[IMX8MQ_SYS2_PLL2_OUT] = imx_clk_mux("sys2_pll2_out", base + 0x3c, 4, 1, sys2_pll2_out_sels, ARRAY_SIZE(sys2_pll2_out_sels));
clks[IMX8MQ_SYS3_PLL2_OUT] = imx_clk_mux("sys3_pll2_out", base + 0x48, 4, 1, sys3_pll2_out_sels, ARRAY_SIZE(sys3_pll2_out_sels));
clks[IMX8MQ_DRAM_PLL2_OUT] = imx_clk_mux("dram_pll2_out", base + 0x60, 4, 1, dram_pll2_out_sels, ARRAY_SIZE(dram_pll2_out_sels));
/* PLL OUT GATE */
clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
clks[IMX8MQ_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21);
clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_gate("sys1_pll_out", "sys1_pll2_out", base + 0x30, 9);
clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_gate("sys2_pll_out", "sys2_pll2_out", base + 0x3c, 9);
clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_gate("sys3_pll_out", "sys3_pll2_out", base + 0x48, 9);
clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll2_out", base + 0x60, 9);
/* SYS PLL fixed output */
clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20);
clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10);
clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8);
clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6);
clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5);
clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4);
clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3);
clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2);
clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1);
clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20);
clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10);
clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8);
clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6);
clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5);
clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4);
clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3);
clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2);
clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1);
np = dev->of_node;
base = of_iomap(np, 0);
if (WARN_ON(!base))
return -ENOMEM;
/* CORE */
clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels));
clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
/* BUS */
clks[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
clks[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
clks[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
clks[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
clks[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
clks[IMX8MQ_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
clks[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
clks[IMX8MQ_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
clks[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
clks[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
clks[IMX8MQ_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
clks[IMX8MQ_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
/* AHB */
clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite("ahb", imx8mq_ahb_sels, base + 0x9000);
clks[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
/* IPG */
clks[IMX8MQ_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
clks[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
/* IP */
clks[IMX8MQ_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
clks[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
clks[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
clks[IMX8MQ_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
clks[IMX8MQ_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180);
clks[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200);
clks[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280);
clks[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300);
clks[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380);
clks[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400);
clks[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480);
clks[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500);
clks[IMX8MQ_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mq_sai1_sels, base + 0xa580);
clks[IMX8MQ_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mq_sai2_sels, base + 0xa600);
clks[IMX8MQ_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mq_sai3_sels, base + 0xa680);
clks[IMX8MQ_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mq_sai4_sels, base + 0xa700);
clks[IMX8MQ_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mq_sai5_sels, base + 0xa780);
clks[IMX8MQ_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mq_sai6_sels, base + 0xa800);
clks[IMX8MQ_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880);
clks[IMX8MQ_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900);
clks[IMX8MQ_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980);
clks[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00);
clks[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80);
clks[IMX8MQ_CLK_NAND] = imx8m_clk_composite("nand", imx8mq_nand_sels, base + 0xab00);
clks[IMX8MQ_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80);
clks[IMX8MQ_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00);
clks[IMX8MQ_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80);
clks[IMX8MQ_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00);
clks[IMX8MQ_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80);
clks[IMX8MQ_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00);
clks[IMX8MQ_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80);
clks[IMX8MQ_CLK_UART1] = imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00);
clks[IMX8MQ_CLK_UART2] = imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80);
clks[IMX8MQ_CLK_UART3] = imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000);
clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080);
clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100);
clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180);
clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280);
clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300);
clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380);
clks[IMX8MQ_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400);
clks[IMX8MQ_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480);
clks[IMX8MQ_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500);
clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
clks[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80);
clks[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00);
clks[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80);
clks[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000);
clks[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080);
clks[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100);
clks[IMX8MQ_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180);
clks[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
clks[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
clks[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
clks[IMX8MQ_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
clks[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
clks[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
clks[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0);
clks[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
clks[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
clks[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
clks[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
clks[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
clks[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
clks[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
clks[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
clks[IMX8MQ_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
clks[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
clks[IMX8MQ_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2);
clks[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
clks[IMX8MQ_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3);
clks[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
clks[IMX8MQ_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
clks[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_core_ref", base + 0x44e0, 0);
clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
clks[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
clks[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
clks[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
clks[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
clks[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX8MQ_CLK_GPU_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0);
clks[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX8MQ_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
clks[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
clks[IMX8MQ_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4_flags("tmu_root_clk", "ipg_root", base + 0x4620, 0, CLK_IS_CRITICAL);
clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
clks[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
clks[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
for (i = 0; i < IMX8MQ_CLK_END; i++)
if (IS_ERR(clks[i]))
pr_err("i.MX8mq clk %u register failed with %ld\n",
i, PTR_ERR(clks[i]));
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
WARN_ON(err);
return err;
}
static const struct of_device_id imx8mq_clk_of_match[] = {
{ .compatible = "fsl,imx8mq-ccm" },
{ /* Sentinel */ },
};
MODULE_DEVICE_TABLE(of, imx8mq_clk_of_match);
static struct platform_driver imx8mq_clk_driver = {
.probe = imx8mq_clocks_probe,
.driver = {
.name = "imx8mq-ccm",
.of_match_table = of_match_ptr(imx8mq_clk_of_match),
},
};
module_platform_driver(imx8mq_clk_driver);
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "clk-scu.h"
#include "clk-imx8qxp-lpcg.h"
#include <dt-bindings/clock/imx8qxp-clock.h>
/*
* struct imx8qxp_lpcg_data - Description of one LPCG clock
* @id: clock ID
* @name: clock name
* @parent: parent clock name
* @flags: common clock flags
* @offset: offset of this LPCG clock
* @bit_idx: bit index of this LPCG clock
* @hw_gate: whether supports HW autogate
*
* This structure describes one LPCG clock
*/
struct imx8qxp_lpcg_data {
int id;
char *name;
char *parent;
unsigned long flags;
u32 offset;
u8 bit_idx;
bool hw_gate;
};
/*
* struct imx8qxp_ss_lpcg - Description of one subsystem LPCG clocks
* @lpcg: LPCG clocks array of one subsystem
* @num_lpcg: the number of LPCG clocks
* @num_max: the maximum number of LPCG clocks
*
* This structure describes each subsystem LPCG clocks information
* which then will be used to create respective LPCGs clocks
*/
struct imx8qxp_ss_lpcg {
const struct imx8qxp_lpcg_data *lpcg;
u8 num_lpcg;
u8 num_max;
};
static const struct imx8qxp_lpcg_data imx8qxp_lpcg_adma[] = {
{ IMX8QXP_ADMA_LPCG_UART0_IPG_CLK, "uart0_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_0_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_UART0_BAUD_CLK, "uart0_lpcg_baud_clk", "uart0_clk", 0, ADMA_LPUART_0_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_UART1_IPG_CLK, "uart1_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_1_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_UART1_BAUD_CLK, "uart1_lpcg_baud_clk", "uart1_clk", 0, ADMA_LPUART_1_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_UART2_IPG_CLK, "uart2_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_2_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_UART2_BAUD_CLK, "uart2_lpcg_baud_clk", "uart2_clk", 0, ADMA_LPUART_2_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_UART3_IPG_CLK, "uart3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPUART_3_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_UART3_BAUD_CLK, "uart3_lpcg_baud_clk", "uart3_clk", 0, ADMA_LPUART_3_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_I2C0_IPG_CLK, "i2c0_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_0_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_I2C0_CLK, "i2c0_lpcg_clk", "i2c0_clk", 0, ADMA_LPI2C_0_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_I2C1_IPG_CLK, "i2c1_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_1_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_I2C1_CLK, "i2c1_lpcg_clk", "i2c1_clk", 0, ADMA_LPI2C_1_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_I2C2_IPG_CLK, "i2c2_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_2_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_I2C2_CLK, "i2c2_lpcg_clk", "i2c2_clk", 0, ADMA_LPI2C_2_LPCG, 0, 0, },
{ IMX8QXP_ADMA_LPCG_I2C3_IPG_CLK, "i2c3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_3_LPCG, 16, 0, },
{ IMX8QXP_ADMA_LPCG_I2C3_CLK, "i2c3_lpcg_clk", "i2c3_clk", 0, ADMA_LPI2C_3_LPCG, 0, 0, },
};
static const struct imx8qxp_ss_lpcg imx8qxp_ss_adma = {
.lpcg = imx8qxp_lpcg_adma,
.num_lpcg = ARRAY_SIZE(imx8qxp_lpcg_adma),
.num_max = IMX8QXP_ADMA_LPCG_CLK_END,
};
static const struct imx8qxp_lpcg_data imx8qxp_lpcg_conn[] = {
{ IMX8QXP_CONN_LPCG_SDHC0_PER_CLK, "sdhc0_lpcg_per_clk", "sdhc0_clk", 0, CONN_USDHC_0_LPCG, 0, 0, },
{ IMX8QXP_CONN_LPCG_SDHC0_IPG_CLK, "sdhc0_lpcg_ipg_clk", "conn_ipg_clk_root", 0, CONN_USDHC_0_LPCG, 16, 0, },
{ IMX8QXP_CONN_LPCG_SDHC0_HCLK, "sdhc0_lpcg_ahb_clk", "conn_axi_clk_root", 0, CONN_USDHC_0_LPCG, 20, 0, },
{ IMX8QXP_CONN_LPCG_SDHC1_PER_CLK, "sdhc1_lpcg_per_clk", "sdhc1_clk", 0, CONN_USDHC_1_LPCG, 0, 0, },
{ IMX8QXP_CONN_LPCG_SDHC1_IPG_CLK, "sdhc1_lpcg_ipg_clk", "conn_ipg_clk_root", 0, CONN_USDHC_1_LPCG, 16, 0, },
{ IMX8QXP_CONN_LPCG_SDHC1_HCLK, "sdhc1_lpcg_ahb_clk", "conn_axi_clk_root", 0, CONN_USDHC_1_LPCG, 20, 0, },
{ IMX8QXP_CONN_LPCG_SDHC2_PER_CLK, "sdhc2_lpcg_per_clk", "sdhc2_clk", 0, CONN_USDHC_2_LPCG, 0, 0, },
{ IMX8QXP_CONN_LPCG_SDHC2_IPG_CLK, "sdhc2_lpcg_ipg_clk", "conn_ipg_clk_root", 0, CONN_USDHC_2_LPCG, 16, 0, },
{ IMX8QXP_CONN_LPCG_SDHC2_HCLK, "sdhc2_lpcg_ahb_clk", "conn_axi_clk_root", 0, CONN_USDHC_2_LPCG, 20, 0, },
{ IMX8QXP_CONN_LPCG_ENET0_ROOT_CLK, "enet0_ipg_root_clk", "enet0_clk", 0, CONN_ENET_0_LPCG, 0, 0, },
{ IMX8QXP_CONN_LPCG_ENET0_TX_CLK, "enet0_tx_clk", "enet0_clk", 0, CONN_ENET_0_LPCG, 4, 0, },
{ IMX8QXP_CONN_LPCG_ENET0_AHB_CLK, "enet0_ahb_clk", "conn_axi_clk_root", 0, CONN_ENET_0_LPCG, 8, 0, },
{ IMX8QXP_CONN_LPCG_ENET0_IPG_S_CLK, "enet0_ipg_s_clk", "conn_ipg_clk_root", 0, CONN_ENET_0_LPCG, 20, 0, },
{ IMX8QXP_CONN_LPCG_ENET0_IPG_CLK, "enet0_ipg_clk", "enet0_ipg_s_clk", 0, CONN_ENET_0_LPCG, 16, 0, },
{ IMX8QXP_CONN_LPCG_ENET1_ROOT_CLK, "enet1_ipg_root_clk", "enet1_clk", 0, CONN_ENET_1_LPCG, 0, 0, },
{ IMX8QXP_CONN_LPCG_ENET1_TX_CLK, "enet1_tx_clk", "enet1_clk", 0, CONN_ENET_1_LPCG, 4, 0, },
{ IMX8QXP_CONN_LPCG_ENET1_AHB_CLK, "enet1_ahb_clk", "conn_axi_clk_root", 0, CONN_ENET_1_LPCG, 8, 0, },
{ IMX8QXP_CONN_LPCG_ENET1_IPG_S_CLK, "enet1_ipg_s_clk", "conn_ipg_clk_root", 0, CONN_ENET_1_LPCG, 20, 0, },
{ IMX8QXP_CONN_LPCG_ENET1_IPG_CLK, "enet1_ipg_clk", "enet0_ipg_s_clk", 0, CONN_ENET_1_LPCG, 16, 0, },
};
static const struct imx8qxp_ss_lpcg imx8qxp_ss_conn = {
.lpcg = imx8qxp_lpcg_conn,
.num_lpcg = ARRAY_SIZE(imx8qxp_lpcg_conn),
.num_max = IMX8QXP_CONN_LPCG_CLK_END,
};
static const struct imx8qxp_lpcg_data imx8qxp_lpcg_lsio[] = {
{ IMX8QXP_LSIO_LPCG_PWM0_IPG_CLK, "pwm0_lpcg_ipg_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM0_IPG_HF_CLK, "pwm0_lpcg_ipg_hf_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM0_IPG_S_CLK, "pwm0_lpcg_ipg_s_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM0_IPG_SLV_CLK, "pwm0_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_0_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM0_IPG_MSTR_CLK, "pwm0_lpcg_ipg_mstr_clk", "pwm0_clk", 0, LSIO_PWM_0_LPCG, 24, 0, },
{ IMX8QXP_LSIO_LPCG_PWM1_IPG_CLK, "pwm1_lpcg_ipg_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM1_IPG_HF_CLK, "pwm1_lpcg_ipg_hf_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM1_IPG_S_CLK, "pwm1_lpcg_ipg_s_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM1_IPG_SLV_CLK, "pwm1_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_1_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM1_IPG_MSTR_CLK, "pwm1_lpcg_ipg_mstr_clk", "pwm1_clk", 0, LSIO_PWM_1_LPCG, 24, 0, },
{ IMX8QXP_LSIO_LPCG_PWM2_IPG_CLK, "pwm2_lpcg_ipg_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM2_IPG_HF_CLK, "pwm2_lpcg_ipg_hf_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM2_IPG_S_CLK, "pwm2_lpcg_ipg_s_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM2_IPG_SLV_CLK, "pwm2_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_2_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM2_IPG_MSTR_CLK, "pwm2_lpcg_ipg_mstr_clk", "pwm2_clk", 0, LSIO_PWM_2_LPCG, 24, 0, },
{ IMX8QXP_LSIO_LPCG_PWM3_IPG_CLK, "pwm3_lpcg_ipg_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM3_IPG_HF_CLK, "pwm3_lpcg_ipg_hf_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM3_IPG_S_CLK, "pwm3_lpcg_ipg_s_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM3_IPG_SLV_CLK, "pwm3_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_3_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM3_IPG_MSTR_CLK, "pwm3_lpcg_ipg_mstr_clk", "pwm3_clk", 0, LSIO_PWM_3_LPCG, 24, 0, },
{ IMX8QXP_LSIO_LPCG_PWM4_IPG_CLK, "pwm4_lpcg_ipg_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM4_IPG_HF_CLK, "pwm4_lpcg_ipg_hf_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM4_IPG_S_CLK, "pwm4_lpcg_ipg_s_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM4_IPG_SLV_CLK, "pwm4_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_4_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM4_IPG_MSTR_CLK, "pwm4_lpcg_ipg_mstr_clk", "pwm4_clk", 0, LSIO_PWM_4_LPCG, 24, 0, },
{ IMX8QXP_LSIO_LPCG_PWM5_IPG_CLK, "pwm5_lpcg_ipg_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM5_IPG_HF_CLK, "pwm5_lpcg_ipg_hf_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM5_IPG_S_CLK, "pwm5_lpcg_ipg_s_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM5_IPG_SLV_CLK, "pwm5_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_5_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM5_IPG_MSTR_CLK, "pwm5_lpcg_ipg_mstr_clk", "pwm5_clk", 0, LSIO_PWM_5_LPCG, 24, 0, },
{ IMX8QXP_LSIO_LPCG_PWM6_IPG_CLK, "pwm6_lpcg_ipg_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 0, 0, },
{ IMX8QXP_LSIO_LPCG_PWM6_IPG_HF_CLK, "pwm6_lpcg_ipg_hf_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 4, 0, },
{ IMX8QXP_LSIO_LPCG_PWM6_IPG_S_CLK, "pwm6_lpcg_ipg_s_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 16, 0, },
{ IMX8QXP_LSIO_LPCG_PWM6_IPG_SLV_CLK, "pwm6_lpcg_ipg_slv_clk", "lsio_bus_clk_root", 0, LSIO_PWM_6_LPCG, 20, 0, },
{ IMX8QXP_LSIO_LPCG_PWM6_IPG_MSTR_CLK, "pwm6_lpcg_ipg_mstr_clk", "pwm6_clk", 0, LSIO_PWM_6_LPCG, 24, 0, },
};
static const struct imx8qxp_ss_lpcg imx8qxp_ss_lsio = {
.lpcg = imx8qxp_lpcg_lsio,
.num_lpcg = ARRAY_SIZE(imx8qxp_lpcg_lsio),
.num_max = IMX8QXP_LSIO_LPCG_CLK_END,
};
static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct clk_hw_onecell_data *clk_data;
const struct imx8qxp_ss_lpcg *ss_lpcg;
const struct imx8qxp_lpcg_data *lpcg;
struct resource *res;
struct clk_hw **clks;
void __iomem *base;
int i;
ss_lpcg = of_device_get_match_data(dev);
if (!ss_lpcg)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap(dev, res->start, resource_size(res));
if (!base)
return -ENOMEM;
clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws,
ss_lpcg->num_max), GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
clk_data->num = ss_lpcg->num_max;
clks = clk_data->hws;
for (i = 0; i < ss_lpcg->num_lpcg; i++) {
lpcg = ss_lpcg->lpcg + i;
clks[lpcg->id] = imx_clk_lpcg_scu(lpcg->name, lpcg->parent,
lpcg->flags, base + lpcg->offset,
lpcg->bit_idx, lpcg->hw_gate);
}
for (i = 0; i < clk_data->num; i++) {
if (IS_ERR(clks[i]))
pr_warn("i.MX clk %u: register failed with %ld\n",
i, PTR_ERR(clks[i]));
}
return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
}
static const struct of_device_id imx8qxp_lpcg_match[] = {
{ .compatible = "fsl,imx8qxp-lpcg-adma", &imx8qxp_ss_adma, },
{ .compatible = "fsl,imx8qxp-lpcg-conn", &imx8qxp_ss_conn, },
{ .compatible = "fsl,imx8qxp-lpcg-lsio", &imx8qxp_ss_lsio, },
{ /* sentinel */ }
};
static struct platform_driver imx8qxp_lpcg_clk_driver = {
.driver = {
.name = "imx8qxp-lpcg-clk",
.of_match_table = imx8qxp_lpcg_match,
.suppress_bind_attrs = true,
},
.probe = imx8qxp_lpcg_clk_probe,
};
builtin_platform_driver(imx8qxp_lpcg_clk_driver);
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#ifndef _IMX8QXP_LPCG_H
#define _IMX8QXP_LPCG_H
/*LSIO SS */
#define LSIO_PWM_0_LPCG 0x00000
#define LSIO_PWM_1_LPCG 0x10000
#define LSIO_PWM_2_LPCG 0x20000
#define LSIO_PWM_3_LPCG 0x30000
#define LSIO_PWM_4_LPCG 0x40000
#define LSIO_PWM_5_LPCG 0x50000
#define LSIO_PWM_6_LPCG 0x60000
#define LSIO_PWM_7_LPCG 0x70000
#define LSIO_GPIO_0_LPCG 0x80000
#define LSIO_GPIO_1_LPCG 0x90000
#define LSIO_GPIO_2_LPCG 0xa0000
#define LSIO_GPIO_3_LPCG 0xb0000
#define LSIO_GPIO_4_LPCG 0xc0000
#define LSIO_GPIO_5_LPCG 0xd0000
#define LSIO_GPIO_6_LPCG 0xe0000
#define LSIO_GPIO_7_LPCG 0xf0000
#define LSIO_FSPI_0_LPCG 0x120000
#define LSIO_FSPI_1_LPCG 0x130000
#define LSIO_GPT_0_LPCG 0x140000
#define LSIO_GPT_1_LPCG 0x150000
#define LSIO_GPT_2_LPCG 0x160000
#define LSIO_GPT_3_LPCG 0x170000
#define LSIO_GPT_4_LPCG 0x180000
#define LSIO_OCRAM_LPCG 0x190000
#define LSIO_KPP_LPCG 0x1a0000
#define LSIO_ROMCP_LPCG 0x100000
/* Connectivity SS */
#define CONN_USDHC_0_LPCG 0x00000
#define CONN_USDHC_1_LPCG 0x10000
#define CONN_USDHC_2_LPCG 0x20000
#define CONN_ENET_0_LPCG 0x30000
#define CONN_ENET_1_LPCG 0x40000
#define CONN_DTCP_LPCG 0x50000
#define CONN_MLB_LPCG 0x60000
#define CONN_USB_2_LPCG 0x70000
#define CONN_USB_3_LPCG 0x80000
#define CONN_NAND_LPCG 0x90000
#define CONN_EDMA_LPCG 0xa0000
/* ADMA SS */
#define ADMA_ASRC_0_LPCG 0x400000
#define ADMA_ESAI_0_LPCG 0x410000
#define ADMA_SPDIF_0_LPCG 0x420000
#define ADMA_SAI_0_LPCG 0x440000
#define ADMA_SAI_1_LPCG 0x450000
#define ADMA_SAI_2_LPCG 0x460000
#define ADMA_SAI_3_LPCG 0x470000
#define ADMA_GPT_5_LPCG 0x4b0000
#define ADMA_GPT_6_LPCG 0x4c0000
#define ADMA_GPT_7_LPCG 0x4d0000
#define ADMA_GPT_8_LPCG 0x4e0000
#define ADMA_GPT_9_LPCG 0x4f0000
#define ADMA_GPT_10_LPCG 0x500000
#define ADMA_HIFI_LPCG 0x580000
#define ADMA_OCRAM_LPCG 0x590000
#define ADMA_EDMA_0_LPCG 0x5f0000
#define ADMA_ASRC_1_LPCG 0xc00000
#define ADMA_SAI_4_LPCG 0xc20000
#define ADMA_SAI_5_LPCG 0xc30000
#define ADMA_AMIX_LPCG 0xc40000
#define ADMA_MQS_LPCG 0xc50000
#define ADMA_ACM_LPCG 0xc60000
#define ADMA_REC_CLK0_LPCG 0xd00000
#define ADMA_REC_CLK1_LPCG 0xd10000
#define ADMA_PLL_CLK0_LPCG 0xd20000
#define ADMA_PLL_CLK1_LPCG 0xd30000
#define ADMA_MCLKOUT0_LPCG 0xd50000
#define ADMA_MCLKOUT1_LPCG 0xd60000
#define ADMA_EDMA_1_LPCG 0xdf0000
#define ADMA_LPSPI_0_LPCG 0x1400000
#define ADMA_LPSPI_1_LPCG 0x1410000
#define ADMA_LPSPI_2_LPCG 0x1420000
#define ADMA_LPSPI_3_LPCG 0x1430000
#define ADMA_LPUART_0_LPCG 0x1460000
#define ADMA_LPUART_1_LPCG 0x1470000
#define ADMA_LPUART_2_LPCG 0x1480000
#define ADMA_LPUART_3_LPCG 0x1490000
#define ADMA_LCD_LPCG 0x1580000
#define ADMA_PWM_LPCG 0x1590000
#define ADMA_LPI2C_0_LPCG 0x1c00000
#define ADMA_LPI2C_1_LPCG 0x1c10000
#define ADMA_LPI2C_2_LPCG 0x1c20000
#define ADMA_LPI2C_3_LPCG 0x1c30000
#define ADMA_ADC_0_LPCG 0x1c80000
#define ADMA_FTM_0_LPCG 0x1ca0000
#define ADMA_FTM_1_LPCG 0x1cb0000
#define ADMA_FLEXCAN_0_LPCG 0x1cd0000
#define ADMA_FLEXCAN_1_LPCG 0x1ce0000
#define ADMA_FLEXCAN_2_LPCG 0x1cf0000
#endif /* _IMX8QXP_LPCG_H */
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "clk-scu.h"
#include <dt-bindings/clock/imx8qxp-clock.h>
#include <dt-bindings/firmware/imx/rsrc.h>
static int imx8qxp_clk_probe(struct platform_device *pdev)
{
struct device_node *ccm_node = pdev->dev.of_node;
struct clk_hw_onecell_data *clk_data;
struct clk_hw **clks;
int ret, i;
ret = imx_clk_scu_init();
if (ret)
return ret;
clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws,
IMX8QXP_SCU_CLK_END), GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
clk_data->num = IMX8QXP_SCU_CLK_END;
clks = clk_data->hws;
/* Fixed clocks */
clks[IMX8QXP_CLK_DUMMY] = clk_hw_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
clks[IMX8QXP_ADMA_IPG_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "dma_ipg_clk_root", NULL, 0, 120000000);
clks[IMX8QXP_CONN_AXI_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "conn_axi_clk_root", NULL, 0, 333333333);
clks[IMX8QXP_CONN_AHB_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "conn_ahb_clk_root", NULL, 0, 166666666);
clks[IMX8QXP_CONN_IPG_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "conn_ipg_clk_root", NULL, 0, 83333333);
clks[IMX8QXP_DC_AXI_EXT_CLK] = clk_hw_register_fixed_rate(NULL, "dc_axi_ext_clk_root", NULL, 0, 800000000);
clks[IMX8QXP_DC_AXI_INT_CLK] = clk_hw_register_fixed_rate(NULL, "dc_axi_int_clk_root", NULL, 0, 400000000);
clks[IMX8QXP_DC_CFG_CLK] = clk_hw_register_fixed_rate(NULL, "dc_cfg_clk_root", NULL, 0, 100000000);
clks[IMX8QXP_MIPI_IPG_CLK] = clk_hw_register_fixed_rate(NULL, "mipi_ipg_clk_root", NULL, 0, 120000000);
clks[IMX8QXP_IMG_AXI_CLK] = clk_hw_register_fixed_rate(NULL, "img_axi_clk_root", NULL, 0, 400000000);
clks[IMX8QXP_IMG_IPG_CLK] = clk_hw_register_fixed_rate(NULL, "img_ipg_clk_root", NULL, 0, 200000000);
clks[IMX8QXP_IMG_PXL_CLK] = clk_hw_register_fixed_rate(NULL, "img_pxl_clk_root", NULL, 0, 600000000);
clks[IMX8QXP_HSIO_AXI_CLK] = clk_hw_register_fixed_rate(NULL, "hsio_axi_clk_root", NULL, 0, 400000000);
clks[IMX8QXP_HSIO_PER_CLK] = clk_hw_register_fixed_rate(NULL, "hsio_per_clk_root", NULL, 0, 133333333);
clks[IMX8QXP_LSIO_MEM_CLK] = clk_hw_register_fixed_rate(NULL, "lsio_mem_clk_root", NULL, 0, 200000000);
clks[IMX8QXP_LSIO_BUS_CLK] = clk_hw_register_fixed_rate(NULL, "lsio_bus_clk_root", NULL, 0, 100000000);
/* ARM core */
clks[IMX8QXP_A35_CLK] = imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU);
/* LSIO SS */
clks[IMX8QXP_LSIO_PWM0_CLK] = imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM1_CLK] = imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM2_CLK] = imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM3_CLK] = imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM4_CLK] = imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM5_CLK] = imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM6_CLK] = imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_PWM7_CLK] = imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_GPT0_CLK] = imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_GPT1_CLK] = imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_GPT2_CLK] = imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_GPT3_CLK] = imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_GPT4_CLK] = imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_FSPI0_CLK] = imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_LSIO_FSPI1_CLK] = imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER);
/* ADMA SS */
clks[IMX8QXP_ADMA_UART0_CLK] = imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_UART1_CLK] = imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_UART2_CLK] = imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_UART3_CLK] = imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_SPI0_CLK] = imx_clk_scu("spi0_clk", IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_SPI1_CLK] = imx_clk_scu("spi1_clk", IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_SPI2_CLK] = imx_clk_scu("spi2_clk", IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_SPI3_CLK] = imx_clk_scu("spi3_clk", IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_CAN0_CLK] = imx_clk_scu("can0_clk", IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_I2C0_CLK] = imx_clk_scu("i2c0_clk", IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_I2C1_CLK] = imx_clk_scu("i2c1_clk", IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_I2C2_CLK] = imx_clk_scu("i2c2_clk", IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_I2C3_CLK] = imx_clk_scu("i2c3_clk", IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_FTM0_CLK] = imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_FTM1_CLK] = imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_ADC0_CLK] = imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_PWM_CLK] = imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_ADMA_LCD_CLK] = imx_clk_scu("lcd_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
/* Connectivity */
clks[IMX8QXP_CONN_SDHC0_CLK] = imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_SDHC1_CLK] = imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_SDHC2_CLK] = imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_ENET0_ROOT_CLK] = imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_ENET0_BYPASS_CLK] = imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS);
clks[IMX8QXP_CONN_ENET0_RGMII_CLK] = imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0);
clks[IMX8QXP_CONN_ENET1_ROOT_CLK] = imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_ENET1_BYPASS_CLK] = imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS);
clks[IMX8QXP_CONN_ENET1_RGMII_CLK] = imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0);
clks[IMX8QXP_CONN_GPMI_BCH_IO_CLK] = imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS);
clks[IMX8QXP_CONN_GPMI_BCH_CLK] = imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_USB2_ACLK] = imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CONN_USB2_BUS_CLK] = imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MST_BUS);
clks[IMX8QXP_CONN_USB2_LPM_CLK] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC);
/* Display controller SS */
clks[IMX8QXP_DC0_DISP0_CLK] = imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
clks[IMX8QXP_DC0_DISP1_CLK] = imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
/* MIPI-LVDS SS */
clks[IMX8QXP_MIPI0_I2C0_CLK] = imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2);
clks[IMX8QXP_MIPI0_I2C1_CLK] = imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2);
/* MIPI CSI SS */
clks[IMX8QXP_CSI0_CORE_CLK] = imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CSI0_ESC_CLK] = imx_clk_scu("mipi_csi0_esc_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC);
clks[IMX8QXP_CSI0_I2C0_CLK] = imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_CSI0_PWM0_CLK] = imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0, IMX_SC_PM_CLK_PER);
/* GPU SS */
clks[IMX8QXP_GPU0_CORE_CLK] = imx_clk_scu("gpu_core0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER);
clks[IMX8QXP_GPU0_SHADER_CLK] = imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC);
for (i = 0; i < clk_data->num; i++) {
if (IS_ERR(clks[i]))
pr_warn("i.MX clk %u: register failed with %ld\n",
i, PTR_ERR(clks[i]));
}
return of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data);
}
static const struct of_device_id imx8qxp_match[] = {
{ .compatible = "fsl,imx8qxp-clk", },
{ /* sentinel */ }
};
static struct platform_driver imx8qxp_clk_driver = {
.driver = {
.name = "imx8qxp-clk",
.of_match_table = imx8qxp_match,
.suppress_bind_attrs = true,
},
.probe = imx8qxp_clk_probe,
};
builtin_platform_driver(imx8qxp_clk_driver);
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include "clk-scu.h"
static DEFINE_SPINLOCK(imx_lpcg_scu_lock);
#define CLK_GATE_SCU_LPCG_MASK 0x3
#define CLK_GATE_SCU_LPCG_HW_SEL BIT(0)
#define CLK_GATE_SCU_LPCG_SW_SEL BIT(1)
/*
* struct clk_lpcg_scu - Description of LPCG clock
*
* @hw: clk_hw of this LPCG
* @reg: register of this LPCG clock
* @bit_idx: bit index of this LPCG clock
* @hw_gate: HW auto gate enable
*
* This structure describes one LPCG clock
*/
struct clk_lpcg_scu {
struct clk_hw hw;
void __iomem *reg;
u8 bit_idx;
bool hw_gate;
};
#define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw)
static int clk_lpcg_scu_enable(struct clk_hw *hw)
{
struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw);
unsigned long flags;
u32 reg, val;
spin_lock_irqsave(&imx_lpcg_scu_lock, flags);
reg = readl_relaxed(clk->reg);
reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx);
val = CLK_GATE_SCU_LPCG_SW_SEL;
if (clk->hw_gate)
val |= CLK_GATE_SCU_LPCG_HW_SEL;
reg |= val << clk->bit_idx;
writel(reg, clk->reg);
spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
return 0;
}
static void clk_lpcg_scu_disable(struct clk_hw *hw)
{
struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw);
unsigned long flags;
u32 reg;
spin_lock_irqsave(&imx_lpcg_scu_lock, flags);
reg = readl_relaxed(clk->reg);
reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx);
writel(reg, clk->reg);
spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
}
static const struct clk_ops clk_lpcg_scu_ops = {
.enable = clk_lpcg_scu_enable,
.disable = clk_lpcg_scu_disable,
};
struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg,
u8 bit_idx, bool hw_gate)
{
struct clk_lpcg_scu *clk;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk)
return ERR_PTR(-ENOMEM);
clk->reg = reg;
clk->bit_idx = bit_idx;
clk->hw_gate = hw_gate;
init.name = name;
init.ops = &clk_lpcg_scu_ops;
init.flags = CLK_SET_RATE_PARENT | flags;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
clk->hw.init = &init;
hw = &clk->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(clk);
hw = ERR_PTR(ret);
}
return hw;
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017~2018 NXP
*
* Author: Dong Aisheng <aisheng.dong@nxp.com>
*
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include "clk.h"
/**
* struct clk_pfdv2 - IMX PFD clock
* @clk_hw: clock source
* @reg: PFD register address
* @gate_bit: Gate bit offset
* @vld_bit: Valid bit offset
* @frac_off: PLL Fractional Divider offset
*/
struct clk_pfdv2 {
struct clk_hw hw;
void __iomem *reg;
u8 gate_bit;
u8 vld_bit;
u8 frac_off;
};
#define to_clk_pfdv2(_hw) container_of(_hw, struct clk_pfdv2, hw)
#define CLK_PFDV2_FRAC_MASK 0x3f
#define LOCK_TIMEOUT_US USEC_PER_MSEC
static DEFINE_SPINLOCK(pfd_lock);
static int clk_pfdv2_wait(struct clk_pfdv2 *pfd)
{
u32 val;
return readl_poll_timeout(pfd->reg, val, val & pfd->vld_bit,
0, LOCK_TIMEOUT_US);
}
static int clk_pfdv2_enable(struct clk_hw *hw)
{
struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
unsigned long flags;
u32 val;
spin_lock_irqsave(&pfd_lock, flags);
val = readl_relaxed(pfd->reg);
val &= ~pfd->gate_bit;
writel_relaxed(val, pfd->reg);
spin_unlock_irqrestore(&pfd_lock, flags);
return clk_pfdv2_wait(pfd);
}
static void clk_pfdv2_disable(struct clk_hw *hw)
{
struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
unsigned long flags;
u32 val;
spin_lock_irqsave(&pfd_lock, flags);
val = readl_relaxed(pfd->reg);
val |= pfd->gate_bit;
writel_relaxed(val, pfd->reg);
spin_unlock_irqrestore(&pfd_lock, flags);
}
static unsigned long clk_pfdv2_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
u64 tmp = parent_rate;
u8 frac;
frac = (readl_relaxed(pfd->reg) >> pfd->frac_off)
& CLK_PFDV2_FRAC_MASK;
if (!frac) {
pr_debug("clk_pfdv2: %s invalid pfd frac value 0\n",
clk_hw_get_name(hw));
return 0;
}
tmp *= 18;
do_div(tmp, frac);
return tmp;
}
static long clk_pfdv2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
u64 tmp = *prate;
u8 frac;
tmp = tmp * 18 + rate / 2;
do_div(tmp, rate);
frac = tmp;
if (frac < 12)
frac = 12;
else if (frac > 35)
frac = 35;
tmp = *prate;
tmp *= 18;
do_div(tmp, frac);
return tmp;
}
static int clk_pfdv2_is_enabled(struct clk_hw *hw)
{
struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
if (readl_relaxed(pfd->reg) & pfd->gate_bit)
return 0;
return 1;
}
static int clk_pfdv2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
unsigned long flags;
u64 tmp = parent_rate;
u32 val;
u8 frac;
tmp = tmp * 18 + rate / 2;
do_div(tmp, rate);
frac = tmp;
if (frac < 12)
frac = 12;
else if (frac > 35)
frac = 35;
spin_lock_irqsave(&pfd_lock, flags);
val = readl_relaxed(pfd->reg);
val &= ~(CLK_PFDV2_FRAC_MASK << pfd->frac_off);
val |= frac << pfd->frac_off;
writel_relaxed(val, pfd->reg);
spin_unlock_irqrestore(&pfd_lock, flags);
return 0;
}
static const struct clk_ops clk_pfdv2_ops = {
.enable = clk_pfdv2_enable,
.disable = clk_pfdv2_disable,
.recalc_rate = clk_pfdv2_recalc_rate,
.round_rate = clk_pfdv2_round_rate,
.set_rate = clk_pfdv2_set_rate,
.is_enabled = clk_pfdv2_is_enabled,
};
struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
void __iomem *reg, u8 idx)
{
struct clk_init_data init;
struct clk_pfdv2 *pfd;
struct clk_hw *hw;
int ret;
WARN_ON(idx > 3);
pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
if (!pfd)
return ERR_PTR(-ENOMEM);
pfd->reg = reg;
pfd->gate_bit = 1 << ((idx + 1) * 8 - 1);
pfd->vld_bit = pfd->gate_bit - 1;
pfd->frac_off = idx * 8;
init.name = name;
init.ops = &clk_pfdv2_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE;
pfd->hw.init = &init;
hw = &pfd->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(pfd);
hw = ERR_PTR(ret);
}
return hw;
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017~2018 NXP
*
* Author: Dong Aisheng <aisheng.dong@nxp.com>
*
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include "clk.h"
/* PLL Control Status Register (xPLLCSR) */
#define PLL_CSR_OFFSET 0x0
#define PLL_VLD BIT(24)
#define PLL_EN BIT(0)
/* PLL Configuration Register (xPLLCFG) */
#define PLL_CFG_OFFSET 0x08
#define BP_PLL_MULT 16
#define BM_PLL_MULT (0x7f << 16)
/* PLL Numerator Register (xPLLNUM) */
#define PLL_NUM_OFFSET 0x10
/* PLL Denominator Register (xPLLDENOM) */
#define PLL_DENOM_OFFSET 0x14
struct clk_pllv4 {
struct clk_hw hw;
void __iomem *base;
};
/* Valid PLL MULT Table */
static const int pllv4_mult_table[] = {33, 27, 22, 20, 17, 16};
#define to_clk_pllv4(__hw) container_of(__hw, struct clk_pllv4, hw)
#define LOCK_TIMEOUT_US USEC_PER_MSEC
static inline int clk_pllv4_wait_lock(struct clk_pllv4 *pll)
{
u32 csr;
return readl_poll_timeout(pll->base + PLL_CSR_OFFSET,
csr, csr & PLL_VLD, 0, LOCK_TIMEOUT_US);
}
static int clk_pllv4_is_enabled(struct clk_hw *hw)
{
struct clk_pllv4 *pll = to_clk_pllv4(hw);
if (readl_relaxed(pll->base) & PLL_EN)
return 1;
return 0;
}
static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv4 *pll = to_clk_pllv4(hw);
u32 div;
div = readl_relaxed(pll->base + PLL_CFG_OFFSET);
div &= BM_PLL_MULT;
div >>= BP_PLL_MULT;
return parent_rate * div;
}
static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
unsigned long round_rate, i;
for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
round_rate = parent_rate * pllv4_mult_table[i];
if (rate >= round_rate)
return round_rate;
}
return round_rate;
}
static bool clk_pllv4_is_valid_mult(unsigned int mult)
{
int i;
/* check if mult is in valid MULT table */
for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
if (pllv4_mult_table[i] == mult)
return true;
}
return false;
}
static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv4 *pll = to_clk_pllv4(hw);
u32 val, mult;
mult = rate / parent_rate;
if (!clk_pllv4_is_valid_mult(mult))
return -EINVAL;
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);
return 0;
}
static int clk_pllv4_enable(struct clk_hw *hw)
{
u32 val;
struct clk_pllv4 *pll = to_clk_pllv4(hw);
val = readl_relaxed(pll->base);
val |= PLL_EN;
writel_relaxed(val, pll->base);
return clk_pllv4_wait_lock(pll);
}
static void clk_pllv4_disable(struct clk_hw *hw)
{
u32 val;
struct clk_pllv4 *pll = to_clk_pllv4(hw);
val = readl_relaxed(pll->base);
val &= ~PLL_EN;
writel_relaxed(val, pll->base);
}
static const struct clk_ops clk_pllv4_ops = {
.recalc_rate = clk_pllv4_recalc_rate,
.round_rate = clk_pllv4_round_rate,
.set_rate = clk_pllv4_set_rate,
.enable = clk_pllv4_enable,
.disable = clk_pllv4_disable,
.is_enabled = clk_pllv4_is_enabled,
};
struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
void __iomem *base)
{
struct clk_pllv4 *pll;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
pll->base = base;
init.name = name;
init.ops = &clk_pllv4_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE;
pll->hw.init = &init;
hw = &pll->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(pll);
hw = ERR_PTR(ret);
}
return hw;
}
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright 2018 NXP.
*
* This driver supports the SCCG plls found in the imx8m SOCs
*
* Documentation for this SCCG pll can be found at:
* https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf#page=834
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include <linux/bitfield.h>
#include "clk.h"
/* PLL CFGs */
#define PLL_CFG0 0x0
#define PLL_CFG1 0x4
#define PLL_CFG2 0x8
#define PLL_DIVF1_MASK GENMASK(18, 13)
#define PLL_DIVF2_MASK GENMASK(12, 7)
#define PLL_DIVR1_MASK GENMASK(27, 25)
#define PLL_DIVR2_MASK GENMASK(24, 19)
#define PLL_REF_MASK GENMASK(2, 0)
#define PLL_LOCK_MASK BIT(31)
#define PLL_PD_MASK BIT(7)
#define OSC_25M 25000000
#define OSC_27M 27000000
#define PLL_SCCG_LOCK_TIMEOUT 70
struct clk_sccg_pll {
struct clk_hw hw;
void __iomem *base;
};
#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
static int clk_pll_wait_lock(struct clk_sccg_pll *pll)
{
u32 val;
return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK, 0,
PLL_SCCG_LOCK_TIMEOUT);
}
static int clk_pll1_is_prepared(struct clk_hw *hw)
{
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
u32 val;
val = readl_relaxed(pll->base + PLL_CFG0);
return (val & PLL_PD_MASK) ? 0 : 1;
}
static unsigned long clk_pll1_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
u32 val, divf;
val = readl_relaxed(pll->base + PLL_CFG2);
divf = FIELD_GET(PLL_DIVF1_MASK, val);
return parent_rate * 2 * (divf + 1);
}
static long clk_pll1_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
u32 div;
if (!parent_rate)
return 0;
div = rate / (parent_rate * 2);
return parent_rate * div * 2;
}
static int clk_pll1_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
u32 val;
u32 divf;
if (!parent_rate)
return -EINVAL;
divf = rate / (parent_rate * 2);
val = readl_relaxed(pll->base + PLL_CFG2);
val &= ~PLL_DIVF1_MASK;
val |= FIELD_PREP(PLL_DIVF1_MASK, divf - 1);
writel_relaxed(val, pll->base + PLL_CFG2);
return clk_pll_wait_lock(pll);
}
static int clk_pll1_prepare(struct clk_hw *hw)
{
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
u32 val;
val = readl_relaxed(pll->base + PLL_CFG0);
val &= ~PLL_PD_MASK;
writel_relaxed(val, pll->base + PLL_CFG0);
return clk_pll_wait_lock(pll);
}
static void clk_pll1_unprepare(struct clk_hw *hw)
{
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
u32 val;
val = readl_relaxed(pll->base + PLL_CFG0);
val |= PLL_PD_MASK;
writel_relaxed(val, pll->base + PLL_CFG0);
}
static unsigned long clk_pll2_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
u32 val, ref, divr1, divf1, divr2, divf2;
u64 temp64;
val = readl_relaxed(pll->base + PLL_CFG0);
switch (FIELD_GET(PLL_REF_MASK, val)) {
case 0:
ref = OSC_25M;
break;
case 1:
ref = OSC_27M;
break;
default:
ref = OSC_25M;
break;
}
val = readl_relaxed(pll->base + PLL_CFG2);
divr1 = FIELD_GET(PLL_DIVR1_MASK, val);
divr2 = FIELD_GET(PLL_DIVR2_MASK, val);
divf1 = FIELD_GET(PLL_DIVF1_MASK, val);
divf2 = FIELD_GET(PLL_DIVF2_MASK, val);
temp64 = ref * 2;
temp64 *= (divf1 + 1) * (divf2 + 1);
do_div(temp64, (divr1 + 1) * (divr2 + 1));
return temp64;
}
static long clk_pll2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
u32 div;
unsigned long parent_rate = *prate;
if (!parent_rate)
return 0;
div = rate / parent_rate;
return parent_rate * div;
}
static int clk_pll2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
u32 val;
u32 divf;
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
if (!parent_rate)
return -EINVAL;
divf = rate / parent_rate;
val = readl_relaxed(pll->base + PLL_CFG2);
val &= ~PLL_DIVF2_MASK;
val |= FIELD_PREP(PLL_DIVF2_MASK, divf - 1);
writel_relaxed(val, pll->base + PLL_CFG2);
return clk_pll_wait_lock(pll);
}
static const struct clk_ops clk_sccg_pll1_ops = {
.is_prepared = clk_pll1_is_prepared,
.recalc_rate = clk_pll1_recalc_rate,
.round_rate = clk_pll1_round_rate,
.set_rate = clk_pll1_set_rate,
};
static const struct clk_ops clk_sccg_pll2_ops = {
.prepare = clk_pll1_prepare,
.unprepare = clk_pll1_unprepare,
.recalc_rate = clk_pll2_recalc_rate,
.round_rate = clk_pll2_round_rate,
.set_rate = clk_pll2_set_rate,
};
struct clk *imx_clk_sccg_pll(const char *name,
const char *parent_name,
void __iomem *base,
enum imx_sccg_pll_type pll_type)
{
struct clk_sccg_pll *pll;
struct clk_init_data init;
struct clk_hw *hw;
int ret;
switch (pll_type) {
case SCCG_PLL1:
init.ops = &clk_sccg_pll1_ops;
break;
case SCCG_PLL2:
init.ops = &clk_sccg_pll2_ops;
break;
default:
return ERR_PTR(-EINVAL);
}
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
init.name = name;
init.flags = 0;
init.parent_names = &parent_name;
init.num_parents = 1;
pll->base = base;
pll->hw.init = &init;
hw = &pll->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(pll);
return ERR_PTR(ret);
}
return hw->clk;
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/slab.h>
#include "clk-scu.h"
static struct imx_sc_ipc *ccm_ipc_handle;
/*
* struct clk_scu - Description of one SCU clock
* @hw: the common clk_hw
* @rsrc_id: resource ID of this SCU clock
* @clk_type: type of this clock resource
*/
struct clk_scu {
struct clk_hw hw;
u16 rsrc_id;
u8 clk_type;
};
/*
* struct imx_sc_msg_req_set_clock_rate - clock set rate protocol
* @hdr: SCU protocol header
* @rate: rate to set
* @resource: clock resource to set rate
* @clk: clk type of this resource
*
* This structure describes the SCU protocol of clock rate set
*/
struct imx_sc_msg_req_set_clock_rate {
struct imx_sc_rpc_msg hdr;
__le32 rate;
__le16 resource;
u8 clk;
} __packed;
struct req_get_clock_rate {
__le16 resource;
u8 clk;
} __packed;
struct resp_get_clock_rate {
__le32 rate;
};
/*
* struct imx_sc_msg_get_clock_rate - clock get rate protocol
* @hdr: SCU protocol header
* @req: get rate request protocol
* @resp: get rate response protocol
*
* This structure describes the SCU protocol of clock rate get
*/
struct imx_sc_msg_get_clock_rate {
struct imx_sc_rpc_msg hdr;
union {
struct req_get_clock_rate req;
struct resp_get_clock_rate resp;
} data;
};
/*
* struct imx_sc_msg_req_clock_enable - clock gate protocol
* @hdr: SCU protocol header
* @resource: clock resource to gate
* @clk: clk type of this resource
* @enable: whether gate off the clock
* @autog: HW auto gate enable
*
* This structure describes the SCU protocol of clock gate
*/
struct imx_sc_msg_req_clock_enable {
struct imx_sc_rpc_msg hdr;
__le16 resource;
u8 clk;
u8 enable;
u8 autog;
} __packed;
static inline struct clk_scu *to_clk_scu(struct clk_hw *hw)
{
return container_of(hw, struct clk_scu, hw);
}
int imx_clk_scu_init(void)
{
return imx_scu_get_handle(&ccm_ipc_handle);
}
/*
* clk_scu_recalc_rate - Get clock rate for a SCU clock
* @hw: clock to get rate for
* @parent_rate: parent rate provided by common clock framework, not used
*
* Gets the current clock rate of a SCU clock. Returns the current
* clock rate, or zero in failure.
*/
static unsigned long clk_scu_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_scu *clk = to_clk_scu(hw);
struct imx_sc_msg_get_clock_rate msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
int ret;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_PM;
hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_RATE;
hdr->size = 2;
msg.data.req.resource = cpu_to_le16(clk->rsrc_id);
msg.data.req.clk = clk->clk_type;
ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
if (ret) {
pr_err("%s: failed to get clock rate %d\n",
clk_hw_get_name(hw), ret);
return 0;
}
return le32_to_cpu(msg.data.resp.rate);
}
/*
* clk_scu_round_rate - Round clock rate for a SCU clock
* @hw: clock to round rate for
* @rate: rate to round
* @parent_rate: parent rate provided by common clock framework, not used
*
* Returns the current clock rate, or zero in failure.
*/
static long clk_scu_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
/*
* Assume we support all the requested rate and let the SCU firmware
* to handle the left work
*/
return rate;
}
/*
* clk_scu_set_rate - Set rate for a SCU clock
* @hw: clock to change rate for
* @rate: target rate for the clock
* @parent_rate: rate of the clock parent, not used for SCU clocks
*
* Sets a clock frequency for a SCU clock. Returns the SCU
* protocol status.
*/
static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_scu *clk = to_clk_scu(hw);
struct imx_sc_msg_req_set_clock_rate msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_PM;
hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_RATE;
hdr->size = 3;
msg.rate = cpu_to_le32(rate);
msg.resource = cpu_to_le16(clk->rsrc_id);
msg.clk = clk->clk_type;
return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
}
static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource,
u8 clk, bool enable, bool autog)
{
struct imx_sc_msg_req_clock_enable msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_PM;
hdr->func = IMX_SC_PM_FUNC_CLOCK_ENABLE;
hdr->size = 3;
msg.resource = cpu_to_le16(resource);
msg.clk = clk;
msg.enable = enable;
msg.autog = autog;
return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
}
/*
* clk_scu_prepare - Enable a SCU clock
* @hw: clock to enable
*
* Enable the clock at the DSC slice level
*/
static int clk_scu_prepare(struct clk_hw *hw)
{
struct clk_scu *clk = to_clk_scu(hw);
return sc_pm_clock_enable(ccm_ipc_handle, clk->rsrc_id,
clk->clk_type, true, false);
}
/*
* clk_scu_unprepare - Disable a SCU clock
* @hw: clock to enable
*
* Disable the clock at the DSC slice level
*/
static void clk_scu_unprepare(struct clk_hw *hw)
{
struct clk_scu *clk = to_clk_scu(hw);
int ret;
ret = sc_pm_clock_enable(ccm_ipc_handle, clk->rsrc_id,
clk->clk_type, false, false);
if (ret)
pr_warn("%s: clk unprepare failed %d\n", clk_hw_get_name(hw),
ret);
}
static const struct clk_ops clk_scu_ops = {
.recalc_rate = clk_scu_recalc_rate,
.round_rate = clk_scu_round_rate,
.set_rate = clk_scu_set_rate,
.prepare = clk_scu_prepare,
.unprepare = clk_scu_unprepare,
};
struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type)
{
struct clk_init_data init;
struct clk_scu *clk;
struct clk_hw *hw;
int ret;
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk)
return ERR_PTR(-ENOMEM);
clk->rsrc_id = rsrc_id;
clk->clk_type = clk_type;
init.name = name;
init.ops = &clk_scu_ops;
init.num_parents = 0;
/*
* Note on MX8, the clocks are tightly coupled with power domain
* that once the power domain is off, the clock status may be
* lost. So we make it NOCACHE to let user to retrieve the real
* clock status from HW instead of using the possible invalid
* cached rate.
*/
init.flags = CLK_GET_RATE_NOCACHE;
clk->hw.init = &init;
hw = &clk->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
kfree(clk);
hw = ERR_PTR(ret);
}
return hw;
}
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#ifndef __IMX_CLK_SCU_H
#define __IMX_CLK_SCU_H
#include <linux/firmware/imx/sci.h>
int imx_clk_scu_init(void);
struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type);
struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg,
u8 bit_idx, bool hw_gate);
#endif
...@@ -18,6 +18,16 @@ void __init imx_check_clocks(struct clk *clks[], unsigned int count) ...@@ -18,6 +18,16 @@ void __init imx_check_clocks(struct clk *clks[], unsigned int count)
i, PTR_ERR(clks[i])); i, PTR_ERR(clks[i]));
} }
void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count)
{
unsigned int i;
for (i = 0; i < count; i++)
if (IS_ERR(clks[i]))
pr_err("i.MX clk %u: register failed with %ld\n",
i, PTR_ERR(clks[i]));
}
static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
{ {
struct of_phandle_args phandle; struct of_phandle_args phandle;
...@@ -49,6 +59,18 @@ struct clk * __init imx_obtain_fixed_clock( ...@@ -49,6 +59,18 @@ struct clk * __init imx_obtain_fixed_clock(
return clk; return clk;
} }
struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np,
const char *name)
{
struct clk *clk;
clk = of_clk_get_by_name(np, name);
if (IS_ERR(clk))
return ERR_PTR(-ENOENT);
return __clk_get_hw(clk);
}
/* /*
* This fixups the register CCM_CSCMR1 write value. * This fixups the register CCM_CSCMR1 write value.
* The write/read/divider values of the aclk_podf field * The write/read/divider values of the aclk_podf field
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
extern spinlock_t imx_ccm_lock; extern spinlock_t imx_ccm_lock;
void imx_check_clocks(struct clk *clks[], unsigned int count); void imx_check_clocks(struct clk *clks[], unsigned int count);
void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
void imx_register_uart_clocks(struct clk ** const clks[]); void imx_register_uart_clocks(struct clk ** const clks[]);
extern void imx_cscmr1_fixup(u32 *val); extern void imx_cscmr1_fixup(u32 *val);
...@@ -21,12 +22,24 @@ enum imx_pllv1_type { ...@@ -21,12 +22,24 @@ enum imx_pllv1_type {
IMX_PLLV1_IMX35, IMX_PLLV1_IMX35,
}; };
enum imx_sccg_pll_type {
SCCG_PLL1,
SCCG_PLL2,
};
struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
const char *parent, void __iomem *base); const char *parent, void __iomem *base);
struct clk *imx_clk_pllv2(const char *name, const char *parent, struct clk *imx_clk_pllv2(const char *name, const char *parent,
void __iomem *base); void __iomem *base);
struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
void __iomem *base);
struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name,
void __iomem *base,
enum imx_sccg_pll_type pll_type);
enum imx_pllv3_type { enum imx_pllv3_type {
IMX_PLLV3_GENERIC, IMX_PLLV3_GENERIC,
IMX_PLLV3_SYS, IMX_PLLV3_SYS,
...@@ -42,6 +55,9 @@ enum imx_pllv3_type { ...@@ -42,6 +55,9 @@ enum imx_pllv3_type {
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent_name, void __iomem *base, u32 div_mask); const char *parent_name, void __iomem *base, u32 div_mask);
struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
void __iomem *base);
struct clk *clk_register_gate2(struct device *dev, const char *name, struct clk *clk_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx, u8 cgr_val, void __iomem *reg, u8 bit_idx, u8 cgr_val,
...@@ -51,26 +67,38 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, ...@@ -51,26 +67,38 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
struct clk * imx_obtain_fixed_clock( struct clk * imx_obtain_fixed_clock(
const char *name, unsigned long rate); const char *name, unsigned long rate);
struct clk_hw *imx_obtain_fixed_clk_hw(struct device_node *np,
const char *name);
struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
void __iomem *reg, u8 shift, u32 exclusive_mask); void __iomem *reg, u8 shift, u32 exclusive_mask);
struct clk *imx_clk_pfd(const char *name, const char *parent_name, struct clk *imx_clk_pfd(const char *name, const char *parent_name,
void __iomem *reg, u8 idx); void __iomem *reg, u8 idx);
struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
void __iomem *reg, u8 idx);
struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
void __iomem *reg, u8 shift, u8 width, void __iomem *reg, u8 shift, u8 width,
void __iomem *busy_reg, u8 busy_shift); void __iomem *busy_reg, u8 busy_shift);
struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
u8 width, void __iomem *busy_reg, u8 busy_shift, u8 width, void __iomem *busy_reg, u8 busy_shift,
const char **parent_names, int num_parents); const char * const *parent_names, int num_parents);
struct clk_hw *imx7ulp_clk_composite(const char *name,
const char * const *parent_names,
int num_parents, bool mux_present,
bool rate_present, bool gate_present,
void __iomem *reg);
struct clk *imx_clk_fixup_divider(const char *name, const char *parent, struct clk *imx_clk_fixup_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width, void __iomem *reg, u8 shift, u8 width,
void (*fixup)(u32 *val)); void (*fixup)(u32 *val));
struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, u8 shift, u8 width, const char * const *parents,
int num_parents, void (*fixup)(u32 *val)); int num_parents, void (*fixup)(u32 *val));
static inline struct clk *imx_clk_fixed(const char *name, int rate) static inline struct clk *imx_clk_fixed(const char *name, int rate)
...@@ -78,8 +106,19 @@ static inline struct clk *imx_clk_fixed(const char *name, int rate) ...@@ -78,8 +106,19 @@ static inline struct clk *imx_clk_fixed(const char *name, int rate)
return clk_register_fixed_rate(NULL, name, NULL, 0, rate); return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
} }
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_get_clk_hw_fixed(const char *name, int rate)
{
return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
}
static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg, static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, int num_parents) u8 shift, u8 width, const char * const *parents,
int num_parents)
{ {
return clk_register_mux(NULL, name, parents, num_parents, return clk_register_mux(NULL, name, parents, num_parents,
CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg,
...@@ -100,6 +139,15 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent, ...@@ -100,6 +139,15 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
reg, shift, width, 0, &imx_ccm_lock); reg, shift, width, 0, &imx_ccm_lock);
} }
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 *imx_clk_divider_flags(const char *name, static inline struct clk *imx_clk_divider_flags(const char *name,
const char *parent, void __iomem *reg, u8 shift, u8 width, const char *parent, void __iomem *reg, u8 shift, u8 width,
unsigned long flags) unsigned long flags)
...@@ -108,6 +156,15 @@ static inline struct clk *imx_clk_divider_flags(const char *name, ...@@ -108,6 +156,15 @@ static inline struct clk *imx_clk_divider_flags(const char *name,
reg, shift, width, 0, &imx_ccm_lock); reg, shift, width, 0, &imx_ccm_lock);
} }
static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
const char *parent,
void __iomem *reg, u8 shift,
u8 width, unsigned long flags)
{
return clk_hw_register_divider(NULL, name, parent, flags,
reg, shift, width, 0, &imx_ccm_lock);
}
static inline struct clk *imx_clk_divider2(const char *name, const char *parent, static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width) void __iomem *reg, u8 shift, u8 width)
{ {
...@@ -116,6 +173,15 @@ static inline struct clk *imx_clk_divider2(const char *name, const char *parent, ...@@ -116,6 +173,15 @@ static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
reg, shift, width, 0, &imx_ccm_lock); 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 *imx_clk_gate(const char *name, const char *parent, static inline struct clk *imx_clk_gate(const char *name, const char *parent,
void __iomem *reg, u8 shift) void __iomem *reg, u8 shift)
{ {
...@@ -130,6 +196,13 @@ static inline struct clk *imx_clk_gate_flags(const char *name, const char *paren ...@@ -130,6 +196,13 @@ static inline struct clk *imx_clk_gate_flags(const char *name, const char *paren
shift, 0, &imx_ccm_lock); shift, 0, &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 *imx_clk_gate_dis(const char *name, const char *parent, static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
void __iomem *reg, u8 shift) void __iomem *reg, u8 shift)
{ {
...@@ -190,6 +263,15 @@ static inline struct clk *imx_clk_gate3(const char *name, const char *parent, ...@@ -190,6 +263,15 @@ static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
reg, shift, 0, &imx_ccm_lock); reg, shift, 0, &imx_ccm_lock);
} }
static inline struct clk *imx_clk_gate3_flags(const char *name,
const char *parent, void __iomem *reg, u8 shift,
unsigned long flags)
{
return clk_register_gate(NULL, name, parent,
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
reg, shift, 0, &imx_ccm_lock);
}
static inline struct clk *imx_clk_gate4(const char *name, const char *parent, static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
void __iomem *reg, u8 shift) void __iomem *reg, u8 shift)
{ {
...@@ -198,8 +280,18 @@ static inline struct clk *imx_clk_gate4(const char *name, const char *parent, ...@@ -198,8 +280,18 @@ static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
reg, shift, 0x3, 0, &imx_ccm_lock, NULL); reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
} }
static inline struct clk *imx_clk_gate4_flags(const char *name,
const char *parent, void __iomem *reg, u8 shift,
unsigned long flags)
{
return clk_register_gate2(NULL, name, parent,
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
}
static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, int num_parents) u8 shift, u8 width, const char * const *parents,
int num_parents)
{ {
return clk_register_mux(NULL, name, parents, num_parents, return clk_register_mux(NULL, name, parents, num_parents,
CLK_SET_RATE_NO_REPARENT, reg, shift, CLK_SET_RATE_NO_REPARENT, reg, shift,
...@@ -207,24 +299,78 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, ...@@ -207,24 +299,78 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
} }
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg, static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, int num_parents) u8 shift, u8 width, const char * const *parents,
int num_parents)
{ {
return clk_register_mux(NULL, name, parents, num_parents, return clk_register_mux(NULL, name, parents, num_parents,
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
reg, shift, width, 0, &imx_ccm_lock); 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, static inline struct clk *imx_clk_mux_flags(const char *name,
void __iomem *reg, u8 shift, u8 width, const char **parents, void __iomem *reg, u8 shift, u8 width,
int num_parents, unsigned long flags) const char * const *parents, int num_parents,
unsigned long flags)
{ {
return clk_register_mux(NULL, name, parents, num_parents, return clk_register_mux(NULL, name, parents, num_parents,
flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0, flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
&imx_ccm_lock); &imx_ccm_lock);
} }
static inline struct clk *imx_clk_mux2_flags(const char *name,
void __iomem *reg, u8 shift, u8 width, const char **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);
}
struct clk *imx_clk_cpu(const char *name, const char *parent_name, struct clk *imx_clk_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll, struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step); struct clk *step);
struct clk *imx8m_clk_composite_flags(const char *name,
const char **parent_names,
int num_parents, void __iomem *reg,
unsigned long flags);
#define __imx8m_clk_composite(name, parent_names, reg, flags) \
imx8m_clk_composite_flags(name, parent_names, \
ARRAY_SIZE(parent_names), reg, \
flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
#define imx8m_clk_composite(name, parent_names, reg) \
__imx8m_clk_composite(name, parent_names, reg, 0)
#define imx8m_clk_composite_critical(name, parent_names, reg) \
__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock);
#endif #endif
...@@ -274,6 +274,8 @@ ...@@ -274,6 +274,8 @@
#define IMX6QDL_CLK_EPIT1 261 #define IMX6QDL_CLK_EPIT1 261
#define IMX6QDL_CLK_EPIT2 262 #define IMX6QDL_CLK_EPIT2 262
#define IMX6QDL_CLK_MMDC_P0_IPG 263 #define IMX6QDL_CLK_MMDC_P0_IPG 263
#define IMX6QDL_CLK_END 264 #define IMX6QDL_CLK_DCIC1 264
#define IMX6QDL_CLK_DCIC2 265
#define IMX6QDL_CLK_END 266
#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017~2018 NXP
*
*/
#ifndef __DT_BINDINGS_CLOCK_IMX7ULP_H
#define __DT_BINDINGS_CLOCK_IMX7ULP_H
/* SCG1 */
#define IMX7ULP_CLK_DUMMY 0
#define IMX7ULP_CLK_ROSC 1
#define IMX7ULP_CLK_SOSC 2
#define IMX7ULP_CLK_FIRC 3
#define IMX7ULP_CLK_SPLL_PRE_SEL 4
#define IMX7ULP_CLK_SPLL_PRE_DIV 5
#define IMX7ULP_CLK_SPLL 6
#define IMX7ULP_CLK_SPLL_POST_DIV1 7
#define IMX7ULP_CLK_SPLL_POST_DIV2 8
#define IMX7ULP_CLK_SPLL_PFD0 9
#define IMX7ULP_CLK_SPLL_PFD1 10
#define IMX7ULP_CLK_SPLL_PFD2 11
#define IMX7ULP_CLK_SPLL_PFD3 12
#define IMX7ULP_CLK_SPLL_PFD_SEL 13
#define IMX7ULP_CLK_SPLL_SEL 14
#define IMX7ULP_CLK_APLL_PRE_SEL 15
#define IMX7ULP_CLK_APLL_PRE_DIV 16
#define IMX7ULP_CLK_APLL 17
#define IMX7ULP_CLK_APLL_POST_DIV1 18
#define IMX7ULP_CLK_APLL_POST_DIV2 19
#define IMX7ULP_CLK_APLL_PFD0 20
#define IMX7ULP_CLK_APLL_PFD1 21
#define IMX7ULP_CLK_APLL_PFD2 22
#define IMX7ULP_CLK_APLL_PFD3 23
#define IMX7ULP_CLK_APLL_PFD_SEL 24
#define IMX7ULP_CLK_APLL_SEL 25
#define IMX7ULP_CLK_UPLL 26
#define IMX7ULP_CLK_SYS_SEL 27
#define IMX7ULP_CLK_CORE_DIV 28
#define IMX7ULP_CLK_BUS_DIV 29
#define IMX7ULP_CLK_PLAT_DIV 30
#define IMX7ULP_CLK_DDR_SEL 31
#define IMX7ULP_CLK_DDR_DIV 32
#define IMX7ULP_CLK_NIC_SEL 33
#define IMX7ULP_CLK_NIC0_DIV 34
#define IMX7ULP_CLK_GPU_DIV 35
#define IMX7ULP_CLK_NIC1_DIV 36
#define IMX7ULP_CLK_NIC1_BUS_DIV 37
#define IMX7ULP_CLK_NIC1_EXT_DIV 38
#define IMX7ULP_CLK_MIPI_PLL 39
#define IMX7ULP_CLK_SIRC 40
#define IMX7ULP_CLK_SOSC_BUS_CLK 41
#define IMX7ULP_CLK_FIRC_BUS_CLK 42
#define IMX7ULP_CLK_SPLL_BUS_CLK 43
#define IMX7ULP_CLK_SCG1_END 44
/* PCC2 */
#define IMX7ULP_CLK_DMA1 0
#define IMX7ULP_CLK_RGPIO2P1 1
#define IMX7ULP_CLK_FLEXBUS 2
#define IMX7ULP_CLK_SEMA42_1 3
#define IMX7ULP_CLK_DMA_MUX1 4
#define IMX7ULP_CLK_SNVS 5
#define IMX7ULP_CLK_CAAM 6
#define IMX7ULP_CLK_LPTPM4 7
#define IMX7ULP_CLK_LPTPM5 8
#define IMX7ULP_CLK_LPIT1 9
#define IMX7ULP_CLK_LPSPI2 10
#define IMX7ULP_CLK_LPSPI3 11
#define IMX7ULP_CLK_LPI2C4 12
#define IMX7ULP_CLK_LPI2C5 13
#define IMX7ULP_CLK_LPUART4 14
#define IMX7ULP_CLK_LPUART5 15
#define IMX7ULP_CLK_FLEXIO1 16
#define IMX7ULP_CLK_USB0 17
#define IMX7ULP_CLK_USB1 18
#define IMX7ULP_CLK_USB_PHY 19
#define IMX7ULP_CLK_USB_PL301 20
#define IMX7ULP_CLK_USDHC0 21
#define IMX7ULP_CLK_USDHC1 22
#define IMX7ULP_CLK_WDG1 23
#define IMX7ULP_CLK_WDG2 24
#define IMX7ULP_CLK_PCC2_END 25
/* PCC3 */
#define IMX7ULP_CLK_LPTPM6 0
#define IMX7ULP_CLK_LPTPM7 1
#define IMX7ULP_CLK_LPI2C6 2
#define IMX7ULP_CLK_LPI2C7 3
#define IMX7ULP_CLK_LPUART6 4
#define IMX7ULP_CLK_LPUART7 5
#define IMX7ULP_CLK_VIU 6
#define IMX7ULP_CLK_DSI 7
#define IMX7ULP_CLK_LCDIF 8
#define IMX7ULP_CLK_MMDC 9
#define IMX7ULP_CLK_PCTLC 10
#define IMX7ULP_CLK_PCTLD 11
#define IMX7ULP_CLK_PCTLE 12
#define IMX7ULP_CLK_PCTLF 13
#define IMX7ULP_CLK_GPU3D 14
#define IMX7ULP_CLK_GPU2D 15
#define IMX7ULP_CLK_PCC3_END 16
#endif /* __DT_BINDINGS_CLOCK_IMX7ULP_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
*/
#ifndef __DT_BINDINGS_CLOCK_IMX8MQ_H
#define __DT_BINDINGS_CLOCK_IMX8MQ_H
#define IMX8MQ_CLK_DUMMY 0
#define IMX8MQ_CLK_32K 1
#define IMX8MQ_CLK_25M 2
#define IMX8MQ_CLK_27M 3
#define IMX8MQ_CLK_EXT1 4
#define IMX8MQ_CLK_EXT2 5
#define IMX8MQ_CLK_EXT3 6
#define IMX8MQ_CLK_EXT4 7
/* ANAMIX PLL clocks */
/* FRAC PLLs */
/* ARM PLL */
#define IMX8MQ_ARM_PLL_REF_SEL 8
#define IMX8MQ_ARM_PLL_REF_DIV 9
#define IMX8MQ_ARM_PLL 10
#define IMX8MQ_ARM_PLL_BYPASS 11
#define IMX8MQ_ARM_PLL_OUT 12
/* GPU PLL */
#define IMX8MQ_GPU_PLL_REF_SEL 13
#define IMX8MQ_GPU_PLL_REF_DIV 14
#define IMX8MQ_GPU_PLL 15
#define IMX8MQ_GPU_PLL_BYPASS 16
#define IMX8MQ_GPU_PLL_OUT 17
/* VPU PLL */
#define IMX8MQ_VPU_PLL_REF_SEL 18
#define IMX8MQ_VPU_PLL_REF_DIV 19
#define IMX8MQ_VPU_PLL 20
#define IMX8MQ_VPU_PLL_BYPASS 21
#define IMX8MQ_VPU_PLL_OUT 22
/* AUDIO PLL1 */
#define IMX8MQ_AUDIO_PLL1_REF_SEL 23
#define IMX8MQ_AUDIO_PLL1_REF_DIV 24
#define IMX8MQ_AUDIO_PLL1 25
#define IMX8MQ_AUDIO_PLL1_BYPASS 26
#define IMX8MQ_AUDIO_PLL1_OUT 27
/* AUDIO PLL2 */
#define IMX8MQ_AUDIO_PLL2_REF_SEL 28
#define IMX8MQ_AUDIO_PLL2_REF_DIV 29
#define IMX8MQ_AUDIO_PLL2 30
#define IMX8MQ_AUDIO_PLL2_BYPASS 31
#define IMX8MQ_AUDIO_PLL2_OUT 32
/* VIDEO PLL1 */
#define IMX8MQ_VIDEO_PLL1_REF_SEL 33
#define IMX8MQ_VIDEO_PLL1_REF_DIV 34
#define IMX8MQ_VIDEO_PLL1 35
#define IMX8MQ_VIDEO_PLL1_BYPASS 36
#define IMX8MQ_VIDEO_PLL1_OUT 37
/* SYS1 PLL */
#define IMX8MQ_SYS1_PLL1_REF_SEL 38
#define IMX8MQ_SYS1_PLL1_REF_DIV 39
#define IMX8MQ_SYS1_PLL1 40
#define IMX8MQ_SYS1_PLL1_OUT 41
#define IMX8MQ_SYS1_PLL1_OUT_DIV 42
#define IMX8MQ_SYS1_PLL2 43
#define IMX8MQ_SYS1_PLL2_DIV 44
#define IMX8MQ_SYS1_PLL2_OUT 45
/* SYS2 PLL */
#define IMX8MQ_SYS2_PLL1_REF_SEL 46
#define IMX8MQ_SYS2_PLL1_REF_DIV 47
#define IMX8MQ_SYS2_PLL1 48
#define IMX8MQ_SYS2_PLL1_OUT 49
#define IMX8MQ_SYS2_PLL1_OUT_DIV 50
#define IMX8MQ_SYS2_PLL2 51
#define IMX8MQ_SYS2_PLL2_DIV 52
#define IMX8MQ_SYS2_PLL2_OUT 53
/* SYS3 PLL */
#define IMX8MQ_SYS3_PLL1_REF_SEL 54
#define IMX8MQ_SYS3_PLL1_REF_DIV 55
#define IMX8MQ_SYS3_PLL1 56
#define IMX8MQ_SYS3_PLL1_OUT 57
#define IMX8MQ_SYS3_PLL1_OUT_DIV 58
#define IMX8MQ_SYS3_PLL2 59
#define IMX8MQ_SYS3_PLL2_DIV 60
#define IMX8MQ_SYS3_PLL2_OUT 61
/* DRAM PLL */
#define IMX8MQ_DRAM_PLL1_REF_SEL 62
#define IMX8MQ_DRAM_PLL1_REF_DIV 63
#define IMX8MQ_DRAM_PLL1 64
#define IMX8MQ_DRAM_PLL1_OUT 65
#define IMX8MQ_DRAM_PLL1_OUT_DIV 66
#define IMX8MQ_DRAM_PLL2 67
#define IMX8MQ_DRAM_PLL2_DIV 68
#define IMX8MQ_DRAM_PLL2_OUT 69
/* SYS PLL DIV */
#define IMX8MQ_SYS1_PLL_40M 70
#define IMX8MQ_SYS1_PLL_80M 71
#define IMX8MQ_SYS1_PLL_100M 72
#define IMX8MQ_SYS1_PLL_133M 73
#define IMX8MQ_SYS1_PLL_160M 74
#define IMX8MQ_SYS1_PLL_200M 75
#define IMX8MQ_SYS1_PLL_266M 76
#define IMX8MQ_SYS1_PLL_400M 77
#define IMX8MQ_SYS1_PLL_800M 78
#define IMX8MQ_SYS2_PLL_50M 79
#define IMX8MQ_SYS2_PLL_100M 80
#define IMX8MQ_SYS2_PLL_125M 81
#define IMX8MQ_SYS2_PLL_166M 82
#define IMX8MQ_SYS2_PLL_200M 83
#define IMX8MQ_SYS2_PLL_250M 84
#define IMX8MQ_SYS2_PLL_333M 85
#define IMX8MQ_SYS2_PLL_500M 86
#define IMX8MQ_SYS2_PLL_1000M 87
/* CCM ROOT clocks */
/* A53 */
#define IMX8MQ_CLK_A53_SRC 88
#define IMX8MQ_CLK_A53_CG 89
#define IMX8MQ_CLK_A53_DIV 90
/* M4 */
#define IMX8MQ_CLK_M4_SRC 91
#define IMX8MQ_CLK_M4_CG 92
#define IMX8MQ_CLK_M4_DIV 93
/* VPU */
#define IMX8MQ_CLK_VPU_SRC 94
#define IMX8MQ_CLK_VPU_CG 95
#define IMX8MQ_CLK_VPU_DIV 96
/* GPU CORE */
#define IMX8MQ_CLK_GPU_CORE_SRC 97
#define IMX8MQ_CLK_GPU_CORE_CG 98
#define IMX8MQ_CLK_GPU_CORE_DIV 99
/* GPU SHADER */
#define IMX8MQ_CLK_GPU_SHADER_SRC 100
#define IMX8MQ_CLK_GPU_SHADER_CG 101
#define IMX8MQ_CLK_GPU_SHADER_DIV 102
/* BUS TYPE */
/* MAIN AXI */
#define IMX8MQ_CLK_MAIN_AXI 103
/* ENET AXI */
#define IMX8MQ_CLK_ENET_AXI 104
/* NAND_USDHC_BUS */
#define IMX8MQ_CLK_NAND_USDHC_BUS 105
/* VPU BUS */
#define IMX8MQ_CLK_VPU_BUS 106
/* DISP_AXI */
#define IMX8MQ_CLK_DISP_AXI 107
/* DISP APB */
#define IMX8MQ_CLK_DISP_APB 108
/* DISP RTRM */
#define IMX8MQ_CLK_DISP_RTRM 109
/* USB_BUS */
#define IMX8MQ_CLK_USB_BUS 110
/* GPU_AXI */
#define IMX8MQ_CLK_GPU_AXI 111
/* GPU_AHB */
#define IMX8MQ_CLK_GPU_AHB 112
/* NOC */
#define IMX8MQ_CLK_NOC 113
/* NOC_APB */
#define IMX8MQ_CLK_NOC_APB 115
/* AHB */
#define IMX8MQ_CLK_AHB 116
/* AUDIO AHB */
#define IMX8MQ_CLK_AUDIO_AHB 117
/* DRAM_ALT */
#define IMX8MQ_CLK_DRAM_ALT 118
/* DRAM APB */
#define IMX8MQ_CLK_DRAM_APB 119
/* VPU_G1 */
#define IMX8MQ_CLK_VPU_G1 120
/* VPU_G2 */
#define IMX8MQ_CLK_VPU_G2 121
/* DISP_DTRC */
#define IMX8MQ_CLK_DISP_DTRC 122
/* DISP_DC8000 */
#define IMX8MQ_CLK_DISP_DC8000 123
/* PCIE_CTRL */
#define IMX8MQ_CLK_PCIE1_CTRL 124
/* PCIE_PHY */
#define IMX8MQ_CLK_PCIE1_PHY 125
/* PCIE_AUX */
#define IMX8MQ_CLK_PCIE1_AUX 126
/* DC_PIXEL */
#define IMX8MQ_CLK_DC_PIXEL 127
/* LCDIF_PIXEL */
#define IMX8MQ_CLK_LCDIF_PIXEL 128
/* SAI1~6 */
#define IMX8MQ_CLK_SAI1 129
#define IMX8MQ_CLK_SAI2 130
#define IMX8MQ_CLK_SAI3 131
#define IMX8MQ_CLK_SAI4 132
#define IMX8MQ_CLK_SAI5 133
#define IMX8MQ_CLK_SAI6 134
/* SPDIF1 */
#define IMX8MQ_CLK_SPDIF1 135
/* SPDIF2 */
#define IMX8MQ_CLK_SPDIF2 136
/* ENET_REF */
#define IMX8MQ_CLK_ENET_REF 137
/* ENET_TIMER */
#define IMX8MQ_CLK_ENET_TIMER 138
/* ENET_PHY */
#define IMX8MQ_CLK_ENET_PHY_REF 139
/* NAND */
#define IMX8MQ_CLK_NAND 140
/* QSPI */
#define IMX8MQ_CLK_QSPI 141
/* USDHC1 */
#define IMX8MQ_CLK_USDHC1 142
/* USDHC2 */
#define IMX8MQ_CLK_USDHC2 143
/* I2C1 */
#define IMX8MQ_CLK_I2C1 144
/* I2C2 */
#define IMX8MQ_CLK_I2C2 145
/* I2C3 */
#define IMX8MQ_CLK_I2C3 146
/* I2C4 */
#define IMX8MQ_CLK_I2C4 147
/* UART1 */
#define IMX8MQ_CLK_UART1 148
/* UART2 */
#define IMX8MQ_CLK_UART2 149
/* UART3 */
#define IMX8MQ_CLK_UART3 150
/* UART4 */
#define IMX8MQ_CLK_UART4 151
/* USB_CORE_REF */
#define IMX8MQ_CLK_USB_CORE_REF 152
/* USB_PHY_REF */
#define IMX8MQ_CLK_USB_PHY_REF 163
/* ECSPI1 */
#define IMX8MQ_CLK_ECSPI1 164
/* ECSPI2 */
#define IMX8MQ_CLK_ECSPI2 165
/* PWM1 */
#define IMX8MQ_CLK_PWM1 166
/* PWM2 */
#define IMX8MQ_CLK_PWM2 167
/* PWM3 */
#define IMX8MQ_CLK_PWM3 168
/* PWM4 */
#define IMX8MQ_CLK_PWM4 169
/* GPT1 */
#define IMX8MQ_CLK_GPT1 170
/* WDOG */
#define IMX8MQ_CLK_WDOG 171
/* WRCLK */
#define IMX8MQ_CLK_WRCLK 172
/* DSI_CORE */
#define IMX8MQ_CLK_DSI_CORE 173
/* DSI_PHY */
#define IMX8MQ_CLK_DSI_PHY_REF 174
/* DSI_DBI */
#define IMX8MQ_CLK_DSI_DBI 175
/*DSI_ESC */
#define IMX8MQ_CLK_DSI_ESC 176
/* CSI1_CORE */
#define IMX8MQ_CLK_CSI1_CORE 177
/* CSI1_PHY */
#define IMX8MQ_CLK_CSI1_PHY_REF 178
/* CSI_ESC */
#define IMX8MQ_CLK_CSI1_ESC 179
/* CSI2_CORE */
#define IMX8MQ_CLK_CSI2_CORE 170
/* CSI2_PHY */
#define IMX8MQ_CLK_CSI2_PHY_REF 181
/* CSI2_ESC */
#define IMX8MQ_CLK_CSI2_ESC 182
/* PCIE2_CTRL */
#define IMX8MQ_CLK_PCIE2_CTRL 183
/* PCIE2_PHY */
#define IMX8MQ_CLK_PCIE2_PHY 184
/* PCIE2_AUX */
#define IMX8MQ_CLK_PCIE2_AUX 185
/* ECSPI3 */
#define IMX8MQ_CLK_ECSPI3 186
/* CCGR clocks */
#define IMX8MQ_CLK_A53_ROOT 187
#define IMX8MQ_CLK_DRAM_ROOT 188
#define IMX8MQ_CLK_ECSPI1_ROOT 189
#define IMX8MQ_CLK_ECSPI2_ROOT 180
#define IMX8MQ_CLK_ECSPI3_ROOT 181
#define IMX8MQ_CLK_ENET1_ROOT 182
#define IMX8MQ_CLK_GPT1_ROOT 193
#define IMX8MQ_CLK_I2C1_ROOT 194
#define IMX8MQ_CLK_I2C2_ROOT 195
#define IMX8MQ_CLK_I2C3_ROOT 196
#define IMX8MQ_CLK_I2C4_ROOT 197
#define IMX8MQ_CLK_M4_ROOT 198
#define IMX8MQ_CLK_PCIE1_ROOT 199
#define IMX8MQ_CLK_PCIE2_ROOT 200
#define IMX8MQ_CLK_PWM1_ROOT 201
#define IMX8MQ_CLK_PWM2_ROOT 202
#define IMX8MQ_CLK_PWM3_ROOT 203
#define IMX8MQ_CLK_PWM4_ROOT 204
#define IMX8MQ_CLK_QSPI_ROOT 205
#define IMX8MQ_CLK_SAI1_ROOT 206
#define IMX8MQ_CLK_SAI2_ROOT 207
#define IMX8MQ_CLK_SAI3_ROOT 208
#define IMX8MQ_CLK_SAI4_ROOT 209
#define IMX8MQ_CLK_SAI5_ROOT 210
#define IMX8MQ_CLK_SAI6_ROOT 212
#define IMX8MQ_CLK_UART1_ROOT 213
#define IMX8MQ_CLK_UART2_ROOT 214
#define IMX8MQ_CLK_UART3_ROOT 215
#define IMX8MQ_CLK_UART4_ROOT 216
#define IMX8MQ_CLK_USB1_CTRL_ROOT 217
#define IMX8MQ_CLK_USB2_CTRL_ROOT 218
#define IMX8MQ_CLK_USB1_PHY_ROOT 219
#define IMX8MQ_CLK_USB2_PHY_ROOT 220
#define IMX8MQ_CLK_USDHC1_ROOT 221
#define IMX8MQ_CLK_USDHC2_ROOT 222
#define IMX8MQ_CLK_WDOG1_ROOT 223
#define IMX8MQ_CLK_WDOG2_ROOT 224
#define IMX8MQ_CLK_WDOG3_ROOT 225
#define IMX8MQ_CLK_GPU_ROOT 226
#define IMX8MQ_CLK_HEVC_ROOT 227
#define IMX8MQ_CLK_AVC_ROOT 228
#define IMX8MQ_CLK_VP9_ROOT 229
#define IMX8MQ_CLK_HEVC_INTER_ROOT 230
#define IMX8MQ_CLK_DISP_ROOT 231
#define IMX8MQ_CLK_HDMI_ROOT 232
#define IMX8MQ_CLK_HDMI_PHY_ROOT 233
#define IMX8MQ_CLK_VPU_DEC_ROOT 234
#define IMX8MQ_CLK_CSI1_ROOT 235
#define IMX8MQ_CLK_CSI2_ROOT 236
#define IMX8MQ_CLK_RAWNAND_ROOT 237
#define IMX8MQ_CLK_SDMA1_ROOT 238
#define IMX8MQ_CLK_SDMA2_ROOT 239
#define IMX8MQ_CLK_VPU_G1_ROOT 240
#define IMX8MQ_CLK_VPU_G2_ROOT 241
/* SCCG PLL GATE */
#define IMX8MQ_SYS1_PLL_OUT 232
#define IMX8MQ_SYS2_PLL_OUT 243
#define IMX8MQ_SYS3_PLL_OUT 244
#define IMX8MQ_DRAM_PLL_OUT 245
#define IMX8MQ_GPT_3M_CLK 246
#define IMX8MQ_CLK_IPG_ROOT 247
#define IMX8MQ_CLK_IPG_AUDIO_ROOT 248
#define IMX8MQ_CLK_SAI1_IPG 249
#define IMX8MQ_CLK_SAI2_IPG 250
#define IMX8MQ_CLK_SAI3_IPG 251
#define IMX8MQ_CLK_SAI4_IPG 252
#define IMX8MQ_CLK_SAI5_IPG 253
#define IMX8MQ_CLK_SAI6_IPG 254
/* DSI AHB/IPG clocks */
/* rxesc clock */
#define IMX8MQ_CLK_DSI_AHB 255
/* txesc clock */
#define IMX8MQ_CLK_DSI_IPG_DIV 256
#define IMX8MQ_CLK_TMU_ROOT 265
/* Display root clocks */
#define IMX8MQ_CLK_DISP_AXI_ROOT 266
#define IMX8MQ_CLK_DISP_APB_ROOT 267
#define IMX8MQ_CLK_DISP_RTRM_ROOT 268
#define IMX8MQ_CLK_OCOTP_ROOT 269
#define IMX8MQ_CLK_DRAM_ALT_ROOT 270
#define IMX8MQ_CLK_DRAM_CORE 271
#define IMX8MQ_CLK_MU_ROOT 272
#define IMX8MQ_VIDEO2_PLL_OUT 273
#define IMX8MQ_CLK_CLKO2 274
#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 275
#define IMX8MQ_CLK_END 276
#endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2018 NXP
* Dong Aisheng <aisheng.dong@nxp.com>
*/
#ifndef __DT_BINDINGS_CLOCK_IMX8QXP_H
#define __DT_BINDINGS_CLOCK_IMX8QXP_H
/* SCU Clocks */
#define IMX8QXP_CLK_DUMMY 0
/* CPU */
#define IMX8QXP_A35_CLK 1
/* LSIO SS */
#define IMX8QXP_LSIO_MEM_CLK 2
#define IMX8QXP_LSIO_BUS_CLK 3
#define IMX8QXP_LSIO_PWM0_CLK 10
#define IMX8QXP_LSIO_PWM1_CLK 11
#define IMX8QXP_LSIO_PWM2_CLK 12
#define IMX8QXP_LSIO_PWM3_CLK 13
#define IMX8QXP_LSIO_PWM4_CLK 14
#define IMX8QXP_LSIO_PWM5_CLK 15
#define IMX8QXP_LSIO_PWM6_CLK 16
#define IMX8QXP_LSIO_PWM7_CLK 17
#define IMX8QXP_LSIO_GPT0_CLK 18
#define IMX8QXP_LSIO_GPT1_CLK 19
#define IMX8QXP_LSIO_GPT2_CLK 20
#define IMX8QXP_LSIO_GPT3_CLK 21
#define IMX8QXP_LSIO_GPT4_CLK 22
#define IMX8QXP_LSIO_FSPI0_CLK 23
#define IMX8QXP_LSIO_FSPI1_CLK 24
/* Connectivity SS */
#define IMX8QXP_CONN_AXI_CLK_ROOT 30
#define IMX8QXP_CONN_AHB_CLK_ROOT 31
#define IMX8QXP_CONN_IPG_CLK_ROOT 32
#define IMX8QXP_CONN_SDHC0_CLK 40
#define IMX8QXP_CONN_SDHC1_CLK 41
#define IMX8QXP_CONN_SDHC2_CLK 42
#define IMX8QXP_CONN_ENET0_ROOT_CLK 43
#define IMX8QXP_CONN_ENET0_BYPASS_CLK 44
#define IMX8QXP_CONN_ENET0_RGMII_CLK 45
#define IMX8QXP_CONN_ENET1_ROOT_CLK 46
#define IMX8QXP_CONN_ENET1_BYPASS_CLK 47
#define IMX8QXP_CONN_ENET1_RGMII_CLK 48
#define IMX8QXP_CONN_GPMI_BCH_IO_CLK 49
#define IMX8QXP_CONN_GPMI_BCH_CLK 50
#define IMX8QXP_CONN_USB2_ACLK 51
#define IMX8QXP_CONN_USB2_BUS_CLK 52
#define IMX8QXP_CONN_USB2_LPM_CLK 53
/* HSIO SS */
#define IMX8QXP_HSIO_AXI_CLK 60
#define IMX8QXP_HSIO_PER_CLK 61
/* Display controller SS */
#define IMX8QXP_DC_AXI_EXT_CLK 70
#define IMX8QXP_DC_AXI_INT_CLK 71
#define IMX8QXP_DC_CFG_CLK 72
#define IMX8QXP_DC0_PLL0_CLK 80
#define IMX8QXP_DC0_PLL1_CLK 81
#define IMX8QXP_DC0_DISP0_CLK 82
#define IMX8QXP_DC0_DISP1_CLK 83
/* MIPI-LVDS SS */
#define IMX8QXP_MIPI_IPG_CLK 90
#define IMX8QXP_MIPI0_PIXEL_CLK 100
#define IMX8QXP_MIPI0_BYPASS_CLK 101
#define IMX8QXP_MIPI0_LVDS_PIXEL_CLK 102
#define IMX8QXP_MIPI0_LVDS_BYPASS_CLK 103
#define IMX8QXP_MIPI0_LVDS_PHY_CLK 104
#define IMX8QXP_MIPI0_I2C0_CLK 105
#define IMX8QXP_MIPI0_I2C1_CLK 106
#define IMX8QXP_MIPI0_PWM0_CLK 107
#define IMX8QXP_MIPI1_PIXEL_CLK 108
#define IMX8QXP_MIPI1_BYPASS_CLK 109
#define IMX8QXP_MIPI1_LVDS_PIXEL_CLK 110
#define IMX8QXP_MIPI1_LVDS_BYPASS_CLK 111
#define IMX8QXP_MIPI1_LVDS_PHY_CLK 112
#define IMX8QXP_MIPI1_I2C0_CLK 113
#define IMX8QXP_MIPI1_I2C1_CLK 114
#define IMX8QXP_MIPI1_PWM0_CLK 115
/* IMG SS */
#define IMX8QXP_IMG_AXI_CLK 120
#define IMX8QXP_IMG_IPG_CLK 121
#define IMX8QXP_IMG_PXL_CLK 122
/* MIPI-CSI SS */
#define IMX8QXP_CSI0_CORE_CLK 130
#define IMX8QXP_CSI0_ESC_CLK 131
#define IMX8QXP_CSI0_PWM0_CLK 132
#define IMX8QXP_CSI0_I2C0_CLK 133
/* PARALLER CSI SS */
#define IMX8QXP_PARALLEL_CSI_DPLL_CLK 140
#define IMX8QXP_PARALLEL_CSI_PIXEL_CLK 141
#define IMX8QXP_PARALLEL_CSI_MCLK_CLK 142
/* VPU SS */
#define IMX8QXP_VPU_ENC_CLK 150
#define IMX8QXP_VPU_DEC_CLK 151
/* GPU SS */
#define IMX8QXP_GPU0_CORE_CLK 160
#define IMX8QXP_GPU0_SHADER_CLK 161
/* ADMA SS */
#define IMX8QXP_ADMA_IPG_CLK_ROOT 165
#define IMX8QXP_ADMA_UART0_CLK 170
#define IMX8QXP_ADMA_UART1_CLK 171
#define IMX8QXP_ADMA_UART2_CLK 172
#define IMX8QXP_ADMA_UART3_CLK 173
#define IMX8QXP_ADMA_SPI0_CLK 174
#define IMX8QXP_ADMA_SPI1_CLK 175
#define IMX8QXP_ADMA_SPI2_CLK 176
#define IMX8QXP_ADMA_SPI3_CLK 177
#define IMX8QXP_ADMA_CAN0_CLK 178
#define IMX8QXP_ADMA_CAN1_CLK 179
#define IMX8QXP_ADMA_CAN2_CLK 180
#define IMX8QXP_ADMA_I2C0_CLK 181
#define IMX8QXP_ADMA_I2C1_CLK 182
#define IMX8QXP_ADMA_I2C2_CLK 183
#define IMX8QXP_ADMA_I2C3_CLK 184
#define IMX8QXP_ADMA_FTM0_CLK 185
#define IMX8QXP_ADMA_FTM1_CLK 186
#define IMX8QXP_ADMA_ADC0_CLK 187
#define IMX8QXP_ADMA_PWM_CLK 188
#define IMX8QXP_ADMA_LCD_CLK 189
#define IMX8QXP_SCU_CLK_END 190
/* LPCG clocks */
/* LSIO SS LPCG */
#define IMX8QXP_LSIO_LPCG_PWM0_IPG_CLK 0
#define IMX8QXP_LSIO_LPCG_PWM0_IPG_S_CLK 1
#define IMX8QXP_LSIO_LPCG_PWM0_IPG_HF_CLK 2
#define IMX8QXP_LSIO_LPCG_PWM0_IPG_SLV_CLK 3
#define IMX8QXP_LSIO_LPCG_PWM0_IPG_MSTR_CLK 4
#define IMX8QXP_LSIO_LPCG_PWM1_IPG_CLK 5
#define IMX8QXP_LSIO_LPCG_PWM1_IPG_S_CLK 6
#define IMX8QXP_LSIO_LPCG_PWM1_IPG_HF_CLK 7
#define IMX8QXP_LSIO_LPCG_PWM1_IPG_SLV_CLK 8
#define IMX8QXP_LSIO_LPCG_PWM1_IPG_MSTR_CLK 9
#define IMX8QXP_LSIO_LPCG_PWM2_IPG_CLK 10
#define IMX8QXP_LSIO_LPCG_PWM2_IPG_S_CLK 11
#define IMX8QXP_LSIO_LPCG_PWM2_IPG_HF_CLK 12
#define IMX8QXP_LSIO_LPCG_PWM2_IPG_SLV_CLK 13
#define IMX8QXP_LSIO_LPCG_PWM2_IPG_MSTR_CLK 14
#define IMX8QXP_LSIO_LPCG_PWM3_IPG_CLK 15
#define IMX8QXP_LSIO_LPCG_PWM3_IPG_S_CLK 16
#define IMX8QXP_LSIO_LPCG_PWM3_IPG_HF_CLK 17
#define IMX8QXP_LSIO_LPCG_PWM3_IPG_SLV_CLK 18
#define IMX8QXP_LSIO_LPCG_PWM3_IPG_MSTR_CLK 19
#define IMX8QXP_LSIO_LPCG_PWM4_IPG_CLK 20
#define IMX8QXP_LSIO_LPCG_PWM4_IPG_S_CLK 21
#define IMX8QXP_LSIO_LPCG_PWM4_IPG_HF_CLK 22
#define IMX8QXP_LSIO_LPCG_PWM4_IPG_SLV_CLK 23
#define IMX8QXP_LSIO_LPCG_PWM4_IPG_MSTR_CLK 24
#define IMX8QXP_LSIO_LPCG_PWM5_IPG_CLK 25
#define IMX8QXP_LSIO_LPCG_PWM5_IPG_S_CLK 26
#define IMX8QXP_LSIO_LPCG_PWM5_IPG_HF_CLK 27
#define IMX8QXP_LSIO_LPCG_PWM5_IPG_SLV_CLK 28
#define IMX8QXP_LSIO_LPCG_PWM5_IPG_MSTR_CLK 29
#define IMX8QXP_LSIO_LPCG_PWM6_IPG_CLK 30
#define IMX8QXP_LSIO_LPCG_PWM6_IPG_S_CLK 31
#define IMX8QXP_LSIO_LPCG_PWM6_IPG_HF_CLK 32
#define IMX8QXP_LSIO_LPCG_PWM6_IPG_SLV_CLK 33
#define IMX8QXP_LSIO_LPCG_PWM6_IPG_MSTR_CLK 34
#define IMX8QXP_LSIO_LPCG_PWM7_IPG_CLK 35
#define IMX8QXP_LSIO_LPCG_PWM7_IPG_S_CLK 36
#define IMX8QXP_LSIO_LPCG_PWM7_IPG_HF_CLK 37
#define IMX8QXP_LSIO_LPCG_PWM7_IPG_SLV_CLK 38
#define IMX8QXP_LSIO_LPCG_PWM7_IPG_MSTR_CLK 39
#define IMX8QXP_LSIO_LPCG_GPT0_IPG_CLK 40
#define IMX8QXP_LSIO_LPCG_GPT0_IPG_S_CLK 41
#define IMX8QXP_LSIO_LPCG_GPT0_IPG_HF_CLK 42
#define IMX8QXP_LSIO_LPCG_GPT0_IPG_SLV_CLK 43
#define IMX8QXP_LSIO_LPCG_GPT0_IPG_MSTR_CLK 44
#define IMX8QXP_LSIO_LPCG_GPT1_IPG_CLK 45
#define IMX8QXP_LSIO_LPCG_GPT1_IPG_S_CLK 46
#define IMX8QXP_LSIO_LPCG_GPT1_IPG_HF_CLK 47
#define IMX8QXP_LSIO_LPCG_GPT1_IPG_SLV_CLK 48
#define IMX8QXP_LSIO_LPCG_GPT1_IPG_MSTR_CLK 49
#define IMX8QXP_LSIO_LPCG_GPT2_IPG_CLK 50
#define IMX8QXP_LSIO_LPCG_GPT2_IPG_S_CLK 51
#define IMX8QXP_LSIO_LPCG_GPT2_IPG_HF_CLK 52
#define IMX8QXP_LSIO_LPCG_GPT2_IPG_SLV_CLK 53
#define IMX8QXP_LSIO_LPCG_GPT2_IPG_MSTR_CLK 54
#define IMX8QXP_LSIO_LPCG_GPT3_IPG_CLK 55
#define IMX8QXP_LSIO_LPCG_GPT3_IPG_S_CLK 56
#define IMX8QXP_LSIO_LPCG_GPT3_IPG_HF_CLK 57
#define IMX8QXP_LSIO_LPCG_GPT3_IPG_SLV_CLK 58
#define IMX8QXP_LSIO_LPCG_GPT3_IPG_MSTR_CLK 59
#define IMX8QXP_LSIO_LPCG_GPT4_IPG_CLK 60
#define IMX8QXP_LSIO_LPCG_GPT4_IPG_S_CLK 61
#define IMX8QXP_LSIO_LPCG_GPT4_IPG_HF_CLK 62
#define IMX8QXP_LSIO_LPCG_GPT4_IPG_SLV_CLK 63
#define IMX8QXP_LSIO_LPCG_GPT4_IPG_MSTR_CLK 64
#define IMX8QXP_LSIO_LPCG_FSPI0_HCLK 65
#define IMX8QXP_LSIO_LPCG_FSPI0_IPG_CLK 66
#define IMX8QXP_LSIO_LPCG_FSPI0_IPG_S_CLK 67
#define IMX8QXP_LSIO_LPCG_FSPI0_IPG_SFCK 68
#define IMX8QXP_LSIO_LPCG_FSPI1_HCLK 69
#define IMX8QXP_LSIO_LPCG_FSPI1_IPG_CLK 70
#define IMX8QXP_LSIO_LPCG_FSPI1_IPG_S_CLK 71
#define IMX8QXP_LSIO_LPCG_FSPI1_IPG_SFCK 72
#define IMX8QXP_LSIO_LPCG_CLK_END 73
/* Connectivity SS LPCG */
#define IMX8QXP_CONN_LPCG_SDHC0_IPG_CLK 0
#define IMX8QXP_CONN_LPCG_SDHC0_PER_CLK 1
#define IMX8QXP_CONN_LPCG_SDHC0_HCLK 2
#define IMX8QXP_CONN_LPCG_SDHC1_IPG_CLK 3
#define IMX8QXP_CONN_LPCG_SDHC1_PER_CLK 4
#define IMX8QXP_CONN_LPCG_SDHC1_HCLK 5
#define IMX8QXP_CONN_LPCG_SDHC2_IPG_CLK 6
#define IMX8QXP_CONN_LPCG_SDHC2_PER_CLK 7
#define IMX8QXP_CONN_LPCG_SDHC2_HCLK 8
#define IMX8QXP_CONN_LPCG_GPMI_APB_CLK 9
#define IMX8QXP_CONN_LPCG_GPMI_BCH_APB_CLK 10
#define IMX8QXP_CONN_LPCG_GPMI_BCH_IO_CLK 11
#define IMX8QXP_CONN_LPCG_GPMI_BCH_CLK 12
#define IMX8QXP_CONN_LPCG_APBHDMA_CLK 13
#define IMX8QXP_CONN_LPCG_ENET0_ROOT_CLK 14
#define IMX8QXP_CONN_LPCG_ENET0_TX_CLK 15
#define IMX8QXP_CONN_LPCG_ENET0_AHB_CLK 16
#define IMX8QXP_CONN_LPCG_ENET0_IPG_S_CLK 17
#define IMX8QXP_CONN_LPCG_ENET0_IPG_CLK 18
#define IMX8QXP_CONN_LPCG_ENET1_ROOT_CLK 19
#define IMX8QXP_CONN_LPCG_ENET1_TX_CLK 20
#define IMX8QXP_CONN_LPCG_ENET1_AHB_CLK 21
#define IMX8QXP_CONN_LPCG_ENET1_IPG_S_CLK 22
#define IMX8QXP_CONN_LPCG_ENET1_IPG_CLK 23
#define IMX8QXP_CONN_LPCG_CLK_END 24
/* ADMA SS LPCG */
#define IMX8QXP_ADMA_LPCG_UART0_IPG_CLK 0
#define IMX8QXP_ADMA_LPCG_UART0_BAUD_CLK 1
#define IMX8QXP_ADMA_LPCG_UART1_IPG_CLK 2
#define IMX8QXP_ADMA_LPCG_UART1_BAUD_CLK 3
#define IMX8QXP_ADMA_LPCG_UART2_IPG_CLK 4
#define IMX8QXP_ADMA_LPCG_UART2_BAUD_CLK 5
#define IMX8QXP_ADMA_LPCG_UART3_IPG_CLK 6
#define IMX8QXP_ADMA_LPCG_UART3_BAUD_CLK 7
#define IMX8QXP_ADMA_LPCG_SPI0_IPG_CLK 8
#define IMX8QXP_ADMA_LPCG_SPI1_IPG_CLK 9
#define IMX8QXP_ADMA_LPCG_SPI2_IPG_CLK 10
#define IMX8QXP_ADMA_LPCG_SPI3_IPG_CLK 11
#define IMX8QXP_ADMA_LPCG_SPI0_CLK 12
#define IMX8QXP_ADMA_LPCG_SPI1_CLK 13
#define IMX8QXP_ADMA_LPCG_SPI2_CLK 14
#define IMX8QXP_ADMA_LPCG_SPI3_CLK 15
#define IMX8QXP_ADMA_LPCG_CAN0_IPG_CLK 16
#define IMX8QXP_ADMA_LPCG_CAN0_IPG_PE_CLK 17
#define IMX8QXP_ADMA_LPCG_CAN0_IPG_CHI_CLK 18
#define IMX8QXP_ADMA_LPCG_CAN1_IPG_CLK 19
#define IMX8QXP_ADMA_LPCG_CAN1_IPG_PE_CLK 20
#define IMX8QXP_ADMA_LPCG_CAN1_IPG_CHI_CLK 21
#define IMX8QXP_ADMA_LPCG_CAN2_IPG_CLK 22
#define IMX8QXP_ADMA_LPCG_CAN2_IPG_PE_CLK 23
#define IMX8QXP_ADMA_LPCG_CAN2_IPG_CHI_CLK 24
#define IMX8QXP_ADMA_LPCG_I2C0_CLK 25
#define IMX8QXP_ADMA_LPCG_I2C1_CLK 26
#define IMX8QXP_ADMA_LPCG_I2C2_CLK 27
#define IMX8QXP_ADMA_LPCG_I2C3_CLK 28
#define IMX8QXP_ADMA_LPCG_I2C0_IPG_CLK 29
#define IMX8QXP_ADMA_LPCG_I2C1_IPG_CLK 30
#define IMX8QXP_ADMA_LPCG_I2C2_IPG_CLK 31
#define IMX8QXP_ADMA_LPCG_I2C3_IPG_CLK 32
#define IMX8QXP_ADMA_LPCG_FTM0_CLK 33
#define IMX8QXP_ADMA_LPCG_FTM1_CLK 34
#define IMX8QXP_ADMA_LPCG_FTM0_IPG_CLK 35
#define IMX8QXP_ADMA_LPCG_FTM1_IPG_CLK 36
#define IMX8QXP_ADMA_LPCG_PWM_HI_CLK 37
#define IMX8QXP_ADMA_LPCG_PWM_IPG_CLK 38
#define IMX8QXP_ADMA_LPCG_LCD_PIX_CLK 39
#define IMX8QXP_ADMA_LPCG_LCD_APB_CLK 40
#define IMX8QXP_ADMA_LPCG_CLK_END 41
#endif /* __DT_BINDINGS_CLOCK_IMX8QXP_H */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017-2018 NXP
*/
#ifndef __DT_BINDINGS_RSCRC_IMX_H
#define __DT_BINDINGS_RSCRC_IMX_H
/*
* These defines are used to indicate a resource. Resources include peripherals
* and bus masters (but not memory regions). Note items from list should
* never be changed or removed (only added to at the end of the list).
*/
#define IMX_SC_R_A53 0
#define IMX_SC_R_A53_0 1
#define IMX_SC_R_A53_1 2
#define IMX_SC_R_A53_2 3
#define IMX_SC_R_A53_3 4
#define IMX_SC_R_A72 5
#define IMX_SC_R_A72_0 6
#define IMX_SC_R_A72_1 7
#define IMX_SC_R_A72_2 8
#define IMX_SC_R_A72_3 9
#define IMX_SC_R_CCI 10
#define IMX_SC_R_DB 11
#define IMX_SC_R_DRC_0 12
#define IMX_SC_R_DRC_1 13
#define IMX_SC_R_GIC_SMMU 14
#define IMX_SC_R_IRQSTR_M4_0 15
#define IMX_SC_R_IRQSTR_M4_1 16
#define IMX_SC_R_SMMU 17
#define IMX_SC_R_GIC 18
#define IMX_SC_R_DC_0_BLIT0 19
#define IMX_SC_R_DC_0_BLIT1 20
#define IMX_SC_R_DC_0_BLIT2 21
#define IMX_SC_R_DC_0_BLIT_OUT 22
#define IMX_SC_R_DC_0_CAPTURE0 23
#define IMX_SC_R_DC_0_CAPTURE1 24
#define IMX_SC_R_DC_0_WARP 25
#define IMX_SC_R_DC_0_INTEGRAL0 26
#define IMX_SC_R_DC_0_INTEGRAL1 27
#define IMX_SC_R_DC_0_VIDEO0 28
#define IMX_SC_R_DC_0_VIDEO1 29
#define IMX_SC_R_DC_0_FRAC0 30
#define IMX_SC_R_DC_0_FRAC1 31
#define IMX_SC_R_DC_0 32
#define IMX_SC_R_GPU_2_PID0 33
#define IMX_SC_R_DC_0_PLL_0 34
#define IMX_SC_R_DC_0_PLL_1 35
#define IMX_SC_R_DC_1_BLIT0 36
#define IMX_SC_R_DC_1_BLIT1 37
#define IMX_SC_R_DC_1_BLIT2 38
#define IMX_SC_R_DC_1_BLIT_OUT 39
#define IMX_SC_R_DC_1_CAPTURE0 40
#define IMX_SC_R_DC_1_CAPTURE1 41
#define IMX_SC_R_DC_1_WARP 42
#define IMX_SC_R_DC_1_INTEGRAL0 43
#define IMX_SC_R_DC_1_INTEGRAL1 44
#define IMX_SC_R_DC_1_VIDEO0 45
#define IMX_SC_R_DC_1_VIDEO1 46
#define IMX_SC_R_DC_1_FRAC0 47
#define IMX_SC_R_DC_1_FRAC1 48
#define IMX_SC_R_DC_1 49
#define IMX_SC_R_GPU_3_PID0 50
#define IMX_SC_R_DC_1_PLL_0 51
#define IMX_SC_R_DC_1_PLL_1 52
#define IMX_SC_R_SPI_0 53
#define IMX_SC_R_SPI_1 54
#define IMX_SC_R_SPI_2 55
#define IMX_SC_R_SPI_3 56
#define IMX_SC_R_UART_0 57
#define IMX_SC_R_UART_1 58
#define IMX_SC_R_UART_2 59
#define IMX_SC_R_UART_3 60
#define IMX_SC_R_UART_4 61
#define IMX_SC_R_EMVSIM_0 62
#define IMX_SC_R_EMVSIM_1 63
#define IMX_SC_R_DMA_0_CH0 64
#define IMX_SC_R_DMA_0_CH1 65
#define IMX_SC_R_DMA_0_CH2 66
#define IMX_SC_R_DMA_0_CH3 67
#define IMX_SC_R_DMA_0_CH4 68
#define IMX_SC_R_DMA_0_CH5 69
#define IMX_SC_R_DMA_0_CH6 70
#define IMX_SC_R_DMA_0_CH7 71
#define IMX_SC_R_DMA_0_CH8 72
#define IMX_SC_R_DMA_0_CH9 73
#define IMX_SC_R_DMA_0_CH10 74
#define IMX_SC_R_DMA_0_CH11 75
#define IMX_SC_R_DMA_0_CH12 76
#define IMX_SC_R_DMA_0_CH13 77
#define IMX_SC_R_DMA_0_CH14 78
#define IMX_SC_R_DMA_0_CH15 79
#define IMX_SC_R_DMA_0_CH16 80
#define IMX_SC_R_DMA_0_CH17 81
#define IMX_SC_R_DMA_0_CH18 82
#define IMX_SC_R_DMA_0_CH19 83
#define IMX_SC_R_DMA_0_CH20 84
#define IMX_SC_R_DMA_0_CH21 85
#define IMX_SC_R_DMA_0_CH22 86
#define IMX_SC_R_DMA_0_CH23 87
#define IMX_SC_R_DMA_0_CH24 88
#define IMX_SC_R_DMA_0_CH25 89
#define IMX_SC_R_DMA_0_CH26 90
#define IMX_SC_R_DMA_0_CH27 91
#define IMX_SC_R_DMA_0_CH28 92
#define IMX_SC_R_DMA_0_CH29 93
#define IMX_SC_R_DMA_0_CH30 94
#define IMX_SC_R_DMA_0_CH31 95
#define IMX_SC_R_I2C_0 96
#define IMX_SC_R_I2C_1 97
#define IMX_SC_R_I2C_2 98
#define IMX_SC_R_I2C_3 99
#define IMX_SC_R_I2C_4 100
#define IMX_SC_R_ADC_0 101
#define IMX_SC_R_ADC_1 102
#define IMX_SC_R_FTM_0 103
#define IMX_SC_R_FTM_1 104
#define IMX_SC_R_CAN_0 105
#define IMX_SC_R_CAN_1 106
#define IMX_SC_R_CAN_2 107
#define IMX_SC_R_DMA_1_CH0 108
#define IMX_SC_R_DMA_1_CH1 109
#define IMX_SC_R_DMA_1_CH2 110
#define IMX_SC_R_DMA_1_CH3 111
#define IMX_SC_R_DMA_1_CH4 112
#define IMX_SC_R_DMA_1_CH5 113
#define IMX_SC_R_DMA_1_CH6 114
#define IMX_SC_R_DMA_1_CH7 115
#define IMX_SC_R_DMA_1_CH8 116
#define IMX_SC_R_DMA_1_CH9 117
#define IMX_SC_R_DMA_1_CH10 118
#define IMX_SC_R_DMA_1_CH11 119
#define IMX_SC_R_DMA_1_CH12 120
#define IMX_SC_R_DMA_1_CH13 121
#define IMX_SC_R_DMA_1_CH14 122
#define IMX_SC_R_DMA_1_CH15 123
#define IMX_SC_R_DMA_1_CH16 124
#define IMX_SC_R_DMA_1_CH17 125
#define IMX_SC_R_DMA_1_CH18 126
#define IMX_SC_R_DMA_1_CH19 127
#define IMX_SC_R_DMA_1_CH20 128
#define IMX_SC_R_DMA_1_CH21 129
#define IMX_SC_R_DMA_1_CH22 130
#define IMX_SC_R_DMA_1_CH23 131
#define IMX_SC_R_DMA_1_CH24 132
#define IMX_SC_R_DMA_1_CH25 133
#define IMX_SC_R_DMA_1_CH26 134
#define IMX_SC_R_DMA_1_CH27 135
#define IMX_SC_R_DMA_1_CH28 136
#define IMX_SC_R_DMA_1_CH29 137
#define IMX_SC_R_DMA_1_CH30 138
#define IMX_SC_R_DMA_1_CH31 139
#define IMX_SC_R_UNUSED1 140
#define IMX_SC_R_UNUSED2 141
#define IMX_SC_R_UNUSED3 142
#define IMX_SC_R_UNUSED4 143
#define IMX_SC_R_GPU_0_PID0 144
#define IMX_SC_R_GPU_0_PID1 145
#define IMX_SC_R_GPU_0_PID2 146
#define IMX_SC_R_GPU_0_PID3 147
#define IMX_SC_R_GPU_1_PID0 148
#define IMX_SC_R_GPU_1_PID1 149
#define IMX_SC_R_GPU_1_PID2 150
#define IMX_SC_R_GPU_1_PID3 151
#define IMX_SC_R_PCIE_A 152
#define IMX_SC_R_SERDES_0 153
#define IMX_SC_R_MATCH_0 154
#define IMX_SC_R_MATCH_1 155
#define IMX_SC_R_MATCH_2 156
#define IMX_SC_R_MATCH_3 157
#define IMX_SC_R_MATCH_4 158
#define IMX_SC_R_MATCH_5 159
#define IMX_SC_R_MATCH_6 160
#define IMX_SC_R_MATCH_7 161
#define IMX_SC_R_MATCH_8 162
#define IMX_SC_R_MATCH_9 163
#define IMX_SC_R_MATCH_10 164
#define IMX_SC_R_MATCH_11 165
#define IMX_SC_R_MATCH_12 166
#define IMX_SC_R_MATCH_13 167
#define IMX_SC_R_MATCH_14 168
#define IMX_SC_R_PCIE_B 169
#define IMX_SC_R_SATA_0 170
#define IMX_SC_R_SERDES_1 171
#define IMX_SC_R_HSIO_GPIO 172
#define IMX_SC_R_MATCH_15 173
#define IMX_SC_R_MATCH_16 174
#define IMX_SC_R_MATCH_17 175
#define IMX_SC_R_MATCH_18 176
#define IMX_SC_R_MATCH_19 177
#define IMX_SC_R_MATCH_20 178
#define IMX_SC_R_MATCH_21 179
#define IMX_SC_R_MATCH_22 180
#define IMX_SC_R_MATCH_23 181
#define IMX_SC_R_MATCH_24 182
#define IMX_SC_R_MATCH_25 183
#define IMX_SC_R_MATCH_26 184
#define IMX_SC_R_MATCH_27 185
#define IMX_SC_R_MATCH_28 186
#define IMX_SC_R_LCD_0 187
#define IMX_SC_R_LCD_0_PWM_0 188
#define IMX_SC_R_LCD_0_I2C_0 189
#define IMX_SC_R_LCD_0_I2C_1 190
#define IMX_SC_R_PWM_0 191
#define IMX_SC_R_PWM_1 192
#define IMX_SC_R_PWM_2 193
#define IMX_SC_R_PWM_3 194
#define IMX_SC_R_PWM_4 195
#define IMX_SC_R_PWM_5 196
#define IMX_SC_R_PWM_6 197
#define IMX_SC_R_PWM_7 198
#define IMX_SC_R_GPIO_0 199
#define IMX_SC_R_GPIO_1 200
#define IMX_SC_R_GPIO_2 201
#define IMX_SC_R_GPIO_3 202
#define IMX_SC_R_GPIO_4 203
#define IMX_SC_R_GPIO_5 204
#define IMX_SC_R_GPIO_6 205
#define IMX_SC_R_GPIO_7 206
#define IMX_SC_R_GPT_0 207
#define IMX_SC_R_GPT_1 208
#define IMX_SC_R_GPT_2 209
#define IMX_SC_R_GPT_3 210
#define IMX_SC_R_GPT_4 211
#define IMX_SC_R_KPP 212
#define IMX_SC_R_MU_0A 213
#define IMX_SC_R_MU_1A 214
#define IMX_SC_R_MU_2A 215
#define IMX_SC_R_MU_3A 216
#define IMX_SC_R_MU_4A 217
#define IMX_SC_R_MU_5A 218
#define IMX_SC_R_MU_6A 219
#define IMX_SC_R_MU_7A 220
#define IMX_SC_R_MU_8A 221
#define IMX_SC_R_MU_9A 222
#define IMX_SC_R_MU_10A 223
#define IMX_SC_R_MU_11A 224
#define IMX_SC_R_MU_12A 225
#define IMX_SC_R_MU_13A 226
#define IMX_SC_R_MU_5B 227
#define IMX_SC_R_MU_6B 228
#define IMX_SC_R_MU_7B 229
#define IMX_SC_R_MU_8B 230
#define IMX_SC_R_MU_9B 231
#define IMX_SC_R_MU_10B 232
#define IMX_SC_R_MU_11B 233
#define IMX_SC_R_MU_12B 234
#define IMX_SC_R_MU_13B 235
#define IMX_SC_R_ROM_0 236
#define IMX_SC_R_FSPI_0 237
#define IMX_SC_R_FSPI_1 238
#define IMX_SC_R_IEE 239
#define IMX_SC_R_IEE_R0 240
#define IMX_SC_R_IEE_R1 241
#define IMX_SC_R_IEE_R2 242
#define IMX_SC_R_IEE_R3 243
#define IMX_SC_R_IEE_R4 244
#define IMX_SC_R_IEE_R5 245
#define IMX_SC_R_IEE_R6 246
#define IMX_SC_R_IEE_R7 247
#define IMX_SC_R_SDHC_0 248
#define IMX_SC_R_SDHC_1 249
#define IMX_SC_R_SDHC_2 250
#define IMX_SC_R_ENET_0 251
#define IMX_SC_R_ENET_1 252
#define IMX_SC_R_MLB_0 253
#define IMX_SC_R_DMA_2_CH0 254
#define IMX_SC_R_DMA_2_CH1 255
#define IMX_SC_R_DMA_2_CH2 256
#define IMX_SC_R_DMA_2_CH3 257
#define IMX_SC_R_DMA_2_CH4 258
#define IMX_SC_R_USB_0 259
#define IMX_SC_R_USB_1 260
#define IMX_SC_R_USB_0_PHY 261
#define IMX_SC_R_USB_2 262
#define IMX_SC_R_USB_2_PHY 263
#define IMX_SC_R_DTCP 264
#define IMX_SC_R_NAND 265
#define IMX_SC_R_LVDS_0 266
#define IMX_SC_R_LVDS_0_PWM_0 267
#define IMX_SC_R_LVDS_0_I2C_0 268
#define IMX_SC_R_LVDS_0_I2C_1 269
#define IMX_SC_R_LVDS_1 270
#define IMX_SC_R_LVDS_1_PWM_0 271
#define IMX_SC_R_LVDS_1_I2C_0 272
#define IMX_SC_R_LVDS_1_I2C_1 273
#define IMX_SC_R_LVDS_2 274
#define IMX_SC_R_LVDS_2_PWM_0 275
#define IMX_SC_R_LVDS_2_I2C_0 276
#define IMX_SC_R_LVDS_2_I2C_1 277
#define IMX_SC_R_M4_0_PID0 278
#define IMX_SC_R_M4_0_PID1 279
#define IMX_SC_R_M4_0_PID2 280
#define IMX_SC_R_M4_0_PID3 281
#define IMX_SC_R_M4_0_PID4 282
#define IMX_SC_R_M4_0_RGPIO 283
#define IMX_SC_R_M4_0_SEMA42 284
#define IMX_SC_R_M4_0_TPM 285
#define IMX_SC_R_M4_0_PIT 286
#define IMX_SC_R_M4_0_UART 287
#define IMX_SC_R_M4_0_I2C 288
#define IMX_SC_R_M4_0_INTMUX 289
#define IMX_SC_R_M4_0_SIM 290
#define IMX_SC_R_M4_0_WDOG 291
#define IMX_SC_R_M4_0_MU_0B 292
#define IMX_SC_R_M4_0_MU_0A0 293
#define IMX_SC_R_M4_0_MU_0A1 294
#define IMX_SC_R_M4_0_MU_0A2 295
#define IMX_SC_R_M4_0_MU_0A3 296
#define IMX_SC_R_M4_0_MU_1A 297
#define IMX_SC_R_M4_1_PID0 298
#define IMX_SC_R_M4_1_PID1 299
#define IMX_SC_R_M4_1_PID2 300
#define IMX_SC_R_M4_1_PID3 301
#define IMX_SC_R_M4_1_PID4 302
#define IMX_SC_R_M4_1_RGPIO 303
#define IMX_SC_R_M4_1_SEMA42 304
#define IMX_SC_R_M4_1_TPM 305
#define IMX_SC_R_M4_1_PIT 306
#define IMX_SC_R_M4_1_UART 307
#define IMX_SC_R_M4_1_I2C 308
#define IMX_SC_R_M4_1_INTMUX 309
#define IMX_SC_R_M4_1_SIM 310
#define IMX_SC_R_M4_1_WDOG 311
#define IMX_SC_R_M4_1_MU_0B 312
#define IMX_SC_R_M4_1_MU_0A0 313
#define IMX_SC_R_M4_1_MU_0A1 314
#define IMX_SC_R_M4_1_MU_0A2 315
#define IMX_SC_R_M4_1_MU_0A3 316
#define IMX_SC_R_M4_1_MU_1A 317
#define IMX_SC_R_SAI_0 318
#define IMX_SC_R_SAI_1 319
#define IMX_SC_R_SAI_2 320
#define IMX_SC_R_IRQSTR_SCU2 321
#define IMX_SC_R_IRQSTR_DSP 322
#define IMX_SC_R_ELCDIF_PLL 323
#define IMX_SC_R_UNUSED6 324
#define IMX_SC_R_AUDIO_PLL_0 325
#define IMX_SC_R_PI_0 326
#define IMX_SC_R_PI_0_PWM_0 327
#define IMX_SC_R_PI_0_PWM_1 328
#define IMX_SC_R_PI_0_I2C_0 329
#define IMX_SC_R_PI_0_PLL 330
#define IMX_SC_R_PI_1 331
#define IMX_SC_R_PI_1_PWM_0 332
#define IMX_SC_R_PI_1_PWM_1 333
#define IMX_SC_R_PI_1_I2C_0 334
#define IMX_SC_R_PI_1_PLL 335
#define IMX_SC_R_SC_PID0 336
#define IMX_SC_R_SC_PID1 337
#define IMX_SC_R_SC_PID2 338
#define IMX_SC_R_SC_PID3 339
#define IMX_SC_R_SC_PID4 340
#define IMX_SC_R_SC_SEMA42 341
#define IMX_SC_R_SC_TPM 342
#define IMX_SC_R_SC_PIT 343
#define IMX_SC_R_SC_UART 344
#define IMX_SC_R_SC_I2C 345
#define IMX_SC_R_SC_MU_0B 346
#define IMX_SC_R_SC_MU_0A0 347
#define IMX_SC_R_SC_MU_0A1 348
#define IMX_SC_R_SC_MU_0A2 349
#define IMX_SC_R_SC_MU_0A3 350
#define IMX_SC_R_SC_MU_1A 351
#define IMX_SC_R_SYSCNT_RD 352
#define IMX_SC_R_SYSCNT_CMP 353
#define IMX_SC_R_DEBUG 354
#define IMX_SC_R_SYSTEM 355
#define IMX_SC_R_SNVS 356
#define IMX_SC_R_OTP 357
#define IMX_SC_R_VPU_PID0 358
#define IMX_SC_R_VPU_PID1 359
#define IMX_SC_R_VPU_PID2 360
#define IMX_SC_R_VPU_PID3 361
#define IMX_SC_R_VPU_PID4 362
#define IMX_SC_R_VPU_PID5 363
#define IMX_SC_R_VPU_PID6 364
#define IMX_SC_R_VPU_PID7 365
#define IMX_SC_R_VPU_UART 366
#define IMX_SC_R_VPUCORE 367
#define IMX_SC_R_VPUCORE_0 368
#define IMX_SC_R_VPUCORE_1 369
#define IMX_SC_R_VPUCORE_2 370
#define IMX_SC_R_VPUCORE_3 371
#define IMX_SC_R_DMA_4_CH0 372
#define IMX_SC_R_DMA_4_CH1 373
#define IMX_SC_R_DMA_4_CH2 374
#define IMX_SC_R_DMA_4_CH3 375
#define IMX_SC_R_DMA_4_CH4 376
#define IMX_SC_R_ISI_CH0 377
#define IMX_SC_R_ISI_CH1 378
#define IMX_SC_R_ISI_CH2 379
#define IMX_SC_R_ISI_CH3 380
#define IMX_SC_R_ISI_CH4 381
#define IMX_SC_R_ISI_CH5 382
#define IMX_SC_R_ISI_CH6 383
#define IMX_SC_R_ISI_CH7 384
#define IMX_SC_R_MJPEG_DEC_S0 385
#define IMX_SC_R_MJPEG_DEC_S1 386
#define IMX_SC_R_MJPEG_DEC_S2 387
#define IMX_SC_R_MJPEG_DEC_S3 388
#define IMX_SC_R_MJPEG_ENC_S0 389
#define IMX_SC_R_MJPEG_ENC_S1 390
#define IMX_SC_R_MJPEG_ENC_S2 391
#define IMX_SC_R_MJPEG_ENC_S3 392
#define IMX_SC_R_MIPI_0 393
#define IMX_SC_R_MIPI_0_PWM_0 394
#define IMX_SC_R_MIPI_0_I2C_0 395
#define IMX_SC_R_MIPI_0_I2C_1 396
#define IMX_SC_R_MIPI_1 397
#define IMX_SC_R_MIPI_1_PWM_0 398
#define IMX_SC_R_MIPI_1_I2C_0 399
#define IMX_SC_R_MIPI_1_I2C_1 400
#define IMX_SC_R_CSI_0 401
#define IMX_SC_R_CSI_0_PWM_0 402
#define IMX_SC_R_CSI_0_I2C_0 403
#define IMX_SC_R_CSI_1 404
#define IMX_SC_R_CSI_1_PWM_0 405
#define IMX_SC_R_CSI_1_I2C_0 406
#define IMX_SC_R_HDMI 407
#define IMX_SC_R_HDMI_I2S 408
#define IMX_SC_R_HDMI_I2C_0 409
#define IMX_SC_R_HDMI_PLL_0 410
#define IMX_SC_R_HDMI_RX 411
#define IMX_SC_R_HDMI_RX_BYPASS 412
#define IMX_SC_R_HDMI_RX_I2C_0 413
#define IMX_SC_R_ASRC_0 414
#define IMX_SC_R_ESAI_0 415
#define IMX_SC_R_SPDIF_0 416
#define IMX_SC_R_SPDIF_1 417
#define IMX_SC_R_SAI_3 418
#define IMX_SC_R_SAI_4 419
#define IMX_SC_R_SAI_5 420
#define IMX_SC_R_GPT_5 421
#define IMX_SC_R_GPT_6 422
#define IMX_SC_R_GPT_7 423
#define IMX_SC_R_GPT_8 424
#define IMX_SC_R_GPT_9 425
#define IMX_SC_R_GPT_10 426
#define IMX_SC_R_DMA_2_CH5 427
#define IMX_SC_R_DMA_2_CH6 428
#define IMX_SC_R_DMA_2_CH7 429
#define IMX_SC_R_DMA_2_CH8 430
#define IMX_SC_R_DMA_2_CH9 431
#define IMX_SC_R_DMA_2_CH10 432
#define IMX_SC_R_DMA_2_CH11 433
#define IMX_SC_R_DMA_2_CH12 434
#define IMX_SC_R_DMA_2_CH13 435
#define IMX_SC_R_DMA_2_CH14 436
#define IMX_SC_R_DMA_2_CH15 437
#define IMX_SC_R_DMA_2_CH16 438
#define IMX_SC_R_DMA_2_CH17 439
#define IMX_SC_R_DMA_2_CH18 440
#define IMX_SC_R_DMA_2_CH19 441
#define IMX_SC_R_DMA_2_CH20 442
#define IMX_SC_R_DMA_2_CH21 443
#define IMX_SC_R_DMA_2_CH22 444
#define IMX_SC_R_DMA_2_CH23 445
#define IMX_SC_R_DMA_2_CH24 446
#define IMX_SC_R_DMA_2_CH25 447
#define IMX_SC_R_DMA_2_CH26 448
#define IMX_SC_R_DMA_2_CH27 449
#define IMX_SC_R_DMA_2_CH28 450
#define IMX_SC_R_DMA_2_CH29 451
#define IMX_SC_R_DMA_2_CH30 452
#define IMX_SC_R_DMA_2_CH31 453
#define IMX_SC_R_ASRC_1 454
#define IMX_SC_R_ESAI_1 455
#define IMX_SC_R_SAI_6 456
#define IMX_SC_R_SAI_7 457
#define IMX_SC_R_AMIX 458
#define IMX_SC_R_MQS_0 459
#define IMX_SC_R_DMA_3_CH0 460
#define IMX_SC_R_DMA_3_CH1 461
#define IMX_SC_R_DMA_3_CH2 462
#define IMX_SC_R_DMA_3_CH3 463
#define IMX_SC_R_DMA_3_CH4 464
#define IMX_SC_R_DMA_3_CH5 465
#define IMX_SC_R_DMA_3_CH6 466
#define IMX_SC_R_DMA_3_CH7 467
#define IMX_SC_R_DMA_3_CH8 468
#define IMX_SC_R_DMA_3_CH9 469
#define IMX_SC_R_DMA_3_CH10 470
#define IMX_SC_R_DMA_3_CH11 471
#define IMX_SC_R_DMA_3_CH12 472
#define IMX_SC_R_DMA_3_CH13 473
#define IMX_SC_R_DMA_3_CH14 474
#define IMX_SC_R_DMA_3_CH15 475
#define IMX_SC_R_DMA_3_CH16 476
#define IMX_SC_R_DMA_3_CH17 477
#define IMX_SC_R_DMA_3_CH18 478
#define IMX_SC_R_DMA_3_CH19 479
#define IMX_SC_R_DMA_3_CH20 480
#define IMX_SC_R_DMA_3_CH21 481
#define IMX_SC_R_DMA_3_CH22 482
#define IMX_SC_R_DMA_3_CH23 483
#define IMX_SC_R_DMA_3_CH24 484
#define IMX_SC_R_DMA_3_CH25 485
#define IMX_SC_R_DMA_3_CH26 486
#define IMX_SC_R_DMA_3_CH27 487
#define IMX_SC_R_DMA_3_CH28 488
#define IMX_SC_R_DMA_3_CH29 489
#define IMX_SC_R_DMA_3_CH30 490
#define IMX_SC_R_DMA_3_CH31 491
#define IMX_SC_R_AUDIO_PLL_1 492
#define IMX_SC_R_AUDIO_CLK_0 493
#define IMX_SC_R_AUDIO_CLK_1 494
#define IMX_SC_R_MCLK_OUT_0 495
#define IMX_SC_R_MCLK_OUT_1 496
#define IMX_SC_R_PMIC_0 497
#define IMX_SC_R_PMIC_1 498
#define IMX_SC_R_SECO 499
#define IMX_SC_R_CAAM_JR1 500
#define IMX_SC_R_CAAM_JR2 501
#define IMX_SC_R_CAAM_JR3 502
#define IMX_SC_R_SECO_MU_2 503
#define IMX_SC_R_SECO_MU_3 504
#define IMX_SC_R_SECO_MU_4 505
#define IMX_SC_R_HDMI_RX_PWM_0 506
#define IMX_SC_R_A35 507
#define IMX_SC_R_A35_0 508
#define IMX_SC_R_A35_1 509
#define IMX_SC_R_A35_2 510
#define IMX_SC_R_A35_3 511
#define IMX_SC_R_DSP 512
#define IMX_SC_R_DSP_RAM 513
#define IMX_SC_R_CAAM_JR1_OUT 514
#define IMX_SC_R_CAAM_JR2_OUT 515
#define IMX_SC_R_CAAM_JR3_OUT 516
#define IMX_SC_R_VPU_DEC_0 517
#define IMX_SC_R_VPU_ENC_0 518
#define IMX_SC_R_CAAM_JR0 519
#define IMX_SC_R_CAAM_JR0_OUT 520
#define IMX_SC_R_PMIC_2 521
#define IMX_SC_R_DBLOGIC 522
#define IMX_SC_R_HDMI_PLL_1 523
#define IMX_SC_R_BOARD_R0 524
#define IMX_SC_R_BOARD_R1 525
#define IMX_SC_R_BOARD_R2 526
#define IMX_SC_R_BOARD_R3 527
#define IMX_SC_R_BOARD_R4 528
#define IMX_SC_R_BOARD_R5 529
#define IMX_SC_R_BOARD_R6 530
#define IMX_SC_R_BOARD_R7 531
#define IMX_SC_R_MJPEG_DEC_MP 532
#define IMX_SC_R_MJPEG_ENC_MP 533
#define IMX_SC_R_VPU_TS_0 534
#define IMX_SC_R_VPU_MU_0 535
#define IMX_SC_R_VPU_MU_1 536
#define IMX_SC_R_VPU_MU_2 537
#define IMX_SC_R_VPU_MU_3 538
#define IMX_SC_R_VPU_ENC_1 539
#define IMX_SC_R_VPU 540
#define IMX_SC_R_LAST 541
#endif /* __DT_BINDINGS_RSCRC_IMX_H */
...@@ -596,6 +596,12 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw); ...@@ -596,6 +596,12 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
* @lock: register lock * @lock: register lock
* *
* Clock with adjustable fractional divider affecting its output frequency. * Clock with adjustable fractional divider affecting its output frequency.
*
* Flags:
* CLK_FRAC_DIVIDER_ZERO_BASED - by default the numerator and denominator
* is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED
* is set then the numerator and denominator are both the value read
* plus one.
*/ */
struct clk_fractional_divider { struct clk_fractional_divider {
struct clk_hw hw; struct clk_hw hw;
...@@ -615,6 +621,8 @@ struct clk_fractional_divider { ...@@ -615,6 +621,8 @@ struct clk_fractional_divider {
#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0)
extern const struct clk_ops clk_fractional_divider_ops; extern const struct clk_ops clk_fractional_divider_ops;
struct clk *clk_register_fractional_divider(struct device *dev, struct clk *clk_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags, const char *name, const char *parent_name, unsigned long flags,
......
...@@ -14,4 +14,5 @@ ...@@ -14,4 +14,5 @@
#include <linux/firmware/imx/types.h> #include <linux/firmware/imx/types.h>
#include <linux/firmware/imx/svc/misc.h> #include <linux/firmware/imx/svc/misc.h>
#include <linux/firmware/imx/svc/pm.h>
#endif /* _SC_SCI_H */ #endif /* _SC_SCI_H */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017-2018 NXP
*
* Header file containing the public API for the System Controller (SC)
* Power Management (PM) function. This includes functions for power state
* control, clock control, reset control, and wake-up event control.
*
* PM_SVC (SVC) Power Management Service
*
* Module for the Power Management (PM) service.
*/
#ifndef _SC_PM_API_H
#define _SC_PM_API_H
#include <linux/firmware/imx/sci.h>
/*
* This type is used to indicate RPC PM function calls.
*/
enum imx_sc_pm_func {
IMX_SC_PM_FUNC_UNKNOWN = 0,
IMX_SC_PM_FUNC_SET_SYS_POWER_MODE = 19,
IMX_SC_PM_FUNC_SET_PARTITION_POWER_MODE = 1,
IMX_SC_PM_FUNC_GET_SYS_POWER_MODE = 2,
IMX_SC_PM_FUNC_SET_RESOURCE_POWER_MODE = 3,
IMX_SC_PM_FUNC_GET_RESOURCE_POWER_MODE = 4,
IMX_SC_PM_FUNC_REQ_LOW_POWER_MODE = 16,
IMX_SC_PM_FUNC_SET_CPU_RESUME_ADDR = 17,
IMX_SC_PM_FUNC_REQ_SYS_IF_POWER_MODE = 18,
IMX_SC_PM_FUNC_SET_CLOCK_RATE = 5,
IMX_SC_PM_FUNC_GET_CLOCK_RATE = 6,
IMX_SC_PM_FUNC_CLOCK_ENABLE = 7,
IMX_SC_PM_FUNC_SET_CLOCK_PARENT = 14,
IMX_SC_PM_FUNC_GET_CLOCK_PARENT = 15,
IMX_SC_PM_FUNC_RESET = 13,
IMX_SC_PM_FUNC_RESET_REASON = 10,
IMX_SC_PM_FUNC_BOOT = 8,
IMX_SC_PM_FUNC_REBOOT = 9,
IMX_SC_PM_FUNC_REBOOT_PARTITION = 12,
IMX_SC_PM_FUNC_CPU_START = 11,
};
/*
* Defines for ALL parameters
*/
#define IMX_SC_PM_CLK_ALL UINT8_MAX /* All clocks */
/*
* Defines for SC PM Power Mode
*/
#define IMX_SC_PM_PW_MODE_OFF 0 /* Power off */
#define IMX_SC_PM_PW_MODE_STBY 1 /* Power in standby */
#define IMX_SC_PM_PW_MODE_LP 2 /* Power in low-power */
#define IMX_SC_PM_PW_MODE_ON 3 /* Power on */
/*
* Defines for SC PM CLK
*/
#define IMX_SC_PM_CLK_SLV_BUS 0 /* Slave bus clock */
#define IMX_SC_PM_CLK_MST_BUS 1 /* Master bus clock */
#define IMX_SC_PM_CLK_PER 2 /* Peripheral clock */
#define IMX_SC_PM_CLK_PHY 3 /* Phy clock */
#define IMX_SC_PM_CLK_MISC 4 /* Misc clock */
#define IMX_SC_PM_CLK_MISC0 0 /* Misc 0 clock */
#define IMX_SC_PM_CLK_MISC1 1 /* Misc 1 clock */
#define IMX_SC_PM_CLK_MISC2 2 /* Misc 2 clock */
#define IMX_SC_PM_CLK_MISC3 3 /* Misc 3 clock */
#define IMX_SC_PM_CLK_MISC4 4 /* Misc 4 clock */
#define IMX_SC_PM_CLK_CPU 2 /* CPU clock */
#define IMX_SC_PM_CLK_PLL 4 /* PLL */
#define IMX_SC_PM_CLK_BYPASS 4 /* Bypass clock */
/*
* Defines for SC PM CLK Parent
*/
#define IMX_SC_PM_PARENT_XTAL 0 /* Parent is XTAL. */
#define IMX_SC_PM_PARENT_PLL0 1 /* Parent is PLL0 */
#define IMX_SC_PM_PARENT_PLL1 2 /* Parent is PLL1 or PLL0/2 */
#define IMX_SC_PM_PARENT_PLL2 3 /* Parent in PLL2 or PLL0/4 */
#define IMX_SC_PM_PARENT_BYPS 4 /* Parent is a bypass clock. */
#endif /* _SC_PM_API_H */
...@@ -9,558 +9,6 @@ ...@@ -9,558 +9,6 @@
#ifndef _SC_TYPES_H #ifndef _SC_TYPES_H
#define _SC_TYPES_H #define _SC_TYPES_H
/*
* This type is used to indicate a resource. Resources include peripherals
* and bus masters (but not memory regions). Note items from list should
* never be changed or removed (only added to at the end of the list).
*/
enum imx_sc_rsrc {
IMX_SC_R_A53 = 0,
IMX_SC_R_A53_0 = 1,
IMX_SC_R_A53_1 = 2,
IMX_SC_R_A53_2 = 3,
IMX_SC_R_A53_3 = 4,
IMX_SC_R_A72 = 5,
IMX_SC_R_A72_0 = 6,
IMX_SC_R_A72_1 = 7,
IMX_SC_R_A72_2 = 8,
IMX_SC_R_A72_3 = 9,
IMX_SC_R_CCI = 10,
IMX_SC_R_DB = 11,
IMX_SC_R_DRC_0 = 12,
IMX_SC_R_DRC_1 = 13,
IMX_SC_R_GIC_SMMU = 14,
IMX_SC_R_IRQSTR_M4_0 = 15,
IMX_SC_R_IRQSTR_M4_1 = 16,
IMX_SC_R_SMMU = 17,
IMX_SC_R_GIC = 18,
IMX_SC_R_DC_0_BLIT0 = 19,
IMX_SC_R_DC_0_BLIT1 = 20,
IMX_SC_R_DC_0_BLIT2 = 21,
IMX_SC_R_DC_0_BLIT_OUT = 22,
IMX_SC_R_DC_0_CAPTURE0 = 23,
IMX_SC_R_DC_0_CAPTURE1 = 24,
IMX_SC_R_DC_0_WARP = 25,
IMX_SC_R_DC_0_INTEGRAL0 = 26,
IMX_SC_R_DC_0_INTEGRAL1 = 27,
IMX_SC_R_DC_0_VIDEO0 = 28,
IMX_SC_R_DC_0_VIDEO1 = 29,
IMX_SC_R_DC_0_FRAC0 = 30,
IMX_SC_R_DC_0_FRAC1 = 31,
IMX_SC_R_DC_0 = 32,
IMX_SC_R_GPU_2_PID0 = 33,
IMX_SC_R_DC_0_PLL_0 = 34,
IMX_SC_R_DC_0_PLL_1 = 35,
IMX_SC_R_DC_1_BLIT0 = 36,
IMX_SC_R_DC_1_BLIT1 = 37,
IMX_SC_R_DC_1_BLIT2 = 38,
IMX_SC_R_DC_1_BLIT_OUT = 39,
IMX_SC_R_DC_1_CAPTURE0 = 40,
IMX_SC_R_DC_1_CAPTURE1 = 41,
IMX_SC_R_DC_1_WARP = 42,
IMX_SC_R_DC_1_INTEGRAL0 = 43,
IMX_SC_R_DC_1_INTEGRAL1 = 44,
IMX_SC_R_DC_1_VIDEO0 = 45,
IMX_SC_R_DC_1_VIDEO1 = 46,
IMX_SC_R_DC_1_FRAC0 = 47,
IMX_SC_R_DC_1_FRAC1 = 48,
IMX_SC_R_DC_1 = 49,
IMX_SC_R_GPU_3_PID0 = 50,
IMX_SC_R_DC_1_PLL_0 = 51,
IMX_SC_R_DC_1_PLL_1 = 52,
IMX_SC_R_SPI_0 = 53,
IMX_SC_R_SPI_1 = 54,
IMX_SC_R_SPI_2 = 55,
IMX_SC_R_SPI_3 = 56,
IMX_SC_R_UART_0 = 57,
IMX_SC_R_UART_1 = 58,
IMX_SC_R_UART_2 = 59,
IMX_SC_R_UART_3 = 60,
IMX_SC_R_UART_4 = 61,
IMX_SC_R_EMVSIM_0 = 62,
IMX_SC_R_EMVSIM_1 = 63,
IMX_SC_R_DMA_0_CH0 = 64,
IMX_SC_R_DMA_0_CH1 = 65,
IMX_SC_R_DMA_0_CH2 = 66,
IMX_SC_R_DMA_0_CH3 = 67,
IMX_SC_R_DMA_0_CH4 = 68,
IMX_SC_R_DMA_0_CH5 = 69,
IMX_SC_R_DMA_0_CH6 = 70,
IMX_SC_R_DMA_0_CH7 = 71,
IMX_SC_R_DMA_0_CH8 = 72,
IMX_SC_R_DMA_0_CH9 = 73,
IMX_SC_R_DMA_0_CH10 = 74,
IMX_SC_R_DMA_0_CH11 = 75,
IMX_SC_R_DMA_0_CH12 = 76,
IMX_SC_R_DMA_0_CH13 = 77,
IMX_SC_R_DMA_0_CH14 = 78,
IMX_SC_R_DMA_0_CH15 = 79,
IMX_SC_R_DMA_0_CH16 = 80,
IMX_SC_R_DMA_0_CH17 = 81,
IMX_SC_R_DMA_0_CH18 = 82,
IMX_SC_R_DMA_0_CH19 = 83,
IMX_SC_R_DMA_0_CH20 = 84,
IMX_SC_R_DMA_0_CH21 = 85,
IMX_SC_R_DMA_0_CH22 = 86,
IMX_SC_R_DMA_0_CH23 = 87,
IMX_SC_R_DMA_0_CH24 = 88,
IMX_SC_R_DMA_0_CH25 = 89,
IMX_SC_R_DMA_0_CH26 = 90,
IMX_SC_R_DMA_0_CH27 = 91,
IMX_SC_R_DMA_0_CH28 = 92,
IMX_SC_R_DMA_0_CH29 = 93,
IMX_SC_R_DMA_0_CH30 = 94,
IMX_SC_R_DMA_0_CH31 = 95,
IMX_SC_R_I2C_0 = 96,
IMX_SC_R_I2C_1 = 97,
IMX_SC_R_I2C_2 = 98,
IMX_SC_R_I2C_3 = 99,
IMX_SC_R_I2C_4 = 100,
IMX_SC_R_ADC_0 = 101,
IMX_SC_R_ADC_1 = 102,
IMX_SC_R_FTM_0 = 103,
IMX_SC_R_FTM_1 = 104,
IMX_SC_R_CAN_0 = 105,
IMX_SC_R_CAN_1 = 106,
IMX_SC_R_CAN_2 = 107,
IMX_SC_R_DMA_1_CH0 = 108,
IMX_SC_R_DMA_1_CH1 = 109,
IMX_SC_R_DMA_1_CH2 = 110,
IMX_SC_R_DMA_1_CH3 = 111,
IMX_SC_R_DMA_1_CH4 = 112,
IMX_SC_R_DMA_1_CH5 = 113,
IMX_SC_R_DMA_1_CH6 = 114,
IMX_SC_R_DMA_1_CH7 = 115,
IMX_SC_R_DMA_1_CH8 = 116,
IMX_SC_R_DMA_1_CH9 = 117,
IMX_SC_R_DMA_1_CH10 = 118,
IMX_SC_R_DMA_1_CH11 = 119,
IMX_SC_R_DMA_1_CH12 = 120,
IMX_SC_R_DMA_1_CH13 = 121,
IMX_SC_R_DMA_1_CH14 = 122,
IMX_SC_R_DMA_1_CH15 = 123,
IMX_SC_R_DMA_1_CH16 = 124,
IMX_SC_R_DMA_1_CH17 = 125,
IMX_SC_R_DMA_1_CH18 = 126,
IMX_SC_R_DMA_1_CH19 = 127,
IMX_SC_R_DMA_1_CH20 = 128,
IMX_SC_R_DMA_1_CH21 = 129,
IMX_SC_R_DMA_1_CH22 = 130,
IMX_SC_R_DMA_1_CH23 = 131,
IMX_SC_R_DMA_1_CH24 = 132,
IMX_SC_R_DMA_1_CH25 = 133,
IMX_SC_R_DMA_1_CH26 = 134,
IMX_SC_R_DMA_1_CH27 = 135,
IMX_SC_R_DMA_1_CH28 = 136,
IMX_SC_R_DMA_1_CH29 = 137,
IMX_SC_R_DMA_1_CH30 = 138,
IMX_SC_R_DMA_1_CH31 = 139,
IMX_SC_R_UNUSED1 = 140,
IMX_SC_R_UNUSED2 = 141,
IMX_SC_R_UNUSED3 = 142,
IMX_SC_R_UNUSED4 = 143,
IMX_SC_R_GPU_0_PID0 = 144,
IMX_SC_R_GPU_0_PID1 = 145,
IMX_SC_R_GPU_0_PID2 = 146,
IMX_SC_R_GPU_0_PID3 = 147,
IMX_SC_R_GPU_1_PID0 = 148,
IMX_SC_R_GPU_1_PID1 = 149,
IMX_SC_R_GPU_1_PID2 = 150,
IMX_SC_R_GPU_1_PID3 = 151,
IMX_SC_R_PCIE_A = 152,
IMX_SC_R_SERDES_0 = 153,
IMX_SC_R_MATCH_0 = 154,
IMX_SC_R_MATCH_1 = 155,
IMX_SC_R_MATCH_2 = 156,
IMX_SC_R_MATCH_3 = 157,
IMX_SC_R_MATCH_4 = 158,
IMX_SC_R_MATCH_5 = 159,
IMX_SC_R_MATCH_6 = 160,
IMX_SC_R_MATCH_7 = 161,
IMX_SC_R_MATCH_8 = 162,
IMX_SC_R_MATCH_9 = 163,
IMX_SC_R_MATCH_10 = 164,
IMX_SC_R_MATCH_11 = 165,
IMX_SC_R_MATCH_12 = 166,
IMX_SC_R_MATCH_13 = 167,
IMX_SC_R_MATCH_14 = 168,
IMX_SC_R_PCIE_B = 169,
IMX_SC_R_SATA_0 = 170,
IMX_SC_R_SERDES_1 = 171,
IMX_SC_R_HSIO_GPIO = 172,
IMX_SC_R_MATCH_15 = 173,
IMX_SC_R_MATCH_16 = 174,
IMX_SC_R_MATCH_17 = 175,
IMX_SC_R_MATCH_18 = 176,
IMX_SC_R_MATCH_19 = 177,
IMX_SC_R_MATCH_20 = 178,
IMX_SC_R_MATCH_21 = 179,
IMX_SC_R_MATCH_22 = 180,
IMX_SC_R_MATCH_23 = 181,
IMX_SC_R_MATCH_24 = 182,
IMX_SC_R_MATCH_25 = 183,
IMX_SC_R_MATCH_26 = 184,
IMX_SC_R_MATCH_27 = 185,
IMX_SC_R_MATCH_28 = 186,
IMX_SC_R_LCD_0 = 187,
IMX_SC_R_LCD_0_PWM_0 = 188,
IMX_SC_R_LCD_0_I2C_0 = 189,
IMX_SC_R_LCD_0_I2C_1 = 190,
IMX_SC_R_PWM_0 = 191,
IMX_SC_R_PWM_1 = 192,
IMX_SC_R_PWM_2 = 193,
IMX_SC_R_PWM_3 = 194,
IMX_SC_R_PWM_4 = 195,
IMX_SC_R_PWM_5 = 196,
IMX_SC_R_PWM_6 = 197,
IMX_SC_R_PWM_7 = 198,
IMX_SC_R_GPIO_0 = 199,
IMX_SC_R_GPIO_1 = 200,
IMX_SC_R_GPIO_2 = 201,
IMX_SC_R_GPIO_3 = 202,
IMX_SC_R_GPIO_4 = 203,
IMX_SC_R_GPIO_5 = 204,
IMX_SC_R_GPIO_6 = 205,
IMX_SC_R_GPIO_7 = 206,
IMX_SC_R_GPT_0 = 207,
IMX_SC_R_GPT_1 = 208,
IMX_SC_R_GPT_2 = 209,
IMX_SC_R_GPT_3 = 210,
IMX_SC_R_GPT_4 = 211,
IMX_SC_R_KPP = 212,
IMX_SC_R_MU_0A = 213,
IMX_SC_R_MU_1A = 214,
IMX_SC_R_MU_2A = 215,
IMX_SC_R_MU_3A = 216,
IMX_SC_R_MU_4A = 217,
IMX_SC_R_MU_5A = 218,
IMX_SC_R_MU_6A = 219,
IMX_SC_R_MU_7A = 220,
IMX_SC_R_MU_8A = 221,
IMX_SC_R_MU_9A = 222,
IMX_SC_R_MU_10A = 223,
IMX_SC_R_MU_11A = 224,
IMX_SC_R_MU_12A = 225,
IMX_SC_R_MU_13A = 226,
IMX_SC_R_MU_5B = 227,
IMX_SC_R_MU_6B = 228,
IMX_SC_R_MU_7B = 229,
IMX_SC_R_MU_8B = 230,
IMX_SC_R_MU_9B = 231,
IMX_SC_R_MU_10B = 232,
IMX_SC_R_MU_11B = 233,
IMX_SC_R_MU_12B = 234,
IMX_SC_R_MU_13B = 235,
IMX_SC_R_ROM_0 = 236,
IMX_SC_R_FSPI_0 = 237,
IMX_SC_R_FSPI_1 = 238,
IMX_SC_R_IEE = 239,
IMX_SC_R_IEE_R0 = 240,
IMX_SC_R_IEE_R1 = 241,
IMX_SC_R_IEE_R2 = 242,
IMX_SC_R_IEE_R3 = 243,
IMX_SC_R_IEE_R4 = 244,
IMX_SC_R_IEE_R5 = 245,
IMX_SC_R_IEE_R6 = 246,
IMX_SC_R_IEE_R7 = 247,
IMX_SC_R_SDHC_0 = 248,
IMX_SC_R_SDHC_1 = 249,
IMX_SC_R_SDHC_2 = 250,
IMX_SC_R_ENET_0 = 251,
IMX_SC_R_ENET_1 = 252,
IMX_SC_R_MLB_0 = 253,
IMX_SC_R_DMA_2_CH0 = 254,
IMX_SC_R_DMA_2_CH1 = 255,
IMX_SC_R_DMA_2_CH2 = 256,
IMX_SC_R_DMA_2_CH3 = 257,
IMX_SC_R_DMA_2_CH4 = 258,
IMX_SC_R_USB_0 = 259,
IMX_SC_R_USB_1 = 260,
IMX_SC_R_USB_0_PHY = 261,
IMX_SC_R_USB_2 = 262,
IMX_SC_R_USB_2_PHY = 263,
IMX_SC_R_DTCP = 264,
IMX_SC_R_NAND = 265,
IMX_SC_R_LVDS_0 = 266,
IMX_SC_R_LVDS_0_PWM_0 = 267,
IMX_SC_R_LVDS_0_I2C_0 = 268,
IMX_SC_R_LVDS_0_I2C_1 = 269,
IMX_SC_R_LVDS_1 = 270,
IMX_SC_R_LVDS_1_PWM_0 = 271,
IMX_SC_R_LVDS_1_I2C_0 = 272,
IMX_SC_R_LVDS_1_I2C_1 = 273,
IMX_SC_R_LVDS_2 = 274,
IMX_SC_R_LVDS_2_PWM_0 = 275,
IMX_SC_R_LVDS_2_I2C_0 = 276,
IMX_SC_R_LVDS_2_I2C_1 = 277,
IMX_SC_R_M4_0_PID0 = 278,
IMX_SC_R_M4_0_PID1 = 279,
IMX_SC_R_M4_0_PID2 = 280,
IMX_SC_R_M4_0_PID3 = 281,
IMX_SC_R_M4_0_PID4 = 282,
IMX_SC_R_M4_0_RGPIO = 283,
IMX_SC_R_M4_0_SEMA42 = 284,
IMX_SC_R_M4_0_TPM = 285,
IMX_SC_R_M4_0_PIT = 286,
IMX_SC_R_M4_0_UART = 287,
IMX_SC_R_M4_0_I2C = 288,
IMX_SC_R_M4_0_INTMUX = 289,
IMX_SC_R_M4_0_SIM = 290,
IMX_SC_R_M4_0_WDOG = 291,
IMX_SC_R_M4_0_MU_0B = 292,
IMX_SC_R_M4_0_MU_0A0 = 293,
IMX_SC_R_M4_0_MU_0A1 = 294,
IMX_SC_R_M4_0_MU_0A2 = 295,
IMX_SC_R_M4_0_MU_0A3 = 296,
IMX_SC_R_M4_0_MU_1A = 297,
IMX_SC_R_M4_1_PID0 = 298,
IMX_SC_R_M4_1_PID1 = 299,
IMX_SC_R_M4_1_PID2 = 300,
IMX_SC_R_M4_1_PID3 = 301,
IMX_SC_R_M4_1_PID4 = 302,
IMX_SC_R_M4_1_RGPIO = 303,
IMX_SC_R_M4_1_SEMA42 = 304,
IMX_SC_R_M4_1_TPM = 305,
IMX_SC_R_M4_1_PIT = 306,
IMX_SC_R_M4_1_UART = 307,
IMX_SC_R_M4_1_I2C = 308,
IMX_SC_R_M4_1_INTMUX = 309,
IMX_SC_R_M4_1_SIM = 310,
IMX_SC_R_M4_1_WDOG = 311,
IMX_SC_R_M4_1_MU_0B = 312,
IMX_SC_R_M4_1_MU_0A0 = 313,
IMX_SC_R_M4_1_MU_0A1 = 314,
IMX_SC_R_M4_1_MU_0A2 = 315,
IMX_SC_R_M4_1_MU_0A3 = 316,
IMX_SC_R_M4_1_MU_1A = 317,
IMX_SC_R_SAI_0 = 318,
IMX_SC_R_SAI_1 = 319,
IMX_SC_R_SAI_2 = 320,
IMX_SC_R_IRQSTR_SCU2 = 321,
IMX_SC_R_IRQSTR_DSP = 322,
IMX_SC_R_UNUSED5 = 323,
IMX_SC_R_UNUSED6 = 324,
IMX_SC_R_AUDIO_PLL_0 = 325,
IMX_SC_R_PI_0 = 326,
IMX_SC_R_PI_0_PWM_0 = 327,
IMX_SC_R_PI_0_PWM_1 = 328,
IMX_SC_R_PI_0_I2C_0 = 329,
IMX_SC_R_PI_0_PLL = 330,
IMX_SC_R_PI_1 = 331,
IMX_SC_R_PI_1_PWM_0 = 332,
IMX_SC_R_PI_1_PWM_1 = 333,
IMX_SC_R_PI_1_I2C_0 = 334,
IMX_SC_R_PI_1_PLL = 335,
IMX_SC_R_SC_PID0 = 336,
IMX_SC_R_SC_PID1 = 337,
IMX_SC_R_SC_PID2 = 338,
IMX_SC_R_SC_PID3 = 339,
IMX_SC_R_SC_PID4 = 340,
IMX_SC_R_SC_SEMA42 = 341,
IMX_SC_R_SC_TPM = 342,
IMX_SC_R_SC_PIT = 343,
IMX_SC_R_SC_UART = 344,
IMX_SC_R_SC_I2C = 345,
IMX_SC_R_SC_MU_0B = 346,
IMX_SC_R_SC_MU_0A0 = 347,
IMX_SC_R_SC_MU_0A1 = 348,
IMX_SC_R_SC_MU_0A2 = 349,
IMX_SC_R_SC_MU_0A3 = 350,
IMX_SC_R_SC_MU_1A = 351,
IMX_SC_R_SYSCNT_RD = 352,
IMX_SC_R_SYSCNT_CMP = 353,
IMX_SC_R_DEBUG = 354,
IMX_SC_R_SYSTEM = 355,
IMX_SC_R_SNVS = 356,
IMX_SC_R_OTP = 357,
IMX_SC_R_VPU_PID0 = 358,
IMX_SC_R_VPU_PID1 = 359,
IMX_SC_R_VPU_PID2 = 360,
IMX_SC_R_VPU_PID3 = 361,
IMX_SC_R_VPU_PID4 = 362,
IMX_SC_R_VPU_PID5 = 363,
IMX_SC_R_VPU_PID6 = 364,
IMX_SC_R_VPU_PID7 = 365,
IMX_SC_R_VPU_UART = 366,
IMX_SC_R_VPUCORE = 367,
IMX_SC_R_VPUCORE_0 = 368,
IMX_SC_R_VPUCORE_1 = 369,
IMX_SC_R_VPUCORE_2 = 370,
IMX_SC_R_VPUCORE_3 = 371,
IMX_SC_R_DMA_4_CH0 = 372,
IMX_SC_R_DMA_4_CH1 = 373,
IMX_SC_R_DMA_4_CH2 = 374,
IMX_SC_R_DMA_4_CH3 = 375,
IMX_SC_R_DMA_4_CH4 = 376,
IMX_SC_R_ISI_CH0 = 377,
IMX_SC_R_ISI_CH1 = 378,
IMX_SC_R_ISI_CH2 = 379,
IMX_SC_R_ISI_CH3 = 380,
IMX_SC_R_ISI_CH4 = 381,
IMX_SC_R_ISI_CH5 = 382,
IMX_SC_R_ISI_CH6 = 383,
IMX_SC_R_ISI_CH7 = 384,
IMX_SC_R_MJPEG_DEC_S0 = 385,
IMX_SC_R_MJPEG_DEC_S1 = 386,
IMX_SC_R_MJPEG_DEC_S2 = 387,
IMX_SC_R_MJPEG_DEC_S3 = 388,
IMX_SC_R_MJPEG_ENC_S0 = 389,
IMX_SC_R_MJPEG_ENC_S1 = 390,
IMX_SC_R_MJPEG_ENC_S2 = 391,
IMX_SC_R_MJPEG_ENC_S3 = 392,
IMX_SC_R_MIPI_0 = 393,
IMX_SC_R_MIPI_0_PWM_0 = 394,
IMX_SC_R_MIPI_0_I2C_0 = 395,
IMX_SC_R_MIPI_0_I2C_1 = 396,
IMX_SC_R_MIPI_1 = 397,
IMX_SC_R_MIPI_1_PWM_0 = 398,
IMX_SC_R_MIPI_1_I2C_0 = 399,
IMX_SC_R_MIPI_1_I2C_1 = 400,
IMX_SC_R_CSI_0 = 401,
IMX_SC_R_CSI_0_PWM_0 = 402,
IMX_SC_R_CSI_0_I2C_0 = 403,
IMX_SC_R_CSI_1 = 404,
IMX_SC_R_CSI_1_PWM_0 = 405,
IMX_SC_R_CSI_1_I2C_0 = 406,
IMX_SC_R_HDMI = 407,
IMX_SC_R_HDMI_I2S = 408,
IMX_SC_R_HDMI_I2C_0 = 409,
IMX_SC_R_HDMI_PLL_0 = 410,
IMX_SC_R_HDMI_RX = 411,
IMX_SC_R_HDMI_RX_BYPASS = 412,
IMX_SC_R_HDMI_RX_I2C_0 = 413,
IMX_SC_R_ASRC_0 = 414,
IMX_SC_R_ESAI_0 = 415,
IMX_SC_R_SPDIF_0 = 416,
IMX_SC_R_SPDIF_1 = 417,
IMX_SC_R_SAI_3 = 418,
IMX_SC_R_SAI_4 = 419,
IMX_SC_R_SAI_5 = 420,
IMX_SC_R_GPT_5 = 421,
IMX_SC_R_GPT_6 = 422,
IMX_SC_R_GPT_7 = 423,
IMX_SC_R_GPT_8 = 424,
IMX_SC_R_GPT_9 = 425,
IMX_SC_R_GPT_10 = 426,
IMX_SC_R_DMA_2_CH5 = 427,
IMX_SC_R_DMA_2_CH6 = 428,
IMX_SC_R_DMA_2_CH7 = 429,
IMX_SC_R_DMA_2_CH8 = 430,
IMX_SC_R_DMA_2_CH9 = 431,
IMX_SC_R_DMA_2_CH10 = 432,
IMX_SC_R_DMA_2_CH11 = 433,
IMX_SC_R_DMA_2_CH12 = 434,
IMX_SC_R_DMA_2_CH13 = 435,
IMX_SC_R_DMA_2_CH14 = 436,
IMX_SC_R_DMA_2_CH15 = 437,
IMX_SC_R_DMA_2_CH16 = 438,
IMX_SC_R_DMA_2_CH17 = 439,
IMX_SC_R_DMA_2_CH18 = 440,
IMX_SC_R_DMA_2_CH19 = 441,
IMX_SC_R_DMA_2_CH20 = 442,
IMX_SC_R_DMA_2_CH21 = 443,
IMX_SC_R_DMA_2_CH22 = 444,
IMX_SC_R_DMA_2_CH23 = 445,
IMX_SC_R_DMA_2_CH24 = 446,
IMX_SC_R_DMA_2_CH25 = 447,
IMX_SC_R_DMA_2_CH26 = 448,
IMX_SC_R_DMA_2_CH27 = 449,
IMX_SC_R_DMA_2_CH28 = 450,
IMX_SC_R_DMA_2_CH29 = 451,
IMX_SC_R_DMA_2_CH30 = 452,
IMX_SC_R_DMA_2_CH31 = 453,
IMX_SC_R_ASRC_1 = 454,
IMX_SC_R_ESAI_1 = 455,
IMX_SC_R_SAI_6 = 456,
IMX_SC_R_SAI_7 = 457,
IMX_SC_R_AMIX = 458,
IMX_SC_R_MQS_0 = 459,
IMX_SC_R_DMA_3_CH0 = 460,
IMX_SC_R_DMA_3_CH1 = 461,
IMX_SC_R_DMA_3_CH2 = 462,
IMX_SC_R_DMA_3_CH3 = 463,
IMX_SC_R_DMA_3_CH4 = 464,
IMX_SC_R_DMA_3_CH5 = 465,
IMX_SC_R_DMA_3_CH6 = 466,
IMX_SC_R_DMA_3_CH7 = 467,
IMX_SC_R_DMA_3_CH8 = 468,
IMX_SC_R_DMA_3_CH9 = 469,
IMX_SC_R_DMA_3_CH10 = 470,
IMX_SC_R_DMA_3_CH11 = 471,
IMX_SC_R_DMA_3_CH12 = 472,
IMX_SC_R_DMA_3_CH13 = 473,
IMX_SC_R_DMA_3_CH14 = 474,
IMX_SC_R_DMA_3_CH15 = 475,
IMX_SC_R_DMA_3_CH16 = 476,
IMX_SC_R_DMA_3_CH17 = 477,
IMX_SC_R_DMA_3_CH18 = 478,
IMX_SC_R_DMA_3_CH19 = 479,
IMX_SC_R_DMA_3_CH20 = 480,
IMX_SC_R_DMA_3_CH21 = 481,
IMX_SC_R_DMA_3_CH22 = 482,
IMX_SC_R_DMA_3_CH23 = 483,
IMX_SC_R_DMA_3_CH24 = 484,
IMX_SC_R_DMA_3_CH25 = 485,
IMX_SC_R_DMA_3_CH26 = 486,
IMX_SC_R_DMA_3_CH27 = 487,
IMX_SC_R_DMA_3_CH28 = 488,
IMX_SC_R_DMA_3_CH29 = 489,
IMX_SC_R_DMA_3_CH30 = 490,
IMX_SC_R_DMA_3_CH31 = 491,
IMX_SC_R_AUDIO_PLL_1 = 492,
IMX_SC_R_AUDIO_CLK_0 = 493,
IMX_SC_R_AUDIO_CLK_1 = 494,
IMX_SC_R_MCLK_OUT_0 = 495,
IMX_SC_R_MCLK_OUT_1 = 496,
IMX_SC_R_PMIC_0 = 497,
IMX_SC_R_PMIC_1 = 498,
IMX_SC_R_SECO = 499,
IMX_SC_R_CAAM_JR1 = 500,
IMX_SC_R_CAAM_JR2 = 501,
IMX_SC_R_CAAM_JR3 = 502,
IMX_SC_R_SECO_MU_2 = 503,
IMX_SC_R_SECO_MU_3 = 504,
IMX_SC_R_SECO_MU_4 = 505,
IMX_SC_R_HDMI_RX_PWM_0 = 506,
IMX_SC_R_A35 = 507,
IMX_SC_R_A35_0 = 508,
IMX_SC_R_A35_1 = 509,
IMX_SC_R_A35_2 = 510,
IMX_SC_R_A35_3 = 511,
IMX_SC_R_DSP = 512,
IMX_SC_R_DSP_RAM = 513,
IMX_SC_R_CAAM_JR1_OUT = 514,
IMX_SC_R_CAAM_JR2_OUT = 515,
IMX_SC_R_CAAM_JR3_OUT = 516,
IMX_SC_R_VPU_DEC_0 = 517,
IMX_SC_R_VPU_ENC_0 = 518,
IMX_SC_R_CAAM_JR0 = 519,
IMX_SC_R_CAAM_JR0_OUT = 520,
IMX_SC_R_PMIC_2 = 521,
IMX_SC_R_DBLOGIC = 522,
IMX_SC_R_HDMI_PLL_1 = 523,
IMX_SC_R_BOARD_R0 = 524,
IMX_SC_R_BOARD_R1 = 525,
IMX_SC_R_BOARD_R2 = 526,
IMX_SC_R_BOARD_R3 = 527,
IMX_SC_R_BOARD_R4 = 528,
IMX_SC_R_BOARD_R5 = 529,
IMX_SC_R_BOARD_R6 = 530,
IMX_SC_R_BOARD_R7 = 531,
IMX_SC_R_MJPEG_DEC_MP = 532,
IMX_SC_R_MJPEG_ENC_MP = 533,
IMX_SC_R_VPU_TS_0 = 534,
IMX_SC_R_VPU_MU_0 = 535,
IMX_SC_R_VPU_MU_1 = 536,
IMX_SC_R_VPU_MU_2 = 537,
IMX_SC_R_VPU_MU_3 = 538,
IMX_SC_R_VPU_ENC_1 = 539,
IMX_SC_R_VPU = 540,
IMX_SC_R_LAST
};
/* NOTE - please add by replacing some of the UNUSED from above! */
/* /*
* This type is used to indicate a control. * This type is used to indicate a control.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment