From 2f51312bebb77962a518b4c6de777dd378b6110a Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 8 Feb 2021 17:43:03 +0200 Subject: [PATCH 1/2] drm/i915/tgl+: Make sure TypeC FIA is powered up when initializing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TypeC FIA can be powered down if the TC-COLD power state is allowed, so block the TC-COLD state when initializing the FIA. Note that this isn't needed on ICL where the FIA is never modular and which has no generic way to block TC-COLD (except for platforms with a legacy TypeC port and on those too only via these legacy ports, not via a DP-alt/TBT port). Cc: # v5.10+ Cc: José Roberto de Souza Reported-by: Paul Menzel Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3027 Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210208154303.6839-1-imre.deak@intel.com Reviewed-by: Jos� Roberto de Souza (cherry picked from commit f48993e5d26b079e8c80fff002499a213dbdb1b4) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_tc.c | 67 ++++++++++++++----------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 4346bc1a747a..8b6f16f9d0d1 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -23,36 +23,6 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) return names[mode]; } -static void -tc_port_load_fia_params(struct drm_i915_private *i915, - struct intel_digital_port *dig_port) -{ - enum port port = dig_port->base.port; - enum tc_port tc_port = intel_port_to_tc(i915, port); - u32 modular_fia; - - if (INTEL_INFO(i915)->display.has_modular_fia) { - modular_fia = intel_uncore_read(&i915->uncore, - PORT_TX_DFLEXDPSP(FIA1)); - drm_WARN_ON(&i915->drm, modular_fia == 0xffffffff); - modular_fia &= MODULAR_FIA_MASK; - } else { - modular_fia = 0; - } - - /* - * Each Modular FIA instance houses 2 TC ports. In SOC that has more - * than two TC ports, there are multiple instances of Modular FIA. - */ - if (modular_fia) { - dig_port->tc_phy_fia = tc_port / 2; - dig_port->tc_phy_fia_idx = tc_port % 2; - } else { - dig_port->tc_phy_fia = FIA1; - dig_port->tc_phy_fia_idx = tc_port; - } -} - static enum intel_display_power_domain tc_cold_get_power_domain(struct intel_digital_port *dig_port) { @@ -646,6 +616,43 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) mutex_unlock(&dig_port->tc_lock); } +static bool +tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port) +{ + intel_wakeref_t wakeref; + u32 val; + + if (!INTEL_INFO(i915)->display.has_modular_fia) + return false; + + wakeref = tc_cold_block(dig_port); + val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1)); + tc_cold_unblock(dig_port, wakeref); + + drm_WARN_ON(&i915->drm, val == 0xffffffff); + + return val & MODULAR_FIA_MASK; +} + +static void +tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port) +{ + enum port port = dig_port->base.port; + enum tc_port tc_port = intel_port_to_tc(i915, port); + + /* + * Each Modular FIA instance houses 2 TC ports. In SOC that has more + * than two TC ports, there are multiple instances of Modular FIA. + */ + if (tc_has_modular_fia(i915, dig_port)) { + dig_port->tc_phy_fia = tc_port / 2; + dig_port->tc_phy_fia_idx = tc_port % 2; + } else { + dig_port->tc_phy_fia = FIA1; + dig_port->tc_phy_fia_idx = tc_port; + } +} + void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); From 5feba0e905c495a217aea9db4ea91093d8fe5dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 9 Feb 2021 04:19:17 +0200 Subject: [PATCH 2/2] drm/i915: Fix overlay frontbuffer tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't have a persistent fb holding a reference to the frontbuffer object, so every time we do the get+put we throw the frontbuffer object immediately away. And so the next time around we get a pristine frontbuffer object with bits==0 even for the old vma. This confuses the frontbuffer tracking code which understandably expects the old frontbuffer to have the overlay's bit set. Fix this by hanging on to the frontbuffer reference until the next flip. And just to make this a bit more clear let's track the frontbuffer explicitly instead of just grabbing it via the old vma. Cc: stable@vger.kernel.org Cc: Chris Wilson Cc: Joonas Lahtinen Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/1136 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210209021918.16234-2-ville.syrjala@linux.intel.com Fixes: 8e7cb1799b4f ("drm/i915: Extract intel_frontbuffer active tracking") Reviewed-by: Chris Wilson (cherry picked from commit 553c23bdb4775130f333f07a51b047276bc53f79) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_overlay.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 0095c8cac9b4..b73d51e766ce 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -182,6 +182,7 @@ struct intel_overlay { struct intel_crtc *crtc; struct i915_vma *vma; struct i915_vma *old_vma; + struct intel_frontbuffer *frontbuffer; bool active; bool pfit_active; u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ @@ -282,21 +283,19 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, struct i915_vma *vma) { enum pipe pipe = overlay->crtc->pipe; - struct intel_frontbuffer *from = NULL, *to = NULL; + struct intel_frontbuffer *frontbuffer = NULL; drm_WARN_ON(&overlay->i915->drm, overlay->old_vma); - if (overlay->vma) - from = intel_frontbuffer_get(overlay->vma->obj); if (vma) - to = intel_frontbuffer_get(vma->obj); + frontbuffer = intel_frontbuffer_get(vma->obj); - intel_frontbuffer_track(from, to, INTEL_FRONTBUFFER_OVERLAY(pipe)); + intel_frontbuffer_track(overlay->frontbuffer, frontbuffer, + INTEL_FRONTBUFFER_OVERLAY(pipe)); - if (to) - intel_frontbuffer_put(to); - if (from) - intel_frontbuffer_put(from); + if (overlay->frontbuffer) + intel_frontbuffer_put(overlay->frontbuffer); + overlay->frontbuffer = frontbuffer; intel_frontbuffer_flip_prepare(overlay->i915, INTEL_FRONTBUFFER_OVERLAY(pipe));