@@ -10506,6 +10506,71 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
}
}
+static enum transcoder transcoder_master(struct drm_i915_private *dev_priv,
+ enum transcoder cpu_transcoder)
+{
+ u32 trans_port_sync, master_select;
+
+ trans_port_sync = I915_READ(TRANS_DDI_FUNC_CTL2(cpu_transcoder));
+
+ if ((trans_port_sync & PORT_SYNC_MODE_ENABLE) == 0)
+ return INVALID_TRANSCODER;
+
+ master_select = trans_port_sync &
+ PORT_SYNC_MODE_MASTER_SELECT_MASK;
+ switch (master_select) {
+ case 1:
+ return TRANSCODER_A;
+ case 2:
+ return TRANSCODER_B;
+ case 3:
+ return TRANSCODER_C;
+ case 4:
+ return TRANSCODER_D;
+ default:
+ MISSING_CASE(master_select);
+ return INVALID_TRANSCODER;
+ }
+}
+
+static void icelake_get_trans_port_sync_config(struct intel_crtc *crtc,
+ struct intel_crtc_state *pipe_config)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ u32 transcoders;
+ enum transcoder cpu_transcoder;
+
+ pipe_config->master_transcoder = transcoder_master(dev_priv,
+ pipe_config->cpu_transcoder);
+ if (pipe_config->master_transcoder != INVALID_TRANSCODER) {
+ pipe_config->sync_mode_slaves_mask = 0;
+ return;
+ }
+
+ transcoders = BIT(TRANSCODER_A) |
+ BIT(TRANSCODER_B) |
+ BIT(TRANSCODER_C) |
+ BIT(TRANSCODER_D);
+ for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) {
+ enum intel_display_power_domain power_domain;
+ intel_wakeref_t trans_wakeref;
+
+ power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
+ trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
+ power_domain);
+
+ if (!trans_wakeref)
+ continue;
+
+ if (transcoder_master(dev_priv, cpu_transcoder) ==
+ pipe_config->cpu_transcoder)
+ pipe_config->sync_mode_slaves_mask |= BIT(cpu_transcoder);
+
+ intel_display_power_put(dev_priv, power_domain, trans_wakeref);
+ }
+}
+
static bool haswell_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
@@ -10625,6 +10690,9 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
pipe_config->pixel_multiplier = 1;
}
+ if (INTEL_GEN(dev_priv) >= 11)
+ icelake_get_trans_port_sync_config(crtc, pipe_config);
+
out:
for_each_power_domain(power_domain, power_domain_mask)
intel_display_power_put(dev_priv,