From 9531221df8f0cadcf4c03151e2a0204787a77b74 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 9 Sep 2018 15:34:56 +0200 Subject: drm/i915: Check for panel orientation quirks on eDP panels So far we have only been calling drm_connector_init_panel_orientation_property(), which checks for panel orientation quirks in the drm_panel_orientation_quirks.c file, for DSI panels as so far only devices with DSI panels have had panels which are not mounted up right. The new GPD win2 device uses a portrait screen in a landscape case, so now we've a device with an eDP panel which needs the panel-orientation property to let the fbcon code and userspace know that the image needs to be fixed-up. This commit makes intel_edp_init_connector() call drm_connector_init_panel_orientation_property() so that the property gets added. Reported-and-tested-by: russianneuromancer@ya.ru Reviewed-by: Jani Nikula Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20180909133457.10636-2-hdegoede@redhat.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6b4c19123f2a..256a71c8c093 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6490,6 +6490,10 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, intel_connector->panel.backlight.power = intel_edp_backlight_power; intel_panel_setup_backlight(connector, pipe); + if (fixed_mode) + drm_connector_init_panel_orientation_property( + connector, fixed_mode->hdisplay, fixed_mode->vdisplay); + return true; out_vdd_off: -- cgit v1.2.3 From 9ebd8202393dde9d3678c9ec162c1aa63ba17eac Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Thu, 27 Sep 2018 13:57:30 -0700 Subject: drm/i915/dp: Fix link retraining comment in intel_dp_long_pulse() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comment claims link needs to be retrained because the connected sink raised a long pulse to indicate link loss. If the sink did so, intel_dp_hotplug() would have handled link retraining. Looking at the logs in Bugzilla referenced in commit '3cf71bc9904d ("drm/i915: Re-apply Perform link quality check, unconditionally during long pulse"")', the issue is that the sink does not trigger an interrupt. What we want is ->detect() from user space to check link status and retrain. Ville's review for the original patch also indicates the same root cause. So, rewrite the comment. v2: Patch split and rewrote comment. Cc: Lyude Paul Cc: Ville Syrjälä Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Jan-Marek Glogowski References: 3cf71bc9904d ("drm/i915: Re-apply "Perform link quality check, unconditionally during long pulse"") Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180927205735.16651-1-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 256a71c8c093..207b3ea2ed1a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5074,16 +5074,9 @@ intel_dp_long_pulse(struct intel_connector *connector, goto out; } else { /* - * If display is now connected check links status, - * there has been known issues of link loss triggering - * long pulse. - * - * Some sinks (eg. ASUS PB287Q) seem to perform some - * weird HPD ping pong during modesets. So we can apparently - * end up with HPD going low during a modeset, and then - * going back up soon after. And once that happens we must - * retrain the link to get a picture. That's in case no - * userspace component reacted to intermittent HPD dip. + * Some external monitors do not signal loss of link + * synchronization with an IRQ_HPD, so force a link status + * check. */ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; -- cgit v1.2.3 From f24f6eb95807bca0dbd8dc5b2f3a4099000f4472 Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Thu, 27 Sep 2018 13:57:31 -0700 Subject: drm/i915/dp: Restrict link retrain workaround to external monitors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit '3cf71bc9904d ("drm/i915: Re-apply "Perform link quality check, unconditionally during long pulse"")' applies a work around for sinks that don't signal link loss. The work around does not need to have to be that broad as the issue was seen with only one particular monitor; limit this only for external displays as eDP features like PSR turn off the link and the driver ends up retraining the link seeeing that link is not synchronized. Cc: Lyude Paul Cc: Jan-Marek Glogowski Cc: Ville Syrjälä Cc: Rodrigo Vivi References: 3cf71bc9904d ("drm/i915: Re-apply "Perform link quality check, unconditionally during long pulse"") Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180927205735.16651-2-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 207b3ea2ed1a..4e0870f3a4a5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5072,12 +5072,13 @@ intel_dp_long_pulse(struct intel_connector *connector, */ status = connector_status_disconnected; goto out; - } else { - /* - * Some external monitors do not signal loss of link - * synchronization with an IRQ_HPD, so force a link status - * check. - */ + } + + /* + * Some external monitors do not signal loss of link synchronization + * with an IRQ_HPD, so force a link status check. + */ + if (!intel_dp_is_edp(intel_dp)) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; intel_dp_retrain_link(encoder, ctx); -- cgit v1.2.3 From d5acd97f5571189616685a4498b7d50687048979 Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Thu, 27 Sep 2018 13:57:32 -0700 Subject: drm/i915/dp: Use a local variable for intel_encoder * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have two cases of intel_dp to intel_encoder conversions, use a local variable to store the conversion. Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Ville Syrjälä Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20180927205735.16651-3-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4e0870f3a4a5..5c0375899974 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5017,6 +5017,7 @@ intel_dp_long_pulse(struct intel_connector *connector, { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_dp *intel_dp = intel_attached_dp(&connector->base); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; enum drm_connector_status status; u8 sink_irq_vector = 0; @@ -5027,7 +5028,7 @@ intel_dp_long_pulse(struct intel_connector *connector, /* Can't disconnect eDP */ if (intel_dp_is_edp(intel_dp)) status = edp_detect(intel_dp); - else if (intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) + else if (intel_digital_port_connected(encoder)) status = intel_dp_detect_dpcd(intel_dp); else status = connector_status_disconnected; @@ -5078,11 +5079,8 @@ intel_dp_long_pulse(struct intel_connector *connector, * Some external monitors do not signal loss of link synchronization * with an IRQ_HPD, so force a link status check. */ - if (!intel_dp_is_edp(intel_dp)) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - + if (!intel_dp_is_edp(intel_dp)) intel_dp_retrain_link(encoder, ctx); - } /* * Clearing NACK and defer counts to get their exact values -- cgit v1.2.3 From 47658556da857c66c5865f192408639f524cca40 Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Thu, 27 Sep 2018 13:57:33 -0700 Subject: drm/i915/dp: Do not grab crtc modeset lock in intel_dp_detect() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A crtc modeset lock was added for link retraining but intel_dp_retrain_link() knows to take the necessary locks since commit c85d200e8321 ("drm/i915: Move SST DP link retraining into the ->post_hotplug() hook") v2: Drop AUX power domain reference in the early return path Fixes: c85d200e8321 ("drm/i915: Move SST DP link retraining into the ->post_hotplug() hook") Cc: Ville Syrjälä Cc: José Roberto de Souza Signed-off-by: Dhinakaran Pandiyan Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20180927205735.16651-4-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5c0375899974..64c8a5330847 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5079,8 +5079,16 @@ intel_dp_long_pulse(struct intel_connector *connector, * Some external monitors do not signal loss of link synchronization * with an IRQ_HPD, so force a link status check. */ - if (!intel_dp_is_edp(intel_dp)) - intel_dp_retrain_link(encoder, ctx); + if (!intel_dp_is_edp(intel_dp)) { + int ret; + + ret = intel_dp_retrain_link(encoder, ctx); + if (ret) { + intel_display_power_put(dev_priv, + intel_dp->aux_power_domain); + return ret; + } + } /* * Clearing NACK and defer counts to get their exact values @@ -5130,19 +5138,8 @@ intel_dp_detect(struct drm_connector *connector, connector->base.id, connector->name); /* If full detect is not performed yet, do a full detect */ - if (!intel_dp->detect_done) { - struct drm_crtc *crtc; - int ret; - - crtc = connector->state->crtc; - if (crtc) { - ret = drm_modeset_lock(&crtc->mutex, ctx); - if (ret) - return ret; - } - + if (!intel_dp->detect_done) status = intel_dp_long_pulse(intel_dp->attached_connector, ctx); - } intel_dp->detect_done = false; -- cgit v1.2.3 From cbfa8ac835cb46ce7535ff11afe33f2bffc08ff7 Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Thu, 27 Sep 2018 13:57:34 -0700 Subject: drm/i915/dp: Kill intel_dp->detect_done flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The intel_dp->detect_done flag is no more useful. Pull intel_dp_long_pulse() into the lone caller, Cc: Jani Nikula Cc: Ville Syrjälä Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180927205735.16651-5-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 64c8a5330847..cb352d2c7e5f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5012,15 +5012,18 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) } static int -intel_dp_long_pulse(struct intel_connector *connector, - struct drm_modeset_acquire_ctx *ctx) +intel_dp_detect(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + bool force) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_dp *intel_dp = intel_attached_dp(&connector->base); + struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; enum drm_connector_status status; u8 sink_irq_vector = 0; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); intel_display_power_get(dev_priv, intel_dp->aux_power_domain); @@ -5099,9 +5102,9 @@ intel_dp_long_pulse(struct intel_connector *connector, intel_dp->aux.i2c_defer_count = 0; intel_dp_set_edid(intel_dp); - if (intel_dp_is_edp(intel_dp) || connector->detect_edid) + if (intel_dp_is_edp(intel_dp) || + to_intel_connector(connector)->detect_edid) status = connector_status_connected; - intel_dp->detect_done = true; /* Try to read the source of the interrupt */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && @@ -5126,26 +5129,6 @@ out: return status; } -static int -intel_dp_detect(struct drm_connector *connector, - struct drm_modeset_acquire_ctx *ctx, - bool force) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - int status = connector->status; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - - /* If full detect is not performed yet, do a full detect */ - if (!intel_dp->detect_done) - status = intel_dp_long_pulse(intel_dp->attached_connector, ctx); - - intel_dp->detect_done = false; - - return status; -} - static void intel_dp_force(struct drm_connector *connector) { @@ -5638,7 +5621,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) if (long_hpd) { intel_dp->reset_link_params = true; - intel_dp->detect_done = false; return IRQ_NONE; } @@ -5655,7 +5637,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) intel_dp->is_mst = false; drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); - intel_dp->detect_done = false; goto put_power; } } @@ -5668,10 +5649,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) /* Short pulse can signify loss of hdcp authentication */ intel_hdcp_check_link(intel_dp->attached_connector); - if (!handled) { - intel_dp->detect_done = false; + if (!handled) goto put_power; - } } ret = IRQ_HANDLED; -- cgit v1.2.3 From 9844bc87cb7a5985bab1f1c26e6c4e534105725b Mon Sep 17 00:00:00 2001 From: Dhinakaran Pandiyan Date: Thu, 27 Sep 2018 13:57:35 -0700 Subject: drm/i915/dp: Fix duplication of DEVICE_SERVICE_IRQ handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two copies of the same code called from long and short pulse handlers. v2: Rebase due to s/int status/enum drm_connector_status in intel_dp_detect() Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Ville Syrjälä Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20180927205735.16651-6-dhinakaran.pandiyan@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 59 +++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cb352d2c7e5f..e59edab5786c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4038,13 +4038,6 @@ intel_dp_configure_mst(struct intel_dp *intel_dp) intel_dp->is_mst); } -static bool -intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector) -{ - return drm_dp_dpcd_readb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, - sink_irq_vector) == 1; -} - static bool intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) { @@ -4432,6 +4425,26 @@ static bool intel_dp_hotplug(struct intel_encoder *encoder, return changed; } +static void intel_dp_check_service_irq(struct intel_dp *intel_dp) +{ + u8 val; + + if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) + return; + + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_DEVICE_SERVICE_IRQ_VECTOR, &val) != 1 || !val) + return; + + drm_dp_dpcd_writeb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val); + + if (val & DP_AUTOMATED_TEST_REQUEST) + intel_dp_handle_test_request(intel_dp); + + if (val & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) + DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); +} + /* * According to DP spec * 5.1.2: @@ -4449,7 +4462,6 @@ static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u8 sink_irq_vector = 0; u8 old_sink_count = intel_dp->sink_count; bool ret; @@ -4472,20 +4484,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) return false; } - /* Try to read the source of the interrupt */ - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && - intel_dp_get_sink_irq(intel_dp, &sink_irq_vector) && - sink_irq_vector != 0) { - /* Clear interrupt source */ - drm_dp_dpcd_writeb(&intel_dp->aux, - DP_DEVICE_SERVICE_IRQ_VECTOR, - sink_irq_vector); - - if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST) - intel_dp_handle_test_request(intel_dp); - if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) - DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); - } + intel_dp_check_service_irq(intel_dp); /* Handle CEC interrupts, if any */ drm_dp_cec_irq(&intel_dp->aux); @@ -5020,7 +5019,6 @@ intel_dp_detect(struct drm_connector *connector, struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; enum drm_connector_status status; - u8 sink_irq_vector = 0; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -5106,20 +5104,7 @@ intel_dp_detect(struct drm_connector *connector, to_intel_connector(connector)->detect_edid) status = connector_status_connected; - /* Try to read the source of the interrupt */ - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && - intel_dp_get_sink_irq(intel_dp, &sink_irq_vector) && - sink_irq_vector != 0) { - /* Clear interrupt source */ - drm_dp_dpcd_writeb(&intel_dp->aux, - DP_DEVICE_SERVICE_IRQ_VECTOR, - sink_irq_vector); - - if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST) - intel_dp_handle_test_request(intel_dp); - if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) - DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); - } + intel_dp_check_service_irq(intel_dp); out: if (status != connector_status_connected && !intel_dp->is_mst) -- cgit v1.2.3 From 7769db5883841b03de544a35a71ff528d4131c17 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 5 Sep 2018 12:53:21 +0300 Subject: drm/i915/dp: optimize eDP 1.4+ link config fast and narrow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've opted to use the maximum link rate and lane count for eDP panels, because typically the maximum supported configuration reported by the panel has matched the native resolution requirements of the panel, and optimizing the link has lead to problems. With eDP 1.4 rate select method and DSC features, this is decreasingly the case. There's a need to optimize the link parameters. Moreover, already eDP 1.3 states fast link with fewer lanes is preferred over the wide and slow. (Wide and slow should still be more reliable for longer cable lengths.) Additionally, there have been reports of panels failing on arbitrary link configurations, although arguably all configurations they claim to support should work. Optimize eDP 1.4+ link config fast and narrow. Side note: The implementation has a near duplicate of the link config function, with just the two inner for loops turned inside out. Perhaps there'd be a way to make this, say, more table driven to reduce the duplication, but seems like that would lead to duplication in the table generation. We'll also have to see how the link config optimization for DSC turns out. Cc: Ville Syrjälä Cc: Manasi Navare Cc: Rodrigo Vivi Cc: Matt Atwood Cc: "Lee, Shawn C" Acked-by: Rodrigo Vivi Reviewed-by: Manasi Navare Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105267 Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180905095321.13843-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 73 ++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e59edab5786c..15a981ef5966 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1921,6 +1921,42 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, return false; } +/* Optimize link config in order: max bpp, min lanes, min clock */ +static bool +intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + const struct link_config_limits *limits) +{ + struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; + int bpp, clock, lane_count; + int mode_rate, link_clock, link_avail; + + for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { + mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, + bpp); + + for (lane_count = limits->min_lane_count; + lane_count <= limits->max_lane_count; + lane_count <<= 1) { + for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { + link_clock = intel_dp->common_rates[clock]; + link_avail = intel_dp_max_data_rate(link_clock, + lane_count); + + if (mode_rate <= link_avail) { + pipe_config->lane_count = lane_count; + pipe_config->pipe_bpp = bpp; + pipe_config->port_clock = link_clock; + + return true; + } + } + } + } + + return false; +} + static bool intel_dp_compute_link_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) @@ -1945,13 +1981,15 @@ 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)) { + if (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 panels are generally - * designed to support only a single clock and lane - * configuration, and typically these values correspond to the - * native resolution of the panel. + * advertizes being capable of. The eDP 1.3 and earlier panels + * are generally designed to support only a single clock and + * lane configuration, and typically these values correspond to + * the native resolution of the panel. With eDP 1.4 rate select + * and DSC, this is decreasingly the case, and we need to be + * able to select less than maximum link config. */ limits.min_lane_count = limits.max_lane_count; limits.min_clock = limits.max_clock; @@ -1965,12 +2003,25 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, intel_dp->common_rates[limits.max_clock], limits.max_bpp, adjusted_mode->crtc_clock); - /* - * Optimize for slow and wide. This is the place to add alternative - * optimization policy. - */ - if (!intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits)) - return false; + if (intel_dp_is_edp(intel_dp)) { + /* + * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 + * section A.1: "It is recommended that the minimum number of + * lanes be used, using the minimum link rate allowed for that + * lane configuration." + * + * Note that we use the max clock and lane count for eDP 1.3 and + * earlier, and fast vs. wide is irrelevant. + */ + if (!intel_dp_compute_link_config_fast(intel_dp, pipe_config, + &limits)) + return false; + } else { + /* Optimize for slow and wide. */ + if (!intel_dp_compute_link_config_wide(intel_dp, pipe_config, + &limits)) + return false; + } DRM_DEBUG_KMS("DP lane count %d clock %d bpp %d\n", pipe_config->lane_count, pipe_config->port_clock, -- cgit v1.2.3 From 9dbf5a4efd8afa2b831b0f76b4f9cab9480af817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 3 Oct 2018 21:42:10 +0300 Subject: drm/i915: Provide more clues as to why MST is/is not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always print out the information whether the port and sink can each do MST. And let's include the modparam in the debug output as well. Makes life a little less confusing when you don't have to wonder why MST isn't kicking in. This does cause a slight change in our behaviour towards the sink. Previously we only read the MSTM_CAP register after passing all the other checks. Now we will read that register regardless. Hopefully some crazy sink doesn't get confused by a simple register read. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181003184210.1306-1-ville.syrjala@linux.intel.com Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_dp.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 15a981ef5966..1a510cf58fb5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4050,16 +4050,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) } static bool -intel_dp_can_mst(struct intel_dp *intel_dp) +intel_dp_sink_can_mst(struct intel_dp *intel_dp) { u8 mstm_cap; - if (!i915_modparams.enable_dp_mst) - return false; - - if (!intel_dp->can_mst) - return false; - if (intel_dp->dpcd[DP_DPCD_REV] < 0x12) return false; @@ -4069,21 +4063,30 @@ intel_dp_can_mst(struct intel_dp *intel_dp) return mstm_cap & DP_MST_CAP; } +static bool +intel_dp_can_mst(struct intel_dp *intel_dp) +{ + return i915_modparams.enable_dp_mst && + intel_dp->can_mst && + intel_dp_sink_can_mst(intel_dp); +} + static void intel_dp_configure_mst(struct intel_dp *intel_dp) { - if (!i915_modparams.enable_dp_mst) - return; + struct intel_encoder *encoder = + &dp_to_dig_port(intel_dp)->base; + bool sink_can_mst = intel_dp_sink_can_mst(intel_dp); + + DRM_DEBUG_KMS("MST support? port %c: %s, sink: %s, modparam: %s\n", + port_name(encoder->port), yesno(intel_dp->can_mst), + yesno(sink_can_mst), yesno(i915_modparams.enable_dp_mst)); if (!intel_dp->can_mst) return; - intel_dp->is_mst = intel_dp_can_mst(intel_dp); - - if (intel_dp->is_mst) - DRM_DEBUG_KMS("Sink is MST capable\n"); - else - DRM_DEBUG_KMS("Sink is not MST capable\n"); + intel_dp->is_mst = sink_can_mst && + i915_modparams.enable_dp_mst; drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); -- cgit v1.2.3 From f56f6648404b411b377a3082bc9459fed66a968f Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 4 Oct 2018 11:46:02 +0200 Subject: drm/i915: Get rid of crtc->config dereference in intel_dp_retrain_link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're already using crtc_state here and made sure no modeset is occurring by looking at conn_state->commit->hw_done, so there's no need to dereference crtc->config. Signed-off-by: Maarten Lankhorst Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181004094604.2646-12-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1a510cf58fb5..19f0c3f59cbe 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4420,7 +4420,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, /* Suppress underruns caused by re-training */ intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); - if (crtc->config->has_pch_encoder) + if (crtc_state->has_pch_encoder) intel_set_pch_fifo_underrun_reporting(dev_priv, intel_crtc_pch_transcoder(crtc), false); @@ -4431,7 +4431,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, intel_wait_for_vblank(dev_priv, crtc->pipe); intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); - if (crtc->config->has_pch_encoder) + if (crtc_state->has_pch_encoder) intel_set_pch_fifo_underrun_reporting(dev_priv, intel_crtc_pch_transcoder(crtc), true); -- cgit v1.2.3 From bc3213c444153848b3a1fcaccbcf2c2123ce3de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 8 Oct 2018 16:46:41 +0300 Subject: drm/i915: Drop the eDP check from intel_dp_connector_destroy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As long as the connector was zeroed during allocation calling intel_panel_fini() is safe even if we haven't initialized the panel struct explicitly. So let's drop the useless eDP check from dp connector destruction. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181008134641.24868-2-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_dp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 19f0c3f59cbe..d12f987a6c43 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5261,12 +5261,7 @@ intel_dp_connector_destroy(struct drm_connector *connector) if (!IS_ERR_OR_NULL(intel_connector->edid)) kfree(intel_connector->edid); - /* - * Can't call intel_dp_is_edp() since the encoder may have been - * destroyed already. - */ - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) - intel_panel_fini(&intel_connector->panel); + intel_panel_fini(&intel_connector->panel); drm_connector_cleanup(connector); kfree(connector); -- cgit v1.2.3 From d4b26e4f438f0b070fbcd1e765fb53db9ac59112 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 9 Oct 2018 17:11:03 +0300 Subject: drm/i915: add a common connector type independent destroy hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Almost all of the connector destroy functions do the same thing. The differences are in the edid, detect_edid and panel cleanups, but those are safely NULL when not initialized. Roll out a common connector destroy hook. Inspired by commit bc3213c44415 ("drm/i915: Drop the eDP check from intel_dp_connector_destroy()"). Cc: Ville Syrjala Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20181009141103.20387-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d12f987a6c43..0855b9785f7b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5251,22 +5251,6 @@ intel_dp_connector_unregister(struct drm_connector *connector) intel_connector_unregister(connector); } -static void -intel_dp_connector_destroy(struct drm_connector *connector) -{ - struct intel_connector *intel_connector = to_intel_connector(connector); - - kfree(intel_connector->detect_edid); - - if (!IS_ERR_OR_NULL(intel_connector->edid)) - kfree(intel_connector->edid); - - intel_panel_fini(&intel_connector->panel); - - drm_connector_cleanup(connector); - kfree(connector); -} - void intel_dp_encoder_destroy(struct drm_encoder *encoder) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); @@ -5613,7 +5597,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { .atomic_set_property = intel_digital_connector_atomic_set_property, .late_register = intel_dp_connector_register, .early_unregister = intel_dp_connector_unregister, - .destroy = intel_dp_connector_destroy, + .destroy = intel_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; -- cgit v1.2.3 From 1e712535c51ab025ebc776d4405683d81521996d Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 9 Oct 2018 14:28:04 -0700 Subject: drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit panel's native mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the original commit c0cfb10d9e1de49 ("drm/i915/edp: Do not do link training fallback or prune modes on EDP") that causes a blank screen in case of certain eDP panels (Eg: seen on Dell XPS13 9350) where first link training fails and a retraining is required by falling back to lower link rate/lane count. In case of some panels they advertise higher link rate/lane count than whats required for supporting the panel's native mode. But we always link train at highest link rate/lane count for eDP and if that fails we can still fallback to lower link rate/lane count as long as the fallback link BW still fits the native mode to avoid pruning the panel's native mode yet retraining at fallback values to recover from a blank screen. v3: * Add const for fixed_mode (Ville) v2: * Send uevent if link failure on eDP unconditionally Fixes: c0cfb10d9e1d ("drm/i915/edp: Do not do link training fallback or prune modes on EDP") Cc: Clinton Taylor Cc: Jani Nikula Cc: Ville Syrjala Cc: Daniel Vetter Cc: Lucas De Marchi Cc: # v4.17+ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107489 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105338 Signed-off-by: Manasi Navare Tested-by: Alexander Wilson Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181009212804.702-1-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0855b9785f7b..13ff89be6ad6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -557,6 +557,22 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, return true; } +static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp, + int link_rate, + uint8_t lane_count) +{ + const struct drm_display_mode *fixed_mode = + intel_dp->attached_connector->panel.fixed_mode; + int mode_rate, max_rate; + + mode_rate = intel_dp_link_required(fixed_mode->clock, 18); + max_rate = intel_dp_max_data_rate(link_rate, lane_count); + if (mode_rate > max_rate) + return false; + + return true; +} + int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, int link_rate, uint8_t lane_count) { @@ -566,9 +582,23 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, intel_dp->num_common_rates, link_rate); if (index > 0) { + if (intel_dp_is_edp(intel_dp) && + !intel_dp_can_link_train_fallback_for_edp(intel_dp, + intel_dp->common_rates[index - 1], + lane_count)) { + DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n"); + return 0; + } intel_dp->max_link_rate = intel_dp->common_rates[index - 1]; intel_dp->max_link_lane_count = lane_count; } else if (lane_count > 1) { + if (intel_dp_is_edp(intel_dp) && + !intel_dp_can_link_train_fallback_for_edp(intel_dp, + intel_dp_max_common_rate(intel_dp), + lane_count >> 1)) { + DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n"); + return 0; + } intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); intel_dp->max_link_lane_count = lane_count >> 1; } else { -- cgit v1.2.3 From d9facae6afe14f461f0667227c1c377cb84ad7fa Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:07 +0530 Subject: drm/i915: Introduce CRTC output format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds an enum "intel_output_format" to represent the output format of a particular CRTC. This enum will be used to produce a RGB/YCBCR4:4:4/YCBCR4:2:0 output format during the atomic modeset calculations. V5: - Created this separate patch to introduce and init output_format. - Initialize parameters of output_format_str respectively (Jani N). - Call it intel_output_format than crtc_output_format(Ville). - Set output format in pipe_config for every encoder (Ville). - Get rid of extra DRM_DEBUG_KMS during get_pipe_config (Ville) V6: Rebase V7: Fixed alignment warnings (checkpatch) V8: Another check[atch warning for alignment V9: Rebase V10: Rebase on top of DSI restructure V11: Addressed review comment from Ville - Set CRTC format for pre-HSW get_pipe_config() function too. Added Ville's R-B Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-1-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 13ff89be6ad6..c3f63306e935 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2085,6 +2085,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) pipe_config->has_pch_encoder = true; + pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_drrs = false; if (IS_G4X(dev_priv) || port == PORT_A) pipe_config->has_audio = false; -- cgit v1.2.3 From 668b6c176c33f443a50afd981cc9c0939e411b3b Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:14 +0530 Subject: drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON LSPCON chips can generate YCBCR outputs, if asked nicely :). In order to generate YCBCR 4:2:0 outputs, a source must: - send YCBCR 4:4:4 signals to LSPCON - program color space as 4:2:0 in AVI infoframes Whereas for YCBCR 4:4:4 outputs, the source must: - send YCBCR 4:4:4 signals to LSPCON - program color space as 4:4:4 in AVI infoframes So for both 4:2:0 as well as 4:4:4 outputs, we are driving the pipe for YCBCR 4:4:4 output, but AVI infoframe's color space information indicates LSPCON FW to start scaling down from YCBCR 4:4:4 and generate YCBCR 4:2:0 output. As the scaling is done by LSPCON device, we need not to reserve a scaler for 4:2:0 outputs. V2: rebase V3: Addressed review comments from Ville - add enum crtc_output_format instead of bool ycbcr420 - use crtc_output_format=4:4:4 for modeset of LSPCON 4:2:0 output cases in this way we will have YCBCR 4:4:4 framework ready (except the ABI part) V4: Added r-b from Maarten (for v3) Addressed review comments from Ville: - Do not add a non-atomic state variable to determine lspcon output. Instead add bool in CRTC state to indicate lspcon based scaling. V5: Addressed review comments from Ville: - Change the state bool name from external scaling to something more relavent. - Keep the info and adjusted_mode structures const. - use crtc_state instead of pipe_config. - Push all the config change into lspcon_ycbcr420_config function. V6: Rebase, small changes to accommodate changes in patch 2. V7: Fixed checkpatch warnings for alignment V8: Rebase PS: Ignored following warnings to match the current formatting: drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON -:53: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV) #53: FILE: drivers/gpu/drm/i915/i915_reg.h:8721: +#define TRANS_MSA_SAMPLING_444 (2<<1) ^ -:54: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV) #54: FILE: drivers/gpu/drm/i915/i915_reg.h:8722: +#define TRANS_MSA_CLRSP_YCBCR (2<<3) V9: Rebase V10: Rebase V11: Rebase Cc: Ville Syrjala Cc: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-8-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c3f63306e935..1156d59758c1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2074,6 +2074,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct intel_lspcon *lspcon = enc_to_intel_lspcon(&encoder->base); enum port port = encoder->port; struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); struct intel_connector *intel_connector = intel_dp->attached_connector; @@ -2086,6 +2087,9 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_pch_encoder = true; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; + if (lspcon->active) + lspcon_ycbcr420_config(&intel_connector->base, pipe_config); + pipe_config->has_drrs = false; if (IS_G4X(dev_priv) || port == PORT_A) pipe_config->has_audio = false; -- cgit v1.2.3 From 4c35475485c1297393a35b161057b57753449a15 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 11 Oct 2018 12:04:49 +0200 Subject: drm/i915: Make intel_dp_set_m_n take crtc_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another user of crtc->config gone. The functions it calls also needed crtc->config, so convert those as well. Signed-off-by: Maarten Lankhorst [mlankhorst: Still pass m_n struct to intel_pch_transcoder_set_m_n (Ville)] Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181011100457.8776-3-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1156d59758c1..7f91b287b2d2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6096,10 +6096,10 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, if (INTEL_GEN(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { switch (index) { case DRRS_HIGH_RR: - intel_dp_set_m_n(intel_crtc, M1_N1); + intel_dp_set_m_n(crtc_state, M1_N1); break; case DRRS_LOW_RR: - intel_dp_set_m_n(intel_crtc, M2_N2); + intel_dp_set_m_n(crtc_state, M2_N2); break; case DRRS_MAX_RR: default: -- cgit v1.2.3 From c0aa834404b33804b3af0822ebcd9881fa8cb214 Mon Sep 17 00:00:00 2001 From: Mahesh Kumar Date: Wed, 3 Oct 2018 12:51:57 +0530 Subject: drm/i915/icl: use combophy/TC helper functions during display detection Instead of directly comparing HPD pins use intel_port_is_combophy/tc helper functions to distinguish between combophy/TC ports. Signed-off-by: Mahesh Kumar Cc: Manasi Navare Reviewed-by: Rodrigo Vivi Reviewed-by: Lucas De Marchi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181003072203.12848-3-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7f91b287b2d2..1f098e509143 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5003,19 +5003,14 @@ static bool icl_digital_port_connected(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); - switch (encoder->hpd_pin) { - case HPD_PORT_A: - case HPD_PORT_B: + if (intel_port_is_combophy(dev_priv, encoder->port)) return icl_combo_port_connected(dev_priv, dig_port); - case HPD_PORT_C: - case HPD_PORT_D: - case HPD_PORT_E: - case HPD_PORT_F: + else if (intel_port_is_tc(dev_priv, encoder->port)) return icl_tc_port_connected(dev_priv, dig_port); - default: + else MISSING_CASE(encoder->hpd_pin); - return false; - } + + return false; } /* -- cgit v1.2.3 From 61cdfb9e194d2a327eef301e8fc80b63e3e1dc7a Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 17 Oct 2018 14:56:52 -0700 Subject: drm/i915/icl: Fix signal_levels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since when it was introduced we forgot to add this case so ICL was using a wrong signal_levels as reference. Fixes: fb5c8e9d4350 ("drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI") Cc: José Roberto de Souza Cc: Manasi Navare Signed-off-by: Rodrigo Vivi Reviewed-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20181017215652.26841-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1f098e509143..3384a9bbdafd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3790,7 +3790,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp) uint32_t signal_levels, mask = 0; uint8_t train_set = intel_dp->train_set[0]; - if (IS_GEN9_LP(dev_priv) || IS_CANNONLAKE(dev_priv)) { + if (IS_GEN9_LP(dev_priv) || INTEL_GEN(dev_priv) >= 10) { signal_levels = bxt_signal_levels(intel_dp); } else if (HAS_DDI(dev_priv)) { signal_levels = ddi_signal_levels(intel_dp); -- cgit v1.2.3 From 210126bd807d39a9ccb65872b1c5112a18b23777 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 22 Oct 2018 10:15:24 -0700 Subject: drm/i915: digital_port_connected sort platforms newer-to-older MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just sorting this "if" block from newer to older platform. The main difference here is the addition of a missing case with return false that should never occur. And if it occurs it is better than to raise a warn than use the icl one. The gen >= 11 was already present in the previous logic, although hidden. So, in summary no real functional change. Cc: Jani Nikula Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181022171526.15641-3-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3384a9bbdafd..8c38efef77a1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5035,20 +5035,23 @@ bool intel_digital_port_connected(struct intel_encoder *encoder) return g4x_digital_port_connected(encoder); } - if (IS_GEN5(dev_priv)) - return ilk_digital_port_connected(encoder); - else if (IS_GEN6(dev_priv)) - return snb_digital_port_connected(encoder); - else if (IS_GEN7(dev_priv)) - return ivb_digital_port_connected(encoder); - else if (IS_GEN8(dev_priv)) - return bdw_digital_port_connected(encoder); + if (INTEL_GEN(dev_priv) >= 11) + return icl_digital_port_connected(encoder); + else if (IS_GEN10(dev_priv) || IS_GEN9_BC(dev_priv)) + return spt_digital_port_connected(encoder); else if (IS_GEN9_LP(dev_priv)) return bxt_digital_port_connected(encoder); - else if (IS_GEN9_BC(dev_priv) || IS_GEN10(dev_priv)) - return spt_digital_port_connected(encoder); - else - return icl_digital_port_connected(encoder); + else if (IS_GEN8(dev_priv)) + return bdw_digital_port_connected(encoder); + else if (IS_GEN7(dev_priv)) + return ivb_digital_port_connected(encoder); + else if (IS_GEN6(dev_priv)) + return snb_digital_port_connected(encoder); + else if (IS_GEN5(dev_priv)) + return ilk_digital_port_connected(encoder); + + MISSING_CASE(INTEL_GEN(dev_priv)); + return false; } static struct edid * -- cgit v1.2.3 From 342ac601df6420070221b977cf0d38f91cdc1e8a Mon Sep 17 00:00:00 2001 From: Ramalingam C Date: Tue, 23 Oct 2018 14:52:28 +0530 Subject: drm/i915: hdcp_check_link only on CP_IRQ HDCP check link is invoked only on CP_IRQ detection, instead of all short pulses. v3: No Changes. v4: Added sean in cc and collected the reviewed-by received. v5: No Change. v6: No Change. v7: No Change. v8: Rebased. Signed-off-by: Ramalingam C cc: Sean Paul Reviewed-by: Uma Shankar Reviewed-by: Sean Paul Reviewed-by: Daniel Vetter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1540286550-20399-3-git-send-email-ramalingam.c@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8c38efef77a1..39957c82d710 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4530,8 +4530,11 @@ static void intel_dp_check_service_irq(struct intel_dp *intel_dp) if (val & DP_AUTOMATED_TEST_REQUEST) intel_dp_handle_test_request(intel_dp); - if (val & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) - DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); + if (val & DP_CP_IRQ) + intel_hdcp_check_link(intel_dp->attached_connector); + + if (val & DP_SINK_SPECIFIC_IRQ) + DRM_DEBUG_DRIVER("Sink specific irq unhandled\n"); } /* @@ -5697,9 +5700,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) handled = intel_dp_short_pulse(intel_dp); - /* Short pulse can signify loss of hdcp authentication */ - intel_hdcp_check_link(intel_dp->attached_connector); - if (!handled) goto put_power; } -- cgit v1.2.3 From 3aae21fc2ed4e2b6b417e81a0d39bfa590e8510d Mon Sep 17 00:00:00 2001 From: Ramalingam C Date: Tue, 23 Oct 2018 16:11:28 +0530 Subject: drm/i915: Move the DDC/AUX failure msgs to debug log When a HDCP authentication is in progress, if the display sink is hot unplugged, all DDC/AUX transaction related to the HDCP authentication will fail. This patch moves those kind of HDCP DDC/AUX failures into the debug logs instead of errors. v2: Bksv invalid state is provided as debug msg Signed-off-by: Ramalingam C Reviewed-by: Daniel Vetter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1540291288-22185-1-git-send-email-ramalingam.c@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 39957c82d710..8e64f149ab09 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5350,7 +5350,8 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port, dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN, an, DRM_HDCP_AN_LEN); if (dpcd_ret != DRM_HDCP_AN_LEN) { - DRM_ERROR("Failed to write An over DP/AUX (%zd)\n", dpcd_ret); + DRM_DEBUG_KMS("Failed to write An over DP/AUX (%zd)\n", + dpcd_ret); return dpcd_ret >= 0 ? -EIO : dpcd_ret; } @@ -5366,10 +5367,10 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port, rxbuf, sizeof(rxbuf), DP_AUX_CH_CTL_AUX_AKSV_SELECT); if (ret < 0) { - DRM_ERROR("Write Aksv over DP/AUX failed (%d)\n", ret); + DRM_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret); return ret; } else if (ret == 0) { - DRM_ERROR("Aksv write over DP/AUX was empty\n"); + DRM_DEBUG_KMS("Aksv write over DP/AUX was empty\n"); return -EIO; } @@ -5384,7 +5385,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv, DRM_HDCP_KSV_LEN); if (ret != DRM_HDCP_KSV_LEN) { - DRM_ERROR("Read Bksv from DP/AUX failed (%zd)\n", ret); + DRM_DEBUG_KMS("Read Bksv from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret; } return 0; @@ -5402,7 +5403,7 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port, ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO, bstatus, DRM_HDCP_BSTATUS_LEN); if (ret != DRM_HDCP_BSTATUS_LEN) { - DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret); + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret; } return 0; @@ -5417,7 +5418,7 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port, ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS, bcaps, 1); if (ret != 1) { - DRM_ERROR("Read bcaps from DP/AUX failed (%zd)\n", ret); + DRM_DEBUG_KMS("Read bcaps from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret; } @@ -5447,7 +5448,7 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port, ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME, ri_prime, DRM_HDCP_RI_LEN); if (ret != DRM_HDCP_RI_LEN) { - DRM_ERROR("Read Ri' from DP/AUX failed (%zd)\n", ret); + DRM_DEBUG_KMS("Read Ri' from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret; } return 0; @@ -5462,7 +5463,7 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port, ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, &bstatus, 1); if (ret != 1) { - DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret); + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret; } *ksv_ready = bstatus & DP_BSTATUS_READY; @@ -5484,8 +5485,8 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port, ksv_fifo + i * DRM_HDCP_KSV_LEN, len); if (ret != len) { - DRM_ERROR("Read ksv[%d] from DP/AUX failed (%zd)\n", i, - ret); + DRM_DEBUG_KMS("Read ksv[%d] from DP/AUX failed (%zd)\n", + i, ret); return ret >= 0 ? -EIO : ret; } } @@ -5505,7 +5506,7 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port, DP_AUX_HDCP_V_PRIME(i), part, DRM_HDCP_V_PRIME_PART_LEN); if (ret != DRM_HDCP_V_PRIME_PART_LEN) { - DRM_ERROR("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret); + DRM_DEBUG_KMS("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret); return ret >= 0 ? -EIO : ret; } return 0; @@ -5528,7 +5529,7 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port) ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS, &bstatus, 1); if (ret != 1) { - DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret); + DRM_DEBUG_KMS("Read bstatus from DP/AUX failed (%zd)\n", ret); return false; } -- cgit v1.2.3 From 9e7833758b9feebc37b9988d13b017534c90a4a2 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 26 Oct 2018 12:51:42 -0700 Subject: drm/i915: Prefer IS_GEN check with bitmask. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whenever possible we should stick with IS_GEN checks. Bitmaks has been introduced on commit ae7617f0ef18 ("drm/i915: Allow optimized platform checks") for efficiency. Let's stick with it whenever possible. This patch was generated with coccinelle: spatch -sp_file is_gen.cocci *{c,h} --in-place is_gen.cocci: @gen2@ expression e; @@ -INTEL_GEN(e) == 2 +IS_GEN2(e) @gen3@ expression e; @@ -INTEL_GEN(e) == 3 +IS_GEN3(e) @gen4@ expression e; @@ -INTEL_GEN(e) == 4 +IS_GEN4(e) @gen5@ expression e; @@ -INTEL_GEN(e) == 5 +IS_GEN5(e) @gen6@ expression e; @@ -INTEL_GEN(e) == 6 +IS_GEN6(e) @gen7@ expression e; @@ -INTEL_GEN(e) == 7 +IS_GEN7(e) @gen8@ expression e; @@ -INTEL_GEN(e) == 8 +IS_GEN8(e) @gen9@ expression e; @@ -INTEL_GEN(e) == 9 +IS_GEN9(e) @gen10@ expression e; @@ -INTEL_GEN(e) == 10 +IS_GEN10(e) @gen11@ expression e; @@ -INTEL_GEN(e) == 11 +IS_GEN11(e) Cc: Tvrtko Ursulin Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181026195143.20353-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8e64f149ab09..6b37d66194a3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -455,7 +455,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) if (INTEL_GEN(dev_priv) >= 10) { source_rates = cnl_rates; size = ARRAY_SIZE(cnl_rates); - if (INTEL_GEN(dev_priv) == 10) + if (IS_GEN10(dev_priv)) max_rate = cnl_max_source_rate(intel_dp); else max_rate = icl_max_source_rate(intel_dp); -- cgit v1.2.3 From 93ac092f054b25e41341b008fdb1ac69c9a8334c Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 30 Oct 2018 17:19:19 -0700 Subject: drm/i915/dp: Cache the DP/eDP DSC DPCD register set on Hotplug/eDP Init DSC is supported on eDP starting GEN 10 display (on GLK) and on DP starting GEN 11. This patch implements the discovery phase of DSC. On hotplug, source reads the DSC DPCD register set (0x00060 - 0x0006F) to read the decompression capabilities of the sink device. This entire block of registers is cached in intel_dp so that capability information can be used during DSC configuration phase during compute_config phase of the modeset. For eDP, this caching happens during the eDP initialization. This caching is done only for eDP and DP rev >= 1.4 v5: * Fix the block comment (Gaurav) * Fix the commit message DSC DPCD addresses (Gaurav) * Use DRM_ERROR for dpcd_read fail (Gaurav,Anusha) v4: * Cache these only for Gen >= 11 v3: * Remove the dsc_sink_support field in intel_dp (Jani N) v2: * Clear the cached registers on hotplug always (Jani N) * Combine the eDP and DP caching in same function (Jani N) Cc: Jani Nikula Cc: Ville Syrjala Cc: Daniel Vetter Cc: Anusha Srivatsa Cc: Gaurav K Singh Signed-off-by: Manasi Navare Reviewed-by: Anusha Srivatsa Reviewed-by: Gaurav K Singh Link: https://patchwork.freedesktop.org/patch/msgid/20181031001923.31442-3-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6b37d66194a3..eb3fada0c857 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3956,6 +3956,29 @@ intel_dp_read_dpcd(struct intel_dp *intel_dp) return intel_dp->dpcd[DP_DPCD_REV] != 0; } +static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp) +{ + /* + * Clear the cached register set to avoid using stale values + * for the sinks that do not support DSC. + */ + memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd)); + + /* Cache the DSC DPCD if eDP or DP rev >= 1.4 */ + if (intel_dp->dpcd[DP_DPCD_REV] >= 0x14 || + intel_dp->edp_dpcd[0] >= DP_EDP_14) { + if (drm_dp_dpcd_read(&intel_dp->aux, DP_DSC_SUPPORT, + intel_dp->dsc_dpcd, + sizeof(intel_dp->dsc_dpcd)) < 0) + DRM_ERROR("Failed to read DPCD register 0x%x\n", + DP_DSC_SUPPORT); + + DRM_DEBUG_KMS("DSC DPCD: %*ph\n", + (int)sizeof(intel_dp->dsc_dpcd), + intel_dp->dsc_dpcd); + } +} + static bool intel_edp_init_dpcd(struct intel_dp *intel_dp) { @@ -4032,6 +4055,10 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) intel_dp_set_common_rates(intel_dp); + /* Read the eDP DSC DPCD registers */ + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) + intel_dp_get_dsc_sink_cap(intel_dp); + return true; } @@ -5126,6 +5153,7 @@ intel_dp_detect(struct drm_connector *connector, if (status == connector_status_disconnected) { memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance)); + memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd)); if (intel_dp->is_mst) { DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", @@ -5151,6 +5179,10 @@ intel_dp_detect(struct drm_connector *connector, intel_dp_print_rates(intel_dp); + /* Read DP Sink DSC Cap DPCD regs for DP v1.4 */ + if (INTEL_GEN(dev_priv) >= 11) + intel_dp_get_dsc_sink_cap(intel_dp); + drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc, drm_dp_is_branch(intel_dp->dpcd)); -- cgit v1.2.3 From d9218c8f6cf43bc0db5422e6b05b9e487c400a23 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 30 Oct 2018 17:19:21 -0700 Subject: drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC This patch adds helpers for calculating the maximum compressed BPP supported with small joiner. This also adds a helper for calculating the slice count in case of small joiner. These are inside intel_dp since they take into account hardware limitations. v6: * Take mode_clock and mode_hdisplay as input arguments so that this can be called in intel_dp_mode_valid (Manasi) v5: * Get the max slice width from DPCD * Check against Min_Slice_width of 2560 (Anusha) v4: * #defines for PPR in slice count helper (Gaurav) v3: * Simply logic for bpp (DK) * Limit the valid slice count by max supported by Sink (Manasi) v2: * Change the small joiner RAM buffer constant as bspec changed (Manasi) * rename it as SMALL_JOINER since we are not enabling big joiner yet (Anusha) Cc: Gaurav K Singh Cc: Jani Nikula Cc: Ville Syrjala Cc: Anusha Srivatsa Cc: Dhinakaran Pandiyan Signed-off-by: Manasi Navare Reviewed-by: Anusha Srivatsa Reviewed-by: Gaurav K Singh Link: https://patchwork.freedesktop.org/patch/msgid/20181031001923.31442-5-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 104 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index eb3fada0c857..11412b21a1c7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -45,6 +45,17 @@ #define DP_DPRX_ESI_LEN 14 +/* DP DSC small joiner has 2 FIFOs each of 640 x 6 bytes */ +#define DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER 61440 + +/* DP DSC throughput values used for slice count calculations KPixels/s */ +#define DP_DSC_PEAK_PIXEL_RATE 2720000 +#define DP_DSC_MAX_ENC_THROUGHPUT_0 340000 +#define DP_DSC_MAX_ENC_THROUGHPUT_1 400000 + +/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */ +#define DP_DSC_FEC_OVERHEAD_FACTOR 976 + /* Compliance test status bits */ #define INTEL_DP_RESOLUTION_SHIFT_MASK 0 #define INTEL_DP_RESOLUTION_PREFERRED (1 << INTEL_DP_RESOLUTION_SHIFT_MASK) @@ -93,6 +104,14 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } }, }; +/* Constants for DP DSC configurations */ +static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15}; + +/* With Single pipe configuration, HW is capable of supporting maximum + * of 4 slices per line. + */ +static const u8 valid_dsc_slicecount[] = {1, 2, 4}; + /** * intel_dp_is_edp - is the given port attached to an eDP panel (either CPU or PCH) * @intel_dp: DP struct @@ -4162,6 +4181,91 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) DP_DPRX_ESI_LEN; } +u16 intel_dp_dsc_get_output_bpp(int link_clock, uint8_t lane_count, + int mode_clock, int mode_hdisplay) +{ + u16 bits_per_pixel, max_bpp_small_joiner_ram; + int i; + + /* + * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* + * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP) + * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1, + * for MST -> TimeSlotsPerMTP has to be calculated + */ + bits_per_pixel = (link_clock * lane_count * 8 * + DP_DSC_FEC_OVERHEAD_FACTOR) / + mode_clock; + + /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ + max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / + mode_hdisplay; + + /* + * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW + * check, output bpp from small joiner RAM check) + */ + bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram); + + /* Error out if the max bpp is less than smallest allowed valid bpp */ + if (bits_per_pixel < valid_dsc_bpp[0]) { + DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel); + return 0; + } + + /* Find the nearest match in the array of known BPPs from VESA */ + for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { + if (bits_per_pixel < valid_dsc_bpp[i + 1]) + break; + } + bits_per_pixel = valid_dsc_bpp[i]; + + /* + * Compressed BPP in U6.4 format so multiply by 16, for Gen 11, + * fractional part is 0 + */ + return bits_per_pixel << 4; +} + +u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, + int mode_clock, + int mode_hdisplay) +{ + u8 min_slice_count, i; + int max_slice_width; + + if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE) + min_slice_count = DIV_ROUND_UP(mode_clock, + DP_DSC_MAX_ENC_THROUGHPUT_0); + else + min_slice_count = DIV_ROUND_UP(mode_clock, + DP_DSC_MAX_ENC_THROUGHPUT_1); + + max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd); + if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) { + DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n", + max_slice_width); + return 0; + } + /* Also take into account max slice width */ + min_slice_count = min_t(uint8_t, min_slice_count, + DIV_ROUND_UP(mode_hdisplay, + max_slice_width)); + + /* Find the closest match to the valid slice count values */ + for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) { + if (valid_dsc_slicecount[i] > + drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, + false)) + break; + if (min_slice_count <= valid_dsc_slicecount[i]) + return valid_dsc_slicecount[i]; + } + + DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count); + return 0; +} + static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp) { int status = 0; -- cgit v1.2.3 From 6cfd04b018f0a37e6d499ffd8382ff93c3f80798 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 30 Oct 2018 17:19:22 -0700 Subject: drm/i915/dp: Validate modes using max Output BPP and slice count when DSC supported When DSC is supported we need to validate the modes based on the maximum supported compressed BPP and maximum supported slice count. This allows us to allow the modes with pixel clock greater than the available link BW as long as it meets the compressed BPP and slice count requirements. v3: * Use the macro for dsc sink support (Jani N) v2: * Properly comment why we are right shifting the bpp value (Anusha) Cc: Gaurav K Singh Cc: Jani Nikula Cc: Ville Syrjala Cc: Anusha Srivatsa Signed-off-by: Manasi Navare Reviewed-by: Anusha Srivatsa Reviewed-by: Gaurav K Singh Link: https://patchwork.freedesktop.org/patch/msgid/20181031001923.31442-6-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 11412b21a1c7..03b8e5104ead 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -635,9 +635,12 @@ intel_dp_mode_valid(struct drm_connector *connector, struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; + struct drm_i915_private *dev_priv = to_i915(connector->dev); int target_clock = mode->clock; int max_rate, mode_rate, max_lanes, max_link_clock; int max_dotclk; + u16 dsc_max_output_bpp = 0; + u8 dsc_slice_count = 0; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -660,7 +663,33 @@ intel_dp_mode_valid(struct drm_connector *connector, max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); mode_rate = intel_dp_link_required(target_clock, 18); - if (mode_rate > max_rate || target_clock > max_dotclk) + /* + * Output bpp is stored in 6.4 format so right shift by 4 to get the + * integer value since we support only integer values of bpp. + */ + if ((INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) && + drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) { + if (intel_dp_is_edp(intel_dp)) { + dsc_max_output_bpp = + drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; + dsc_slice_count = + drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, + true); + } else { + dsc_max_output_bpp = + intel_dp_dsc_get_output_bpp(max_link_clock, + max_lanes, + target_clock, + mode->hdisplay) >> 4; + dsc_slice_count = + intel_dp_dsc_get_slice_count(intel_dp, + target_clock, + mode->hdisplay); + } + } + + if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) || + target_clock > max_dotclk) return MODE_CLOCK_HIGH; if (mode->clock < 10000) -- cgit v1.2.3 From b298ba5f51fca1c8204ec7448eb767fafb899ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Tue, 30 Oct 2018 14:57:47 -0700 Subject: drm/i915/icl: Set TC type to unknown in the disconnection flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise it would be in a inconsistent state as port is disconnected but with a valid tc type. Also setting it to unknown will earlier return icl_tc_phy_disconnect() for any future calls to intel_digital_port_connected(), this way we don't need to check if port is marked as safe everytime. Cc: Paulo Zanoni Reviewed-by: Ville Syrjälä Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181030215750.28213-2-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 03b8e5104ead..5973f77f9740 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5102,21 +5102,24 @@ static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv, struct intel_digital_port *dig_port) { enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port); - u32 val; - if (dig_port->tc_type != TC_PORT_LEGACY && - dig_port->tc_type != TC_PORT_TYPEC) + if (dig_port->tc_type == TC_PORT_UNKNOWN) return; /* - * This function may be called many times in a row without an HPD event - * in between, so try to avoid the write when we can. + * TBT disconnection flow is read the live status, what was done in + * caller. */ - val = I915_READ(PORT_TX_DFLEXDPCSSS); - if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) { + if (dig_port->tc_type == TC_PORT_TYPEC || + dig_port->tc_type == TC_PORT_LEGACY) { + u32 val; + + val = I915_READ(PORT_TX_DFLEXDPCSSS); val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port); I915_WRITE(PORT_TX_DFLEXDPCSSS, val); } + + dig_port->tc_type = TC_PORT_UNKNOWN; } /* -- cgit v1.2.3 From d1b5973c877856d24e4453a498145e5f5eb1d9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Tue, 30 Oct 2018 14:57:48 -0700 Subject: drm/i915/icl: Set TC type to unknown when a sudden disconnection happen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise it would be in a inconsistent state as port is disconnected but with a valid tc type. Cc: Paulo Zanoni Reviewed-by: Ville Syrjälä Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181030215750.28213-3-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5973f77f9740..5762a284c3ee 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5031,6 +5031,9 @@ static void icl_update_tc_port_type(struct drm_i915_private *dev_priv, type_str); } +static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv, + struct intel_digital_port *dig_port); + /* * This function implements the first part of the Connect Flow described by our * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading @@ -5085,9 +5088,7 @@ static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv, if (dig_port->tc_type == TC_PORT_TYPEC && !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) { DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port); - val = I915_READ(PORT_TX_DFLEXDPCSSS); - val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port); - I915_WRITE(PORT_TX_DFLEXDPCSSS, val); + icl_tc_phy_disconnect(dev_priv, dig_port); return false; } -- cgit v1.2.3 From 36b80aa36b63117f99626e60ee50435e5b02a77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Tue, 30 Oct 2018 14:57:49 -0700 Subject: drm/i915: Initialize panel_vdd_work only for eDP ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is only used by eDP ports so no need to initialize it for each DP port. Reviewed-by: Ville Syrjälä Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181030215750.28213-4-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5762a284c3ee..9a2db61c1ba7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6587,6 +6587,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (!intel_dp_is_edp(intel_dp)) return true; + INIT_DELAYED_WORK(&intel_dp->panel_vdd_work, edp_panel_vdd_work); + /* * On IBX/CPT we may get here with LVDS already registered. Since the * driver uses the only internal power sequencer available for both @@ -6793,9 +6795,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, intel_dp_aux_init(intel_dp); - INIT_DELAYED_WORK(&intel_dp->panel_vdd_work, - edp_panel_vdd_work); - intel_connector_attach_encoder(intel_connector, intel_encoder); if (HAS_DDI(dev_priv)) -- cgit v1.2.3 From 15d248ae374a0e1672b79ddaa2596e6166641b7c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 1 Nov 2018 16:04:20 +0200 Subject: drm/i915: Move intel_aux_ch() to intel_bios.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From ICL onwards all the DDI/TypeC ports - even working in HDMI mode - need to know their corresponding AUX channel, so move the corresponding helper to a common place. No functional change. v4: - Fix 'no space is necessary after a cast' checkpatch warn. Cc: Paulo Zanoni Cc: Ville Syrjälä Cc: José Roberto de Souza Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181101140427.31026-2-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 50 +---------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9a2db61c1ba7..ec0ae1f7a187 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1551,54 +1551,6 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) return ret; } -static enum aux_ch intel_aux_ch(struct intel_dp *intel_dp) -{ - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum port port = encoder->port; - const struct ddi_vbt_port_info *info = - &dev_priv->vbt.ddi_port_info[port]; - enum aux_ch aux_ch; - - if (!info->alternate_aux_channel) { - aux_ch = (enum aux_ch) port; - - DRM_DEBUG_KMS("using AUX %c for port %c (platform default)\n", - aux_ch_name(aux_ch), port_name(port)); - return aux_ch; - } - - switch (info->alternate_aux_channel) { - case DP_AUX_A: - aux_ch = AUX_CH_A; - break; - case DP_AUX_B: - aux_ch = AUX_CH_B; - break; - case DP_AUX_C: - aux_ch = AUX_CH_C; - break; - case DP_AUX_D: - aux_ch = AUX_CH_D; - break; - case DP_AUX_E: - aux_ch = AUX_CH_E; - break; - case DP_AUX_F: - aux_ch = AUX_CH_F; - break; - default: - MISSING_CASE(info->alternate_aux_channel); - aux_ch = AUX_CH_A; - break; - } - - DRM_DEBUG_KMS("using AUX %c for port %c (VBT)\n", - aux_ch_name(aux_ch), port_name(port)); - - return aux_ch; -} - static enum intel_display_power_domain intel_aux_power_domain(struct intel_dp *intel_dp) { @@ -1739,7 +1691,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - intel_dp->aux_ch = intel_aux_ch(intel_dp); + intel_dp->aux_ch = intel_aux_ch(dev_priv, encoder->port); intel_dp->aux_power_domain = intel_aux_power_domain(intel_dp); if (INTEL_GEN(dev_priv) >= 9) { -- cgit v1.2.3 From 563d22a0394856a5d984c48b94312ef614fce841 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 1 Nov 2018 16:04:21 +0200 Subject: drm/i915: Move aux_ch to intel_digital_port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From ICL onwards all DDI/TypeC ports - even working in HDMI mode - need to know their corresponding AUX CH, so move the field to a common struct. No functional change. v3: - Add code comment about which ports aux_ch is used for. (Jose) Cc: Paulo Zanoni Cc: Ville Syrjälä Cc: José Roberto de Souza Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181101140427.31026-3-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ec0ae1f7a187..0cfc727c2c7d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1204,6 +1204,7 @@ static uint32_t g4x_get_aux_clock_divider(struct intel_dp *intel_dp, int index) static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); if (index) return 0; @@ -1213,7 +1214,7 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) * like to run at 2MHz. So, take the cdclk or PCH rawclk value and * divide by 2000 and use that */ - if (intel_dp->aux_ch == AUX_CH_A) + if (dig_port->aux_ch == AUX_CH_A) return DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.cdclk, 2000); else return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); @@ -1222,8 +1223,9 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - if (intel_dp->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(dev_priv)) { + if (dig_port->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(dev_priv)) { /* Workaround for non-ULT HSW */ switch (index) { case 0: return 63; @@ -1554,7 +1556,9 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) static enum intel_display_power_domain intel_aux_power_domain(struct intel_dp *intel_dp) { - switch (intel_dp->aux_ch) { + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + + switch (dig_port->aux_ch) { case AUX_CH_A: return POWER_DOMAIN_AUX_A; case AUX_CH_B: @@ -1568,7 +1572,7 @@ intel_aux_power_domain(struct intel_dp *intel_dp) case AUX_CH_F: return POWER_DOMAIN_AUX_F; default: - MISSING_CASE(intel_dp->aux_ch); + MISSING_CASE(dig_port->aux_ch); return POWER_DOMAIN_AUX_A; } } @@ -1576,7 +1580,8 @@ intel_aux_power_domain(struct intel_dp *intel_dp) static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum aux_ch aux_ch = intel_dp->aux_ch; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + enum aux_ch aux_ch = dig_port->aux_ch; switch (aux_ch) { case AUX_CH_B: @@ -1592,7 +1597,8 @@ static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp) static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum aux_ch aux_ch = intel_dp->aux_ch; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + enum aux_ch aux_ch = dig_port->aux_ch; switch (aux_ch) { case AUX_CH_B: @@ -1608,7 +1614,8 @@ static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index) static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum aux_ch aux_ch = intel_dp->aux_ch; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + enum aux_ch aux_ch = dig_port->aux_ch; switch (aux_ch) { case AUX_CH_A: @@ -1626,7 +1633,8 @@ static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp) static i915_reg_t ilk_aux_data_reg(struct intel_dp *intel_dp, int index) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum aux_ch aux_ch = intel_dp->aux_ch; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + enum aux_ch aux_ch = dig_port->aux_ch; switch (aux_ch) { case AUX_CH_A: @@ -1644,7 +1652,8 @@ static i915_reg_t ilk_aux_data_reg(struct intel_dp *intel_dp, int index) static i915_reg_t skl_aux_ctl_reg(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum aux_ch aux_ch = intel_dp->aux_ch; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + enum aux_ch aux_ch = dig_port->aux_ch; switch (aux_ch) { case AUX_CH_A: @@ -1663,7 +1672,8 @@ static i915_reg_t skl_aux_ctl_reg(struct intel_dp *intel_dp) static i915_reg_t skl_aux_data_reg(struct intel_dp *intel_dp, int index) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum aux_ch aux_ch = intel_dp->aux_ch; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + enum aux_ch aux_ch = dig_port->aux_ch; switch (aux_ch) { case AUX_CH_A: @@ -1689,9 +1699,10 @@ static void intel_dp_aux_init(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *encoder = &dig_port->base; - intel_dp->aux_ch = intel_aux_ch(dev_priv, encoder->port); + dig_port->aux_ch = intel_aux_ch(dev_priv, encoder->port); intel_dp->aux_power_domain = intel_aux_power_domain(intel_dp); if (INTEL_GEN(dev_priv) >= 9) { -- cgit v1.2.3 From ac897d6bd7035390d621c283769b19a488ee15bc Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 1 Nov 2018 16:04:22 +0200 Subject: drm/i915: Init aux_ch for HDMI ports too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From ICL onwards DDI/TypeC ports - even in HDMI static mode - need to know which AUX CH belongs to them, so initialize aux_ch for those ports too. For consistency do this for all HDMI ports, not only for DDI/TypeC ones. Cc: Paulo Zanoni Cc: Ville Syrjälä Cc: José Roberto de Souza Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181101140427.31026-4-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0cfc727c2c7d..552bb3d69ed0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1702,7 +1702,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp) struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - dig_port->aux_ch = intel_aux_ch(dev_priv, encoder->port); intel_dp->aux_power_domain = intel_aux_power_domain(intel_dp); if (INTEL_GEN(dev_priv) >= 9) { @@ -6874,6 +6873,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, if (port != PORT_A) intel_infoframe_init(intel_dig_port); + intel_dig_port->aux_ch = intel_aux_ch(dev_priv, port); if (!intel_dp_init_connector(intel_dig_port, intel_connector)) goto err_init_connector; -- cgit v1.2.3 From 337837ac3a75f126b53a522bebf2d8b3e82b105b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 1 Nov 2018 16:04:23 +0200 Subject: drm/i915: Use a helper to get the aux power domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From ICL onwards the AUX power domain may change dynamically based on whether a DDI/TypeC port is in thunderbolt or non-thunderbolt mode, so use a helper function instead of a static field to get the current domain. Cc: Paulo Zanoni Cc: Ville Syrjälä Cc: José Roberto de Souza Cc: Lucas De Marchi Cc: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181101140427.31026-5-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 73 +++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 42 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 552bb3d69ed0..b39b4bda8e40 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -738,7 +738,8 @@ static void pps_lock(struct intel_dp *intel_dp) * See intel_power_sequencer_reset() why we need * a power domain reference here. */ - intel_display_power_get(dev_priv, intel_dp->aux_power_domain); + intel_display_power_get(dev_priv, + intel_aux_power_domain(dp_to_dig_port(intel_dp))); mutex_lock(&dev_priv->pps_mutex); } @@ -749,7 +750,8 @@ static void pps_unlock(struct intel_dp *intel_dp) mutex_unlock(&dev_priv->pps_mutex); - intel_display_power_put(dev_priv, intel_dp->aux_power_domain); + intel_display_power_put(dev_priv, + intel_aux_power_domain(dp_to_dig_port(intel_dp))); } static void @@ -1553,29 +1555,6 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) return ret; } -static enum intel_display_power_domain -intel_aux_power_domain(struct intel_dp *intel_dp) -{ - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - - switch (dig_port->aux_ch) { - case AUX_CH_A: - return POWER_DOMAIN_AUX_A; - case AUX_CH_B: - return POWER_DOMAIN_AUX_B; - case AUX_CH_C: - return POWER_DOMAIN_AUX_C; - case AUX_CH_D: - return POWER_DOMAIN_AUX_D; - case AUX_CH_E: - return POWER_DOMAIN_AUX_E; - case AUX_CH_F: - return POWER_DOMAIN_AUX_F; - default: - MISSING_CASE(dig_port->aux_ch); - return POWER_DOMAIN_AUX_A; - } -} static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp) { @@ -1702,8 +1681,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp) struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - intel_dp->aux_power_domain = intel_aux_power_domain(intel_dp); - if (INTEL_GEN(dev_priv) >= 9) { intel_dp->aux_ch_ctl_reg = skl_aux_ctl_reg; intel_dp->aux_ch_data_reg = skl_aux_data_reg; @@ -2404,7 +2381,8 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) if (edp_have_panel_vdd(intel_dp)) return need_to_disable; - intel_display_power_get(dev_priv, intel_dp->aux_power_domain); + intel_display_power_get(dev_priv, + intel_aux_power_domain(intel_dig_port)); DRM_DEBUG_KMS("Turning eDP port %c VDD on\n", port_name(intel_dig_port->base.port)); @@ -2490,7 +2468,8 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) if ((pp & PANEL_POWER_ON) == 0) intel_dp->panel_power_off_time = ktime_get_boottime(); - intel_display_power_put(dev_priv, intel_dp->aux_power_domain); + intel_display_power_put(dev_priv, + intel_aux_power_domain(intel_dig_port)); } static void edp_panel_vdd_work(struct work_struct *__work) @@ -2603,6 +2582,7 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) static void edp_panel_off(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); u32 pp; i915_reg_t pp_ctrl_reg; @@ -2612,10 +2592,10 @@ static void edp_panel_off(struct intel_dp *intel_dp) return; DRM_DEBUG_KMS("Turn eDP port %c panel power off\n", - port_name(dp_to_dig_port(intel_dp)->base.port)); + port_name(dig_port->base.port)); WARN(!intel_dp->want_panel_vdd, "Need eDP port %c VDD to turn off panel\n", - port_name(dp_to_dig_port(intel_dp)->base.port)); + port_name(dig_port->base.port)); pp = ironlake_get_pp_control(intel_dp); /* We need to switch off panel power _and_ force vdd, for otherwise some @@ -2634,7 +2614,7 @@ static void edp_panel_off(struct intel_dp *intel_dp) intel_dp->panel_power_off_time = ktime_get_boottime(); /* We got a reference when we enabled the VDD. */ - intel_display_power_put(dev_priv, intel_dp->aux_power_domain); + intel_display_power_put(dev_priv, intel_aux_power_domain(dig_port)); } void intel_edp_panel_off(struct intel_dp *intel_dp) @@ -5233,14 +5213,17 @@ intel_dp_detect(struct drm_connector *connector, { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_dp *intel_dp = intel_attached_dp(connector); - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *encoder = &dig_port->base; enum drm_connector_status status; + enum intel_display_power_domain aux_domain = + intel_aux_power_domain(dig_port); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); - intel_display_power_get(dev_priv, intel_dp->aux_power_domain); + intel_display_power_get(dev_priv, aux_domain); /* Can't disconnect eDP */ if (intel_dp_is_edp(intel_dp)) @@ -5307,7 +5290,7 @@ intel_dp_detect(struct drm_connector *connector, ret = intel_dp_retrain_link(encoder, ctx); if (ret) { intel_display_power_put(dev_priv, - intel_dp->aux_power_domain); + intel_aux_power_domain(dig_port)); return ret; } } @@ -5331,7 +5314,7 @@ out: if (status != connector_status_connected && !intel_dp->is_mst) intel_dp_unset_edid(intel_dp); - intel_display_power_put(dev_priv, intel_dp->aux_power_domain); + intel_display_power_put(dev_priv, aux_domain); return status; } @@ -5339,8 +5322,11 @@ static void intel_dp_force(struct drm_connector *connector) { struct intel_dp *intel_dp = intel_attached_dp(connector); - struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *intel_encoder = &dig_port->base; struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); + enum intel_display_power_domain aux_domain = + intel_aux_power_domain(dig_port); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -5349,11 +5335,11 @@ intel_dp_force(struct drm_connector *connector) if (connector->status != connector_status_connected) return; - intel_display_power_get(dev_priv, intel_dp->aux_power_domain); + intel_display_power_get(dev_priv, aux_domain); intel_dp_set_edid(intel_dp); - intel_display_power_put(dev_priv, intel_dp->aux_power_domain); + intel_display_power_put(dev_priv, aux_domain); } static int intel_dp_get_modes(struct drm_connector *connector) @@ -5699,6 +5685,7 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = { static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); lockdep_assert_held(&dev_priv->pps_mutex); @@ -5712,7 +5699,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) * indefinitely. */ DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n"); - intel_display_power_get(dev_priv, intel_dp->aux_power_domain); + intel_display_power_get(dev_priv, intel_aux_power_domain(dig_port)); edp_panel_vdd_schedule_off(intel_dp); } @@ -5810,7 +5797,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) return IRQ_NONE; } - intel_display_power_get(dev_priv, intel_dp->aux_power_domain); + intel_display_power_get(dev_priv, + intel_aux_power_domain(intel_dig_port)); if (intel_dp->is_mst) { if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { @@ -5839,7 +5827,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) ret = IRQ_HANDLED; put_power: - intel_display_power_put(dev_priv, intel_dp->aux_power_domain); + intel_display_power_put(dev_priv, + intel_aux_power_domain(intel_dig_port)); return ret; } -- cgit v1.2.3 From f1a1217222a24775eaaafbcbd386101dc44f8a81 Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Mon, 22 Oct 2018 18:44:00 -0700 Subject: drm/i915: Allow "max bpc" property to limit pipe_bpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the newly added "max bpc" connector property to limit pipe bpp. V3: Use drm_connector_state to access the "max bpc" property V4: Initialize the drm property, add suuport to DP(Ville) V5: Use the property in the connector and fix CI failure(Ville) V6: Use the core function to attach max_bpc property, remove the redundant clamping of pipe bpp based on connector info V7: Fix Checkpatch warnings V9: Cleanup connected_sink_max_bpp and fix initial value in DP(Ville) V12: Fix debug message(Ville) V13: Remove the redundant check and simplify the check logic(Stan) V14: Fix the check in connected_sink_max_bpp(Stan) v15 (From Manasi): Add missing break (Stan) Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Rodrigo Vivi Cc: Kishore Kadiyala Cc: Manasi Navare Cc: Stanislav Lisovskiy Signed-off-by: Radhakrishna Sripada Reviewed-by: Stanislav Lisovskiy Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20181023014400.16055-1-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b39b4bda8e40..e7233dfa1794 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5859,6 +5859,10 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); + if (HAS_GMCH_DISPLAY(dev_priv)) + drm_connector_attach_max_bpc_property(connector, 6, 10); + else if (INTEL_GEN(dev_priv) >= 5) + drm_connector_attach_max_bpc_property(connector, 6, 12); if (intel_dp_is_edp(intel_dp)) { u32 allowed_scalers; -- cgit v1.2.3 From 08cadae8e1570c069f639a86fe4370485094552c Mon Sep 17 00:00:00 2001 From: Anusha Srivatsa Date: Thu, 1 Nov 2018 21:14:54 -0700 Subject: i915/dp/fec: Cache the FEC_CAPABLE DPCD register Similar to DSC DPCD registers, let us cache FEC_CAPABLE register to avoid using stale values. With this we can avoid aux reads everytime and instead read the cached values. v2: Avoid using memset and array for a single field. (Manasi,Jani) v3: Print FEC CAPABILITY value. (Manasi) Suggested-by: Jani Nikula Cc: Jani Nikula Cc: Ville Syrjala Cc: Manasi Navare Signed-off-by: Anusha Srivatsa Reviewed-by: Manasi Navare Signed-off-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20181102041455.15818-1-anusha.srivatsa@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e7233dfa1794..d6ee11525dd9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3954,6 +3954,9 @@ static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp) */ memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd)); + /* Clear fec_capable to avoid using stale values */ + intel_dp->fec_capable = 0; + /* Cache the DSC DPCD if eDP or DP rev >= 1.4 */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x14 || intel_dp->edp_dpcd[0] >= DP_EDP_14) { @@ -3966,6 +3969,15 @@ static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp) DRM_DEBUG_KMS("DSC DPCD: %*ph\n", (int)sizeof(intel_dp->dsc_dpcd), intel_dp->dsc_dpcd); + /* FEC is supported only on DP 1.4 */ + if (!intel_dp_is_edp(intel_dp)) { + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY, + &intel_dp->fec_capable) < 0) + DRM_ERROR("Failed to read FEC DPCD register\n"); + + DRM_DEBUG_KMS("FEC CAPABILITY: %x\n", + intel_dp->fec_capable); + } } } -- cgit v1.2.3 From cb9ff519439bb79b4f917008f26e5000076d48a3 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 2 Nov 2018 21:26:55 +0200 Subject: drm/i915/icl: Configure MG PHY gating for HDMI ports too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MG PHY clock gating needs to be configured for Type C static/fixed/legacy HDMI ports the same way it's configured for Type C static/fixed/legacy and aternate mode DP ports, fix this. Bspec: 4232, 21735 Cc: Vandita Kulkarni Cc: Paulo Zanoni Cc: Maarten Lankhorst Cc: Manasi Navare Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Tested-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20181102192656.4472-2-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 66 ----------------------------------------- 1 file changed, 66 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d6ee11525dd9..a057ef8d92a0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -307,72 +307,6 @@ void icl_program_mg_dp_mode(struct intel_dp *intel_dp) I915_WRITE(MG_DP_MODE(port, 1), ln1); } -void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); - enum port port = dig_port->base.port; - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); - i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; - u32 val; - int i; - - if (tc_port == PORT_TC_NONE) - return; - - for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { - val = I915_READ(mg_regs[i]); - val |= MG_DP_MODE_CFG_TR2PWR_GATING | - MG_DP_MODE_CFG_TRPWR_GATING | - MG_DP_MODE_CFG_CLNPWR_GATING | - MG_DP_MODE_CFG_DIGPWR_GATING | - MG_DP_MODE_CFG_GAONPWR_GATING; - I915_WRITE(mg_regs[i], val); - } - - val = I915_READ(MG_MISC_SUS0(tc_port)); - val |= MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(3) | - MG_MISC_SUS0_CFG_TR2PWR_GATING | - MG_MISC_SUS0_CFG_CL2PWR_GATING | - MG_MISC_SUS0_CFG_GAONPWR_GATING | - MG_MISC_SUS0_CFG_TRPWR_GATING | - MG_MISC_SUS0_CFG_CL1PWR_GATING | - MG_MISC_SUS0_CFG_DGPWR_GATING; - I915_WRITE(MG_MISC_SUS0(tc_port), val); -} - -void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); - enum port port = dig_port->base.port; - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); - i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; - u32 val; - int i; - - if (tc_port == PORT_TC_NONE) - return; - - for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { - val = I915_READ(mg_regs[i]); - val &= ~(MG_DP_MODE_CFG_TR2PWR_GATING | - MG_DP_MODE_CFG_TRPWR_GATING | - MG_DP_MODE_CFG_CLNPWR_GATING | - MG_DP_MODE_CFG_DIGPWR_GATING | - MG_DP_MODE_CFG_GAONPWR_GATING); - I915_WRITE(mg_regs[i], val); - } - - val = I915_READ(MG_MISC_SUS0(tc_port)); - val &= ~(MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK | - MG_MISC_SUS0_CFG_TR2PWR_GATING | - MG_MISC_SUS0_CFG_CL2PWR_GATING | - MG_MISC_SUS0_CFG_GAONPWR_GATING | - MG_MISC_SUS0_CFG_TRPWR_GATING | - MG_MISC_SUS0_CFG_CL1PWR_GATING | - MG_MISC_SUS0_CFG_DGPWR_GATING); - I915_WRITE(MG_MISC_SUS0(tc_port), val); -} - int intel_dp_max_data_rate(int max_link_clock, int max_lanes) { -- cgit v1.2.3 From 93b662d329d60ede951aa4cb49a3fc0a111b7223 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 2 Nov 2018 21:26:56 +0200 Subject: drm/i915/icl: Configure MG DP mode for HDMI ports too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MG DP mode needs to be configured for Type C static/fixed/legacy HDMI ports too, the same way as it's configured for Type C static/fixed/legacy, fix this. Bspec: 4232, 21735 Cc: Vandita Kulkarni Cc: Paulo Zanoni Cc: Maarten Lankhorst Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Tested-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20181102192656.4472-3-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 66 ----------------------------------------- 1 file changed, 66 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a057ef8d92a0..5258c9d654f4 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -241,72 +241,6 @@ intel_dp_link_required(int pixel_clock, int bpp) return DIV_ROUND_UP(pixel_clock * bpp, 8); } -void icl_program_mg_dp_mode(struct intel_dp *intel_dp) -{ - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - enum port port = intel_dig_port->base.port; - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); - u32 ln0, ln1, lane_info; - - if (tc_port == PORT_TC_NONE || intel_dig_port->tc_type == TC_PORT_TBT) - return; - - ln0 = I915_READ(MG_DP_MODE(port, 0)); - ln1 = I915_READ(MG_DP_MODE(port, 1)); - - switch (intel_dig_port->tc_type) { - case TC_PORT_TYPEC: - ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); - ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); - - lane_info = (I915_READ(PORT_TX_DFLEXDPSP) & - DP_LANE_ASSIGNMENT_MASK(tc_port)) >> - DP_LANE_ASSIGNMENT_SHIFT(tc_port); - - switch (lane_info) { - case 0x1: - case 0x4: - break; - case 0x2: - ln0 |= MG_DP_MODE_CFG_DP_X1_MODE; - break; - case 0x3: - ln0 |= MG_DP_MODE_CFG_DP_X1_MODE | - MG_DP_MODE_CFG_DP_X2_MODE; - break; - case 0x8: - ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; - break; - case 0xC: - ln1 |= MG_DP_MODE_CFG_DP_X1_MODE | - MG_DP_MODE_CFG_DP_X2_MODE; - break; - case 0xF: - ln0 |= MG_DP_MODE_CFG_DP_X1_MODE | - MG_DP_MODE_CFG_DP_X2_MODE; - ln1 |= MG_DP_MODE_CFG_DP_X1_MODE | - MG_DP_MODE_CFG_DP_X2_MODE; - break; - default: - MISSING_CASE(lane_info); - } - break; - - case TC_PORT_LEGACY: - ln0 |= MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE; - ln1 |= MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE; - break; - - default: - MISSING_CASE(intel_dig_port->tc_type); - return; - } - - I915_WRITE(MG_DP_MODE(port, 0), ln0); - I915_WRITE(MG_DP_MODE(port, 1), ln1); -} - int intel_dp_max_data_rate(int max_link_clock, int max_lanes) { -- cgit v1.2.3 From 6423382247e06a149b4d9138f11265f5dc317b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Wed, 7 Nov 2018 15:54:47 -0800 Subject: drm/i915: Reuse the aux_domain cached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp_detect() caches the aux_domain in the beginning of the function as it is used twice, so lets also use it as the aux_domain don't change in runtime. v3: returning intel_dp_retrain_link() error insted of connector_status_disconnected Cc: Imre Deak Reviewed-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: José Roberto de Souza Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20181107235449.32264-1-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5258c9d654f4..2b090609bee2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5169,8 +5169,7 @@ intel_dp_detect(struct drm_connector *connector, ret = intel_dp_retrain_link(encoder, ctx); if (ret) { - intel_display_power_put(dev_priv, - intel_aux_power_domain(dig_port)); + intel_display_power_put(dev_priv, aux_domain); return ret; } } -- cgit v1.2.3 From 3905308940b830f6a5ddf53300523251d15d6f3e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 15 Nov 2018 12:52:35 +0200 Subject: drm/i915/bios: rename intel_aux_ch() to intel_bios_port_aux_ch() Conform to function naming in intel_bios.c. Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20181115105237.1237-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2b090609bee2..7699f9b7b2d2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6745,7 +6745,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, if (port != PORT_A) intel_infoframe_init(intel_dig_port); - intel_dig_port->aux_ch = intel_aux_ch(dev_priv, port); + intel_dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port); if (!intel_dp_init_connector(intel_dig_port, intel_connector)) goto err_init_connector; -- cgit v1.2.3