From aa791f2cb6777e8ca99102009b631afdeea1c59d Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 3 Jul 2020 16:06:55 +0100 Subject: [PATCH] drm/vc4: FKMS Block modes with odd horizontal timing values on Pi4 Pi4 HDMI pipeline is 2 pixels/clock and can not produce timings that have odd values for active pixels, front porch, sync width, or back porch. Detect these modes and block them within fkms. Signed-off-by: Dave Stevenson --- drivers/gpu/drm/vc4/vc4_firmware_kms.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c @@ -44,6 +44,7 @@ struct get_display_cfg { struct vc4_fkms { struct get_display_cfg cfg; + bool bcm2711; }; #define PLANES_PER_CRTC 3 @@ -1097,6 +1098,17 @@ vc4_crtc_mode_valid(struct drm_crtc *crt break; } + /* Pi4 can't generate odd horizontal timings on HDMI, so reject modes + * that would set them. + */ + if (fkms->bcm2711 && + (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) && + ((mode->hdisplay | /* active */ + (mode->hsync_start - mode->hdisplay) | /* front porch */ + (mode->hsync_end - mode->hsync_start) | /* sync pulse */ + (mode->htotal - mode->hsync_end)) & 1)) /* back porch */ + return MODE_H_ILLEGAL; + return MODE_OK; } @@ -1282,6 +1294,8 @@ static const struct drm_crtc_helper_func static const struct of_device_id vc4_firmware_kms_dt_match[] = { { .compatible = "raspberrypi,rpi-firmware-kms" }, + { .compatible = "raspberrypi,rpi-firmware-kms-2711", + .data = (void *)1 }, {} }; @@ -1815,6 +1829,7 @@ static int vc4_fkms_bind(struct device * struct drm_device *drm = dev_get_drvdata(master); struct vc4_dev *vc4 = to_vc4_dev(drm); struct device_node *firmware_node; + const struct of_device_id *match; struct vc4_crtc **crtc_list; u32 num_displays, display_num; struct vc4_fkms *fkms; @@ -1827,6 +1842,12 @@ static int vc4_fkms_bind(struct device * if (!fkms) return -ENOMEM; + match = of_match_device(vc4_firmware_kms_dt_match, dev); + if (!match) + return -ENODEV; + if (match->data) + fkms->bcm2711 = true; + /* firmware kms doesn't have precise a scanoutpos implementation, so * we can't do the precise vblank timestamp mode. */