]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
clk: rockchip: rk3328: Add VOP clk support
authorJagan Teki <jagan@edgeble.ai>
Wed, 17 Jan 2024 07:51:46 +0000 (13:21 +0530)
committerAnatolij Gustschin <agust@denx.de>
Sun, 21 Apr 2024 07:07:00 +0000 (09:07 +0200)
VOP get and set clock would needed for VOP drivers.

Add support for it.

Signed-off-by: Jagan Teki <jagan@edgeble.ai>
arch/arm/include/asm/arch-rockchip/cru_rk3328.h
drivers/clk/rockchip/clk_rk3328.c

index 226744d67d9fdb16893a603a75676a8c36f23a08..4ad1d33e056e25d3fdc97ac4eea427698de2b29d 100644 (file)
@@ -62,6 +62,40 @@ check_member(rk3328_cru, sdmmc_ext_con[1], 0x39c);
 enum apll_frequencies {
        APLL_816_MHZ,
        APLL_600_MHZ,
+
+       /* CRU_CLK_SEL37_CON */
+       ACLK_VIO_PLL_SEL_CPLL           = 0,
+       ACLK_VIO_PLL_SEL_GPLL           = 1,
+       ACLK_VIO_PLL_SEL_HDMIPHY        = 2,
+       ACLK_VIO_PLL_SEL_USB480M        = 3,
+       ACLK_VIO_PLL_SEL_SHIFT          = 6,
+       ACLK_VIO_PLL_SEL_MASK           = 3 << ACLK_VIO_PLL_SEL_SHIFT,
+       ACLK_VIO_DIV_CON_SHIFT          = 0,
+       ACLK_VIO_DIV_CON_MASK           = 0x1f << ACLK_VIO_DIV_CON_SHIFT,
+       HCLK_VIO_DIV_CON_SHIFT          = 8,
+       HCLK_VIO_DIV_CON_MASK           = 0x1f << HCLK_VIO_DIV_CON_SHIFT,
+
+       /* CRU_CLK_SEL39_CON */
+       ACLK_VOP_PLL_SEL_CPLL           = 0,
+       ACLK_VOP_PLL_SEL_GPLL           = 1,
+       ACLK_VOP_PLL_SEL_HDMIPHY        = 2,
+       ACLK_VOP_PLL_SEL_USB480M        = 3,
+       ACLK_VOP_PLL_SEL_SHIFT          = 6,
+       ACLK_VOP_PLL_SEL_MASK           = 3 << ACLK_VOP_PLL_SEL_SHIFT,
+       ACLK_VOP_DIV_CON_SHIFT          = 0,
+       ACLK_VOP_DIV_CON_MASK           = 0x1f << ACLK_VOP_DIV_CON_SHIFT,
+
+       /* CRU_CLK_SEL40_CON */
+       DCLK_LCDC_PLL_SEL_GPLL          = 0,
+       DCLK_LCDC_PLL_SEL_CPLL          = 1,
+       DCLK_LCDC_PLL_SEL_SHIFT         = 0,
+       DCLK_LCDC_PLL_SEL_MASK          = 1 << DCLK_LCDC_PLL_SEL_SHIFT,
+       DCLK_LCDC_SEL_HDMIPHY           = 0,
+       DCLK_LCDC_SEL_PLL               = 1,
+       DCLK_LCDC_SEL_SHIFT             = 1,
+       DCLK_LCDC_SEL_MASK              = 1 << DCLK_LCDC_SEL_SHIFT,
+       DCLK_LCDC_DIV_CON_SHIFT         = 8,
+       DCLK_LCDC_DIV_CON_MASK          = 0xFf << DCLK_LCDC_DIV_CON_SHIFT,
 };
 
 void rk3328_configure_cpu(struct rk3328_cru *cru,
index cfec1d974ac92fe3af191aac9559bcedfc5b188a..df6076e4dcbe08f541c56610e61119ceca0fba3e 100644 (file)
@@ -580,6 +580,86 @@ static ulong rk3328_spi_set_clk(struct rk3328_cru *cru, uint hz)
        return rk3328_spi_get_clk(cru);
 }
 
+#ifndef CONFIG_SPL_BUILD
+static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
+{
+       struct rk3328_cru *cru = priv->cru;
+       u32 div, con, parent;
+
+       switch (clk_id) {
+       case ACLK_VOP_PRE:
+               con = readl(&cru->clksel_con[39]);
+               div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT;
+               parent = GPLL_HZ;
+               break;
+       case ACLK_VIO_PRE:
+               con = readl(&cru->clksel_con[37]);
+               div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT;
+               parent = GPLL_HZ;
+               break;
+       case DCLK_LCDC:
+               con = readl(&cru->clksel_con[40]);
+               div = (con & DCLK_LCDC_DIV_CON_MASK) >> DCLK_LCDC_DIV_CON_SHIFT;
+               parent = GPLL_HZ;
+               break;
+       default:
+               printf("%s: Unsupported vop get clk#%ld\n", __func__, clk_id);
+               return -ENOENT;
+       }
+
+       return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv,
+                               ulong clk_id, uint hz)
+{
+       struct rk3328_cru *cru = priv->cru;
+       int src_clk_div;
+       u32 con, parent;
+
+       src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz);
+       assert(src_clk_div - 1 < 31);
+
+       switch (clk_id) {
+       case ACLK_VOP_PRE:
+               rk_clrsetreg(&cru->clksel_con[39],
+                            ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
+                            ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT |
+                            (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT);
+               break;
+       case ACLK_VIO_PRE:
+               rk_clrsetreg(&cru->clksel_con[37],
+                            ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK,
+                            ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT |
+                            (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT);
+               break;
+       case DCLK_LCDC:
+               con = readl(&cru->clksel_con[40]);
+               con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT;
+               if (con) {
+                       parent = readl(&cru->clksel_con[40]);
+                       parent = (parent & DCLK_LCDC_PLL_SEL_MASK) >>
+                                DCLK_LCDC_PLL_SEL_SHIFT;
+                       if (parent)
+                               src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz);
+                       else
+                               src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz);
+
+                       rk_clrsetreg(&cru->clksel_con[40],
+                                    DCLK_LCDC_DIV_CON_MASK,
+                                    (src_clk_div - 1) <<
+                                    DCLK_LCDC_DIV_CON_SHIFT);
+               }
+               break;
+       default:
+               printf("%s: Unable to set vop clk#%ld\n", __func__, clk_id);
+               return -EINVAL;
+       }
+
+       return rk3328_vop_get_clk(priv, clk_id);
+}
+#endif
+
 static ulong rk3328_clk_get_rate(struct clk *clk)
 {
        struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
@@ -648,7 +728,13 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
        case SCLK_SPI:
                ret = rk3328_spi_set_clk(priv->cru, rate);
                break;
+#ifndef CONFIG_SPL_BUILD
        case DCLK_LCDC:
+       case ACLK_VOP_PRE:
+       case ACLK_VIO_PRE:
+               rate = rk3328_vop_set_clk(priv, clk->id, rate);
+               break;
+#endif
        case SCLK_PDM:
        case SCLK_RTC32K:
        case SCLK_UART0:
@@ -663,11 +749,9 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
        case ACLK_PERI_PRE:
        case HCLK_PERI:
        case PCLK_PERI:
-       case ACLK_VIO_PRE:
        case HCLK_VIO_PRE:
        case ACLK_RGA_PRE:
        case SCLK_RGA:
-       case ACLK_VOP_PRE:
        case ACLK_RKVDEC_PRE:
        case ACLK_RKVENC:
        case ACLK_VPU_PRE: