Merge tag 'drm-intel-next-2026-03-16' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

[airlied: fixed conflict with xe tree]
drm/i915 feature pull for v7.1:

Features and functionality:
- C10/C20/LT PHY PLL divider verification (Mika)
- Use trans push mechanism to generate PSR frame change event on LNL+ (Jouni)
- Account for DSC bubble overhead for horizontal slices (Ankit, Chaitanya)

Refactoring and cleanups:
- Refactor DP DSC slice config computation (Imre)
- Use GVT versions of register helper macros for GVT MMIO table (Ankit)
- C10/C20/LT PHY PLL computation refactoring (Mika)
- VGA decode refactoring and related fixes/cleanups (Ville)
- Move DSB buffer buffer implementation to display parent interface (Jani)
- Move error interrupt capture to display irq snapshot (Jani)
- Move pcode calls to display parent interface (Jani)
- Reduce GVT dependency on display headers (Jani)
- Compute config and mode valid refactoring for DSC (Ankit)
- Stop using i915 core register headers in display (Uma)
- Refactor DPT, move i915 parts to display parent interface (Jani)
- Refactor gen2-4 overlay, move to display parent interface (Ville)
- Refactor masked field register macro helpers, move to shared headers (Jani)
- Convert a number of workaround checks to the new workaround framework (Luca)
- Refactor and move frontbuffer calls to display parent interface (Jani)
- Add VMA calls to display parent interface (Jani)
- Refactor stolen memory allocation decisions (Vinod, Ville)
- Clean up and unify workqueue usage (Marco Crivellari)
- Preparation for UHBR DP tunnels (Imre)
- Allow DSC passthrough modes during DP MST mode validation (Imre)
- Move framebuffer bo interface to display parent interface (Jani)

Fixes:
- Plenty of DP SST HPD IRQ handling fixes (Imre)
- DP AUX backlight and luminance control fixes (Suraj)
- Respect VBT pipe joiner disable for eDP (Ankit)
- Do not use CASF with joiner (Nemesa)
- Clear C10/C20 PHY response read and error bit to avoid PHY hangs (Suraj)
- Xe3p_LPD DMG clock gating, CDCLK, port sync workarounds (Suraj, Gustavo, Mitul)
- Fix GVT error path (Michał)
- Handle errors on DP DSC receiver cap reads (Suraj)
- DSS clock gating workaround on MTL+ to avoid DSC corruption (Mika)
- Skip state verification for LT PHY in TBT mode (Suraj)
- Fix NULL pointer dereference on suspend when uc firmware not loaded (Rahul Bukte)
- Fix an unlikely DMC state related NULL pointer dereference at probe (Imre)
- Handle error returns from vga_get_uninterruptible() (Simon Richter)
- Increase C10/C20/LT PHY timeouts to include SOC/OS turnaround (Arun)
- Fix BIOS FB vs. stolen memory size check (Ville)
- Fix LOBF to use computed guardband and set context latency (Ankit)
- Handle modeset WW mutex lock failures due to contention properly (Imre)
- Fix pipe BPP clamping due to HDR (Imre)
- Fix stale state usage in DSC state computation (Imre)
- Take HDCP 1.4 vs 2.x into account during link check (Suraj)
- Fix forced link retrain handling in MST HPD IRQ handler (Imre)
- Remove redundant warning on vcpi < 0 (Jonathan)

Core changes:
- iopoll: fix function parameter names in read_poll_timeout_atomic() (Randy Dunlap)

