mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 04:23:35 +02:00
drm/i915/mso: add splitter state readout for platforms that support it
Add splitter configuration to crtc state, and read it where supported. Also add splitter state dumping. The stream splitter will be required for eDP MSO. v4: - Catch invalid splitter configuration (Uma) v3: - Convert segment timings to full panel timings. - Refer to splitter instead of mso in crtc state. - Dump splitter state. v2: Add warning for mso being enabled on pipes other than A. Cc: Nischal Varide <nischal.varide@intel.com> Cc: Uma Shankar <uma.shankar@intel.com> Reviewed-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/95cbe1c9d45edf3e3ec252e49fb49055def98155.1614682842.git.jani.nikula@intel.com
This commit is contained in:
parent
a49388bd2b
commit
5b616a2958
|
|
@ -2136,6 +2136,45 @@ static void intel_ddi_power_up_lanes(struct intel_encoder *encoder,
|
|||
}
|
||||
}
|
||||
|
||||
static void intel_ddi_mso_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 dss1;
|
||||
|
||||
if (!HAS_MSO(i915))
|
||||
return;
|
||||
|
||||
dss1 = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe));
|
||||
|
||||
pipe_config->splitter.enable = dss1 & SPLITTER_ENABLE;
|
||||
if (!pipe_config->splitter.enable)
|
||||
return;
|
||||
|
||||
/* Splitter enable is supported for pipe A only. */
|
||||
if (drm_WARN_ON(&i915->drm, pipe != PIPE_A)) {
|
||||
pipe_config->splitter.enable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (dss1 & SPLITTER_CONFIGURATION_MASK) {
|
||||
default:
|
||||
drm_WARN(&i915->drm, true,
|
||||
"Invalid splitter configuration, dss1=0x%08x\n", dss1);
|
||||
fallthrough;
|
||||
case SPLITTER_CONFIGURATION_2_SEGMENT:
|
||||
pipe_config->splitter.link_count = 2;
|
||||
break;
|
||||
case SPLITTER_CONFIGURATION_4_SEGMENT:
|
||||
pipe_config->splitter.link_count = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
pipe_config->splitter.pixel_overlap = REG_FIELD_GET(OVERLAP_PIXELS_MASK, dss1);
|
||||
}
|
||||
|
||||
static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
|
|
@ -3316,6 +3355,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
|
|||
intel_ddi_read_func_ctl(encoder, pipe_config);
|
||||
}
|
||||
|
||||
intel_ddi_mso_get_config(encoder, pipe_config);
|
||||
|
||||
pipe_config->has_audio =
|
||||
intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
|
||||
|
||||
|
|
|
|||
|
|
@ -4862,8 +4862,30 @@ static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state
|
|||
pipe_mode->crtc_clock /= 2;
|
||||
}
|
||||
|
||||
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
|
||||
intel_mode_from_crtc_timings(adjusted_mode, adjusted_mode);
|
||||
if (crtc_state->splitter.enable) {
|
||||
int n = crtc_state->splitter.link_count;
|
||||
int overlap = crtc_state->splitter.pixel_overlap;
|
||||
|
||||
/*
|
||||
* eDP MSO uses segment timings from EDID for transcoder
|
||||
* timings, but full mode for everything else.
|
||||
*
|
||||
* h_full = (h_segment - pixel_overlap) * link_count
|
||||
*/
|
||||
pipe_mode->crtc_hdisplay = (pipe_mode->crtc_hdisplay - overlap) * n;
|
||||
pipe_mode->crtc_hblank_start = (pipe_mode->crtc_hblank_start - overlap) * n;
|
||||
pipe_mode->crtc_hblank_end = (pipe_mode->crtc_hblank_end - overlap) * n;
|
||||
pipe_mode->crtc_hsync_start = (pipe_mode->crtc_hsync_start - overlap) * n;
|
||||
pipe_mode->crtc_hsync_end = (pipe_mode->crtc_hsync_end - overlap) * n;
|
||||
pipe_mode->crtc_htotal = (pipe_mode->crtc_htotal - overlap) * n;
|
||||
pipe_mode->crtc_clock *= n;
|
||||
|
||||
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
|
||||
intel_mode_from_crtc_timings(adjusted_mode, pipe_mode);
|
||||
} else {
|
||||
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
|
||||
intel_mode_from_crtc_timings(adjusted_mode, adjusted_mode);
|
||||
}
|
||||
|
||||
intel_crtc_compute_pixel_rate(crtc_state);
|
||||
|
||||
|
|
@ -8272,6 +8294,11 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
|
|||
pipe_config->bigjoiner_slave ? "slave" :
|
||||
pipe_config->bigjoiner ? "master" : "no");
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "splitter: %s, link count %d, overlap %d\n",
|
||||
enableddisabled(pipe_config->splitter.enable),
|
||||
pipe_config->splitter.link_count,
|
||||
pipe_config->splitter.pixel_overlap);
|
||||
|
||||
if (pipe_config->has_pch_encoder)
|
||||
intel_dump_m_n_config(pipe_config, "fdi",
|
||||
pipe_config->fdi_lanes,
|
||||
|
|
|
|||
|
|
@ -1169,6 +1169,13 @@ struct intel_crtc_state {
|
|||
u8 pipeline_full;
|
||||
u16 flipline, vmin, vmax;
|
||||
} vrr;
|
||||
|
||||
/* Stream Splitter for eDP MSO */
|
||||
struct {
|
||||
bool enable;
|
||||
u8 link_count;
|
||||
u8 pixel_overlap;
|
||||
} splitter;
|
||||
};
|
||||
|
||||
enum intel_pipe_crc_source {
|
||||
|
|
|
|||
|
|
@ -1705,6 +1705,8 @@ tgl_stepping_get(struct drm_i915_private *dev_priv)
|
|||
|
||||
#define HAS_CSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_csr)
|
||||
|
||||
#define HAS_MSO(i915) (INTEL_GEN(i915) >= 12)
|
||||
|
||||
#define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
|
||||
#define HAS_64BIT_RELOC(dev_priv) (INTEL_INFO(dev_priv)->has_64bit_reloc)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user