Merge branches 'clk-imx', 'clk-samsung', 'clk-ti', 'clk-uniphier-gear' and 'clk-mmp2-lcdc' into clk-next
- Split LCDC into two clks on the Marvell MMP2 SoC * clk-imx: clk: imx8mq: add GPIO clocks to clock tree clk: imx: Refactor entire sccg pll clk clk: imx: scu: add cpu frequency scaling support clk: imx: imx8mm: Mark init function __init clk: imx8mq: Add the missing ARM clock dt-bindings: imx8mq-clock: Add the missing ARM clock clk: imx: imx8mq: Fix the rate propagation for arm pll clk: imx8mq: Add support for the CLKO1 clock clk: imx8mq: Fix the CLKO2 source select list clk: imx8mq: Add missing M4 clocks clk: imx: Add clock driver support for imx8mm dt-bindings: imx: Add clock binding doc for imx8mm clk: imx: Add PLLs driver for imx8mm soc clk: imx5: add imx5_SCC2_IPG_GATE clk: imx: scu: add set parent support clk: imx: scu: add fallback compatible string support clk: imx8mq: Make parent names arrays const pointers clk: imx: Make parents const pointer in mux wrappers clk: imx: Make parent_names const pointer in composite-8m * clk-samsung: clk: samsung: s3c2443: Mark expected switch fall-through clk: samsung: exynos5: Fix kfree() of const memory on setting driver_override clk: samsung: exynos5: Fix possible NULL pointer exception on platform_device_alloc() failure clk: samsung: exynos5433: Add selected IMEM clocks clk: samsung: dt-bindings: Document Exynos5433 IMEM CMU clk: samsung: exynos5433: Fix name typo in sssx clk: samsung: exynos5433: Fix definition of CLK_ACLK_IMEM_{200, 266} clocks clk: samsung: dt-bindings: Add Exynos5433 IMEM CMU clock IDs * clk-ti: clk: clk-twl6040: Fix imprecise external abort for pdmclk ARM: OMAP2+: hwmod: disable ick autoidling when a hwmod requires that clk: ti: check clock type before doing autoidle ops clk: ti: add a usecount for autoidle clk: ti: generalize the init sequence of clk_hw_omap clocks clk: ti: remove usage of CLK_IS_BASIC clk: ti: add new API for checking if a provided clock is an OMAP clock clk: ti: move clk_hw_omap list handling under generic part of the driver * clk-uniphier-gear: clk: uniphier: Fix update register for CPU-gear * clk-mmp2-lcdc: clk: mmp2: separate LCDC peripheral clk form the display clock dt-bindings: marvell,mmp2: Add clock id for the LCDC clock
This commit is contained in:
commit
e7faa095cb
@ -50,6 +50,8 @@ Required Properties:
|
||||
IPs.
|
||||
- "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1
|
||||
which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs.
|
||||
- "samsung,exynos5433-cmu-imem" - clock controller compatible for CMU_IMEM
|
||||
which generates clocks for SSS (Security SubSystem) and SlimSSS IPs.
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
@ -168,6 +170,12 @@ Required Properties:
|
||||
- aclk_cam1_400
|
||||
- aclk_cam1_552
|
||||
|
||||
Input clocks for imem clock controller:
|
||||
- oscclk
|
||||
- aclk_imem_sssx_266
|
||||
- aclk_imem_266
|
||||
- aclk_imem_200
|
||||
|
||||
Optional properties:
|
||||
- power-domains: a phandle to respective power domain node as described by
|
||||
generic PM domain bindings (see power/power_domain.txt for more
|
||||
@ -469,6 +477,21 @@ Example 2: Examples of clock controller nodes are listed below.
|
||||
power-domains = <&pd_cam1>;
|
||||
};
|
||||
|
||||
cmu_imem: clock-controller@11060000 {
|
||||
compatible = "samsung,exynos5433-cmu-imem";
|
||||
reg = <0x11060000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"aclk_imem_sssx_266",
|
||||
"aclk_imem_266",
|
||||
"aclk_imem_200";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_DIV_ACLK_IMEM_SSSX_266>,
|
||||
<&cmu_top CLK_DIV_ACLK_IMEM_266>,
|
||||
<&cmu_top CLK_DIV_ACLK_IMEM_200>;
|
||||
};
|
||||
|
||||
Example 3: UART controller node that consumes the clock generated by the clock
|
||||
controller.
|
||||
|
||||
|
29
Documentation/devicetree/bindings/clock/imx8mm-clock.txt
Normal file
29
Documentation/devicetree/bindings/clock/imx8mm-clock.txt
Normal file
@ -0,0 +1,29 @@
|
||||
* Clock bindings for NXP i.MX8M Mini
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,imx8mm-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:
|
||||
- "osc_32k"
|
||||
- "osc_24m"
|
||||
- "clk_ext1"
|
||||
- "clk_ext2"
|
||||
- "clk_ext3"
|
||||
- "clk_ext4"
|
||||
|
||||
clk: clock-controller@30380000 {
|
||||
compatible = "fsl,imx8mm-ccm";
|
||||
reg = <0x0 0x30380000 0x0 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
|
||||
<&clk_ext3>, <&clk_ext4>;
|
||||
clock-names = "osc_32k", "osc_24m", "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/imx8mm-clock.h
|
||||
for the full list of i.MX8M Mini clock IDs.
|
@ -1002,8 +1002,10 @@ static int _enable_clocks(struct omap_hwmod *oh)
|
||||
clk_enable(oh->_clk);
|
||||
|
||||
list_for_each_entry(os, &oh->slave_ports, node) {
|
||||
if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
|
||||
if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
|
||||
omap2_clk_deny_idle(os->_clk);
|
||||
clk_enable(os->_clk);
|
||||
}
|
||||
}
|
||||
|
||||
/* The opt clocks are controlled by the device driver. */
|
||||
@ -1055,8 +1057,10 @@ static int _disable_clocks(struct omap_hwmod *oh)
|
||||
clk_disable(oh->_clk);
|
||||
|
||||
list_for_each_entry(os, &oh->slave_ports, node) {
|
||||
if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE))
|
||||
if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
|
||||
clk_disable(os->_clk);
|
||||
omap2_clk_allow_idle(os->_clk);
|
||||
}
|
||||
}
|
||||
|
||||
if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
|
||||
@ -2436,9 +2440,13 @@ static void _setup_iclk_autoidle(struct omap_hwmod *oh)
|
||||
continue;
|
||||
|
||||
if (os->flags & OCPIF_SWSUP_IDLE) {
|
||||
/* XXX omap_iclk_deny_idle(c); */
|
||||
/*
|
||||
* we might have multiple users of one iclk with
|
||||
* different requirements, disable autoidle when
|
||||
* the module is enabled, e.g. dss iclk
|
||||
*/
|
||||
} else {
|
||||
/* XXX omap_iclk_allow_idle(c); */
|
||||
/* we are enabling autoidle afterwards anyways */
|
||||
clk_enable(os->_clk);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,43 @@ static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
|
||||
return pdmclk->enabled;
|
||||
}
|
||||
|
||||
static int twl6040_pdmclk_reset_one_clock(struct twl6040_pdmclk *pdmclk,
|
||||
unsigned int reg)
|
||||
{
|
||||
const u8 reset_mask = TWL6040_HPLLRST; /* Same for HPPLL and LPPLL */
|
||||
int ret;
|
||||
|
||||
ret = twl6040_set_bits(pdmclk->twl6040, reg, reset_mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = twl6040_clear_bits(pdmclk->twl6040, reg, reset_mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TWL6040A2 Phoenix Audio IC erratum #6: "PDM Clock Generation Issue At
|
||||
* Cold Temperature". This affects cold boot and deeper idle states it
|
||||
* seems. The workaround consists of resetting HPPLL and LPPLL.
|
||||
*/
|
||||
static int twl6040_pdmclk_quirk_reset_clocks(struct twl6040_pdmclk *pdmclk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_HPPLLCTL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_LPPLLCTL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int twl6040_pdmclk_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
|
||||
@ -48,8 +85,20 @@ static int twl6040_pdmclk_prepare(struct clk_hw *hw)
|
||||
int ret;
|
||||
|
||||
ret = twl6040_power(pdmclk->twl6040, 1);
|
||||
if (!ret)
|
||||
pdmclk->enabled = 1;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = twl6040_pdmclk_quirk_reset_clocks(pdmclk);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
pdmclk->enabled = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
dev_err(pdmclk->dev, "%s: error %i\n", __func__, ret);
|
||||
twl6040_power(pdmclk->twl6040, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -8,6 +8,12 @@ config MXC_CLK_SCU
|
||||
bool
|
||||
depends on IMX_SCU
|
||||
|
||||
config CLK_IMX8MM
|
||||
bool "IMX8MM CCM Clock Driver"
|
||||
depends on ARCH_MXC && ARM64
|
||||
help
|
||||
Build the driver for i.MX8MM CCM Clock Driver
|
||||
|
||||
config CLK_IMX8MQ
|
||||
bool "IMX8MQ CCM Clock Driver"
|
||||
depends on ARCH_MXC && ARM64
|
||||
|
@ -18,12 +18,14 @@ obj-$(CONFIG_MXC_CLK) += \
|
||||
clk-pllv2.o \
|
||||
clk-pllv3.o \
|
||||
clk-pllv4.o \
|
||||
clk-sccg-pll.o
|
||||
clk-sccg-pll.o \
|
||||
clk-pll14xx.o
|
||||
|
||||
obj-$(CONFIG_MXC_CLK_SCU) += \
|
||||
clk-scu.o \
|
||||
clk-lpcg-scu.o
|
||||
|
||||
obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
|
||||
obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
|
||||
obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
|
||||
|
||||
|
@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
|
||||
};
|
||||
|
||||
struct clk *imx8m_clk_composite_flags(const char *name,
|
||||
const char **parent_names,
|
||||
const char * const *parent_names,
|
||||
int num_parents, void __iomem *reg,
|
||||
unsigned long flags)
|
||||
{
|
||||
|
@ -428,6 +428,7 @@ static void __init mx51_clocks_init(struct device_node *np)
|
||||
clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
|
||||
clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
|
||||
clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
|
||||
clk[IMX5_CLK_SCC2_IPG_GATE] = imx_clk_gate2("scc2_gate", "ipg", MXC_CCM_CCGR1, 30);
|
||||
clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL);
|
||||
clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL);
|
||||
clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL);
|
||||
|
675
drivers/clk/imx/clk-imx8mm.c
Normal file
675
drivers/clk/imx/clk-imx8mm.c
Normal file
@ -0,0 +1,675 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2017-2018 NXP.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/imx8mm-clock.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.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_pdm;
|
||||
static u32 share_count_nand;
|
||||
|
||||
#define PLL_1416X_RATE(_rate, _m, _p, _s) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
}
|
||||
|
||||
#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
.kdiv = (_k), \
|
||||
}
|
||||
|
||||
static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
|
||||
PLL_1416X_RATE(1800000000U, 225, 3, 0),
|
||||
PLL_1416X_RATE(1600000000U, 200, 3, 0),
|
||||
PLL_1416X_RATE(1200000000U, 300, 3, 1),
|
||||
PLL_1416X_RATE(1000000000U, 250, 3, 1),
|
||||
PLL_1416X_RATE(800000000U, 200, 3, 1),
|
||||
PLL_1416X_RATE(750000000U, 250, 2, 2),
|
||||
PLL_1416X_RATE(700000000U, 350, 3, 2),
|
||||
PLL_1416X_RATE(600000000U, 300, 3, 2),
|
||||
};
|
||||
|
||||
static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
|
||||
PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
|
||||
PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
|
||||
};
|
||||
|
||||
static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
|
||||
PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
|
||||
PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
|
||||
};
|
||||
|
||||
static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
|
||||
PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
|
||||
.type = PLL_1443X,
|
||||
.rate_table = imx8mm_audiopll_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
|
||||
.type = PLL_1443X,
|
||||
.rate_table = imx8mm_videopll_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_videopll_tbl),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
|
||||
.type = PLL_1443X,
|
||||
.rate_table = imx8mm_drampll_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
|
||||
.type = PLL_1416X,
|
||||
.rate_table = imx8mm_pll1416x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
|
||||
.type = PLL_1416X,
|
||||
.rate_table = imx8mm_pll1416x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
|
||||
.type = PLL_1416X,
|
||||
.rate_table = imx8mm_pll1416x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
|
||||
};
|
||||
|
||||
static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
|
||||
.type = PLL_1416X,
|
||||
.rate_table = imx8mm_pll1416x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
|
||||
};
|
||||
|
||||
static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
|
||||
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 *dram_pll_bypass_sels[] = {"dram_pll", "dram_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 *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
|
||||
static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
|
||||
static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
|
||||
static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
|
||||
|
||||
/* CCM ROOT */
|
||||
static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
|
||||
"sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
|
||||
|
||||
static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
|
||||
"sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
|
||||
|
||||
static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
|
||||
"sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
|
||||
|
||||
static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
|
||||
"sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
|
||||
|
||||
static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
|
||||
"sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
|
||||
|
||||
static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
|
||||
"sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
|
||||
|
||||
static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", };
|
||||
|
||||
static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
|
||||
|
||||
static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
|
||||
"audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
|
||||
|
||||
static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
|
||||
"sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
|
||||
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
|
||||
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
|
||||
"audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
|
||||
"sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
|
||||
"sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
|
||||
|
||||
static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
|
||||
"sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
|
||||
|
||||
static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
|
||||
|
||||
static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
|
||||
"sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
|
||||
|
||||
static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2",
|
||||
"clk_ext3", "clk_ext4", "sys_pll1_400m", };
|
||||
|
||||
static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
|
||||
"sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
|
||||
|
||||
static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
|
||||
"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
|
||||
"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
|
||||
|
||||
static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
|
||||
|
||||
static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
|
||||
|
||||
static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
|
||||
|
||||
static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
|
||||
|
||||
static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
|
||||
"sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
|
||||
|
||||
static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
|
||||
"clk_ext3", "clk_ext4", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
|
||||
"sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
|
||||
"audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
|
||||
"audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
|
||||
|
||||
static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
|
||||
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
|
||||
|
||||
static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
|
||||
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
|
||||
|
||||
static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
|
||||
"sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
|
||||
"sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
|
||||
"sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
|
||||
"sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
|
||||
"sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
|
||||
"sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
|
||||
"sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
|
||||
"sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
|
||||
"sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
|
||||
"sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
|
||||
"sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
|
||||
"sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
|
||||
"video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
|
||||
|
||||
static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
|
||||
"sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
|
||||
|
||||
static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m",
|
||||
"sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
|
||||
|
||||
static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
|
||||
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
|
||||
|
||||
static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
|
||||
"sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
|
||||
|
||||
static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1",
|
||||
"clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", };
|
||||
|
||||
static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
|
||||
"sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
|
||||
|
||||
static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
|
||||
"sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
|
||||
"audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
|
||||
|
||||
static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
|
||||
|
||||
static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk",
|
||||
"vpu_pll", "sys_pll1_80m", };
|
||||
|
||||
static struct clk *clks[IMX8MM_CLK_END];
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
static struct clk ** const uart_clks[] __initconst = {
|
||||
&clks[IMX8MM_CLK_UART1_ROOT],
|
||||
&clks[IMX8MM_CLK_UART2_ROOT],
|
||||
&clks[IMX8MM_CLK_UART3_ROOT],
|
||||
&clks[IMX8MM_CLK_UART4_ROOT],
|
||||
NULL
|
||||
};
|
||||
|
||||
static int __init imx8mm_clocks_init(struct device_node *ccm_node)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m");
|
||||
clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k");
|
||||
clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
|
||||
clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
|
||||
clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
|
||||
clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
|
||||
base = of_iomap(np, 0);
|
||||
if (WARN_ON(!base))
|
||||
return -ENOMEM;
|
||||
|
||||
clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
|
||||
clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
|
||||
clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
|
||||
clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
|
||||
clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
|
||||
clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
|
||||
clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
|
||||
clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
|
||||
clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
|
||||
clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
|
||||
clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
|
||||
|
||||
/* PLL bypass out */
|
||||
clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
||||
/* unbypass all the plls */
|
||||
clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
|
||||
clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
|
||||
clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
|
||||
clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
|
||||
clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
|
||||
clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
|
||||
clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
|
||||
clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
|
||||
clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
|
||||
clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
|
||||
|
||||
/* PLL out gate */
|
||||
clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
|
||||
clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
|
||||
clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
|
||||
clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
|
||||
clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
|
||||
clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13);
|
||||
clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13);
|
||||
clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13);
|
||||
clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13);
|
||||
clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13);
|
||||
|
||||
/* SYS PLL fixed output */
|
||||
clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
|
||||
clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
|
||||
clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
|
||||
clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
|
||||
clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
|
||||
clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
|
||||
clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
|
||||
clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
|
||||
clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
|
||||
|
||||
clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
|
||||
clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
|
||||
clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
|
||||
clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
|
||||
clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
|
||||
clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
|
||||
clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
|
||||
clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
|
||||
clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||
|
||||
np = ccm_node;
|
||||
base = of_iomap(np, 0);
|
||||
if (WARN_ON(!base))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Core Slice */
|
||||
clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
|
||||
clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
|
||||
clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
|
||||
clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
|
||||
clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
|
||||
clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
|
||||
clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
|
||||
clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
|
||||
clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
|
||||
clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
|
||||
clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
|
||||
clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
|
||||
|
||||
/* BUS */
|
||||
clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
|
||||
clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
|
||||
clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
|
||||
clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
|
||||
clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
|
||||
clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
|
||||
clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
|
||||
clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
|
||||
clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
|
||||
clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
|
||||
clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
|
||||
clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
|
||||
|
||||
/* AHB */
|
||||
clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
|
||||
clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
|
||||
|
||||
/* IPG */
|
||||
clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
|
||||
/* IP */
|
||||
clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
|
||||
clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
|
||||
clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
|
||||
clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
|
||||
clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
|
||||
clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
|
||||
clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
|
||||
clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
|
||||
clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
|
||||
clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
|
||||
clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
|
||||
clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
|
||||
clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
|
||||
clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
|
||||
clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
|
||||
clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
|
||||
clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
|
||||
clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
|
||||
clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
|
||||
clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
|
||||
clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
|
||||
clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
|
||||
clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00);
|
||||
clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
|
||||
clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
|
||||
clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
|
||||
clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
|
||||
clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
|
||||
clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
|
||||
clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
|
||||
clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
|
||||
clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
|
||||
clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
|
||||
clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
|
||||
clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
|
||||
clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
|
||||
clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
|
||||
clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
|
||||
clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
|
||||
clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
|
||||
clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
|
||||
clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
|
||||
clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
|
||||
clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
|
||||
clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
|
||||
clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
|
||||
clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
|
||||
clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
|
||||
clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
|
||||
clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
|
||||
clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
|
||||
clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
|
||||
clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
|
||||
clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
|
||||
clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
|
||||
clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
|
||||
clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
|
||||
clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
|
||||
clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
|
||||
clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
|
||||
clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
|
||||
clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
|
||||
|
||||
/* CCGR */
|
||||
clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
|
||||
clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
|
||||
clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
|
||||
clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
|
||||
clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
|
||||
clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
|
||||
clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
|
||||
clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
|
||||
clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
|
||||
clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
|
||||
clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
|
||||
clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
|
||||
clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
|
||||
clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
|
||||
clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
|
||||
clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
|
||||
clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||
clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
|
||||
clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
|
||||
|
||||
clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
|
||||
|
||||
clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
|
||||
clks[IMX8MM_CLK_A53_DIV],
|
||||
clks[IMX8MM_CLK_A53_SRC],
|
||||
clks[IMX8MM_ARM_PLL_OUT],
|
||||
clks[IMX8MM_CLK_24M]);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to register clks for i.MX8MM\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(imx8mm, "fsl,imx8mm-ccm", imx8mm_clocks_init);
|
@ -26,246 +26,246 @@ 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 * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
|
||||
static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
|
||||
static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
|
||||
static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
|
||||
static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
|
||||
static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
|
||||
static const char * const 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", };
|
||||
static const char * const sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", };
|
||||
static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", };
|
||||
static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", };
|
||||
static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", };
|
||||
|
||||
/* CCM ROOT */
|
||||
static const char *imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
|
||||
static const char * const 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",
|
||||
static const char * const imx8mq_arm_m4_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_250m", "sys1_pll_266m",
|
||||
"sys1_pll_800m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
|
||||
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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 * const 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 * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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 * const 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 * const 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 * const 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 * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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",
|
||||
static const char * const 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 * const 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 const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "osc_27m", "sys1_pll_200m",
|
||||
"audio_pll2_out", "sys2_pll_500m", "vpu_pll_out", "sys1_pll_80m", };
|
||||
static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m",
|
||||
"sys3_pll2_out", "audio_pll1_out", "video_pll1_out", "ckil", };
|
||||
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
@ -308,10 +308,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
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);
|
||||
@ -319,43 +315,15 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
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_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
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);
|
||||
@ -363,11 +331,11 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_sccg_pll("sys1_pll_out", sys1_pll_out_sels, ARRAY_SIZE(sys1_pll_out_sels), 0, 0, 0, base + 0x30, CLK_IS_CRITICAL);
|
||||
clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL);
|
||||
clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL);
|
||||
clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL);
|
||||
/* 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);
|
||||
@ -396,15 +364,19 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
|
||||
/* 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_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_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_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
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_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 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);
|
||||
@ -479,6 +451,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
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_CLKO1] = imx8m_clk_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
|
||||
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);
|
||||
@ -500,6 +473,11 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
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_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 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);
|
||||
@ -558,6 +536,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
|
||||
clks[IMX8MQ_CLK_A53_DIV],
|
||||
clks[IMX8MQ_CLK_A53_SRC],
|
||||
clks[IMX8MQ_ARM_PLL_OUT],
|
||||
clks[IMX8MQ_SYS1_PLL_800M]);
|
||||
|
||||
for (i = 0; i < IMX8MQ_CLK_END; i++)
|
||||
if (IS_ERR(clks[i]))
|
||||
pr_err("i.MX8mq clk %u register failed with %ld\n",
|
||||
|
@ -138,6 +138,7 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id imx8qxp_match[] = {
|
||||
{ .compatible = "fsl,scu-clk", },
|
||||
{ .compatible = "fsl,imx8qxp-clk", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
392
drivers/clk/imx/clk-pll14xx.c
Normal file
392
drivers/clk/imx/clk-pll14xx.c
Normal file
@ -0,0 +1,392 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2017-2018 NXP.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define GNRL_CTL 0x0
|
||||
#define DIV_CTL 0x4
|
||||
#define LOCK_STATUS BIT(31)
|
||||
#define LOCK_SEL_MASK BIT(29)
|
||||
#define CLKE_MASK BIT(11)
|
||||
#define RST_MASK BIT(9)
|
||||
#define BYPASS_MASK BIT(4)
|
||||
#define MDIV_SHIFT 12
|
||||
#define MDIV_MASK GENMASK(21, 12)
|
||||
#define PDIV_SHIFT 4
|
||||
#define PDIV_MASK GENMASK(9, 4)
|
||||
#define SDIV_SHIFT 0
|
||||
#define SDIV_MASK GENMASK(2, 0)
|
||||
#define KDIV_SHIFT 0
|
||||
#define KDIV_MASK GENMASK(15, 0)
|
||||
|
||||
#define LOCK_TIMEOUT_US 10000
|
||||
|
||||
struct clk_pll14xx {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
enum imx_pll14xx_type type;
|
||||
const struct imx_pll14xx_rate_table *rate_table;
|
||||
int rate_count;
|
||||
};
|
||||
|
||||
#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
|
||||
|
||||
static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
|
||||
struct clk_pll14xx *pll, unsigned long rate)
|
||||
{
|
||||
const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++)
|
||||
if (rate == rate_table[i].rate)
|
||||
return &rate_table[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
/* Assumming rate_table is in descending order */
|
||||
for (i = 0; i < pll->rate_count; i++)
|
||||
if (rate >= rate_table[i].rate)
|
||||
return rate_table[i].rate;
|
||||
|
||||
/* return minimum supported value */
|
||||
return rate_table[i - 1].rate;
|
||||
}
|
||||
|
||||
static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_gnrl = readl_relaxed(pll->base);
|
||||
pll_div = readl_relaxed(pll->base + 4);
|
||||
mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
|
||||
pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
|
||||
sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
|
||||
|
||||
fvco *= mdiv;
|
||||
do_div(fvco, pdiv << sdiv);
|
||||
|
||||
return fvco;
|
||||
}
|
||||
|
||||
static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
|
||||
short int kdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_gnrl = readl_relaxed(pll->base);
|
||||
pll_div_ctl0 = readl_relaxed(pll->base + 4);
|
||||
pll_div_ctl1 = readl_relaxed(pll->base + 8);
|
||||
mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
|
||||
pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
|
||||
sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
|
||||
kdiv = pll_div_ctl1 & KDIV_MASK;
|
||||
|
||||
/* fvco = (m * 65536 + k) * Fin / (p * 65536) */
|
||||
fvco *= (mdiv * 65536 + kdiv);
|
||||
pdiv *= 65536;
|
||||
|
||||
do_div(fvco, pdiv << sdiv);
|
||||
|
||||
return fvco;
|
||||
}
|
||||
|
||||
static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
|
||||
u32 pll_div)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv;
|
||||
|
||||
old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
|
||||
old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
|
||||
|
||||
return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
|
||||
}
|
||||
|
||||
static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
|
||||
u32 pll_div_ctl0, u32 pll_div_ctl1)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv, old_kdiv;
|
||||
|
||||
old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
|
||||
old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
|
||||
old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
|
||||
|
||||
return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
|
||||
rate->kdiv != old_kdiv;
|
||||
}
|
||||
|
||||
static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
|
||||
u32 pll_div_ctl0, u32 pll_div_ctl1)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv, old_kdiv;
|
||||
|
||||
old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
|
||||
old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
|
||||
old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
|
||||
|
||||
return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
|
||||
rate->kdiv != old_kdiv;
|
||||
}
|
||||
|
||||
static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0,
|
||||
LOCK_TIMEOUT_US);
|
||||
}
|
||||
|
||||
static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
const struct imx_pll14xx_rate_table *rate;
|
||||
u32 tmp, div_val;
|
||||
int ret;
|
||||
|
||||
rate = imx_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, clk_hw_get_name(hw));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = readl_relaxed(pll->base + 4);
|
||||
|
||||
if (!clk_pll1416x_mp_change(rate, tmp)) {
|
||||
tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
|
||||
tmp |= rate->sdiv << SDIV_SHIFT;
|
||||
writel_relaxed(tmp, pll->base + 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bypass clock and set lock to pll output lock */
|
||||
tmp = readl_relaxed(pll->base);
|
||||
tmp |= LOCK_SEL_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
/* Enable RST */
|
||||
tmp &= ~RST_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
|
||||
(rate->sdiv << SDIV_SHIFT);
|
||||
writel_relaxed(div_val, pll->base + 0x4);
|
||||
|
||||
/*
|
||||
* According to SPEC, t3 - t2 need to be greater than
|
||||
* 1us and 1/FREF, respectively.
|
||||
* FREF is FIN / Prediv, the prediv is [1, 63], so choose
|
||||
* 3us.
|
||||
*/
|
||||
udelay(3);
|
||||
|
||||
/* Disable RST */
|
||||
tmp |= RST_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
/* Wait Lock */
|
||||
ret = clk_pll14xx_wait_lock(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Bypass */
|
||||
tmp &= ~BYPASS_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
const struct imx_pll14xx_rate_table *rate;
|
||||
u32 tmp, div_val;
|
||||
int ret;
|
||||
|
||||
rate = imx_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, clk_hw_get_name(hw));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = readl_relaxed(pll->base + 4);
|
||||
div_val = readl_relaxed(pll->base + 8);
|
||||
|
||||
if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
|
||||
tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
|
||||
tmp |= rate->sdiv << SDIV_SHIFT;
|
||||
writel_relaxed(tmp, pll->base + 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enable RST */
|
||||
tmp = readl_relaxed(pll->base);
|
||||
tmp &= ~RST_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
|
||||
(rate->sdiv << SDIV_SHIFT);
|
||||
writel_relaxed(div_val, pll->base + 0x4);
|
||||
writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
|
||||
|
||||
/*
|
||||
* According to SPEC, t3 - t2 need to be greater than
|
||||
* 1us and 1/FREF, respectively.
|
||||
* FREF is FIN / Prediv, the prediv is [1, 63], so choose
|
||||
* 3us.
|
||||
*/
|
||||
udelay(3);
|
||||
|
||||
/* Disable RST */
|
||||
tmp |= RST_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
/* Wait Lock*/
|
||||
ret = clk_pll14xx_wait_lock(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Bypass */
|
||||
tmp &= ~BYPASS_MASK;
|
||||
writel_relaxed(tmp, pll->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_pll14xx_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* RESETB = 1 from 0, PLL starts its normal
|
||||
* operation after lock time
|
||||
*/
|
||||
val = readl_relaxed(pll->base + GNRL_CTL);
|
||||
val |= RST_MASK;
|
||||
writel_relaxed(val, pll->base + GNRL_CTL);
|
||||
|
||||
return clk_pll14xx_wait_lock(pll);
|
||||
}
|
||||
|
||||
static int clk_pll14xx_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(pll->base + GNRL_CTL);
|
||||
|
||||
return (val & RST_MASK) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void clk_pll14xx_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll14xx *pll = to_clk_pll14xx(hw);
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* Set RST to 0, power down mode is enabled and
|
||||
* every digital block is reset
|
||||
*/
|
||||
val = readl_relaxed(pll->base + GNRL_CTL);
|
||||
val &= ~RST_MASK;
|
||||
writel_relaxed(val, pll->base + GNRL_CTL);
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pll1416x_ops = {
|
||||
.prepare = clk_pll14xx_prepare,
|
||||
.unprepare = clk_pll14xx_unprepare,
|
||||
.is_prepared = clk_pll14xx_is_prepared,
|
||||
.recalc_rate = clk_pll1416x_recalc_rate,
|
||||
.round_rate = clk_pll14xx_round_rate,
|
||||
.set_rate = clk_pll1416x_set_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_pll1416x_min_ops = {
|
||||
.recalc_rate = clk_pll1416x_recalc_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_pll1443x_ops = {
|
||||
.prepare = clk_pll14xx_prepare,
|
||||
.unprepare = clk_pll14xx_unprepare,
|
||||
.is_prepared = clk_pll14xx_is_prepared,
|
||||
.recalc_rate = clk_pll1443x_recalc_rate,
|
||||
.round_rate = clk_pll14xx_round_rate,
|
||||
.set_rate = clk_pll1443x_set_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base,
|
||||
const struct imx_pll14xx_clk *pll_clk)
|
||||
{
|
||||
struct clk_pll14xx *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.flags = pll_clk->flags;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
switch (pll_clk->type) {
|
||||
case PLL_1416X:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &clk_pll1416x_min_ops;
|
||||
else
|
||||
init.ops = &clk_pll1416x_ops;
|
||||
break;
|
||||
case PLL_1443X:
|
||||
init.ops = &clk_pll1443x_ops;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Unknown pll type for pll clk %s\n",
|
||||
__func__, name);
|
||||
};
|
||||
|
||||
pll->base = base;
|
||||
pll->hw.init = &init;
|
||||
pll->type = pll_clk->type;
|
||||
pll->rate_table = pll_clk->rate_table;
|
||||
pll->rate_count = pll_clk->rate_count;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll %s %lu\n",
|
||||
__func__, name, PTR_ERR(clk));
|
||||
kfree(pll);
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
@ -25,87 +25,292 @@
|
||||
#define PLL_DIVF2_MASK GENMASK(12, 7)
|
||||
#define PLL_DIVR1_MASK GENMASK(27, 25)
|
||||
#define PLL_DIVR2_MASK GENMASK(24, 19)
|
||||
#define PLL_DIVQ_MASK GENMASK(6, 1)
|
||||
#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
|
||||
/* These are the specification limits for the SSCG PLL */
|
||||
#define PLL_REF_MIN_FREQ 25000000UL
|
||||
#define PLL_REF_MAX_FREQ 235000000UL
|
||||
|
||||
#define PLL_SCCG_LOCK_TIMEOUT 70
|
||||
#define PLL_STAGE1_MIN_FREQ 1600000000UL
|
||||
#define PLL_STAGE1_MAX_FREQ 2400000000UL
|
||||
|
||||
#define PLL_STAGE1_REF_MIN_FREQ 25000000UL
|
||||
#define PLL_STAGE1_REF_MAX_FREQ 54000000UL
|
||||
|
||||
#define PLL_STAGE2_MIN_FREQ 1200000000UL
|
||||
#define PLL_STAGE2_MAX_FREQ 2400000000UL
|
||||
|
||||
#define PLL_STAGE2_REF_MIN_FREQ 54000000UL
|
||||
#define PLL_STAGE2_REF_MAX_FREQ 75000000UL
|
||||
|
||||
#define PLL_OUT_MIN_FREQ 20000000UL
|
||||
#define PLL_OUT_MAX_FREQ 1200000000UL
|
||||
|
||||
#define PLL_DIVR1_MAX 7
|
||||
#define PLL_DIVR2_MAX 63
|
||||
#define PLL_DIVF1_MAX 63
|
||||
#define PLL_DIVF2_MAX 63
|
||||
#define PLL_DIVQ_MAX 63
|
||||
|
||||
#define PLL_BYPASS_NONE 0x0
|
||||
#define PLL_BYPASS1 0x2
|
||||
#define PLL_BYPASS2 0x1
|
||||
|
||||
#define SSCG_PLL_BYPASS1_MASK BIT(5)
|
||||
#define SSCG_PLL_BYPASS2_MASK BIT(4)
|
||||
#define SSCG_PLL_BYPASS_MASK GENMASK(5, 4)
|
||||
|
||||
#define PLL_SCCG_LOCK_TIMEOUT 70
|
||||
|
||||
struct clk_sccg_pll_setup {
|
||||
int divr1, divf1;
|
||||
int divr2, divf2;
|
||||
int divq;
|
||||
int bypass;
|
||||
|
||||
uint64_t vco1;
|
||||
uint64_t vco2;
|
||||
uint64_t fout;
|
||||
uint64_t ref;
|
||||
uint64_t ref_div1;
|
||||
uint64_t ref_div2;
|
||||
uint64_t fout_request;
|
||||
int fout_error;
|
||||
};
|
||||
|
||||
struct clk_sccg_pll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
const struct clk_ops ops;
|
||||
|
||||
void __iomem *base;
|
||||
|
||||
struct clk_sccg_pll_setup setup;
|
||||
|
||||
u8 parent;
|
||||
u8 bypass1;
|
||||
u8 bypass2;
|
||||
};
|
||||
|
||||
#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)
|
||||
static int clk_sccg_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);
|
||||
|
||||
/* don't wait for lock if all plls are bypassed */
|
||||
if (!(val & SSCG_PLL_BYPASS2_MASK))
|
||||
return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK,
|
||||
0, PLL_SCCG_LOCK_TIMEOUT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
{
|
||||
int new_diff = temp_setup->fout - temp_setup->fout_request;
|
||||
int diff = temp_setup->fout_error;
|
||||
|
||||
if (abs(diff) > abs(new_diff)) {
|
||||
temp_setup->fout_error = new_diff;
|
||||
memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
|
||||
|
||||
if (temp_setup->fout_request == temp_setup->fout)
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX;
|
||||
temp_setup->divq++) {
|
||||
temp_setup->vco2 = temp_setup->vco1;
|
||||
do_div(temp_setup->vco2, temp_setup->divr2 + 1);
|
||||
temp_setup->vco2 *= 2;
|
||||
temp_setup->vco2 *= temp_setup->divf2 + 1;
|
||||
if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ &&
|
||||
temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) {
|
||||
temp_setup->fout = temp_setup->vco2;
|
||||
do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
|
||||
|
||||
ret = clk_sccg_pll2_check_match(setup, temp_setup);
|
||||
if (!ret) {
|
||||
temp_setup->bypass = PLL_BYPASS1;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
|
||||
temp_setup->divf2++) {
|
||||
ret = clk_sccg_divq_lookup(setup, temp_setup);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX;
|
||||
temp_setup->divr2++) {
|
||||
temp_setup->ref_div2 = temp_setup->vco1;
|
||||
do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
|
||||
if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
|
||||
temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
|
||||
ret = clk_sccg_divf2_lookup(setup, temp_setup);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup,
|
||||
uint64_t ref)
|
||||
{
|
||||
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
|
||||
return ret;
|
||||
|
||||
temp_setup->vco1 = ref;
|
||||
|
||||
ret = clk_sccg_divr2_lookup(setup, temp_setup);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX;
|
||||
temp_setup->divf1++) {
|
||||
uint64_t vco1 = temp_setup->ref;
|
||||
|
||||
do_div(vco1, temp_setup->divr1 + 1);
|
||||
vco1 *= 2;
|
||||
vco1 *= temp_setup->divf1 + 1;
|
||||
|
||||
ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
|
||||
if (!ret) {
|
||||
temp_setup->bypass = PLL_BYPASS_NONE;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX;
|
||||
temp_setup->divr1++) {
|
||||
temp_setup->ref_div1 = temp_setup->ref;
|
||||
do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
|
||||
if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
|
||||
temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
|
||||
ret = clk_sccg_divf1_lookup(setup, temp_setup);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup,
|
||||
uint64_t ref)
|
||||
{
|
||||
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
|
||||
return ret;
|
||||
|
||||
temp_setup->ref = ref;
|
||||
|
||||
ret = clk_sccg_divr1_lookup(setup, temp_setup);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
uint64_t prate,
|
||||
uint64_t rate, int try_bypass)
|
||||
{
|
||||
struct clk_sccg_pll_setup temp_setup;
|
||||
int ret = -EINVAL;
|
||||
|
||||
memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
|
||||
memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
|
||||
|
||||
temp_setup.fout_error = PLL_OUT_MAX_FREQ;
|
||||
temp_setup.fout_request = rate;
|
||||
|
||||
switch (try_bypass) {
|
||||
|
||||
case PLL_BYPASS2:
|
||||
if (prate == rate) {
|
||||
setup->bypass = PLL_BYPASS2;
|
||||
setup->fout = rate;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PLL_BYPASS1:
|
||||
ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
|
||||
break;
|
||||
|
||||
case PLL_BYPASS_NONE:
|
||||
ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
|
||||
u32 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)
|
||||
static int clk_sccg_pll_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
u32 val;
|
||||
@ -114,10 +319,10 @@ static int clk_pll1_prepare(struct clk_hw *hw)
|
||||
val &= ~PLL_PD_MASK;
|
||||
writel_relaxed(val, pll->base + PLL_CFG0);
|
||||
|
||||
return clk_pll_wait_lock(pll);
|
||||
return clk_sccg_pll_wait_lock(pll);
|
||||
}
|
||||
|
||||
static void clk_pll1_unprepare(struct clk_hw *hw)
|
||||
static void clk_sccg_pll_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
u32 val;
|
||||
@ -125,121 +330,208 @@ static void clk_pll1_unprepare(struct clk_hw *hw)
|
||||
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,
|
||||
static unsigned long clk_sccg_pll_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;
|
||||
u32 val, divr1, divf1, divr2, divf2, divq;
|
||||
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);
|
||||
divq = FIELD_GET(PLL_DIVQ_MASK, val);
|
||||
|
||||
temp64 = ref * 2;
|
||||
temp64 *= (divf1 + 1) * (divf2 + 1);
|
||||
temp64 = parent_rate;
|
||||
|
||||
do_div(temp64, (divr1 + 1) * (divr2 + 1));
|
||||
val = clk_readl(pll->base + PLL_CFG0);
|
||||
if (val & SSCG_PLL_BYPASS2_MASK) {
|
||||
temp64 = parent_rate;
|
||||
} else if (val & SSCG_PLL_BYPASS1_MASK) {
|
||||
temp64 *= divf2;
|
||||
do_div(temp64, (divr2 + 1) * (divq + 1));
|
||||
} else {
|
||||
temp64 *= 2;
|
||||
temp64 *= (divf1 + 1) * (divf2 + 1);
|
||||
do_div(temp64, (divr1 + 1) * (divr2 + 1) * (divq + 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,
|
||||
static int clk_sccg_pll_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);
|
||||
struct clk_sccg_pll_setup *setup = &pll->setup;
|
||||
u32 val;
|
||||
|
||||
if (!parent_rate)
|
||||
return -EINVAL;
|
||||
|
||||
divf = rate / parent_rate;
|
||||
/* set bypass here too since the parent might be the same */
|
||||
val = clk_readl(pll->base + PLL_CFG0);
|
||||
val &= ~SSCG_PLL_BYPASS_MASK;
|
||||
val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
|
||||
clk_writel(val, pll->base + PLL_CFG0);
|
||||
|
||||
val = readl_relaxed(pll->base + PLL_CFG2);
|
||||
val &= ~PLL_DIVF2_MASK;
|
||||
val |= FIELD_PREP(PLL_DIVF2_MASK, divf - 1);
|
||||
val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
|
||||
val &= ~(PLL_DIVR1_MASK | PLL_DIVR2_MASK | PLL_DIVQ_MASK);
|
||||
val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1);
|
||||
val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2);
|
||||
val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1);
|
||||
val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2);
|
||||
val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
|
||||
writel_relaxed(val, pll->base + PLL_CFG2);
|
||||
|
||||
return clk_pll_wait_lock(pll);
|
||||
return clk_sccg_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 u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
u32 val;
|
||||
u8 ret = pll->parent;
|
||||
|
||||
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,
|
||||
val = clk_readl(pll->base + PLL_CFG0);
|
||||
if (val & SSCG_PLL_BYPASS2_MASK)
|
||||
ret = pll->bypass2;
|
||||
else if (val & SSCG_PLL_BYPASS1_MASK)
|
||||
ret = pll->bypass1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
u32 val;
|
||||
|
||||
val = clk_readl(pll->base + PLL_CFG0);
|
||||
val &= ~SSCG_PLL_BYPASS_MASK;
|
||||
val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
|
||||
clk_writel(val, pll->base + PLL_CFG0);
|
||||
|
||||
return clk_sccg_pll_wait_lock(pll);
|
||||
}
|
||||
|
||||
static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req,
|
||||
uint64_t min,
|
||||
uint64_t max,
|
||||
uint64_t rate,
|
||||
int bypass)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sccg_pll_setup *setup = &pll->setup;
|
||||
struct clk_hw *parent_hw = NULL;
|
||||
int bypass_parent_index;
|
||||
int ret = -EINVAL;
|
||||
|
||||
req->max_rate = max;
|
||||
req->min_rate = min;
|
||||
|
||||
switch (bypass) {
|
||||
case PLL_BYPASS2:
|
||||
bypass_parent_index = pll->bypass2;
|
||||
break;
|
||||
case PLL_BYPASS1:
|
||||
bypass_parent_index = pll->bypass1;
|
||||
break;
|
||||
default:
|
||||
bypass_parent_index = pll->parent;
|
||||
break;
|
||||
}
|
||||
|
||||
parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
|
||||
ret = __clk_determine_rate(parent_hw, req);
|
||||
if (!ret) {
|
||||
ret = clk_sccg_pll_find_setup(setup, req->rate,
|
||||
rate, bypass);
|
||||
}
|
||||
|
||||
req->best_parent_hw = parent_hw;
|
||||
req->best_parent_rate = req->rate;
|
||||
req->rate = setup->fout;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sccg_pll_setup *setup = &pll->setup;
|
||||
uint64_t rate = req->rate;
|
||||
uint64_t min = req->min_rate;
|
||||
uint64_t max = req->max_rate;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
|
||||
return ret;
|
||||
|
||||
ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
|
||||
rate, PLL_BYPASS2);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
|
||||
PLL_STAGE1_REF_MAX_FREQ, rate,
|
||||
PLL_BYPASS1);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
|
||||
PLL_REF_MAX_FREQ, rate,
|
||||
PLL_BYPASS_NONE);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
if (setup->fout >= min && setup->fout <= max)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_sccg_pll_ops = {
|
||||
.prepare = clk_sccg_pll_prepare,
|
||||
.unprepare = clk_sccg_pll_unprepare,
|
||||
.is_prepared = clk_sccg_pll_is_prepared,
|
||||
.recalc_rate = clk_sccg_pll_recalc_rate,
|
||||
.set_rate = clk_sccg_pll_set_rate,
|
||||
.set_parent = clk_sccg_pll_set_parent,
|
||||
.get_parent = clk_sccg_pll_get_parent,
|
||||
.determine_rate = clk_sccg_pll_determine_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_sccg_pll(const char *name,
|
||||
const char *parent_name,
|
||||
const char * const *parent_names,
|
||||
u8 num_parents,
|
||||
u8 parent, u8 bypass1, u8 bypass2,
|
||||
void __iomem *base,
|
||||
enum imx_sccg_pll_type pll_type)
|
||||
unsigned long flags)
|
||||
{
|
||||
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);
|
||||
|
||||
pll->parent = parent;
|
||||
pll->bypass1 = bypass1;
|
||||
pll->bypass2 = bypass2;
|
||||
|
||||
pll->base = base;
|
||||
init.name = name;
|
||||
init.flags = 0;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.ops = &clk_sccg_pll_ops;
|
||||
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_names;
|
||||
init.num_parents = num_parents;
|
||||
|
||||
pll->base = base;
|
||||
pll->hw.init = &init;
|
||||
|
@ -4,12 +4,17 @@
|
||||
* Dong Aisheng <aisheng.dong@nxp.com>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "clk-scu.h"
|
||||
|
||||
#define IMX_SIP_CPUFREQ 0xC2000001
|
||||
#define IMX_SIP_SET_CPUFREQ 0x00
|
||||
|
||||
static struct imx_sc_ipc *ccm_ipc_handle;
|
||||
|
||||
/*
|
||||
@ -65,6 +70,41 @@ struct imx_sc_msg_get_clock_rate {
|
||||
} data;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct imx_sc_msg_get_clock_parent - clock get parent protocol
|
||||
* @hdr: SCU protocol header
|
||||
* @req: get parent request protocol
|
||||
* @resp: get parent response protocol
|
||||
*
|
||||
* This structure describes the SCU protocol of clock get parent
|
||||
*/
|
||||
struct imx_sc_msg_get_clock_parent {
|
||||
struct imx_sc_rpc_msg hdr;
|
||||
union {
|
||||
struct req_get_clock_parent {
|
||||
__le16 resource;
|
||||
u8 clk;
|
||||
} __packed req;
|
||||
struct resp_get_clock_parent {
|
||||
u8 parent;
|
||||
} resp;
|
||||
} data;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct imx_sc_msg_set_clock_parent - clock set parent protocol
|
||||
* @hdr: SCU protocol header
|
||||
* @req: set parent request protocol
|
||||
*
|
||||
* This structure describes the SCU protocol of clock set parent
|
||||
*/
|
||||
struct imx_sc_msg_set_clock_parent {
|
||||
struct imx_sc_rpc_msg hdr;
|
||||
__le16 resource;
|
||||
u8 clk;
|
||||
u8 parent;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* struct imx_sc_msg_req_clock_enable - clock gate protocol
|
||||
* @hdr: SCU protocol header
|
||||
@ -145,6 +185,25 @@ static long clk_scu_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_scu *clk = to_clk_scu(hw);
|
||||
struct arm_smccc_res res;
|
||||
unsigned long cluster_id;
|
||||
|
||||
if (clk->rsrc_id == IMX_SC_R_A35)
|
||||
cluster_id = 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
/* CPU frequency scaling can ONLY be done by ARM-Trusted-Firmware */
|
||||
arm_smccc_smc(IMX_SIP_CPUFREQ, IMX_SIP_SET_CPUFREQ,
|
||||
cluster_id, rate, 0, 0, 0, 0, &res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* clk_scu_set_rate - Set rate for a SCU clock
|
||||
* @hw: clock to change rate for
|
||||
@ -173,6 +232,49 @@ static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
|
||||
}
|
||||
|
||||
static u8 clk_scu_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_scu *clk = to_clk_scu(hw);
|
||||
struct imx_sc_msg_get_clock_parent 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_PARENT;
|
||||
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 parent %d\n",
|
||||
clk_hw_get_name(hw), ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return msg.data.resp.parent;
|
||||
}
|
||||
|
||||
static int clk_scu_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct clk_scu *clk = to_clk_scu(hw);
|
||||
struct imx_sc_msg_set_clock_parent 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_PARENT;
|
||||
hdr->size = 2;
|
||||
|
||||
msg.resource = cpu_to_le16(clk->rsrc_id);
|
||||
msg.clk = clk->clk_type;
|
||||
msg.parent = index;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -228,11 +330,22 @@ 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,
|
||||
.get_parent = clk_scu_get_parent,
|
||||
.set_parent = clk_scu_set_parent,
|
||||
.prepare = clk_scu_prepare,
|
||||
.unprepare = clk_scu_unprepare,
|
||||
};
|
||||
|
||||
struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type)
|
||||
static const struct clk_ops clk_scu_cpu_ops = {
|
||||
.recalc_rate = clk_scu_recalc_rate,
|
||||
.round_rate = clk_scu_round_rate,
|
||||
.set_rate = clk_scu_atf_set_cpu_rate,
|
||||
.prepare = clk_scu_prepare,
|
||||
.unprepare = clk_scu_unprepare,
|
||||
};
|
||||
|
||||
struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
|
||||
int num_parents, u32 rsrc_id, u8 clk_type)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct clk_scu *clk;
|
||||
@ -248,7 +361,13 @@ struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type)
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_scu_ops;
|
||||
init.num_parents = 0;
|
||||
if (rsrc_id == IMX_SC_R_A35)
|
||||
init.ops = &clk_scu_cpu_ops;
|
||||
else
|
||||
init.ops = &clk_scu_ops;
|
||||
init.parent_names = parents;
|
||||
init.num_parents = num_parents;
|
||||
|
||||
/*
|
||||
* Note on MX8, the clocks are tightly coupled with power domain
|
||||
* that once the power domain is off, the clock status may be
|
||||
|
@ -10,7 +10,21 @@
|
||||
#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_scu(const char *name, const char * const *parents,
|
||||
int num_parents, u32 rsrc_id, u8 clk_type);
|
||||
|
||||
static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id,
|
||||
u8 clk_type)
|
||||
{
|
||||
return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents,
|
||||
int num_parents, u32 rsrc_id, u8 clk_type)
|
||||
{
|
||||
return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type);
|
||||
}
|
||||
|
||||
struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
|
||||
unsigned long flags, void __iomem *reg,
|
||||
|
@ -27,6 +27,30 @@ enum imx_sccg_pll_type {
|
||||
SCCG_PLL2,
|
||||
};
|
||||
|
||||
enum imx_pll14xx_type {
|
||||
PLL_1416X,
|
||||
PLL_1443X,
|
||||
};
|
||||
|
||||
/* NOTE: Rate table should be kept sorted in descending order. */
|
||||
struct imx_pll14xx_rate_table {
|
||||
unsigned int rate;
|
||||
unsigned int pdiv;
|
||||
unsigned int mdiv;
|
||||
unsigned int sdiv;
|
||||
unsigned int kdiv;
|
||||
};
|
||||
|
||||
struct imx_pll14xx_clk {
|
||||
enum imx_pll14xx_type type;
|
||||
const struct imx_pll14xx_rate_table *rate_table;
|
||||
int rate_count;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
|
||||
|
||||
struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
|
||||
const char *parent, void __iomem *base);
|
||||
|
||||
@ -36,9 +60,12 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
|
||||
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);
|
||||
struct clk *imx_clk_sccg_pll(const char *name,
|
||||
const char * const *parent_names,
|
||||
u8 num_parents,
|
||||
u8 parent, u8 bypass1, u8 bypass2,
|
||||
void __iomem *base,
|
||||
unsigned long flags);
|
||||
|
||||
enum imx_pllv3_type {
|
||||
IMX_PLLV3_GENERIC,
|
||||
@ -329,7 +356,8 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux2_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width, const char **parents,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents, unsigned long flags)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
@ -354,7 +382,7 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
|
||||
struct clk *step);
|
||||
|
||||
struct clk *imx8m_clk_composite_flags(const char *name,
|
||||
const char **parent_names,
|
||||
const char * const *parent_names,
|
||||
int num_parents, void __iomem *reg,
|
||||
unsigned long flags);
|
||||
|
||||
|
@ -229,9 +229,10 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
|
||||
{MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
|
||||
{MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
|
||||
{MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
|
||||
{MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
|
||||
{MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x09, 0x09, 0x0, 0, &disp0_lock},
|
||||
{MMP2_CLK_DISP0_LCDC, "disp0_lcdc_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x12, 0x12, 0x0, 0, &disp0_lock},
|
||||
{MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
|
||||
{MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock},
|
||||
{MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x09, 0x09, 0x0, 0, &disp1_lock},
|
||||
{MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock},
|
||||
{MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
|
||||
{MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
|
||||
|
@ -136,15 +136,20 @@ static int __init exynos5_clk_register_subcmu(struct device *parent,
|
||||
{
|
||||
struct of_phandle_args genpdspec = { .np = pd_node };
|
||||
struct platform_device *pdev;
|
||||
int ret;
|
||||
|
||||
pdev = platform_device_alloc("exynos5-subcmu", PLATFORM_DEVID_AUTO);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
pdev = platform_device_alloc(info->pd_name, -1);
|
||||
pdev->dev.parent = parent;
|
||||
pdev->driver_override = "exynos5-subcmu";
|
||||
platform_set_drvdata(pdev, (void *)info);
|
||||
of_genpd_add_device(&genpdspec, &pdev->dev);
|
||||
platform_device_add(pdev);
|
||||
ret = platform_device_add(pdev);
|
||||
if (ret)
|
||||
platform_device_put(pdev);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init exynos5_clk_probe(struct platform_device *pdev)
|
||||
|
@ -559,7 +559,7 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
|
||||
/* ENABLE_ACLK_TOP */
|
||||
GATE(CLK_ACLK_G3D_400, "aclk_g3d_400", "div_aclk_g3d_400",
|
||||
ENABLE_ACLK_TOP, 30, CLK_IS_CRITICAL, 0),
|
||||
GATE(CLK_ACLK_IMEM_SSX_266, "aclk_imem_ssx_266",
|
||||
GATE(CLK_ACLK_IMEM_SSSX_266, "aclk_imem_sssx_266",
|
||||
"div_aclk_imem_sssx_266", ENABLE_ACLK_TOP,
|
||||
29, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400",
|
||||
@ -568,10 +568,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
|
||||
GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400",
|
||||
ENABLE_ACLK_TOP, 25,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_266",
|
||||
GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_200",
|
||||
ENABLE_ACLK_TOP, 24,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_200",
|
||||
GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_266",
|
||||
ENABLE_ACLK_TOP, 23,
|
||||
CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b",
|
||||
@ -5467,6 +5467,35 @@ static const struct samsung_cmu_info cam1_cmu_info __initconst = {
|
||||
.clk_name = "aclk_cam1_400",
|
||||
};
|
||||
|
||||
/*
|
||||
* Register offset definitions for CMU_IMEM
|
||||
*/
|
||||
#define ENABLE_ACLK_IMEM_SLIMSSS 0x080c
|
||||
#define ENABLE_PCLK_IMEM_SLIMSSS 0x0908
|
||||
|
||||
static const unsigned long imem_clk_regs[] __initconst = {
|
||||
ENABLE_ACLK_IMEM_SLIMSSS,
|
||||
ENABLE_PCLK_IMEM_SLIMSSS,
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
|
||||
/* ENABLE_ACLK_IMEM_SLIMSSS */
|
||||
GATE(CLK_ACLK_SLIMSSS, "aclk_slimsss", "aclk_imem_sssx_266",
|
||||
ENABLE_ACLK_IMEM_SLIMSSS, 0, CLK_IGNORE_UNUSED, 0),
|
||||
|
||||
/* ENABLE_PCLK_IMEM_SLIMSSS */
|
||||
GATE(CLK_PCLK_SLIMSSS, "pclk_slimsss", "aclk_imem_200",
|
||||
ENABLE_PCLK_IMEM_SLIMSSS, 0, CLK_IGNORE_UNUSED, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info imem_cmu_info __initconst = {
|
||||
.gate_clks = imem_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(imem_gate_clks),
|
||||
.nr_clk_ids = IMEM_NR_CLK,
|
||||
.clk_regs = imem_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(imem_clk_regs),
|
||||
.clk_name = "aclk_imem_200",
|
||||
};
|
||||
|
||||
struct exynos5433_cmu_data {
|
||||
struct samsung_clk_reg_dump *clk_save;
|
||||
@ -5654,6 +5683,9 @@ static const struct of_device_id exynos5433_cmu_of_match[] = {
|
||||
}, {
|
||||
.compatible = "samsung,exynos5433-cmu-mscl",
|
||||
.data = &mscl_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos5433-cmu-imem",
|
||||
.data = &imem_cmu_info,
|
||||
}, {
|
||||
},
|
||||
};
|
||||
|
@ -389,7 +389,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
|
||||
ARRAY_SIZE(s3c2450_gates));
|
||||
samsung_clk_register_alias(ctx, s3c2450_aliases,
|
||||
ARRAY_SIZE(s3c2450_aliases));
|
||||
/* fall through, as s3c2450 extends the s3c2416 clocks */
|
||||
/* fall through - as s3c2450 extends the s3c2416 clocks */
|
||||
case S3C2416:
|
||||
samsung_clk_register_div(ctx, s3c2416_dividers,
|
||||
ARRAY_SIZE(s3c2416_dividers));
|
||||
|
@ -614,7 +614,7 @@ static int ti_adpll_init_clkout(struct ti_adpll_data *d,
|
||||
|
||||
init.name = child_name;
|
||||
init.ops = ops;
|
||||
init.flags = CLK_IS_BASIC;
|
||||
init.flags = 0;
|
||||
co->hw.init = &init;
|
||||
parent_names[0] = __clk_get_name(clk0);
|
||||
parent_names[1] = __clk_get_name(clk1);
|
||||
|
@ -165,7 +165,7 @@ static void __init omap_clk_register_apll(void *user,
|
||||
|
||||
ad->clk_bypass = __clk_get_hw(clk);
|
||||
|
||||
clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
|
||||
clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
|
||||
if (!IS_ERR(clk)) {
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
kfree(clk_hw->hw.init->parent_names);
|
||||
@ -402,7 +402,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
clk = clk_register(NULL, &clk_hw->hw);
|
||||
clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
|
||||
if (!IS_ERR(clk)) {
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
kfree(init);
|
||||
|
@ -35,7 +35,44 @@ struct clk_ti_autoidle {
|
||||
#define AUTOIDLE_LOW 0x1
|
||||
|
||||
static LIST_HEAD(autoidle_clks);
|
||||
static LIST_HEAD(clk_hw_omap_clocks);
|
||||
|
||||
/*
|
||||
* we have some non-atomic read/write
|
||||
* operations behind it, so lets
|
||||
* take one lock for handling autoidle
|
||||
* of all clocks
|
||||
*/
|
||||
static DEFINE_SPINLOCK(autoidle_spinlock);
|
||||
|
||||
static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
if (clk->ops && clk->ops->deny_idle) {
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock_irqsave(&autoidle_spinlock, irqflags);
|
||||
clk->autoidle_count++;
|
||||
if (clk->autoidle_count == 1)
|
||||
clk->ops->deny_idle(clk);
|
||||
|
||||
spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
if (clk->ops && clk->ops->allow_idle) {
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock_irqsave(&autoidle_spinlock, irqflags);
|
||||
clk->autoidle_count--;
|
||||
if (clk->autoidle_count == 0)
|
||||
clk->ops->allow_idle(clk);
|
||||
|
||||
spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_deny_idle - disable autoidle on an OMAP clock
|
||||
@ -45,12 +82,15 @@ static LIST_HEAD(clk_hw_omap_clocks);
|
||||
*/
|
||||
int omap2_clk_deny_idle(struct clk *clk)
|
||||
{
|
||||
struct clk_hw_omap *c;
|
||||
struct clk_hw *hw = __clk_get_hw(clk);
|
||||
|
||||
c = to_clk_hw_omap(__clk_get_hw(clk));
|
||||
if (c->ops && c->ops->deny_idle)
|
||||
c->ops->deny_idle(c);
|
||||
return 0;
|
||||
if (omap2_clk_is_hw_omap(hw)) {
|
||||
struct clk_hw_omap *c = to_clk_hw_omap(hw);
|
||||
|
||||
return _omap2_clk_deny_idle(c);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,12 +101,15 @@ int omap2_clk_deny_idle(struct clk *clk)
|
||||
*/
|
||||
int omap2_clk_allow_idle(struct clk *clk)
|
||||
{
|
||||
struct clk_hw_omap *c;
|
||||
struct clk_hw *hw = __clk_get_hw(clk);
|
||||
|
||||
c = to_clk_hw_omap(__clk_get_hw(clk));
|
||||
if (c->ops && c->ops->allow_idle)
|
||||
c->ops->allow_idle(c);
|
||||
return 0;
|
||||
if (omap2_clk_is_hw_omap(hw)) {
|
||||
struct clk_hw_omap *c = to_clk_hw_omap(hw);
|
||||
|
||||
return _omap2_clk_allow_idle(c);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void _allow_autoidle(struct clk_ti_autoidle *clk)
|
||||
@ -167,26 +210,6 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_init_clk_hw_omap_clocks - initialize an OMAP clock
|
||||
* @hw: struct clk_hw * to initialize
|
||||
*
|
||||
* Add an OMAP clock @clk to the internal list of OMAP clocks. Used
|
||||
* temporarily for autoidle handling, until this support can be
|
||||
* integrated into the common clock framework code in some way. No
|
||||
* return value.
|
||||
*/
|
||||
void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *c;
|
||||
|
||||
if (clk_hw_get_flags(hw) & CLK_IS_BASIC)
|
||||
return;
|
||||
|
||||
c = to_clk_hw_omap(hw);
|
||||
list_add(&c->node, &clk_hw_omap_clocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that
|
||||
* support it
|
||||
@ -198,11 +221,11 @@ void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
|
||||
*/
|
||||
int omap2_clk_enable_autoidle_all(void)
|
||||
{
|
||||
struct clk_hw_omap *c;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(c, &clk_hw_omap_clocks, node)
|
||||
if (c->ops && c->ops->allow_idle)
|
||||
c->ops->allow_idle(c);
|
||||
ret = omap2_clk_for_each(_omap2_clk_allow_idle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
_clk_generic_allow_autoidle_all();
|
||||
|
||||
@ -220,11 +243,11 @@ int omap2_clk_enable_autoidle_all(void)
|
||||
*/
|
||||
int omap2_clk_disable_autoidle_all(void)
|
||||
{
|
||||
struct clk_hw_omap *c;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(c, &clk_hw_omap_clocks, node)
|
||||
if (c->ops && c->ops->deny_idle)
|
||||
c->ops->deny_idle(c);
|
||||
ret = omap2_clk_for_each(_omap2_clk_deny_idle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
_clk_generic_deny_autoidle_all();
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
static LIST_HEAD(clk_hw_omap_clocks);
|
||||
struct ti_clk_ll_ops *ti_clk_ll_ops;
|
||||
static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
|
||||
|
||||
@ -521,3 +522,74 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework
|
||||
* @dev: device for this clock
|
||||
* @hw: hardware clock handle
|
||||
* @con: connection ID for this clock
|
||||
*
|
||||
* Registers a clk_hw_omap clock to the clock framewor, adds a clock alias
|
||||
* for it, and adds the list to the available clk_hw_omap type clocks.
|
||||
* Returns a handle to the registered clock if successful, ERR_PTR value
|
||||
* in failure.
|
||||
*/
|
||||
struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
|
||||
const char *con)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_hw_omap *oclk;
|
||||
|
||||
clk = ti_clk_register(dev, hw, con);
|
||||
if (IS_ERR(clk))
|
||||
return clk;
|
||||
|
||||
oclk = to_clk_hw_omap(hw);
|
||||
|
||||
list_add(&oclk->node, &clk_hw_omap_clocks);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_for_each - call function for each registered clk_hw_omap
|
||||
* @fn: pointer to a callback function
|
||||
*
|
||||
* Call @fn for each registered clk_hw_omap, passing @hw to each
|
||||
* function. @fn must return 0 for success or any other value for
|
||||
* failure. If @fn returns non-zero, the iteration across clocks
|
||||
* will stop and the non-zero return value will be passed to the
|
||||
* caller of omap2_clk_for_each().
|
||||
*/
|
||||
int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw))
|
||||
{
|
||||
int ret;
|
||||
struct clk_hw_omap *hw;
|
||||
|
||||
list_for_each_entry(hw, &clk_hw_omap_clocks, node) {
|
||||
ret = (*fn)(hw);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_is_hw_omap - check if the provided clk_hw is OMAP clock
|
||||
* @hw: clk_hw to check if it is an omap clock or not
|
||||
*
|
||||
* Checks if the provided clk_hw is OMAP clock or not. Returns true if
|
||||
* it is, false otherwise.
|
||||
*/
|
||||
bool omap2_clk_is_hw_omap(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *oclk;
|
||||
|
||||
list_for_each_entry(oclk, &clk_hw_omap_clocks, node) {
|
||||
if (&oclk->hw == hw)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
|
||||
init.parent_names = parents;
|
||||
init.num_parents = num_parents;
|
||||
init.ops = ops;
|
||||
init.flags = CLK_IS_BASIC;
|
||||
init.flags = 0;
|
||||
|
||||
clk = ti_clk_register(NULL, clk_hw, init.name);
|
||||
if (IS_ERR_OR_NULL(clk)) {
|
||||
|
@ -203,6 +203,8 @@ typedef void (*ti_of_clk_init_cb_t)(void *, struct device_node *);
|
||||
|
||||
struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
|
||||
const char *con);
|
||||
struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
|
||||
const char *con);
|
||||
int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
|
||||
void ti_clk_add_aliases(void);
|
||||
|
||||
@ -221,7 +223,6 @@ int ti_clk_retry_init(struct device_node *node, void *user,
|
||||
ti_of_clk_init_cb_t func);
|
||||
int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type);
|
||||
|
||||
void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw);
|
||||
int of_ti_clk_autoidle_setup(struct device_node *node);
|
||||
void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
|
||||
|
||||
@ -301,6 +302,8 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
|
||||
unsigned long *parent_rate);
|
||||
int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req);
|
||||
int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw));
|
||||
bool omap2_clk_is_hw_omap(struct clk_hw *hw);
|
||||
|
||||
extern struct ti_clk_ll_ops *ti_clk_ll_ops;
|
||||
|
||||
|
@ -143,7 +143,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
|
||||
continue;
|
||||
}
|
||||
clk_hw = __clk_get_hw(clk);
|
||||
if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) {
|
||||
if (!omap2_clk_is_hw_omap(clk_hw)) {
|
||||
pr_warn("can't setup clkdm for basic clk %s\n",
|
||||
__clk_get_name(clk));
|
||||
continue;
|
||||
|
@ -336,7 +336,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
|
||||
|
||||
init.name = name;
|
||||
init.ops = &ti_clk_divider_ops;
|
||||
init.flags = flags | CLK_IS_BASIC;
|
||||
init.flags = flags;
|
||||
init.parent_names = (parent_name ? &parent_name : NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
||||
|
@ -192,10 +192,9 @@ static void __init _register_dpll(void *user,
|
||||
dd->clk_bypass = __clk_get_hw(clk);
|
||||
|
||||
/* register the clock */
|
||||
clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
|
||||
clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
kfree(clk_hw->hw.init->parent_names);
|
||||
kfree(clk_hw->hw.init);
|
||||
@ -265,14 +264,12 @@ static void _register_dpll_x2(struct device_node *node,
|
||||
#endif
|
||||
|
||||
/* register the clock */
|
||||
clk = ti_clk_register(NULL, &clk_hw->hw, name);
|
||||
clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
if (IS_ERR(clk))
|
||||
kfree(clk_hw);
|
||||
} else {
|
||||
omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
|
||||
else
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -731,7 +731,7 @@ static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
|
||||
do {
|
||||
do {
|
||||
hw = clk_hw_get_parent(hw);
|
||||
} while (hw && (clk_hw_get_flags(hw) & CLK_IS_BASIC));
|
||||
} while (hw && (!omap2_clk_is_hw_omap(hw)));
|
||||
if (!hw)
|
||||
break;
|
||||
pclk = to_clk_hw_omap(hw);
|
||||
|
@ -123,7 +123,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
|
||||
|
||||
init.flags = flags;
|
||||
|
||||
clk = ti_clk_register(NULL, &clk_hw->hw, name);
|
||||
clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
|
||||
|
||||
if (IS_ERR(clk))
|
||||
kfree(clk_hw);
|
||||
|
@ -57,12 +57,10 @@ static struct clk *_register_interface(struct device *dev, const char *name,
|
||||
init.num_parents = 1;
|
||||
init.parent_names = &parent_name;
|
||||
|
||||
clk = ti_clk_register(NULL, &clk_hw->hw, name);
|
||||
clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
|
||||
|
||||
if (IS_ERR(clk))
|
||||
kfree(clk_hw);
|
||||
else
|
||||
omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
|
||||
|
||||
init.name = name;
|
||||
init.ops = &ti_clk_mux_ops;
|
||||
init.flags = flags | CLK_IS_BASIC;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_names;
|
||||
init.num_parents = num_parents;
|
||||
|
||||
|
@ -47,7 +47,7 @@ static int uniphier_clk_cpugear_set_parent(struct clk_hw *hw, u8 index)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write_bits(gear->regmap,
|
||||
gear->regbase + UNIPHIER_CLK_CPUGEAR_SET,
|
||||
gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
|
||||
UNIPHIER_CLK_CPUGEAR_UPD_BIT,
|
||||
UNIPHIER_CLK_CPUGEAR_UPD_BIT);
|
||||
if (ret)
|
||||
|
@ -156,7 +156,7 @@
|
||||
#define CLK_ACLK_G2D_266 220
|
||||
#define CLK_ACLK_G2D_400 221
|
||||
#define CLK_ACLK_G3D_400 222
|
||||
#define CLK_ACLK_IMEM_SSX_266 223
|
||||
#define CLK_ACLK_IMEM_SSSX_266 223
|
||||
#define CLK_ACLK_BUS0_400 224
|
||||
#define CLK_ACLK_BUS1_400 225
|
||||
#define CLK_ACLK_IMEM_200 226
|
||||
@ -1406,4 +1406,10 @@
|
||||
|
||||
#define CAM1_NR_CLK 113
|
||||
|
||||
/* CMU_IMEM */
|
||||
#define CLK_ACLK_SLIMSSS 2
|
||||
#define CLK_PCLK_SLIMSSS 35
|
||||
|
||||
#define IMEM_NR_CLK 36
|
||||
|
||||
#endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */
|
||||
|
@ -214,6 +214,7 @@
|
||||
#define IMX5_CLK_IEEE1588_SEL 202
|
||||
#define IMX5_CLK_IEEE1588_PODF 203
|
||||
#define IMX5_CLK_IEEE1588_GATE 204
|
||||
#define IMX5_CLK_END 205
|
||||
#define IMX5_CLK_SCC2_IPG_GATE 205
|
||||
#define IMX5_CLK_END 206
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_IMX5_H */
|
||||
|
244
include/dt-bindings/clock/imx8mm-clock.h
Normal file
244
include/dt-bindings/clock/imx8mm-clock.h
Normal file
@ -0,0 +1,244 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright 2017-2018 NXP
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_CLOCK_IMX8MM_H
|
||||
#define __DT_BINDINGS_CLOCK_IMX8MM_H
|
||||
|
||||
#define IMX8MM_CLK_DUMMY 0
|
||||
#define IMX8MM_CLK_32K 1
|
||||
#define IMX8MM_CLK_24M 2
|
||||
#define IMX8MM_OSC_HDMI_CLK 3
|
||||
#define IMX8MM_CLK_EXT1 4
|
||||
#define IMX8MM_CLK_EXT2 5
|
||||
#define IMX8MM_CLK_EXT3 6
|
||||
#define IMX8MM_CLK_EXT4 7
|
||||
#define IMX8MM_AUDIO_PLL1_REF_SEL 8
|
||||
#define IMX8MM_AUDIO_PLL2_REF_SEL 9
|
||||
#define IMX8MM_VIDEO_PLL1_REF_SEL 10
|
||||
#define IMX8MM_DRAM_PLL_REF_SEL 11
|
||||
#define IMX8MM_GPU_PLL_REF_SEL 12
|
||||
#define IMX8MM_VPU_PLL_REF_SEL 13
|
||||
#define IMX8MM_ARM_PLL_REF_SEL 14
|
||||
#define IMX8MM_SYS_PLL1_REF_SEL 15
|
||||
#define IMX8MM_SYS_PLL2_REF_SEL 16
|
||||
#define IMX8MM_SYS_PLL3_REF_SEL 17
|
||||
#define IMX8MM_AUDIO_PLL1 18
|
||||
#define IMX8MM_AUDIO_PLL2 19
|
||||
#define IMX8MM_VIDEO_PLL1 20
|
||||
#define IMX8MM_DRAM_PLL 21
|
||||
#define IMX8MM_GPU_PLL 22
|
||||
#define IMX8MM_VPU_PLL 23
|
||||
#define IMX8MM_ARM_PLL 24
|
||||
#define IMX8MM_SYS_PLL1 25
|
||||
#define IMX8MM_SYS_PLL2 26
|
||||
#define IMX8MM_SYS_PLL3 27
|
||||
#define IMX8MM_AUDIO_PLL1_BYPASS 28
|
||||
#define IMX8MM_AUDIO_PLL2_BYPASS 29
|
||||
#define IMX8MM_VIDEO_PLL1_BYPASS 30
|
||||
#define IMX8MM_DRAM_PLL_BYPASS 31
|
||||
#define IMX8MM_GPU_PLL_BYPASS 32
|
||||
#define IMX8MM_VPU_PLL_BYPASS 33
|
||||
#define IMX8MM_ARM_PLL_BYPASS 34
|
||||
#define IMX8MM_SYS_PLL1_BYPASS 35
|
||||
#define IMX8MM_SYS_PLL2_BYPASS 36
|
||||
#define IMX8MM_SYS_PLL3_BYPASS 37
|
||||
#define IMX8MM_AUDIO_PLL1_OUT 38
|
||||
#define IMX8MM_AUDIO_PLL2_OUT 39
|
||||
#define IMX8MM_VIDEO_PLL1_OUT 40
|
||||
#define IMX8MM_DRAM_PLL_OUT 41
|
||||
#define IMX8MM_GPU_PLL_OUT 42
|
||||
#define IMX8MM_VPU_PLL_OUT 43
|
||||
#define IMX8MM_ARM_PLL_OUT 44
|
||||
#define IMX8MM_SYS_PLL1_OUT 45
|
||||
#define IMX8MM_SYS_PLL2_OUT 46
|
||||
#define IMX8MM_SYS_PLL3_OUT 47
|
||||
#define IMX8MM_SYS_PLL1_40M 48
|
||||
#define IMX8MM_SYS_PLL1_80M 49
|
||||
#define IMX8MM_SYS_PLL1_100M 50
|
||||
#define IMX8MM_SYS_PLL1_133M 51
|
||||
#define IMX8MM_SYS_PLL1_160M 52
|
||||
#define IMX8MM_SYS_PLL1_200M 53
|
||||
#define IMX8MM_SYS_PLL1_266M 54
|
||||
#define IMX8MM_SYS_PLL1_400M 55
|
||||
#define IMX8MM_SYS_PLL1_800M 56
|
||||
#define IMX8MM_SYS_PLL2_50M 57
|
||||
#define IMX8MM_SYS_PLL2_100M 58
|
||||
#define IMX8MM_SYS_PLL2_125M 59
|
||||
#define IMX8MM_SYS_PLL2_166M 60
|
||||
#define IMX8MM_SYS_PLL2_200M 61
|
||||
#define IMX8MM_SYS_PLL2_250M 62
|
||||
#define IMX8MM_SYS_PLL2_333M 63
|
||||
#define IMX8MM_SYS_PLL2_500M 64
|
||||
#define IMX8MM_SYS_PLL2_1000M 65
|
||||
|
||||
/* core */
|
||||
#define IMX8MM_CLK_A53_SRC 66
|
||||
#define IMX8MM_CLK_M4_SRC 67
|
||||
#define IMX8MM_CLK_VPU_SRC 68
|
||||
#define IMX8MM_CLK_GPU3D_SRC 69
|
||||
#define IMX8MM_CLK_GPU2D_SRC 70
|
||||
#define IMX8MM_CLK_A53_CG 71
|
||||
#define IMX8MM_CLK_M4_CG 72
|
||||
#define IMX8MM_CLK_VPU_CG 73
|
||||
#define IMX8MM_CLK_GPU3D_CG 74
|
||||
#define IMX8MM_CLK_GPU2D_CG 75
|
||||
#define IMX8MM_CLK_A53_DIV 76
|
||||
#define IMX8MM_CLK_M4_DIV 77
|
||||
#define IMX8MM_CLK_VPU_DIV 78
|
||||
#define IMX8MM_CLK_GPU3D_DIV 79
|
||||
#define IMX8MM_CLK_GPU2D_DIV 80
|
||||
|
||||
/* bus */
|
||||
#define IMX8MM_CLK_MAIN_AXI 81
|
||||
#define IMX8MM_CLK_ENET_AXI 82
|
||||
#define IMX8MM_CLK_NAND_USDHC_BUS 83
|
||||
#define IMX8MM_CLK_VPU_BUS 84
|
||||
#define IMX8MM_CLK_DISP_AXI 85
|
||||
#define IMX8MM_CLK_DISP_APB 86
|
||||
#define IMX8MM_CLK_DISP_RTRM 87
|
||||
#define IMX8MM_CLK_USB_BUS 88
|
||||
#define IMX8MM_CLK_GPU_AXI 89
|
||||
#define IMX8MM_CLK_GPU_AHB 90
|
||||
#define IMX8MM_CLK_NOC 91
|
||||
#define IMX8MM_CLK_NOC_APB 92
|
||||
|
||||
#define IMX8MM_CLK_AHB 93
|
||||
#define IMX8MM_CLK_AUDIO_AHB 94
|
||||
#define IMX8MM_CLK_IPG_ROOT 95
|
||||
#define IMX8MM_CLK_IPG_AUDIO_ROOT 96
|
||||
|
||||
#define IMX8MM_CLK_DRAM_ALT 97
|
||||
#define IMX8MM_CLK_DRAM_APB 98
|
||||
#define IMX8MM_CLK_VPU_G1 99
|
||||
#define IMX8MM_CLK_VPU_G2 100
|
||||
#define IMX8MM_CLK_DISP_DTRC 101
|
||||
#define IMX8MM_CLK_DISP_DC8000 102
|
||||
#define IMX8MM_CLK_PCIE1_CTRL 103
|
||||
#define IMX8MM_CLK_PCIE1_PHY 104
|
||||
#define IMX8MM_CLK_PCIE1_AUX 105
|
||||
#define IMX8MM_CLK_DC_PIXEL 106
|
||||
#define IMX8MM_CLK_LCDIF_PIXEL 107
|
||||
#define IMX8MM_CLK_SAI1 108
|
||||
#define IMX8MM_CLK_SAI2 109
|
||||
#define IMX8MM_CLK_SAI3 110
|
||||
#define IMX8MM_CLK_SAI4 111
|
||||
#define IMX8MM_CLK_SAI5 112
|
||||
#define IMX8MM_CLK_SAI6 113
|
||||
#define IMX8MM_CLK_SPDIF1 114
|
||||
#define IMX8MM_CLK_SPDIF2 115
|
||||
#define IMX8MM_CLK_ENET_REF 116
|
||||
#define IMX8MM_CLK_ENET_TIMER 117
|
||||
#define IMX8MM_CLK_ENET_PHY_REF 118
|
||||
#define IMX8MM_CLK_NAND 119
|
||||
#define IMX8MM_CLK_QSPI 120
|
||||
#define IMX8MM_CLK_USDHC1 121
|
||||
#define IMX8MM_CLK_USDHC2 122
|
||||
#define IMX8MM_CLK_I2C1 123
|
||||
#define IMX8MM_CLK_I2C2 124
|
||||
#define IMX8MM_CLK_I2C3 125
|
||||
#define IMX8MM_CLK_I2C4 126
|
||||
#define IMX8MM_CLK_UART1 127
|
||||
#define IMX8MM_CLK_UART2 128
|
||||
#define IMX8MM_CLK_UART3 129
|
||||
#define IMX8MM_CLK_UART4 130
|
||||
#define IMX8MM_CLK_USB_CORE_REF 131
|
||||
#define IMX8MM_CLK_USB_PHY_REF 132
|
||||
#define IMX8MM_CLK_ECSPI1 133
|
||||
#define IMX8MM_CLK_ECSPI2 134
|
||||
#define IMX8MM_CLK_PWM1 135
|
||||
#define IMX8MM_CLK_PWM2 136
|
||||
#define IMX8MM_CLK_PWM3 137
|
||||
#define IMX8MM_CLK_PWM4 138
|
||||
#define IMX8MM_CLK_GPT1 139
|
||||
#define IMX8MM_CLK_WDOG 140
|
||||
#define IMX8MM_CLK_WRCLK 141
|
||||
#define IMX8MM_CLK_DSI_CORE 142
|
||||
#define IMX8MM_CLK_DSI_PHY_REF 143
|
||||
#define IMX8MM_CLK_DSI_DBI 144
|
||||
#define IMX8MM_CLK_USDHC3 145
|
||||
#define IMX8MM_CLK_CSI1_CORE 146
|
||||
#define IMX8MM_CLK_CSI1_PHY_REF 147
|
||||
#define IMX8MM_CLK_CSI1_ESC 148
|
||||
#define IMX8MM_CLK_CSI2_CORE 149
|
||||
#define IMX8MM_CLK_CSI2_PHY_REF 150
|
||||
#define IMX8MM_CLK_CSI2_ESC 151
|
||||
#define IMX8MM_CLK_PCIE2_CTRL 152
|
||||
#define IMX8MM_CLK_PCIE2_PHY 153
|
||||
#define IMX8MM_CLK_PCIE2_AUX 154
|
||||
#define IMX8MM_CLK_ECSPI3 155
|
||||
#define IMX8MM_CLK_PDM 156
|
||||
#define IMX8MM_CLK_VPU_H1 157
|
||||
#define IMX8MM_CLK_CLKO1 158
|
||||
|
||||
#define IMX8MM_CLK_ECSPI1_ROOT 159
|
||||
#define IMX8MM_CLK_ECSPI2_ROOT 160
|
||||
#define IMX8MM_CLK_ECSPI3_ROOT 161
|
||||
#define IMX8MM_CLK_ENET1_ROOT 162
|
||||
#define IMX8MM_CLK_GPT1_ROOT 163
|
||||
#define IMX8MM_CLK_I2C1_ROOT 164
|
||||
#define IMX8MM_CLK_I2C2_ROOT 165
|
||||
#define IMX8MM_CLK_I2C3_ROOT 166
|
||||
#define IMX8MM_CLK_I2C4_ROOT 167
|
||||
#define IMX8MM_CLK_OCOTP_ROOT 168
|
||||
#define IMX8MM_CLK_PCIE1_ROOT 169
|
||||
#define IMX8MM_CLK_PWM1_ROOT 170
|
||||
#define IMX8MM_CLK_PWM2_ROOT 171
|
||||
#define IMX8MM_CLK_PWM3_ROOT 172
|
||||
#define IMX8MM_CLK_PWM4_ROOT 173
|
||||
#define IMX8MM_CLK_QSPI_ROOT 174
|
||||
#define IMX8MM_CLK_NAND_ROOT 175
|
||||
#define IMX8MM_CLK_SAI1_ROOT 176
|
||||
#define IMX8MM_CLK_SAI1_IPG 177
|
||||
#define IMX8MM_CLK_SAI2_ROOT 178
|
||||
#define IMX8MM_CLK_SAI2_IPG 179
|
||||
#define IMX8MM_CLK_SAI3_ROOT 180
|
||||
#define IMX8MM_CLK_SAI3_IPG 181
|
||||
#define IMX8MM_CLK_SAI4_ROOT 182
|
||||
#define IMX8MM_CLK_SAI4_IPG 183
|
||||
#define IMX8MM_CLK_SAI5_ROOT 184
|
||||
#define IMX8MM_CLK_SAI5_IPG 185
|
||||
#define IMX8MM_CLK_SAI6_ROOT 186
|
||||
#define IMX8MM_CLK_SAI6_IPG 187
|
||||
#define IMX8MM_CLK_UART1_ROOT 188
|
||||
#define IMX8MM_CLK_UART2_ROOT 189
|
||||
#define IMX8MM_CLK_UART3_ROOT 190
|
||||
#define IMX8MM_CLK_UART4_ROOT 191
|
||||
#define IMX8MM_CLK_USB1_CTRL_ROOT 192
|
||||
#define IMX8MM_CLK_GPU3D_ROOT 193
|
||||
#define IMX8MM_CLK_USDHC1_ROOT 194
|
||||
#define IMX8MM_CLK_USDHC2_ROOT 195
|
||||
#define IMX8MM_CLK_WDOG1_ROOT 196
|
||||
#define IMX8MM_CLK_WDOG2_ROOT 197
|
||||
#define IMX8MM_CLK_WDOG3_ROOT 198
|
||||
#define IMX8MM_CLK_VPU_G1_ROOT 199
|
||||
#define IMX8MM_CLK_GPU_BUS_ROOT 200
|
||||
#define IMX8MM_CLK_VPU_H1_ROOT 201
|
||||
#define IMX8MM_CLK_VPU_G2_ROOT 202
|
||||
#define IMX8MM_CLK_PDM_ROOT 203
|
||||
#define IMX8MM_CLK_DISP_ROOT 204
|
||||
#define IMX8MM_CLK_DISP_AXI_ROOT 205
|
||||
#define IMX8MM_CLK_DISP_APB_ROOT 206
|
||||
#define IMX8MM_CLK_DISP_RTRM_ROOT 207
|
||||
#define IMX8MM_CLK_USDHC3_ROOT 208
|
||||
#define IMX8MM_CLK_TMU_ROOT 209
|
||||
#define IMX8MM_CLK_VPU_DEC_ROOT 210
|
||||
#define IMX8MM_CLK_SDMA1_ROOT 211
|
||||
#define IMX8MM_CLK_SDMA2_ROOT 212
|
||||
#define IMX8MM_CLK_SDMA3_ROOT 213
|
||||
#define IMX8MM_CLK_GPT_3M 214
|
||||
#define IMX8MM_CLK_ARM 215
|
||||
#define IMX8MM_CLK_PDM_IPG 216
|
||||
#define IMX8MM_CLK_GPU2D_ROOT 217
|
||||
#define IMX8MM_CLK_MU_ROOT 218
|
||||
#define IMX8MM_CLK_CSI1_ROOT 219
|
||||
|
||||
#define IMX8MM_CLK_DRAM_CORE 220
|
||||
#define IMX8MM_CLK_DRAM_ALT_ROOT 221
|
||||
|
||||
#define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222
|
||||
|
||||
#define IMX8MM_CLK_END 223
|
||||
|
||||
#endif
|
@ -391,5 +391,14 @@
|
||||
|
||||
#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 267
|
||||
|
||||
#define IMX8MQ_CLK_END 268
|
||||
#define IMX8MQ_CLK_CLKO1 268
|
||||
#define IMX8MQ_CLK_ARM 269
|
||||
|
||||
#define IMX8MQ_CLK_GPIO1_ROOT 270
|
||||
#define IMX8MQ_CLK_GPIO2_ROOT 271
|
||||
#define IMX8MQ_CLK_GPIO3_ROOT 272
|
||||
#define IMX8MQ_CLK_GPIO4_ROOT 273
|
||||
#define IMX8MQ_CLK_GPIO5_ROOT 274
|
||||
|
||||
#define IMX8MQ_CLK_END 275
|
||||
#endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */
|
||||
|
@ -71,6 +71,7 @@
|
||||
#define MMP2_CLK_CCIC1_MIX 117
|
||||
#define MMP2_CLK_CCIC1_PHY 118
|
||||
#define MMP2_CLK_CCIC1_SPHY 119
|
||||
#define MMP2_CLK_DISP0_LCDC 120
|
||||
|
||||
#define MMP2_NR_CLKS 200
|
||||
#endif
|
||||
|
@ -160,6 +160,7 @@ struct clk_hw_omap {
|
||||
struct clockdomain *clkdm;
|
||||
const struct clk_hw_omap_ops *ops;
|
||||
u32 context;
|
||||
int autoidle_count;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user