From bd5266c50b0b5cb3fc9f197ddd4367afa3cc498e Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Fri, 8 Sep 2017 10:59:07 +0900 Subject: DO NOT MERGE: Add default display modes Rpi3 can't get edid from some monitors. In those cases, we can make them work by adding default display modes. Bug: 65403744 Test: Rpi3 should display on 7" Pillow TFT monitor. Change-Id: I32b0f12c4d0fef00ce1cd1aafbdd43b53a4370e2 --- drivers/gpu/drm/drm_probe_helper.c | 7 +++++++ drivers/gpu/drm/vc4/vc4_hdmi.c | 22 ++++++++++++++++++++++ include/drm/drm_crtc_helper.h | 2 ++ 3 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index f8b5fcfa91a2..e1eb839361ba 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -194,7 +194,13 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", connector->base.id, connector->name); + if (connector_funcs->get_default_modes) + count = (*connector_funcs->get_default_modes)(connector); drm_mode_connector_update_edid_property(connector, NULL); + if (count > 0) { + connector->status = connector_status_connected; + goto validate; + } verbose_prune = false; goto prune; } @@ -219,6 +225,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect if (count == 0) goto prune; +validate: drm_mode_connector_list_update(connector, merge_type_bits); if (connector->interlace_allowed) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 2684003343c2..8b72d675d625 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -211,6 +211,27 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) return ret; } +static int vc4_hdmi_connector_get_default_modes(struct drm_connector *connector) +{ + struct vc4_hdmi_connector *vc4_connector = + to_vc4_hdmi_connector(connector); + struct drm_encoder *encoder = vc4_connector->encoder; + struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); + struct drm_device *dev = connector->dev; + struct drm_display_mode *default_mode = NULL; + int ret = 0; + + default_mode = drm_cvt_mode(dev, 800, 480, 60, false, false, false); + if (default_mode) { + drm_mode_probed_add(connector, default_mode); + ret++; + } + if (ret > 0) + vc4_encoder->hdmi_monitor = true; + + return ret; +} + static struct drm_encoder * vc4_hdmi_connector_best_encoder(struct drm_connector *connector) { @@ -231,6 +252,7 @@ static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = { .get_modes = vc4_hdmi_connector_get_modes, + .get_default_modes = vc4_hdmi_connector_get_default_modes, .best_encoder = vc4_hdmi_connector_best_encoder, }; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 3febb4b9fce9..d2b9174b0116 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -168,6 +168,7 @@ struct drm_encoder_helper_funcs { /** * struct drm_connector_helper_funcs - helper operations for connectors * @get_modes: get mode list for this connector + * @get_default_modes: get default mode list for this connector * @mode_valid: is this mode valid on the given connector? (optional) * @best_encoder: return the preferred encoder for this connector * @atomic_best_encoder: atomic version of @best_encoder @@ -176,6 +177,7 @@ struct drm_encoder_helper_funcs { */ struct drm_connector_helper_funcs { int (*get_modes)(struct drm_connector *connector); + int (*get_default_modes)(struct drm_connector *connector); enum drm_mode_status (*mode_valid)(struct drm_connector *connector, struct drm_display_mode *mode); struct drm_encoder *(*best_encoder)(struct drm_connector *connector); -- cgit v1.2.3