diff options
Diffstat (limited to 'drivers/clk/imx')
-rw-r--r-- | drivers/clk/imx/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/imx/clk-composite-8m.c | 26 | ||||
-rw-r--r-- | drivers/clk/imx/clk-composite-93.c | 216 | ||||
-rw-r--r-- | drivers/clk/imx/clk-fracn-gppll.c | 297 | ||||
-rw-r--r-- | drivers/clk/imx/clk-gate-93.c | 186 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx1.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx21.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx25.c | 49 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx27.c | 14 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx31.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx35.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx5.c | 43 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx6.c | 15 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx6sl.c | 13 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx6sx.c | 13 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx6ul.c | 13 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx7.c | 40 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8mm.c | 65 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8mn.c | 65 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8mp.c | 97 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx93.c | 331 | ||||
-rw-r--r-- | drivers/clk/imx/clk-vf610.c | 9 | ||||
-rw-r--r-- | drivers/clk/imx/clk.h | 65 |
23 files changed, 1367 insertions, 219 deletions
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 4a792422d5..eb9f8334c3 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -34,4 +34,5 @@ obj-$(CONFIG_ARCH_IMX8MM) += clk-imx8mm.o obj-$(CONFIG_ARCH_IMX8MN) += clk-imx8mn.o obj-$(CONFIG_ARCH_IMX8MP) += clk-imx8mp.o obj-$(CONFIG_ARCH_IMX8MQ) += clk-imx8mq.o +obj-$(CONFIG_ARCH_IMX93) += clk-imx93.o clk-composite-93.o clk-gate-93.o clk-fracn-gppll.o obj-$(CONFIG_ARCH_VF610) += clk-vf610.o diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 72534117f2..04d83d208b 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -158,40 +158,43 @@ struct clk *imx8m_clk_composite_flags(const char *name, u32 composite_flags, unsigned long flags) { - struct clk *comp = ERR_PTR(-ENOMEM); + struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw; + struct clk_hw *div_hw, *gate_hw = NULL; struct clk_divider *div = NULL; struct clk_gate *gate = NULL; struct clk_mux *mux = NULL; + const struct clk_ops *divider_ops; const struct clk_ops *mux_ops; mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) goto fail; + mux_hw = &mux->hw; mux->reg = reg; mux->shift = PCG_PCS_SHIFT; mux->width = PCG_PCS_WIDTH; - mux->hw.clk.ops = &clk_mux_ops; div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) goto fail; + div_hw = &div->hw; div->reg = reg; if (composite_flags & IMX_COMPOSITE_CORE) { div->shift = PCG_DIV_SHIFT; div->width = PCG_CORE_DIV_WIDTH; - div->hw.clk.ops = &clk_divider_ops; + divider_ops = &clk_divider_ops; mux_ops = &imx8m_clk_composite_mux_ops; } else if (composite_flags & IMX_COMPOSITE_BUS) { div->shift = PCG_PREDIV_SHIFT; div->width = PCG_PREDIV_WIDTH; - div->hw.clk.ops = &imx8m_clk_composite_divider_ops; + divider_ops = &imx8m_clk_composite_divider_ops; mux_ops = &imx8m_clk_composite_mux_ops; } else { div->shift = PCG_PREDIV_SHIFT; div->width = PCG_PREDIV_WIDTH; - div->hw.clk.ops = &imx8m_clk_composite_divider_ops; + divider_ops = &imx8m_clk_composite_divider_ops; mux_ops = &clk_mux_ops; } @@ -199,20 +202,21 @@ struct clk *imx8m_clk_composite_flags(const char *name, if (!gate) goto fail; + gate_hw = &gate->hw; gate->reg = reg; gate->shift = PCG_CGC_SHIFT; - gate->hw.clk.ops = &clk_gate_ops; - comp = clk_register_composite(name, parent_names, num_parents, - &mux->hw.clk, &div->hw.clk, &gate->hw.clk, flags); - if (IS_ERR(comp)) + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux_hw, mux_ops, div_hw, + divider_ops, gate_hw, &clk_gate_ops, flags); + if (IS_ERR(hw)) goto fail; - return comp; + return clk_hw_to_clk(hw); fail: kfree(gate); kfree(div); kfree(mux); - return ERR_CAST(comp); + return ERR_CAST(hw); } diff --git a/drivers/clk/imx/clk-composite-93.c b/drivers/clk/imx/clk-composite-93.c new file mode 100644 index 0000000000..2b3753d569 --- /dev/null +++ b/drivers/clk/imx/clk-composite-93.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 NXP + * + * Peng Fan <peng.fan@nxp.com> + */ + +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/types.h> +#include <of_address.h> +#include <linux/iopoll.h> + +#include "clk.h" + +#define TIMEOUT_US 500U + +#define CCM_DIV_SHIFT 0 +#define CCM_DIV_WIDTH 8 +#define CCM_MUX_SHIFT 8 +#define CCM_MUX_MASK 3 +#define CCM_OFF_SHIFT 24 +#define CCM_BUSY_SHIFT 28 + +#define STAT_OFFSET 0x4 +#define AUTHEN_OFFSET 0x30 +#define TZ_NS_SHIFT 9 +#define TZ_NS_MASK BIT(9) + +#define WHITE_LIST_SHIFT 16 + +static int imx93_clk_composite_wait_ready(struct clk_hw *hw, void __iomem *reg) +{ + int ret; + u32 val; + + ret = readl_poll_timeout(reg + STAT_OFFSET, val, !(val & BIT(CCM_BUSY_SHIFT)), + TIMEOUT_US); + if (ret) + pr_err("Slice[%s] busy timeout\n", clk_hw_get_name(hw)); + + return ret; +} + +static void imx93_clk_composite_gate_endisable(struct clk_hw *hw, int enable) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 reg; + + reg = readl(gate->reg); + + if (enable) + reg &= ~BIT(gate->shift); + else + reg |= BIT(gate->shift); + + writel(reg, gate->reg); + + imx93_clk_composite_wait_ready(hw, gate->reg); +} + +static int imx93_clk_composite_gate_enable(struct clk_hw *hw) +{ + imx93_clk_composite_gate_endisable(hw, 1); + + return 0; +} + +static void imx93_clk_composite_gate_disable(struct clk_hw *hw) +{ + imx93_clk_composite_gate_endisable(hw, 0); +} + +static const struct clk_ops imx93_clk_composite_gate_ops = { + .enable = imx93_clk_composite_gate_enable, + .disable = imx93_clk_composite_gate_disable, + .is_enabled = clk_gate_is_enabled, +}; + +static unsigned long +imx93_clk_composite_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + return clk_divider_ops.recalc_rate(hw, parent_rate); +} + +static long +imx93_clk_composite_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) +{ + return clk_divider_ops.round_rate(hw, rate, prate); +} + +static int imx93_clk_composite_divider_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_divider *divider = to_clk_divider(hw); + int value; + u32 val; + int ret; + + value = divider_get_val(rate, parent_rate, divider->table, divider->width, divider->flags); + if (value < 0) + return value; + + val = readl(divider->reg); + val &= ~(clk_div_mask(divider->width) << divider->shift); + val |= (u32)value << divider->shift; + writel(val, divider->reg); + + ret = imx93_clk_composite_wait_ready(hw, divider->reg); + + return ret; +} + +static const struct clk_ops imx93_clk_composite_divider_ops = { + .recalc_rate = imx93_clk_composite_divider_recalc_rate, + .round_rate = imx93_clk_composite_divider_round_rate, + .set_rate = imx93_clk_composite_divider_set_rate, +}; + +static int imx93_clk_composite_mux_get_parent(struct clk_hw *hw) +{ + return clk_mux_ops.get_parent(hw); +} + +static int imx93_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_mux *mux = to_clk_mux(hw); + u32 val = clk_mux_index_to_val(mux->table, mux->flags, index); + u32 reg; + int ret; + + reg = readl(mux->reg); + reg &= ~(((1 << mux->width) - 1) << mux->shift); + val = val << mux->shift; + reg |= val; + writel(reg, mux->reg); + + ret = imx93_clk_composite_wait_ready(hw, mux->reg); + + return ret; +} + +static const struct clk_ops imx93_clk_composite_mux_ops = { + .get_parent = imx93_clk_composite_mux_get_parent, + .set_parent = imx93_clk_composite_mux_set_parent, +}; + +struct clk *imx93_clk_composite_flags(const char *name, const char * const *parent_names, + int num_parents, void __iomem *reg, u32 domain_id, + unsigned long flags) +{ + struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw; + struct clk_hw *div_hw, *gate_hw; + struct clk_divider *div = NULL; + struct clk_gate *gate = NULL; + struct clk_mux *mux = NULL; + bool clk_ro = false; + u32 authen; + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto fail; + + mux_hw = &mux->hw; + mux->reg = reg; + mux->shift = CCM_MUX_SHIFT; + mux->width = 2; + + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto fail; + + div_hw = &div->hw; + div->reg = reg; + div->shift = CCM_DIV_SHIFT; + div->width = CCM_DIV_WIDTH; +// div->flags = CLK_DIVIDER_ROUND_CLOSEST; + + authen = readl(reg + AUTHEN_OFFSET); + if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id))) + clk_ro = true; + + if (clk_ro) { + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux_hw, &clk_mux_ro_ops, div_hw, + &clk_divider_ro_ops, NULL, NULL, flags); + } else { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto fail; + + gate_hw = &gate->hw; + gate->reg = reg; + gate->shift = CCM_OFF_SHIFT; + gate->flags = CLK_GATE_SET_TO_DISABLE; + + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux_hw, &imx93_clk_composite_mux_ops, div_hw, + &imx93_clk_composite_divider_ops, gate_hw, + &imx93_clk_composite_gate_ops, + flags | CLK_SET_RATE_NO_REPARENT); + } + + if (IS_ERR(hw)) + goto fail; + + return &hw->clk; + +fail: + kfree(gate); + kfree(div); + kfree(mux); + return ERR_CAST(hw); +} +EXPORT_SYMBOL_GPL(imx93_clk_composite_flags); diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c new file mode 100644 index 0000000000..24e66fd65f --- /dev/null +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2021 NXP + */ + +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/types.h> +#include <of_address.h> +#include <linux/iopoll.h> +#include <linux/bitfield.h> +#include <soc/imx/clk-fracn-gppll.h> + +#include "clk.h" + +#define PLL_FRACN_GP(_rate, _mfi, _mfn, _mfd, _rdiv, _odiv) \ + { \ + .rate = (_rate), \ + .mfi = (_mfi), \ + .mfn = (_mfn), \ + .mfd = (_mfd), \ + .rdiv = (_rdiv), \ + .odiv = (_odiv), \ + } + +#define PLL_FRACN_GP_INTEGER(_rate, _mfi, _rdiv, _odiv) \ + { \ + .rate = (_rate), \ + .mfi = (_mfi), \ + .mfn = 0, \ + .mfd = 0, \ + .rdiv = (_rdiv), \ + .odiv = (_odiv), \ + } + +struct clk_fracn_gppll { + struct clk_hw hw; + void __iomem *base; + const struct imx_fracn_gppll_rate_table *rate_table; + int rate_count; + u32 flags; +}; + +/* + * Fvco = (Fref / rdiv) * (MFI + MFN / MFD) + * Fout = Fvco / odiv + * The (Fref / rdiv) should be in range 20MHz to 40MHz + * The Fvco should be in range 2.5Ghz to 5Ghz + */ +static const struct imx_fracn_gppll_rate_table fracn_tbl[] = { + PLL_FRACN_GP(650000000U, 162, 50, 100, 0, 6), + PLL_FRACN_GP(594000000U, 198, 0, 1, 0, 8), + PLL_FRACN_GP(560000000U, 140, 0, 1, 0, 6), + PLL_FRACN_GP(519750000U, 173, 25, 100, 1, 8), + PLL_FRACN_GP(498000000U, 166, 0, 1, 0, 8), + PLL_FRACN_GP(484000000U, 121, 0, 1, 0, 6), + PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9), + PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12), + PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10), + PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12) +}; + +struct imx_fracn_gppll_clk imx_fracn_gppll = { + .rate_table = fracn_tbl, + .rate_count = ARRAY_SIZE(fracn_tbl), +}; +EXPORT_SYMBOL_GPL(imx_fracn_gppll); + +/* + * Fvco = (Fref / rdiv) * MFI + * Fout = Fvco / odiv + * The (Fref / rdiv) should be in range 20MHz to 40MHz + * The Fvco should be in range 2.5Ghz to 5Ghz + */ +static const struct imx_fracn_gppll_rate_table int_tbl[] = { + PLL_FRACN_GP_INTEGER(1700000000U, 141, 1, 2), + PLL_FRACN_GP_INTEGER(1400000000U, 175, 1, 3), + PLL_FRACN_GP_INTEGER(900000000U, 150, 1, 4), +}; + +struct imx_fracn_gppll_clk imx_fracn_gppll_integer = { + .rate_table = int_tbl, + .rate_count = ARRAY_SIZE(int_tbl), +}; +EXPORT_SYMBOL_GPL(imx_fracn_gppll_integer); + +static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw) +{ + return container_of(hw, struct clk_fracn_gppll, hw); +} + +static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; + int i; + + /* Assuming 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[pll->rate_count - 1].rate; +} + +static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; + u32 pll_numerator, pll_denominator, pll_div; + u32 mfi, mfn, mfd, rdiv, odiv; + u64 fvco = parent_rate; + long rate = 0; + int i; + + pll_numerator = readl_relaxed(pll->base + GPPLL_NUMERATOR); + mfn = FIELD_GET(GPPLL_MFN_MASK, pll_numerator); + + pll_denominator = readl_relaxed(pll->base + GPPLL_DENOMINATOR); + mfd = FIELD_GET(GPPLL_MFD_MASK, pll_denominator); + + pll_div = readl_relaxed(pll->base + GPPLL_DIV); + mfi = FIELD_GET(GPPLL_MFI_MASK, pll_div); + + rdiv = FIELD_GET(GPPLL_RDIV_MASK, pll_div); + odiv = FIELD_GET(GPPLL_ODIV_MASK, pll_div); + + /* + * Sometimes, the recalculated rate has deviation due to + * the frac part. So find the accurate pll rate from the table + * first, if no match rate in the table, use the rate calculated + * from the equation below. + */ + for (i = 0; i < pll->rate_count; i++) { + if (rate_table[i].mfn == mfn && rate_table[i].mfi == mfi && + rate_table[i].mfd == mfd && rate_table[i].rdiv == rdiv && + rate_table[i].odiv == odiv) + rate = rate_table[i].rate; + } + + if (rate) + return (unsigned long)rate; + + if (!rdiv) + rdiv = rdiv + 1; + + switch (odiv) { + case 0: + odiv = 2; + break; + case 1: + odiv = 3; + break; + default: + break; + } + + if (pll->flags & CLK_FRACN_GPPLL_INTEGER) { + /* Fvco = (Fref / rdiv) * MFI */ + fvco = fvco * mfi; + do_div(fvco, rdiv * odiv); + } else { + /* Fvco = (Fref / rdiv) * (MFI + MFN / MFD) */ + fvco = fvco * mfi * mfd + fvco * mfn; + do_div(fvco, mfd * rdiv * odiv); + } + + return (unsigned long)fvco; +} + +static int clk_fracn_gppll_wait_lock(struct clk_fracn_gppll *pll) +{ + return fracn_gppll_wait_lock(pll->base); +} + +static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + + return fracn_gppll_set_rate(pll->base, pll->flags, pll->rate_table, + pll->rate_count, drate); +} + +static int clk_fracn_gppll_prepare(struct clk_hw *hw) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 val; + int ret; + + val = readl_relaxed(pll->base + GPPLL_CTRL); + if (val & POWERUP_MASK) + return 0; + + val |= CLKMUX_BYPASS; + writel_relaxed(val, pll->base + GPPLL_CTRL); + + val |= POWERUP_MASK; + writel_relaxed(val, pll->base + GPPLL_CTRL); + + val |= CLKMUX_EN; + writel_relaxed(val, pll->base + GPPLL_CTRL); + + ret = clk_fracn_gppll_wait_lock(pll); + if (ret) + return ret; + + val &= ~CLKMUX_BYPASS; + writel_relaxed(val, pll->base + GPPLL_CTRL); + + return 0; +} + +static int clk_fracn_gppll_is_prepared(struct clk_hw *hw) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 val; + + val = readl_relaxed(pll->base + GPPLL_CTRL); + + return (val & POWERUP_MASK) ? 1 : 0; +} + +static void clk_fracn_gppll_unprepare(struct clk_hw *hw) +{ + struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); + u32 val; + + val = readl_relaxed(pll->base + GPPLL_CTRL); + val &= ~POWERUP_MASK; + writel_relaxed(val, pll->base + GPPLL_CTRL); +} + +static const struct clk_ops clk_fracn_gppll_ops = { + .enable = clk_fracn_gppll_prepare, + .disable = clk_fracn_gppll_unprepare, + .is_enabled = clk_fracn_gppll_is_prepared, + .recalc_rate = clk_fracn_gppll_recalc_rate, + .round_rate = clk_fracn_gppll_round_rate, + .set_rate = clk_fracn_gppll_set_rate, +}; + +static struct clk *_imx_clk_fracn_gppll(const char *name, const char *parent_name, + void __iomem *base, + const struct imx_fracn_gppll_clk *pll_clk, + u32 pll_flags) +{ + struct clk_fracn_gppll *pll; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + 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; + init.ops = &clk_fracn_gppll_ops; + + pll->base = base; + pll->hw.init = &init; + pll->rate_table = pll_clk->rate_table; + pll->rate_count = pll_clk->rate_count; + pll->flags = pll_flags; + + hw = &pll->hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { + pr_err("%s: failed to register pll %s %d\n", __func__, name, ret); + kfree(pll); + return ERR_PTR(ret); + } + + return &hw->clk; +} + +struct clk *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base, + const struct imx_fracn_gppll_clk *pll_clk) +{ + return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_FRACN); +} +EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll); + +struct clk *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name, + void __iomem *base, + const struct imx_fracn_gppll_clk *pll_clk) +{ + return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_INTEGER); +} +EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll_integer); diff --git a/drivers/clk/imx/clk-gate-93.c b/drivers/clk/imx/clk-gate-93.c new file mode 100644 index 0000000000..ed2714a03c --- /dev/null +++ b/drivers/clk/imx/clk-gate-93.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 NXP + * + * Peng Fan <peng.fan@nxp.com> + */ + +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/types.h> +#include <of_address.h> +#include <linux/iopoll.h> + +#include "clk.h" + +#define DIRECT_OFFSET 0x0 + +/* + * 0b000 - LPCG will be OFF in any CPU mode. + * 0b100 - LPCG will be ON in any CPU mode. + */ +#define LPM_SETTING_OFF 0x0 +#define LPM_SETTING_ON 0x4 + +#define LPM_CUR_OFFSET 0x1c + +#define AUTHEN_OFFSET 0x30 +#define CPULPM_EN BIT(2) +#define TZ_NS_SHIFT 9 +#define TZ_NS_MASK BIT(9) + +#define WHITE_LIST_SHIFT 16 + +struct imx93_clk_gate { + struct clk_hw hw; + void __iomem *reg; + u32 bit_idx; + u32 val; + u32 mask; + spinlock_t *lock; + unsigned int *share_count; +}; + +#define to_imx93_clk_gate(_hw) container_of(_hw, struct imx93_clk_gate, hw) + +static void imx93_clk_gate_do_hardware(struct clk_hw *hw, bool enable) +{ + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); + u32 val; + + val = readl(gate->reg + AUTHEN_OFFSET); + if (val & CPULPM_EN) { + val = enable ? LPM_SETTING_ON : LPM_SETTING_OFF; + writel(val, gate->reg + LPM_CUR_OFFSET); + } else { + val = readl(gate->reg + DIRECT_OFFSET); + val &= ~(gate->mask << gate->bit_idx); + if (enable) + val |= (gate->val & gate->mask) << gate->bit_idx; + writel(val, gate->reg + DIRECT_OFFSET); + } +} + +static int imx93_clk_gate_enable(struct clk_hw *hw) +{ + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); + unsigned long flags; + + spin_lock_irqsave(gate->lock, flags); + + if (gate->share_count && (*gate->share_count)++ > 0) + goto out; + + imx93_clk_gate_do_hardware(hw, true); +out: + spin_unlock_irqrestore(gate->lock, flags); + + return 0; +} + +static void imx93_clk_gate_disable(struct clk_hw *hw) +{ + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); + unsigned long flags; + + spin_lock_irqsave(gate->lock, flags); + + if (gate->share_count) { + if (WARN_ON(*gate->share_count == 0)) + goto out; + else if (--(*gate->share_count) > 0) + goto out; + } + + imx93_clk_gate_do_hardware(hw, false); +out: + spin_unlock_irqrestore(gate->lock, flags); +} + +static int imx93_clk_gate_reg_is_enabled(struct imx93_clk_gate *gate) +{ + u32 val = readl(gate->reg + AUTHEN_OFFSET); + + if (val & CPULPM_EN) { + val = readl(gate->reg + LPM_CUR_OFFSET); + if (val == LPM_SETTING_ON) + return 1; + } else { + val = readl(gate->reg); + if (((val >> gate->bit_idx) & gate->mask) == gate->val) + return 1; + } + + return 0; +} + +static int imx93_clk_gate_is_enabled(struct clk_hw *hw) +{ + struct imx93_clk_gate *gate = to_imx93_clk_gate(hw); + unsigned long flags; + int ret; + + spin_lock_irqsave(gate->lock, flags); + + ret = imx93_clk_gate_reg_is_enabled(gate); + + spin_unlock_irqrestore(gate->lock, flags); + + return ret; +} + +static const struct clk_ops imx93_clk_gate_ops = { + .set_rate = clk_parent_set_rate, + .round_rate = clk_parent_round_rate, + .enable = imx93_clk_gate_enable, + .disable = imx93_clk_gate_disable, + .is_enabled = imx93_clk_gate_is_enabled, +}; + +static const struct clk_ops imx93_clk_gate_ro_ops = { + .is_enabled = imx93_clk_gate_is_enabled, +}; + +struct clk *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name, + unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val, + u32 mask, u32 domain_id, unsigned int *share_count) +{ + struct imx93_clk_gate *gate; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + u32 authen; + + gate = kzalloc(sizeof(struct imx93_clk_gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + gate->reg = reg; + gate->bit_idx = bit_idx; + gate->val = val; + gate->mask = mask; + gate->share_count = share_count; + + init.name = name; + init.ops = &imx93_clk_gate_ops; + init.flags = flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + + gate->hw.init = &init; + hw = &gate->hw; + + authen = readl(reg + AUTHEN_OFFSET); + if (!(authen & TZ_NS_MASK) || !(authen & BIT(WHITE_LIST_SHIFT + domain_id))) + init.ops = &imx93_clk_gate_ro_ops; + + ret = clk_hw_register(dev, hw); + if (ret) { + kfree(gate); + return ERR_PTR(ret); + } + + return &hw->clk; +} +EXPORT_SYMBOL_GPL(imx93_clk_gate); diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c index cff32c0f99..3b97fbcc6d 100644 --- a/drivers/clk/imx/clk-imx1.c +++ b/drivers/clk/imx/clk-imx1.c @@ -10,7 +10,7 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx1-regs.h> +#include <mach/imx/imx1-regs.h> #include "clk.h" @@ -73,7 +73,7 @@ static int __init mx1_clocks_init(void __iomem *regs, unsigned long fref) return 0; } -static int imx1_ccm_probe(struct device_d *dev) +static int imx1_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *regs; @@ -95,8 +95,9 @@ static __maybe_unused struct of_device_id imx1_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx1_ccm_dt_ids); -static struct driver_d imx1_ccm_driver = { +static struct driver imx1_ccm_driver = { .probe = imx1_ccm_probe, .name = "imx1-ccm", .of_compatible = DRV_OF_COMPAT(imx1_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c index 7abd82eeb1..6f2386e7d2 100644 --- a/drivers/clk/imx/clk-imx21.c +++ b/drivers/clk/imx/clk-imx21.c @@ -12,7 +12,7 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx21-regs.h> +#include <mach/imx/imx21-regs.h> #include "clk.h" @@ -92,7 +92,7 @@ static const char *spll_sel_clks[] = { "ckih", }; -static int imx21_ccm_probe(struct device_d *dev) +static int imx21_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base; @@ -169,8 +169,9 @@ static __maybe_unused struct of_device_id imx21_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx21_ccm_dt_ids); -static struct driver_d imx21_ccm_driver = { +static struct driver imx21_ccm_driver = { .probe = imx21_ccm_probe, .name = "imx21-ccm", .of_compatible = DRV_OF_COMPAT(imx21_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c index 8aa87a5200..cbaca348e2 100644 --- a/drivers/clk/imx/clk-imx25.c +++ b/drivers/clk/imx/clk-imx25.c @@ -10,7 +10,7 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx25-regs.h> +#include <mach/imx/imx25-regs.h> #include "clk.h" @@ -37,25 +37,25 @@ #define CCM_MCR 0x64 enum mx25_clks { - dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg, - per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel, - per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel, - per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5, - per6, per7, per8, per9, per10, per11, per12, per13, per14, per15, - csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, - gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per, - pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per, - uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb, - esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb, - reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg, - cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg, - reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9, - gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12, - iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg, - pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg, - sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg, - uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17, - wdt_ipg, clk_max + /* 0 */ dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg, + /* 10 */ per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel, + /* 17 */ per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel, + /* 23 */ per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5, + /* 32 */ per6, per7, per8, per9, per10, per11, per12, per13, per14, per15, + /* 42 */ csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, + /* 47 */ gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per, + /* 52 */ pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per, + /* 57 */ uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb, + /* 64 */ esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb, + /* 71 */ reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg, + /* 78 */ cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg, + /* 85 */ reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9, + /* 92 */ gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12, + /* 99 */ iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg, + /* 106 */ pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg, + /* 113 */ sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg, + /* 120 */ uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17, + /* 126 */ wdt_ipg, clk_max }; static struct clk *clks[clk_max]; @@ -70,7 +70,7 @@ static const char *per_sel_clks[] = { "upll", }; -static int imx25_ccm_probe(struct device_d *dev) +static int imx25_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base; @@ -143,6 +143,9 @@ static int imx25_ccm_probe(struct device_d *dev) clks[rngb_ipg] = imx_clk_gate("rngb_ipg", "ipg", base + CCM_CGCR2, 3); clks[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", base + CCM_CGCR1, 8); + /* reserved in datasheet, but used as wdt in FSL kernel */ + clks[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", base + CCM_CGCR2, 19); + clkdev_add_physbase(clks[per15], MX25_UART1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per15], MX25_UART2_BASE_ADDR, NULL); clkdev_add_physbase(clks[per15], MX25_UART3_BASE_ADDR, NULL); @@ -168,6 +171,7 @@ static int imx25_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[scc_ipg], MX25_SCC_BASE_ADDR, "ipg"); clkdev_add_physbase(clks[rngb_ipg], MX25_RNGB_BASE_ADDR, "ipg"); clkdev_add_physbase(clks[dryice_ipg], MX25_DRYICE_BASE_ADDR, NULL); + clkdev_add_physbase(clks[wdt_ipg], MX25_WATCHDOG_BASE_ADDR, NULL); return 0; } @@ -179,8 +183,9 @@ static __maybe_unused struct of_device_id imx25_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx25_ccm_dt_ids); -static struct driver_d imx25_ccm_driver = { +static struct driver imx25_ccm_driver = { .probe = imx25_ccm_probe, .name = "imx25-ccm", .of_compatible = DRV_OF_COMPAT(imx25_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c index 54894d1032..3f03705634 100644 --- a/drivers/clk/imx/clk-imx27.c +++ b/drivers/clk/imx/clk-imx27.c @@ -6,9 +6,9 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx27-regs.h> -#include <mach/generic.h> -#include <mach/revision.h> +#include <mach/imx/imx27-regs.h> +#include <mach/imx/generic.h> +#include <mach/imx/revision.h> #include "clk.h" @@ -155,7 +155,7 @@ static const char *clko_sel_clks[] = { NULL, }; -static int imx27_ccm_probe(struct device_d *dev) +static int imx27_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base; @@ -221,6 +221,7 @@ static int imx27_ccm_probe(struct device_d *dev) clks[per3_gate] = imx_clk_gate("per3_gate", "per3_div", base + CCM_PCCR1, 8); clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR1, 15); clks[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", base + CCM_PCCR0, 14); + clks[wdog_ipg_gate] = imx_clk_gate("wdog_ipg_gate", "ipg", base + CCM_PCCR1, 24); clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL); @@ -246,6 +247,8 @@ static int imx27_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[lcdc_ahb_gate], MX27_LCDC_BASE_ADDR, "ahb"); clkdev_add_physbase(clks[lcdc_ipg_gate], MX27_LCDC_BASE_ADDR, "ipg"); clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[nfc_div], MX27_NFC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[wdog_ipg_gate], MX27_WDOG_BASE_ADDR, NULL); return 0; } @@ -257,8 +260,9 @@ static __maybe_unused struct of_device_id imx27_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx27_ccm_dt_ids); -static struct driver_d imx27_ccm_driver = { +static struct driver imx27_ccm_driver = { .probe = imx27_ccm_probe, .name = "imx27-ccm", .of_compatible = DRV_OF_COMPAT(imx27_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c index fe241cba5f..47189f7814 100644 --- a/drivers/clk/imx/clk-imx31.c +++ b/drivers/clk/imx/clk-imx31.c @@ -10,7 +10,7 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx31-regs.h> +#include <mach/imx/imx31-regs.h> #include "clk.h" @@ -79,7 +79,7 @@ static const char *per_sel[] = { "ipg", }; -static int imx31_ccm_probe(struct device_d *dev) +static int imx31_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base; @@ -138,8 +138,9 @@ static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx31_ccm_dt_ids); -static struct driver_d imx31_ccm_driver = { +static struct driver imx31_ccm_driver = { .probe = imx31_ccm_probe, .name = "imx31-ccm", .of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c index 9af149f68e..7ea823c6c9 100644 --- a/drivers/clk/imx/clk-imx35.c +++ b/drivers/clk/imx/clk-imx35.c @@ -9,7 +9,7 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx35-regs.h> +#include <mach/imx/imx35-regs.h> #include <reset_source.h> #include "clk.h" @@ -85,7 +85,7 @@ static const char *ipg_per_sel[] = { "arm_per_div", }; -static int imx35_ccm_probe(struct device_d *dev) +static int imx35_ccm_probe(struct device *dev) { struct resource *iores; u32 pdr0, consumer_sel, hsp_sel; @@ -201,8 +201,9 @@ static __maybe_unused struct of_device_id imx35_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx35_ccm_dt_ids); -static struct driver_d imx35_ccm_driver = { +static struct driver imx35_ccm_driver = { .probe = imx35_ccm_probe, .name = "imx35-ccm", .of_compatible = DRV_OF_COMPAT(imx35_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx5.c b/drivers/clk/imx/clk-imx5.c index c7a1818bd7..b78611b0d4 100644 --- a/drivers/clk/imx/clk-imx5.c +++ b/drivers/clk/imx/clk-imx5.c @@ -10,9 +10,9 @@ #include <of.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx50-regs.h> -#include <mach/imx51-regs.h> -#include <mach/imx53-regs.h> +#include <mach/imx/imx50-regs.h> +#include <mach/imx/imx51-regs.h> +#include <mach/imx/imx53-regs.h> #include <dt-bindings/clock/imx5-clock.h> #include "clk.h" @@ -194,7 +194,8 @@ static const char *ipu_sel[] = { "ahb", }; -static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *base) +static void __init mx5_clocks_common_init(struct device *dev, + void __iomem *base) { writel(0xffffffff, base + CCM_CCGR0); writel(0xffffffff, base + CCM_CCGR1); @@ -205,7 +206,9 @@ static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *ba writel(0xffffffff, base + CCM_CCGR6); writel(0xffffffff, base + CCM_CCGR7); - if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) { + clks[IMX5_CLK_DUMMY] = clk_fixed("dummy", 0); + + if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->of_node) { clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768); clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000); } @@ -277,7 +280,7 @@ static void mx5_clocks_ipu_init(void __iomem *regs) clks[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", regs + CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); } -static int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs) +static int __init mx50_clocks_init(struct device *dev, void __iomem *regs) { clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX50_PLL1_BASE_ADDR); @@ -312,11 +315,12 @@ static int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs) clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per"); clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per"); clkdev_add_physbase(clks[IMX5_CLK_AHB], MX50_OTG_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX50_WDOG1_BASE_ADDR, NULL); return 0; } -static int imx50_ccm_probe(struct device_d *dev) +static int imx50_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *regs; @@ -338,8 +342,9 @@ static __maybe_unused struct of_device_id imx50_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx50_ccm_dt_ids); -static __maybe_unused struct driver_d imx50_ccm_driver = { +static __maybe_unused struct driver imx50_ccm_driver = { .probe = imx50_ccm_probe, .name = "imx50-ccm", .of_compatible = DRV_OF_COMPAT(imx50_ccm_dt_ids), @@ -366,7 +371,7 @@ static void mx51_clocks_ipu_init(void __iomem *regs) clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX51_IPU_BASE_ADDR, "di1"); } -static int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs) +static int __init mx51_clocks_init(struct device *dev, void __iomem *regs) { clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX51_PLL1_BASE_ADDR); clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX51_PLL2_BASE_ADDR); @@ -392,6 +397,8 @@ static int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs) clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_ATA_BASE_ADDR, NULL); clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM1_BASE_ADDR, "per"); clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM2_BASE_ADDR, "per"); + clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX51_WDOG_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX51_WDOG2_BASE_ADDR, NULL); if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3)) mx51_clocks_ipu_init(regs); @@ -399,7 +406,7 @@ static int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs) return 0; } -static int imx51_ccm_probe(struct device_d *dev) +static int imx51_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *regs; @@ -413,7 +420,7 @@ static int imx51_ccm_probe(struct device_d *dev) clk_data.clks = clks; clk_data.clk_num = IMX5_CLK_END; - of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &clk_data); return 0; } @@ -425,8 +432,9 @@ static __maybe_unused struct of_device_id imx51_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx51_ccm_dt_ids); -static __maybe_unused struct driver_d imx51_ccm_driver = { +static __maybe_unused struct driver imx51_ccm_driver = { .probe = imx51_ccm_probe, .name = "imx51-ccm", .of_compatible = DRV_OF_COMPAT(imx51_ccm_dt_ids), @@ -458,7 +466,7 @@ static void mx53_clocks_ipu_init(void __iomem *regs) clkdev_add_physbase(clks[IMX5_CLK_IPU_DI1_SEL], MX53_IPU_BASE_ADDR, "di1"); } -static int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs) +static int __init mx53_clocks_init(struct device *dev, void __iomem *regs) { clks[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", (void *)MX53_PLL1_BASE_ADDR); clks[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", (void *)MX53_PLL2_BASE_ADDR); @@ -488,6 +496,8 @@ static int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs) clkdev_add_physbase(clks[IMX5_CLK_AHB], MX53_SATA_BASE_ADDR, NULL); clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM1_BASE_ADDR, "per"); clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM2_BASE_ADDR, "per"); + clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX53_WDOG1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX53_WDOG2_BASE_ADDR, NULL); if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3)) mx53_clocks_ipu_init(regs); @@ -495,7 +505,7 @@ static int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs) return 0; } -static int imx53_ccm_probe(struct device_d *dev) +static int imx53_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *regs; @@ -509,7 +519,7 @@ static int imx53_ccm_probe(struct device_d *dev) clk_data.clks = clks; clk_data.clk_num = IMX5_CLK_END; - of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &clk_data); return 0; } @@ -521,8 +531,9 @@ static __maybe_unused struct of_device_id imx53_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx53_ccm_dt_ids); -static __maybe_unused struct driver_d imx53_ccm_driver = { +static __maybe_unused struct driver imx53_ccm_driver = { .probe = imx53_ccm_probe, .name = "imx53-ccm", .of_compatible = DRV_OF_COMPAT(imx53_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx6.c b/drivers/clk/imx/clk-imx6.c index 06cc992b72..bac0c73d21 100644 --- a/drivers/clk/imx/clk-imx6.c +++ b/drivers/clk/imx/clk-imx6.c @@ -12,9 +12,9 @@ #include <of.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx6-regs.h> -#include <mach/revision.h> -#include <mach/imx6.h> +#include <mach/imx/imx6-regs.h> +#include <mach/imx/revision.h> +#include <mach/imx/imx6.h> #include <dt-bindings/clock/imx6qdl-clock.h> #include "clk.h" @@ -647,7 +647,7 @@ static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb, struct dev clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); } -static int imx6_ccm_probe(struct device_d *dev) +static int imx6_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base, *anatop_base, *ccm_base; @@ -808,7 +808,7 @@ static int imx6_ccm_probe(struct device_d *dev) imx6q_mmdc_ch1_mask_handshake(ccm_base); if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3)) - imx6_add_video_clks(anatop_base, ccm_base, dev->device_node); + imx6_add_video_clks(anatop_base, ccm_base, dev->of_node); writel(0xffffffff, ccm_base + CCGR0); writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */ @@ -824,7 +824,7 @@ static int imx6_ccm_probe(struct device_d *dev) clk_data.clks = clks; clk_data.clk_num = IMX6QDL_CLK_END; - of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &clk_data); clk_enable(clks[IMX6QDL_CLK_MMDC_CH0_AXI_PODF]); clk_enable(clks[IMX6QDL_CLK_PLL6_ENET]); @@ -849,8 +849,9 @@ static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx6_ccm_dt_ids); -static struct driver_d imx6_ccm_driver = { +static struct driver imx6_ccm_driver = { .probe = imx6_ccm_probe, .name = "imx6-ccm", .of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index 466893f82f..93edf24c1d 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c @@ -12,9 +12,9 @@ #include <linux/clkdev.h> #include <linux/err.h> #include <linux/clk.h> -#include <mach/imx6-regs.h> -#include <mach/revision.h> -#include <mach/imx6.h> +#include <mach/imx/imx6-regs.h> +#include <mach/imx/revision.h> +#include <mach/imx/imx6.h> #include "clk.h" #include "common.h" @@ -81,11 +81,11 @@ static struct clk_div_table video_div_table[] = { { } }; -static int imx6sl_ccm_probe(struct device_d *dev) +static int imx6sl_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base, *anatop_base, *ccm_base; - struct device_node *ccm_node = dev->device_node; + struct device_node *ccm_node = dev->of_node; clks[IMX6SL_CLK_DUMMY] = clk_fixed("dummy", 0); @@ -308,8 +308,9 @@ static __maybe_unused struct of_device_id imx6sl_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx6sl_ccm_dt_ids); -static struct driver_d imx6sl_ccm_driver = { +static struct driver imx6sl_ccm_driver = { .probe = imx6sl_ccm_probe, .name = "imx6-ccm", .of_compatible = DRV_OF_COMPAT(imx6sl_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index c11829259e..bebe1ed685 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -12,9 +12,9 @@ #include <linux/clkdev.h> #include <linux/err.h> #include <linux/clk.h> -#include <mach/imx6-regs.h> -#include <mach/revision.h> -#include <mach/imx6.h> +#include <mach/imx/imx6-regs.h> +#include <mach/imx/revision.h> +#include <mach/imx/imx6.h> #include "clk.h" #include "common.h" @@ -109,11 +109,11 @@ static struct clk_div_table video_div_table[] = { { } }; -static int imx6sx_ccm_probe(struct device_d *dev) +static int imx6sx_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base, *anatop_base, *ccm_base; - struct device_node *ccm_node = dev->device_node; + struct device_node *ccm_node = dev->of_node; clks[IMX6SX_CLK_DUMMY] = clk_fixed("dummy", 0); @@ -462,8 +462,9 @@ static __maybe_unused struct of_device_id imx6sx_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx6sx_ccm_dt_ids); -static struct driver_d imx6sx_ccm_driver = { +static struct driver imx6sx_ccm_driver = { .probe = imx6sx_ccm_probe, .name = "imx6-ccm", .of_compatible = DRV_OF_COMPAT(imx6sx_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index af5d582ffc..e60267d8fb 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -11,9 +11,9 @@ #include <of.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx6-regs.h> -#include <mach/revision.h> -#include <mach/imx6.h> +#include <mach/imx/imx6-regs.h> +#include <mach/imx/revision.h> +#include <mach/imx/imx6.h> #include <dt-bindings/clock/imx6ul-clock.h> #include "clk.h" @@ -92,12 +92,12 @@ static struct clk_div_table clk_enet_ref_table[] = { { } }; -static int imx6_ccm_probe(struct device_d *dev) +static int imx6_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base, *anatop_base, *ccm_base; int i; - struct device_node *ccm_node = dev->device_node; + struct device_node *ccm_node = dev->of_node; struct clk_hw *hw; anatop_base = IOMEM(MX6_ANATOP_BASE_ADDR); @@ -461,8 +461,9 @@ static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx6_ccm_dt_ids); -static struct driver_d imx6_ccm_driver = { +static struct driver imx6_ccm_driver = { .probe = imx6_ccm_probe, .name = "imx6-ccm", .of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx7.c b/drivers/clk/imx/clk-imx7.c index ffa39d17b0..224471a982 100644 --- a/drivers/clk/imx/clk-imx7.c +++ b/drivers/clk/imx/clk-imx7.c @@ -6,13 +6,14 @@ #include <common.h> #include <init.h> #include <driver.h> +#include <deep-probe.h> #include <linux/clk.h> #include <io.h> #include <of.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx7-regs.h> -#include <mach/revision.h> +#include <mach/imx/imx7-regs.h> +#include <mach/imx/revision.h> #include <dt-bindings/clock/imx7d-clock.h> #include "clk.h" @@ -358,9 +359,11 @@ static int const clks_init_on[] __initconst = { static struct clk_onecell_data clk_data; -static int imx7_clk_initialized; +static struct device_node *ccm_np; -static int imx7_ccm_probe(struct device_d *dev) +static int imx7_clk_setup(void); + +static int imx7_ccm_probe(struct device *dev) { struct resource *iores; void __iomem *base, *anatop_base, *ccm_base; @@ -804,21 +807,37 @@ static int imx7_ccm_probe(struct device_d *dev) clk_data.clks = clks; clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &clk_data); + + ccm_np = dev->of_node; - imx7_clk_initialized = 1; + /* + * imx7_clk_setup() requires both the CCM and fixed-clock osc devices + * to be available. + * With deep probe enabled, we can instead just directly call + * imx7_clk_setup because the osc fixed-clock will just be probed + * on demand if not yet available. Otherwise, the imx7_clk_setup + * will run at postcore_initcall level. + */ + if (deep_probe_is_supported()) + return imx7_clk_setup(); return 0; } static int imx7_clk_setup(void) { + struct clk *clk; int i; - if (!imx7_clk_initialized) + if (!ccm_np) return 0; - clks[IMX7D_OSC_24M_CLK] = clk_lookup("osc"); + clk = of_clk_get_by_name(ccm_np, "osc"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + clks[IMX7D_OSC_24M_CLK] = clk; for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) clk_enable(clks[clks_init_on[i]]); @@ -840,6 +859,8 @@ static int imx7_clk_setup(void) clk_set_rate(clks[IMX7D_ENET1_TIME_ROOT_CLK], 25000000); clk_set_rate(clks[IMX7D_ENET2_TIME_ROOT_CLK], 25000000); + ccm_np = NULL; + return 0; } postcore_initcall(imx7_clk_setup); @@ -851,8 +872,9 @@ static __maybe_unused struct of_device_id imx7_ccm_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx7_ccm_dt_ids); -static struct driver_d imx7_ccm_driver = { +static struct driver imx7_ccm_driver = { .probe = imx7_ccm_probe, .name = "imx6-ccm", .of_compatible = DRV_OF_COMPAT(imx7_ccm_dt_ids), diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index e6927f58f4..d467062e64 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -280,6 +280,7 @@ static int imx8mm_clocks_init(struct device_node *ccm_np) { struct device_node *anatop_np; void __iomem *ccm, *ana; + u32 val; int ret; anatop_np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop"); @@ -340,45 +341,45 @@ static int imx8mm_clocks_init(struct device_node *ccm_np) clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", ana + 0x114, 11); /* SYS PLL1 fixed output */ - clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", ana + 0x94, 27); - clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", ana + 0x94, 25); - clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", ana + 0x94, 23); - clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", ana + 0x94, 21); - clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", ana + 0x94, 19); - clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", ana + 0x94, 17); - clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", ana + 0x94, 15); - clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", ana + 0x94, 13); + /* + * The gates in CCM_ANALOG_SYS_PLL1_GEN_CTRL are not handled by the + * driver, make sure they are all enabled. + */ + val = readl(ana + 0x94); + val |= BIT(13) | BIT(15) | BIT(17) | BIT(19) | BIT(21) | BIT(23) | BIT(25) | BIT(27); + writel(val, ana + 0x94); + clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", ana + 0x94, 11); - clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + 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); /* SYS PLL2 fixed output */ - clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", ana + 0x104, 27); - clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", ana + 0x104, 25); - clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", ana + 0x104, 23); - clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", ana + 0x104, 21); - clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", ana + 0x104, 19); - clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", ana + 0x104, 17); - clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", ana + 0x104, 15); - clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", ana + 0x104, 13); + /* + * The gates in CCM_ANALOG_SYS_PLL2_GEN_CTRL are not handled by the + * driver, make sure they are all enabled. + */ + val = readl(ana + 0x104); + val |= BIT(13) | BIT(15) | BIT(17) | BIT(19) | BIT(21) | BIT(23) | BIT(25) | BIT(27); + writel(val, ana + 0x104); + clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", ana + 0x104, 11); - clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + 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); /* Core Slice */ diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index a57bfffcb6..02522add39 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -281,6 +281,7 @@ static int imx8mn_clocks_init(struct device_node *ccm_np) { struct device_node *anatop_np; void __iomem *ccm, *ana; + u32 val; int ret; anatop_np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); @@ -341,45 +342,45 @@ static int imx8mn_clocks_init(struct device_node *ccm_np) clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", ana + 0x114, 11); /* SYS PLL1 fixed output */ - clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", ana + 0x94, 27); - clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", ana + 0x94, 25); - clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", ana + 0x94, 23); - clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", ana + 0x94, 21); - clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", ana + 0x94, 19); - clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", ana + 0x94, 17); - clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", ana + 0x94, 15); - clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", ana + 0x94, 13); + /* + * The gates in CCM_ANALOG_SYS_PLL1_GEN_CTRL are not handled by the + * driver, make sure they are all enabled. + */ + val = readl(ana + 0x94); + val |= BIT(13) | BIT(15) | BIT(17) | BIT(19) | BIT(21) | BIT(23) | BIT(25) | BIT(27); + writel(val, ana + 0x94); + clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", ana + 0x94, 11); - clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); - clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); - clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); - clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); - clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); - clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); - clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); - clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); + clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", ana + 0x104, 27); - clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", ana + 0x104, 25); - clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", ana + 0x104, 23); - clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", ana + 0x104, 21); - clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", ana + 0x104, 19); - clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", ana + 0x104, 17); - clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", ana + 0x104, 15); - clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", ana + 0x104, 13); + /* + * The gates in CCM_ANALOG_SYS_PLL2_GEN_CTRL are not handled by the + * driver, make sure they are all enabled. + */ + val = readl(ana + 0x104); + val |= BIT(13) | BIT(15) | BIT(17) | BIT(19) | BIT(21) | BIT(23) | BIT(25) | BIT(27); + writel(val, ana + 0x104); + clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", ana + 0x104, 11); - clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); - clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); - clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); - clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); - clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); - clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); - clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); - clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); + clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); clks[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_mux("clkout1_sel", ana + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index a1611be183..ca1066a4dc 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -12,6 +12,11 @@ #include "clk.h" +static u32 share_count_nand; +static u32 share_count_media; +static u32 share_count_usb; +static u32 share_count_audio; + static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; 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", }; @@ -146,10 +151,6 @@ static const char * const imx8mp_can2_sels[] = {"osc_24m", "sys_pll2_200m", "sys "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; -static const char * const imx8mp_memrepair_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 * const imx8mp_pcie_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", }; @@ -174,10 +175,6 @@ static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "au "video_pll1_out", "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", }; -static const char * const imx8mp_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 * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", }; @@ -356,7 +353,7 @@ static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_p "clk_ext2", "audio_pll2_out", "video_pll1_out", }; -static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", +static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", }; @@ -366,14 +363,13 @@ static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_2 "video_pll1_out", }; static const char * const imx8mp_media_ldb_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", - "sys_pll1_800m", "sys_pll2_1000m", - "clk_ext2", "audio_pll2_out", - "video_pll1_out", }; + "sys_pll1_800m", "sys_pll2_1000m", + "clk_ext2", "audio_pll2_out", + "video_pll1_out", }; -static const char * const imx8mp_media_mipi_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 * const imx8mp_memrepair_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 * const imx8mp_media_mipi_test_byte_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out", "sys_pll2_100m", @@ -398,6 +394,11 @@ static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "au static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; +static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "dummy", "dummy", "gpu_pll_out", "vpu_pll_out", + "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", + "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; + static struct clk_onecell_data clk_data; static struct clk *clks[IMX8MP_CLK_END]; @@ -510,6 +511,15 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4, + imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels)); + hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4); + hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8); + hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4, + imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels)); + hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4); + hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24); + hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000); hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV]; hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV]; @@ -526,9 +536,9 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) /* CORE SEL */ hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels)); - hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800); + hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_bus_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800); hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880); - hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900); + hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900); hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980); hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite_bus("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00); hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite_bus("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80); @@ -536,14 +546,15 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite_bus("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80); hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00); hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80); - hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00); - hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80); + hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_bus_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00); + hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_bus_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80); hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite_bus("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00); hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite_bus("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80); - hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000); + hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000); hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100); hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200); + hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite_bus("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300); hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1); @@ -553,14 +564,12 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180); hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200); hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280); - hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite("memrepair", imx8mp_memrepair_sels, ccm_base + 0xa300); hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400); hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480); hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, ccm_base + 0xa500); hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580); hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600); hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680); - hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700); hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780); hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800); hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880); @@ -607,10 +616,10 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80); hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00); hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80); - hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00); + hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00); hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80); hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00); - hws[IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC] = imx8m_clk_hw_composite("media_mipi_csi2_esc", imx8mp_media_mipi_csi2_esc_sels, ccm_base + 0xbf80); + hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80); hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100); hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mp_ecspi3_sels, ccm_base + 0xc180); hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, ccm_base + 0xc200); @@ -640,6 +649,7 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0); hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0); hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0); + hws[IMX8MP_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", ccm_base + 0x4210, 0); hws[IMX8MP_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", ccm_base + 0x4220, 0); hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0); hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0); @@ -649,23 +659,23 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_CLK_QOS_ROOT] = imx_clk_hw_gate4("qos_root_clk", "ipg_root", ccm_base + 0x42c0, 0); hws[IMX8MP_CLK_QOS_ENET_ROOT] = imx_clk_hw_gate4("qos_enet_root_clk", "ipg_root", ccm_base + 0x42e0, 0); hws[IMX8MP_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", ccm_base + 0x42f0, 0); - hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0); - hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0); + hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0, &share_count_nand); + hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0, &share_count_nand); hws[IMX8MP_CLK_I2C5_ROOT] = imx_clk_hw_gate2("i2c5_root_clk", "i2c5", ccm_base + 0x4330, 0); hws[IMX8MP_CLK_I2C6_ROOT] = imx_clk_hw_gate2("i2c6_root_clk", "i2c6", ccm_base + 0x4340, 0); hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0); hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0); hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0); - hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0); hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0); + hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0); hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0); hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0); - hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0); hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0); hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0); hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0); hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0); - hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "osc_32k", ccm_base + 0x44d0, 0); + hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb); + hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb); hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0); hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0); hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0); @@ -678,19 +688,30 @@ static int imx8mp_clocks_init(struct device_node *ccm_np) hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0); hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_core", ccm_base + 0x45b0, 0); hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0); - hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0); - hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0); - hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0); - hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0); - hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0); - hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0); - hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0); + hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT] = imx_clk_hw_gate2_shared2("media_mipi_phy1_ref_root", "media_mipi_phy1_ref", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_LDB_ROOT] = imx_clk_hw_gate2_shared2("media_ldb_root_clk", "media_ldb", ccm_base + 0x45d0, 0, &share_count_media); + hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media); hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0); hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0); hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0); hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0); - hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0); + + hws[IMX8MP_CLK_AUDIO_AHB_ROOT] = imx_clk_hw_gate2_shared2("audio_ahb_root", "audio_ahb", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_AUDIO_AXI_ROOT] = imx_clk_hw_gate2_shared2("audio_axi_root", "audio_axi", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root", "sai1", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root", "sai2", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root", "sai3", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root", "sai5", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root", "sai6", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root", "sai7", ccm_base + 0x4650, 0, &share_count_audio); + hws[IMX8MP_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root", "pdm", ccm_base + 0x4650, 0, &share_count_audio); hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", hws[IMX8MP_CLK_A53_CORE], diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c new file mode 100644 index 0000000000..e460091ba6 --- /dev/null +++ b/drivers/clk/imx/clk-imx93.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2021 NXP. + */ + +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/types.h> +#include <of_address.h> +#include <dt-bindings/clock/imx93-clock.h> + +#include "clk.h" + +enum clk_sel { + LOW_SPEED_IO_SEL, + NON_IO_SEL, + FAST_SEL, + AUDIO_SEL, + VIDEO_SEL, + TPM_SEL, + CKO1_SEL, + CKO2_SEL, + MISC_SEL, + MAX_SEL +}; + +static u32 share_count_sai1; +static u32 share_count_sai2; +static u32 share_count_sai3; +static u32 share_count_mub; +static u32 share_count_pdm; + +static const char * const a55_core_sels[] = {"a55_alt", "arm_pll"}; +static const char *parent_names[MAX_SEL][4] = { + {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "video_pll"}, + {"osc_24m", "sys_pll_pfd0_div2", "sys_pll_pfd1_div2", "sys_pll_pfd2_div2"}, + {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "sys_pll_pfd2"}, + {"osc_24m", "audio_pll", "video_pll", "clk_ext1"}, + {"osc_24m", "audio_pll", "video_pll", "sys_pll_pfd0"}, + {"osc_24m", "sys_pll_pfd0", "audio_pll", "clk_ext1"}, + {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "audio_pll"}, + {"osc_24m", "sys_pll_pfd0", "sys_pll_pfd1", "video_pll"}, + {"osc_24m", "audio_pll", "video_pll", "sys_pll_pfd2"}, +}; + +static const struct imx93_clk_root { + u32 clk; + char *name; + u32 off; + enum clk_sel sel; + unsigned long flags; +} root_array[] = { + /* a55/m33/bus critical clk for system run */ + { IMX93_CLK_A55_PERIPH, "a55_periph_root", 0x0000, FAST_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_A55_MTR_BUS, "a55_mtr_bus_root", 0x0080, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_A55, "a55_alt_root", 0x0100, FAST_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_M33, "m33_root", 0x0180, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_BUS_WAKEUP, "bus_wakeup_root", 0x0280, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_BUS_AON, "bus_aon_root", 0x0300, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_WAKEUP_AXI, "wakeup_axi_root", 0x0380, FAST_SEL, CLK_IS_CRITICAL }, + { IMX93_CLK_SWO_TRACE, "swo_trace_root", 0x0400, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_M33_SYSTICK, "m33_systick_root", 0x0480, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPTMR1, "lptmr1_root", 0x0700, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPTMR2, "lptmr2_root", 0x0780, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_TPM2, "tpm2_root", 0x0880, TPM_SEL, }, + { IMX93_CLK_TPM4, "tpm4_root", 0x0980, TPM_SEL, }, + { IMX93_CLK_TPM5, "tpm5_root", 0x0a00, TPM_SEL, }, + { IMX93_CLK_TPM6, "tpm6_root", 0x0a80, TPM_SEL, }, + { IMX93_CLK_FLEXSPI1, "flexspi1_root", 0x0b00, FAST_SEL, }, + { IMX93_CLK_CAN1, "can1_root", 0x0b80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_CAN2, "can2_root", 0x0c00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART1, "lpuart1_root", 0x0c80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART2, "lpuart2_root", 0x0d00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART3, "lpuart3_root", 0x0d80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART4, "lpuart4_root", 0x0e00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART5, "lpuart5_root", 0x0e80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART6, "lpuart6_root", 0x0f00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART7, "lpuart7_root", 0x0f80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPUART8, "lpuart8_root", 0x1000, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C1, "lpi2c1_root", 0x1080, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C2, "lpi2c2_root", 0x1100, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C3, "lpi2c3_root", 0x1180, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C4, "lpi2c4_root", 0x1200, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C5, "lpi2c5_root", 0x1280, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C6, "lpi2c6_root", 0x1300, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C7, "lpi2c7_root", 0x1380, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPI2C8, "lpi2c8_root", 0x1400, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI1, "lpspi1_root", 0x1480, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI2, "lpspi2_root", 0x1500, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI3, "lpspi3_root", 0x1580, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI4, "lpspi4_root", 0x1600, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI5, "lpspi5_root", 0x1680, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI6, "lpspi6_root", 0x1700, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI7, "lpspi7_root", 0x1780, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_LPSPI8, "lpspi8_root", 0x1800, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C1, "i3c1_root", 0x1880, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C2, "i3c2_root", 0x1900, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_USDHC1, "usdhc1_root", 0x1980, FAST_SEL, }, + { IMX93_CLK_USDHC2, "usdhc2_root", 0x1a00, FAST_SEL, }, + { IMX93_CLK_USDHC3, "usdhc3_root", 0x1a80, FAST_SEL, }, + { IMX93_CLK_SAI1, "sai1_root", 0x1b00, AUDIO_SEL, }, + { IMX93_CLK_SAI2, "sai2_root", 0x1b80, AUDIO_SEL, }, + { IMX93_CLK_SAI3, "sai3_root", 0x1c00, AUDIO_SEL, }, + { IMX93_CLK_CCM_CKO1, "ccm_cko1_root", 0x1c80, CKO1_SEL, }, + { IMX93_CLK_CCM_CKO2, "ccm_cko2_root", 0x1d00, CKO2_SEL, }, + { IMX93_CLK_CCM_CKO3, "ccm_cko3_root", 0x1d80, CKO1_SEL, }, + { IMX93_CLK_CCM_CKO4, "ccm_cko4_root", 0x1e00, CKO2_SEL, }, + /* + * Critical because clk is used for handshake between HSIOMIX and NICMIX when + * NICMIX power down/on during system suspend/resume + */ + { IMX93_CLK_HSIO, "hsio_root", 0x1e80, LOW_SPEED_IO_SEL, CLK_IS_CRITICAL}, + { IMX93_CLK_HSIO_USB_TEST_60M, "hsio_usb_test_60m_root", 0x1f00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_HSIO_ACSCAN_80M, "hsio_acscan_80m_root", 0x1f80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_HSIO_ACSCAN_480M, "hsio_acscan_480m_root", 0x2000, MISC_SEL, }, + { IMX93_CLK_NIC_AXI, "nic_axi_root", 0x2080, FAST_SEL, CLK_IS_CRITICAL, }, + { IMX93_CLK_ML_APB, "ml_apb_root", 0x2180, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_ML, "ml_root", 0x2200, FAST_SEL, }, + { IMX93_CLK_MEDIA_AXI, "media_axi_root", 0x2280, FAST_SEL, }, + { IMX93_CLK_MEDIA_APB, "media_apb_root", 0x2300, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_MEDIA_LDB, "media_ldb_root", 0x2380, VIDEO_SEL, }, + { IMX93_CLK_MEDIA_DISP_PIX, "media_disp_pix_root", 0x2400, VIDEO_SEL, }, + { IMX93_CLK_CAM_PIX, "cam_pix_root", 0x2480, VIDEO_SEL, }, + { IMX93_CLK_MIPI_TEST_BYTE, "mipi_test_byte_root", 0x2500, VIDEO_SEL, }, + { IMX93_CLK_MIPI_PHY_CFG, "mipi_phy_cfg_root", 0x2580, VIDEO_SEL, }, + { IMX93_CLK_ADC, "adc_root", 0x2700, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_PDM, "pdm_root", 0x2780, AUDIO_SEL, }, + { IMX93_CLK_TSTMR1, "tstmr1_root", 0x2800, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_TSTMR2, "tstmr2_root", 0x2880, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_MQS1, "mqs1_root", 0x2900, AUDIO_SEL, }, + { IMX93_CLK_MQS2, "mqs2_root", 0x2980, AUDIO_SEL, }, + { IMX93_CLK_AUDIO_XCVR, "audio_xcvr_root", 0x2a00, NON_IO_SEL, }, + { IMX93_CLK_SPDIF, "spdif_root", 0x2a80, AUDIO_SEL, }, + { IMX93_CLK_ENET, "enet_root", 0x2b00, NON_IO_SEL, }, + { IMX93_CLK_ENET_TIMER1, "enet_timer1_root", 0x2b80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_ENET_TIMER2, "enet_timer2_root", 0x2c00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_ENET_REF, "enet_ref_root", 0x2c80, NON_IO_SEL, }, + { IMX93_CLK_ENET_REF_PHY, "enet_ref_phy_root", 0x2d00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C1_SLOW, "i3c1_slow_root", 0x2d80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_I3C2_SLOW, "i3c2_slow_root", 0x2e00, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_USB_PHY_BURUNIN, "usb_phy_root", 0x2e80, LOW_SPEED_IO_SEL, }, + { IMX93_CLK_PAL_CAME_SCAN, "pal_came_scan_root", 0x2f00, MISC_SEL, } +}; + +static const struct imx93_clk_ccgr { + u32 clk; + char *name; + char *parent_name; + u32 off; + unsigned long flags; + u32 *shared_count; +} ccgr_array[] = { + { IMX93_CLK_A55_GATE, "a55_alt", "a55_alt_root", 0x8000, }, + /* M33 critical clk for system run */ + { IMX93_CLK_CM33_GATE, "cm33", "m33_root", 0x8040, CLK_IS_CRITICAL }, + { IMX93_CLK_ADC1_GATE, "adc1", "adc_root", 0x82c0, }, + { IMX93_CLK_WDOG1_GATE, "wdog1", "osc_24m", 0x8300, }, + { IMX93_CLK_WDOG2_GATE, "wdog2", "osc_24m", 0x8340, }, + { IMX93_CLK_WDOG3_GATE, "wdog3", "osc_24m", 0x8380, }, + { IMX93_CLK_WDOG4_GATE, "wdog4", "osc_24m", 0x83c0, }, + { IMX93_CLK_WDOG5_GATE, "wdog5", "osc_24m", 0x8400, }, + { IMX93_CLK_SEMA1_GATE, "sema1", "bus_aon_root", 0x8440, }, + { IMX93_CLK_SEMA2_GATE, "sema2", "bus_wakeup_root", 0x8480, }, + { IMX93_CLK_MU1_A_GATE, "mu1_a", "bus_aon_root", 0x84c0, CLK_IGNORE_UNUSED }, + { IMX93_CLK_MU2_A_GATE, "mu2_a", "bus_wakeup_root", 0x84c0, CLK_IGNORE_UNUSED }, + { IMX93_CLK_MU1_B_GATE, "mu1_b", "bus_aon_root", 0x8500, 0, &share_count_mub }, + { IMX93_CLK_MU2_B_GATE, "mu2_b", "bus_wakeup_root", 0x8500, 0, &share_count_mub }, + { IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, }, + { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, }, + { IMX93_CLK_FLEXSPI1_GATE, "flexspi1", "flexspi1_root", 0x8640, }, + { IMX93_CLK_GPIO1_GATE, "gpio1", "m33_root", 0x8880, }, + { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, }, + { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, }, + { IMX93_CLK_GPIO4_GATE, "gpio4", "bus_wakeup_root", 0x8940, }, + { IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, }, + { IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, }, + { IMX93_CLK_LPIT1_GATE, "lpit1", "bus_aon_root", 0x8a00, }, + { IMX93_CLK_LPIT2_GATE, "lpit2", "bus_wakeup_root", 0x8a40, }, + { IMX93_CLK_LPTMR1_GATE, "lptmr1", "lptmr1_root", 0x8a80, }, + { IMX93_CLK_LPTMR2_GATE, "lptmr2", "lptmr2_root", 0x8ac0, }, + { IMX93_CLK_TPM1_GATE, "tpm1", "bus_aon_root", 0x8b00, }, + { IMX93_CLK_TPM2_GATE, "tpm2", "tpm2_root", 0x8b40, }, + { IMX93_CLK_TPM3_GATE, "tpm3", "bus_wakeup_root", 0x8b80, }, + { IMX93_CLK_TPM4_GATE, "tpm4", "tpm4_root", 0x8bc0, }, + { IMX93_CLK_TPM5_GATE, "tpm5", "tpm5_root", 0x8c00, }, + { IMX93_CLK_TPM6_GATE, "tpm6", "tpm6_root", 0x8c40, }, + { IMX93_CLK_CAN1_GATE, "can1", "can1_root", 0x8c80, }, + { IMX93_CLK_CAN2_GATE, "can2", "can2_root", 0x8cc0, }, + { IMX93_CLK_LPUART1_GATE, "lpuart1", "lpuart1_root", 0x8d00, }, + { IMX93_CLK_LPUART2_GATE, "lpuart2", "lpuart2_root", 0x8d40, }, + { IMX93_CLK_LPUART3_GATE, "lpuart3", "lpuart3_root", 0x8d80, }, + { IMX93_CLK_LPUART4_GATE, "lpuart4", "lpuart4_root", 0x8dc0, }, + { IMX93_CLK_LPUART5_GATE, "lpuart5", "lpuart5_root", 0x8e00, }, + { IMX93_CLK_LPUART6_GATE, "lpuart6", "lpuart6_root", 0x8e40, }, + { IMX93_CLK_LPUART7_GATE, "lpuart7", "lpuart7_root", 0x8e80, }, + { IMX93_CLK_LPUART8_GATE, "lpuart8", "lpuart8_root", 0x8ec0, }, + { IMX93_CLK_LPI2C1_GATE, "lpi2c1", "lpi2c1_root", 0x8f00, }, + { IMX93_CLK_LPI2C2_GATE, "lpi2c2", "lpi2c2_root", 0x8f40, }, + { IMX93_CLK_LPI2C3_GATE, "lpi2c3", "lpi2c3_root", 0x8f80, }, + { IMX93_CLK_LPI2C4_GATE, "lpi2c4", "lpi2c4_root", 0x8fc0, }, + { IMX93_CLK_LPI2C5_GATE, "lpi2c5", "lpi2c5_root", 0x9000, }, + { IMX93_CLK_LPI2C6_GATE, "lpi2c6", "lpi2c6_root", 0x9040, }, + { IMX93_CLK_LPI2C7_GATE, "lpi2c7", "lpi2c7_root", 0x9080, }, + { IMX93_CLK_LPI2C8_GATE, "lpi2c8", "lpi2c8_root", 0x90c0, }, + { IMX93_CLK_LPSPI1_GATE, "lpspi1", "lpspi1_root", 0x9100, }, + { IMX93_CLK_LPSPI2_GATE, "lpspi2", "lpspi2_root", 0x9140, }, + { IMX93_CLK_LPSPI3_GATE, "lpspi3", "lpspi3_root", 0x9180, }, + { IMX93_CLK_LPSPI4_GATE, "lpspi4", "lpspi4_root", 0x91c0, }, + { IMX93_CLK_LPSPI5_GATE, "lpspi5", "lpspi5_root", 0x9200, }, + { IMX93_CLK_LPSPI6_GATE, "lpspi6", "lpspi6_root", 0x9240, }, + { IMX93_CLK_LPSPI7_GATE, "lpspi7", "lpspi7_root", 0x9280, }, + { IMX93_CLK_LPSPI8_GATE, "lpspi8", "lpspi8_root", 0x92c0, }, + { IMX93_CLK_I3C1_GATE, "i3c1", "i3c1_root", 0x9300, }, + { IMX93_CLK_I3C2_GATE, "i3c2", "i3c2_root", 0x9340, }, + { IMX93_CLK_USDHC1_GATE, "usdhc1", "usdhc1_root", 0x9380, }, + { IMX93_CLK_USDHC2_GATE, "usdhc2", "usdhc2_root", 0x93c0, }, + { IMX93_CLK_USDHC3_GATE, "usdhc3", "usdhc3_root", 0x9400, }, + { IMX93_CLK_SAI1_GATE, "sai1", "sai1_root", 0x9440, 0, &share_count_sai1}, + { IMX93_CLK_SAI1_IPG, "sai1_ipg_clk", "bus_aon_root", 0x9440, 0, &share_count_sai1}, + { IMX93_CLK_SAI2_GATE, "sai2", "sai2_root", 0x9480, 0, &share_count_sai2}, + { IMX93_CLK_SAI2_IPG, "sai2_ipg_clk", "bus_wakeup_root", 0x9480, 0, &share_count_sai2}, + { IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, 0, &share_count_sai3}, + { IMX93_CLK_SAI3_IPG, "sai3_ipg_clk", "bus_wakeup_root", 0x94c0, 0, &share_count_sai3}, + { IMX93_CLK_MIPI_CSI_GATE, "mipi_csi", "media_apb_root", 0x9580, }, + { IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, }, + { IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, }, + { IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, }, + { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, }, + { IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, }, + { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_axi_root", 0x9700, }, + { IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, }, + { IMX93_CLK_USB_TEST_60M_GATE, "usb_test_60m", "hsio_usb_test_60m_root", 0x9a40, }, + { IMX93_CLK_HSIO_TROUT_24M_GATE, "hsio_trout_24m", "osc_24m", 0x9a80, }, + { IMX93_CLK_PDM_GATE, "pdm", "pdm_root", 0x9ac0, 0, &share_count_pdm}, + { IMX93_CLK_PDM_IPG, "pdm_ipg_clk", "bus_aon_root", 0x9ac0, 0, &share_count_pdm}, + { IMX93_CLK_MQS1_GATE, "mqs1", "sai1_root", 0x9b00, }, + { IMX93_CLK_MQS2_GATE, "mqs2", "sai3_root", 0x9b40, }, + { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, }, + { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, }, + { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, }, + { IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, }, + { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, }, + /* Critical because clk accessed during CPU idle */ + { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, CLK_IS_CRITICAL}, + { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, }, + { IMX93_CLK_TSTMR2_GATE, "tstmr2", "bus_wakeup_root", 0x9f00, }, + { IMX93_CLK_TMC_GATE, "tmc", "osc_24m", 0x9f40, }, + { IMX93_CLK_PMRO_GATE, "pmro", "osc_24m", 0x9f80, } +}; + +static struct clk_onecell_data clk_data; +static struct clk *clks[IMX93_CLK_END]; + +static int imx93_clocks_probe(struct device_node *np) +{ + struct device_node *anatop_np; + const struct imx93_clk_root *root; + const struct imx93_clk_ccgr *ccgr; + void __iomem *base, *anatop_base; + int i, ret; + + clk_data.clk_num = IMX93_CLK_END; + clk_data.clks = clks; + + clks[IMX93_CLK_DUMMY] = clk_fixed("dummy", 0); + clks[IMX93_CLK_24M] = of_clk_get_by_name(np, "osc_24m"); + clks[IMX93_CLK_32K] = of_clk_get_by_name(np, "osc_32k"); + clks[IMX93_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1"); + + clks[IMX93_CLK_SYS_PLL_PFD0] = clk_fixed("sys_pll_pfd0", 1000000000); + clks[IMX93_CLK_SYS_PLL_PFD0_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd0_div2", + "sys_pll_pfd0", 1, 2); + clks[IMX93_CLK_SYS_PLL_PFD1] = clk_fixed("sys_pll_pfd1", 800000000); + clks[IMX93_CLK_SYS_PLL_PFD1_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd1_div2", + "sys_pll_pfd1", 1, 2); + clks[IMX93_CLK_SYS_PLL_PFD2] = clk_fixed("sys_pll_pfd2", 625000000); + clks[IMX93_CLK_SYS_PLL_PFD2_DIV2] = imx_clk_hw_fixed_factor("sys_pll_pfd2_div2", + "sys_pll_pfd2", 1, 2); + + anatop_np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); + anatop_base = of_iomap(anatop_np, 0); + if (WARN_ON(IS_ERR(anatop_base))) + return PTR_ERR(anatop_base); + + clks[IMX93_CLK_ARM_PLL] = imx_clk_fracn_gppll_integer("arm_pll", "osc_24m", + anatop_base + 0x1000, + &imx_fracn_gppll_integer); + clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200, + &imx_fracn_gppll); + clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", anatop_base + 0x1400, + &imx_fracn_gppll); + + base = of_iomap(np, 0); + if (WARN_ON(IS_ERR(base))) + return PTR_ERR(base); + + for (i = 0; i < ARRAY_SIZE(root_array); i++) { + root = &root_array[i]; + clks[root->clk] = imx93_clk_composite_flags(root->name, + parent_names[root->sel], + 4, base + root->off, 3, + root->flags); + } + + for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) { + ccgr = &ccgr_array[i]; + clks[ccgr->clk] = imx93_clk_gate(NULL, ccgr->name, ccgr->parent_name, + ccgr->flags, base + ccgr->off, 0, 1, 1, 3, + ccgr->shared_count); + } + + clks[IMX93_CLK_A55_SEL] = imx_clk_hw_mux2("a55_sel", base + 0x4820, 0, 1, a55_core_sels, + ARRAY_SIZE(a55_core_sels)); + clks[IMX93_CLK_A55_CORE] = imx_clk_hw_cpu("a55_core", "a55_sel", + clks[IMX93_CLK_A55_SEL], + clks[IMX93_CLK_A55_SEL], + clks[IMX93_CLK_ARM_PLL], + clks[IMX93_CLK_A55_GATE]); + + imx_check_clocks(clks, IMX93_CLK_END); + + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + if (ret < 0) + return ret; + + return 0; +} +CLK_OF_DECLARE(imx93, "fsl,imx93-ccm", imx93_clocks_probe); diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 1bd1fe5c44..112f64df9b 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -13,8 +13,8 @@ #include <linux/clk.h> #include <notifier.h> #include <dt-bindings/clock/vf610-clock.h> -#include <mach/vf610-regs.h> -#include <mach/vf610-fusemap.h> +#include <mach/imx/vf610-regs.h> +#include <mach/imx/vf610-fusemap.h> #include "clk.h" @@ -568,13 +568,16 @@ static int vf610_switch_cpu_clock_to_400mhz(void) static int vf610_switch_cpu_clock(void) { int ret; - bool sense_enable; + int sense_enable; uint32_t speed_grading; if (!of_machine_is_compatible("fsl,vf610")) return 0; sense_enable = imx_ocotp_sense_enable(true); + if (sense_enable < 0) + return sense_enable; + ret = imx_ocotp_read_field(VF610_OCOTP_SPEED_GRADING, &speed_grading); imx_ocotp_sense_enable(sense_enable); if (ret < 0) diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index bc44d0c739..32e4903837 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -40,11 +40,19 @@ static inline struct clk *imx_clk_divider_table(const char *name, width, table, 0); } +static inline struct clk *__imx_clk_mux(const char *name, void __iomem *reg, + u8 shift, u8 width, const char * const *parents, + u8 num_parents, unsigned flags, unsigned long clk_mux_flags) +{ + return clk_mux(name, CLK_SET_RATE_NO_REPARENT | flags, reg, + shift, width, parents, num_parents, clk_mux_flags); +} + static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, int num_parents) { - return clk_mux(name, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, - shift, width, parents, num_parents, CLK_MUX_READ_ONLY); + return __imx_clk_mux(name, reg, shift, width, parents, num_parents, + CLK_SET_RATE_PARENT, CLK_MUX_READ_ONLY); } @@ -59,36 +67,36 @@ static inline struct clk *imx_clk_mux_flags(const char *name, void __iomem *reg, const char * const *parents, u8 num_parents, unsigned long clk_flags) { - return clk_mux(name, clk_flags, reg, shift, width, parents, num_parents, - 0); + return __imx_clk_mux(name, reg, shift, width, parents, num_parents, + clk_flags, 0); } static inline struct clk *imx_clk_mux2_flags(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, int num_parents, unsigned long clk_flags) { - return clk_mux(name, clk_flags | CLK_OPS_PARENT_ENABLE, reg, shift, - width, parents, num_parents, 0); + return __imx_clk_mux(name,reg, shift, width, parents, num_parents, + clk_flags | CLK_OPS_PARENT_ENABLE, 0); } static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, u8 num_parents) { - return clk_mux(name, 0, reg, shift, width, parents, num_parents, 0); + return __imx_clk_mux(name, reg, shift, width, parents, num_parents, 0, 0); } static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, u8 num_parents) { - return clk_mux(name, CLK_OPS_PARENT_ENABLE, reg, shift, width, parents, - num_parents, 0); + return __imx_clk_mux(name, reg, shift, width, parents, + num_parents, CLK_OPS_PARENT_ENABLE, 0); } static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, u8 num_parents) { - return clk_mux(name, CLK_SET_RATE_PARENT, reg, shift, width, parents, - num_parents, 0); + return __imx_clk_mux(name, reg, shift, width, parents, num_parents, + CLK_SET_RATE_PARENT, 0); } static inline struct clk *imx_clk_gate(const char *name, const char *parent, @@ -268,6 +276,11 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name, #define IMX_COMPOSITE_CORE BIT(0) #define IMX_COMPOSITE_BUS BIT(1) +#define IMX_COMPOSITE_CLK_FLAGS_DEFAULT \ + (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) +#define IMX_COMPOSITE_CLK_FLAGS_CRITICAL \ + (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_IS_CRITICAL) + struct clk *imx8m_clk_composite_flags(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, u32 composite_flags, @@ -277,13 +290,19 @@ struct clk *imx8m_clk_composite_flags(const char *name, imx8m_clk_hw_composite_flags(name, parent_names, \ ARRAY_SIZE(parent_names), reg, \ IMX_COMPOSITE_CORE, \ - CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + IMX_COMPOSITE_CLK_FLAGS_DEFAULT) #define imx8m_clk_hw_composite_bus(name, parent_names, reg) \ imx8m_clk_hw_composite_flags(name, parent_names, \ ARRAY_SIZE(parent_names), reg, \ IMX_COMPOSITE_BUS, \ - CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + IMX_COMPOSITE_CLK_FLAGS_DEFAULT) + +#define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, \ + IMX_COMPOSITE_BUS, \ + IMX_COMPOSITE_CLK_FLAGS_CRITICAL) #define __imx8m_clk_composite(name, parent_names, reg, flags) \ imx8m_clk_composite_flags(name, parent_names, \ @@ -296,6 +315,22 @@ struct clk *imx8m_clk_composite_flags(const char *name, #define imx8m_clk_composite_critical(name, parent_names, reg) \ __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL) +#include <soc/imx/clk-fracn-gppll.h> + +struct clk *imx93_clk_composite_flags(const char *name, + const char * const *parent_names, + int num_parents, + void __iomem *reg, + u32 domain_id, + unsigned long flags); +#define imx93_clk_composite(name, parent_names, num_parents, reg, domain_id) \ + imx93_clk_composite_flags(name, parent_names, num_parents, reg, domain_id \ + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + +struct clk *imx93_clk_gate(struct device *dev, const char *name, const char *parent_name, + unsigned long flags, void __iomem *reg, u32 bit_idx, u32 val, + u32 mask, u32 domain_id, unsigned int *share_count); + /* * Names of the above functions used in the Linux Kernel. Added here * to be able to use the same names in barebox to reduce the diffs @@ -306,6 +341,7 @@ struct clk *imx8m_clk_composite_flags(const char *name, #define imx_clk_hw_gate imx_clk_gate #define imx_clk_hw_fixed_factor imx_clk_fixed_factor #define imx_clk_hw_mux_flags imx_clk_mux_flags +#define imx_clk_hw_divider imx_clk_divider #define imx_clk_hw_divider2 imx_clk_divider2 #define imx_clk_hw_mux2_flags imx_clk_mux2_flags #define imx_clk_hw_gate4_flags imx_clk_gate4_flags @@ -315,7 +351,8 @@ struct clk *imx8m_clk_composite_flags(const char *name, #define imx8m_clk_hw_composite_flags imx8m_clk_composite_flags #define imx8m_clk_hw_composite imx8m_clk_composite #define imx8m_clk_hw_composite_critical imx8m_clk_composite_critical -#define imx_clk_hw_gate2_shared2 imx_clk_gate2_shared2 +#define imx_clk_hw_gate2_shared2(name, parent, reg, shift, shared_count) \ + ({ (void)shared_count; imx_clk_gate2_shared2(name, parent, reg, shift); }) #define imx_clk_hw_mux2 imx_clk_mux2 #endif /* __IMX_CLK_H */ |