clk: rockchip: rk3288: fix up the dclk_vop freq setting
Change-Id: I960a02cba63076afbc845e5ccdfb9f85a553d38b Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
This commit is contained in:
parent
ba5feded0a
commit
b328c914c0
|
|
@ -133,6 +133,28 @@ enum {
|
|||
SPI0_DIV_MASK = 0x7f << SPI0_DIV_SHIFT,
|
||||
};
|
||||
|
||||
/* CRU_CLKSEL27_CON */
|
||||
enum {
|
||||
DCLK_VOP0_DIV_SHIFT = 8,
|
||||
DCLK_VOP0_DIV_MASK = 0xff << DCLK_VOP0_DIV_SHIFT,
|
||||
DCLK_VOP0_PLL_SHIFT = 0,
|
||||
DCLK_VOP0_PLL_MASK = 3 << DCLK_VOP0_PLL_SHIFT,
|
||||
DCLK_VOP0_SELECT_CPLL = 0,
|
||||
DCLK_VOP0_SELECT_GPLL = 1,
|
||||
DCLK_VOP0_SELECT_NPLL = 2,
|
||||
};
|
||||
|
||||
/* CRU_CLKSEL29_CON */
|
||||
enum {
|
||||
DCLK_VOP1_DIV_SHIFT = 8,
|
||||
DCLK_VOP1_DIV_MASK = 0xff << DCLK_VOP1_DIV_SHIFT,
|
||||
DCLK_VOP1_PLL_SHIFT = 6,
|
||||
DCLK_VOP1_PLL_MASK = 3 << DCLK_VOP1_PLL_SHIFT,
|
||||
DCLK_VOP1_SELECT_CPLL = 0,
|
||||
DCLK_VOP1_SELECT_GPLL = 1,
|
||||
DCLK_VOP1_SELECT_NPLL = 2,
|
||||
};
|
||||
|
||||
/* CRU_CLKSEL37_CON */
|
||||
enum {
|
||||
PCLK_CORE_DBG_DIV_SHIFT = 9,
|
||||
|
|
|
|||
|
|
@ -177,6 +177,40 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Get pll rate by id */
|
||||
static u32 rkclk_pll_get_rate(struct rk3288_cru *cru,
|
||||
enum rk_clk_id clk_id)
|
||||
{
|
||||
u32 nr, no, nf;
|
||||
u32 con;
|
||||
int pll_id = rk_pll_id(clk_id);
|
||||
struct rk3288_pll *pll = &cru->pll[pll_id];
|
||||
static u8 clk_shift[CLK_COUNT] = {
|
||||
0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
|
||||
GPLL_MODE_SHIFT, NPLL_MODE_SHIFT
|
||||
};
|
||||
uint shift;
|
||||
|
||||
con = readl(&cru->cru_mode_con);
|
||||
shift = clk_shift[clk_id];
|
||||
switch ((con >> shift) & CRU_MODE_MASK) {
|
||||
case APLL_MODE_SLOW:
|
||||
return OSC_HZ;
|
||||
case APLL_MODE_NORMAL:
|
||||
/* normal mode */
|
||||
con = readl(&pll->con0);
|
||||
no = ((con & CLKOD_MASK) >> CLKOD_SHIFT) + 1;
|
||||
nr = ((con & CLKR_MASK) >> CLKR_SHIFT) + 1;
|
||||
con = readl(&pll->con1);
|
||||
nf = ((con & CLKF_MASK) >> CLKF_SHIFT) + 1;
|
||||
|
||||
return (24 * nf / (nr * no)) * 1000000;
|
||||
case APLL_MODE_DEEP:
|
||||
default:
|
||||
return 32768;
|
||||
}
|
||||
}
|
||||
|
||||
static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
|
||||
unsigned int hz)
|
||||
{
|
||||
|
|
@ -342,37 +376,90 @@ static int rockchip_mac_set_clk(struct rk3288_cru *cru, uint freq)
|
|||
static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
|
||||
int periph, unsigned int rate_hz)
|
||||
{
|
||||
struct pll_div npll_config = {0};
|
||||
u32 lcdc_div;
|
||||
struct pll_div cpll_config = {0};
|
||||
u32 lcdc_div, parent;
|
||||
int ret;
|
||||
unsigned int gpll_rate, npll_rate;
|
||||
|
||||
ret = pll_para_config(rate_hz, &npll_config, &lcdc_div);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
npll_rate = rkclk_pll_get_rate(cru, CLK_NEW);
|
||||
|
||||
rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK,
|
||||
NPLL_MODE_SLOW << NPLL_MODE_SHIFT);
|
||||
rkclk_set_pll(cru, CLK_NEW, &npll_config);
|
||||
|
||||
/* waiting for pll lock */
|
||||
while (1) {
|
||||
if (readl(&grf->soc_status[1]) & SOCSTS_NPLL_LOCK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK,
|
||||
NPLL_MODE_NORMAL << NPLL_MODE_SHIFT);
|
||||
|
||||
/* vop dclk source clk: npll,dclk_div: 1 */
|
||||
/* vop dclk source clk: cpll,dclk_div: 1 */
|
||||
switch (periph) {
|
||||
case DCLK_VOP0:
|
||||
rk_clrsetreg(&cru->cru_clksel_con[27], 0xff << 8 | 3 << 0,
|
||||
(lcdc_div - 1) << 8 | 2 << 0);
|
||||
ret = (readl(&cru->cru_clksel_con[27]) && DCLK_VOP0_PLL_MASK) >>
|
||||
DCLK_VOP0_PLL_SHIFT;
|
||||
if (ret == DCLK_VOP0_SELECT_CPLL) {
|
||||
ret = pll_para_config(rate_hz, &cpll_config, &lcdc_div);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
|
||||
CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
|
||||
rkclk_set_pll(cru, CLK_NEW, &cpll_config);
|
||||
|
||||
/* waiting for pll lock */
|
||||
while (1) {
|
||||
if (readl(&grf->soc_status[1]) &
|
||||
SOCSTS_CPLL_LOCK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
|
||||
CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
|
||||
parent = DCLK_VOP0_SELECT_CPLL;
|
||||
} else if (ret == DCLK_VOP0_SELECT_GPLL) {
|
||||
parent = DCLK_VOP0_SELECT_GPLL;
|
||||
lcdc_div = DIV_ROUND_UP(gpll_rate,
|
||||
rate_hz);
|
||||
} else {
|
||||
parent = DCLK_VOP0_SELECT_NPLL;
|
||||
lcdc_div = DIV_ROUND_UP(npll_rate,
|
||||
rate_hz);
|
||||
}
|
||||
rk_clrsetreg(&cru->cru_clksel_con[27],
|
||||
DCLK_VOP0_DIV_MASK | DCLK_VOP0_PLL_MASK,
|
||||
((lcdc_div - 1) << DCLK_VOP0_DIV_SHIFT) |
|
||||
(parent << DCLK_VOP0_PLL_SHIFT));
|
||||
break;
|
||||
case DCLK_VOP1:
|
||||
rk_clrsetreg(&cru->cru_clksel_con[29], 0xff << 8 | 3 << 6,
|
||||
(lcdc_div - 1) << 8 | 2 << 6);
|
||||
ret = (readl(&cru->cru_clksel_con[29]) && DCLK_VOP1_PLL_MASK) >>
|
||||
DCLK_VOP1_PLL_SHIFT;
|
||||
if (ret == DCLK_VOP1_SELECT_CPLL) {
|
||||
ret = pll_para_config(rate_hz, &cpll_config, &lcdc_div);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
|
||||
CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
|
||||
rkclk_set_pll(cru, CLK_NEW, &cpll_config);
|
||||
|
||||
/* waiting for pll lock */
|
||||
while (1) {
|
||||
if (readl(&grf->soc_status[1]) &
|
||||
SOCSTS_CPLL_LOCK)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
rk_clrsetreg(&cru->cru_mode_con, CPLL_MODE_MASK,
|
||||
CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
|
||||
|
||||
parent = DCLK_VOP1_SELECT_CPLL;
|
||||
} else if (ret == DCLK_VOP1_SELECT_GPLL) {
|
||||
parent = DCLK_VOP1_SELECT_GPLL;
|
||||
lcdc_div = DIV_ROUND_UP(gpll_rate,
|
||||
rate_hz);
|
||||
} else {
|
||||
parent = DCLK_VOP1_SELECT_NPLL;
|
||||
lcdc_div = DIV_ROUND_UP(npll_rate,
|
||||
rate_hz);
|
||||
}
|
||||
rk_clrsetreg(&cru->cru_clksel_con[29],
|
||||
DCLK_VOP1_DIV_MASK | DCLK_VOP1_PLL_MASK,
|
||||
((lcdc_div - 1) << DCLK_VOP1_DIV_SHIFT) |
|
||||
(parent << DCLK_VOP1_PLL_SHIFT));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -495,40 +582,6 @@ void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
|
|||
APLL_MODE_NORMAL << APLL_MODE_SHIFT);
|
||||
}
|
||||
|
||||
/* Get pll rate by id */
|
||||
static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru,
|
||||
enum rk_clk_id clk_id)
|
||||
{
|
||||
uint32_t nr, no, nf;
|
||||
uint32_t con;
|
||||
int pll_id = rk_pll_id(clk_id);
|
||||
struct rk3288_pll *pll = &cru->pll[pll_id];
|
||||
static u8 clk_shift[CLK_COUNT] = {
|
||||
0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
|
||||
GPLL_MODE_SHIFT, NPLL_MODE_SHIFT
|
||||
};
|
||||
uint shift;
|
||||
|
||||
con = readl(&cru->cru_mode_con);
|
||||
shift = clk_shift[clk_id];
|
||||
switch ((con >> shift) & CRU_MODE_MASK) {
|
||||
case APLL_MODE_SLOW:
|
||||
return OSC_HZ;
|
||||
case APLL_MODE_NORMAL:
|
||||
/* normal mode */
|
||||
con = readl(&pll->con0);
|
||||
no = ((con & CLKOD_MASK) >> CLKOD_SHIFT) + 1;
|
||||
nr = ((con & CLKR_MASK) >> CLKR_SHIFT) + 1;
|
||||
con = readl(&pll->con1);
|
||||
nf = ((con & CLKF_MASK) >> CLKF_SHIFT) + 1;
|
||||
|
||||
return (24 * nf / (nr * no)) * 1000000;
|
||||
case APLL_MODE_DEEP:
|
||||
default:
|
||||
return 32768;
|
||||
}
|
||||
}
|
||||
|
||||
static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
|
||||
int periph)
|
||||
{
|
||||
|
|
@ -1039,11 +1092,52 @@ static int __maybe_unused rk3288_gmac_set_parent(struct clk *clk, struct clk *pa
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int __maybe_unused rk3288_vop_set_parent(struct clk *clk,
|
||||
struct clk *parent)
|
||||
{
|
||||
struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
struct rk3288_cru *cru = priv->cru;
|
||||
int parent_sel;
|
||||
|
||||
switch (parent->id) {
|
||||
case PLL_CPLL:
|
||||
parent_sel = 0;
|
||||
break;
|
||||
case PLL_GPLL:
|
||||
parent_sel = 1;
|
||||
break;
|
||||
case PLL_NPLL:
|
||||
parent_sel = 2;
|
||||
break;
|
||||
default:
|
||||
parent_sel = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (clk->id) {
|
||||
case DCLK_VOP0:
|
||||
rk_clrsetreg(&cru->cru_clksel_con[27],
|
||||
DCLK_VOP0_PLL_MASK, parent_sel << 0);
|
||||
break;
|
||||
case DCLK_VOP1:
|
||||
rk_clrsetreg(&cru->cru_clksel_con[29],
|
||||
DCLK_VOP1_PLL_MASK, parent_sel << 6);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rk3288_clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
switch (clk->id) {
|
||||
case SCLK_MAC:
|
||||
return rk3288_gmac_set_parent(clk, parent);
|
||||
case DCLK_VOP0:
|
||||
case DCLK_VOP1:
|
||||
return rk3288_vop_set_parent(clk, parent);
|
||||
case SCLK_USBPHY480M_SRC:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue