Skip to content
Snippets Groups Projects
Commit 2c1268e7 authored by Cristian Ciocaltea's avatar Cristian Ciocaltea Committed by Heiko Stuebner
Browse files

drm/rockchip: vop2: Improve display modes handling on RK3588 HDMI0


The RK3588 specific implementation is currently quite limited in terms
of handling the full range of display modes supported by the connected
screens, e.g. 2560x1440@75Hz, 2048x1152@60Hz, 1024x768@60Hz are just a
few of them.

Additionally, it doesn't cope well with non-integer refresh rates like
59.94, 29.97, 23.98, etc.

Make use of HDMI0 PHY PLL as a more accurate DCLK source to handle
all display modes up to 4K@60Hz.

Tested-by: default avatarFUKAUMI Naoki <naoki@radxa.com>
Signed-off-by: default avatarCristian Ciocaltea <cristian.ciocaltea@collabora.com>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20250204-vop2-hdmi0-disp-modes-v3-3-d71c6a196e58@collabora.com
parent 9f40d7a9
No related branches found
No related tags found
No related merge requests found
......@@ -159,6 +159,7 @@ struct vop2_video_port {
struct drm_crtc crtc;
struct vop2 *vop2;
struct clk *dclk;
struct clk *dclk_src;
unsigned int id;
const struct vop2_video_port_data *data;
......@@ -214,6 +215,7 @@ struct vop2 {
struct clk *hclk;
struct clk *aclk;
struct clk *pclk;
struct clk *pll_hdmiphy0;
/* optional internal rgb encoder */
struct rockchip_rgb *rgb;
......@@ -222,6 +224,8 @@ struct vop2 {
struct vop2_win win[];
};
#define VOP2_MAX_DCLK_RATE 600000000
#define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
(x) == ROCKCHIP_VOP2_EP_HDMI1)
......@@ -1155,6 +1159,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
if (vp->dclk_src)
clk_set_parent(vp->dclk, vp->dclk_src);
clk_disable_unprepare(vp->dclk);
vop2->enable_count--;
......@@ -2259,6 +2266,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
/*
* Switch to HDMI PHY PLL as DCLK source for display modes up
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 && clock <= VOP2_MAX_DCLK_RATE) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
if (!vp->dclk_src)
vp->dclk_src = clk_get_parent(vp->dclk);
ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
if (ret < 0)
drm_warn(vop2->drm,
"Could not switch to HDMI0 PHY PLL: %d\n", ret);
break;
}
}
}
clk_set_rate(vp->dclk, clock);
vop2_post_config(crtc);
......@@ -3699,6 +3727,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(vop2->pclk);
}
vop2->pll_hdmiphy0 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy0");
if (IS_ERR(vop2->pll_hdmiphy0)) {
drm_err(vop2->drm, "failed to get pll_hdmiphy0\n");
return PTR_ERR(vop2->pll_hdmiphy0);
}
vop2->irq = platform_get_irq(pdev, 0);
if (vop2->irq < 0) {
drm_err(vop2->drm, "cannot find irq for vop2\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment