aboutsummaryrefslogtreecommitdiffstats
diff options
authorMark Brown <broonie@kernel.org>2026-05-29 22:42:13 +0100
committerMark Brown <broonie@kernel.org>2026-05-29 22:42:13 +0100
commit3c09a9267c25450885364263e8f90daffc65702f (patch)
treec5120c110f9f2f8708bb7e087a24b9ed5b7378fe
parentc7c18ef008859bbe0017e164f8522aef5bac3e7b (diff)
parent7185566c3db090aa5e17a17bca92dfcef9656b03 (diff)
downloadlinux-next-history-3c09a9267c25450885364263e8f90daffc65702f.tar.gz
Merge branch 'for-linux-next' of https://gitlab.freedesktop.org/drm/i915/kernel.git
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_wm.c32
-rw-r--r--drivers/gpu/drm/i915/display/intel_alpm.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c311
-rw-r--r--drivers/gpu/drm/i915/display/intel_casf.c32
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c47
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c17
-rw-r--r--drivers/gpu/drm/i915/display/intel_dbuf_bw.c7
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c208
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h80
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_core.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_driver.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_irq.c238
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_irq.h37
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c90
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h21
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_trace.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_wa.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_wa.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc_wl.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c178
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c19
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_test.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_tunnel.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_drrs.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_fdi.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_fifo_underrun.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_flipq.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_global_state.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_initial_plane.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_link_bw.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_load_detect.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_setup.c36
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_pmdemand.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c65
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_vrr.c4
-rw-r--r--drivers/gpu/drm/i915/display/skl_scaler.c76
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c2
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.c38
-rw-r--r--drivers/gpu/drm/i915/i915_driver.c32
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c185
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c2
-rw-r--r--drivers/gpu/drm/xe/display/xe_display.c64
58 files changed, 1185 insertions, 834 deletions
diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c
index 33d8f6b6afeaf..86d1c9f7f0ff0 100644
--- a/drivers/gpu/drm/i915/display/i9xx_wm.c
+++ b/drivers/gpu/drm/i915/display/i9xx_wm.c
@@ -640,7 +640,7 @@ static struct intel_crtc *single_enabled_crtc(struct intel_display *display)
{
struct intel_crtc *crtc, *enabled = NULL;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
if (intel_crtc_active(crtc)) {
if (enabled)
return NULL;
@@ -1393,7 +1393,7 @@ static void g4x_merge_wm(struct intel_display *display,
wm->hpll_en = true;
wm->fbc_en = true;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x;
if (!crtc->active)
@@ -1415,7 +1415,7 @@ static void g4x_merge_wm(struct intel_display *display,
wm->fbc_en = false;
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x;
enum pipe pipe = crtc->pipe;
@@ -2034,7 +2034,7 @@ static void vlv_merge_wm(struct intel_display *display,
wm->level = display->wm.num_levels - 1;
wm->cxsr = true;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv;
if (!crtc->active)
@@ -2053,7 +2053,7 @@ static void vlv_merge_wm(struct intel_display *display,
if (num_active_pipes > 1)
wm->level = VLV_WM_LEVEL_PM2;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv;
enum pipe pipe = crtc->pipe;
@@ -3078,7 +3078,7 @@ static void ilk_merge_wm_level(struct intel_display *display,
ret_wm->enable = true;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_pipe_wm *active = &crtc->wm.active.ilk;
const struct intel_wm_level *wm = &active->wm[level];
@@ -3218,7 +3218,7 @@ static void ilk_compute_wm_results(struct intel_display *display,
}
/* LP0 register values */
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
enum pipe pipe = crtc->pipe;
const struct intel_pipe_wm *pipe_wm = &crtc->wm.active.ilk;
const struct intel_wm_level *r = &pipe_wm->wm[0];
@@ -3416,7 +3416,7 @@ static void ilk_compute_wm_config(struct intel_display *display,
struct intel_crtc *crtc;
/* Compute the currently _active_ config */
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_pipe_wm *wm = &crtc->wm.active.ilk;
if (!wm->pipe_enabled)
@@ -3533,10 +3533,11 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc)
static int ilk_sanitize_watermarks_add_affected(struct drm_atomic_commit *state)
{
+ struct intel_display *display = to_intel_display(state->dev);
struct drm_plane *plane;
struct intel_crtc *crtc;
- for_each_intel_crtc(state->dev, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state;
crtc_state = intel_atomic_get_crtc_state(state, crtc);
@@ -3581,7 +3582,6 @@ void ilk_wm_sanitize(struct intel_display *display)
struct intel_crtc_state *crtc_state;
struct drm_modeset_acquire_ctx ctx;
int ret;
- int i;
/* Only supported on platforms that use atomic watermark design */
if (!display->wm.funcs->optimize_watermarks)
@@ -3619,7 +3619,7 @@ retry:
goto fail;
/* Write calculated watermark values back */
- for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state) {
crtc_state->wm.need_postvbl_update = true;
intel_optimize_watermarks(intel_state, crtc);
@@ -3769,7 +3769,7 @@ static void g4x_wm_get_hw_state(struct intel_display *display)
wm->cxsr = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct g4x_wm_state *active = &crtc->wm.active.g4x;
@@ -3884,7 +3884,7 @@ static void g4x_wm_sanitize(struct intel_display *display)
}
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
int ret;
@@ -3951,7 +3951,7 @@ static void vlv_wm_get_hw_state(struct intel_display *display)
vlv_punit_put(display);
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct vlv_wm_state *active = &crtc->wm.active.vlv;
@@ -4033,7 +4033,7 @@ static void vlv_wm_sanitize(struct intel_display *display)
}
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
int ret;
@@ -4074,7 +4074,7 @@ static void ilk_wm_get_hw_state(struct intel_display *display)
ilk_init_lp_watermarks(display);
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
ilk_pipe_wm_get_hw_state(crtc);
hw->wm_lp[0] = intel_de_read(display, WM1_LP_ILK);
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
index a7350ce8e7163..c6963ea420cc9 100644
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -11,6 +11,7 @@
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
+#include "intel_display_utils.h"
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_psr.h"
@@ -359,6 +360,23 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
crtc_state->has_lobf = true;
}
+static u32 get_pr_alpm_as_sdp_transmission_time(const struct intel_crtc_state *crtc_state)
+{
+ u8 as_sdp_setup_time = intel_dp_as_sdp_transmission_time();
+
+ switch (as_sdp_setup_time) {
+ case DP_PR_AS_SDP_SETUP_TIME_T1:
+ return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
+ case DP_PR_AS_SDP_SETUP_TIME_DYNAMIC:
+ return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1_OR_T2;
+ case DP_PR_AS_SDP_SETUP_TIME_T2:
+ return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T2;
+ default:
+ MISSING_CASE(as_sdp_setup_time);
+ return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
+ }
+}
+
static void lnl_alpm_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
@@ -382,7 +400,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
ALPM_CTL_AUX_LESS_WAKE_TIME(crtc_state->alpm_state.aux_less_wake_lines);
if (intel_dp->as_sdp_supported) {
- u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
+ u32 pr_alpm_ctl = get_pr_alpm_as_sdp_transmission_time(crtc_state);
if (crtc_state->link_off_after_as_sdp_when_pr_active)
pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 38bbd6964d8ee..0e4f0678c53cd 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -200,9 +200,8 @@ bool intel_any_crtc_needs_modeset(struct intel_atomic_state *state)
{
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
if (intel_crtc_needs_modeset(crtc_state))
return true;
}
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 9c3a9bbb49f66..dc5a5b639d872 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -67,25 +67,31 @@ struct intel_qgv_info {
u8 deinterleave;
};
+static int dclk_freq_mhz(int ratio)
+{
+ /* multiple of 16.666 MHz (100/6) */
+ return DIV_ROUND_CLOSEST(ratio * 100, 6);
+}
+
static int dg1_mchbar_read_qgv_point_info(struct intel_display *display,
struct intel_qgv_point *sp,
int point)
{
- u32 dclk_ratio, dclk_reference;
+ u32 dclk_ratio;
u32 val;
val = intel_mchbar_read(display, SA_PERF_STATUS_0_0_0_MCHBAR_PC);
dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val);
if (val & DG1_QCLK_REFERENCE)
- dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */
+ dclk_ratio *= 6; /* 6 * 16.666 MHz = 100 MHz */
else
- dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */
- sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000);
+ dclk_ratio *= 8; /* 8 * 16.666 MHz = 133 MHz */
val = intel_mchbar_read(display, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
if (val & DG1_GEAR_TYPE)
- sp->dclk *= 2;
+ dclk_ratio *= 2;
+ sp->dclk = dclk_freq_mhz(dclk_ratio);
if (sp->dclk == 0)
return -EINVAL;
@@ -107,7 +113,6 @@ static int icl_pcode_read_qgv_point_info(struct intel_display *display,
int point)
{
u32 val = 0, val2 = 0;
- u16 dclk;
int ret;
ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
@@ -116,9 +121,7 @@ static int icl_pcode_read_qgv_point_info(struct intel_display *display,
if (ret)
return ret;
- dclk = val & 0xffff;
- sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(display) >= 12 ? 500 : 0),
- 1000);
+ sp->dclk = dclk_freq_mhz(val & 0xffff);
sp->t_rp = (val & 0xff0000) >> 16;
sp->t_rcd = (val & 0xff000000) >> 24;
@@ -208,12 +211,11 @@ static int mtl_read_qgv_point_info(struct intel_display *display,
struct intel_qgv_point *sp, int point)
{
u32 val, val2;
- u16 dclk;
val = intel_de_read(display, MTL_MEM_SS_INFO_QGV_POINT_LOW(point));
val2 = intel_de_read(display, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point));
- dclk = REG_FIELD_GET(MTL_DCLK_MASK, val);
- sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000);
+
+ sp->dclk = dclk_freq_mhz(REG_FIELD_GET(MTL_DCLK_MASK, val));
sp->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val);
sp->t_rcd = REG_FIELD_GET(MTL_TRCD_MASK, val);
@@ -238,10 +240,15 @@ intel_read_qgv_point_info(struct intel_display *display,
return icl_pcode_read_qgv_point_info(display, sp, point);
}
+static bool is_y_tile(struct intel_display *display)
+{
+ /* assume Y tile may be used if supported */
+ return !HAS_4TILE(display);
+}
+
static int icl_get_qgv_points(struct intel_display *display,
const struct dram_info *dram_info,
- struct intel_qgv_info *qi,
- bool is_y_tile)
+ struct intel_qgv_info *qi)
{
int i, ret;
@@ -280,16 +287,16 @@ static int icl_get_qgv_points(struct intel_display *display,
} else if (DISPLAY_VER(display) >= 12) {
switch (dram_info->type) {
case INTEL_DRAM_DDR4:
- qi->t_bl = is_y_tile ? 8 : 4;
+ qi->t_bl = is_y_tile(display) ? 8 : 4;
qi->max_numchannels = 2;
qi->channel_width = 64;
- qi->deinterleave = is_y_tile ? 1 : 2;
+ qi->deinterleave = is_y_tile(display) ? 1 : 2;
break;
case INTEL_DRAM_DDR5:
- qi->t_bl = is_y_tile ? 16 : 8;
+ qi->t_bl = is_y_tile(display) ? 16 : 8;
qi->max_numchannels = 4;
qi->channel_width = 32;
- qi->deinterleave = is_y_tile ? 1 : 2;
+ qi->deinterleave = is_y_tile(display) ? 1 : 2;
break;
case INTEL_DRAM_LPDDR4:
if (display->platform.rocketlake) {
@@ -304,7 +311,7 @@ static int icl_get_qgv_points(struct intel_display *display,
qi->t_bl = 16;
qi->max_numchannels = 8;
qi->channel_width = 16;
- qi->deinterleave = is_y_tile ? 2 : 4;
+ qi->deinterleave = is_y_tile(display) ? 2 : 4;
break;
default:
qi->t_bl = 16;
@@ -372,85 +379,144 @@ static int icl_sagv_max_dclk(const struct intel_qgv_info *qi)
return dclk;
}
-struct intel_sa_info {
- u16 displayrtids;
- u8 deburst, deprogbwlimit, derating;
+/*
+ * Bandwidth parameters that are tied to the SoC (as opposed to struct
+ * intel_display_bw_params).
+ */
+struct intel_soc_bw_params {
+ u8 deprogbwlimit;
+ u8 derating;
};
-static const struct intel_sa_info icl_sa_info = {
- .deburst = 8,
- .deprogbwlimit = 25, /* GB/s */
- .displayrtids = 128,
+static const struct intel_soc_bw_params icl_bw_params = {
+ .deprogbwlimit = 25,
.derating = 10,
};
-static const struct intel_sa_info tgl_sa_info = {
- .deburst = 16,
- .deprogbwlimit = 34, /* GB/s */
- .displayrtids = 256,
+static const struct intel_soc_bw_params tgl_bw_params = {
+ .deprogbwlimit = 34,
.derating = 10,
};
-static const struct intel_sa_info rkl_sa_info = {
- .deburst = 8,
- .deprogbwlimit = 20, /* GB/s */
- .displayrtids = 128,
+static const struct intel_soc_bw_params rkl_bw_params = {
+ .deprogbwlimit = 20,
.derating = 10,
};
-static const struct intel_sa_info adls_sa_info = {
- .deburst = 16,
- .deprogbwlimit = 38, /* GB/s */
- .displayrtids = 256,
+static const struct intel_soc_bw_params adl_s_bw_params = {
+ .deprogbwlimit = 38,
.derating = 10,
};
-static const struct intel_sa_info adlp_sa_info = {
- .deburst = 16,
- .deprogbwlimit = 38, /* GB/s */
- .displayrtids = 256,
+static const struct intel_soc_bw_params adl_p_bw_params = {
+ .deprogbwlimit = 38,
.derating = 20,
};
-static const struct intel_sa_info mtl_sa_info = {
- .deburst = 32,
- .deprogbwlimit = 38, /* GB/s */
- .displayrtids = 256,
- .derating = 10,
+static const struct intel_soc_bw_params bmg_bw_params = {
+ .deprogbwlimit = 53,
+ .derating = 30,
};
-static const struct intel_sa_info xe2_hpd_sa_info = {
- .derating = 30,
+static const struct intel_soc_bw_params bmg_ecc_bw_params = {
.deprogbwlimit = 53,
- /* Other values not used by simplified algorithm */
+ .derating = 45,
};
-static const struct intel_sa_info xe2_hpd_ecc_sa_info = {
- .derating = 45,
- .deprogbwlimit = 53,
- /* Other values not used by simplified algorithm */
+static const struct intel_soc_bw_params ptl_bw_params = {
+ .deprogbwlimit = 65,
+ .derating = 10,
};
-static const struct intel_sa_info xe3lpd_sa_info = {
- .deburst = 32,
- .deprogbwlimit = 65, /* GB/s */
- .displayrtids = 256,
+static const struct intel_soc_bw_params wcl_bw_params = {
+ .deprogbwlimit = 22,
.derating = 10,
};
-static const struct intel_sa_info xe3lpd_3002_sa_info = {
+static const struct intel_soc_bw_params *get_soc_bw_params(struct intel_display *display,
+ const struct dram_info *dram_info)
+{
+ if (display->platform.icelake ||
+ display->platform.jasperlake ||
+ display->platform.elkhartlake)
+ return &icl_bw_params;
+ else if (display->platform.tigerlake ||
+ display->platform.dg1)
+ return &tgl_bw_params;
+ else if (display->platform.rocketlake)
+ return &rkl_bw_params;
+ else if (display->platform.alderlake_s ||
+ display->platform.meteorlake ||
+ display->platform.lunarlake)
+ return &adl_s_bw_params;
+ else if (display->platform.alderlake_p)
+ return &adl_p_bw_params;
+ else if (display->platform.battlemage &&
+ dram_info->type == INTEL_DRAM_GDDR_ECC)
+ return &bmg_ecc_bw_params;
+ else if (display->platform.battlemage)
+ return &bmg_bw_params;
+ else if (display->platform.pantherlake_wildcatlake)
+ return &wcl_bw_params;
+ else if (display->platform.pantherlake ||
+ display->platform.novalake)
+ return &ptl_bw_params;
+
+ return NULL;
+}
+
+/*
+ * Bandwidth parameters that are tied to the display IP (as opposed to struct
+ * intel_soc_bw_params).
+ */
+struct intel_display_bw_params {
+ u16 displayrtids;
+ u8 deburst;
+};
+
+static const struct intel_display_bw_params gen11_bw_params = {
+ .deburst = 8,
+ .displayrtids = 128,
+};
+
+static const struct intel_display_bw_params gen12_bw_params = {
+ .deburst = 16,
+ .displayrtids = 256,
+};
+
+static const struct intel_display_bw_params xelpdp_bw_params = {
.deburst = 32,
- .deprogbwlimit = 22, /* GB/s */
.displayrtids = 256,
- .derating = 10,
};
+static const struct intel_display_bw_params *get_display_bw_params(struct intel_display *display)
+{
+ if (DISPLAY_VER(display) >= 14) {
+ return &xelpdp_bw_params;
+ } else if (DISPLAY_VER(display) >= 12) {
+ /*
+ * RKL's SoC was based on ICL and the display, even though being
+ * gen12, had changes to the memory interface to match gen11's,
+ * consequently inheriting gen11's display-specific bandwidth
+ * parameters.
+ */
+ if (display->platform.rocketlake)
+ return &gen11_bw_params;
+ else
+ return &gen12_bw_params;
+ } else if (DISPLAY_VER(display) == 11) {
+ return &gen11_bw_params;
+ }
+
+ return NULL;
+}
+
static int icl_get_bw_info(struct intel_display *display,
const struct dram_info *dram_info,
- const struct intel_sa_info *sa)
+ const struct intel_soc_bw_params *soc_bw_params,
+ const struct intel_display_bw_params *display_bw_params)
{
struct intel_qgv_info qi = {};
- bool is_y_tile = true; /* assume y tile may be used */
int num_channels = max_t(u8, 1, dram_info->num_channels);
int ipqdepth, ipqdepthpch = 16;
int dclk_max;
@@ -458,7 +524,7 @@ static int icl_get_bw_info(struct intel_display *display,
int num_groups = ARRAY_SIZE(display->bw.max);
int i, ret;
- ret = icl_get_qgv_points(display, dram_info, &qi, is_y_tile);
+ ret = icl_get_qgv_points(display, dram_info, &qi);
if (ret) {
drm_dbg_kms(display->drm,
"Failed to get memory subsystem information, ignoring bandwidth limits");
@@ -466,16 +532,16 @@ static int icl_get_bw_info(struct intel_display *display,
}
dclk_max = icl_sagv_max_dclk(&qi);
- maxdebw = min(sa->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10);
- ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
- qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
+ maxdebw = min(soc_bw_params->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10);
+ ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels);
+ qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile(display) ? 4 : 2);
for (i = 0; i < num_groups; i++) {
struct intel_bw_info *bi = &display->bw.max[i];
int clpchgroup;
int j;
- clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i;
+ clpchgroup = (display_bw_params->deburst * qi.deinterleave / num_channels) << i;
bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
bi->num_qgv_points = qi.num_points;
@@ -493,10 +559,10 @@ static int icl_get_bw_info(struct intel_display *display,
*/
ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd +
(clpchgroup - 1) * qi.t_bl + sp->t_rdpre);
- bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct);
+ bw = sp->dclk * clpchgroup * 32 * num_channels / ct;
bi->deratedbw[j] = min(maxdebw,
- bw * (100 - sa->derating) / 100);
+ bw * (100 - soc_bw_params->derating) / 100);
drm_dbg_kms(display->drm,
"BW%d / QGV %d: num_planes=%d deratedbw=%u\n",
@@ -516,21 +582,25 @@ static int icl_get_bw_info(struct intel_display *display,
return 0;
}
+static int tgl_peakbw(int num_channels, int channel_width, int dclk)
+{
+ return num_channels * (channel_width / 8) * dclk;
+}
+
static int tgl_get_bw_info(struct intel_display *display,
const struct dram_info *dram_info,
- const struct intel_sa_info *sa)
+ const struct intel_soc_bw_params *soc_bw_params,
+ const struct intel_display_bw_params *display_bw_params)
{
struct intel_qgv_info qi = {};
- bool is_y_tile = true; /* assume y tile may be used */
int num_channels = max_t(u8, 1, dram_info->num_channels);
int ipqdepth, ipqdepthpch = 16;
- int dclk_max;
int maxdebw, peakbw;
int clperchgroup;
int num_groups = ARRAY_SIZE(display->bw.max);
int i, ret;
- ret = icl_get_qgv_points(display, dram_info, &qi, is_y_tile);
+ ret = icl_get_qgv_points(display, dram_info, &qi);
if (ret) {
drm_dbg_kms(display->drm,
"Failed to get memory subsystem information, ignoring bandwidth limits");
@@ -541,27 +611,23 @@ static int tgl_get_bw_info(struct intel_display *display,
(dram_info->type == INTEL_DRAM_LPDDR4 || dram_info->type == INTEL_DRAM_LPDDR5))
num_channels *= 2;
- qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
-
if (num_channels < qi.max_numchannels && DISPLAY_VER(display) >= 12)
- qi.deinterleave = max(DIV_ROUND_UP(qi.deinterleave, 2), 1);
+ qi.deinterleave = max(qi.deinterleave / 2, 1);
if (DISPLAY_VER(display) >= 12 && num_channels > qi.max_numchannels)
drm_warn(display->drm, "Number of channels exceeds max number of channels.");
if (qi.max_numchannels != 0)
num_channels = min_t(u8, num_channels, qi.max_numchannels);
- dclk_max = icl_sagv_max_dclk(&qi);
-
- peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max;
- maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100);
+ peakbw = tgl_peakbw(num_channels, qi.channel_width, icl_sagv_max_dclk(&qi));
+ maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100);
- ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
+ ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels);
/*
* clperchgroup = 4kpagespermempage * clperchperblock,
* clperchperblock = 8 / num_channels * interleave
*/
- clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave;
+ clperchgroup = 4 * (8 / num_channels) * qi.deinterleave;
for (i = 0; i < num_groups; i++) {
struct intel_bw_info *bi = &display->bw.max[i];
@@ -569,14 +635,13 @@ static int tgl_get_bw_info(struct intel_display *display,
int clpchgroup;
int j;
- clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i;
+ clpchgroup = (display_bw_params->deburst * qi.deinterleave / num_channels) << i;
if (i < num_groups - 1) {
bi_next = &display->bw.max[i + 1];
if (clpchgroup < clperchgroup)
- bi_next->num_planes = (ipqdepth - clpchgroup) /
- clpchgroup + 1;
+ bi_next->num_planes = (ipqdepth - clpchgroup) / clpchgroup;
else
bi_next->num_planes = 0;
}
@@ -596,13 +661,11 @@ static int tgl_get_bw_info(struct intel_display *display,
*/
ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd +
(clpchgroup - 1) * qi.t_bl + sp->t_rdpre);
- bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct);
+ bw = sp->dclk * clpchgroup * 32 * num_channels / ct;
bi->deratedbw[j] = min(maxdebw,
- bw * (100 - sa->derating) / 100);
- bi->peakbw[j] = DIV_ROUND_CLOSEST(sp->dclk *
- num_channels *
- qi.channel_width, 8);
+ bw * (100 - soc_bw_params->derating) / 100);
+ bi->peakbw[j] = tgl_peakbw(num_channels, qi.channel_width, sp->dclk);
drm_dbg_kms(display->drm,
"BW%d / QGV %d: num_planes=%d deratedbw=%u peakbw: %u\n",
@@ -661,29 +724,29 @@ static void dg2_get_bw_info(struct intel_display *display)
static int xe2_hpd_get_bw_info(struct intel_display *display,
const struct dram_info *dram_info,
- const struct intel_sa_info *sa)
+ const struct intel_soc_bw_params *soc_bw_params)
{
struct intel_qgv_info qi = {};
int num_channels = dram_info->num_channels;
int peakbw, maxdebw;
int ret, i;
- ret = icl_get_qgv_points(display, dram_info, &qi, true);
+ ret = icl_get_qgv_points(display, dram_info, &qi);
if (ret) {
drm_dbg_kms(display->drm,
"Failed to get memory subsystem information, ignoring bandwidth limits");
return ret;
}
- peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi);
- maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 10);
+ peakbw = tgl_peakbw(num_channels, qi.channel_width, icl_sagv_max_dclk(&qi));
+ maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100);
for (i = 0; i < qi.num_points; i++) {
- const struct intel_qgv_point *point = &qi.points[i];
- int bw = num_channels * (qi.channel_width / 8) * point->dclk;
+ const struct intel_qgv_point *sp = &qi.points[i];
+ int bw = tgl_peakbw(num_channels, qi.channel_width, sp->dclk);
display->bw.max[0].deratedbw[i] =
- min(maxdebw, (100 - sa->derating) * bw / 100);
+ min(maxdebw, (100 - soc_bw_params->derating) * bw / 100);
display->bw.max[0].peakbw[i] = bw;
drm_dbg_kms(display->drm, "QGV %d: deratedbw=%u peakbw: %u\n",
@@ -741,11 +804,6 @@ static unsigned int tgl_max_bw_index(struct intel_display *display,
{
int i;
- /*
- * Let's return max bw for 0 planes
- */
- num_planes = max(1, num_planes);
-
for (i = ARRAY_SIZE(display->bw.max) - 1; i >= 0; i--) {
const struct intel_bw_info *bi =
&display->bw.max[i];
@@ -791,11 +849,17 @@ static unsigned int icl_qgv_bw(struct intel_display *display,
void intel_bw_init_hw(struct intel_display *display)
{
- const struct dram_info *dram_info = intel_dram_info(display);
+ const struct dram_info *dram_info;
+ const struct intel_soc_bw_params *soc_bw_params;
+ const struct intel_display_bw_params *display_bw_params;
if (!HAS_DISPLAY(display))
return;
+ dram_info = intel_dram_info(display);
+ soc_bw_params = get_soc_bw_params(display, dram_info);
+ display_bw_params = get_display_bw_params(display);
+
/*
* Starting with Xe3p_LPD, the hardware tells us whether memory has ECC
* enabled that would impact display bandwidth. However, so far there
@@ -805,30 +869,14 @@ void intel_bw_init_hw(struct intel_display *display)
if (DISPLAY_VER(display) >= 35)
drm_WARN_ON(display->drm, dram_info->ecc_impacting_de_bw);
- if (DISPLAY_VER(display) >= 30) {
- if (DISPLAY_VERx100(display) == 3002)
- tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
- else
- tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
- } else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) {
- if (dram_info->type == INTEL_DRAM_GDDR_ECC)
- xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_ecc_sa_info);
- else
- xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info);
- } else if (DISPLAY_VER(display) >= 14) {
- tgl_get_bw_info(display, dram_info, &mtl_sa_info);
+ if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) {
+ xe2_hpd_get_bw_info(display, dram_info, soc_bw_params);
} else if (display->platform.dg2) {
dg2_get_bw_info(display);
- } else if (display->platform.alderlake_p) {
- tgl_get_bw_info(display, dram_info, &adlp_sa_info);
- } else if (display->platform.alderlake_s) {
- tgl_get_bw_info(display, dram_info, &adls_sa_info);
- } else if (display->platform.rocketlake) {
- tgl_get_bw_info(display, dram_info, &rkl_sa_info);
- } else if (DISPLAY_VER(display) == 12) {
- tgl_get_bw_info(display, dram_info, &tgl_sa_info);
+ } else if (DISPLAY_VER(display) >= 12) {
+ tgl_get_bw_info(display, dram_info, soc_bw_params, display_bw_params);
} else if (DISPLAY_VER(display) == 11) {
- icl_get_bw_info(display, dram_info, &icl_sa_info);
+ icl_get_bw_info(display, dram_info, soc_bw_params, display_bw_params);
}
}
@@ -1103,7 +1151,7 @@ static int mtl_find_qgv_points(struct intel_display *display,
}
/* MTL PM DEMAND expects QGV BW parameter in multiples of 100 mbps */
- new_bw_state->qgv_point_peakbw = DIV_ROUND_CLOSEST(qgv_peak_bw, 100);
+ new_bw_state->qgv_point_peakbw = qgv_peak_bw / 100;
return 0;
}
@@ -1219,10 +1267,8 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
unsigned int old_data_rate =
intel_crtc_bw_data_rate(old_crtc_state);
unsigned int new_data_rate =
@@ -1268,10 +1314,9 @@ static int intel_bw_check_sagv_mask(struct intel_atomic_state *state)
const struct intel_bw_state *old_bw_state = NULL;
struct intel_bw_state *new_bw_state = NULL;
struct intel_crtc *crtc;
- int ret, i;
+ int ret;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (intel_crtc_can_enable_sagv(old_crtc_state) ==
intel_crtc_can_enable_sagv(new_crtc_state))
continue;
@@ -1378,7 +1423,7 @@ void intel_bw_update_hw_state(struct intel_display *display)
bw_state->pipe_sagv_reject = 0;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c
index c2d2746c5f041..cafd21a036320 100644
--- a/drivers/gpu/drm/i915/display/intel_casf.c
+++ b/drivers/gpu/drm/i915/display/intel_casf.c
@@ -88,7 +88,7 @@ static void intel_casf_compute_win_size(struct intel_crtc_state *crtc_state)
crtc_state->pch_pfit.casf.win_size = SHARPNESS_FILTER_SIZE_7X7;
}
-static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state);
+static void intel_casf_scaler_compute_coeff(struct intel_crtc_state *crtc_state);
int intel_casf_compute_config(struct intel_crtc_state *crtc_state)
{
@@ -118,7 +118,7 @@ int intel_casf_compute_config(struct intel_crtc_state *crtc_state)
intel_casf_compute_win_size(crtc_state);
- intel_casf_scaler_compute_coef(crtc_state);
+ intel_casf_scaler_compute_coeff(crtc_state);
return 0;
}
@@ -148,12 +148,12 @@ static int casf_coeff_tap(int i)
return i % SCALER_FILTER_NUM_TAPS;
}
-static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int t)
+static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int tap)
{
struct scaler_filter_coeff value;
u32 coeff;
- value = crtc_state->pch_pfit.casf.coeff[t];
+ value = crtc_state->pch_pfit.casf.coeff[tap];
value.sign = 0;
coeff = value.sign << 15 | value.exp << 12 | value.mantissa << 3;
@@ -162,7 +162,7 @@ static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int t)
/*
* 17 phase of 7 taps requires 119 coefficients in 60 dwords per set.
- * To enable casf: program scaler coefficients with the coeffients
+ * To enable casf: program scaler coefficients with the coefficients
* that are calculated and stored in pch_pfit.casf.coeff as per
* SCALER_COEFFICIENT_FORMAT
*/
@@ -183,20 +183,20 @@ static void intel_casf_write_coeff(const struct intel_crtc_state *crtc_state)
for (i = 0; i < 17 * SCALER_FILTER_NUM_TAPS; i += 2) {
u32 tmp;
- int t;
+ int tap;
- t = casf_coeff_tap(i);
- tmp = casf_coeff(crtc_state, t);
+ tap = casf_coeff_tap(i);
+ tmp = casf_coeff(crtc_state, tap);
- t = casf_coeff_tap(i + 1);
- tmp |= casf_coeff(crtc_state, t) << 16;
+ tap = casf_coeff_tap(i + 1);
+ tmp |= casf_coeff(crtc_state, tap) << 16;
intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 0),
tmp);
}
}
-static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff,
+static void convert_sharpness_coeff_binary(struct scaler_filter_coeff *coeff,
u16 coefficient)
{
if (coefficient < 25) {
@@ -214,11 +214,11 @@ static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff,
}
}
-static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state)
+static void intel_casf_scaler_compute_coeff(struct intel_crtc_state *crtc_state)
{
const u16 *filtercoeff;
u16 filter_coeff[SCALER_FILTER_NUM_TAPS];
- u16 sumcoeff = 0;
+ u16 sum_coeff = 0;
int i;
if (crtc_state->pch_pfit.casf.win_size == 0)
@@ -229,11 +229,11 @@ static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state)
filtercoeff = filtercoeff_3;
for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++)
- sumcoeff += *(filtercoeff + i);
+ sum_coeff += *(filtercoeff + i);
for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) {
- filter_coeff[i] = (*(filtercoeff + i) * 100 / sumcoeff);
- convert_sharpness_coef_binary(&crtc_state->pch_pfit.casf.coeff[i],
+ filter_coeff[i] = (*(filtercoeff + i) * 100 / sum_coeff);
+ convert_sharpness_coeff_binary(&crtc_state->pch_pfit.casf.coeff[i],
filter_coeff[i]);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index a1bf01021d65d..189ae2d3cfc9e 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -3124,10 +3124,9 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
u8 min_voltage_level;
- int i;
enum pipe pipe;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
int ret;
if (crtc_state->hw.enable)
@@ -3219,13 +3218,13 @@ static int skl_dpll0_vco(struct intel_atomic_state *state)
intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
- int vco, i;
+ int vco;
vco = cdclk_state->logical.vco;
if (!vco)
vco = display->cdclk.skl_preferred_vco_freq;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
if (!crtc_state->hw.enable)
continue;
@@ -3424,10 +3423,9 @@ static int intel_crtcs_calc_min_cdclk(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state;
const struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int i, ret;
+ int ret;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
ret = intel_cdclk_update_crtc_min_cdclk(state, crtc,
old_crtc_state->min_cdclk,
new_crtc_state->min_cdclk,
@@ -3647,7 +3645,7 @@ void intel_cdclk_update_hw_state(struct intel_display *display)
cdclk_state->enabled_pipes = 0;
cdclk_state->active_pipes = 0;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 3bfe09d81a4c0..7ef870cd9a169 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -1102,19 +1102,37 @@ static void skl_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ u32 color;
crtc_state->gamma_mode = hsw_read_gamma_mode(crtc);
crtc_state->csc_mode = ilk_read_csc_mode(crtc);
+ color = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe));
if (DISPLAY_VER(display) < 35) {
- u32 tmp = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe));
-
- if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
+ if (color & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
crtc_state->gamma_enable = true;
- if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
+ if (color & SKL_BOTTOM_COLOR_CSC_ENABLE)
crtc_state->csc_enable = true;
}
+
+ crtc_state->hw.background_color = color & GENMASK(29, 0);
+}
+
+u32 intel_color_background_color_drm_to_hw(u64 drm_background_color)
+{
+ return (DRM_ARGB64_GETR_BPC(drm_background_color, 10) << 20) |
+ (DRM_ARGB64_GETG_BPC(drm_background_color, 10) << 10) |
+ (DRM_ARGB64_GETB_BPC(drm_background_color, 10));
+}
+
+u64 intel_color_background_color_hw_to_drm(u32 hw_background_color)
+{
+ u16 r = (hw_background_color >> 20) & 0x3ff;
+ u16 g = (hw_background_color >> 10) & 0x3ff;
+ u16 b = hw_background_color & 0x3ff;
+
+ return DRM_ARGB64_PREP_BPC(0x3ff, r, g, b, 10);
}
static void skl_color_commit_arm(struct intel_dsb *dsb,
@@ -1123,16 +1141,11 @@ static void skl_color_commit_arm(struct intel_dsb *dsb,
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum pipe pipe = crtc->pipe;
- u32 val = 0;
+ u32 val = crtc_state->hw.background_color;
if (crtc_state->has_psr)
ilk_load_csc_matrix(dsb, crtc_state);
- /*
- * We don't (yet) allow userspace to control the pipe background color,
- * so force it to black, but apply pipe gamma and CSC appropriately
- * so that its handling will match how we program our planes.
- */
if (crtc_state->gamma_enable)
val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
if (crtc_state->csc_enable)
@@ -1151,11 +1164,7 @@ static void icl_color_commit_arm(struct intel_dsb *dsb,
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum pipe pipe = crtc->pipe;
- /*
- * We don't (yet) allow userspace to control the pipe background color,
- * so force it to black.
- */
- intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), 0);
+ intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), crtc_state->hw.background_color);
intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
@@ -2107,9 +2116,15 @@ int intel_color_check(struct intel_atomic_state *state,
* May need to update pipe gamma enable bits
* when C8 planes are getting enabled/disabled.
*/
- if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes)
+ if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes ||
+ old_crtc_state->hw.background_color != new_crtc_state->hw.background_color)
new_crtc_state->uapi.color_mgmt_changed = true;
+ if (DRM_ARGB64_GETA(new_crtc_state->uapi.background_color) != 0xffff) {
+ drm_dbg_kms(display->drm, "New background not completely opaque\n");
+ return -EINVAL;
+ }
+
if (!intel_crtc_needs_color_update(new_crtc_state))
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h
index c21b9bdf7bb8a..f3963a8d1239f 100644
--- a/drivers/gpu/drm/i915/display/intel_color.h
+++ b/drivers/gpu/drm/i915/display/intel_color.h
@@ -47,4 +47,7 @@ void intel_color_plane_program_pipeline(struct intel_dsb *dsb,
void intel_color_plane_commit_arm(struct intel_dsb *dsb,
const struct intel_plane_state *plane_state);
bool intel_color_crtc_has_3dlut(struct intel_display *display, enum pipe pipe);
+u32 intel_color_background_color_drm_to_hw(u64 drm_background_color);
+u64 intel_color_background_color_hw_to_drm(u32 hw_background_color);
+
#endif /* __INTEL_COLOR_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 03de219f7a645..7ce2b52297d17 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
@@ -55,7 +56,7 @@ struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display,
{
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
if (crtc->pipe == pipe)
return crtc;
}
@@ -405,6 +406,9 @@ static int __intel_crtc_init(struct intel_display *display, enum pipe pipe)
BIT(DRM_SCALING_FILTER_DEFAULT) |
BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
+ if (DISPLAY_VER(display) >= 9)
+ drm_crtc_attach_background_color_property(&crtc->base);
+
intel_color_crtc_init(crtc);
intel_drrs_crtc_init(crtc);
intel_crtc_crc_init(crtc);
@@ -534,9 +538,8 @@ void intel_wait_for_vblank_workers(struct intel_atomic_state *state)
{
struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
if (!intel_crtc_needs_vblank_work(crtc_state))
continue;
@@ -828,10 +831,8 @@ bool intel_any_crtc_enable_changed(struct intel_atomic_state *state)
{
const struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (intel_crtc_enable_changed(old_crtc_state, new_crtc_state))
return true;
}
@@ -849,10 +850,8 @@ bool intel_any_crtc_active_changed(struct intel_atomic_state *state)
{
const struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (intel_crtc_active_changed(old_crtc_state, new_crtc_state))
return true;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c
index 0562d4df6a078..6cf674c586dc4 100644
--- a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c
@@ -184,13 +184,12 @@ int intel_dbuf_bw_calc_min_cdclk(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state;
const struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int ret, i;
+ int ret;
if (DISPLAY_VER(display) < 9)
return 0;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
struct intel_dbuf_bw old_dbuf_bw, new_dbuf_bw;
skl_crtc_calc_dbuf_bw(&old_dbuf_bw, old_crtc_state);
@@ -236,7 +235,7 @@ void intel_dbuf_bw_update_hw_state(struct intel_display *display)
if (DISPLAY_VER(display) < 9)
return;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 86520848892e0..205978c9feb6d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3230,9 +3230,8 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *pipe_crtc;
bool is_hdmi = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI);
- int i;
- for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -3259,7 +3258,7 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state,
intel_ddi_disable_transcoder_func(old_crtc_state);
- for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -3516,7 +3515,6 @@ static void intel_ddi_enable(struct intel_atomic_state *state,
struct intel_crtc *pipe_crtc;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
bool is_hdmi = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
- int i;
/* 128b/132b SST */
if (!is_hdmi && intel_dp_is_uhbr(crtc_state)) {
@@ -3550,7 +3548,7 @@ static void intel_ddi_enable(struct intel_atomic_state *state,
intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
- for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state, i) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -3672,7 +3670,7 @@ void intel_ddi_update_active_dpll(struct intel_atomic_state *state,
if (!intel_encoder_is_tc(encoder) || !display->dpll.mgr)
return;
- for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, pipe_crtc,
intel_crtc_joined_pipe_mask(crtc_state))
intel_dpll_update_active(state, pipe_crtc, encoder);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 9094ab4a9b6c1..8e269b71f18e4 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -714,22 +714,22 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state)
bool intel_has_pending_fb_unpin(struct intel_display *display)
{
- struct drm_crtc *crtc;
+ struct intel_crtc *crtc;
bool cleanup_done;
- drm_for_each_crtc(crtc, display->drm) {
+ for_each_intel_crtc(display, crtc) {
struct drm_crtc_commit *commit;
- spin_lock(&crtc->commit_lock);
- commit = list_first_entry_or_null(&crtc->commit_list,
+ spin_lock(&crtc->base.commit_lock);
+ commit = list_first_entry_or_null(&crtc->base.commit_list,
struct drm_crtc_commit, commit_entry);
cleanup_done = commit ?
try_wait_for_completion(&commit->cleanup_done) : true;
- spin_unlock(&crtc->commit_lock);
+ spin_unlock(&crtc->base.commit_lock);
if (cleanup_done)
continue;
- intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc));
+ intel_crtc_wait_for_next_vblank(crtc);
return true;
}
@@ -737,6 +737,28 @@ bool intel_has_pending_fb_unpin(struct intel_display *display)
return false;
}
+/* FIXME: remove this and just flush the cleanup wq where appropriate */
+void intel_display_flush_cleanup_work(struct intel_display *display)
+{
+ struct intel_crtc *crtc;
+
+ for_each_intel_crtc(display, crtc) {
+ struct drm_crtc_commit *commit;
+
+ spin_lock(&crtc->base.commit_lock);
+ commit = list_first_entry_or_null(&crtc->base.commit_list,
+ struct drm_crtc_commit, commit_entry);
+ if (commit)
+ drm_crtc_commit_get(commit);
+ spin_unlock(&crtc->base.commit_lock);
+
+ if (commit) {
+ wait_for_completion(&commit->cleanup_done);
+ drm_crtc_commit_put(commit);
+ }
+ }
+}
+
/*
* Finds the encoder associated with the given CRTC. This can only be
* used when we know that the CRTC isn't feeding multiple encoders!
@@ -1295,14 +1317,13 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state)
struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *new_crtc_state, *old_crtc_state;
struct intel_crtc *crtc;
- int i;
/*
* Make sure the DPLL state is up-to-date for fastset TypeC ports after non-blocking commits.
* TODO: Update the DPLL state for all cases in the encoder->update_prepare() hook.
*/
if (display->dpll.mgr) {
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (intel_crtc_needs_modeset(new_crtc_state))
continue;
@@ -1633,11 +1654,10 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc);
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
struct intel_crtc *pipe_crtc;
- int i;
if (drm_WARN_ON(display->drm, crtc->active))
return;
- for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) {
const struct intel_crtc_state *new_pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -1651,7 +1671,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
intel_encoders_pre_enable(state, crtc);
- for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -1669,7 +1689,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
if (!transcoder_is_dsi(cpu_transcoder))
hsw_configure_cpu_transcoder(new_crtc_state);
- for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -1699,7 +1719,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
intel_encoders_enable(state, crtc);
- for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
enum pipe hsw_workaround_pipe;
@@ -1767,7 +1787,6 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_crtc *pipe_crtc;
- int i;
/*
* FIXME collapse everything to one hook.
@@ -1780,7 +1799,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
intel_encoders_post_pll_disable(state, crtc);
- for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -3505,7 +3524,7 @@ static void enabled_uncompressed_joiner_pipes(struct intel_display *display,
if (!HAS_UNCOMPRESSED_JOINER(display))
return;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc,
+ for_each_intel_crtc_in_pipe_mask(display, crtc,
joiner_pipes(display)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
@@ -3533,7 +3552,7 @@ static void enabled_bigjoiner_pipes(struct intel_display *display,
if (!HAS_BIGJOINER(display))
return;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc,
+ for_each_intel_crtc_in_pipe_mask(display, crtc,
joiner_pipes(display)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
@@ -3602,7 +3621,7 @@ static void enabled_ultrajoiner_pipes(struct intel_display *display,
if (!HAS_ULTRAJOINER(display))
return;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc,
+ for_each_intel_crtc_in_pipe_mask(display, crtc,
joiner_pipes(display)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
@@ -4505,6 +4524,8 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
crtc_state->uapi.gamma_lut);
drm_property_replace_blob(&crtc_state->hw.ctm,
crtc_state->uapi.ctm);
+ crtc_state->hw.background_color =
+ intel_color_background_color_drm_to_hw(crtc_state->uapi.background_color);
}
static void
@@ -4544,6 +4565,7 @@ copy_joiner_crtc_state_nomodeset(struct intel_atomic_state *state,
primary_crtc_state->hw.gamma_lut);
drm_property_replace_blob(&secondary_crtc_state->hw.ctm,
primary_crtc_state->hw.ctm);
+ secondary_crtc_state->hw.background_color = primary_crtc_state->hw.background_color;
secondary_crtc_state->uapi.color_mgmt_changed = primary_crtc_state->uapi.color_mgmt_changed;
}
@@ -4881,11 +4903,16 @@ static bool
intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a,
const struct drm_dp_as_sdp *b)
{
- return a->vtotal == b->vtotal &&
+ return a->sdp_type == b->sdp_type &&
+ a->revision == b->revision &&
+ a->length == b->length &&
+ a->vtotal == b->vtotal &&
a->target_rr == b->target_rr &&
a->duration_incr_ms == b->duration_incr_ms &&
a->duration_decr_ms == b->duration_decr_ms &&
- a->mode == b->mode;
+ a->target_rr_divider == b->target_rr_divider &&
+ a->mode == b->mode &&
+ a->coasting_vtotal == b->coasting_vtotal;
}
static bool
@@ -5356,6 +5383,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
else
PIPE_CONF_CHECK_X(csc_mode);
PIPE_CONF_CHECK_BOOL(gamma_enable);
+
+ PIPE_CONF_CHECK_X(hw.background_color);
PIPE_CONF_CHECK_BOOL(csc_enable);
PIPE_CONF_CHECK_BOOL(wgc_enable);
@@ -5556,7 +5585,7 @@ int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, mask) {
struct intel_crtc_state *crtc_state;
int ret;
@@ -5603,7 +5632,7 @@ int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state;
int ret;
@@ -5644,7 +5673,7 @@ int intel_modeset_commit_pipes(struct intel_display *display,
state->acquire_ctx = ctx;
to_intel_atomic_state(state)->internal = true;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
struct intel_crtc_state *crtc_state =
intel_atomic_get_crtc_state(state, crtc);
@@ -5671,15 +5700,15 @@ out:
*/
static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state)
{
+ struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
struct intel_crtc_state *first_crtc_state = NULL;
struct intel_crtc_state *other_crtc_state = NULL;
enum pipe first_pipe = INVALID_PIPE, enabled_pipe = INVALID_PIPE;
- int i;
/* look at all crtc's that are going to be enabled in during modeset */
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
if (!crtc_state->hw.active ||
!intel_crtc_needs_modeset(crtc_state))
continue;
@@ -5698,7 +5727,7 @@ static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state)
return 0;
/* w/a possibly needed, check how many crtc's are already enabled. */
- for_each_intel_crtc(state->base.dev, crtc) {
+ for_each_intel_crtc(display, crtc) {
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
@@ -5729,9 +5758,8 @@ u8 intel_calc_enabled_pipes(struct intel_atomic_state *state,
{
const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
if (crtc_state->hw.enable)
enabled_pipes |= BIT(crtc->pipe);
else
@@ -5746,9 +5774,8 @@ u8 intel_calc_active_pipes(struct intel_atomic_state *state,
{
const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
if (crtc_state->hw.active)
active_pipes |= BIT(crtc->pipe);
else
@@ -5819,9 +5846,8 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
struct intel_display *display = to_intel_display(state);
struct intel_crtc_state __maybe_unused *crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
int ret;
ret = intel_crtc_atomic_check(state, crtc);
@@ -5841,9 +5867,8 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
{
const struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (new_crtc_state->hw.enable &&
transcoders & BIT(new_crtc_state->cpu_transcoder) &&
intel_crtc_needs_modeset(new_crtc_state))
@@ -5858,9 +5883,8 @@ static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
{
const struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (new_crtc_state->hw.enable &&
pipes & BIT(crtc->pipe) &&
intel_crtc_needs_modeset(new_crtc_state))
@@ -5895,7 +5919,7 @@ static int intel_atomic_check_joiner(struct intel_atomic_state *state,
return -EINVAL;
}
- for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, secondary_crtc,
intel_crtc_joiner_secondary_pipes(primary_crtc_state)) {
struct intel_crtc_state *secondary_crtc_state;
int ret;
@@ -5938,7 +5962,7 @@ static void kill_joiner_secondaries(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, primary_crtc);
struct intel_crtc *secondary_crtc;
- for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, secondary_crtc,
intel_crtc_joiner_secondary_pipes(primary_crtc_state)) {
struct intel_crtc_state *secondary_crtc_state =
intel_atomic_get_new_crtc_state(state, secondary_crtc);
@@ -6231,19 +6255,19 @@ static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state)
}
/* Now pull in all joined crtcs */
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
affected_pipes |= crtc_state->joiner_pipes;
if (intel_crtc_needs_modeset(crtc_state))
modeset_pipes |= crtc_state->joiner_pipes;
}
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, affected_pipes) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, affected_pipes) {
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
}
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, modeset_pipes) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, modeset_pipes) {
int ret;
crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
@@ -6259,7 +6283,7 @@ static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state)
return ret;
}
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
/* Kill old joiner link, we may re-establish afterwards */
if (intel_crtc_needs_modeset(crtc_state) &&
intel_crtc_is_joiner_primary(crtc_state))
@@ -6277,7 +6301,6 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
int ret;
- int i;
*failed_pipe = INVALID_PIPE;
@@ -6289,7 +6312,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
if (ret)
return ret;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (!intel_crtc_needs_modeset(new_crtc_state)) {
if (!intel_crtc_is_joiner_secondary(new_crtc_state))
intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
@@ -6311,7 +6334,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
goto fail;
}
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
@@ -6383,13 +6406,12 @@ int intel_atomic_check(struct drm_device *dev,
struct intel_atomic_state *state = to_intel_atomic_state(_state);
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct intel_crtc *crtc;
- int ret, i;
+ int ret;
if (!intel_display_driver_check_access(display))
return -ENODEV;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
/*
* crtc's state no longer considered to be inherited
* after the first userspace/client initiated commit.
@@ -6415,7 +6437,7 @@ int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
ret = intel_async_flip_check_uapi(state, crtc);
if (ret)
return ret;
@@ -6425,7 +6447,7 @@ int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (!intel_crtc_needs_modeset(new_crtc_state)) {
if (intel_crtc_is_joiner_secondary(new_crtc_state))
copy_joiner_crtc_state_nomodeset(state, crtc);
@@ -6442,8 +6464,7 @@ int intel_atomic_check(struct drm_device *dev,
goto fail;
}
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
@@ -6463,7 +6484,7 @@ int intel_atomic_check(struct drm_device *dev,
* needs a full modeset, all other synced crtcs should be
* forced a full modeset.
*/
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (!new_crtc_state->hw.enable || intel_crtc_needs_modeset(new_crtc_state))
continue;
@@ -6493,8 +6514,7 @@ int intel_atomic_check(struct drm_device *dev,
}
}
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
@@ -6511,7 +6531,7 @@ int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
new_crtc_state->min_cdclk = intel_crtc_min_cdclk(new_crtc_state);
ret = intel_compute_global_watermarks(state);
@@ -6544,8 +6564,7 @@ int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
intel_color_assert_luts(new_crtc_state);
ret = intel_async_flip_check_hw(state, crtc);
@@ -6576,8 +6595,7 @@ int intel_atomic_check(struct drm_device *dev,
* FIXME would probably be nice to know which crtc specifically
* caused the failure, in cases where we can pinpoint it.
*/
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i)
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state)
intel_crtc_state_dump(new_crtc_state, state, "failed");
return ret;
@@ -6728,7 +6746,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
if (!intel_crtc_needs_modeset(new_crtc_state))
return;
- for_each_intel_crtc_in_pipe_mask_reverse(display->drm, pipe_crtc,
+ for_each_intel_crtc_in_pipe_mask_reverse(display, pipe_crtc,
intel_crtc_joined_pipe_mask(new_crtc_state)) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -6866,7 +6884,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
* We need to disable pipe CRC before disabling the pipe,
* or we race against vblank off.
*/
- for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, pipe_crtc,
intel_crtc_joined_pipe_mask(old_crtc_state))
intel_crtc_disable_pipe_crc(pipe_crtc);
@@ -6874,7 +6892,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
display->modeset.funcs->crtc_disable(state, crtc);
- for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, pipe_crtc,
intel_crtc_joined_pipe_mask(old_crtc_state)) {
const struct intel_crtc_state *new_pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -6893,10 +6911,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
struct intel_crtc *crtc;
u8 disable_pipes = 0;
- int i;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
@@ -6912,7 +6928,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
disable_pipes |= BIT(crtc->pipe);
}
- for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) {
+ for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) {
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
@@ -6922,7 +6938,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
}
/* Only disable port sync and MST slaves */
- for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) {
+ for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) {
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
@@ -6944,7 +6960,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
}
/* Disable everything else left on */
- for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) {
+ for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) {
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
@@ -6963,9 +6979,8 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
{
struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (!new_crtc_state->hw.active)
continue;
@@ -6973,7 +6988,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
intel_pre_update_crtc(state, crtc);
}
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (!new_crtc_state->hw.active)
continue;
@@ -6988,9 +7003,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
u8 update_pipes = 0, modeset_pipes = 0;
- int i;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if (!new_crtc_state->hw.active)
@@ -7014,7 +7028,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* So first lets enable all pipes that do not need a fullmodeset as
* those don't have any external dependency.
*/
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if ((update_pipes & BIT(pipe)) == 0)
@@ -7030,8 +7044,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* Commit in reverse order to make joiner primary
* send the uapi events after secondaries are done.
*/
- for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if ((update_pipes & BIT(pipe)) == 0)
@@ -7067,7 +7080,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* Enable all pipes that needs a modeset and do not depends on other
* pipes
*/
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if ((modeset_pipes & BIT(pipe)) == 0)
@@ -7089,7 +7102,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* Then we enable all remaining pipes that depend on other
* pipes: MST slaves and port sync masters
*/
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if ((modeset_pipes & BIT(pipe)) == 0)
@@ -7106,7 +7119,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
/*
* Finally we do the plane updates/etc. for all pipes that got enabled.
*/
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if ((update_pipes & BIT(pipe)) == 0)
@@ -7119,7 +7132,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* Commit in reverse order to make joiner primary
* send the uapi events after secondaries are done.
*/
- for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state) {
enum pipe pipe = crtc->pipe;
if ((update_pipes & BIT(pipe)) == 0)
@@ -7184,9 +7197,8 @@ static void intel_atomic_cleanup_work(struct work_struct *work)
struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *old_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i)
+ for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state)
intel_atomic_dsb_cleanup(old_crtc_state);
drm_atomic_helper_cleanup_planes(display->drm, &state->base);
@@ -7416,9 +7428,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
struct intel_crtc *crtc;
struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
struct ref_tracker *wakeref = NULL;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
intel_atomic_dsb_prepare(state, crtc);
intel_atomic_commit_fence_wait(state);
@@ -7427,10 +7438,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_atomic_prepare_plane_clear_colors(state);
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
intel_fbc_prepare_dirty_rect(state, crtc);
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
intel_atomic_dsb_finish(state, crtc);
drm_atomic_helper_wait_for_dependencies(&state->base);
@@ -7466,8 +7477,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
*/
wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF);
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (intel_crtc_needs_modeset(new_crtc_state) ||
intel_crtc_needs_fastset(new_crtc_state))
intel_modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]);
@@ -7478,7 +7488,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_dp_tunnel_atomic_alloc_bw(state);
/* FIXME: Eventually get rid of our crtc->config pointer */
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
crtc->config = new_crtc_state;
/*
@@ -7500,7 +7510,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_sagv_pre_plane_update(state);
/* Complete the events for pipes that have now been disabled */
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
bool modeset = intel_crtc_needs_modeset(new_crtc_state);
/* Complete events for now disable pipes here. */
@@ -7518,7 +7528,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_dbuf_pre_plane_update(state);
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (new_crtc_state->do_async_flip)
intel_crtc_enable_flip_done(state, crtc);
}
@@ -7542,7 +7552,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
*/
drm_atomic_helper_wait_for_flip_done(display->drm, &state->base);
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
if (new_crtc_state->do_async_flip)
intel_crtc_disable_flip_done(state, crtc);
@@ -7562,8 +7572,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
*
* TODO: Move this (and other cleanup) to an async worker eventually.
*/
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
/*
* Gen2 reports pipe underruns whenever all planes are disabled.
* So re-enable underrun reporting after some planes get enabled.
@@ -7580,7 +7589,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_dbuf_post_plane_update(state);
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
intel_post_plane_update(state, crtc);
intel_modeset_put_crtc_power_domains(crtc, &put_domains[crtc->pipe]);
@@ -7724,9 +7733,8 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_commit *_state
if (DISPLAY_VER(display) < 9 && state->base.legacy_cursor_update) {
struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
if (new_crtc_state->wm.need_postvbl_update ||
new_crtc_state->update_wm_post)
state->base.legacy_cursor_update = false;
@@ -7786,7 +7794,7 @@ static u32 intel_encoder_possible_crtcs(struct intel_encoder *encoder)
struct intel_crtc *crtc;
u32 possible_crtcs = 0;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, encoder->pipe_mask)
+ for_each_intel_crtc_in_pipe_mask(display, crtc, encoder->pipe_mask)
possible_crtcs |= drm_crtc_mask(&crtc->base);
return possible_crtcs;
@@ -8279,7 +8287,7 @@ int intel_initial_commit(struct intel_display *display)
to_intel_atomic_state(state)->internal = true;
retry:
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
intel_atomic_get_crtc_state(state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 45a90d2fe6ec5..1963dbc802217 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -212,22 +212,22 @@ enum phy_fia {
base.head) \
for_each_if((intel_plane)->pipe == (intel_crtc)->pipe)
-#define for_each_intel_crtc(dev, crtc) \
+#define for_each_intel_crtc(display, crtc) \
list_for_each_entry((crtc), \
- &to_intel_display(dev)->pipe_list, \
+ &(display)->pipe_list, \
pipe_head)
-#define for_each_intel_crtc_reverse(dev, crtc) \
+#define for_each_intel_crtc_reverse(display, crtc) \
list_for_each_entry_reverse((crtc), \
- &to_intel_display(dev)->pipe_list, \
+ &(display)->pipe_list, \
pipe_head)
-#define for_each_intel_crtc_in_pipe_mask(dev, crtc, pipe_mask) \
- for_each_intel_crtc((dev), (crtc)) \
+#define for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) \
+ for_each_intel_crtc((display), (crtc)) \
for_each_if((pipe_mask) & BIT((crtc)->pipe))
-#define for_each_intel_crtc_in_pipe_mask_reverse(dev, crtc, pipe_mask) \
- for_each_intel_crtc_reverse((dev), (crtc)) \
+#define for_each_intel_crtc_in_pipe_mask_reverse(display, crtc, pipe_mask) \
+ for_each_intel_crtc_reverse((display), (crtc)) \
for_each_if((pipe_mask) & BIT((crtc)->pipe))
#define for_each_intel_encoder(dev, intel_encoder) \
@@ -287,31 +287,26 @@ enum phy_fia {
(__i)++) \
for_each_if(plane)
-#define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state, __i) \
- for_each_intel_crtc((__state)->base.dev, (crtc)) \
- for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
- (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc))))
+#define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state) \
+ for_each_intel_crtc(to_intel_display(__state), (crtc)) \
+ for_each_if((old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)))
-#define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state, __i) \
- for_each_intel_crtc((__state)->base.dev, (crtc)) \
- for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
- (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
+#define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state) \
+ for_each_intel_crtc(to_intel_display(__state), (crtc)) \
+ for_each_if((new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))
-#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state, __i) \
- for_each_intel_crtc_reverse((__state)->base.dev, (crtc)) \
- for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
- (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
+#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state) \
+ for_each_intel_crtc_reverse(to_intel_display(__state), (crtc)) \
+ for_each_if((new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))
-#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
- for_each_intel_crtc((__state)->base.dev, (crtc)) \
- for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
- (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \
+#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state) \
+ for_each_intel_crtc(to_intel_display(__state), (crtc)) \
+ for_each_if(((old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \
(new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
-#define for_each_oldnew_intel_crtc_in_state_reverse(__state, crtc, old_crtc_state, new_crtc_state, __i) \
- for_each_intel_crtc_reverse((__state)->base.dev, (crtc)) \
- for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \
- (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \
+#define for_each_oldnew_intel_crtc_in_state_reverse(__state, crtc, old_crtc_state, new_crtc_state) \
+ for_each_intel_crtc_reverse(to_intel_display(__state), (crtc)) \
+ for_each_if(((old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \
(new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))))
#define intel_atomic_crtc_state_for_each_plane_state( \
@@ -330,29 +325,29 @@ enum phy_fia {
((connector) = to_intel_connector((__state)->base.connectors[__i].ptr), \
(new_connector_state) = to_intel_digital_connector_state((__state)->base.connectors[__i].new_state), 1))
-#define for_each_crtc_in_masks(display, crtc, first_pipes, second_pipes, i) \
- for ((i) = 0; \
+#define __for_each_crtc_in_masks(display, crtc, first_pipes, second_pipes, i) \
+ for (int (i) = 0; \
(i) < (I915_MAX_PIPES * 2) && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \
(i)++) \
for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i))
-#define for_each_crtc_in_masks_reverse(display, crtc, first_pipes, second_pipes, i) \
- for ((i) = (I915_MAX_PIPES * 2 - 1); \
+#define __for_each_crtc_in_masks_reverse(display, crtc, first_pipes, second_pipes, i) \
+ for (int (i) = (I915_MAX_PIPES * 2 - 1); \
(i) >= 0 && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \
(i)--) \
for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i))
-#define for_each_pipe_crtc_modeset_disable(display, crtc, crtc_state, i) \
- for_each_crtc_in_masks(display, crtc, \
- _intel_modeset_primary_pipes(crtc_state), \
- _intel_modeset_secondary_pipes(crtc_state), \
- i)
+#define for_each_pipe_crtc_modeset_disable(display, crtc, crtc_state) \
+ __for_each_crtc_in_masks(display, crtc, \
+ _intel_modeset_primary_pipes(crtc_state), \
+ _intel_modeset_secondary_pipes(crtc_state), \
+ __UNIQUE_ID(i))
-#define for_each_pipe_crtc_modeset_enable(display, crtc, crtc_state, i) \
- for_each_crtc_in_masks_reverse(display, crtc, \
- _intel_modeset_primary_pipes(crtc_state), \
- _intel_modeset_secondary_pipes(crtc_state), \
- i)
+#define for_each_pipe_crtc_modeset_enable(display, crtc, crtc_state) \
+ __for_each_crtc_in_masks_reverse(display, crtc, \
+ _intel_modeset_primary_pipes(crtc_state), \
+ _intel_modeset_secondary_pipes(crtc_state), \
+ __UNIQUE_ID(i))
int intel_atomic_check(struct drm_device *dev, struct drm_atomic_commit *state);
u8 intel_calc_enabled_pipes(struct intel_atomic_state *state,
@@ -402,6 +397,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state);
void i830_enable_pipe(struct intel_display *display, enum pipe pipe);
void i830_disable_pipe(struct intel_display *display, enum pipe pipe);
bool intel_has_pending_fb_unpin(struct intel_display *display);
+void intel_display_flush_cleanup_work(struct intel_display *display);
void intel_encoder_destroy(struct drm_encoder *encoder);
struct drm_display_mode *
intel_encoder_current_mode(struct intel_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index adafe103c2b93..09ce25a6d4b11 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -475,6 +475,9 @@ struct intel_display {
} ips;
struct {
+ /* internal display irq functions */
+ const struct intel_display_irq_funcs *funcs;
+
/* protects the irq masks */
spinlock_t lock;
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 81bef000a4e3e..08004c1ba03f4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -572,6 +572,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
intel_scaler_info(m, crtc);
+ if (DISPLAY_VER(display) >= 9) {
+ u32 background = crtc_state->hw.background_color;
+
+ seq_printf(m, "\tbackground color (10bpc XRGB2101010): %08x\n", background);
+ }
+
if (crtc_state->joiner_pipes)
seq_printf(m, "\tLinked to 0x%x pipes as a %s\n",
crtc_state->joiner_pipes,
@@ -606,7 +612,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
seq_printf(m, "CRTC info\n");
seq_printf(m, "---------\n");
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
intel_crtc_info(m, crtc);
seq_printf(m, "\n");
@@ -664,7 +670,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
@@ -771,7 +777,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
if (!reset)
return cnt;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct drm_crtc_commit *commit;
struct intel_crtc_state *crtc_state;
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index 074e3ba8fb77d..12e5a522a2994 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -162,7 +162,6 @@ struct intel_display_platforms {
#define HAS_DDI(__display) (DISPLAY_INFO(__display)->has_ddi)
#define HAS_DISPLAY(__display) (DISPLAY_RUNTIME_INFO(__display)->pipe_mask != 0)
#define HAS_DMC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dmc)
-#define HAS_DMC_WAKELOCK(__display) (DISPLAY_VER(__display) >= 20)
#define HAS_DOUBLE_BUFFERED_M_N(__display) (IS_DISPLAY_VER((__display), 9, 14) || (__display)->platform.broadwell)
#define HAS_DOUBLE_BUFFERED_LUT(__display) (DISPLAY_VER(__display) >= 30)
#define HAS_DOUBLE_WIDE(__display) (DISPLAY_VER(__display) < 4)
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 8e6c3dfab5c0c..d0729936f6816 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -212,13 +212,13 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
intel_psr_dc5_dc6_wa_init(display);
/* FIXME: completely on the wrong abstraction layer */
- ret = intel_power_domains_init(display);
+ ret = intel_display_power_init(display);
if (ret < 0)
goto cleanup_bios;
intel_pmdemand_init_early(display);
- intel_power_domains_init_hw(display, false);
+ intel_display_power_init_hw(display);
if (!HAS_DISPLAY(display))
return 0;
@@ -300,7 +300,7 @@ cleanup_wq_dp:
destroy_workqueue(display->hotplug.dp_wq);
cleanup_pw_domain_dmc:
intel_dmc_fini(display);
- intel_power_domains_driver_remove(display);
+ intel_display_power_driver_remove(display);
cleanup_bios:
intel_bios_driver_remove(display);
@@ -641,7 +641,7 @@ void intel_display_driver_remove_nogem(struct intel_display *display)
{
intel_dmc_fini(display);
- intel_power_domains_driver_remove(display);
+ intel_display_power_driver_remove(display);
intel_bios_driver_remove(display);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index ca72b799ba0a8..4a821b0674fda 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -23,6 +23,7 @@
#include "intel_fifo_underrun.h"
#include "intel_gmbus.h"
#include "intel_hotplug_irq.h"
+#include "intel_lpe_audio.h"
#include "intel_parent.h"
#include "intel_pipe_crc_regs.h"
#include "intel_plane.h"
@@ -529,8 +530,8 @@ static void i9xx_pipestat_irq_reset(struct intel_display *display)
}
}
-void i9xx_pipestat_irq_ack(struct intel_display *display,
- u32 iir, u32 pipe_stats[I915_MAX_PIPES])
+static void i9xx_pipestat_irq_ack(struct intel_display *display,
+ u32 iir, u32 pipe_stats[I915_MAX_PIPES])
{
enum pipe pipe;
@@ -596,8 +597,8 @@ void i9xx_pipestat_irq_ack(struct intel_display *display,
spin_unlock(&display->irq.lock);
}
-void i915_pipestat_irq_handler(struct intel_display *display,
- u32 iir, u32 pipe_stats[I915_MAX_PIPES])
+static void i915_pipestat_irq_handler(struct intel_display *display,
+ u32 iir, const u32 pipe_stats[I915_MAX_PIPES])
{
bool blc_event = false;
enum pipe pipe;
@@ -620,8 +621,8 @@ void i915_pipestat_irq_handler(struct intel_display *display,
intel_opregion_asle_intr(display);
}
-void i965_pipestat_irq_handler(struct intel_display *display,
- u32 iir, u32 pipe_stats[I915_MAX_PIPES])
+static void i965_pipestat_irq_handler(struct intel_display *display,
+ u32 iir, const u32 pipe_stats[I915_MAX_PIPES])
{
bool blc_event = false;
enum pipe pipe;
@@ -647,8 +648,8 @@ void i965_pipestat_irq_handler(struct intel_display *display,
intel_gmbus_irq_handler(display);
}
-void valleyview_pipestat_irq_handler(struct intel_display *display,
- u32 pipe_stats[I915_MAX_PIPES])
+static void valleyview_pipestat_irq_handler(struct intel_display *display,
+ const u32 pipe_stats[I915_MAX_PIPES])
{
enum pipe pipe;
@@ -1020,7 +1021,8 @@ void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u3
intel_de_write_fw(display, SDEIER, sde_ier);
}
-bool ilk_display_irq_handler(struct intel_display *display)
+static bool ilk_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
{
u32 de_iir;
bool handled = false;
@@ -1404,7 +1406,7 @@ static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_i
intel_de_write(display, PICAINTERRUPT_IER, pica_ier);
}
-void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
+static void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
{
u32 iir;
enum pipe pipe;
@@ -1565,6 +1567,14 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
}
}
+static bool gen8_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
+{
+ gen8_de_irq_handler(display, state->master_ctl);
+
+ return true;
+}
+
u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl)
{
u32 iir;
@@ -1589,7 +1599,8 @@ void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir)
intel_opregion_asle_intr(display);
}
-void gen11_display_irq_handler(struct intel_display *display)
+static bool gen11_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
{
u32 disp_ctl;
@@ -1605,6 +1616,8 @@ void gen11_display_irq_handler(struct intel_display *display)
intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
intel_display_rpm_assert_unblock(display);
+
+ return true;
}
static void i915gm_irq_cstate_wa_enable(struct intel_display *display)
@@ -1902,8 +1915,8 @@ static void vlv_page_table_error_irq_handler(struct intel_display *display, u32
}
}
-void vlv_display_error_irq_ack(struct intel_display *display,
- u32 *eir, u32 *dpinvgtt)
+static void vlv_display_error_irq_ack(struct intel_display *display,
+ u32 *eir, u32 *dpinvgtt)
{
u32 emr;
@@ -1924,8 +1937,8 @@ void vlv_display_error_irq_ack(struct intel_display *display,
intel_de_write(display, VLV_EMR, emr);
}
-void vlv_display_error_irq_handler(struct intel_display *display,
- u32 eir, u32 dpinvgtt)
+static void vlv_display_error_irq_handler(struct intel_display *display,
+ u32 eir, u32 dpinvgtt)
{
drm_dbg(display->drm, "Master Error, EIR 0x%08x\n", eir);
@@ -1951,7 +1964,7 @@ static void _vlv_display_irq_reset(struct intel_display *display)
display->irq.vlv_imr_mask = ~0u;
}
-void vlv_display_irq_reset(struct intel_display *display)
+static void vlv_display_irq_reset(struct intel_display *display)
{
spin_lock_irq(&display->irq.lock);
if (display->irq.vlv_display_irqs_enabled)
@@ -1959,7 +1972,7 @@ void vlv_display_irq_reset(struct intel_display *display)
spin_unlock_irq(&display->irq.lock);
}
-void i9xx_display_irq_reset(struct intel_display *display)
+static void i9xx_display_irq_reset(struct intel_display *display)
{
if (HAS_HOTPLUG(display)) {
i915_hotplug_interrupt_update(display, 0xffffffff, 0);
@@ -1985,7 +1998,7 @@ u32 i9xx_display_irq_enable_mask(struct intel_display *display)
return enable_mask;
}
-void i915_display_irq_postinstall(struct intel_display *display)
+static void i915_display_irq_postinstall(struct intel_display *display)
{
/*
* Interrupt setup is already guaranteed to be single-threaded, this is
@@ -1999,7 +2012,7 @@ void i915_display_irq_postinstall(struct intel_display *display)
i915_enable_asle_pipestat(display);
}
-void i965_display_irq_postinstall(struct intel_display *display)
+static void i965_display_irq_postinstall(struct intel_display *display)
{
/*
* Interrupt setup is already guaranteed to be single-threaded, this is
@@ -2014,6 +2027,38 @@ void i965_display_irq_postinstall(struct intel_display *display)
i915_enable_asle_pipestat(display);
}
+static void i9xx_display_irq_ack(struct intel_display *display,
+ struct intel_display_irq_state *state)
+{
+ if (state->iir & I915_DISPLAY_PORT_INTERRUPT)
+ state->hotplug_status = i9xx_hpd_irq_ack(display);
+
+ /* Call regardless, as some status bits might not be signalled in IIR */
+ i9xx_pipestat_irq_ack(display, state->iir, state->pipe_stats);
+}
+
+static bool i965_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
+{
+ if (state->hotplug_status)
+ i9xx_hpd_irq_handler(display, state->hotplug_status);
+
+ i965_pipestat_irq_handler(display, state->iir, state->pipe_stats);
+
+ return true;
+}
+
+static bool i915_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
+{
+ if (state->hotplug_status)
+ i9xx_hpd_irq_handler(display, state->hotplug_status);
+
+ i915_pipestat_irq_handler(display, state->iir, state->pipe_stats);
+
+ return true;
+}
+
static u32 vlv_error_mask(void)
{
/* TODO enable other errors too? */
@@ -2061,7 +2106,7 @@ static void _vlv_display_irq_postinstall(struct intel_display *display)
irq_init(display, VLV_IRQ_REGS, display->irq.vlv_imr_mask, enable_mask);
}
-void vlv_display_irq_postinstall(struct intel_display *display)
+static void vlv_display_irq_postinstall(struct intel_display *display)
{
spin_lock_irq(&display->irq.lock);
if (display->irq.vlv_display_irqs_enabled)
@@ -2069,6 +2114,46 @@ void vlv_display_irq_postinstall(struct intel_display *display)
spin_unlock_irq(&display->irq.lock);
}
+static u32 vlv_lpe_irq_mask(struct intel_display *display)
+{
+ if (display->platform.cherryview)
+ return I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT |
+ I915_LPE_PIPE_C_INTERRUPT;
+ else
+ return I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT;
+}
+
+static void vlv_display_irq_ack(struct intel_display *display,
+ struct intel_display_irq_state *state)
+{
+ if (state->iir & I915_DISPLAY_PORT_INTERRUPT)
+ state->hotplug_status = i9xx_hpd_irq_ack(display);
+
+ if (state->iir & I915_MASTER_ERROR_INTERRUPT)
+ vlv_display_error_irq_ack(display, &state->eir, &state->dpinvgtt);
+
+ /* Call regardless, as some status bits might not be signalled in IIR */
+ i9xx_pipestat_irq_ack(display, state->iir, state->pipe_stats);
+
+ /* The handler acks the irq, so need to call the handler here */
+ if (state->iir & vlv_lpe_irq_mask(display))
+ intel_lpe_audio_irq_handler(display);
+}
+
+static bool vlv_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
+{
+ if (state->hotplug_status)
+ i9xx_hpd_irq_handler(display, state->hotplug_status);
+
+ if (state->iir & I915_MASTER_ERROR_INTERRUPT)
+ vlv_display_error_irq_handler(display, state->eir, state->dpinvgtt);
+
+ valleyview_pipestat_irq_handler(display, state->pipe_stats);
+
+ return true;
+}
+
static void ibx_display_irq_reset(struct intel_display *display)
{
if (HAS_PCH_NOP(display))
@@ -2080,7 +2165,7 @@ static void ibx_display_irq_reset(struct intel_display *display)
intel_de_write(display, SERR_INT, 0xffffffff);
}
-void ilk_display_irq_reset(struct intel_display *display)
+static void ilk_display_irq_reset(struct intel_display *display)
{
irq_reset(display, DE_IRQ_REGS);
display->irq.ilk_de_imr_mask = ~0u;
@@ -2096,13 +2181,10 @@ void ilk_display_irq_reset(struct intel_display *display)
ibx_display_irq_reset(display);
}
-void gen8_display_irq_reset(struct intel_display *display)
+static void gen8_display_irq_reset(struct intel_display *display)
{
enum pipe pipe;
- if (!HAS_DISPLAY(display))
- return;
-
intel_de_write(display, EDP_PSR_IMR, 0xffffffff);
intel_de_write(display, EDP_PSR_IIR, 0xffffffff);
@@ -2118,15 +2200,12 @@ void gen8_display_irq_reset(struct intel_display *display)
ibx_display_irq_reset(display);
}
-void gen11_display_irq_reset(struct intel_display *display)
+static void gen11_display_irq_reset(struct intel_display *display)
{
enum pipe pipe;
u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
- if (!HAS_DISPLAY(display))
- return;
-
intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0);
if (DISPLAY_VER(display) >= 12) {
@@ -2272,7 +2351,7 @@ out:
spin_unlock_irq(&display->irq.lock);
}
-void ilk_de_irq_postinstall(struct intel_display *display)
+static void ilk_de_irq_postinstall(struct intel_display *display)
{
u32 display_mask, extra_mask;
@@ -2316,7 +2395,7 @@ void ilk_de_irq_postinstall(struct intel_display *display)
static void mtp_irq_postinstall(struct intel_display *display);
static void icp_irq_postinstall(struct intel_display *display);
-void gen8_de_irq_postinstall(struct intel_display *display)
+static void gen8_de_irq_postinstall(struct intel_display *display)
{
u32 de_pipe_masked = gen8_de_pipe_fault_mask(display) |
GEN8_PIPE_CDCLK_CRC_DONE;
@@ -2443,28 +2522,92 @@ static void icp_irq_postinstall(struct intel_display *display)
irq_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff);
}
-void gen11_de_irq_postinstall(struct intel_display *display)
+static void gen11_de_irq_postinstall(struct intel_display *display)
{
- if (!HAS_DISPLAY(display))
- return;
-
gen8_de_irq_postinstall(display);
intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
}
-void dg1_de_irq_postinstall(struct intel_display *display)
+struct intel_display_irq_funcs {
+ void (*reset)(struct intel_display *display);
+ void (*postinstall)(struct intel_display *display);
+ void (*ack)(struct intel_display *display, struct intel_display_irq_state *state);
+ bool (*handler)(struct intel_display *display, const struct intel_display_irq_state *state);
+};
+
+static const struct intel_display_irq_funcs gen11_display_irq_funcs = {
+ .reset = gen11_display_irq_reset,
+ .postinstall = gen11_de_irq_postinstall,
+ .handler = gen11_display_irq_handler,
+};
+
+static const struct intel_display_irq_funcs gen8_display_irq_funcs = {
+ .reset = gen8_display_irq_reset,
+ .postinstall = gen8_de_irq_postinstall,
+ .handler = gen8_display_irq_handler,
+};
+
+static const struct intel_display_irq_funcs vlv_display_irq_funcs = {
+ .reset = vlv_display_irq_reset,
+ .postinstall = vlv_display_irq_postinstall,
+ .ack = vlv_display_irq_ack,
+ .handler = vlv_display_irq_handler,
+};
+
+static const struct intel_display_irq_funcs ilk_display_irq_funcs = {
+ .reset = ilk_display_irq_reset,
+ .postinstall = ilk_de_irq_postinstall,
+ .handler = ilk_display_irq_handler,
+};
+
+static const struct intel_display_irq_funcs i965_display_irq_funcs = {
+ .reset = i9xx_display_irq_reset,
+ .postinstall = i965_display_irq_postinstall,
+ .ack = i9xx_display_irq_ack,
+ .handler = i965_display_irq_handler,
+};
+
+static const struct intel_display_irq_funcs i915_display_irq_funcs = {
+ .reset = i9xx_display_irq_reset,
+ .postinstall = i915_display_irq_postinstall,
+ .ack = i9xx_display_irq_ack,
+ .handler = i915_display_irq_handler,
+};
+
+void intel_display_irq_reset(struct intel_display *display)
+{
+ if (!HAS_DISPLAY(display))
+ return;
+
+ display->irq.funcs->reset(display);
+}
+
+void intel_display_irq_postinstall(struct intel_display *display)
{
if (!HAS_DISPLAY(display))
return;
- gen8_de_irq_postinstall(display);
- intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
+ display->irq.funcs->postinstall(display);
}
-struct intel_display_irq_funcs {
- void (*reset)(struct intel_display *display);
-};
+void intel_display_irq_ack(struct intel_display *display,
+ struct intel_display_irq_state *state)
+{
+ if (!HAS_DISPLAY(display) || !display->irq.funcs->ack)
+ return;
+
+ display->irq.funcs->ack(display, state);
+}
+
+bool intel_display_irq_handler(struct intel_display *display,
+ const struct intel_display_irq_state *state)
+{
+ if (!HAS_DISPLAY(display) || !display->irq.funcs->handler)
+ return true;
+
+ return display->irq.funcs->handler(display, state);
+}
void intel_display_irq_init(struct intel_display *display)
{
@@ -2476,6 +2619,19 @@ void intel_display_irq_init(struct intel_display *display)
INIT_WORK(&display->irq.vblank_notify_work,
intel_display_vblank_notify_work);
+
+ if (DISPLAY_VER(display) >= 11)
+ display->irq.funcs = &gen11_display_irq_funcs;
+ else if (display->platform.cherryview || display->platform.valleyview)
+ display->irq.funcs = &vlv_display_irq_funcs;
+ else if (DISPLAY_VER(display) >= 8)
+ display->irq.funcs = &gen8_display_irq_funcs;
+ else if (DISPLAY_VER(display) >= 5)
+ display->irq.funcs = &ilk_display_irq_funcs;
+ else if (DISPLAY_VER(display) == 4)
+ display->irq.funcs = &i965_display_irq_funcs;
+ else
+ display->irq.funcs = &i915_display_irq_funcs;
}
struct intel_display_irq_snapshot {
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h
index b25d180254d75..a1227cee885ae 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.h
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
@@ -51,41 +51,30 @@ void bdw_disable_vblank(struct drm_crtc *crtc);
void ilk_display_irq_master_disable(struct intel_display *display, u32 *de_ier, u32 *sde_ier);
void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u32 sde_ier);
-bool ilk_display_irq_handler(struct intel_display *display);
-void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl);
-void gen11_display_irq_handler(struct intel_display *display);
u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl);
void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir);
-void i9xx_display_irq_reset(struct intel_display *display);
-void ilk_display_irq_reset(struct intel_display *display);
-void vlv_display_irq_reset(struct intel_display *display);
-void gen8_display_irq_reset(struct intel_display *display);
-void gen11_display_irq_reset(struct intel_display *display);
+struct intel_display_irq_state {
+ u32 master_ctl;
+ u32 iir;
+ u32 eir;
+ u32 hotplug_status;
+ u32 dpinvgtt;
+ u32 pipe_stats[I915_MAX_PIPES];
+};
+
+void intel_display_irq_reset(struct intel_display *display);
+void intel_display_irq_postinstall(struct intel_display *display);
+void intel_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state);
+bool intel_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state);
u32 i9xx_display_irq_enable_mask(struct intel_display *display);
-void i915_display_irq_postinstall(struct intel_display *display);
-void i965_display_irq_postinstall(struct intel_display *display);
-void vlv_display_irq_postinstall(struct intel_display *display);
-void ilk_de_irq_postinstall(struct intel_display *display);
-void gen8_de_irq_postinstall(struct intel_display *display);
-void gen11_de_irq_postinstall(struct intel_display *display);
-void dg1_de_irq_postinstall(struct intel_display *display);
u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe);
void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask);
void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask);
-void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
-
-void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
-void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
-void valleyview_pipestat_irq_handler(struct intel_display *display, u32 pipe_stats[I915_MAX_PIPES]);
-
-void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt);
-void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt);
-
void intel_display_irq_init(struct intel_display *display);
void i915gm_irq_cstate_wa(struct intel_display *display, bool enable);
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 751e6b7d4a292..2e51dfcd5dce2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -1018,13 +1018,13 @@ static u32 get_allowed_dc_mask(struct intel_display *display, int enable_dc)
}
/**
- * intel_power_domains_init - initializes the power domain structures
+ * intel_display_power_init - initializes the power domain structures
* @display: display device instance
*
* Initializes the power domain structures for @display depending upon the
* supported platform.
*/
-int intel_power_domains_init(struct intel_display *display)
+int intel_display_power_init(struct intel_display *display)
{
struct i915_power_domains *power_domains = &display->power.domains;
@@ -1045,12 +1045,12 @@ int intel_power_domains_init(struct intel_display *display)
}
/**
- * intel_power_domains_cleanup - clean up power domains resources
+ * intel_display_power_cleanup - clean up power domains resources
* @display: display device instance
*
- * Release any resources acquired by intel_power_domains_init()
+ * Release any resources acquired by intel_display_power_init()
*/
-void intel_power_domains_cleanup(struct intel_display *display)
+void intel_display_power_cleanup(struct intel_display *display)
{
intel_display_power_map_cleanup(&display->power.domains);
}
@@ -1203,7 +1203,7 @@ static void assert_can_disable_lcpll(struct intel_display *display)
{
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
INTEL_DISPLAY_STATE_WARN(display, crtc->active,
"CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
@@ -1917,23 +1917,7 @@ static void assert_isp_power_gated(struct intel_display *display)
static void intel_power_domains_verify_state(struct intel_display *display);
-/**
- * intel_power_domains_init_hw - initialize hardware power domain state
- * @display: display device instance
- * @resume: Called from resume code paths or not
- *
- * This function initializes the hardware power domain state and enables all
- * power wells belonging to the INIT power domain. Power wells in other
- * domains (and not in the INIT domain) are referenced or disabled by
- * intel_modeset_readout_hw_state(). After that the reference count of each
- * power well must match its HW enabled state, see
- * intel_power_domains_verify_state().
- *
- * It will return with power domains disabled (to be enabled later by
- * intel_power_domains_enable()) and must be paired with
- * intel_power_domains_driver_remove().
- */
-void intel_power_domains_init_hw(struct intel_display *display, bool resume)
+static void __intel_display_power_init_hw(struct intel_display *display, bool resume)
{
struct i915_power_domains *power_domains = &display->power.domains;
@@ -1967,7 +1951,7 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume)
* Keep all power wells enabled for any dependent HW access during
* initialization and to make sure we keep BIOS enabled display HW
* resources powered until display HW readout is complete. We drop
- * this reference in intel_power_domains_enable().
+ * this reference in intel_display_power_enable().
*/
drm_WARN_ON(display->drm, power_domains->init_wakeref);
power_domains->init_wakeref =
@@ -1985,17 +1969,37 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume)
}
/**
- * intel_power_domains_driver_remove - deinitialize hw power domain state
+ * intel_display_power_init_hw - initialize hardware power domain state
+ * @display: display device instance
+ *
+ * This function initializes the hardware power domain state and enables all
+ * power wells belonging to the INIT power domain. Power wells in other
+ * domains (and not in the INIT domain) are referenced or disabled by
+ * intel_modeset_readout_hw_state(). After that the reference count of each
+ * power well must match its HW enabled state, see
+ * intel_power_domains_verify_state().
+ *
+ * It will return with power domains disabled (to be enabled later by
+ * intel_display_power_enable()) and must be paired with
+ * intel_display_power_driver_remove().
+ */
+void intel_display_power_init_hw(struct intel_display *display)
+{
+ __intel_display_power_init_hw(display, false);
+}
+
+/**
+ * intel_display_power_driver_remove - deinitialize hw power domain state
* @display: display device instance
*
* De-initializes the display power domain HW state. It also ensures that the
* device stays powered up so that the driver can be reloaded.
*
* It must be called with power domains already disabled (after a call to
- * intel_power_domains_disable()) and must be paired with
- * intel_power_domains_init_hw().
+ * intel_display_power_disable()) and must be paired with
+ * intel_display_power_init_hw().
*/
-void intel_power_domains_driver_remove(struct intel_display *display)
+void intel_display_power_driver_remove(struct intel_display *display)
{
struct ref_tracker *wakeref __maybe_unused =
fetch_and_zero(&display->power.domains.init_wakeref);
@@ -2014,7 +2018,7 @@ void intel_power_domains_driver_remove(struct intel_display *display)
}
/**
- * intel_power_domains_sanitize_state - sanitize power domains state
+ * intel_display_power_sanitize_state - sanitize power domains state
* @display: display device instance
*
* Sanitize the power domains state during driver loading and system resume.
@@ -2023,7 +2027,7 @@ void intel_power_domains_driver_remove(struct intel_display *display)
* on it by the time this function is called, after the state of all the
* pipe, encoder, etc. HW resources have been sanitized).
*/
-void intel_power_domains_sanitize_state(struct intel_display *display)
+void intel_display_power_sanitize_state(struct intel_display *display)
{
struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *power_well;
@@ -2045,18 +2049,18 @@ void intel_power_domains_sanitize_state(struct intel_display *display)
}
/**
- * intel_power_domains_enable - enable toggling of display power wells
+ * intel_display_power_enable - enable toggling of display power wells
* @display: display device instance
*
* Enable the ondemand enabling/disabling of the display power wells. Note that
* power wells not belonging to POWER_DOMAIN_INIT are allowed to be toggled
* only at specific points of the display modeset sequence, thus they are not
- * affected by the intel_power_domains_enable()/disable() calls. The purpose
+ * affected by the intel_display_power_enable()/disable() calls. The purpose
* of these function is to keep the rest of power wells enabled until the end
* of display HW readout (which will acquire the power references reflecting
* the current HW state).
*/
-void intel_power_domains_enable(struct intel_display *display)
+void intel_display_power_enable(struct intel_display *display)
{
struct ref_tracker *wakeref __maybe_unused =
fetch_and_zero(&display->power.domains.init_wakeref);
@@ -2066,13 +2070,13 @@ void intel_power_domains_enable(struct intel_display *display)
}
/**
- * intel_power_domains_disable - disable toggling of display power wells
+ * intel_display_power_disable - disable toggling of display power wells
* @display: display device instance
*
* Disable the ondemand enabling/disabling of the display power wells. See
- * intel_power_domains_enable() for which power wells this call controls.
+ * intel_display_power_enable() for which power wells this call controls.
*/
-void intel_power_domains_disable(struct intel_display *display)
+void intel_display_power_disable(struct intel_display *display)
{
struct i915_power_domains *power_domains = &display->power.domains;
@@ -2092,9 +2096,9 @@ void intel_power_domains_disable(struct intel_display *display)
* system suspend.
*
* It must be called with power domains already disabled (after a call to
- * intel_power_domains_disable()) and paired with intel_power_domains_resume().
+ * intel_display_power_disable()) and paired with intel_power_domains_resume().
*/
-void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
+static void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
{
struct i915_power_domains *power_domains = &display->power.domains;
struct ref_tracker *wakeref __maybe_unused =
@@ -2144,15 +2148,15 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
* This function resume the hardware power domain state during system resume.
*
* It will return with power domain support disabled (to be enabled later by
- * intel_power_domains_enable()) and must be paired with
+ * intel_display_power_enable()) and must be paired with
* intel_power_domains_suspend().
*/
-void intel_power_domains_resume(struct intel_display *display)
+static void intel_power_domains_resume(struct intel_display *display)
{
struct i915_power_domains *power_domains = &display->power.domains;
if (power_domains->display_core_suspended) {
- intel_power_domains_init_hw(display, true);
+ __intel_display_power_init_hw(display, true);
power_domains->display_core_suspended = false;
} else {
drm_WARN_ON(display->drm, power_domains->init_wakeref);
@@ -2285,7 +2289,7 @@ void intel_display_power_resume_early(struct intel_display *display)
intel_power_domains_resume(display);
}
-void intel_display_power_suspend(struct intel_display *display)
+void intel_display_power_runtime_suspend(struct intel_display *display)
{
if (DISPLAY_VER(display) >= 11) {
icl_display_core_uninit(display);
@@ -2298,7 +2302,7 @@ void intel_display_power_suspend(struct intel_display *display)
}
}
-void intel_display_power_resume(struct intel_display *display)
+void intel_display_power_runtime_resume(struct intel_display *display)
{
struct i915_power_domains *power_domains = &display->power.domains;
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index d616d5d09cbed..56dc89eed3f89 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -169,24 +169,23 @@ struct intel_display_power_domain_set {
for ((__domain) = 0; (__domain) < POWER_DOMAIN_NUM; (__domain)++) \
for_each_if(test_bit((__domain), (__mask)->bits))
-int intel_power_domains_init(struct intel_display *display);
-void intel_power_domains_cleanup(struct intel_display *display);
-void intel_power_domains_init_hw(struct intel_display *display, bool resume);
-void intel_power_domains_driver_remove(struct intel_display *display);
-void intel_power_domains_enable(struct intel_display *display);
-void intel_power_domains_disable(struct intel_display *display);
-void intel_power_domains_suspend(struct intel_display *display, bool s2idle);
-void intel_power_domains_resume(struct intel_display *display);
-void intel_power_domains_sanitize_state(struct intel_display *display);
+int intel_display_power_init(struct intel_display *display);
+void intel_display_power_cleanup(struct intel_display *display);
+void intel_display_power_init_hw(struct intel_display *display);
+void intel_display_power_driver_remove(struct intel_display *display);
+void intel_display_power_enable(struct intel_display *display);
+void intel_display_power_disable(struct intel_display *display);
+void intel_display_power_sanitize_state(struct intel_display *display);
void intel_display_power_suspend_late(struct intel_display *display, bool s2idle);
void intel_display_power_resume_early(struct intel_display *display);
-void intel_display_power_suspend(struct intel_display *display);
-void intel_display_power_resume(struct intel_display *display);
void intel_display_power_set_target_dc_state(struct intel_display *display,
u32 state);
u32 intel_display_power_get_current_dc_state(struct intel_display *display);
+void intel_display_power_runtime_suspend(struct intel_display *display);
+void intel_display_power_runtime_resume(struct intel_display *display);
+
bool intel_display_power_is_enabled(struct intel_display *display,
enum intel_display_power_domain domain);
struct ref_tracker *intel_display_power_get(struct intel_display *display,
diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h
index 27ebc32cb61a5..504d105935bc0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_trace.h
+++ b/drivers/gpu/drm/i915/display/intel_display_trace.h
@@ -84,7 +84,7 @@ TRACE_EVENT(intel_pipe_enable,
sizeof(__entry->frame[0]) * I915_MAX_PIPES);
memset(__entry->scanline, 0,
sizeof(__entry->scanline[0]) * I915_MAX_PIPES);
- for_each_intel_crtc(display->drm, it__) {
+ for_each_intel_crtc(display, it__) {
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
}
@@ -114,7 +114,7 @@ TRACE_EVENT(intel_pipe_disable,
sizeof(__entry->frame[0]) * I915_MAX_PIPES);
memset(__entry->scanline, 0,
sizeof(__entry->scanline[0]) * I915_MAX_PIPES);
- for_each_intel_crtc(display->drm, it__) {
+ for_each_intel_crtc(display, it__) {
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
}
@@ -244,7 +244,7 @@ TRACE_EVENT(intel_memory_cxsr,
sizeof(__entry->frame[0]) * I915_MAX_PIPES);
memset(__entry->scanline, 0,
sizeof(__entry->scanline[0]) * I915_MAX_PIPES);
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
__entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc);
__entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index b8ccd635c5751..c21e0c0ef0b12 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1035,6 +1035,7 @@ struct intel_crtc_state {
/* logical state of LUTs */
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
struct drm_display_mode mode, pipe_mode, adjusted_mode;
+ u32 background_color;
enum drm_scaling_filter scaling_filter;
u8 sharpness_strength;
} hw;
@@ -1822,6 +1823,7 @@ struct intel_dp {
/* intersection of source and sink rates */
int num_common_rates;
int common_rates[DP_MAX_SUPPORTED_RATES];
+ int max_common_lane_count;
struct {
/* TODO: move the rest of link specific fields to here */
bool active;
@@ -1874,6 +1876,7 @@ struct intel_dp {
/* connector directly attached - won't be use for modeset in mst world */
struct intel_connector *attached_connector;
bool as_sdp_supported;
+ bool as_sdp_v2_supported;
struct drm_dp_tunnel *tunnel;
bool tunnel_suspended:1;
diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c
index 7d3d63a59882b..2094eda09c912 100644
--- a/drivers/gpu/drm/i915/display/intel_display_wa.c
+++ b/drivers/gpu/drm/i915/display/intel_display_wa.c
@@ -136,6 +136,8 @@ bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa,
return DISPLAY_VER(display) == 20 &&
IS_DISPLAY_VERx100_STEP(display, 3000,
STEP_A0, STEP_B0);
+ case INTEL_DISPLAY_WA_16029024088:
+ return DISPLAY_VER(display) >= 35;
case INTEL_DISPLAY_WA_18034343758:
return DISPLAY_VER(display) == 20 ||
(display->platform.pantherlake &&
diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h
index 15fec843f15e1..9cdd148ea4fad 100644
--- a/drivers/gpu/drm/i915/display/intel_display_wa.h
+++ b/drivers/gpu/drm/i915/display/intel_display_wa.h
@@ -52,6 +52,7 @@ enum intel_display_wa {
INTEL_DISPLAY_WA_16023588340,
INTEL_DISPLAY_WA_16025573575,
INTEL_DISPLAY_WA_16025596647,
+ INTEL_DISPLAY_WA_16029024088,
INTEL_DISPLAY_WA_18034343758,
INTEL_DISPLAY_WA_22010178259,
INTEL_DISPLAY_WA_22010947358,
diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
index 605a4a5556018..b007343721e12 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
@@ -39,6 +39,13 @@
* current implementation, we only need one wakelock, so only
* DMC_WAKELOCK1_CTL is used. The other definitions are here for
* potential future use.
+ *
+ * This is available starting with Xe2_LPD (display version 20) as an
+ * experimental feature and on Xe3_LPD (display version 30) as the
+ * first display release with official support. That means that we
+ * only enable the feature by default on the latter and using it on
+ * the former requires explicitly using the enable_dmc_wl module
+ * parameter.
*/
/*
@@ -286,7 +293,7 @@ static void intel_dmc_wl_sanitize_param(struct intel_display *display)
{
const char *desc;
- if (!HAS_DMC_WAKELOCK(display)) {
+ if (DISPLAY_VER(display) < 20) {
display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED;
} else if (display->params.enable_dmc_wl < 0) {
if (DISPLAY_VER(display) >= 30)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f01a6eed38395..0ce0c09835f6d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -362,19 +362,30 @@ int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
return max_lanes;
}
-/* Theoretical max between source and sink */
-int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
+/*
+ * Theoretical max between source and sink.
+ * Return %true if the max common lane count changed.
+ */
+static bool intel_dp_set_max_common_lane_count(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
int source_max = intel_dp_max_source_lane_count(dig_port);
int sink_max = intel_dp->max_sink_lane_count;
int lane_max = intel_tc_port_max_lane_count(dig_port);
int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
+ int old_max_common_lane_count = intel_dp->max_common_lane_count;
if (lttpr_max)
sink_max = min(sink_max, lttpr_max);
- return min3(source_max, sink_max, lane_max);
+ intel_dp->max_common_lane_count = min3(source_max, sink_max, lane_max);
+
+ return intel_dp->max_common_lane_count != old_max_common_lane_count;
+}
+
+int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
+{
+ return intel_dp->max_common_lane_count;
}
static int forced_lane_count(struct intel_dp *intel_dp)
@@ -787,13 +798,22 @@ int intel_dp_link_config_index(struct intel_dp *intel_dp, int link_rate, int lan
return -1;
}
-static void intel_dp_set_common_rates(struct intel_dp *intel_dp)
+/* Return %true if the common rates changed. */
+static bool intel_dp_set_common_rates(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
+ int num_old_common_rates = intel_dp->num_common_rates;
+ int old_common_rates[DP_MAX_SUPPORTED_RATES];
drm_WARN_ON(display->drm,
!intel_dp->num_source_rates || !intel_dp->num_sink_rates);
+ /* TODO: Add a struct containing both rates and number of rates. */
+ static_assert(__same_type(old_common_rates[0], intel_dp->common_rates[0]) &&
+ sizeof(old_common_rates) == sizeof(intel_dp->common_rates));
+ memcpy(old_common_rates, intel_dp->common_rates,
+ num_old_common_rates * sizeof(old_common_rates[0]));
+
intel_dp->num_common_rates = intersect_rates(intel_dp->source_rates,
intel_dp->num_source_rates,
intel_dp->sink_rates,
@@ -806,7 +826,25 @@ static void intel_dp_set_common_rates(struct intel_dp *intel_dp)
intel_dp->num_common_rates = 1;
}
+ return num_old_common_rates != intel_dp->num_common_rates ||
+ memcmp(old_common_rates, intel_dp->common_rates,
+ num_old_common_rates * sizeof(old_common_rates[0]));
+}
+
+/* Return %true if any common link param changed. */
+static bool intel_dp_set_common_link_params(struct intel_dp *intel_dp)
+{
+ bool params_changed = false;
+
+ if (intel_dp_set_common_rates(intel_dp))
+ params_changed = true;
+
+ if (intel_dp_set_max_common_lane_count(intel_dp))
+ params_changed = true;
+
intel_dp_link_config_init(intel_dp);
+
+ return params_changed;
}
bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
@@ -3172,16 +3210,20 @@ static void intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc
static bool intel_dp_needs_as_sdp(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
- if (!intel_dp->as_sdp_supported)
+ if (!intel_dp->as_sdp_v2_supported)
return false;
/*
- * #TODO Implement AS SDP for DP branch device.
+ * #TODO: Add AS SDP v1 support for PCONs (DP branch devices).
*/
if (drm_dp_is_branch(intel_dp->dpcd))
return false;
- return crtc_state->vrr.enable;
+ if (intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) &&
+ !intel_psr_pr_async_video_timing_supported(intel_dp))
+ return true;
+
+ return intel_vrr_possible(crtc_state);
}
static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
@@ -3204,16 +3246,34 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
as_sdp->duration_incr_ms = 0;
+ as_sdp->revision = 0x2;
as_sdp->vtotal = intel_vrr_vmin_vtotal(crtc_state);
if (crtc_state->cmrr.enable) {
as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED;
as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode);
as_sdp->target_rr_divider = true;
- } else {
+ } else if (crtc_state->vrr.enable) {
as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL;
- as_sdp->target_rr = 0;
+ } else {
+ as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
}
+
+ /*
+ * For Panel Replay with Async Video Timing support, the source can
+ * disable sending the AS SDP during PR Active state. In that case,
+ * the sink needs the coasting vtotal value to maintain the refresh
+ * rate. The HW only samples this on PR_ALPM_CTL[AS SDP Transmission
+ * in Active Disable], which we never program, so providing the value
+ * unconditionally when the sink advertises the capability is safe.
+ *
+ * #TODO:
+ * If we ever advertise support for coasting at other refresh targets,
+ * this logic could be revisited. For now, use the minimum refresh rate
+ * as the only safe coasting value.
+ */
+ if (intel_psr_pr_async_video_timing_supported(intel_dp))
+ as_sdp->coasting_vtotal = crtc_state->vrr.vmax;
}
static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
@@ -3688,8 +3748,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count;
intel_vrr_compute_config(pipe_config, conn_state);
- intel_dp_compute_as_sdp(intel_dp, pipe_config);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
+ intel_dp_compute_as_sdp(intel_dp, pipe_config);
intel_alpm_lobf_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
@@ -4874,9 +4934,21 @@ intel_dp_has_sink_count(struct intel_dp *intel_dp)
void intel_dp_update_sink_caps(struct intel_dp *intel_dp)
{
+ struct intel_display *display = to_intel_display(intel_dp);
+
intel_dp_set_sink_rates(intel_dp);
intel_dp_set_max_sink_lane_count(intel_dp);
- intel_dp_set_common_rates(intel_dp);
+ /*
+ * Handle unexpected sink cap changes, or a race between setting
+ * the deferred link params flag in the HPD IRQ handler and
+ * clearing the flag during connector detect.
+ */
+ if (intel_dp_set_common_link_params(intel_dp) &&
+ !intel_dp->reset_link_params) {
+ drm_dbg_kms(display->drm,
+ "DPRX capabilities changed before long HPD or RX_CAP_CHANGED signal\n");
+ intel_dp->reset_link_params = true;
+ }
}
static bool
@@ -5180,7 +5252,7 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,
/* Prepare AS (Adaptive Sync) SDP Header */
sdp->sdp_header.HB0 = 0;
sdp->sdp_header.HB1 = as_sdp->sdp_type;
- sdp->sdp_header.HB2 = 0x02;
+ sdp->sdp_header.HB2 = as_sdp->revision;
sdp->sdp_header.HB3 = as_sdp->length;
/* Fill AS (Adaptive Sync) SDP Payload */
@@ -5193,6 +5265,9 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,
if (as_sdp->target_rr_divider)
sdp->db[4] |= 0x20;
+ sdp->db[7] = as_sdp->coasting_vtotal & 0xFF;
+ sdp->db[8] = (as_sdp->coasting_vtotal >> 8) & 0xFF;
+
return length;
}
@@ -5367,17 +5442,17 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
if (sdp->sdp_header.HB1 != DP_SDP_ADAPTIVE_SYNC)
return -EINVAL;
- if (sdp->sdp_header.HB2 != 0x02)
- return -EINVAL;
-
if ((sdp->sdp_header.HB3 & 0x3F) != 9)
return -EINVAL;
+ as_sdp->sdp_type = sdp->sdp_header.HB1;
as_sdp->length = sdp->sdp_header.HB3 & DP_AS_SDP_LENGTH_MASK;
+ as_sdp->revision = sdp->sdp_header.HB2;
as_sdp->mode = sdp->db[0] & DP_AS_SDP_OPERATION_MODE_MASK;
as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1];
as_sdp->target_rr = ((sdp->db[4] & 0x3) << 8) | sdp->db[3];
as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false;
+ as_sdp->coasting_vtotal = (sdp->db[8] << 8) | sdp->db[7];
return 0;
}
@@ -6000,8 +6075,10 @@ static bool intel_dp_handle_link_service_irq(struct intel_dp *intel_dp, u8 irq_m
drm_WARN_ON(display->drm, irq_mask & ~(INTEL_DP_LINK_SERVICE_IRQ_MASK_SST |
INTEL_DP_LINK_SERVICE_IRQ_MASK_MST));
- if (irq_mask & RX_CAP_CHANGED)
+ if (irq_mask & RX_CAP_CHANGED) {
+ intel_dp->reset_link_params = true;
reprobe_needed = true;
+ }
if (irq_mask & LINK_STATUS_CHANGED)
intel_dp_check_link_state(intel_dp);
@@ -6365,6 +6442,46 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
false);
}
+static bool
+intel_dp_sink_supports_as_sdp_v2(struct intel_dp *intel_dp)
+{
+ u8 rx_features;
+
+ /*
+ * The DP spec does not explicitly provide the AS SDP v2 capability.
+ * So based on the DP v2.1 SCR, we infer it from the following bits:
+ *
+ * DP_AS_SDP_FAVT_PAYLOAD_FIELDS_PARSING_SUPPORTED indicates support for
+ * FAVT, which is explicitly defined to use AS SDP v2.
+ *
+ * DP_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR indicates that the sink
+ * does not support asynchronous video timing while in PR Active,
+ * requiring the source to keep transmitting Adaptive-Sync SDPs. The
+ * spec mandates that such sinks shall support AS SDP v2.
+ *
+ * #TODO: Check the Adaptive-Sync DisplayID 2.1 block once DisplayID
+ * parsing is available. This may help detect AS SDP v2 support for
+ * native DP 2.1 sinks that do not expose FAVT or PR-based capability
+ * bits.
+ *
+ * In the presence of PCONs, check PCON support from DPCD and sink
+ * support from Display ID.
+ */
+
+ if (drm_dp_dpcd_read_byte(&intel_dp->aux,
+ DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1,
+ &rx_features) == 1) {
+ if (rx_features & DP_AS_SDP_FAVT_PAYLOAD_FIELDS_PARSING_SUPPORTED)
+ return true;
+ }
+
+ if (intel_dp->psr.sink_panel_replay_support &&
+ !intel_psr_pr_async_video_timing_supported(intel_dp))
+ return true;
+
+ return false;
+}
+
static void
intel_dp_detect_sdp_caps(struct intel_dp *intel_dp)
{
@@ -6372,6 +6489,15 @@ intel_dp_detect_sdp_caps(struct intel_dp *intel_dp)
intel_dp->as_sdp_supported = HAS_AS_SDP(display) &&
drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd);
+
+ if (!intel_dp->as_sdp_supported)
+ return;
+
+ /* eDP Adaptive-Sync SDP always uses AS SDP v2 */
+ if (intel_dp_is_edp(intel_dp))
+ intel_dp->as_sdp_v2_supported = true;
+ else
+ intel_dp->as_sdp_v2_supported = intel_dp_sink_supports_as_sdp_v2(intel_dp);
}
static bool intel_dp_needs_dpcd_probe(struct intel_dp *intel_dp, bool force_on_external)
@@ -6751,7 +6877,7 @@ static int intel_modeset_affected_transcoders(struct intel_atomic_state *state,
if (transcoders == 0)
return 0;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state;
int ret;
@@ -7316,7 +7442,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
}
intel_dp_set_source_rates(intel_dp);
- intel_dp_set_common_rates(intel_dp);
+ intel_dp_set_common_link_params(intel_dp);
intel_dp_reset_link_params(intel_dp);
/* init MST on ports that can support it */
@@ -7465,7 +7591,6 @@ int intel_dp_get_lines_for_sdp(const struct intel_crtc_state *crtc_state, u32 ty
int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state,
bool assume_all_enabled)
{
- struct intel_display *display = to_intel_display(crtc_state);
int sdp_guardband = 0;
if (assume_all_enabled ||
@@ -7480,8 +7605,8 @@ int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state,
sdp_guardband = max(sdp_guardband,
intel_dp_get_lines_for_sdp(crtc_state, DP_SDP_PPS));
- if ((assume_all_enabled && HAS_AS_SDP(display)) ||
- crtc_state->infoframes.enable & intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC))
+ if (crtc_state->infoframes.enable &
+ intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC))
sdp_guardband = max(sdp_guardband,
intel_dp_get_lines_for_sdp(crtc_state, DP_SDP_ADAPTIVE_SYNC));
@@ -7506,3 +7631,14 @@ bool intel_dp_joiner_candidate_valid(struct intel_connector *connector,
return true;
}
+
+u8 intel_dp_as_sdp_transmission_time(void)
+{
+ /*
+ * DP allows AS SDP position to move during PR active in some cases, but
+ * software-controlled refresh rate changes with DC6v / ALPM require the
+ * AS SDP to remain at T1. Use T1 unconditionally for now.
+ */
+
+ return DP_PR_AS_SDP_SETUP_TIME_T1;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index f41480d247142..46a7f5c70981f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -241,4 +241,6 @@ bool intel_dp_joiner_candidate_valid(struct intel_connector *connector,
for ((__num_joined_pipes) = 1; (__num_joined_pipes) <= (I915_MAX_PIPES); (__num_joined_pipes)++) \
for_each_if(intel_dp_joiner_candidate_valid(__connector, (__mode)->hdisplay, __num_joined_pipes))
+u8 intel_dp_as_sdp_transmission_time(void);
+
#endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index a8d56ebf06a2f..7a6c07f6aaeb4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -691,10 +691,9 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_device *dev = connector->base.dev;
struct intel_panel *panel = &connector->panel;
- bool try_intel_interface = false;
+ bool try_intel_interface = false, try_vesa_interface = false;
- /*
- * Check the VBT and user's module parameters to figure out which
+ /* Check the VBT and user's module parameters to figure out which
* interfaces to probe
*/
switch (display->params.enable_dpcd_backlight) {
@@ -703,6 +702,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
case INTEL_DP_AUX_BACKLIGHT_AUTO:
switch (panel->vbt.backlight.type) {
case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
+ try_vesa_interface = true;
break;
case INTEL_BACKLIGHT_DISPLAY_DDI:
try_intel_interface = true;
@@ -715,12 +715,20 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
try_intel_interface = true;
+ try_vesa_interface = true;
+ break;
+ case INTEL_DP_AUX_BACKLIGHT_FORCE_VESA:
+ try_vesa_interface = true;
break;
case INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL:
try_intel_interface = true;
break;
}
+ /* For eDP 1.5 and above we are supposed to use VESA interface for brightness control */
+ if (intel_dp->edp_dpcd[0] >= DP_EDP_15)
+ try_vesa_interface = true;
+
/*
* Since Intel has their own backlight control interface, the majority of machines out there
* using DPCD backlight controls with Intel GPUs will be using this interface as opposed to
@@ -733,9 +741,6 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
* panel with Intel's OUI - which is also required for us to be able to detect Intel's
* backlight interface at all. This means that the only sensible way for us to detect both
* interfaces is to probe for Intel's first, and VESA's second.
- *
- * Also there is a chance some VBTs may advertise false Intel backlight support even if the
- * TCON DPCD says otherwise. This means we keep VESA interface as fallback in that case.
*/
if (try_intel_interface && intel_dp->edp_dpcd[0] <= DP_EDP_14b &&
intel_dp_aux_supports_hdr_backlight(connector)) {
@@ -745,7 +750,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
return 0;
}
- if (intel_dp_aux_supports_vesa_backlight(connector)) {
+ if (try_vesa_interface && intel_dp_aux_supports_vesa_backlight(connector)) {
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Using VESA eDP backlight controls\n",
connector->base.base.id, connector->base.name);
panel->backlight.funcs = &intel_dp_vesa_bl_funcs;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index a26094223f780..e566f2b49594a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -34,8 +34,10 @@
#include "intel_dp.h"
#include "intel_dp_link_training.h"
#include "intel_encoder.h"
+#include "intel_hdmi.h"
#include "intel_hotplug.h"
#include "intel_panel.h"
+#include "intel_psr.h"
#define LT_MSG_PREFIX "[CONNECTOR:%d:%s][ENCODER:%d:%s][%s] "
#define LT_MSG_ARGS(_intel_dp, _dp_phy) (_intel_dp)->attached_connector->base.base.id, \
@@ -710,16 +712,28 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp,
return true;
}
-void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate, bool is_vrr)
+void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate,
+ bool is_vrr,
+ bool pr_with_as_sdp_enable)
{
u8 link_config[2];
link_config[0] = is_vrr ? DP_MSA_TIMING_PAR_IGNORE_EN : 0;
+ link_config[0] |= pr_with_as_sdp_enable ? DP_FIXED_VTOTAL_AS_SDP_EN_IN_PR_ACTIVE : 0;
link_config[1] = drm_dp_is_uhbr_rate(link_rate) ?
DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B;
drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
}
+static bool
+intel_dp_pr_with_as_sdp_enabled(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ return intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) &&
+ (crtc_state->infoframes.enable &
+ intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC));
+}
+
static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
@@ -737,7 +751,9 @@ static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp,
* especially on the first real commit when clearing the inherited flag.
*/
intel_dp_link_training_set_mode(intel_dp,
- crtc_state->port_clock, crtc_state->vrr.in_range);
+ crtc_state->port_clock,
+ crtc_state->vrr.in_range,
+ intel_dp_pr_with_as_sdp_enabled(intel_dp, crtc_state));
}
void intel_dp_link_training_set_bw(struct intel_dp *intel_dp,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 33dcbde6a4089..18c34c1a472fa 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -18,7 +18,8 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp);
void intel_dp_link_training_set_mode(struct intel_dp *intel_dp,
- int link_rate, bool is_vrr);
+ int link_rate, bool is_vrr,
+ bool pr_with_as_sdp_enable);
void intel_dp_link_training_set_bw(struct intel_dp *intel_dp,
int link_bw, int rate_select, int lane_count,
bool enhanced_framing, bool post_lt_adj_req);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 8f73e01db17c9..bcdc504913471 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -837,7 +837,7 @@ static int intel_dp_mst_check_dsc_change(struct intel_atomic_state *state,
mst_pipe_mask = get_pipes_downstream_of_mst_port(state, mst_mgr, NULL);
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, mst_pipe_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, mst_pipe_mask) {
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@@ -1065,14 +1065,13 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
drm_atomic_get_mst_payload_state(new_mst_state, connector->mst.port);
struct intel_crtc *pipe_crtc;
bool last_mst_stream;
- int i;
last_mst_stream = intel_dp_mst_dec_active_streams(intel_dp);
drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream &&
!intel_dp_mst_is_master_trans(old_crtc_state));
- for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -1099,7 +1098,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state,
intel_ddi_disable_transcoder_func(old_crtc_state);
- for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -1310,7 +1309,7 @@ static void mst_stream_enable(struct intel_atomic_state *state,
enum transcoder trans = pipe_config->cpu_transcoder;
bool first_mst_stream = intel_dp_mst_active_streams(intel_dp) == 1;
struct intel_crtc *pipe_crtc;
- int ret, i;
+ int ret;
drm_WARN_ON(display->drm, pipe_config->has_pch_encoder);
@@ -1355,7 +1354,7 @@ static void mst_stream_enable(struct intel_atomic_state *state,
intel_enable_transcoder(pipe_config);
- for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config, i) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -2145,7 +2144,7 @@ void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp)
intel_dp_compute_rate(intel_dp, link_rate, &link_bw, &rate_select);
- intel_dp_link_training_set_mode(intel_dp, link_rate, false);
+ intel_dp_link_training_set_mode(intel_dp, link_rate, false, false);
intel_dp_link_training_set_bw(intel_dp, link_bw, rate_select, lane_count,
drm_dp_enhanced_frame_cap(intel_dp->dpcd), false);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c
index 5cfa1dd411dab..ba44769c9cfbe 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_test.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_test.c
@@ -471,7 +471,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder,
drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n",
encoder->base.base.id, encoder->base.name);
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
index 11712a151f729..d6bd1f7e01e18 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
@@ -146,7 +146,7 @@ static int allocate_initial_tunnel_bw_for_pipes(struct intel_dp *intel_dp, u8 pi
int tunnel_bw = 0;
int err;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
int stream_bw = intel_dp_config_required_rate(crtc_state);
@@ -740,9 +740,8 @@ static void atomic_decrease_bw(struct intel_atomic_state *state)
struct intel_crtc *crtc;
const struct intel_crtc_state *old_crtc_state;
const struct intel_crtc_state *new_crtc_state;
- int i;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
const struct drm_dp_tunnel_state *new_tunnel_state;
struct drm_dp_tunnel *tunnel;
int old_bw;
@@ -795,9 +794,8 @@ static void atomic_increase_bw(struct intel_atomic_state *state)
{
struct intel_crtc *crtc;
const struct intel_crtc_state *crtc_state;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
struct drm_dp_tunnel_state *tunnel_state;
struct drm_dp_tunnel *tunnel = crtc_state->dp_tunnel_ref.tunnel;
int bw;
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index bb487e647f767..0f933101b7dd1 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -4965,7 +4965,7 @@ static void readout_dpll_hw_state(struct intel_display *display,
pll->wakeref = intel_display_power_get(display, pll->info->power_domain);
pll->state.pipe_mask = 0;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 0fdb32ef241cd..6c95d4ae1ea90 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -137,7 +137,7 @@ static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *c
frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc,
+ for_each_intel_crtc_in_pipe_mask(display, crtc,
crtc_state->joiner_pipes)
frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
@@ -227,7 +227,7 @@ static void intel_drrs_frontbuffer_update(struct intel_display *display,
{
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
unsigned int frontbuffer_bits;
mutex_lock(&crtc->drrs.mutex);
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index df1d3d9dc3e5b..c8d4e3a5ce6b1 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -380,7 +380,7 @@ static bool intel_fbdev_init_bios(struct intel_display *display,
unsigned int max_size = 0;
/* Find the largest fb */
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
@@ -419,7 +419,7 @@ static bool intel_fbdev_init_bios(struct intel_display *display,
}
/* Now make sure all the pipes will fit into it */
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
@@ -489,7 +489,7 @@ static bool intel_fbdev_init_bios(struct intel_display *display,
drm_framebuffer_get(&ifbdev->fb->base);
/* Final pass to check if any active pipes don't have fbs */
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c
index f8876aa23c9ff..c170d3104e4cb 100644
--- a/drivers/gpu/drm/i915/display/intel_fdi.c
+++ b/drivers/gpu/drm/i915/display/intel_fdi.c
@@ -368,9 +368,8 @@ int intel_fdi_atomic_check_link(struct intel_atomic_state *state,
{
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
int ret;
if (!crtc_state->has_pch_encoder ||
diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
index 02013e89d8f2e..eca016d725d25 100644
--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
@@ -527,7 +527,7 @@ void intel_check_cpu_fifo_underruns(struct intel_display *display)
spin_lock_irq(&display->irq.lock);
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
if (crtc->cpu_fifo_underrun_disabled)
continue;
@@ -554,7 +554,7 @@ void intel_check_pch_fifo_underruns(struct intel_display *display)
spin_lock_irq(&display->irq.lock);
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
if (crtc->pch_fifo_underrun_disabled)
continue;
diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c b/drivers/gpu/drm/i915/display/intel_flipq.c
index 333d28faf4caa..bf278f60bba78 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.c
+++ b/drivers/gpu/drm/i915/display/intel_flipq.c
@@ -132,7 +132,7 @@ void intel_flipq_init(struct intel_display *display)
intel_dmc_wait_fw_load(display);
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
intel_flipq_crtc_init(crtc);
}
diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c b/drivers/gpu/drm/i915/display/intel_global_state.c
index 9e1369c834e49..886caf29c9ae8 100644
--- a/drivers/gpu/drm/i915/display/intel_global_state.c
+++ b/drivers/gpu/drm/i915/display/intel_global_state.c
@@ -140,7 +140,7 @@ static void assert_global_state_write_locked(struct intel_display *display)
{
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
drm_modeset_lock_assert_held(&crtc->base.mutex);
}
@@ -163,7 +163,7 @@ static void assert_global_state_read_locked(struct intel_atomic_state *state)
struct drm_modeset_acquire_ctx *ctx = state->base.acquire_ctx;
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
if (modeset_lock_is_held(ctx, &crtc->base.mutex))
return;
}
@@ -301,7 +301,7 @@ int intel_atomic_lock_global_state(struct intel_global_state *obj_state)
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
int ret;
ret = drm_modeset_lock(&crtc->base.mutex,
@@ -334,7 +334,7 @@ intel_atomic_global_state_is_serialized(struct intel_atomic_state *state)
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
if (!intel_atomic_get_new_crtc_state(state, crtc))
return false;
return true;
diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c
index 034fe199c2a15..6aa253678ec94 100644
--- a/drivers/gpu/drm/i915/display/intel_initial_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c
@@ -50,7 +50,7 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this,
struct intel_display *display = to_intel_display(this);
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_plane *plane =
to_intel_plane(crtc->base.primary);
const struct intel_plane_state *plane_state =
@@ -208,7 +208,7 @@ void intel_initial_plane_config(struct intel_display *display)
struct intel_initial_plane_configs all_plane_configs = {};
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_initial_plane_config *plane_config =
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c
index d2862de894fa7..b47474a3e9fec 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
@@ -108,7 +108,7 @@ static int __intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
struct intel_crtc *crtc;
int max_bpp_x16 = 0;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
struct intel_crtc_state *crtc_state;
int link_bpp_x16;
diff --git a/drivers/gpu/drm/i915/display/intel_load_detect.c b/drivers/gpu/drm/i915/display/intel_load_detect.c
index 2f767b15a7f9b..3fef1ebc63570 100644
--- a/drivers/gpu/drm/i915/display/intel_load_detect.c
+++ b/drivers/gpu/drm/i915/display/intel_load_detect.c
@@ -89,7 +89,7 @@ intel_load_detect_get_pipe(struct drm_connector *connector,
}
/* Find an unused one (if possible) */
- for_each_intel_crtc(display->drm, possible_crtc) {
+ for_each_intel_crtc(display, possible_crtc) {
if (!(encoder->base.possible_crtcs &
drm_crtc_mask(&possible_crtc->base)))
continue;
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
index e88082c8caace..e8730b5baf2a4 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
@@ -71,7 +71,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
to_intel_atomic_state(state)->internal = true;
/* Everything's already locked, -EDEADLK can't happen. */
- for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, temp_crtc,
BIT(pipe) |
intel_crtc_joiner_secondary_pipes(crtc_state)) {
struct intel_crtc_state *temp_crtc_state =
@@ -192,7 +192,7 @@ static u8 get_transcoder_pipes(struct intel_display *display,
struct intel_crtc *temp_crtc;
u8 pipes = 0;
- for_each_intel_crtc(display->drm, temp_crtc) {
+ for_each_intel_crtc(display, temp_crtc) {
struct intel_crtc_state *temp_crtc_state =
to_intel_crtc_state(temp_crtc->base.state);
@@ -248,7 +248,7 @@ static u8 get_joiner_secondary_pipes(struct intel_display *display, u8 primary_p
struct intel_crtc *primary_crtc;
u8 pipes = 0;
- for_each_intel_crtc_in_pipe_mask(display->drm, primary_crtc, primary_pipes_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, primary_crtc, primary_pipes_mask) {
struct intel_crtc_state *primary_crtc_state =
to_intel_crtc_state(primary_crtc->base.state);
@@ -278,16 +278,16 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
portsync_master_mask & joiner_secondaries_mask ||
portsync_slaves_mask & joiner_secondaries_mask);
- for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, joiner_secondaries_mask)
+ for_each_intel_crtc_in_pipe_mask(display, temp_crtc, joiner_secondaries_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
- for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_slaves_mask)
+ for_each_intel_crtc_in_pipe_mask(display, temp_crtc, portsync_slaves_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
- for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_master_mask)
+ for_each_intel_crtc_in_pipe_mask(display, temp_crtc, portsync_master_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
- for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, temp_crtc,
joiner_secondaries_mask |
portsync_slaves_mask |
portsync_master_mask)
@@ -334,6 +334,8 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
crtc_state->uapi.sharpness_strength = crtc_state->hw.sharpness_strength;
+ crtc_state->uapi.background_color =
+ intel_color_background_color_hw_to_drm(crtc_state->hw.background_color);
if (DISPLAY_INFO(display)->color.degamma_lut_size) {
/* assume 1:1 mapping */
@@ -376,7 +378,7 @@ intel_sanitize_plane_mapping(struct intel_display *display)
if (DISPLAY_VER(display) >= 4)
return;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_plane *plane =
to_intel_plane(crtc->base.primary);
struct intel_crtc *plane_crtc;
@@ -532,7 +534,7 @@ static void intel_sanitize_all_crtcs(struct intel_display *display,
for (;;) {
u32 old_mask = crtcs_forced_off;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
u32 crtc_mask = drm_crtc_mask(&crtc->base);
if (crtcs_forced_off & crtc_mask)
@@ -545,7 +547,7 @@ static void intel_sanitize_all_crtcs(struct intel_display *display,
break;
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -681,7 +683,7 @@ static void readout_plane_state(struct intel_display *display)
str_enabled_disabled(visible), pipe_name(pipe));
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -699,7 +701,7 @@ static void intel_modeset_readout_hw_state(struct intel_display *display)
struct intel_connector *connector;
struct drm_connector_list_iter conn_iter;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -741,7 +743,7 @@ static void intel_modeset_readout_hw_state(struct intel_display *display)
/* encoder should read be linked to joiner primary */
WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
- for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc,
+ for_each_intel_crtc_in_pipe_mask(display, secondary_crtc,
intel_crtc_joiner_secondary_pipes(crtc_state)) {
struct intel_crtc_state *secondary_crtc_state;
@@ -814,7 +816,7 @@ static void intel_modeset_readout_hw_state(struct intel_display *display)
}
drm_connector_list_iter_end(&conn_iter);
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane;
@@ -961,7 +963,7 @@ void intel_modeset_setup_hw_state(struct intel_display *display,
* intel_sanitize_plane_mapping() may need to do vblank
* waits, so we need vblank interrupts restored beforehand.
*/
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -997,7 +999,7 @@ void intel_modeset_setup_hw_state(struct intel_display *display,
intel_wm_get_hw_state(display);
intel_wm_sanitize(display);
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_power_domain_mask put_domains;
@@ -1009,5 +1011,5 @@ void intel_modeset_setup_hw_state(struct intel_display *display,
intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref);
- intel_power_domains_sanitize_state(display);
+ intel_display_power_sanitize_state(display);
}
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index a1f9558d53af2..2a52b36c646c7 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -1794,6 +1794,7 @@ static u8 intel_joiner_affected_planes(struct intel_atomic_state *state,
static int intel_joiner_add_affected_planes(struct intel_atomic_state *state,
u8 joined_pipes)
{
+ struct intel_display *display = to_intel_display(state);
u8 prev_affected_planes, affected_planes = 0;
/*
@@ -1811,7 +1812,7 @@ static int intel_joiner_add_affected_planes(struct intel_atomic_state *state,
do {
struct intel_crtc *crtc;
- for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, joined_pipes) {
int ret;
ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes);
@@ -1830,9 +1831,8 @@ static int intel_add_affected_planes(struct intel_atomic_state *state)
{
const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
- int i;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
int ret;
ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state));
@@ -1866,8 +1866,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state)
}
}
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
u8 old_active_planes, new_active_planes;
ret = icl_check_nv12_planes(state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c
index 7819b724795bb..6d32c52269a66 100644
--- a/drivers/gpu/drm/i915/display/intel_pmdemand.c
+++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c
@@ -190,7 +190,7 @@ intel_pmdemand_update_max_ddiclk(struct intel_display *display,
struct intel_crtc *crtc;
int i;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state)
intel_pmdemand_update_port_clock(display, pmdemand_state,
crtc->pipe,
new_crtc_state->port_clock);
@@ -299,7 +299,6 @@ static bool intel_pmdemand_needs_update(struct intel_atomic_state *state)
{
const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
struct intel_crtc *crtc;
- int i;
if (intel_bw_pmdemand_needs_update(state))
return true;
@@ -310,8 +309,7 @@ static bool intel_pmdemand_needs_update(struct intel_atomic_state *state)
if (intel_cdclk_pmdemand_needs_update(state))
return true;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i)
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state)
if (new_crtc_state->port_clock != old_crtc_state->port_clock)
return true;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 34eff85f4ea27..e138982dc91f6 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -793,27 +793,30 @@ static bool psr2_su_region_et_valid(struct intel_connector *connector, bool pane
static void _panel_replay_enable_sink(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
- u8 val = DP_PANEL_REPLAY_ENABLE |
- DP_PANEL_REPLAY_VSC_SDP_CRC_EN |
- DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN |
- DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN |
- DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN;
- u8 panel_replay_config2 = DP_PANEL_REPLAY_CRC_VERIFICATION;
+ u8 panel_replay_config[2];
+ u8 panel_replay_config_3;
+ panel_replay_config[0] = DP_PANEL_REPLAY_ENABLE |
+ DP_PANEL_REPLAY_VSC_SDP_CRC_EN |
+ DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN |
+ DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN |
+ DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN;
+ panel_replay_config[1] = DP_PANEL_REPLAY_CRC_VERIFICATION;
if (crtc_state->has_sel_update)
- val |= DP_PANEL_REPLAY_SU_ENABLE;
+ panel_replay_config[0] |= DP_PANEL_REPLAY_SU_ENABLE;
if (crtc_state->enable_psr2_su_region_et)
- val |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET;
+ panel_replay_config[0] |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET;
if (crtc_state->req_psr2_sdp_prior_scanline)
- panel_replay_config2 |=
+ panel_replay_config[1] |=
DP_PANEL_REPLAY_SU_REGION_SCANLINE_CAPTURE;
- drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG, val);
+ drm_dp_dpcd_write(&intel_dp->aux, PANEL_REPLAY_CONFIG,
+ panel_replay_config, sizeof(panel_replay_config));
- drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG2,
- panel_replay_config2);
+ panel_replay_config_3 = intel_dp_as_sdp_transmission_time();
+ drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG3, panel_replay_config_3);
}
static void _psr_enable_sink(struct intel_dp *intel_dp,
@@ -1508,15 +1511,21 @@ int _intel_psr_min_set_context_latency(const struct intel_crtc_state *crtc_state
* SRD_STATUS is used by PSR1 and Panel Replay DP on LunarLake.
*/
- if (DISPLAY_VER(display) >= 30 && (needs_panel_replay ||
- needs_sel_update))
+ if (needs_sel_update)
return 0;
- else if (DISPLAY_VER(display) < 30 && (needs_sel_update ||
- intel_crtc_has_type(crtc_state,
- INTEL_OUTPUT_EDP)))
+
+ if (DISPLAY_VER(display) < 30 &&
+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
return 0;
- else
- return 1;
+
+ if (DISPLAY_VER(display) >= 30 &&
+ needs_panel_replay)
+ return 0;
+
+ if (intel_vrr_always_use_vrr_tg(display))
+ return 0;
+
+ return 1;
}
static bool _wake_lines_fit_into_vblank(const struct intel_crtc_state *crtc_state,
@@ -1902,7 +1911,7 @@ void intel_psr_set_non_psr_pipes(struct intel_dp *intel_dp,
return;
/* We ignore possible secondary PSR/Panel Replay capable eDP */
- for_each_intel_crtc(display->drm, crtc)
+ for_each_intel_crtc(display, crtc)
active_pipes |= crtc->active ? BIT(crtc->pipe) : 0;
active_pipes = intel_calc_active_pipes(state, active_pipes);
@@ -2913,6 +2922,11 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
crtc_state->splitter.enable)
crtc_state->psr2_su_area.y1 = 0;
+ if (intel_display_wa(display, INTEL_DISPLAY_WA_16029024088) &&
+ crtc_state->req_psr2_sdp_prior_scanline &&
+ !crtc_state->enable_psr2_su_region_et)
+ crtc_state->psr2_su_area.y1 = 0;
+
/* Wa 14019834836 */
if (DISPLAY_VER(display) == 30)
intel_psr_apply_pr_link_on_su_wa(crtc_state);
@@ -4684,3 +4698,14 @@ bool intel_psr_use_trans_push(const struct intel_crtc_state *crtc_state)
return HAS_PSR_TRANS_PUSH_FRAME_CHANGE(display) && crtc_state->has_psr;
}
+
+bool intel_psr_pr_async_video_timing_supported(struct intel_dp *intel_dp)
+{
+ struct intel_connector *connector = intel_dp->attached_connector;
+ u8 *dpcd = connector->dp.panel_replay_caps.dpcd;
+ u8 pr_support = dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)];
+ u8 pr_cap = dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)];
+
+ return (pr_support & DP_PANEL_REPLAY_SUPPORT) &&
+ !(pr_cap & DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index 394b641840b39..29723e63888f8 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -86,5 +86,6 @@ void intel_psr_compute_config_late(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state);
int intel_psr_min_guardband(struct intel_crtc_state *crtc_state);
bool intel_psr_use_trans_push(const struct intel_crtc_state *crtc_state);
+bool intel_psr_pr_async_video_timing_supported(struct intel_dp *intel_dp);
#endif /* __INTEL_PSR_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 2880f2aa42437..f2d86b29c4154 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -1779,7 +1779,7 @@ static int reset_link_commit(struct intel_tc_port *tc,
if (!pipe_mask)
return 0;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) {
+ for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
struct intel_crtc_state *crtc_state;
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 1b09992ce9fdd..e03b5daac5be0 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -94,12 +94,10 @@ bool intel_vrr_possible(const struct intel_crtc_state *crtc_state)
void
intel_vrr_check_modeset(struct intel_atomic_state *state)
{
- int i;
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
struct intel_crtc *crtc;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
if (new_crtc_state->uapi.vrr_enabled !=
old_crtc_state->uapi.vrr_enabled)
new_crtc_state->uapi.mode_changed = true;
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c
index 308b8d363bba0..7994b983d509d 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.c
+++ b/drivers/gpu/drm/i915/display/skl_scaler.c
@@ -661,9 +661,9 @@ static int glk_coef_tap(int i)
return i % 7;
}
-static u16 glk_nearest_filter_coef(int t)
+static u16 glk_nearest_filter_coef(int tap)
{
- return t == 3 ? 0x0800 : 0x3000;
+ return tap == 3 ? 0x0800 : 0x3000;
}
/*
@@ -715,13 +715,13 @@ static void glk_program_nearest_filter_coefs(struct intel_display *display,
for (i = 0; i < 17 * 7; i += 2) {
u32 tmp;
- int t;
+ int tap;
- t = glk_coef_tap(i);
- tmp = glk_nearest_filter_coef(t);
+ tap = glk_coef_tap(i);
+ tmp = glk_nearest_filter_coef(tap);
- t = glk_coef_tap(i + 1);
- tmp |= glk_nearest_filter_coef(t) << 16;
+ tap = glk_coef_tap(i + 1);
+ tmp |= glk_nearest_filter_coef(tap) << 16;
intel_de_write_dsb(display, dsb,
GLK_PS_COEF_DATA_SET(pipe, id, set), tmp);
@@ -836,6 +836,22 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state)
PS_WIN_XSIZE(width) | PS_WIN_YSIZE(height));
}
+static int skl_pipe_scaler_get_hw_state(struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ for (int scaler_id = 0; scaler_id < crtc->num_scalers; scaler_id++) {
+ u32 ctl;
+
+ ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, scaler_id));
+ if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) == (PS_SCALER_EN | PS_BINDING_PIPE))
+ return scaler_id;
+ }
+
+ return -1;
+}
+
void
skl_program_plane_scaler(struct intel_dsb *dsb,
struct intel_plane *plane,
@@ -950,42 +966,32 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state)
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
- int id = -1;
- int i;
+ int scaler_id;
+ u32 pos, size;
/* find scaler attached to this pipe */
- for (i = 0; i < crtc->num_scalers; i++) {
- u32 ctl, pos, size;
-
- ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, i));
- if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) != (PS_SCALER_EN | PS_BINDING_PIPE))
- continue;
-
- id = i;
+ scaler_id = skl_pipe_scaler_get_hw_state(crtc_state);
+ if (scaler_id < 0)
+ return;
- if (scaler_has_casf(display, i))
- intel_casf_sharpness_get_config(crtc_state);
+ if (scaler_has_casf(display, scaler_id))
+ intel_casf_sharpness_get_config(crtc_state);
- crtc_state->pch_pfit.enabled = true;
+ crtc_state->pch_pfit.enabled = true;
- pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, i));
- size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, i));
+ pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, scaler_id));
+ size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, scaler_id));
- drm_rect_init(&crtc_state->pch_pfit.dst,
- REG_FIELD_GET(PS_WIN_XPOS_MASK, pos),
- REG_FIELD_GET(PS_WIN_YPOS_MASK, pos),
- REG_FIELD_GET(PS_WIN_XSIZE_MASK, size),
- REG_FIELD_GET(PS_WIN_YSIZE_MASK, size));
+ drm_rect_init(&crtc_state->pch_pfit.dst,
+ REG_FIELD_GET(PS_WIN_XPOS_MASK, pos),
+ REG_FIELD_GET(PS_WIN_YPOS_MASK, pos),
+ REG_FIELD_GET(PS_WIN_XSIZE_MASK, size),
+ REG_FIELD_GET(PS_WIN_YSIZE_MASK, size));
- scaler_state->scalers[i].in_use = true;
- break;
- }
+ scaler_state->scalers[scaler_id].in_use = true;
- scaler_state->scaler_id = id;
- if (id >= 0)
- scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
- else
- scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
+ scaler_state->scaler_id = scaler_id;
+ scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
}
void adl_scaler_ecc_mask(const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index ef431dd32e74a..ad4bfff6903da 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1532,7 +1532,7 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_dsb *dsb,
if (!color_plane)
y = plane_state->view.color_plane[color_plane].y + clip->y1;
else
- y = plane_state->view.color_plane[color_plane].y + clip->y1 / 2;
+ y = plane_state->view.color_plane[color_plane].y + DIV_ROUND_UP(clip->y1, 2);
val = y << 16 | x;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 96d2dcbe7bbcf..5a3677ea25b07 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2495,9 +2495,9 @@ skl_compute_ddb(struct intel_atomic_state *state)
struct intel_dbuf_state *new_dbuf_state = NULL;
struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
- int ret, i;
+ int ret;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
new_dbuf_state = intel_atomic_get_dbuf_state(state);
if (IS_ERR(new_dbuf_state))
return PTR_ERR(new_dbuf_state);
@@ -2529,7 +2529,7 @@ skl_compute_ddb(struct intel_atomic_state *state)
}
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
enum pipe pipe = crtc->pipe;
new_dbuf_state->slices[pipe] =
@@ -2561,7 +2561,7 @@ skl_compute_ddb(struct intel_atomic_state *state)
str_yes_no(new_dbuf_state->joined_mbus));
}
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
enum pipe pipe = crtc->pipe;
new_dbuf_state->weight[pipe] = intel_crtc_ddb_weight(new_crtc_state);
@@ -2574,13 +2574,13 @@ skl_compute_ddb(struct intel_atomic_state *state)
return ret;
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
ret = skl_crtc_allocate_ddb(state, crtc);
if (ret)
return ret;
}
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
ret = skl_crtc_allocate_plane_ddb(state, crtc);
if (ret)
return ret;
@@ -2687,13 +2687,11 @@ skl_print_wm_changes(struct intel_atomic_state *state)
const struct intel_crtc_state *new_crtc_state;
struct intel_plane *plane;
struct intel_crtc *crtc;
- int i;
if (!drm_debug_enabled(DRM_UT_KMS))
return;
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) {
const struct skl_pipe_wm *old_pipe_wm, *new_pipe_wm;
old_pipe_wm = &old_crtc_state->wm.skl.optimal;
@@ -2833,19 +2831,19 @@ static int pkgc_max_linetime(struct intel_atomic_state *state)
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
- int i, max_linetime;
+ int max_linetime;
/*
* Apparenty the hardware uses WM_LINETIME internally for
* this stuff, compute everything based on that.
*/
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state) {
display->pkgc.disable[crtc->pipe] = crtc_state->vrr.enable;
display->pkgc.linetime[crtc->pipe] = DIV_ROUND_UP(crtc_state->linetime, 8);
}
max_linetime = 0;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
if (display->pkgc.disable[crtc->pipe])
return 0;
@@ -2909,9 +2907,9 @@ skl_compute_wm(struct intel_atomic_state *state)
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc;
struct intel_crtc_state __maybe_unused *new_crtc_state;
- int ret, i;
+ int ret;
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
ret = skl_build_pipe_wm(state, crtc);
if (ret)
return ret;
@@ -2926,7 +2924,7 @@ skl_compute_wm(struct intel_atomic_state *state)
* based on how much ddb is available. Now we can actually
* check if the final watermarks changed.
*/
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
/*
@@ -3033,7 +3031,7 @@ static void skl_wm_get_hw_state(struct intel_display *display)
dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw);
dbuf_state->active_pipes = 0;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
@@ -3446,7 +3444,7 @@ static void pipe_mbus_dbox_ctl_update(struct intel_display *display,
{
struct intel_crtc *crtc;
- for_each_intel_crtc_in_pipe_mask(display->drm, crtc, dbuf_state->active_pipes)
+ for_each_intel_crtc_in_pipe_mask(display, crtc, dbuf_state->active_pipes)
intel_de_write(display, PIPE_MBUS_DBOX_CTL(crtc->pipe),
pipe_mbus_dbox_ctl(crtc, dbuf_state));
}
@@ -3758,14 +3756,14 @@ static bool skl_dbuf_is_misconfigured(struct intel_display *display)
struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
struct intel_crtc *crtc;
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
entries[crtc->pipe] = crtc_state->wm.skl.ddb;
}
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
u8 slices;
@@ -3803,7 +3801,7 @@ static void skl_dbuf_sanitize(struct intel_display *display)
drm_dbg_kms(display->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n");
- for_each_intel_crtc(display->drm, crtc) {
+ for_each_intel_crtc(display, crtc) {
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index f06b2e8cf7d4b..58081b52461ac 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -297,7 +297,7 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv)
struct intel_display *display = dev_priv->display;
intel_irq_fini(dev_priv);
- intel_power_domains_cleanup(display);
+ intel_display_power_cleanup(display);
i915_gem_cleanup_early(dev_priv);
intel_gt_driver_late_release_all(dev_priv);
intel_region_ttm_device_fini(dev_priv);
@@ -660,7 +660,7 @@ static int i915_driver_register(struct drm_i915_private *dev_priv)
intel_display_driver_register(display);
- intel_power_domains_enable(display);
+ intel_display_power_enable(display);
intel_runtime_pm_enable(&dev_priv->runtime_pm);
if (i915_switcheroo_register(dev_priv))
@@ -682,7 +682,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
i915_switcheroo_unregister(dev_priv);
intel_runtime_pm_disable(&dev_priv->runtime_pm);
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
intel_display_driver_unregister(display);
@@ -971,6 +971,7 @@ void i915_driver_remove(struct drm_i915_private *i915)
intel_display_driver_remove(display);
intel_irq_uninstall(i915);
+ intel_hpd_cancel_work(display);
intel_display_driver_remove_noirq(display);
@@ -1042,7 +1043,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
disable_rpm_wakeref_asserts(&i915->runtime_pm);
intel_runtime_pm_disable(&i915->runtime_pm);
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
drm_client_dev_suspend(&i915->drm);
if (intel_display_device_present(display)) {
@@ -1078,7 +1079,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
* - unify the driver remove and system/runtime suspend sequences with
* the above unified shutdown/poweroff sequence.
*/
- intel_power_domains_driver_remove(display);
+ intel_display_power_driver_remove(display);
enable_rpm_wakeref_asserts(&i915->runtime_pm);
intel_runtime_pm_driver_last_release(&i915->runtime_pm);
@@ -1125,7 +1126,7 @@ static int i915_drm_suspend(struct drm_device *dev)
/* We do a lot of poking in a lot of registers, make sure they work
* properly. */
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
drm_client_dev_suspend(dev);
if (intel_display_device_present(display)) {
drm_kms_helper_poll_disable(dev);
@@ -1325,7 +1326,7 @@ static int i915_drm_resume(struct drm_device *dev)
drm_client_dev_resume(dev);
- intel_power_domains_enable(display);
+ intel_display_power_enable(display);
intel_gvt_resume(dev_priv);
@@ -1557,7 +1558,7 @@ static int i915_pm_restore(struct device *kdev)
return i915_pm_resume(kdev);
}
-static int intel_runtime_suspend(struct device *kdev)
+static int i915_pm_runtime_suspend(struct device *kdev)
{
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
struct intel_display *display = dev_priv->display;
@@ -1590,7 +1591,7 @@ static int intel_runtime_suspend(struct device *kdev)
for_each_gt(gt, dev_priv, i)
intel_uncore_suspend(gt->uncore);
- intel_display_power_suspend(display);
+ intel_display_power_runtime_suspend(display);
ret = vlv_suspend_complete(dev_priv);
if (ret) {
@@ -1631,7 +1632,7 @@ static int intel_runtime_suspend(struct device *kdev)
if (IS_BROADWELL(dev_priv)) {
/*
* On Broadwell, if we use PCI_D1 the PCH DDI ports will stop
- * being detected, and the call we do at intel_runtime_resume()
+ * being detected, and the call we do at i915_pm_runtime_resume()
* won't be able to restore them. Since PCI_D3hot matches the
* actual specification and appears to be working, use it.
*/
@@ -1656,7 +1657,7 @@ static int intel_runtime_suspend(struct device *kdev)
return 0;
}
-static int intel_runtime_resume(struct device *kdev)
+static int i915_pm_runtime_resume(struct device *kdev)
{
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
struct intel_display *display = dev_priv->display;
@@ -1684,7 +1685,7 @@ static int intel_runtime_resume(struct device *kdev)
drm_dbg(&dev_priv->drm,
"Unclaimed access during suspend, bios?\n");
- intel_display_power_resume(display);
+ intel_display_power_runtime_resume(display);
ret = vlv_resume_prepare(dev_priv, true);
@@ -1764,8 +1765,8 @@ const struct dev_pm_ops i915_pm_ops = {
.restore = i915_pm_restore,
/* S0ix (via runtime suspend) event handlers */
- .runtime_suspend = intel_runtime_suspend,
- .runtime_resume = intel_runtime_resume,
+ .runtime_suspend = i915_pm_runtime_suspend,
+ .runtime_resume = i915_pm_runtime_resume,
};
static const struct file_operations i915_driver_fops = {
@@ -1869,9 +1870,6 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
#define DRIVER_PATCHLEVEL 0
static const struct drm_driver i915_drm_driver = {
- /* Don't use MTRRs here; the Xserver or userspace app should
- * deal with them for Intel hardware.
- */
.driver_features =
DRIVER_GEM |
DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d4d8dd0a41749..932409b943ad2 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -37,9 +37,6 @@
#include <drm/intel/intel_gmd_interrupt_regs.h>
#include "display/intel_display_irq.h"
-#include "display/intel_hotplug.h"
-#include "display/intel_hotplug_irq.h"
-#include "display/intel_lpe_audio.h"
#include "gt/intel_breadcrumbs.h"
#include "gt/intel_gt.h"
@@ -236,17 +233,15 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
do {
- u32 iir, gt_iir, pm_iir;
- u32 eir = 0, dpinvgtt = 0;
- u32 pipe_stats[I915_MAX_PIPES] = {};
- u32 hotplug_status = 0;
+ struct intel_display_irq_state state = {};
+ u32 gt_iir, pm_iir;
u32 ier = 0;
gt_iir = intel_uncore_read(&dev_priv->uncore, GTIIR);
pm_iir = intel_uncore_read(&dev_priv->uncore, GEN6_PMIIR);
- iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR);
+ state.iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR);
- if (gt_iir == 0 && pm_iir == 0 && iir == 0)
+ if (gt_iir == 0 && pm_iir == 0 && state.iir == 0)
break;
ret = IRQ_HANDLED;
@@ -272,26 +267,14 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
if (pm_iir)
intel_uncore_write(&dev_priv->uncore, GEN6_PMIIR, pm_iir);
- if (iir & I915_DISPLAY_PORT_INTERRUPT)
- hotplug_status = i9xx_hpd_irq_ack(display);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
- vlv_display_error_irq_ack(display, &eir, &dpinvgtt);
-
- /* Call regardless, as some status bits might not be
- * signalled in IIR */
- i9xx_pipestat_irq_ack(display, iir, pipe_stats);
-
- if (iir & (I915_LPE_PIPE_A_INTERRUPT |
- I915_LPE_PIPE_B_INTERRUPT))
- intel_lpe_audio_irq_handler(display);
+ intel_display_irq_ack(display, &state);
/*
* VLV_IIR is single buffered, and reflects the level
* from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
*/
- if (iir)
- intel_uncore_write(&dev_priv->uncore, VLV_IIR, iir);
+ if (state.iir)
+ intel_uncore_write(&dev_priv->uncore, VLV_IIR, state.iir);
intel_uncore_write(&dev_priv->uncore, VLV_IER, ier);
intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE);
@@ -301,13 +284,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
if (pm_iir)
gen6_rps_irq_handler(&to_gt(dev_priv)->rps, pm_iir);
- if (hotplug_status)
- i9xx_hpd_irq_handler(display, hotplug_status);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
- vlv_display_error_irq_handler(display, eir, dpinvgtt);
-
- valleyview_pipestat_irq_handler(display, pipe_stats);
+ intel_display_irq_handler(display, &state);
} while (0);
pmu_irq_stats(dev_priv, ret);
@@ -330,16 +307,14 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
do {
- u32 master_ctl, iir;
- u32 eir = 0, dpinvgtt = 0;
- u32 pipe_stats[I915_MAX_PIPES] = {};
- u32 hotplug_status = 0;
+ struct intel_display_irq_state state = {};
+ u32 master_ctl;
u32 ier = 0;
master_ctl = intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
- iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR);
+ state.iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR);
- if (master_ctl == 0 && iir == 0)
+ if (master_ctl == 0 && state.iir == 0)
break;
ret = IRQ_HANDLED;
@@ -362,38 +337,19 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
gen8_gt_irq_handler(to_gt(dev_priv), master_ctl);
- if (iir & I915_DISPLAY_PORT_INTERRUPT)
- hotplug_status = i9xx_hpd_irq_ack(display);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
- vlv_display_error_irq_ack(display, &eir, &dpinvgtt);
-
- /* Call regardless, as some status bits might not be
- * signalled in IIR */
- i9xx_pipestat_irq_ack(display, iir, pipe_stats);
-
- if (iir & (I915_LPE_PIPE_A_INTERRUPT |
- I915_LPE_PIPE_B_INTERRUPT |
- I915_LPE_PIPE_C_INTERRUPT))
- intel_lpe_audio_irq_handler(display);
+ intel_display_irq_ack(display, &state);
/*
* VLV_IIR is single buffered, and reflects the level
* from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
*/
- if (iir)
- intel_uncore_write(&dev_priv->uncore, VLV_IIR, iir);
+ if (state.iir)
+ intel_uncore_write(&dev_priv->uncore, VLV_IIR, state.iir);
intel_uncore_write(&dev_priv->uncore, VLV_IER, ier);
intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
- if (hotplug_status)
- i9xx_hpd_irq_handler(display, hotplug_status);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
- vlv_display_error_irq_handler(display, eir, dpinvgtt);
-
- valleyview_pipestat_irq_handler(display, pipe_stats);
+ intel_display_irq_handler(display, &state);
} while (0);
pmu_irq_stats(dev_priv, ret);
@@ -440,7 +396,7 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg)
ret = IRQ_HANDLED;
}
- if (ilk_display_irq_handler(display))
+ if (intel_display_irq_handler(display, NULL))
ret = IRQ_HANDLED;
if (GRAPHICS_VER(i915) >= 6) {
@@ -502,8 +458,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
/* IRQs are synced during runtime_suspend, we don't require a wakeref */
if (master_ctl & ~GEN8_GT_IRQS) {
+ const struct intel_display_irq_state state = {
+ .master_ctl = master_ctl,
+ };
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
- gen8_de_irq_handler(display, master_ctl);
+ intel_display_irq_handler(display, &state);
enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
}
@@ -555,7 +514,7 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
/* IRQs are synced during runtime_suspend, we don't require a wakeref */
if (master_ctl & GEN11_DISPLAY_IRQ)
- gen11_display_irq_handler(display);
+ intel_display_irq_handler(display, NULL);
gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl);
@@ -622,7 +581,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg)
gen11_gt_irq_handler(gt, master_ctl);
if (master_ctl & GEN11_DISPLAY_IRQ)
- gen11_display_irq_handler(display);
+ intel_display_irq_handler(display, NULL);
gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl);
@@ -640,7 +599,7 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv)
struct intel_display *display = dev_priv->display;
/* The master interrupt enable is in DEIER, reset display irq first */
- ilk_display_irq_reset(display);
+ intel_display_irq_reset(display);
gen5_gt_irq_reset(to_gt(dev_priv));
}
@@ -653,7 +612,7 @@ static void valleyview_irq_reset(struct drm_i915_private *dev_priv)
gen5_gt_irq_reset(to_gt(dev_priv));
- vlv_display_irq_reset(display);
+ intel_display_irq_reset(display);
}
static void gen8_irq_reset(struct drm_i915_private *dev_priv)
@@ -664,7 +623,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
gen8_master_intr_disable(intel_uncore_regs(uncore));
gen8_gt_irq_reset(to_gt(dev_priv));
- gen8_display_irq_reset(display);
+ intel_display_irq_reset(display);
gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
}
@@ -677,7 +636,7 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv)
gen11_master_intr_disable(intel_uncore_regs(&dev_priv->uncore));
gen11_gt_irq_reset(gt);
- gen11_display_irq_reset(display);
+ intel_display_irq_reset(display);
gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS);
gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
@@ -695,7 +654,7 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv)
for_each_gt(gt, dev_priv, i)
gen11_gt_irq_reset(gt);
- gen11_display_irq_reset(display);
+ intel_display_irq_reset(display);
gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS);
gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
@@ -715,7 +674,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv)
gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
- vlv_display_irq_reset(display);
+ intel_display_irq_reset(display);
}
static void ilk_irq_postinstall(struct drm_i915_private *dev_priv)
@@ -724,7 +683,7 @@ static void ilk_irq_postinstall(struct drm_i915_private *dev_priv)
gen5_gt_irq_postinstall(to_gt(dev_priv));
- ilk_de_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
}
static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv)
@@ -733,7 +692,7 @@ static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv)
gen5_gt_irq_postinstall(to_gt(dev_priv));
- vlv_display_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE);
intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER);
@@ -744,7 +703,7 @@ static void gen8_irq_postinstall(struct drm_i915_private *dev_priv)
struct intel_display *display = dev_priv->display;
gen8_gt_irq_postinstall(to_gt(dev_priv));
- gen8_de_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
gen8_master_intr_enable(intel_uncore_regs(&dev_priv->uncore));
}
@@ -757,7 +716,7 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
u32 gu_misc_masked = GEN11_GU_MISC_GSE;
gen11_gt_irq_postinstall(gt);
- gen11_de_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked);
@@ -778,7 +737,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv)
gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked);
- dg1_de_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
dg1_master_intr_enable(intel_uncore_regs(uncore));
intel_uncore_posting_read(uncore, DG1_MSTR_TILE_INTR);
@@ -790,7 +749,7 @@ static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv)
gen8_gt_irq_postinstall(to_gt(dev_priv));
- vlv_display_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ);
@@ -864,7 +823,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv)
struct intel_display *display = dev_priv->display;
struct intel_uncore *uncore = &dev_priv->uncore;
- i9xx_display_irq_reset(display);
+ intel_display_irq_reset(display);
gen2_error_reset(uncore, GEN2_ERROR_REGS);
gen2_irq_reset(uncore, GEN2_IRQ_REGS);
@@ -888,7 +847,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv)
gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->gen2_imr_mask, enable_mask);
- i915_display_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
}
static irqreturn_t i915_irq_handler(int irq, void *arg)
@@ -904,39 +863,29 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
do {
- u32 pipe_stats[I915_MAX_PIPES] = {};
+ struct intel_display_irq_state state = {};
u32 eir = 0, eir_stuck = 0;
- u32 hotplug_status = 0;
- u32 iir;
- iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR);
- if (iir == 0)
+ state.iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR);
+ if (state.iir == 0)
break;
ret = IRQ_HANDLED;
- if (iir & I915_DISPLAY_PORT_INTERRUPT)
- hotplug_status = i9xx_hpd_irq_ack(display);
+ intel_display_irq_ack(display, &state);
- /* Call regardless, as some status bits might not be
- * signalled in IIR */
- i9xx_pipestat_irq_ack(display, iir, pipe_stats);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
+ if (state.iir & I915_MASTER_ERROR_INTERRUPT)
i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck);
- intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir);
+ intel_uncore_write(&dev_priv->uncore, GEN2_IIR, state.iir);
- if (iir & I915_USER_INTERRUPT)
- intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], iir);
+ if (state.iir & I915_USER_INTERRUPT)
+ intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], state.iir);
- if (iir & I915_MASTER_ERROR_INTERRUPT)
+ if (state.iir & I915_MASTER_ERROR_INTERRUPT)
i9xx_error_irq_handler(dev_priv, eir, eir_stuck);
- if (hotplug_status)
- i9xx_hpd_irq_handler(display, hotplug_status);
-
- i915_pipestat_irq_handler(display, iir, pipe_stats);
+ intel_display_irq_handler(display, &state);
} while (0);
pmu_irq_stats(dev_priv, ret);
@@ -951,7 +900,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv)
struct intel_display *display = dev_priv->display;
struct intel_uncore *uncore = &dev_priv->uncore;
- i9xx_display_irq_reset(display);
+ intel_display_irq_reset(display);
gen2_error_reset(uncore, GEN2_ERROR_REGS);
gen2_irq_reset(uncore, GEN2_IRQ_REGS);
@@ -997,7 +946,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv)
gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->gen2_imr_mask, enable_mask);
- i965_display_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
}
static irqreturn_t i965_irq_handler(int irq, void *arg)
@@ -1013,44 +962,34 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
do {
- u32 pipe_stats[I915_MAX_PIPES] = {};
+ struct intel_display_irq_state state = {};
u32 eir = 0, eir_stuck = 0;
- u32 hotplug_status = 0;
- u32 iir;
- iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR);
- if (iir == 0)
+ state.iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR);
+ if (state.iir == 0)
break;
ret = IRQ_HANDLED;
- if (iir & I915_DISPLAY_PORT_INTERRUPT)
- hotplug_status = i9xx_hpd_irq_ack(display);
+ intel_display_irq_ack(display, &state);
- /* Call regardless, as some status bits might not be
- * signalled in IIR */
- i9xx_pipestat_irq_ack(display, iir, pipe_stats);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
+ if (state.iir & I915_MASTER_ERROR_INTERRUPT)
i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck);
- intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir);
+ intel_uncore_write(&dev_priv->uncore, GEN2_IIR, state.iir);
- if (iir & I915_USER_INTERRUPT)
+ if (state.iir & I915_USER_INTERRUPT)
intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0],
- iir);
+ state.iir);
- if (iir & I915_BSD_USER_INTERRUPT)
+ if (state.iir & I915_BSD_USER_INTERRUPT)
intel_engine_cs_irq(to_gt(dev_priv)->engine[VCS0],
- iir >> 25);
+ state.iir >> 25);
- if (iir & I915_MASTER_ERROR_INTERRUPT)
+ if (state.iir & I915_MASTER_ERROR_INTERRUPT)
i9xx_error_irq_handler(dev_priv, eir, eir_stuck);
- if (hotplug_status)
- i9xx_hpd_irq_handler(display, hotplug_status);
-
- i965_pipestat_irq_handler(display, iir, pipe_stats);
+ intel_display_irq_handler(display, &state);
} while (0);
pmu_irq_stats(dev_priv, IRQ_HANDLED);
@@ -1200,7 +1139,6 @@ int intel_irq_install(struct drm_i915_private *dev_priv)
*/
void intel_irq_uninstall(struct drm_i915_private *dev_priv)
{
- struct intel_display *display = dev_priv->display;
int irq = to_pci_dev(dev_priv->drm.dev)->irq;
if (drm_WARN_ON(&dev_priv->drm, !dev_priv->irqs_enabled))
@@ -1210,7 +1148,6 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
free_irq(irq, dev_priv);
- intel_hpd_cancel_work(display);
dev_priv->irqs_enabled = false;
}
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index d11c2814b787b..0d5b2624fe661 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -442,7 +442,7 @@ void intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref)
*
* Note that this function does currently not enable runtime pm for the
* subordinate display power domains. That is done by
- * intel_power_domains_enable().
+ * intel_display_power_enable().
*/
void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
{
diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
index 053abd6f65146..810d93fefcbcc 100644
--- a/drivers/gpu/drm/xe/display/xe_display.c
+++ b/drivers/gpu/drm/xe/display/xe_display.c
@@ -88,7 +88,7 @@ static void xe_display_fini_early(void *arg)
intel_display_driver_remove_nogem(display);
intel_display_driver_remove_noirq(display);
intel_opregion_cleanup(display);
- intel_power_domains_cleanup(display);
+ intel_display_power_cleanup(display);
}
int xe_display_init_early(struct xe_device *xe)
@@ -104,6 +104,15 @@ int xe_display_init_early(struct xe_device *xe)
intel_display_driver_early_probe(display);
+ intel_display_device_info_runtime_init(display);
+
+ /* Display may have been disabled at runtime init */
+ if (!intel_display_device_present(display)) {
+ xe->info.probe_display = false;
+ unset_display_features(xe);
+ return 0;
+ }
+
/* Early display init.. */
intel_opregion_setup(display);
@@ -117,8 +126,6 @@ int xe_display_init_early(struct xe_device *xe)
intel_bw_init_hw(display);
- intel_display_device_info_runtime_init(display);
-
err = intel_display_driver_probe_noirq(display);
if (err)
goto err_opregion;
@@ -130,7 +137,7 @@ int xe_display_init_early(struct xe_device *xe)
return devm_add_action_or_reset(xe->drm.dev, xe_display_fini_early, xe);
err_noirq:
intel_display_driver_remove_noirq(display);
- intel_power_domains_cleanup(display);
+ intel_display_power_cleanup(display);
err_opregion:
intel_opregion_cleanup(display);
return err;
@@ -170,7 +177,7 @@ void xe_display_register(struct xe_device *xe)
return;
intel_display_driver_register(display);
- intel_power_domains_enable(display);
+ intel_display_power_enable(display);
}
void xe_display_unregister(struct xe_device *xe)
@@ -180,7 +187,7 @@ void xe_display_unregister(struct xe_device *xe)
if (!xe->info.probe_display)
return;
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
intel_display_driver_unregister(display);
}
@@ -194,7 +201,7 @@ void xe_display_irq_handler(struct xe_device *xe, u32 master_ctl)
return;
if (master_ctl & DISPLAY_IRQ)
- gen11_display_irq_handler(display);
+ intel_display_irq_handler(display, NULL);
}
void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir)
@@ -215,7 +222,7 @@ void xe_display_irq_reset(struct xe_device *xe)
if (!xe->info.probe_display)
return;
- gen11_display_irq_reset(display);
+ intel_display_irq_reset(display);
}
void xe_display_irq_postinstall(struct xe_device *xe)
@@ -225,7 +232,7 @@ void xe_display_irq_postinstall(struct xe_device *xe)
if (!xe->info.probe_display)
return;
- gen11_de_irq_postinstall(display);
+ intel_display_irq_postinstall(display);
}
static bool suspend_to_idle(void)
@@ -237,27 +244,6 @@ static bool suspend_to_idle(void)
return false;
}
-static void xe_display_flush_cleanup_work(struct xe_device *xe)
-{
- struct intel_crtc *crtc;
-
- for_each_intel_crtc(&xe->drm, crtc) {
- struct drm_crtc_commit *commit;
-
- spin_lock(&crtc->base.commit_lock);
- commit = list_first_entry_or_null(&crtc->base.commit_list,
- struct drm_crtc_commit, commit_entry);
- if (commit)
- drm_crtc_commit_get(commit);
- spin_unlock(&crtc->base.commit_lock);
-
- if (commit) {
- wait_for_completion(&commit->cleanup_done);
- drm_crtc_commit_put(commit);
- }
- }
-}
-
static void xe_display_enable_d3cold(struct xe_device *xe)
{
struct intel_display *display = xe->display;
@@ -269,9 +255,9 @@ static void xe_display_enable_d3cold(struct xe_device *xe)
* We do a lot of poking in a lot of registers, make sure they work
* properly.
*/
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
- xe_display_flush_cleanup_work(xe);
+ intel_display_flush_cleanup_work(display);
intel_opregion_suspend(display, PCI_D3cold);
@@ -302,7 +288,7 @@ static void xe_display_disable_d3cold(struct xe_device *xe)
intel_opregion_resume(display);
- intel_power_domains_enable(display);
+ intel_display_power_enable(display);
}
void xe_display_pm_suspend(struct xe_device *xe)
@@ -317,7 +303,7 @@ void xe_display_pm_suspend(struct xe_device *xe)
* We do a lot of poking in a lot of registers, make sure they work
* properly.
*/
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
drm_client_dev_suspend(&xe->drm);
if (intel_display_device_present(display)) {
@@ -326,7 +312,7 @@ void xe_display_pm_suspend(struct xe_device *xe)
intel_display_driver_suspend(display);
}
- xe_display_flush_cleanup_work(xe);
+ intel_display_flush_cleanup_work(display);
intel_encoder_block_all_hpds(display);
@@ -349,7 +335,7 @@ void xe_display_pm_shutdown(struct xe_device *xe)
if (!xe->info.probe_display)
return;
- intel_power_domains_disable(display);
+ intel_display_power_disable(display);
drm_client_dev_suspend(&xe->drm);
if (intel_display_device_present(display)) {
@@ -358,7 +344,7 @@ void xe_display_pm_shutdown(struct xe_device *xe)
intel_display_driver_suspend(display);
}
- xe_display_flush_cleanup_work(xe);
+ intel_display_flush_cleanup_work(display);
intel_dp_mst_suspend(display);
intel_encoder_block_all_hpds(display);
intel_hpd_cancel_work(display);
@@ -430,7 +416,7 @@ void xe_display_pm_shutdown_late(struct xe_device *xe)
* for now leaving all display power wells in the INIT power domain
* enabled.
*/
- intel_power_domains_driver_remove(display);
+ intel_display_power_driver_remove(display);
}
void xe_display_pm_resume_early(struct xe_device *xe)
@@ -477,7 +463,7 @@ void xe_display_pm_resume(struct xe_device *xe)
drm_client_dev_resume(&xe->drm);
- intel_power_domains_enable(display);
+ intel_display_power_enable(display);
}
void xe_display_pm_runtime_resume(struct xe_device *xe)