clk: rockchip: rv1126: Add support for sfc and nandc

Change-Id: Ifb6873bf417adaaf95703064deeaed54b890b20b
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
This commit is contained in:
Finley Xiao 2020-02-26 17:56:13 +08:00
parent ba2ff15a2a
commit 57ae0852b1
2 changed files with 92 additions and 0 deletions

View File

@ -313,6 +313,22 @@ enum {
EMMC_DIV_SHIFT = 0,
EMMC_DIV_MASK = 0xff,
/* CRU_CLK_SEL58_CON */
SCLK_SFC_SEL_SHIFT = 15,
SCLK_SFC_SEL_MASK = 0x1 << SCLK_SFC_SEL_SHIFT,
SCLK_SFC_SEL_CPLL = 0,
SCLK_SFC_SEL_GPLL,
SCLK_SFC_DIV_SHIFT = 0,
SCLK_SFC_DIV_MASK = 0xff,
/* CRU_CLK_SEL59_CON */
CLK_NANDC_SEL_SHIFT = 15,
CLK_NANDC_SEL_MASK = 0x1 << CLK_NANDC_SEL_SHIFT,
CLK_NANDC_SEL_GPLL = 0,
CLK_NANDC_SEL_CPLL,
CLK_NANDC_DIV_SHIFT = 0,
CLK_NANDC_DIV_MASK = 0xff,
/* CRU_GMAC_CON */
GMAC_SRC_M1_SEL_SHIFT = 5,
GMAC_SRC_M1_SEL_MASK = 0x1 << GMAC_SRC_M1_SEL_SHIFT,

View File

@ -1070,6 +1070,70 @@ static ulong rv1126_emmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
return rv1126_mmc_get_clk(priv, clk_id);
}
static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv)
{
struct rv1126_cru *cru = priv->cru;
u32 div, sel, con, parent;
con = readl(&cru->clksel_con[58]);
div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
if (sel == SCLK_SFC_SEL_GPLL)
parent = priv->gpll_hz;
else if (sel == SCLK_SFC_SEL_CPLL)
parent = priv->cpll_hz;
else
return -ENOENT;
return DIV_TO_RATE(parent, div);
}
static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
{
struct rv1126_cru *cru = priv->cru;
int src_clk_div;
src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
rk_clrsetreg(&cru->clksel_con[58],
SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT |
(src_clk_div - 1) << SCLK_SFC_DIV_SHIFT);
return rv1126_sfc_get_clk(priv);
}
static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv)
{
struct rv1126_cru *cru = priv->cru;
u32 div, sel, con, parent;
con = readl(&cru->clksel_con[59]);
div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT;
sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT;
if (sel == CLK_NANDC_SEL_GPLL)
parent = priv->gpll_hz;
else if (sel == CLK_NANDC_SEL_CPLL)
parent = priv->cpll_hz;
else
return -ENOENT;
return DIV_TO_RATE(parent, div);
}
static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate)
{
struct rv1126_cru *cru = priv->cru;
int src_clk_div;
src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
rk_clrsetreg(&cru->clksel_con[59],
CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK,
CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT |
(src_clk_div - 1) << CLK_NANDC_DIV_SHIFT);
return rv1126_nand_get_clk(priv);
}
static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv)
{
struct rv1126_cru *cru = priv->cru;
@ -1231,6 +1295,12 @@ static ulong rv1126_clk_get_rate(struct clk *clk)
case SCLK_EMMC_SAMPLE:
rate = rv1126_mmc_get_clk(priv, clk->id);
break;
case SCLK_SFC:
rate = rv1126_sfc_get_clk(priv);
break;
case CLK_NANDC:
rate = rv1126_nand_get_clk(priv);
break;
case ACLK_PDVO:
case ACLK_VOP:
rate = rv1126_aclk_vop_get_clk(priv);
@ -1309,6 +1379,12 @@ static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
case HCLK_EMMC:
ret = rv1126_emmc_set_clk(priv, clk->id, rate);
break;
case SCLK_SFC:
ret = rv1126_sfc_set_clk(priv, rate);
break;
case CLK_NANDC:
ret = rv1126_nand_set_clk(priv, rate);
break;
case ACLK_PDVO:
case ACLK_VOP:
ret = rv1126_aclk_vop_set_clk(priv, rate);