To support a seamless transition from BIOS to kernel driver (fastboot),
especially on PTL with MSO panels, several adjustments are needed to
avoid unnecessary hardware resets and verification failures.
1. **Power Well & CDCLK Preservation**: In `icl_display_core_init`,
check if the display power well 1 is already enabled. If so, preserve
the current CDCLK configuration instead of forcibly resetting it.
This prevents the display from glitching or blanking during driver load.
2. **Verification Relaxation**:
* Skip the "connector not active" warning in
`intel_connector_verify_state`
for MSO panels where the split link topology might confuse the
standard checks during fastset.
* Bypass `intel_modeset_verify_crtc` for inherited states or the
boot pipe if no full modeset is required. This avoids verifying
state that hasn't been fully touched by the driver yet but is
known to be valid from BIOS.
3. **Type Extensions**: Add necessary fields to `intel_atomic_state`
(fastset flag), `intel_digital_port` (DDI tracking), and
`intel_vbt_panel_data` (MSO parameters) to support the enhanced
fastboot logic.
Signed-off-by: Juasheem Sultan <[email protected]>
---
drivers/gpu/drm/i915/display/intel_display_power.c | 16 +++++++++++++---
drivers/gpu/drm/i915/display/intel_display_types.h | 8 ++++++++
drivers/gpu/drm/i915/display/intel_modeset_verify.c | 14 ++++++++++++--
3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
b/drivers/gpu/drm/i915/display/intel_display_power.c
index
da4babfd6bcbd3b427c6da76cc54b450abeb4a38..0ac2acf34371bb43ddc2308d0ad81177023dad5b
100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -1661,8 +1661,7 @@ static void icl_display_core_init(struct intel_display
*display,
{
struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
-
- gen9_set_dc_state(display, DC_STATE_DISABLE);
+ bool was_enabled;
/* Wa_14011294188:ehl,jsl,tgl,rkl,adl-s */
if (INTEL_PCH_TYPE(display) >= PCH_TGP &&
@@ -1685,6 +1684,7 @@ static void icl_display_core_init(struct intel_display
*display,
*/
mutex_lock(&power_domains->lock);
well = lookup_power_well(display, SKL_DISP_PW_1);
+ was_enabled = intel_power_well_is_enabled(display, well);
intel_power_well_enable(display, well);
mutex_unlock(&power_domains->lock);
@@ -1693,7 +1693,17 @@ static void icl_display_core_init(struct intel_display
*display,
HOLD_PHY_PG1_LATCH | HOLD_PHY_CLKREQ_PG1_LATCH, 0);
/* 4. Enable CDCLK. */
- intel_cdclk_init_hw(display);
+ if (was_enabled) {
+ struct intel_cdclk_config cdclk_config;
+
+ intel_cdclk_get_cdclk(display, &cdclk_config);
+ if (intel_cdclk_clock_changed(&display->cdclk.hw,
&cdclk_config)) {
+ display->cdclk.hw = cdclk_config;
+ }
+ } else {
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
+ intel_cdclk_init_hw(display);
+ }
if (DISPLAY_VER(display) == 12 || display->platform.dg2)
gen12_dbuf_slices_config(display);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
b/drivers/gpu/drm/i915/display/intel_display_types.h
index
358ab922d7a769a363d2c6dfa7960f2fd869fe03..eb8331698fb18d77419c18ca648733e2699d45b1
100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -350,6 +350,8 @@ struct intel_vbt_panel_data {
bool low_vswing;
bool hobl;
bool dsc_disable;
+ u8 mso_link_count;
+ u8 mso_pixel_overlap;
} edp;
struct {
@@ -594,6 +596,8 @@ struct dpll {
struct intel_atomic_state {
struct drm_atomic_state base;
+ bool fastset;
+
struct ref_tracker *wakeref;
struct intel_global_objs_state *global_objs;
@@ -1879,6 +1883,10 @@ struct intel_lspcon {
struct intel_digital_port {
struct intel_encoder base;
+ i915_reg_t ddi_buf_ctl_reg;
+ intel_wakeref_t ddi_power_wakeref;
+
+ u32 saved_port_bits;
struct intel_dp dp;
struct intel_hdmi hdmi;
struct intel_lspcon lspcon;
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_verify.c
b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
index
f2f6b9d9afa10b921d991a34de9b59b19317b544..76d19e9ef4e204535885768bc119d26f07cf6c54
100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_verify.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
@@ -55,8 +55,13 @@ static void intel_connector_verify_state(const struct
intel_crtc_state *crtc_sta
INTEL_DISPLAY_STATE_WARN(display, conn_state->crtc !=
encoder->base.crtc,
"attached encoder crtc differs from
connector crtc\n");
} else {
- INTEL_DISPLAY_STATE_WARN(display, crtc_state &&
crtc_state->hw.active,
- "attached crtc is active, but
connector isn't\n");
+ /*
+ * HACK: Skip this warning for MSO panels if fastset is being
tricky.
+ */
+ if (!crtc_state || !crtc_state->splitter.enable)
+ INTEL_DISPLAY_STATE_WARN(display, crtc_state &&
crtc_state->hw.active,
+ "attached crtc is active, but
connector isn't\n");
+
INTEL_DISPLAY_STATE_WARN(display, !crtc_state &&
conn_state->best_encoder,
"best encoder set without crtc!\n");
}
@@ -236,6 +241,11 @@ void intel_modeset_verify_crtc(struct intel_atomic_state
*state,
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
+ if (new_crtc_state->inherited ||
+ (intel_is_boot_pipe(crtc->pipe) &&
!intel_crtc_needs_modeset(new_crtc_state))) {
+ return;
+ }
+
if (!intel_crtc_needs_modeset(new_crtc_state) &&
!intel_crtc_needs_fastset(new_crtc_state))
return;
--
2.52.0.457.g6b5491de43-goog