Hello Sebastian,

At 2026-02-18 00:08:45, "Sebastian Reichel" <[email protected]> 
wrote:
>The display might offer modes, which exceed the maximum clock rate of a
>video output. This usually happens for displays that offer refresh rates
>above 60 Hz. This results in no picture being displayed without manual
>intervention. Fix this by teaching the driver about the maximum
>achievable clock rates.
>
>Signed-off-by: Sebastian Reichel <[email protected]>
>---
>I've taken the max. clock rate information from the video output
>information of the RK3568/RK3588/RK3576 datasheets. The real max. clock
>rates should be above those to take blank times into account. I haven't
>found the proper information source for this. I hope Andy can help out.
>---
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c |  3 +++
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  1 +
> drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 10 ++++++++++
> 3 files changed, 14 insertions(+)
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
>b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>index ec3b4fde10db..1051418e5fff 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>@@ -1434,6 +1434,9 @@ static enum drm_mode_status vop2_crtc_mode_valid(struct 
>drm_crtc *crtc,
>       if (mode->hdisplay > vp->data->max_output.width)
>               return MODE_BAD_HVALUE;
> 
>+      if (mode->clock > vp->data->max_clock_rate / 1000)
>+              return MODE_CLOCK_HIGH;
>+
>       return MODE_OK;
> }
> 
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h 
>b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>index 9124191899ba..42d70426bf08 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>@@ -225,6 +225,7 @@ struct vop2_video_port_data {
>       u16 gamma_lut_len;
>       u16 cubic_lut_len;
>       struct vop_rect max_output;
>+      u32 max_clock_rate;
>       const u8 pre_scan_max_dly[4];
>       unsigned int offset;
>       /**
>diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c 
>b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>index f3950e8476a7..8be2cf0c47b6 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>@@ -559,18 +559,21 @@ static const struct vop2_video_port_data 
>rk3568_vop_video_ports[] = {
>               .gamma_lut_len = 1024,
>               .cubic_lut_len = 9 * 9 * 9,
>               .max_output = { 4096, 2304 },
>+              .max_clock_rate = 4096 * 2304 * 60,           

               600000000 MHZ

>               .pre_scan_max_dly = { 69, 53, 53, 42 },
>               .offset = 0xc00,
>       }, {
>               .id = 1,
>               .gamma_lut_len = 1024,
>               .max_output = { 2048, 1536 },
>+              .max_clock_rate = 2048 * 1536 * 60,

                200000000 Mhz
>               .pre_scan_max_dly = { 40, 40, 40, 40 },
>               .offset = 0xd00,
>       }, {
>               .id = 2,
>               .gamma_lut_len = 1024,
>               .max_output = { 1920, 1080 },
>+              .max_clock_rate = 1920 * 1080 * 60,
                 150000000 Hz

>               .pre_scan_max_dly = { 40, 40, 40, 40 },
>               .offset = 0xe00,
>       },
>@@ -775,6 +778,7 @@ static const struct vop2_video_port_data 
>rk3576_vop_video_ports[] = {
>               .gamma_lut_len = 1024,
>               .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
>               .max_output = { 4096, 2304 },
>+              .max_clock_rate = 4096 * 2304 * 120,
                600000000Mhz

>               /* win layer_mix hdr  */
>               .pre_scan_max_dly = { 10, 8, 2, 0 },
>               .offset = 0xc00,
>@@ -785,6 +789,7 @@ static const struct vop2_video_port_data 
>rk3576_vop_video_ports[] = {
>               .gamma_lut_len = 1024,
>               .cubic_lut_len = 729, /* 9x9x9 */
>               .max_output = { 2560, 1600 },
>+              .max_clock_rate = 2560 * 1600 * 60,

                 300000000 Mhz


>               /* win layer_mix hdr  */
>               .pre_scan_max_dly = { 10, 6, 0, 0 },
>               .offset = 0xd00,
>@@ -793,6 +798,7 @@ static const struct vop2_video_port_data 
>rk3576_vop_video_ports[] = {
>               .id = 2,
>               .gamma_lut_len = 1024,
>               .max_output = { 1920, 1080 },
>+              .max_clock_rate = 1920 * 1080 * 60,

                150000000 Mhz

>               /* win layer_mix hdr  */
>               .pre_scan_max_dly = { 10, 6, 0, 0 },
>               .offset = 0xe00,
>@@ -1061,6 +1067,7 @@ static const struct vop2_video_port_data 
>rk3588_vop_video_ports[] = {
>               .gamma_lut_len = 1024,
>               .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */
>               .max_output = { 4096, 2304 },
>+              .max_clock_rate = 7680 * 4320 * 60,
                 600 000000 Mhz


             For all current platforms, the maximum dclk input supported by VOP 
is 600 MHz. 
    The tricky part is that when we need to display a resolution higher than 
4K@60, even though
    the required dclk exceeds 600 MHz, VOP internally processes 2 or 4 pixels 
per clock cycle to
    output a higher resolution using a lower dclk. Therefore, even when 
outputting an 8K@60 resolution,
    CRU only needs to provide VOP with a dclk of 594 MHz. This is what the 
rk3588_calc_cru_cfg function does.

>               /* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */
>               .pre_scan_max_dly = { 76, 65, 65, 54 },
>               .offset = 0xc00,
>@@ -1070,6 +1077,7 @@ static const struct vop2_video_port_data 
>rk3588_vop_video_ports[] = {
>               .gamma_lut_len = 1024,
>               .cubic_lut_len = 729, /* 9x9x9 */
>               .max_output = { 4096, 2304 },
>+              .max_clock_rate = 4096 * 2304 * 60,
                600 000000 Mhz
>               .pre_scan_max_dly = { 76, 65, 65, 54 },
>               .offset = 0xd00,
>       }, {
>@@ -1078,12 +1086,14 @@ static const struct vop2_video_port_data 
>rk3588_vop_video_ports[] = {
>               .gamma_lut_len = 1024,
>               .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */
>               .max_output = { 4096, 2304 },
>+              .max_clock_rate = 4096 * 2304 * 60,
                 600 000000 Mhz
>               .pre_scan_max_dly = { 52, 52, 52, 52 },
>               .offset = 0xe00,
>       }, {
>               .id = 3,
>               .gamma_lut_len = 1024,
>               .max_output = { 2048, 1536 },
>+              .max_clock_rate = 1920 * 1080 * 60,

                150 000000 Mhz
>               .pre_scan_max_dly = { 52, 52, 52, 52 },
>               .offset = 0xf00,
>       },
>
>---
>base-commit: 9702969978695d9a699a1f34771580cdbb153b33
>change-id: 20260217-vop2-clk-rate-check-268269778cac
>
>Best regards,
>-- 
>Sebastian Reichel <[email protected]>

Reply via email to