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 <dave.stevenson@raspberrypi.com>
struct vc4_fkms {
struct get_display_cfg cfg;
struct vc4_fkms {
struct get_display_cfg cfg;
};
#define PLANES_PER_CRTC 3
};
#define PLANES_PER_CRTC 3
+ /* 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;
+
static const struct of_device_id vc4_firmware_kms_dt_match[] = {
{ .compatible = "raspberrypi,rpi-firmware-kms" },
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 },
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
struct device_node *firmware_node;
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;
struct vc4_crtc **crtc_list;
u32 num_displays, display_num;
struct vc4_fkms *fkms;
if (!fkms)
return -ENOMEM;
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.
*/
/* firmware kms doesn't have precise a scanoutpos implementation, so
* we can't do the precise vblank timestamp mode.
*/