For DP sinks which don't expose color depth via EDID, use
the drm_dp_sink_bpc() helper to derive the bpc of the sink.

This should handle DP native sinks with the "Assume 6 bpc if EDID
doesn't tell us" as mandated by DP spec. It gives more accurate
values for DP->legacy converters for HDMI, DVI and VGA.

Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
Cc: Jani Nikula <jani.nikula at intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++++++++++++-----
 drivers/gpu/drm/i915/intel_dp.c      |  7 +++++++
 drivers/gpu/drm/i915/intel_drv.h     |  1 +
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c7854f4..1a5287f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12212,11 +12212,27 @@ connected_sink_compute_bpp(struct intel_connector 
*connector,
                pipe_config->pipe_bpp = connector->base.display_info.bpc*3;
        }

-       /* Clamp bpp to 8 on screens without EDID 1.4 */
-       if (connector->base.display_info.bpc == 0 && bpp > 24) {
-               DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit 
of 24\n",
-                             bpp);
-               pipe_config->pipe_bpp = 24;
+       /* Clamp bpp to default limit on screens without EDID 1.4 */
+       if (connector->base.display_info.bpc == 0) {
+               int type = connector->base.connector_type;
+               int clamp_bpp = 24;
+
+               /* On DisplayPort try harder to find sink bpc */
+               if (type == DRM_MODE_CONNECTOR_DisplayPort ||
+                   type == DRM_MODE_CONNECTOR_eDP) {
+                       int sink_bpc = intel_dp_sink_bpc(&connector->base);
+
+                       if (sink_bpc) {
+                               DRM_DEBUG_KMS("DP sink with bpc %d\n", 
sink_bpc);
+                               clamp_bpp = 3 * sink_bpc;
+                       }
+               }
+
+               if (bpp > clamp_bpp) {
+                       DRM_DEBUG_KMS("clamping display bpp (was %d) to default 
limit of %d\n",
+                                     bpp, clamp_bpp);
+                       pipe_config->pipe_bpp = clamp_bpp;
+               }
        }
 }

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ffa43ec..d8dab0b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5689,3 +5689,10 @@ void intel_dp_mst_resume(struct drm_device *dev)
                }
        }
 }
+
+/* XXX Only supports up to 1 downstream port atm. */
+int intel_dp_sink_bpc(struct drm_connector *connector)
+{
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
+       return drm_dp_sink_bpc(intel_dp->dpcd, intel_dp->downstream_ports, 0);
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 089a425..e8feac1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1335,6 +1335,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp);
 void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector 
*connector);
 void intel_dp_mst_suspend(struct drm_device *dev);
 void intel_dp_mst_resume(struct drm_device *dev);
+int intel_dp_sink_bpc(struct drm_connector *connector);
 int intel_dp_max_link_rate(struct intel_dp *intel_dp);
 int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
 void intel_dp_hot_plug(struct intel_encoder *intel_encoder);
-- 
2.7.0

Reply via email to