aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_dp_mst.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-12-27 15:25:04 +1000
committerDave Airlie <airlied@redhat.com>2019-12-27 15:25:04 +1000
commit3ae3271443b337c1cd421a9b73d51c5c2de52977 (patch)
tree2ce6c36149f45e50af5b3c321fa2b5222f9b81ae /drivers/gpu/drm/i915/display/intel_dp_mst.c
parentdrm/amdgpu/display: use msleep rather than udelay for HDCP (diff)
parentdrm/i915: Update DRIVER_DATE to 20191223 (diff)
downloadlinux-dev-3ae3271443b337c1cd421a9b73d51c5c2de52977.tar.xz
linux-dev-3ae3271443b337c1cd421a9b73d51c5c2de52977.zip
Merge tag 'drm-intel-next-2019-12-23' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
i915 features for v5.6: - Separate hardware and uapi state (Maarten) - Expose a number of sprite and plane formats (Ville) - DDC symlink in HDMI connector sysfs directory (Andrzej Pietrasiewicz) - Improve obj->mm.lock nesting lock annotation (Daniel) (Includes lockdep changes) - Selftest improvements across the board (Chris) - ICL/TGL VDSC support on DSI (Jani, Vandita) - TGL DSB fixes (Animesh, Lucas, Tvrtko) - VBT parsing improvements and fixes (Lucas, Matt, José, Jani, Dan Carpenter) - Fix LPSS vs. PMIC PWM backlight use on BYT/CHT (Hans) (Includes ACPI+MFD changes) - Display state, crtc, plane code refactoring (Ville) - Set opregion chpd value to indicate the driver handles hotplug (Hans de Goede) - DSI updates and fixes, TGL pipe D support, port mapping (José, Jani, Vandita) - Make HDCP 2.2 support cover CFL (Juston Li) - Fix CML PCI IDs and ULT (Shawn Lee) - CMP-V PCH fix (Imre) - TGL: Add another TGL PCH ID (James) - EHL/JSL: Add new PCI IDs (James) - Rename pipe update tracepoints (Ville) - Fix FBC on GLK+ (Ville) - GuC fixes and improvements (Daniele, Don Hiatt, Stuart Summers, Matthew Brost) - Display debugfs improvements (Ville) - Hotplug/irq fixes (Matt) - PSR fixes and improvements (José) - DRM_I915_GEM_MMAP_OFFSET ioctl (Abdiel) - Static analysis fixes (Colin Ian King) - Register sysctl path globally (Venkata Sandeep Dhanalakota) - Introduce new macros for tracing (Venkata Sandeep Dhanalakota) - Migrate gt towards intel_uncore_read/write (Andi) - Add rps frequency translation helpers (Andi) - Fix TGL transcoder clock off sequence (José) - Fix TGL port A audio (Kai Vehmanen) - TGL render decompression (DK) - GEM/GT improvements and fixes across the board (Chris) - Couple of backmerges (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> # gpg: Signature made Tue 24 Dec 2019 03:20:48 AM AEST # gpg: using RSA key D398079D26ABEE6F # gpg: Good signature from "Jani Nikula <jani.nikula@intel.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 1565 A65B 77B0 632E 1124 E59C D398 079D 26AB EE6F # Conflicts: # drivers/gpu/drm/i915/display/intel_fbc.c # drivers/gpu/drm/i915/gt/intel_lrc.c # drivers/gpu/drm/i915/i915_gem.c From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87lfr3rkry.fsf@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c81
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 03d1cba0b696..7aa0975c33b7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -42,13 +42,13 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state,
struct link_config_limits *limits)
{
- struct drm_atomic_state *state = crtc_state->base.state;
+ struct drm_atomic_state *state = crtc_state->uapi.state;
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
struct intel_dp *intel_dp = &intel_mst->primary->dp;
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode =
- &crtc_state->base.adjusted_mode;
+ &crtc_state->hw.adjusted_mode;
void *port = connector->port;
bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
DP_DPCD_QUIRK_CONSTANT_N);
@@ -99,7 +99,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
struct intel_digital_connector_state *intel_conn_state =
to_intel_digital_connector_state(conn_state);
const struct drm_display_mode *adjusted_mode =
- &pipe_config->base.adjusted_mode;
+ &pipe_config->hw.adjusted_mode;
void *port = connector->port;
struct link_config_limits limits;
int ret;
@@ -168,7 +168,6 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
struct intel_connector *intel_connector =
to_intel_connector(connector);
struct drm_crtc *new_crtc = new_conn_state->crtc;
- struct drm_crtc_state *crtc_state;
struct drm_dp_mst_topology_mgr *mgr;
int ret;
@@ -183,11 +182,16 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
* connector
*/
if (new_crtc) {
- crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
+ struct intel_atomic_state *intel_state =
+ to_intel_atomic_state(state);
+ struct intel_crtc *intel_crtc = to_intel_crtc(new_crtc);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(intel_state,
+ intel_crtc);
if (!crtc_state ||
- !drm_atomic_crtc_needs_modeset(crtc_state) ||
- crtc_state->enable)
+ !drm_atomic_crtc_needs_modeset(&crtc_state->uapi) ||
+ crtc_state->uapi.enable)
return 0;
}
@@ -231,8 +235,32 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
struct intel_dp *intel_dp = &intel_dig_port->dp;
struct intel_connector *connector =
to_intel_connector(old_conn_state->connector);
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ bool last_mst_stream;
- intel_ddi_disable_pipe_clock(old_crtc_state);
+ intel_dp->active_mst_links--;
+ last_mst_stream = intel_dp->active_mst_links == 0;
+
+ intel_crtc_vblank_off(old_crtc_state);
+
+ intel_disable_pipe(old_crtc_state);
+
+ intel_ddi_disable_transcoder_func(old_crtc_state);
+
+ if (INTEL_GEN(dev_priv) >= 9)
+ skylake_scaler_disable(old_crtc_state);
+ else
+ ironlake_pfit_disable(old_crtc_state);
+
+ /*
+ * From TGL spec: "If multi-stream slave transcoder: Configure
+ * Transcoder Clock Select to direct no clock to the transcoder"
+ *
+ * From older GENs spec: "Configure Transcoder Clock Select to direct
+ * no clock to the transcoder"
+ */
+ if (INTEL_GEN(dev_priv) < 12 || !last_mst_stream)
+ intel_ddi_disable_pipe_clock(old_crtc_state);
/* this can fail */
drm_dp_check_act_status(&intel_dp->mst_mgr);
@@ -248,14 +276,10 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
false);
- intel_dp->active_mst_links--;
-
intel_mst->connector = NULL;
- if (intel_dp->active_mst_links == 0) {
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+ if (last_mst_stream)
intel_dig_port->base.post_disable(&intel_dig_port->base,
old_crtc_state, NULL);
- }
DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
}
@@ -273,20 +297,6 @@ static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder,
pipe_config, NULL);
}
-static void intel_mst_post_pll_disable_dp(struct intel_encoder *encoder,
- const struct intel_crtc_state *old_crtc_state,
- const struct drm_connector_state *old_conn_state)
-{
- struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
- struct intel_digital_port *intel_dig_port = intel_mst->primary;
- struct intel_dp *intel_dp = &intel_dig_port->dp;
-
- if (intel_dp->active_mst_links == 0)
- intel_dig_port->base.post_pll_disable(&intel_dig_port->base,
- old_crtc_state,
- old_conn_state);
-}
-
static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *pipe_config,
const struct drm_connector_state *conn_state)
@@ -299,21 +309,23 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
to_intel_connector(conn_state->connector);
int ret;
u32 temp;
+ bool first_mst_stream;
/* MST encoders are bound to a crtc, not to a connector,
* force the mapping here for get_hw_state.
*/
connector->encoder = encoder;
intel_mst->connector = connector;
+ first_mst_stream = intel_dp->active_mst_links == 0;
DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
- if (intel_dp->active_mst_links == 0)
+ if (first_mst_stream)
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
- if (intel_dp->active_mst_links == 0)
+ if (first_mst_stream)
intel_dig_port->base.pre_enable(&intel_dig_port->base,
pipe_config, NULL);
@@ -330,7 +342,15 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
- intel_ddi_enable_pipe_clock(pipe_config);
+ /*
+ * Before Gen 12 this is not done as part of
+ * intel_dig_port->base.pre_enable() and should be done here. For
+ * Gen 12+ the step in which this should be done is different for the
+ * first MST stream, so it's done on the DDI for the first stream and
+ * here for the following ones.
+ */
+ if (INTEL_GEN(dev_priv) < 12 || !first_mst_stream)
+ intel_ddi_enable_pipe_clock(pipe_config);
intel_ddi_set_dp_msa(pipe_config, conn_state);
}
@@ -633,7 +653,6 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
intel_encoder->disable = intel_mst_disable_dp;
intel_encoder->post_disable = intel_mst_post_disable_dp;
intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
- intel_encoder->post_pll_disable = intel_mst_post_pll_disable_dp;
intel_encoder->pre_enable = intel_mst_pre_enable_dp;
intel_encoder->enable = intel_mst_enable_dp;
intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state;