clk: rockchip: rk3328: Add VOP clk support

VOP get and set clock would needed for VOP drivers.

Add support for it.

Signed-off-by: Jagan Teki <jagan@edgeble.ai>
This commit is contained in:
Jagan Teki
2024-04-21 09:07:00 +02:00
committed by Anatolij Gustschin
parent 7cebb300ae
commit 92edae779f
2 changed files with 120 additions and 2 deletions
@@ -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,
+86 -2
View 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: