lkml.org 
[lkml]   [2022]   [Jul]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 07/12] clk: imx: Update pllv3 to support i.MXRT1170
    Date
    The i.MXRT1170 has a pll that has the multiplier bits inverted and
    cannot be changed add IMX_PLLV3_GENERICV2.

    The i.MXRT1170 also has the lock bit moved as well as the
    power bit inverted the power bit also is in different locations on each
    pll control register.

    Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com>
    ---
    V1 -> V2:
    - Nothing done
    V2 -> V3:
    - Nothing done
    V3 -> V4:
    - Nothing done
    V4 -> V5:
    - Add __imx_clk_hw_pllv3 to change power bit
    - Add BM_PLL_POWER and imx_clk_hw_pllv3 to header
    - Remove imx_clk_hw_pll3_powerbit
    ---
    drivers/clk/imx/clk-pllv3.c | 57 +++++++++++++++++++++++++++++++++----
    drivers/clk/imx/clk.h | 11 +++++++
    2 files changed, 62 insertions(+), 6 deletions(-)

    diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
    index eea32f87c60a..68b1498cafe1 100644
    --- a/drivers/clk/imx/clk-pllv3.c
    +++ b/drivers/clk/imx/clk-pllv3.c
    @@ -21,8 +21,8 @@
    #define PLL_VF610_NUM_OFFSET 0x20
    #define PLL_VF610_DENOM_OFFSET 0x30

    -#define BM_PLL_POWER (0x1 << 12)
    #define BM_PLL_LOCK (0x1 << 31)
    +#define BM_PLL_LOCK_V2 (0x1 << 29)
    #define IMX7_ENET_PLL_POWER (0x1 << 5)
    #define IMX7_DDR_PLL_POWER (0x1 << 20)

    @@ -34,6 +34,7 @@
    * @base: base address of PLL registers
    * @power_bit: pll power bit mask
    * @powerup_set: set power_bit to power up the PLL
    + * @lock_bit: pll lock bit mask
    * @div_mask: mask of divider bits
    * @div_shift: shift of divider bits
    * @ref_clock: reference clock rate
    @@ -48,6 +49,7 @@ struct clk_pllv3 {
    void __iomem *base;
    u32 power_bit;
    bool powerup_set;
    + u32 lock_bit;
    u32 div_mask;
    u32 div_shift;
    unsigned long ref_clock;
    @@ -65,7 +67,7 @@ static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
    if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
    return 0;

    - return readl_relaxed_poll_timeout(pll->base, val, val & BM_PLL_LOCK,
    + return readl_relaxed_poll_timeout(pll->base, val, val & pll->lock_bit,
    500, PLL_LOCK_TIMEOUT);
    }

    @@ -101,7 +103,7 @@ static int clk_pllv3_is_prepared(struct clk_hw *hw)
    {
    struct clk_pllv3 *pll = to_clk_pllv3(hw);

    - if (readl_relaxed(pll->base) & BM_PLL_LOCK)
    + if (readl_relaxed(pll->base) & pll->lock_bit)
    return 1;

    return 0;
    @@ -155,6 +157,39 @@ static const struct clk_ops clk_pllv3_ops = {
    .set_rate = clk_pllv3_set_rate,
    };

    +static int clk_pllv3_genericv2_set_rate(struct clk_hw *hw, unsigned long rate,
    + unsigned long parent_rate)
    +{
    + struct clk_pllv3 *pll = to_clk_pllv3(hw);
    + u32 val, div;
    +
    + div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask;
    + val = (div == 0) ? parent_rate * 22 : parent_rate * 20;
    +
    + if (rate == val)
    + return 0;
    +
    + return -EINVAL;
    +}
    +
    +static unsigned long clk_pllv3_genericv2_recalc_rate(struct clk_hw *hw,
    + unsigned long parent_rate)
    +{
    + struct clk_pllv3 *pll = to_clk_pllv3(hw);
    + u32 div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask;
    +
    + return (div == 0) ? parent_rate * 22 : parent_rate * 20;
    +}
    +
    +static const struct clk_ops clk_pllv3_genericv2_ops = {
    + .prepare = clk_pllv3_prepare,
    + .unprepare = clk_pllv3_unprepare,
    + .is_prepared = clk_pllv3_is_prepared,
    + .recalc_rate = clk_pllv3_genericv2_recalc_rate,
    + .round_rate = clk_pllv3_round_rate,
    + .set_rate = clk_pllv3_genericv2_set_rate,
    +};
    +
    static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
    unsigned long parent_rate)
    {
    @@ -407,9 +442,9 @@ static const struct clk_ops clk_pllv3_enet_ops = {
    .recalc_rate = clk_pllv3_enet_recalc_rate,
    };

    -struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
    +struct clk_hw *__imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
    const char *parent_name, void __iomem *base,
    - u32 div_mask)
    + u32 div_mask, u8 pwr_bit)
    {
    struct clk_pllv3 *pll;
    const struct clk_ops *ops;
    @@ -421,11 +456,21 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
    if (!pll)
    return ERR_PTR(-ENOMEM);

    - pll->power_bit = BM_PLL_POWER;
    + pll->power_bit = pwr_bit;
    + pll->lock_bit = BM_PLL_LOCK;
    pll->num_offset = PLL_NUM_OFFSET;
    pll->denom_offset = PLL_DENOM_OFFSET;

    switch (type) {
    + case IMX_PLLV3_GENERICV2:
    + pll->lock_bit = BM_PLL_LOCK_V2;
    + pll->powerup_set = true;
    + ops = &clk_pllv3_genericv2_ops;
    + break;
    + case IMX_PLLV3_SYSV2:
    + pll->lock_bit = BM_PLL_LOCK_V2;
    + pll->powerup_set = true;
    + fallthrough;
    case IMX_PLLV3_SYS:
    ops = &clk_pllv3_sys_ops;
    break;
    diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
    index 5061a06468df..782100b2846d 100644
    --- a/drivers/clk/imx/clk.h
    +++ b/drivers/clk/imx/clk.h
    @@ -6,6 +6,8 @@
    #include <linux/spinlock.h>
    #include <linux/clk-provider.h>

    +#define BM_PLL_POWER (0x1 << 12)
    +
    extern spinlock_t imx_ccm_lock;
    extern bool mcore_booted;

    @@ -102,6 +104,11 @@ extern struct imx_fracn_gppll_clk imx_fracn_gppll;
    to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
    cgr_val, cgr_mask, clk_gate_flags, lock, share_count))

    +#define imx_clk_hw_pllv3(name, parent_names, num_parents, parent, \
    + bypass1, bypass2, base, flags) \
    + __imx_clk_hw_pllv3(name, parent_names, num_parents, parent, \
    + bypass1, bypass2, base, flags, BM_PLL_POWER)
    +
    #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
    to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))

    @@ -242,6 +249,8 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name,

    enum imx_pllv3_type {
    IMX_PLLV3_GENERIC,
    + IMX_PLLV3_GENERICV2,
    + IMX_PLLV3_SYSV2,
    IMX_PLLV3_SYS,
    IMX_PLLV3_USB,
    IMX_PLLV3_USB_VF610,
    @@ -253,6 +262,8 @@ enum imx_pllv3_type {
    IMX_PLLV3_AV_IMX7,
    };

    +void imx_clk_hw_pll3_powerbit(struct clk_hw *hw, u8 shift);
    +
    struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
    const char *parent_name, void __iomem *base, u32 div_mask);

    --
    2.36.1
    \
     
     \ /
      Last update: 2022-07-23 18:06    [W:6.157 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site