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:
committed by
Anatolij Gustschin
parent
7cebb300ae
commit
92edae779f
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user