summaryrefslogtreecommitdiff
path: root/src/soc/rockchip
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/rockchip')
-rw-r--r--src/soc/rockchip/rk3288/clock.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/soc/rockchip/rk3288/clock.c b/src/soc/rockchip/rk3288/clock.c
index 878c1949a3..e4d2e3eb98 100644
--- a/src/soc/rockchip/rk3288/clock.c
+++ b/src/soc/rockchip/rk3288/clock.c
@@ -498,7 +498,7 @@ void rkclk_configure_tsadc(unsigned int hz)
RK_CLRSETBITS(0x3f << 0, (div - 1) << 0));
}
-static int pll_para_config(u32 freq_hz, struct pll_div *div)
+static int pll_para_config(u32 freq_hz, struct pll_div *div, u32 *ext_div)
{
u32 ref_khz = OSC_HZ / KHz, nr, nf = 0;
u32 fref_khz;
@@ -512,17 +512,27 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
printk(BIOS_ERR, "%s: the frequency can not be 0 Hz\n", __func__);
return -1;
}
+
no = div_round_up(VCO_MIN_KHZ, freq_khz);
+ if (ext_div) {
+ *ext_div = div_round_up(no, max_no);
+ no = div_round_up(no, *ext_div);
+ }
/* only even divisors (and 1) are supported */
if (no > 1)
no = div_round_up(no, 2) * 2;
+
vco_khz = freq_khz * no;
+ if (ext_div)
+ vco_khz *= *ext_div;
+
if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || no > max_no) {
printk(BIOS_ERR, "%s: Cannot find out a supported VCO"
" for Frequency (%uHz).\n", __func__, freq_hz);
return -1;
}
+
div->no = no;
best_diff_khz = vco_khz;
@@ -608,8 +618,9 @@ void rkclk_configure_vop_aclk(u32 vop_id, u32 aclk_hz)
int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz)
{
struct pll_div npll_config = {0};
+ u32 lcdc_div;
- if (pll_para_config(dclk_hz, &npll_config))
+ if (pll_para_config(dclk_hz, &npll_config, &lcdc_div))
return -1;
/* npll enter slow-mode */
@@ -633,12 +644,14 @@ int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz)
switch (vop_id) {
case 0:
write32(&cru_ptr->cru_clksel_con[27],
- RK_CLRSETBITS(0xff << 8 | 3 << 0, 0 << 8 | 2 << 0));
+ RK_CLRSETBITS(0xff << 8 | 3 << 0,
+ (lcdc_div - 1) << 8 | 2 << 0));
break;
case 1:
write32(&cru_ptr->cru_clksel_con[29],
- RK_CLRSETBITS(0xff << 8 | 3 << 6, 0 << 8 | 2 << 6));
+ RK_CLRSETBITS(0xff << 8 | 3 << 6,
+ (lcdc_div - 1) << 8 | 2 << 6));
break;
}
return 0;