diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b506e3622b08..04634851f7d8 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -84,6 +84,8 @@ #define EDID_QUIRK_FORCE_10BPC (1 << 11) /* Non desktop display (i.e. HMD) */ #define EDID_QUIRK_NON_DESKTOP (1 << 12) +/* Force max lane count */ +#define EDID_QUIRK_FORCE_MAX_LANE_COUNT (1 << 13) struct detailed_mode_closure { struct drm_connector *connector; @@ -193,6 +195,9 @@ static const struct edid_quirk { /* Sony PlayStation VR Headset */ { "SNY", 0x0704, EDID_QUIRK_NON_DESKTOP }, + + /* SHP eDP 1.4 panel only works with max lane count */ + { "SHP", 0x149a, EDID_QUIRK_FORCE_MAX_LANE_COUNT }, }; /* @@ -4475,6 +4480,7 @@ drm_reset_display_info(struct drm_connector *connector) memset(&info->hdmi, 0, sizeof(info->hdmi)); info->non_desktop = 0; + info->force_max_lane_count = 0; } u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) @@ -4756,6 +4762,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) if (quirks & EDID_QUIRK_FORCE_12BPC) connector->display_info.bpc = 12; + if (quirks & EDID_QUIRK_FORCE_MAX_LANE_COUNT) + connector->display_info.force_max_lane_count = true; + return num_modes; } EXPORT_SYMBOL(drm_add_edid_modes); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 22a74608c6e4..694a60ced14c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2013,7 +2013,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, limits.min_bpp = 6 * 3; limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); - if (intel_dp_is_edp(intel_dp) && intel_dp->edp_dpcd[0] < DP_EDP_14) { + if (intel_dp->edp_force_max_lane_count || (intel_dp_is_edp(intel_dp) && + intel_dp->edp_dpcd[0] < DP_EDP_14)) { /* * Use the maximum clock and number of lanes the eDP panel * advertizes being capable of. The eDP 1.3 and earlier panels @@ -6666,6 +6667,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, edid = drm_get_edid(connector, &intel_dp->aux.ddc); if (edid) { if (drm_add_edid_modes(connector, edid)) { + if (connector->display_info.force_max_lane_count) + intel_dp->edp_force_max_lane_count = true; drm_connector_update_edid_property(connector, edid); } else { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e9ddeaf05a14..92117da15c60 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1219,6 +1219,9 @@ struct intel_dp { /* Displayport compliance testing */ struct intel_dp_compliance compliance; + + /* eDP 1.4 EDID quirk to use max lane count */ + bool edp_force_max_lane_count; }; enum lspcon_vendor { diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 9be2181b3ed7..72c8b572f9ed 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -385,6 +385,11 @@ struct drm_display_info { * @non_desktop: Non desktop display (HMD). */ bool non_desktop; + + /** + * @force_max_lane_count: Link training requires max lane count to pass + */ + bool force_max_lane_count; }; int drm_display_info_set_bus_formats(struct drm_display_info *info,