From: Dave Stevenson Date: Fri, 3 Jul 2020 15:06:55 +0000 (+0100) Subject: drm/vc4: FKMS Block modes with odd horizontal timing values on Pi4 X-Git-Tag: accepted/tizen/unified/20200709.164653~310 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=18967206cfdb067cb7e33a04fadbd8078c71e960;p=platform%2Fkernel%2Flinux-rpi.git 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 --- diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c index a173ca4..ff72648 100644 --- 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 *crtc, const struct drm_display_mode *mode) 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_funcs vc4_crtc_helper_funcs = { 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 *dev, struct device *master, void *data) 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 *dev, struct device *master, void *data) 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. */