clk: imx: Add i.MXRT11xx pllv3 variant
authorJesse Taube <mr.bossman075@gmail.com>
Tue, 26 Jul 2022 05:43:42 +0000 (01:43 -0400)
committerStefano Babic <sbabic@denx.de>
Sun, 18 Sep 2022 18:42:56 +0000 (20:42 +0200)
The i.MXRT11 series has two new pll types but are variants of existing.
This patch adds the ability to read one of the pll types' frequency
as it can't be changed unlike the generic pll it also has the
division factors swapped.

Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com>
drivers/clk/imx/clk-pllv3.c
drivers/clk/imx/clk.h

index 077757e..fad306a 100644 (file)
 #define UBOOT_DM_CLK_IMX_PLLV3_USB     "imx_clk_pllv3_usb"
 #define UBOOT_DM_CLK_IMX_PLLV3_AV      "imx_clk_pllv3_av"
 #define UBOOT_DM_CLK_IMX_PLLV3_ENET     "imx_clk_pllv3_enet"
+#define UBOOT_DM_CLK_IMX_PLLV3_GENV2   "imx_clk_pllv3_genericv2"
 
 #define PLL_NUM_OFFSET         0x10
 #define PLL_DENOM_OFFSET       0x20
 
 #define BM_PLL_POWER           (0x1 << 12)
+#define BM_PLL_POWER_V2                (0x1 << 21)
 #define BM_PLL_ENABLE          (0x1 << 13)
 #define BM_PLL_LOCK            (0x1 << 31)
+#define BM_PLL_LOCK_V2         (0x1 << 29)
 
 struct clk_pllv3 {
        struct clk      clk;
        void __iomem    *base;
        u32             power_bit;
        bool            powerup_set;
+       u32             lock_bit;
        u32             enable_bit;
        u32             div_mask;
        u32             div_shift;
@@ -42,6 +46,30 @@ struct clk_pllv3 {
 
 #define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
 
+static ulong clk_pllv3_genericv2_get_rate(struct clk *clk)
+{
+       struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+
+       u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+
+       return (div == 0) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static ulong clk_pllv3_genericv2_set_rate(struct clk *clk, ulong rate)
+{
+       struct clk_pllv3 *pll = to_clk_pllv3(clk);
+       unsigned long parent_rate = clk_get_parent_rate(clk);
+
+       u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+       u32 val = (div == 0) ? parent_rate * 22 : parent_rate * 20;
+
+       if (rate == val)
+               return 0;
+
+       return -EINVAL;
+}
+
 static ulong clk_pllv3_generic_get_rate(struct clk *clk)
 {
        struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
@@ -71,7 +99,7 @@ static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate)
        writel(val, pll->base);
 
        /* Wait for PLL to lock */
-       while (!(readl(pll->base) & BM_PLL_LOCK))
+       while (!(readl(pll->base) & pll->lock_bit))
                ;
 
        return 0;
@@ -120,6 +148,13 @@ static const struct clk_ops clk_pllv3_generic_ops = {
        .set_rate       = clk_pllv3_generic_set_rate,
 };
 
+static const struct clk_ops clk_pllv3_genericv2_ops = {
+       .get_rate       = clk_pllv3_genericv2_get_rate,
+       .enable         = clk_pllv3_generic_enable,
+       .disable        = clk_pllv3_generic_disable,
+       .set_rate       = clk_pllv3_genericv2_set_rate,
+};
+
 static ulong clk_pllv3_sys_get_rate(struct clk *clk)
 {
        struct clk_pllv3 *pll = to_clk_pllv3(clk);
@@ -153,7 +188,7 @@ static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
        writel(val, pll->base);
 
        /* Wait for PLL to lock */
-       while (!(readl(pll->base) & BM_PLL_LOCK))
+       while (!(readl(pll->base) & pll->lock_bit))
                ;
 
        return 0;
@@ -221,7 +256,7 @@ static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
        writel(mfd, pll->base + PLL_DENOM_OFFSET);
 
        /* Wait for PLL to lock */
-       while (!(readl(pll->base) & BM_PLL_LOCK))
+       while (!(readl(pll->base) & pll->lock_bit))
                ;
 
        return 0;
@@ -262,6 +297,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 
        pll->power_bit = BM_PLL_POWER;
        pll->enable_bit = BM_PLL_ENABLE;
+       pll->lock_bit = BM_PLL_LOCK;
 
        switch (type) {
        case IMX_PLLV3_GENERIC:
@@ -269,6 +305,13 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
                pll->div_shift = 0;
                pll->powerup_set = false;
                break;
+       case IMX_PLLV3_GENERICV2:
+               pll->power_bit = BM_PLL_POWER_V2;
+               pll->lock_bit = BM_PLL_LOCK_V2;
+               drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENV2;
+               pll->div_shift = 0;
+               pll->powerup_set = false;
+               break;
        case IMX_PLLV3_SYS:
                drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS;
                pll->div_shift = 0;
@@ -313,6 +356,13 @@ U_BOOT_DRIVER(clk_pllv3_generic) = {
        .flags = DM_FLAG_PRE_RELOC,
 };
 
+U_BOOT_DRIVER(clk_pllv3_genericv2) = {
+       .name   = UBOOT_DM_CLK_IMX_PLLV3_GENV2,
+       .id     = UCLASS_CLK,
+       .ops    = &clk_pllv3_genericv2_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
+
 U_BOOT_DRIVER(clk_pllv3_sys) = {
        .name   = UBOOT_DM_CLK_IMX_PLLV3_SYS,
        .id     = UCLASS_CLK,
index 0e1eaf0..46dee35 100644 (file)
@@ -10,6 +10,7 @@
 
 enum imx_pllv3_type {
        IMX_PLLV3_GENERIC,
+       IMX_PLLV3_GENERICV2,
        IMX_PLLV3_SYS,
        IMX_PLLV3_USB,
        IMX_PLLV3_USB_VF610,