Merges:
- Backmerge drm-next for v7.0-rc1 (Jani)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patch.msgid.link/b14bb0f297b1750816cf5f342bde608e435655fa@intel.com
This commit is contained in:
Dave Airlie
2026-03-17 15:44:26 +10:00
218 changed files with 5636 additions and 3896 deletions
+4 -3
View File
@@ -76,9 +76,13 @@ i915-$(CONFIG_PERF_EVENTS) += \
# core display adaptation
i915-y += \
i915_bo.o \
i915_display_pc8.o \
i915_dpt.o \
i915_dsb_buffer.o \
i915_hdcp_gsc.o \
i915_initial_plane.o \
i915_overlay.o \
i915_panic.o
# "Graphics Technology" (aka we talk to the gpu)
@@ -270,13 +274,10 @@ i915-y += \
display/intel_dpll.o \
display/intel_dpll_mgr.o \
display/intel_dpt.o \
display/intel_dpt_common.o \
display/intel_dram.o \
display/intel_drrs.o \
display/intel_dsb.o \
display/intel_dsb_buffer.o \
display/intel_fb.o \
display/intel_fb_bo.o \
display/intel_fb_pin.o \
display/intel_fbc.o \
display/intel_fdi.o \
-1
View File
@@ -10,7 +10,6 @@
#include <drm/drm_print.h>
#include "g4x_dp.h"
#include "i915_reg.h"
#include "intel_audio.h"
#include "intel_backlight.h"
#include "intel_connector.h"
-1
View File
@@ -8,7 +8,6 @@
#include <drm/drm_print.h>
#include "g4x_hdmi.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_connector.h"
+5 -5
View File
@@ -6,15 +6,15 @@
#include <linux/debugfs.h>
#include <drm/drm_print.h>
#include <drm/intel/intel_pcode_regs.h>
#include "hsw_ips.h"
#include "i915_reg.h"
#include "intel_color_regs.h"
#include "intel_de.h"
#include "intel_display_regs.h"
#include "intel_display_rpm.h"
#include "intel_display_types.h"
#include "intel_pcode.h"
#include "intel_parent.h"
static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
{
@@ -39,8 +39,8 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
if (display->platform.broadwell) {
drm_WARN_ON(display->drm,
intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL,
val | IPS_PCODE_CONTROL));
intel_parent_pcode_write(display, DISPLAY_IPS_CONTROL,
val | IPS_PCODE_CONTROL));
/*
* Quoting Art Runyan: "its not safe to expect any particular
* value in IPS_CTL bit 31 after enabling IPS through the
@@ -72,7 +72,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
if (display->platform.broadwell) {
drm_WARN_ON(display->drm,
intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 0));
intel_parent_pcode_write(display, DISPLAY_IPS_CONTROL, 0));
/*
* Wait for PCODE to finish disabling IPS. The BSpec specified
* 42ms timeout value leads to occasional timeouts so use 100ms
@@ -10,7 +10,6 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i9xx_plane.h"
#include "i9xx_plane_regs.h"
#include "intel_atomic.h"
+5 -5
View File
@@ -6,8 +6,8 @@
#include <linux/iopoll.h>
#include <drm/drm_print.h>
#include <drm/intel/intel_gmd_misc_regs.h>
#include "i915_reg.h"
#include "i9xx_wm.h"
#include "i9xx_wm_regs.h"
#include "intel_atomic.h"
@@ -182,8 +182,8 @@ static bool _intel_set_memory_cxsr(struct intel_display *display, bool enable)
intel_de_posting_read(display, DSPFW3(display));
} else if (display->platform.i945g || display->platform.i945gm) {
was_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN;
val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) :
_MASKED_BIT_DISABLE(FW_BLC_SELF_EN);
val = enable ? REG_MASKED_FIELD_ENABLE(FW_BLC_SELF_EN) :
REG_MASKED_FIELD_DISABLE(FW_BLC_SELF_EN);
intel_de_write(display, FW_BLC_SELF, val);
intel_de_posting_read(display, FW_BLC_SELF);
} else if (display->platform.i915gm) {
@@ -193,8 +193,8 @@ static bool _intel_set_memory_cxsr(struct intel_display *display, bool enable)
* FW_BLC_SELF. What's going on?
*/
was_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN;
val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) :
_MASKED_BIT_DISABLE(INSTPM_SELF_EN);
val = enable ? REG_MASKED_FIELD_ENABLE(INSTPM_SELF_EN) :
REG_MASKED_FIELD_DISABLE(INSTPM_SELF_EN);
intel_de_write(display, INSTPM, val);
intel_de_posting_read(display, INSTPM);
} else {
-7
View File
@@ -34,7 +34,6 @@
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_reg.h"
#include "icl_dsi.h"
#include "icl_dsi_regs.h"
#include "intel_atomic.h"
@@ -1624,12 +1623,6 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
if (crtc_state->pipe_bpp < 8 * 3)
return -EINVAL;
/* FIXME: split only when necessary */
if (crtc_state->dsc.slice_count > 1)
crtc_state->dsc.num_streams = 2;
else
crtc_state->dsc.num_streams = 1;
/* FIXME: initialize from VBT */
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
+93 -57
View File
@@ -15,6 +15,7 @@
#include "intel_dp_aux.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
#include "intel_vrr.h"
#define SILENCE_PERIOD_MIN_TIME 80
#define SILENCE_PERIOD_MAX_TIME 180
@@ -43,12 +44,6 @@ bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp,
void intel_alpm_init(struct intel_dp *intel_dp)
{
u8 dpcd;
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP, &dpcd) < 0)
return;
intel_dp->alpm_dpcd = dpcd;
mutex_init(&intel_dp->alpm.lock);
}
@@ -248,14 +243,87 @@ bool intel_alpm_compute_params(struct intel_dp *intel_dp,
return true;
}
int intel_alpm_lobf_min_guardband(struct intel_crtc_state *crtc_state)
{
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int first_sdp_position = adjusted_mode->crtc_vtotal -
adjusted_mode->crtc_vsync_start;
int waketime_in_lines;
/*
* #FIXME: Need to check if io_wake_lines or aux_less_wake_lines
* is applicable. Currently this information is not readily
* available in crtc_state, so max will suffice for now.
*/
waketime_in_lines = max(crtc_state->alpm_state.io_wake_lines,
crtc_state->alpm_state.aux_less_wake_lines);
if (!crtc_state->has_lobf)
return 0;
return first_sdp_position + waketime_in_lines + crtc_state->set_context_latency;
}
static bool intel_alpm_lobf_is_window1_sufficient(struct intel_crtc_state *crtc_state)
{
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int vblank = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay;
int window1;
/*
* LOBF must be disabled if the number of lines within Window 1 is not
* greater than ALPM_CTL[ALPM Entry Check]
*/
window1 = vblank - min(vblank,
crtc_state->vrr.guardband +
crtc_state->set_context_latency);
return window1 > crtc_state->alpm_state.check_entry_lines;
}
void intel_alpm_lobf_compute_config_late(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int waketime_in_lines, first_sdp_position;
if (!crtc_state->has_lobf)
return;
if (!intel_alpm_lobf_is_window1_sufficient(crtc_state)) {
crtc_state->has_lobf = false;
return;
}
/*
* LOBF can only be enabled if the time from the start of the SCL+Guardband
* window to the position of the first SDP is greater than the time it takes
* to wake the main link.
*
* Position of first sdp : vsync_start
* start of scl + guardband : vtotal - (scl + guardband)
* time in lines to wake main link : waketime_in_lines
*
* Position of first sdp - start of (scl + guardband) > time in lines to wake main link
* vsync_start - (vtotal - (scl + guardband)) > waketime_in_lines
* vsync_start - vtotal + scl + guardband > waketime_in_lines
* scl + guardband > waketime_in_lines + (vtotal - vsync_start)
*/
first_sdp_position = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
if (intel_alpm_aux_less_wake_supported(intel_dp))
waketime_in_lines = crtc_state->alpm_state.io_wake_lines;
else
waketime_in_lines = crtc_state->alpm_state.aux_less_wake_lines;
crtc_state->has_lobf = (crtc_state->set_context_latency + crtc_state->vrr.guardband) >
(first_sdp_position + waketime_in_lines);
}
void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int waketime_in_lines, first_sdp_position;
int context_latency, guardband;
if (intel_dp->alpm.lobf_disable_debug) {
drm_dbg_kms(display->drm, "LOBF is disabled by debug flag\n");
@@ -277,8 +345,8 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
if (crtc_state->has_psr)
return;
if (crtc_state->vrr.vmin != crtc_state->vrr.vmax ||
crtc_state->vrr.vmin != crtc_state->vrr.flipline)
if (!intel_vrr_always_use_vrr_tg(display) ||
!intel_vrr_is_fixed_rr(crtc_state))
return;
if (!(intel_alpm_aux_wake_supported(intel_dp) ||
@@ -288,17 +356,7 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
if (!intel_alpm_compute_params(intel_dp, crtc_state))
return;
context_latency = adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
guardband = adjusted_mode->crtc_vtotal -
adjusted_mode->crtc_vdisplay - context_latency;
first_sdp_position = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
if (intel_alpm_aux_less_wake_supported(intel_dp))
waketime_in_lines = crtc_state->alpm_state.io_wake_lines;
else
waketime_in_lines = crtc_state->alpm_state.aux_less_wake_lines;
crtc_state->has_lobf = (context_latency + guardband) >
(first_sdp_position + waketime_in_lines);
crtc_state->has_lobf = true;
}
static void lnl_alpm_configure(struct intel_dp *intel_dp,
@@ -388,25 +446,14 @@ void intel_alpm_port_configure(struct intel_dp *intel_dp,
intel_de_write(display, PORT_ALPM_LFPS_CTL(port), lfps_ctl_val);
}
void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
void intel_alpm_lobf_disable(const struct intel_crtc_state *new_crtc_state)
{
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
struct intel_display *display = to_intel_display(new_crtc_state);
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
struct intel_encoder *encoder;
if (DISPLAY_VER(display) < 20)
return;
if (crtc_state->has_lobf || crtc_state->has_lobf == old_crtc_state->has_lobf)
return;
for_each_intel_encoder_mask(display->drm, encoder,
crtc_state->uapi.encoder_mask) {
new_crtc_state->uapi.encoder_mask) {
struct intel_dp *intel_dp;
if (!intel_encoder_is_dp(encoder))
@@ -417,12 +464,10 @@ void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
if (!intel_dp_is_edp(intel_dp))
continue;
if (old_crtc_state->has_lobf) {
mutex_lock(&intel_dp->alpm.lock);
intel_de_write(display, ALPM_CTL(display, cpu_transcoder), 0);
drm_dbg_kms(display->drm, "Link off between frames (LOBF) disabled\n");
mutex_unlock(&intel_dp->alpm.lock);
}
mutex_lock(&intel_dp->alpm.lock);
intel_de_write(display, ALPM_CTL(display, cpu_transcoder), 0);
drm_dbg_kms(display->drm, "Link off between frames (LOBF) disabled\n");
mutex_unlock(&intel_dp->alpm.lock);
}
}
@@ -443,22 +488,13 @@ void intel_alpm_enable_sink(struct intel_dp *intel_dp,
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
}
void intel_alpm_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
void intel_alpm_lobf_enable(const struct intel_crtc_state *new_crtc_state)
{
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_display *display = to_intel_display(new_crtc_state);
struct intel_encoder *encoder;
if (crtc_state->has_psr || !crtc_state->has_lobf ||
crtc_state->has_lobf == old_crtc_state->has_lobf)
return;
for_each_intel_encoder_mask(display->drm, encoder,
crtc_state->uapi.encoder_mask) {
new_crtc_state->uapi.encoder_mask) {
struct intel_dp *intel_dp;
if (!intel_encoder_is_dp(encoder))
@@ -467,8 +503,8 @@ void intel_alpm_post_plane_update(struct intel_atomic_state *state,
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp_is_edp(intel_dp)) {
intel_alpm_enable_sink(intel_dp, crtc_state);
intel_alpm_configure(intel_dp, crtc_state);
intel_alpm_enable_sink(intel_dp, new_crtc_state);
intel_alpm_configure(intel_dp, new_crtc_state);
}
}
}
+5 -4
View File
@@ -25,12 +25,10 @@ void intel_alpm_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_alpm_enable_sink(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_alpm_lobf_disable(const struct intel_crtc_state *new_crtc_state);
void intel_alpm_port_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_alpm_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_alpm_lobf_enable(const struct intel_crtc_state *new_crtc_state);
void intel_alpm_lobf_debugfs_add(struct intel_connector *connector);
bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp);
bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp);
@@ -38,4 +36,7 @@ bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_alpm_disable(struct intel_dp *intel_dp);
bool intel_alpm_get_error(struct intel_dp *intel_dp);
void intel_alpm_lobf_compute_config_late(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state);
int intel_alpm_lobf_min_guardband(struct intel_crtc_state *crtc_state);
#endif
+11 -13
View File
@@ -37,6 +37,7 @@
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_display_wa.h"
#include "intel_lpe_audio.h"
/**
@@ -184,17 +185,6 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
{ 192000, TMDS_445_5M, 20480, 371250 },
};
/*
* WA_14020863754: Implement Audio Workaround
* Corner case with Min Hblank Fix can cause audio hang
*/
static bool needs_wa_14020863754(struct intel_display *display)
{
return DISPLAY_VERx100(display) == 3000 ||
DISPLAY_VERx100(display) == 2000 ||
DISPLAY_VERx100(display) == 1401;
}
/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
{
@@ -440,7 +430,11 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder,
intel_de_rmw(display, HSW_AUD_PIN_ELD_CP_VLD,
AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0);
if (needs_wa_14020863754(display))
/*
* WA_14020863754: Implement Audio Workaround
* Corner case with Min Hblank Fix can cause audio hang
*/
if (intel_display_wa(display, INTEL_DISPLAY_WA_14020863754))
intel_de_rmw(display, AUD_CHICKENBIT_REG3, DACBE_DISABLE_MIN_HBLANK_FIX, 0);
intel_audio_sdp_split_update(old_crtc_state, false);
@@ -572,7 +566,11 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
intel_audio_sdp_split_update(crtc_state, true);
if (needs_wa_14020863754(display))
/*
* WA_14020863754: Implement Audio Workaround
* Corner case with Min Hblank Fix can cause audio hang
*/
if (intel_display_wa(display, INTEL_DISPLAY_WA_14020863754))
intel_de_rmw(display, AUD_CHICKENBIT_REG3, 0, DACBE_DISABLE_MIN_HBLANK_FIX);
/* Enable audio presence detect */
@@ -12,7 +12,6 @@
#include <drm/drm_file.h>
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "intel_backlight.h"
#include "intel_backlight_regs.h"
#include "intel_connector.h"
+22 -9
View File
@@ -41,6 +41,7 @@
#include "intel_display_utils.h"
#include "intel_gmbus.h"
#include "intel_rom.h"
#include "intel_vdsc.h"
#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"
@@ -1545,6 +1546,10 @@ parse_edp(struct intel_display *display,
if (display->vbt.version >= 251)
panel->vbt.edp.dsc_disable =
panel_bool(edp->edp_dsc_disable, panel_type);
if (display->vbt.version >= 261)
panel->vbt.edp.pipe_joiner_enable =
panel_bool(edp->pipe_joiner_enable, panel_type);
}
static void
@@ -3543,12 +3548,13 @@ bool intel_bios_is_dsi_present(struct intel_display *display,
return false;
}
static void fill_dsc(struct intel_crtc_state *crtc_state,
static bool fill_dsc(struct intel_crtc_state *crtc_state,
struct dsc_compression_parameters_entry *dsc,
int dsc_max_bpc)
{
struct intel_display *display = to_intel_display(crtc_state);
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
int slices_per_line;
int bpc = 8;
vdsc_cfg->dsc_version_major = dsc->version_major;
@@ -3574,26 +3580,33 @@ static void fill_dsc(struct intel_crtc_state *crtc_state,
* throughput etc. into account.
*
* Also, per spec DSI supports 1, 2, 3 or 4 horizontal slices.
*
* FIXME: split only when necessary
*/
if (dsc->slices_per_line & BIT(2)) {
crtc_state->dsc.slice_count = 4;
slices_per_line = 4;
} else if (dsc->slices_per_line & BIT(1)) {
crtc_state->dsc.slice_count = 2;
slices_per_line = 2;
} else {
/* FIXME */
if (!(dsc->slices_per_line & BIT(0)))
drm_dbg_kms(display->drm,
"VBT: Unsupported DSC slice count for DSI\n");
crtc_state->dsc.slice_count = 1;
slices_per_line = 1;
}
if (drm_WARN_ON(display->drm,
!intel_dsc_get_slice_config(display, 1, slices_per_line,
&crtc_state->dsc.slice_config)))
return false;
if (crtc_state->hw.adjusted_mode.crtc_hdisplay %
crtc_state->dsc.slice_count != 0)
intel_dsc_line_slice_count(&crtc_state->dsc.slice_config) != 0)
drm_dbg_kms(display->drm,
"VBT: DSC hdisplay %d not divisible by slice count %d\n",
crtc_state->hw.adjusted_mode.crtc_hdisplay,
crtc_state->dsc.slice_count);
intel_dsc_line_slice_count(&crtc_state->dsc.slice_config));
/*
* The VBT rc_buffer_block_size and rc_buffer_size definitions
@@ -3608,6 +3621,8 @@ static void fill_dsc(struct intel_crtc_state *crtc_state,
vdsc_cfg->block_pred_enable = dsc->block_prediction_enable;
vdsc_cfg->slice_height = dsc->slice_height;
return true;
}
/* FIXME: initially DSI specific */
@@ -3628,9 +3643,7 @@ bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
if (!devdata->dsc)
return false;
fill_dsc(crtc_state, devdata->dsc, dsc_max_bpc);
return true;
return fill_dsc(crtc_state, devdata->dsc, dsc_max_bpc);
}
}
+50 -50
View File
@@ -1,87 +1,87 @@
// SPDX-License-Identifier: MIT
/* Copyright © 2024 Intel Corporation */
/* Copyright © 2026 Intel Corporation */
#include <drm/drm_panic.h>
#include <drm/drm_gem.h>
#include <drm/intel/display_parent_interface.h>
#include "gem/i915_gem_mman.h"
#include "gem/i915_gem_object.h"
#include "gem/i915_gem_object_frontbuffer.h"
#include "pxp/intel_pxp.h"
#include "i915_debugfs.h"
#include "intel_bo.h"
#include "intel_display_core.h"
#include "intel_display_types.h"
bool intel_bo_is_tiled(struct drm_gem_object *obj)
{
return i915_gem_object_is_tiled(to_intel_bo(obj));
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->is_tiled && display->parent->bo->is_tiled(obj);
}
bool intel_bo_is_userptr(struct drm_gem_object *obj)
{
return i915_gem_object_is_userptr(to_intel_bo(obj));
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->is_userptr && display->parent->bo->is_userptr(obj);
}
bool intel_bo_is_shmem(struct drm_gem_object *obj)
{
return i915_gem_object_is_shmem(to_intel_bo(obj));
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->is_shmem && display->parent->bo->is_shmem(obj);
}
bool intel_bo_is_protected(struct drm_gem_object *obj)
{
return i915_gem_object_is_protected(to_intel_bo(obj));
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->is_protected(obj);
}
int intel_bo_key_check(struct drm_gem_object *obj)
{
return intel_pxp_key_check(obj, false);
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->key_check(obj);
}
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
{
return i915_gem_fb_mmap(to_intel_bo(obj), vma);
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->fb_mmap(obj, vma);
}
int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size)
{
return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size);
}
struct intel_display *display = to_intel_display(obj->dev);
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *_obj)
{
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
struct i915_frontbuffer *front;
front = i915_gem_object_frontbuffer_get(obj);
if (!front)
return NULL;
return &front->base;
}
void intel_bo_frontbuffer_ref(struct intel_frontbuffer *_front)
{
struct i915_frontbuffer *front =
container_of(_front, typeof(*front), base);
i915_gem_object_frontbuffer_ref(front);
}
void intel_bo_frontbuffer_put(struct intel_frontbuffer *_front)
{
struct i915_frontbuffer *front =
container_of(_front, typeof(*front), base);
return i915_gem_object_frontbuffer_put(front);
}
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *_front)
{
struct i915_frontbuffer *front =
container_of(_front, typeof(*front), base);
i915_gem_object_flush_if_display(front->obj);
return display->parent->bo->read_from_page(obj, offset, dst, size);
}
void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
{
i915_debugfs_describe_obj(m, to_intel_bo(obj));
struct intel_display *display = to_intel_display(obj->dev);
if (display->parent->bo->describe)
display->parent->bo->describe(m, obj);
}
int intel_bo_framebuffer_init(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd)
{
struct intel_display *display = to_intel_display(obj->dev);
return display->parent->bo->framebuffer_init(obj, mode_cmd);
}
void intel_bo_framebuffer_fini(struct drm_gem_object *obj)
{
struct intel_display *display = to_intel_display(obj->dev);
display->parent->bo->framebuffer_fini(obj);
}
struct drm_gem_object *intel_bo_framebuffer_lookup(struct intel_display *display,
struct drm_file *filp,
const struct drm_mode_fb_cmd2 *user_mode_cmd)
{
return display->parent->bo->framebuffer_lookup(display->drm, filp, user_mode_cmd);
}
+9 -5
View File
@@ -6,8 +6,11 @@
#include <linux/types.h>
struct drm_file;
struct drm_gem_object;
struct drm_mode_fb_cmd2;
struct drm_scanout_buffer;
struct intel_display;
struct intel_framebuffer;
struct seq_file;
struct vm_area_struct;
@@ -20,11 +23,12 @@ int intel_bo_key_check(struct drm_gem_object *obj);
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size);
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj);
void intel_bo_frontbuffer_ref(struct intel_frontbuffer *front);
void intel_bo_frontbuffer_put(struct intel_frontbuffer *front);
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front);
void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj);
void intel_bo_framebuffer_fini(struct drm_gem_object *obj);
int intel_bo_framebuffer_init(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd);
struct drm_gem_object *intel_bo_framebuffer_lookup(struct intel_display *display,
struct drm_file *filp,
const struct drm_mode_fb_cmd2 *user_mode_cmd);
#endif /* __INTEL_BO__ */
+12 -12
View File
@@ -5,8 +5,8 @@
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_print.h>
#include <drm/intel/intel_pcode_regs.h>
#include "i915_reg.h"
#include "intel_bw.h"
#include "intel_crtc.h"
#include "intel_display_core.h"
@@ -15,7 +15,7 @@
#include "intel_display_utils.h"
#include "intel_dram.h"
#include "intel_mchbar_regs.h"
#include "intel_pcode.h"
#include "intel_parent.h"
#include "intel_uncore.h"
#include "skl_watermark.h"
@@ -114,9 +114,9 @@ static int icl_pcode_read_qgv_point_info(struct intel_display *display,
u16 dclk;
int ret;
ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
&val, &val2);
ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
&val, &val2);
if (ret)
return ret;
@@ -141,8 +141,8 @@ static int adls_pcode_read_psf_gv_point_info(struct intel_display *display,
int ret;
int i;
ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL);
ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL);
if (ret)
return ret;
@@ -189,11 +189,11 @@ static int icl_pcode_restrict_qgv_points(struct intel_display *display,
return 0;
/* bspec says to keep retrying for at least 1 ms */
ret = intel_pcode_request(display->drm, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
points_mask,
ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK,
ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE,
1);
ret = intel_parent_pcode_request(display, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
points_mask,
ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK,
ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE,
1);
if (ret < 0) {
drm_err(display->drm,
+6 -1
View File
@@ -3,7 +3,6 @@
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "intel_casf.h"
#include "intel_casf_regs.h"
#include "intel_de.h"
@@ -116,6 +115,12 @@ int intel_casf_compute_config(struct intel_crtc_state *crtc_state)
return 0;
}
/* CASF with joiner not supported in hardware */
if (crtc_state->joiner_pipes) {
drm_dbg_kms(display->drm, "CASF not supported with joiner\n");
return -EINVAL;
}
crtc_state->hw.casf_params.casf_enable = true;
/*
+32 -31
View File
@@ -27,9 +27,9 @@
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include <drm/intel/intel_pcode_regs.h>
#include "hsw_ips.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_cdclk.h"
@@ -42,8 +42,8 @@
#include "intel_display_wa.h"
#include "intel_dram.h"
#include "intel_mchbar_regs.h"
#include "intel_parent.h"
#include "intel_pci_config.h"
#include "intel_pcode.h"
#include "intel_plane.h"
#include "intel_psr.h"
#include "intel_step.h"
@@ -888,7 +888,7 @@ static void bdw_set_cdclk(struct intel_display *display,
"trying to change cdclk frequency with cdclk not enabled\n"))
return;
ret = intel_pcode_write(display->drm, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
ret = intel_parent_pcode_write(display, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
if (ret) {
drm_err(display->drm,
"failed to inform pcode about cdclk change\n");
@@ -918,8 +918,8 @@ static void bdw_set_cdclk(struct intel_display *display,
if (ret)
drm_err(display->drm, "Switching back to LCPLL failed\n");
intel_pcode_write(display->drm, HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level);
intel_parent_pcode_write(display, HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level);
intel_de_write(display, CDCLK_FREQ,
DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
@@ -1175,10 +1175,10 @@ static void skl_set_cdclk(struct intel_display *display,
drm_WARN_ON_ONCE(display->drm,
display->platform.skylake && vco == 8640000);
ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
ret = intel_parent_pcode_request(display, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
if (ret) {
drm_err(display->drm,
"Failed to inform PCU about cdclk change (%d)\n", ret);
@@ -1221,8 +1221,8 @@ static void skl_set_cdclk(struct intel_display *display,
intel_de_posting_read(display, CDCLK_CTL);
/* inform PCU of the change */
intel_pcode_write(display->drm, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
intel_parent_pcode_write(display, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
intel_update_cdclk(display);
}
@@ -1870,7 +1870,7 @@ static void icl_cdclk_pll_disable(struct intel_display *display)
* after the PLL is enabled (which is already done as part of the
* normal flow of _bxt_set_cdclk()).
*/
if (intel_display_wa(display, 13012396614))
if (intel_display_wa(display, INTEL_DISPLAY_WA_13012396614))
intel_de_rmw(display, CDCLK_CTL, MDCLK_SOURCE_SEL_MASK, MDCLK_SOURCE_SEL_CD2XCLK);
intel_de_rmw(display, BXT_DE_PLL_ENABLE,
@@ -2186,7 +2186,8 @@ static u32 bxt_cdclk_ctl(struct intel_display *display,
* icl_cdclk_pll_disable(). Here we are just making sure
* we keep the expected value.
*/
if (intel_display_wa(display, 13012396614) && vco == 0)
if (intel_display_wa(display, INTEL_DISPLAY_WA_13012396614) &&
vco == 0)
val |= MDCLK_SOURCE_SEL_CD2XCLK;
else
val |= xe2lpd_mdclk_source_sel(display);
@@ -2247,18 +2248,18 @@ static void bxt_set_cdclk(struct intel_display *display,
if (DISPLAY_VER(display) >= 14 || display->platform.dg2)
; /* NOOP */
else if (DISPLAY_VER(display) >= 11)
ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
ret = intel_parent_pcode_request(display, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
else
/*
* BSpec requires us to wait up to 150usec, but that leads to
* timeouts; the 2ms used here is based on experiment.
*/
ret = intel_pcode_write_timeout(display->drm,
HSW_PCODE_DE_WRITE_FREQ_REQ,
0x80000000, 2);
ret = intel_parent_pcode_write_timeout(display,
HSW_PCODE_DE_WRITE_FREQ_REQ,
0x80000000, 2);
if (ret) {
drm_err(display->drm,
@@ -2287,8 +2288,8 @@ static void bxt_set_cdclk(struct intel_display *display,
* Display versions 14 and beyond
*/;
else if (DISPLAY_VER(display) >= 11 && !display->platform.dg2)
ret = intel_pcode_write(display->drm, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
ret = intel_parent_pcode_write(display, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
if (DISPLAY_VER(display) < 11) {
/*
* The timeout isn't specified, the 2ms used here is based on
@@ -2296,9 +2297,9 @@ static void bxt_set_cdclk(struct intel_display *display,
* FIXME: Waiting for the request completion could be delayed
* until the next PCODE request based on BSpec.
*/
ret = intel_pcode_write_timeout(display->drm,
HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level, 2);
ret = intel_parent_pcode_write_timeout(display,
HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level, 2);
}
if (ret) {
drm_err(display->drm,
@@ -2598,11 +2599,11 @@ static void intel_pcode_notify(struct intel_display *display,
if (pipe_count_update_valid)
update_mask |= DISPLAY_TO_PCODE_PIPE_COUNT_VALID;
ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE |
update_mask,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
ret = intel_parent_pcode_request(display, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE |
update_mask,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
if (ret)
drm_err(display->drm,
"Failed to inform PCU about display config (err %d)\n",
@@ -4006,7 +4007,7 @@ void intel_init_cdclk_hooks(struct intel_display *display)
display->cdclk.table = dg2_cdclk_table;
} else if (display->platform.alderlake_p) {
/* Wa_22011320316:adl-p[a0] */
if (display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) {
if (intel_display_wa(display, INTEL_DISPLAY_WA_22011320316)) {
display->cdclk.table = adlp_a_step_cdclk_table;
display->funcs.cdclk = &tgl_cdclk_funcs;
} else if (display->platform.alderlake_p_raptorlake_u) {
+11 -7
View File
@@ -33,6 +33,7 @@
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <video/vga.h>
#include "intel_connector.h"
#include "intel_crt.h"
@@ -55,6 +56,7 @@
#include "intel_pch_display.h"
#include "intel_pch_refclk.h"
#include "intel_pfit.h"
#include "intel_vga.h"
/* Here's the desired hotplug mode */
#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_ENABLE | \
@@ -691,6 +693,11 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
return ret;
}
static bool intel_crt_sense_above_threshold(struct intel_display *display)
{
return intel_vga_read(display, VGA_IS0_R, true) & (1 << 4);
}
static enum drm_connector_status
intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
{
@@ -702,7 +709,6 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
u32 vsample;
u32 vblank, vblank_start, vblank_end;
u32 dsl;
u8 st00;
enum drm_connector_status status;
drm_dbg_kms(display->drm, "starting load-detect on CRT\n");
@@ -736,8 +742,8 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
* border color for Color info.
*/
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe));
st00 = intel_de_read8(display, _VGA_MSR_WRITE);
status = ((st00 & (1 << 4)) != 0) ?
status = intel_crt_sense_above_threshold(display) ?
connector_status_connected :
connector_status_disconnected;
@@ -777,15 +783,13 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
while ((dsl = intel_de_read(display, PIPEDSL(display, pipe))) <= vsample)
;
/*
* Watch ST00 for an entire scanline
* Watch sense for an entire scanline
*/
detect = 0;
count = 0;
do {
count++;
/* Read the ST00 VGA status register */
st00 = intel_de_read8(display, _VGA_MSR_WRITE);
if (st00 & (1 << 4))
if (intel_crt_sense_above_threshold(display))
detect++;
} while ((intel_de_read(display, PIPEDSL(display, pipe)) == dsl));
@@ -45,6 +45,4 @@
#define ADPA_VSYNC_ACTIVE_HIGH REG_BIT(4)
#define ADPA_HSYNC_ACTIVE_HIGH REG_BIT(3)
#define _VGA_MSR_WRITE _MMIO(0x3c2)
#endif /* __INTEL_CRT_REGS_H__ */
+3 -1
View File
@@ -747,7 +747,9 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
* which would cause the next frame to terminate already at vmin
* vblank start instead of vmax vblank start.
*/
if (!state->base.legacy_cursor_update)
if (!state->base.legacy_cursor_update ||
(intel_psr_use_trans_push(new_crtc_state) &&
!new_crtc_state->vrr.enable))
intel_vrr_send_push(NULL, new_crtc_state);
local_irq_enable();

Some files were not shown because too many files have changed in this diff Show More