Skip to content

Commit 2c1268e

Browse files
cristiccmmind
authored andcommitted
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: FUKAUMI Naoki <[email protected]> Signed-off-by: Cristian Ciocaltea <[email protected]> Signed-off-by: Heiko Stuebner <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 9f40d7a commit 2c1268e

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

drivers/gpu/drm/rockchip/rockchip_drm_vop2.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ struct vop2_video_port {
159159
struct drm_crtc crtc;
160160
struct vop2 *vop2;
161161
struct clk *dclk;
162+
struct clk *dclk_src;
162163
unsigned int id;
163164
const struct vop2_video_port_data *data;
164165

@@ -214,6 +215,7 @@ struct vop2 {
214215
struct clk *hclk;
215216
struct clk *aclk;
216217
struct clk *pclk;
218+
struct clk *pll_hdmiphy0;
217219

218220
/* optional internal rgb encoder */
219221
struct rockchip_rgb *rgb;
@@ -222,6 +224,8 @@ struct vop2 {
222224
struct vop2_win win[];
223225
};
224226

227+
#define VOP2_MAX_DCLK_RATE 600000000
228+
225229
#define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
226230
(x) == ROCKCHIP_VOP2_EP_HDMI1)
227231

@@ -1155,6 +1159,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
11551159

11561160
vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
11571161

1162+
if (vp->dclk_src)
1163+
clk_set_parent(vp->dclk, vp->dclk_src);
1164+
11581165
clk_disable_unprepare(vp->dclk);
11591166

11601167
vop2->enable_count--;
@@ -2259,6 +2266,27 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
22592266

22602267
vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
22612268

2269+
/*
2270+
* Switch to HDMI PHY PLL as DCLK source for display modes up
2271+
* to 4K@60Hz, if available, otherwise keep using the system CRU.
2272+
*/
2273+
if (vop2->pll_hdmiphy0 && clock <= VOP2_MAX_DCLK_RATE) {
2274+
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
2275+
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
2276+
2277+
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
2278+
if (!vp->dclk_src)
2279+
vp->dclk_src = clk_get_parent(vp->dclk);
2280+
2281+
ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
2282+
if (ret < 0)
2283+
drm_warn(vop2->drm,
2284+
"Could not switch to HDMI0 PHY PLL: %d\n", ret);
2285+
break;
2286+
}
2287+
}
2288+
}
2289+
22622290
clk_set_rate(vp->dclk, clock);
22632291

22642292
vop2_post_config(crtc);
@@ -3699,6 +3727,12 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
36993727
return PTR_ERR(vop2->pclk);
37003728
}
37013729

3730+
vop2->pll_hdmiphy0 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy0");
3731+
if (IS_ERR(vop2->pll_hdmiphy0)) {
3732+
drm_err(vop2->drm, "failed to get pll_hdmiphy0\n");
3733+
return PTR_ERR(vop2->pll_hdmiphy0);
3734+
}
3735+
37023736
vop2->irq = platform_get_irq(pdev, 0);
37033737
if (vop2->irq < 0) {
37043738
drm_err(vop2->drm, "cannot find irq for vop2\n");

0 commit comments

Comments
 (0)