mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
drm/rockchip: vop: use rockchip_drm_dclk_set_rate() for some special pll
In addition, fix the version check process to switch for efficiency and readability. Change-Id: I372e528f61403a72ea574de5aae28174ef3f95fa Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
This commit is contained in:
@@ -64,6 +64,33 @@ static long rockchip_rk3568_drm_dclk_round_rate(struct clk *dclk, unsigned long
|
||||
return round_rate;
|
||||
}
|
||||
|
||||
static long rockchip_rk3576_vopl_drm_dclk_round_rate(struct clk *dclk, unsigned long rate)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
struct clk_hw *p_hw;
|
||||
unsigned long round_rate;
|
||||
const char *name;
|
||||
|
||||
hw = __clk_get_hw(dclk);
|
||||
if (!hw)
|
||||
return -EINVAL;
|
||||
|
||||
p_hw = clk_hw_get_parent(hw);
|
||||
if (!p_hw)
|
||||
return -EINVAL;
|
||||
|
||||
name = clk_hw_get_name(p_hw);
|
||||
|
||||
if (!strcmp(name, "vpll"))
|
||||
round_rate = rate;
|
||||
else if (!strcmp(name, "dclk_ebc_frac_src"))
|
||||
round_rate = rate;
|
||||
else
|
||||
round_rate = clk_round_rate(dclk, rate);
|
||||
|
||||
return round_rate;
|
||||
}
|
||||
|
||||
static long rockchip_rk3576_drm_dclk_round_rate(struct clk *dclk, unsigned long rate)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
@@ -218,6 +245,57 @@ static int rockchip_rk3568_drm_dclk_set_rate(struct clk *dclk, unsigned long rat
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The rk3576 ebc setting clk rule.
|
||||
* The dclk_ebc can select vpll, the vpll is ebc exclusive.
|
||||
* The dclk_ebc can select dclk_ebc_frac_src, use digital decimal divider, the recommended frequency is less than 60M.
|
||||
* The dclk_ebc can select gpll or cpll, can only choose the nearest frequency division(gpll:1188M,cpll:1000M),
|
||||
* and can't support accurate frequency setting.
|
||||
*
|
||||
*/
|
||||
static int rockchip_rk3576_vopl_drm_dclk_set_rate(struct clk *dclk, unsigned long rate)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
struct clk_hw *p_hw;
|
||||
unsigned long pll_rate;
|
||||
const char *name;
|
||||
int div = 0;
|
||||
|
||||
hw = __clk_get_hw(dclk);
|
||||
if (!hw)
|
||||
return -EINVAL;
|
||||
|
||||
p_hw = clk_hw_get_parent(hw);
|
||||
if (!p_hw)
|
||||
return -EINVAL;
|
||||
|
||||
name = clk_hw_get_name(p_hw);
|
||||
|
||||
if (!strcmp(name, "vpll")) {
|
||||
pll_rate = clk_hw_get_rate(p_hw);
|
||||
if (pll_rate >= VOP2_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
|
||||
clk_set_rate(dclk, rate);
|
||||
} else {
|
||||
div = DIV_ROUND_UP(VOP2_PLL_LIMIT_FREQ, rate);
|
||||
if (div % 2)
|
||||
div += 1;
|
||||
clk_set_rate(p_hw->clk, rate * div);
|
||||
clk_set_rate(dclk, rate);
|
||||
}
|
||||
} else if (!strcmp(name, "dclk_ebc_frac_src")) {
|
||||
clk_set_rate(p_hw->clk, rate);
|
||||
clk_set_rate(dclk, rate);
|
||||
} else {
|
||||
clk_set_rate(dclk, rate);
|
||||
}
|
||||
|
||||
pr_debug("%s:request rate = %ld, %s = %ld %s = %ld\n", __func__, rate,
|
||||
clk_hw_get_name(hw), clk_hw_get_rate(hw),
|
||||
clk_hw_get_name(p_hw), clk_hw_get_rate(p_hw));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The rk3576 has three ports, dclk_vp0\1\2.
|
||||
* The dclk_vp0\1\2 can select 1 port specified on clk_hdmiphy_pixelx.
|
||||
@@ -330,16 +408,26 @@ long rockchip_drm_dclk_round_rate(u32 version, struct clk *dclk, unsigned long r
|
||||
{
|
||||
long round_rate;
|
||||
|
||||
if (version == VOP_VERSION_RK3562)
|
||||
switch (version) {
|
||||
case VOP_VERSION_RK3562:
|
||||
round_rate = rockchip_rk3562_drm_dclk_round_rate(dclk, rate);
|
||||
else if (version == VOP_VERSION_RK3568)
|
||||
break;
|
||||
case VOP_VERSION_RK3568:
|
||||
round_rate = rockchip_rk3568_drm_dclk_round_rate(dclk, rate);
|
||||
else if (version == VOP_VERSION_RK3576)
|
||||
break;
|
||||
case VOP_VERSION_RK3576:
|
||||
round_rate = rockchip_rk3576_drm_dclk_round_rate(dclk, rate);
|
||||
else if (version == VOP_VERSION_RK3588)
|
||||
break;
|
||||
case VOP_VERSION_RK3576_LITE:
|
||||
round_rate = rockchip_rk3576_vopl_drm_dclk_round_rate(dclk, rate);
|
||||
break;
|
||||
case VOP_VERSION_RK3588:
|
||||
round_rate = rockchip_rk3588_drm_dclk_round_rate(dclk, rate);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
round_rate = clk_round_rate(dclk, rate);
|
||||
break;
|
||||
}
|
||||
|
||||
if (round_rate < 0)
|
||||
pr_warn("%s:the clk_hw of dclk or parent of dclk may be NULL\n", __func__);
|
||||
@@ -351,16 +439,26 @@ int rockchip_drm_dclk_set_rate(u32 version, struct clk *dclk, unsigned long rate
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (version == VOP_VERSION_RK3562)
|
||||
switch (version) {
|
||||
case VOP_VERSION_RK3562:
|
||||
ret = rockchip_rk3562_drm_dclk_set_rate(dclk, rate);
|
||||
else if (version == VOP_VERSION_RK3568)
|
||||
break;
|
||||
case VOP_VERSION_RK3568:
|
||||
ret = rockchip_rk3568_drm_dclk_set_rate(dclk, rate);
|
||||
else if (version == VOP_VERSION_RK3576)
|
||||
break;
|
||||
case VOP_VERSION_RK3576:
|
||||
ret = rockchip_rk3576_drm_dclk_set_rate(dclk, rate);
|
||||
else if (version == VOP_VERSION_RK3588)
|
||||
break;
|
||||
case VOP_VERSION_RK3576_LITE:
|
||||
ret = rockchip_rk3576_vopl_drm_dclk_set_rate(dclk, rate);
|
||||
break;
|
||||
case VOP_VERSION_RK3588:
|
||||
ret = rockchip_rk3588_drm_dclk_set_rate(dclk, rate);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
ret = clk_set_rate(dclk, rate);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
pr_warn("%s:the clk_hw of dclk or parent of dclk may be NULL\n", __func__);
|
||||
|
||||
@@ -3687,8 +3687,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
|
||||
VOP_CTRL_SET(vop, win_csc_mode_sel, 1);
|
||||
|
||||
clk_set_rate(vop->dclk, adjusted_mode->crtc_clock * 1000);
|
||||
|
||||
rockchip_drm_dclk_set_rate(vop->version, vop->dclk, adjusted_mode->crtc_clock * 1000);
|
||||
|
||||
vop_cfg_done(vop);
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#define VOP_MAJOR(version) ((version) >> 8)
|
||||
#define VOP_MINOR(version) ((version) & 0xff)
|
||||
|
||||
#define VOP_VERSION_RK3576_LITE VOP_VERSION(0x2, 0xd)
|
||||
|
||||
#define VOP2_VERSION(major, minor, build) ((major) << 24 | (minor) << 16 | (build))
|
||||
#define VOP2_MAJOR(version) (((version) >> 24) & 0xff)
|
||||
#define VOP2_MINOR(version) (((version) >> 16) & 0xff)
|
||||
|
||||
Reference in New Issue
Block a user