CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
}
+static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /*
+ * Interlaced video modes got CRTC_INTERLACE_HALVE_V applied when
+ * coming from user space. We don't want this, as it screws up
+ * vblank timestamping, so fix it up.
+ */
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+ DRM_DEBUG_KMS("[CRTC:%d] adjusted_mode :\n", crtc->base.id);
+ drm_mode_debug_printmodeline(adjusted_mode);
+
+ return true;
+}
+
static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
.mode_set_nofb = vc4_crtc_mode_set_nofb,
.disable = vc4_crtc_disable,
.enable = vc4_crtc_enable,
+ .mode_fixup = vc4_crtc_mode_fixup,
.atomic_check = vc4_crtc_atomic_check,
.atomic_flush = vc4_crtc_atomic_flush,
};
return ret;
}
+/*
+ * drm_helper_probe_single_connector_modes() applies drm_mode_set_crtcinfo to
+ * all modes with flag CRTC_INTERLACE_HALVE_V. We don't want this, as it
+ * screws up vblank timestamping for interlaced modes, so fix it up.
+ */
+static int vc4_hdmi_connector_probe_modes(struct drm_connector *connector,
+ uint32_t maxX, uint32_t maxY)
+{
+ struct drm_display_mode *mode;
+ int count;
+
+ count = drm_helper_probe_single_connector_modes(connector, maxX, maxY);
+ if (count == 0)
+ return 0;
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed adapted modes :\n",
+ connector->base.id, connector->name);
+ list_for_each_entry(mode, &connector->modes, head) {
+ drm_mode_set_crtcinfo(mode, 0);
+ drm_mode_debug_printmodeline(mode);
+ }
+
+ return count;
+}
+
static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms,
.detect = vc4_hdmi_connector_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
+ .fill_modes = vc4_hdmi_connector_probe_modes,
.destroy = vc4_hdmi_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT);
- connector->interlace_allowed = 0;
+ connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
drm_mode_connector_attach_encoder(connector, encoder);