summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-03-31 16:38:49 +1000
committerDave Airlie <airlied@redhat.com>2026-03-31 16:38:50 +1000
commit28899037b85e77490f202fa9361c3c2780be3ec2 (patch)
treebbe3497523d520a86923e8affb6aabd737fb90bb /drivers/gpu/drm
parentf6225b546dfccfc322b18c0d757b7b9c767a1e27 (diff)
parente012fa31f90de0928d85ab22d9cc5fc8fe84c5b0 (diff)
Merge tag 'drm-intel-next-2026-03-30' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
drm/i915 feature pull #2 for v7.1: Refactoring and cleanups: - Refactor LT PHY PLL handling to use the DPLL framework (Mika) - Implement display register polling and waits in display code (Ville) - Move PCH clock gating in display PCH file (Luca) - Add shared stepping info header for i915 and display (Jani) - Clean up GVT I2C command decoding (Jonathan) - NV12 plane unlinking cleanups (Ville) - Clean up NV12 DDB/watermark handling for pre-ICL platforms (Ville) Fixes: - An assortment of DSI fixes (Ville) - Handle PORT_NONE in assert_port_valid() (Jonathan) - Fix link failure without FBDEV emulation (Arnd Bergmann) - Quirk disable panel replay on certain Dell XPS models (Jouni) - Check if VESA DPCD AUX backlight is possible (Suraj) Other: - Mailmap update for Christoph (Christoph) Signed-off-by: Dave Airlie <airlied@redhat.com> # Conflicts: # drivers/gpu/drm/i915/display/intel_plane.c From: Jani Nikula <jani.nikula@intel.com> Link: https://patch.msgid.link/ac9dfdb745d5a67c519ea150a6f36f8f74b8760e@intel.com
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c21
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi_regs.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c26
-rw-r--r--drivers/gpu/drm/i915/display/intel_de.c178
-rw-r--r--drivers/gpu/drm/i915/display/intel_de.h121
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c35
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.c28
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c19
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c32
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c26
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c186
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi_vbt.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_lt_phy.c193
-rw-r--r--drivers/gpu/drm/i915/display/intel_lt_phy.h23
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_verify.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch.c93
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane.c60
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_quirks.c25
-rw-r--r--drivers/gpu/drm/i915/display/intel_quirks.h1
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.c160
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/edid.c18
-rw-r--r--drivers/gpu/drm/i915/i915_initial_plane.c3
-rw-r--r--drivers/gpu/drm/i915/intel_clock_gating.c86
-rw-r--r--drivers/gpu/drm/i915/intel_step.h57
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c72
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_uncore.c62
-rw-r--r--drivers/gpu/drm/xe/Makefile1
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_step.h3
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h31
40 files changed, 943 insertions, 670 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index be976a90c5a6..b677720a1c2d 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -254,6 +254,7 @@ i915-y += \
display/intel_crtc_state_dump.o \
display/intel_cursor.o \
display/intel_dbuf_bw.o \
+ display/intel_de.o \
display/intel_display.o \
display/intel_display_conversion.o \
display/intel_display_driver.o \
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index c04327979678..afbaa0465842 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -711,7 +711,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
dsi_trans = dsi_port_to_transcoder(port);
tmp = intel_de_read(display, DSI_TRANS_FUNC_CONF(dsi_trans));
- if (intel_dsi->eotp_pkt)
+ if (intel_dsi->eot_pkt)
tmp &= ~EOTP_DISABLED;
else
tmp |= EOTP_DISABLED;
@@ -729,6 +729,12 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
else
tmp |= CLK_HS_CONTINUOUS;
+ if (DISPLAY_VER(display) >= 12 &&
+ intel_dsi->lp_clock_during_lpm)
+ tmp |= LP_CLK_DURING_LPM;
+ else
+ tmp &= ~LP_CLK_DURING_LPM;
+
/* configure buffer threshold limit to minimum */
tmp &= ~PIX_BUF_THRESHOLD_MASK;
tmp |= PIX_BUF_THRESHOLD_1_4;
@@ -765,10 +771,11 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
}
}
- if (DISPLAY_VER(display) >= 12) {
- if (is_vid_mode(intel_dsi))
- tmp |= BLANKING_PACKET_ENABLE;
- }
+ if (DISPLAY_VER(display) >= 12 &&
+ is_vid_mode(intel_dsi) && intel_dsi->blanking_pkt)
+ tmp |= BLANKING_PACKET_ENABLE;
+ else
+ tmp &= ~BLANKING_PACKET_ENABLE;
/* program DSI operation mode */
if (is_vid_mode(intel_dsi)) {
@@ -888,7 +895,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
* non-compressed link speeds, and simplifies down to the ratio between
* compressed and non-compressed bpp.
*/
- if (crtc_state->dsc.compression_enable) {
+ if (is_vid_mode(intel_dsi) && crtc_state->dsc.compression_enable) {
mul = fxp_q4_to_int(crtc_state->dsc.compressed_bpp_x16);
div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
}
@@ -1502,7 +1509,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
- if (pipe_config->dsc.compressed_bpp_x16) {
+ if (is_vid_mode(intel_dsi) && pipe_config->dsc.compressed_bpp_x16) {
int div = fxp_q4_to_int(pipe_config->dsc.compressed_bpp_x16);
int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
diff --git a/drivers/gpu/drm/i915/display/icl_dsi_regs.h b/drivers/gpu/drm/i915/display/icl_dsi_regs.h
index b601b7632339..55ab57adcb0f 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi_regs.h
+++ b/drivers/gpu/drm/i915/display/icl_dsi_regs.h
@@ -227,12 +227,13 @@
#define CLK_ENTER_LP_AFTER_DATA (0x0 << 8)
#define CLK_HS_OR_LP (0x2 << 8)
#define CLK_HS_CONTINUOUS (0x3 << 8)
+#define LP_CLK_DURING_LPM (1 << 7) /* tgl+ */
#define LINK_CALIBRATION_MASK (0x3 << 4)
#define LINK_CALIBRATION_SHIFT 4
#define CALIBRATION_DISABLED (0x0 << 4)
#define CALIBRATION_ENABLED_INITIAL_ONLY (0x2 << 4)
#define CALIBRATION_ENABLED_INITIAL_PERIODIC (0x3 << 4)
-#define BLANKING_PACKET_ENABLE (1 << 2)
+#define BLANKING_PACKET_ENABLE (1 << 2) /* tgl+ */
#define S3D_ORIENTATION_LANDSCAPE (1 << 1)
#define EOTP_DISABLED (1 << 0)
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index 6a471c021c0e..7e59409bbf01 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -2180,7 +2180,7 @@ static int intel_c10pll_calc_state(const struct intel_crtc_state *crtc_state,
return 0;
}
-static int readout_enabled_lane_count(struct intel_encoder *encoder)
+int intel_readout_lane_count(struct intel_encoder *encoder, int lane0, int lane1)
{
struct intel_display *display = to_intel_display(encoder);
u8 enabled_tx_lane_count = 0;
@@ -2212,7 +2212,7 @@ static int readout_enabled_lane_count(struct intel_encoder *encoder)
max_tx_lane_count = round_up(max_tx_lane_count, 2);
for (tx_lane = 0; tx_lane < max_tx_lane_count; tx_lane++) {
- u8 phy_lane_mask = tx_lane < 2 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1;
+ u8 phy_lane_mask = tx_lane < 2 ? lane0 : lane1;
int tx = tx_lane % 2 + 1;
u8 val;
@@ -2252,7 +2252,8 @@ static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
*/
intel_c10_msgbus_access_begin(encoder, lane);
- cx0pll_state->lane_count = readout_enabled_lane_count(encoder);
+ cx0pll_state->lane_count = intel_readout_lane_count(encoder, INTEL_CX0_LANE0,
+ INTEL_CX0_LANE1);
for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++)
pll_state->pll[i] = intel_cx0_read(encoder, lane, PHY_C10_VDR_PLL(i));
@@ -2707,7 +2708,8 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
wakeref = intel_cx0_phy_transaction_begin(encoder);
- cx0pll_state->lane_count = readout_enabled_lane_count(encoder);
+ cx0pll_state->lane_count = intel_readout_lane_count(encoder, INTEL_CX0_LANE0,
+ INTEL_CX0_LANE1);
/* 1. Read VDR params and current context selection */
intel_c20_readout_vdr_params(encoder, &pll_state->vdr, &cntx);
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
index 1d4480b8bf39..1428e7a5a318 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
@@ -28,6 +28,7 @@ struct intel_hdmi;
void intel_cx0_clear_response_ready_flag(struct intel_encoder *encoder,
int lane);
bool intel_encoder_is_c10phy(struct intel_encoder *encoder);
+int intel_readout_lane_count(struct intel_encoder *encoder, int lane0, int lane1);
void intel_mtl_pll_enable(struct intel_encoder *encoder,
struct intel_dpll *pll,
const struct intel_dpll_hw_state *dpll_hw_state);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 7f1576bfe4b0..ebefa889bc8c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4243,21 +4243,6 @@ void intel_ddi_get_clock(struct intel_encoder *encoder,
&crtc_state->dpll_hw_state);
}
-static void xe3plpd_ddi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_state *crtc_state)
-{
- struct intel_display *display = to_intel_display(encoder);
-
- intel_lt_phy_pll_readout_hw_state(encoder, crtc_state, &crtc_state->dpll_hw_state.ltpll);
-
- if (crtc_state->dpll_hw_state.ltpll.tbt_mode)
- crtc_state->port_clock = intel_mtl_tbt_calc_port_clock(encoder);
- else
- crtc_state->port_clock =
- intel_lt_phy_calc_port_clock(display, &crtc_state->dpll_hw_state.ltpll);
- intel_ddi_get_config(encoder, crtc_state);
-}
-
static bool icl_ddi_tc_pll_is_tbt(const struct intel_dpll *pll)
{
return pll->info->id == DPLL_ID_ICL_TBTPLL;
@@ -5298,10 +5283,13 @@ void intel_ddi_init(struct intel_display *display,
encoder->pipe_mask = ~0;
if (HAS_LT_PHY(display)) {
- encoder->enable_clock = intel_xe3plpd_pll_enable;
- encoder->disable_clock = intel_xe3plpd_pll_disable;
- encoder->port_pll_type = intel_mtl_port_pll_type;
- encoder->get_config = xe3plpd_ddi_get_config;
+ encoder->enable_clock = intel_mtl_pll_enable_clock;
+ encoder->disable_clock = intel_mtl_pll_disable_clock;
+ encoder->port_pll_type = icl_ddi_tc_port_pll_type;
+ if (intel_encoder_is_tc(encoder))
+ encoder->get_config = mtl_ddi_tc_phy_get_config;
+ else
+ encoder->get_config = mtl_ddi_non_tc_phy_get_config;
} else if (DISPLAY_VER(display) >= 14) {
encoder->enable_clock = intel_mtl_pll_enable_clock;
encoder->disable_clock = intel_mtl_pll_disable_clock;
diff --git a/drivers/gpu/drm/i915/display/intel_de.c b/drivers/gpu/drm/i915/display/intel_de.c
new file mode 100644
index 000000000000..d2a418da2d54
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_de.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#include <linux/delay.h>
+
+#include <drm/drm_print.h>
+
+#include "intel_de.h"
+
+static int __intel_de_wait_for_register(struct intel_display *display,
+ i915_reg_t reg, u32 mask, u32 value,
+ unsigned int timeout_us,
+ u32 (*read)(struct intel_display *display, i915_reg_t reg),
+ u32 *out_val, bool is_atomic)
+{
+ const ktime_t end = ktime_add_us(ktime_get_raw(), timeout_us);
+ int wait_max = 1000;
+ int wait = 10;
+ u32 reg_value;
+ int ret;
+
+ might_sleep_if(!is_atomic);
+
+ if (timeout_us <= 10) {
+ is_atomic = true;
+ wait = 1;
+ }
+
+ for (;;) {
+ bool expired = ktime_after(ktime_get_raw(), end);
+
+ /* guarantee the condition is evaluated after timeout expired */
+ barrier();
+
+ reg_value = read(display, reg);
+ if ((reg_value & mask) == value) {
+ ret = 0;
+ break;
+ }
+
+ if (expired) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+
+ if (is_atomic)
+ udelay(wait);
+ else
+ usleep_range(wait, wait << 1);
+
+ if (wait < wait_max)
+ wait <<= 1;
+ }
+
+ if (out_val)
+ *out_val = reg_value;
+
+ return ret;
+}
+
+static int intel_de_wait_for_register(struct intel_display *display,
+ i915_reg_t reg, u32 mask, u32 value,
+ unsigned int fast_timeout_us,
+ unsigned int slow_timeout_us,
+ u32 (*read)(struct intel_display *display, i915_reg_t reg),
+ u32 *out_value, bool is_atomic)
+{
+ int ret = -EINVAL;
+
+ if (fast_timeout_us)
+ ret = __intel_de_wait_for_register(display, reg, mask, value,
+ fast_timeout_us, read,
+ out_value, is_atomic);
+
+ if (ret && slow_timeout_us)
+ ret = __intel_de_wait_for_register(display, reg, mask, value,
+ slow_timeout_us, read,
+ out_value, is_atomic);
+
+ return ret;
+}
+
+int intel_de_wait_us(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_us,
+ u32 *out_value)
+{
+ int ret;
+
+ intel_dmc_wl_get(display, reg);
+
+ ret = intel_de_wait_for_register(display, reg, mask, value,
+ timeout_us, 0,
+ intel_de_read,
+ out_value, false);
+
+ intel_dmc_wl_put(display, reg);
+
+ return ret;
+}
+
+int intel_de_wait_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_ms,
+ u32 *out_value)
+{
+ int ret;
+
+ intel_dmc_wl_get(display, reg);
+
+ ret = intel_de_wait_for_register(display, reg, mask, value,
+ 2, timeout_ms * 1000,
+ intel_de_read,
+ out_value, false);
+
+ intel_dmc_wl_put(display, reg);
+
+ return ret;
+}
+
+int intel_de_wait_fw_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_ms,
+ u32 *out_value)
+{
+ return intel_de_wait_for_register(display, reg, mask, value,
+ 2, timeout_ms * 1000,
+ intel_de_read_fw,
+ out_value, false);
+}
+
+int intel_de_wait_fw_us_atomic(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_us,
+ u32 *out_value)
+{
+ return intel_de_wait_for_register(display, reg, mask, value,
+ timeout_us, 0,
+ intel_de_read_fw,
+ out_value, true);
+}
+
+int intel_de_wait_for_set_us(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_us)
+{
+ return intel_de_wait_us(display, reg, mask, mask, timeout_us, NULL);
+}
+
+int intel_de_wait_for_clear_us(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_us)
+{
+ return intel_de_wait_us(display, reg, mask, 0, timeout_us, NULL);
+}
+
+int intel_de_wait_for_set_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_ms)
+{
+ return intel_de_wait_ms(display, reg, mask, mask, timeout_ms, NULL);
+}
+
+int intel_de_wait_for_clear_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_ms)
+{
+ return intel_de_wait_ms(display, reg, mask, 0, timeout_ms, NULL);
+}
+
+u8 intel_de_read8(struct intel_display *display, i915_reg_t reg)
+{
+ /* this is only used on VGA registers (possible on pre-g4x) */
+ drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 5 || display->platform.g4x);
+
+ return intel_uncore_read8(__to_uncore(display), reg);
+}
+
+void intel_de_write8(struct intel_display *display, i915_reg_t reg, u8 val)
+{
+ drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 5 || display->platform.g4x);
+
+ intel_uncore_write8(__to_uncore(display), reg, val);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h
index f30f3f8ebee1..f87b84ab9d6d 100644
--- a/drivers/gpu/drm/i915/display/intel_de.h
+++ b/drivers/gpu/drm/i915/display/intel_de.h
@@ -6,8 +6,6 @@
#ifndef __INTEL_DE_H__
#define __INTEL_DE_H__
-#include <drm/drm_print.h>
-
#include "intel_display_core.h"
#include "intel_dmc_wl.h"
#include "intel_dsb.h"
@@ -19,6 +17,9 @@ static inline struct intel_uncore *__to_uncore(struct intel_display *display)
return to_intel_uncore(display->drm);
}
+u8 intel_de_read8(struct intel_display *display, i915_reg_t reg);
+void intel_de_write8(struct intel_display *display, i915_reg_t reg, u8 val);
+
static inline u32
intel_de_read(struct intel_display *display, i915_reg_t reg)
{
@@ -33,23 +34,6 @@ intel_de_read(struct intel_display *display, i915_reg_t reg)
return val;
}
-static inline u8
-intel_de_read8(struct intel_display *display, i915_reg_t reg)
-{
- /* this is only used on VGA registers (possible on pre-g4x) */
- drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 5 || display->platform.g4x);
-
- return intel_uncore_read8(__to_uncore(display), reg);
-}
-
-static inline void
-intel_de_write8(struct intel_display *display, i915_reg_t reg, u8 val)
-{
- drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 5 || display->platform.g4x);
-
- intel_uncore_write8(__to_uncore(display), reg, val);
-}
-
static inline u64
intel_de_read64_2x32(struct intel_display *display,
i915_reg_t lower_reg, i915_reg_t upper_reg)
@@ -102,85 +86,26 @@ intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set)
return val;
}
-static inline int
-intel_de_wait_us(struct intel_display *display, i915_reg_t reg,
- u32 mask, u32 value, unsigned int timeout_us,
- u32 *out_value)
-{
- int ret;
-
- intel_dmc_wl_get(display, reg);
-
- ret = __intel_wait_for_register(__to_uncore(display), reg, mask,
- value, timeout_us, 0, out_value);
-
- intel_dmc_wl_put(display, reg);
-
- return ret;
-}
-
-static inline int
-intel_de_wait_ms(struct intel_display *display, i915_reg_t reg,
- u32 mask, u32 value, unsigned int timeout_ms,
- u32 *out_value)
-{
- int ret;
-
- intel_dmc_wl_get(display, reg);
-
- ret = __intel_wait_for_register(__to_uncore(display), reg, mask,
- value, 2, timeout_ms, out_value);
-
- intel_dmc_wl_put(display, reg);
-
- return ret;
-}
-
-static inline int
-intel_de_wait_fw_ms(struct intel_display *display, i915_reg_t reg,
- u32 mask, u32 value, unsigned int timeout_ms,
- u32 *out_value)
-{
- return __intel_wait_for_register_fw(__to_uncore(display), reg, mask,
- value, 2, timeout_ms, out_value);
-}
-
-static inline int
-intel_de_wait_fw_us_atomic(struct intel_display *display, i915_reg_t reg,
- u32 mask, u32 value, unsigned int timeout_us,
- u32 *out_value)
-{
- return __intel_wait_for_register_fw(__to_uncore(display), reg, mask,
- value, timeout_us, 0, out_value);
-}
-
-static inline int
-intel_de_wait_for_set_us(struct intel_display *display, i915_reg_t reg,
- u32 mask, unsigned int timeout_us)
-{
- return intel_de_wait_us(display, reg, mask, mask, timeout_us, NULL);
-}
-
-static inline int
-intel_de_wait_for_clear_us(struct intel_display *display, i915_reg_t reg,
- u32 mask, unsigned int timeout_us)
-{
- return intel_de_wait_us(display, reg, mask, 0, timeout_us, NULL);
-}
-
-static inline int
-intel_de_wait_for_set_ms(struct intel_display *display, i915_reg_t reg,
- u32 mask, unsigned int timeout_ms)
-{
- return intel_de_wait_ms(display, reg, mask, mask, timeout_ms, NULL);
-}
-
-static inline int
-intel_de_wait_for_clear_ms(struct intel_display *display, i915_reg_t reg,
- u32 mask, unsigned int timeout_ms)
-{
- return intel_de_wait_ms(display, reg, mask, 0, timeout_ms, NULL);
-}
+int intel_de_wait_us(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_us,
+ u32 *out_value);
+int intel_de_wait_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_ms,
+ u32 *out_value);
+int intel_de_wait_fw_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_ms,
+ u32 *out_value);
+int intel_de_wait_fw_us_atomic(struct intel_display *display, i915_reg_t reg,
+ u32 mask, u32 value, unsigned int timeout_us,
+ u32 *out_value);
+int intel_de_wait_for_set_us(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_us);
+int intel_de_wait_for_clear_us(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_us);
+int intel_de_wait_for_set_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_ms);
+int intel_de_wait_for_clear_ms(struct intel_display *display, i915_reg_t reg,
+ u32 mask, unsigned int timeout_ms);
/*
* Unlocked mmio-accessors, think carefully before using these.
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 720a2c6e247f..10b6c6fcb03f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5063,24 +5063,6 @@ static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_s
!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
}
-static void
-pipe_config_lt_phy_pll_mismatch(struct drm_printer *p, bool fastset,
- const struct intel_crtc *crtc,
- const char *name,
- const struct intel_lt_phy_pll_state *a,
- const struct intel_lt_phy_pll_state *b)
-{
- struct intel_display *display = to_intel_display(crtc);
- char *chipname = "LTPHY";
-
- pipe_config_mismatch(p, fastset, crtc, name, chipname);
-
- drm_printf(p, "expected:\n");
- intel_lt_phy_dump_hw_state(display, a);
- drm_printf(p, "found:\n");
- intel_lt_phy_dump_hw_state(display, b);
-}
-
bool
intel_pipe_config_compare(const struct intel_crtc_state *current_config,
const struct intel_crtc_state *pipe_config,
@@ -5195,16 +5177,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
} \
} while (0)
-#define PIPE_CONF_CHECK_PLL_LT(name) do { \
- if (!intel_lt_phy_pll_compare_hw_state(&current_config->name, \
- &pipe_config->name)) { \
- pipe_config_lt_phy_pll_mismatch(&p, fastset, crtc, __stringify(name), \
- &current_config->name, \
- &pipe_config->name); \
- ret = false; \
- } \
-} while (0)
-
#define PIPE_CONF_CHECK_TIMINGS(name) do { \
PIPE_CONF_CHECK_I(name.crtc_hdisplay); \
PIPE_CONF_CHECK_I(name.crtc_htotal); \
@@ -5431,10 +5403,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
if (display->dpll.mgr || HAS_GMCH(display))
PIPE_CONF_CHECK_PLL(dpll_hw_state);
- /* FIXME convert MTL+ platforms over to dpll_mgr */
- if (HAS_LT_PHY(display))
- PIPE_CONF_CHECK_PLL_LT(dpll_hw_state.ltpll);
-
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
PIPE_CONF_CHECK_X(dsi_pll.div);
@@ -7896,7 +7864,8 @@ static bool intel_ddi_crt_present(struct intel_display *display)
bool assert_port_valid(struct intel_display *display, enum port port)
{
- return !drm_WARN(display->drm, !(DISPLAY_RUNTIME_INFO(display)->port_mask & BIT(port)),
+ return !drm_WARN(display->drm,
+ !(port >= 0 && DISPLAY_RUNTIME_INFO(display)->port_mask & BIT(port)),
"Platform does not support port %c\n", port_name(port));
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index a8ef1e6193b8..be55ef8ea617 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -1654,6 +1654,28 @@ static void display_platforms_or(struct intel_display_platforms *dst,
bitmap_or(dst->bitmap, dst->bitmap, src->bitmap, display_platforms_num_bits());
}
+#define __STEP_NAME(name) [STEP_##name] = #name,
+
+static void initialize_step(struct intel_display *display, enum intel_step step)
+{
+ static const char step_names[][3] = {
+ STEP_NAME_LIST(__STEP_NAME)
+ };
+
+ DISPLAY_RUNTIME_INFO(display)->step = step;
+
+ /* Step name will remain an empty string if not applicable */
+ if (step >= 0 && step < ARRAY_SIZE(step_names))
+ strscpy(DISPLAY_RUNTIME_INFO(display)->step_name, step_names[step]);
+}
+
+#undef __STEP_NAME
+
+static const char *step_name(const struct intel_display_runtime_info *runtime)
+{
+ return strlen(runtime->step_name) ? runtime->step_name : "N/A";
+}
+
struct intel_display *intel_display_device_probe(struct pci_dev *pdev,
const struct intel_display_parent_interface *parent)
{
@@ -1731,14 +1753,14 @@ struct intel_display *intel_display_device_probe(struct pci_dev *pdev,
subdesc ? &subdesc->step_info : NULL);
}
- DISPLAY_RUNTIME_INFO(display)->step = step;
+ initialize_step(display, step);
drm_info(display->drm, "Found %s%s%s (device ID %04x) %s display version %u.%02u stepping %s\n",
desc->name, subdesc ? "/" : "", subdesc ? subdesc->name : "",
pdev->device, display->platform.dgfx ? "discrete" : "integrated",
DISPLAY_RUNTIME_INFO(display)->ip.ver,
DISPLAY_RUNTIME_INFO(display)->ip.rel,
- step != STEP_NONE ? intel_step_name(step) : "N/A");
+ step_name(DISPLAY_RUNTIME_INFO(display)));
return display;
@@ -1954,7 +1976,7 @@ void intel_display_device_info_print(const struct intel_display_device_info *inf
drm_printf(p, "display version: %u\n",
runtime->ip.ver);
- drm_printf(p, "display stepping: %s\n", intel_step_name(runtime->step));
+ drm_printf(p, "display stepping: %s\n", step_name(runtime));
#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, str_yes_no(info->name))
DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index e84c190dcc4f..1170ac346615 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -287,6 +287,7 @@ struct intel_display_runtime_info {
u16 step; /* hardware */
} ip;
int step; /* symbolic */
+ char step_name[3]; /* empty string if not applicable */
u32 rawclk_freq;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index d3a9ace4c9d1..e2496db1642a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -835,6 +835,7 @@ struct intel_pipe_wm {
struct skl_wm_level {
u16 min_ddb_alloc;
+ u16 min_ddb_alloc_uv; /* for pre-icl */
u16 blocks;
u8 lines;
bool enable;
@@ -845,13 +846,11 @@ struct skl_wm_level {
struct skl_plane_wm {
struct skl_wm_level wm[8];
- struct skl_wm_level uv_wm[8];
struct skl_wm_level trans_wm;
struct {
struct skl_wm_level wm0;
struct skl_wm_level trans_wm;
} sagv;
- bool is_planar;
};
struct skl_pipe_wm {
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 90ba932d940a..1667a829e708 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -39,7 +39,6 @@
#include "intel_dmc.h"
#include "intel_dmc_regs.h"
#include "intel_flipq.h"
-#include "intel_step.h"
/**
* DOC: DMC Firmware Support
@@ -418,15 +417,12 @@ bool intel_dmc_has_payload(struct intel_display *display)
return has_dmc_id_fw(display, DMC_FW_MAIN);
}
-static const struct stepping_info *
-intel_get_stepping_info(struct intel_display *display,
- struct stepping_info *si)
+static void initialize_stepping_info(struct intel_display *display, struct stepping_info *si)
{
- const char *step_name = intel_step_name(INTEL_DISPLAY_STEP(display));
+ const char *step_name = DISPLAY_RUNTIME_INFO(display)->step_name;
- si->stepping = step_name[0];
- si->substepping = step_name[1];
- return si;
+ si->stepping = step_name[0] ?: '*';
+ si->substepping = step_name[1] ?: '*';
}
static void gen9_set_dc_state_debugmask(struct intel_display *display)
@@ -1274,8 +1270,7 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
struct intel_css_header *css_header;
struct intel_package_header *package_header;
struct intel_dmc_header_base *dmc_header;
- struct stepping_info display_info = { '*', '*'};
- const struct stepping_info *si = intel_get_stepping_info(display, &display_info);
+ struct stepping_info si = {};
enum intel_dmc_id dmc_id;
u32 readcount = 0;
u32 r, offset;
@@ -1283,6 +1278,8 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
if (!fw)
return -EINVAL;
+ initialize_stepping_info(display, &si);
+
/* Extract CSS Header information */
css_header = (struct intel_css_header *)fw->data;
r = parse_dmc_fw_css(dmc, css_header, fw->size);
@@ -1293,7 +1290,7 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
/* Extract Package Header information */
package_header = (struct intel_package_header *)&fw->data[readcount];
- r = parse_dmc_fw_package(dmc, package_header, si, fw->size - readcount);
+ r = parse_dmc_fw_package(dmc, package_header, &si, fw->size - readcount);
if (!r)
return -EINVAL;
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 a7b186d0e3c4..d0c76632a946 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -610,6 +610,34 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
}
static bool
+check_if_vesa_backlight_possible(struct intel_dp *intel_dp)
+{
+ int ret;
+ u8 bit_min, bit_max;
+
+ if (!(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP))
+ return true;
+
+ ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &bit_min);
+ if (ret < 0)
+ return false;
+
+ bit_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
+ if (bit_min < 1)
+ return false;
+
+ ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &bit_max);
+ if (ret < 0)
+ return false;
+
+ bit_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
+ if (bit_max < bit_min)
+ return false;
+
+ return true;
+}
+
+static bool
intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(connector);
@@ -625,12 +653,14 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
return true;
}
- if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
+ if (drm_edp_backlight_supported(intel_dp->edp_dpcd) &&
+ check_if_vesa_backlight_possible(intel_dp)) {
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] AUX Backlight Control Supported!\n",
connector->base.base.id, connector->base.name);
return true;
}
+
return false;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index 8433e3ff0319..c7d37e74fbe9 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1212,29 +1212,6 @@ static int dg2_crtc_compute_clock(struct intel_atomic_state *state,
return 0;
}
-static int xe3plpd_crtc_compute_clock(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
-{
- struct intel_crtc_state *crtc_state =
- intel_atomic_get_new_crtc_state(state, crtc);
- struct intel_encoder *encoder =
- intel_get_crtc_new_encoder(state, crtc_state);
- struct intel_display *display = to_intel_display(encoder);
- int ret;
-
- ret = intel_lt_phy_pll_calc_state(crtc_state, encoder);
- if (ret)
- return ret;
-
- /* TODO: Do the readback via intel_compute_shared_dplls() */
- crtc_state->port_clock =
- intel_lt_phy_calc_port_clock(display, &crtc_state->dpll_hw_state.ltpll);
-
- crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
-
- return 0;
-}
-
static int ilk_fb_cb_factor(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
@@ -1695,7 +1672,8 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
}
static const struct intel_dpll_global_funcs xe3plpd_dpll_funcs = {
- .crtc_compute_clock = xe3plpd_crtc_compute_clock,
+ .crtc_compute_clock = hsw_crtc_compute_clock,
+ .crtc_get_dpll = hsw_crtc_get_dpll,
};
static const struct intel_dpll_global_funcs mtl_dpll_funcs = {
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index f35a9252f4e1..f5d4f7146fbc 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -4571,6 +4571,170 @@ static const struct intel_dpll_mgr mtl_pll_mgr = {
.compare_hw_state = mtl_compare_hw_state,
};
+static bool xe3plpd_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
+{
+ struct intel_encoder *encoder = get_intel_encoder(display, pll);
+
+ if (!encoder)
+ return false;
+
+ return intel_lt_phy_pll_readout_hw_state(encoder, &dpll_hw_state->ltpll);
+}
+
+static int xe3plpd_pll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
+{
+ struct intel_encoder *encoder = get_intel_encoder(display, pll);
+
+ if (drm_WARN_ON(display->drm, !encoder))
+ return -EINVAL;
+
+ return intel_lt_phy_calc_port_clock(display, &dpll_hw_state->ltpll);
+}
+
+static void xe3plpd_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
+{
+ struct intel_encoder *encoder = get_intel_encoder(display, pll);
+
+ if (drm_WARN_ON(display->drm, !encoder))
+ return;
+
+ intel_xe3plpd_pll_enable(encoder, pll, dpll_hw_state);
+}
+
+static void xe3plpd_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
+{
+ struct intel_encoder *encoder = get_intel_encoder(display, pll);
+
+ if (drm_WARN_ON(display->drm, !encoder))
+ return;
+
+ intel_xe3plpd_pll_disable(encoder);
+}
+
+static const struct intel_dpll_funcs xe3plpd_tbt_pll_funcs = {
+ .enable = mtl_tbt_pll_enable,
+ .disable = mtl_tbt_pll_disable,
+ .get_hw_state = intel_lt_phy_tbt_pll_readout_hw_state,
+ .get_freq = mtl_tbt_pll_get_freq,
+};
+
+static const struct intel_dpll_funcs xe3plpd_pll_funcs = {
+ .enable = xe3plpd_pll_enable,
+ .disable = xe3plpd_pll_disable,
+ .get_hw_state = xe3plpd_pll_get_hw_state,
+ .get_freq = xe3plpd_pll_get_freq,
+};
+
+static const struct dpll_info xe3plpd_plls[] = {
+ { .name = "DPLL 0", .funcs = &xe3plpd_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &xe3plpd_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "TBT PLL", .funcs = &xe3plpd_tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+ .is_alt_port_dpll = true, .always_on = true },
+ { .name = "TC PLL 1", .funcs = &xe3plpd_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
+ { .name = "TC PLL 2", .funcs = &xe3plpd_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
+ { .name = "TC PLL 3", .funcs = &xe3plpd_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
+ { .name = "TC PLL 4", .funcs = &xe3plpd_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
+ {}
+};
+
+static int xe3plpd_compute_non_tc_phy_dpll(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
+{
+ struct intel_display *display = to_intel_display(encoder);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+ struct icl_port_dpll *port_dpll =
+ &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
+ int ret;
+
+ ret = intel_lt_phy_pll_calc_state(crtc_state, encoder, &port_dpll->hw_state);
+ if (ret)
+ return ret;
+
+ /* this is mainly for the fastset check */
+ icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT);
+
+ crtc_state->port_clock = intel_lt_phy_calc_port_clock(display, &port_dpll->hw_state.ltpll);
+
+ return 0;
+}
+
+static int xe3plpd_compute_tc_phy_dplls(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
+{
+ struct intel_display *display = to_intel_display(encoder);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ struct icl_port_dpll *port_dpll;
+ int ret;
+
+ port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
+ intel_lt_phy_tbt_pll_calc_state(&port_dpll->hw_state);
+
+ port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
+ ret = intel_lt_phy_pll_calc_state(crtc_state, encoder, &port_dpll->hw_state);
+ if (ret)
+ return ret;
+
+ /* this is mainly for the fastset check */
+ if (old_crtc_state->intel_dpll &&
+ old_crtc_state->intel_dpll->info->id == DPLL_ID_ICL_TBTPLL)
+ icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT);
+ else
+ icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY);
+
+ crtc_state->port_clock = intel_lt_phy_calc_port_clock(display, &port_dpll->hw_state.ltpll);
+
+ return 0;
+}
+
+static int xe3plpd_compute_dplls(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
+{
+ if (intel_encoder_is_tc(encoder))
+ return xe3plpd_compute_tc_phy_dplls(state, crtc, encoder);
+ else
+ return xe3plpd_compute_non_tc_phy_dpll(state, crtc, encoder);
+}
+
+static void xe3plpd_dump_hw_state(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
+{
+ intel_lt_phy_dump_hw_state(p, &dpll_hw_state->ltpll);
+}
+
+static bool xe3plpd_compare_hw_state(const struct intel_dpll_hw_state *_a,
+ const struct intel_dpll_hw_state *_b)
+{
+ const struct intel_lt_phy_pll_state *a = &_a->ltpll;
+ const struct intel_lt_phy_pll_state *b = &_b->ltpll;
+
+ return intel_lt_phy_pll_compare_hw_state(a, b);
+}
+
+static const struct intel_dpll_mgr xe3plpd_pll_mgr = {
+ .dpll_info = xe3plpd_plls,
+ .compute_dplls = xe3plpd_compute_dplls,
+ .get_dplls = mtl_get_dplls,
+ .put_dplls = icl_put_dplls,
+ .update_active_dpll = icl_update_active_dpll,
+ .update_ref_clks = icl_update_dpll_ref_clks,
+ .dump_hw_state = xe3plpd_dump_hw_state,
+ .compare_hw_state = xe3plpd_compare_hw_state,
+};
+
/**
* intel_dpll_init - Initialize DPLLs
* @display: intel_display device
@@ -4585,9 +4749,11 @@ void intel_dpll_init(struct intel_display *display)
mutex_init(&display->dpll.lock);
- if (DISPLAY_VER(display) >= 35 || display->platform.dg2)
- /* No shared DPLLs on NVL or DG2; port PLLs are part of the PHY */
+ if (display->platform.dg2)
+ /* No shared DPLLs on DG2; port PLLs are part of the PHY */
dpll_mgr = NULL;
+ else if (DISPLAY_VER(display) >= 35)
+ dpll_mgr = &xe3plpd_pll_mgr;
else if (DISPLAY_VER(display) >= 14)
dpll_mgr = &mtl_pll_mgr;
else if (display->platform.alderlake_p)
@@ -4910,6 +5076,7 @@ verify_single_dpll_state(struct intel_display *display,
const struct intel_crtc_state *new_crtc_state)
{
struct intel_dpll_hw_state dpll_hw_state = {};
+ bool pll_mismatch = false;
u8 pipe_mask;
bool active;
@@ -4951,9 +5118,18 @@ verify_single_dpll_state(struct intel_display *display,
"%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
pll->info->name, pipe_mask, pll->state.pipe_mask);
- if (INTEL_DISPLAY_STATE_WARN(display,
- pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state,
- sizeof(dpll_hw_state)),
+ if (pll->on) {
+ const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
+
+ if (HAS_LT_PHY(display))
+ pll_mismatch = !dpll_mgr->compare_hw_state(&pll->state.hw_state,
+ &dpll_hw_state);
+ else
+ pll_mismatch = memcmp(&pll->state.hw_state, &dpll_hw_state,
+ sizeof(dpll_hw_state));
+ }
+
+ if (INTEL_DISPLAY_STATE_WARN(display, pll_mismatch,
"%s: pll hw state mismatch\n",
pll->info->name)) {
struct drm_printer p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL);
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index 4cc14ce5eebe..d408ccf6f902 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -278,6 +278,7 @@ struct intel_lt_phy_pll_state {
u8 config[3];
bool ssc_enabled;
bool tbt_mode;
+ int lane_count;
};
struct intel_dpll_hw_state {
diff --git a/drivers/gpu/drm/i915/display/intel_dsi.h b/drivers/gpu/drm/i915/display/intel_dsi.h
index 489d26ffd235..9fcdabbf3740 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.h
+++ b/drivers/gpu/drm/i915/display/intel_dsi.h
@@ -80,9 +80,10 @@ struct intel_dsi {
/* NON_BURST_SYNC_PULSE, NON_BURST_SYNC_EVENTS, or BURST_MODE */
int video_mode;
- /* eot for MIPI_EOT_DISABLE register */
- u8 eotp_pkt;
- u8 clock_stop;
+ bool lp_clock_during_lpm;
+ bool blanking_pkt;
+ bool eot_pkt;
+ bool clock_stop;
u8 escape_clk_div;
u8 dual_link;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 18755a8e613d..fe12041e913c 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -718,8 +718,10 @@ void intel_dsi_log_params(struct intel_dsi *intel_dsi)
"burst" : "<unknown>");
drm_printf(&p, "Burst mode ratio %d\n", intel_dsi->burst_mode_ratio);
drm_printf(&p, "Reset timer %d\n", intel_dsi->rst_timer_val);
- drm_printf(&p, "Eot %s\n", str_enabled_disabled(intel_dsi->eotp_pkt));
- drm_printf(&p, "Clockstop %s\n", str_enabled_disabled(!intel_dsi->clock_stop));
+ drm_printf(&p, "LP clock during LPM %s\n", str_enabled_disabled(intel_dsi->lp_clock_during_lpm));
+ drm_printf(&p, "Blanking packets during BLLP %s\n", str_enabled_disabled(intel_dsi->blanking_pkt));
+ drm_printf(&p, "EoT packet %s\n", str_enabled_disabled(intel_dsi->eot_pkt));
+ drm_printf(&p, "Clock stop during BLLP %s\n", str_enabled_disabled(intel_dsi->clock_stop));
drm_printf(&p, "Mode %s\n", intel_dsi->operation_mode ? "command" : "video");
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
drm_printf(&p, "Dual link: DSI_DUAL_LINK_FRONT_BACK\n");
@@ -770,8 +772,10 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
drm_dbg_kms(display->drm, "\n");
- intel_dsi->eotp_pkt = mipi_config->eot_pkt_disabled ? 0 : 1;
- intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0;
+ intel_dsi->lp_clock_during_lpm = mipi_config->lp_clock_during_lpm;
+ intel_dsi->blanking_pkt = mipi_config->blanking_packets_during_bllp;
+ intel_dsi->eot_pkt = !mipi_config->eot_pkt_disabled;
+ intel_dsi->clock_stop = mipi_config->enable_clk_stop;
intel_dsi->lane_count = mipi_config->lane_cnt + 1;
intel_dsi->pixel_format =
vbt_to_dsi_pixel_format(mipi_config->videomode_color_format);
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c
index dd79a866b87e..ea5cf8f51b31 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -694,7 +694,7 @@ retry:
goto clear_err;
}
- /* Generate a STOP condition on the bus. Note that gmbus can't generata
+ /* Generate a STOP condition on the bus. Note that gmbus can't generate
* a STOP on the very first cycle. To simplify the code we
* unconditionally generate the STOP condition with an additional gmbus
* cycle. */
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c
index eced8493e566..657ad5cb0eff 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c
@@ -11,6 +11,7 @@
#include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display.h"
+#include "intel_display_regs.h"
#include "intel_display_types.h"
#include "intel_display_utils.h"
#include "intel_dpll.h"
@@ -32,6 +33,7 @@
INTEL_LT_PHY_LANE0)
#define MODE_DP 3
#define MODE_HDMI_20 4
+#define MODE_HDMI_FRL 5
#define Q32_TO_INT(x) ((x) >> 32)
#define Q32_TO_FRAC(x) ((x) & 0xFFFFFFFF)
#define DCO_MIN_FREQ_MHZ 11850
@@ -1176,9 +1178,30 @@ intel_lt_phy_lane_reset(struct intel_encoder *encoder,
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_phy_pulse_status, 0);
}
+static bool intel_lt_phy_is_hdmi(const struct intel_lt_phy_pll_state *ltpll)
+{
+ u8 mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK, ltpll->config[0]);
+
+ if (mode == MODE_HDMI_20 || mode == MODE_HDMI_FRL)
+ return true;
+
+ return false;
+}
+
+static bool intel_lt_phy_is_dp(const struct intel_lt_phy_pll_state *ltpll)
+{
+ u8 mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK, ltpll->config[0]);
+
+ if (mode == MODE_DP)
+ return true;
+
+ return false;
+}
+
static void
intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
+ const struct intel_lt_phy_pll_state *ltpll,
+ int port_clock,
bool lane_reversal)
{
struct intel_display *display = to_intel_display(encoder);
@@ -1195,17 +1218,16 @@ intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder,
* but since the register bits still remain the same we use
* the same definition
*/
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
- intel_hdmi_is_frl(crtc_state->port_clock))
+ if (intel_lt_phy_is_hdmi(ltpll) && intel_hdmi_is_frl(port_clock))
val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
else
val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
/* DP2.0 10G and 20G rates enable MPLLA*/
- if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000)
+ if (port_clock == 1000000 || port_clock == 2000000)
val |= XELPDP_SSC_ENABLE_PLLA;
else
- val |= crtc_state->dpll_hw_state.ltpll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
+ val |= ltpll->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
@@ -1248,7 +1270,8 @@ static u32 intel_lt_phy_get_dp_clock(u8 rate)
static bool
intel_lt_phy_config_changed(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+ const struct intel_lt_phy_pll_state *ltpll,
+ u32 port_clock)
{
u8 val, rate;
u32 clock;
@@ -1262,9 +1285,9 @@ intel_lt_phy_config_changed(struct intel_encoder *encoder,
* using 1.62 Gbps clock since PHY PLL defaults to that
* otherwise we always need to reconfigure it.
*/
- if (intel_crtc_has_dp_encoder(crtc_state)) {
+ if (intel_lt_phy_is_dp(ltpll)) {
clock = intel_lt_phy_get_dp_clock(rate);
- if (crtc_state->port_clock == 1620000 && crtc_state->port_clock == clock)
+ if (port_clock == 1620000 && port_clock == clock)
return false;
}
@@ -1723,12 +1746,15 @@ intel_lt_phy_calc_port_clock(struct intel_display *display,
int
intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state,
- struct intel_encoder *encoder)
+ struct intel_encoder *encoder,
+ struct intel_dpll_hw_state *hw_state)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct intel_lt_phy_pll_params *tables;
int i;
+ memset(hw_state, 0, sizeof(*hw_state));
+
tables = intel_lt_phy_pll_tables_get(crtc_state, encoder);
if (!tables)
return -EINVAL;
@@ -1738,62 +1764,71 @@ intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state,
drm_WARN_ON(display->drm, !intel_dpll_clock_matches(clock, tables[i].clock_rate));
if (intel_dpll_clock_matches(crtc_state->port_clock, clock)) {
- crtc_state->dpll_hw_state.ltpll = *tables[i].state;
+ hw_state->ltpll = *tables[i].state;
if (intel_crtc_has_dp_encoder(crtc_state)) {
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
- crtc_state->dpll_hw_state.ltpll.config[2] = 1;
+ hw_state->ltpll.config[2] = 1;
}
- crtc_state->dpll_hw_state.ltpll.ssc_enabled =
+ hw_state->ltpll.ssc_enabled =
intel_lt_phy_pll_is_ssc_enabled(crtc_state, encoder);
+ hw_state->ltpll.lane_count = crtc_state->lane_count;
return 0;
}
}
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
- return intel_lt_phy_calculate_hdmi_state(&crtc_state->dpll_hw_state.ltpll,
+ hw_state->ltpll.lane_count = crtc_state->lane_count;
+ return intel_lt_phy_calculate_hdmi_state(&hw_state->ltpll,
crtc_state->port_clock);
}
return -EINVAL;
}
+void intel_lt_phy_tbt_pll_calc_state(struct intel_dpll_hw_state *hw_state)
+{
+ memset(hw_state, 0, sizeof(*hw_state));
+
+ hw_state->ltpll.tbt_mode = true;
+}
+
static void
intel_lt_phy_program_pll(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+ const struct intel_lt_phy_pll_state *ltpll)
{
u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
int i, j, k;
intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_0_CONFIG,
- crtc_state->dpll_hw_state.ltpll.config[0], MB_WRITE_COMMITTED);
+ ltpll->config[0], MB_WRITE_COMMITTED);
intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG,
- crtc_state->dpll_hw_state.ltpll.config[1], MB_WRITE_COMMITTED);
+ ltpll->config[1], MB_WRITE_COMMITTED);
intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_2_CONFIG,
- crtc_state->dpll_hw_state.ltpll.config[2], MB_WRITE_COMMITTED);
+ ltpll->config[2], MB_WRITE_COMMITTED);
for (i = 0; i <= 12; i++) {
intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_MSB(i),
- crtc_state->dpll_hw_state.ltpll.addr_msb[i],
+ ltpll->addr_msb[i],
MB_WRITE_COMMITTED);
intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_LSB(i),
- crtc_state->dpll_hw_state.ltpll.addr_lsb[i],
+ ltpll->addr_lsb[i],
MB_WRITE_COMMITTED);
for (j = 3, k = 0; j >= 0; j--, k++)
intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0,
LT_PHY_VDR_X_DATAY(i, j),
- crtc_state->dpll_hw_state.ltpll.data[i][k],
+ ltpll->data[i][k],
MB_WRITE_COMMITTED);
}
}
static void
intel_lt_phy_enable_disable_tx(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+ const struct intel_lt_phy_pll_state *ltpll)
{
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
bool lane_reversal = dig_port->lane_reversal;
- u8 lane_count = crtc_state->lane_count;
+ u8 lane_count = ltpll->lane_count;
bool is_dp_alt =
intel_tc_port_in_dp_alt_mode(dig_port);
enum intel_tc_pin_assignment tc_pin =
@@ -1874,9 +1909,11 @@ intel_lt_phy_enable_disable_tx(struct intel_encoder *encoder,
}
void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
struct intel_display *display = to_intel_display(encoder);
+ int port_clock = intel_lt_phy_calc_port_clock(display, &dpll_hw_state->ltpll);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
bool lane_reversal = dig_port->lane_reversal;
u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
@@ -1892,10 +1929,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
wakeref = intel_lt_phy_transaction_begin(encoder);
/* 1. Enable MacCLK at default 162 MHz frequency. */
- intel_lt_phy_lane_reset(encoder, crtc_state->lane_count);
+ intel_lt_phy_lane_reset(encoder, dpll_hw_state->ltpll.lane_count);
/* 2. Program PORT_CLOCK_CTL register to configure clock muxes, gating, and SSC. */
- intel_lt_phy_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
+ intel_lt_phy_program_port_clock_ctl(encoder, &dpll_hw_state->ltpll,
+ port_clock, lane_reversal);
/* 3. Change owned PHY lanes power to Ready state. */
intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
@@ -1905,12 +1943,12 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
* 4. Read the PHY message bus VDR register PHY_VDR_0_Config check enabled PLL type,
* encoded rate and encoded mode.
*/
- if (intel_lt_phy_config_changed(encoder, crtc_state)) {
+ if (intel_lt_phy_config_changed(encoder, &dpll_hw_state->ltpll, port_clock)) {
/*
* 5. Program the PHY internal PLL registers over PHY message bus for the desired
* frequency and protocol type
*/
- intel_lt_phy_program_pll(encoder, crtc_state);
+ intel_lt_phy_program_pll(encoder, &dpll_hw_state->ltpll);
/* 6. Use the P2P transaction flow */
/*
@@ -1942,8 +1980,7 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
* Change. We handle this step in bxt_set_cdclk().
*/
/* 10. Program DDI_CLK_VALFREQ to match intended DDI clock frequency. */
- intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
- crtc_state->port_clock);
+ intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
/* 11. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 1. */
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
@@ -1990,7 +2027,7 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
lane_phy_pulse_status,
lane_phy_pulse_status);
} else {
- intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), crtc_state->port_clock);
+ intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
}
/*
@@ -2001,7 +2038,7 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
XELPDP_P0_STATE_ACTIVE);
- intel_lt_phy_enable_disable_tx(encoder, crtc_state);
+ intel_lt_phy_enable_disable_tx(encoder, &dpll_hw_state->ltpll);
intel_lt_phy_transaction_end(encoder, wakeref);
}
@@ -2136,21 +2173,23 @@ void intel_lt_phy_set_signal_levels(struct intel_encoder *encoder,
intel_lt_phy_transaction_end(encoder, wakeref);
}
-void intel_lt_phy_dump_hw_state(struct intel_display *display,
+void intel_lt_phy_dump_hw_state(struct drm_printer *p,
const struct intel_lt_phy_pll_state *hw_state)
{
int i, j;
- drm_dbg_kms(display->drm, "lt_phy_pll_hw_state:\n");
+ drm_printf(p, "lt_phy_pll_hw_state: lane count: %d, ssc enabled: %d, tbt mode: %d\n",
+ hw_state->lane_count, hw_state->ssc_enabled, hw_state->tbt_mode);
+
for (i = 0; i < 3; i++) {
- drm_dbg_kms(display->drm, "config[%d] = 0x%.4x,\n",
- i, hw_state->config[i]);
+ drm_printf(p, "config[%d] = 0x%.4x,\n",
+ i, hw_state->config[i]);
}
for (i = 0; i <= 12; i++)
for (j = 3; j >= 0; j--)
- drm_dbg_kms(display->drm, "vdr_data[%d][%d] = 0x%.4x,\n",
- i, j, hw_state->data[i][j]);
+ drm_printf(p, "vdr_data[%d][%d] = 0x%.4x,\n",
+ i, j, hw_state->data[i][j]);
}
bool
@@ -2174,8 +2213,26 @@ intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a,
return false;
}
-void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
+static bool intel_lt_phy_pll_is_enabled(struct intel_encoder *encoder)
+{
+ struct intel_display *display = to_intel_display(encoder);
+
+ return intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)) &
+ XELPDP_LANE_PCLK_PLL_ACK(0);
+}
+
+bool intel_lt_phy_tbt_pll_readout_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *hw_state)
+{
+ memset(hw_state, 0, sizeof(*hw_state));
+
+ hw_state->ltpll.tbt_mode = true;
+
+ return true;
+}
+
+bool intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
struct intel_lt_phy_pll_state *pll_state)
{
u8 owned_lane_mask;
@@ -2183,14 +2240,19 @@ void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
struct ref_tracker *wakeref;
int i, j, k;
+ if (!intel_lt_phy_pll_is_enabled(encoder))
+ return false;
+
pll_state->tbt_mode = intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder));
if (pll_state->tbt_mode)
- return;
+ return false;
owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
lane = owned_lane_mask & INTEL_LT_PHY_LANE0 ? : INTEL_LT_PHY_LANE1;
wakeref = intel_lt_phy_transaction_begin(encoder);
+ pll_state->lane_count = intel_readout_lane_count(encoder, INTEL_LT_PHY_LANE0,
+ INTEL_LT_PHY_LANE1);
pll_state->config[0] = intel_lt_phy_read(encoder, lane, LT_PHY_VDR_0_CONFIG);
pll_state->config[1] = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG);
pll_state->config[2] = intel_lt_phy_read(encoder, lane, LT_PHY_VDR_2_CONFIG);
@@ -2203,56 +2265,15 @@ void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
}
intel_lt_phy_transaction_end(encoder, wakeref);
-}
-
-void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
-{
- struct intel_display *display = to_intel_display(state);
- struct intel_digital_port *dig_port;
- const struct intel_crtc_state *new_crtc_state =
- intel_atomic_get_new_crtc_state(state, crtc);
- struct intel_encoder *encoder;
- struct intel_lt_phy_pll_state pll_hw_state = {};
- const struct intel_lt_phy_pll_state *pll_sw_state = &new_crtc_state->dpll_hw_state.ltpll;
-
- if (DISPLAY_VER(display) < 35)
- return;
- if (!new_crtc_state->hw.active)
- return;
-
- /* intel_get_crtc_new_encoder() only works for modeset/fastset commits */
- if (!intel_crtc_needs_modeset(new_crtc_state) &&
- !intel_crtc_needs_fastset(new_crtc_state))
- return;
-
- encoder = intel_get_crtc_new_encoder(state, new_crtc_state);
- intel_lt_phy_pll_readout_hw_state(encoder, new_crtc_state, &pll_hw_state);
-
- dig_port = enc_to_dig_port(encoder);
- if (intel_tc_port_in_tbt_alt_mode(dig_port))
- return;
-
- INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[0] != pll_sw_state->config[0],
- "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG 0: (expected 0x%04x, found 0x%04x)",
- crtc->base.base.id, crtc->base.name,
- pll_sw_state->config[0], pll_hw_state.config[0]);
- INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[2] != pll_sw_state->config[2],
- "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG 2: (expected 0x%04x, found 0x%04x)",
- crtc->base.base.id, crtc->base.name,
- pll_sw_state->config[2], pll_hw_state.config[2]);
+ return true;
}
void intel_xe3plpd_pll_enable(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
-
- if (intel_tc_port_in_tbt_alt_mode(dig_port))
- intel_mtl_tbt_pll_enable_clock(encoder, crtc_state->port_clock);
- else
- intel_lt_phy_pll_enable(encoder, crtc_state);
+ intel_lt_phy_pll_enable(encoder, pll, dpll_hw_state);
}
void intel_xe3plpd_pll_disable(struct intel_encoder *encoder)
@@ -2294,7 +2315,7 @@ static void intel_lt_phy_pll_verify_clock(struct intel_display *display,
drm_printf(&p, "PLL state %s (%s):\n",
pll_state_name,
is_precomputed_state ? "precomputed" : "computed");
- intel_lt_phy_dump_hw_state(display, pll_state);
+ intel_lt_phy_dump_hw_state(&p, pll_state);
}
static void intel_lt_phy_pll_verify_params(struct intel_display *display,
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.h b/drivers/gpu/drm/i915/display/intel_lt_phy.h
index db905668f86d..16de39484779 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.h
@@ -8,38 +8,45 @@
#include <linux/types.h>
+struct drm_printer;
struct intel_atomic_state;
struct intel_display;
+struct intel_dpll;
+struct intel_dpll_hw_state;
struct intel_encoder;
struct intel_crtc_state;
struct intel_crtc;
struct intel_lt_phy_pll_state;
void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state);
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state);
void intel_lt_phy_pll_disable(struct intel_encoder *encoder);
int
intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state,
- struct intel_encoder *encoder);
+ struct intel_encoder *encoder,
+ struct intel_dpll_hw_state *hw_state);
+void intel_lt_phy_tbt_pll_calc_state(struct intel_dpll_hw_state *hw_state);
int intel_lt_phy_calc_port_clock(struct intel_display *display,
const struct intel_lt_phy_pll_state *lt_state);
void intel_lt_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
-void intel_lt_phy_dump_hw_state(struct intel_display *display,
+void intel_lt_phy_dump_hw_state(struct drm_printer *p,
const struct intel_lt_phy_pll_state *hw_state);
bool
intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a,
const struct intel_lt_phy_pll_state *b);
-void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
+bool intel_lt_phy_tbt_pll_readout_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *hw_state);
+bool intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
struct intel_lt_phy_pll_state *pll_state);
-void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
int
intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state,
u32 frequency_khz);
void intel_xe3plpd_pll_enable(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state);
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state);
void intel_xe3plpd_pll_disable(struct intel_encoder *encoder);
void intel_lt_phy_verify_plls(struct intel_display *display);
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_verify.c b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
index 12a00121c274..2ec17c2bfe0f 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_verify.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
@@ -246,7 +246,6 @@ void intel_modeset_verify_crtc(struct intel_atomic_state *state,
verify_crtc_state(state, crtc);
intel_dpll_state_verify(state, crtc);
intel_mpllb_state_verify(state, crtc);
- intel_lt_phy_pll_state_verify(state, crtc);
}
void intel_modeset_verify_disabled(struct intel_atomic_state *state)
diff --git a/drivers/gpu/drm/i915/display/intel_pch.c b/drivers/gpu/drm/i915/display/intel_pch.c
index 65359a36df48..d2c1b1751838 100644
--- a/drivers/gpu/drm/i915/display/intel_pch.c
+++ b/drivers/gpu/drm/i915/display/intel_pch.c
@@ -5,6 +5,9 @@
#include <drm/drm_print.h>
+#include "intel_de.h"
+#include "intel_display.h"
+#include "intel_display_regs.h"
#include "intel_display_core.h"
#include "intel_display_utils.h"
#include "intel_pch.h"
@@ -214,6 +217,96 @@ intel_pch_type(const struct intel_display *display, unsigned short id)
}
}
+static void intel_pch_ibx_init_clock_gating(struct intel_display *display)
+{
+ /*
+ * On Ibex Peak and Cougar Point, we need to disable clock
+ * gating for the panel power sequencer or it will fail to
+ * start up when no ports are active.
+ */
+ intel_de_write(display, SOUTH_DSPCLK_GATE_D,
+ PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+}
+
+static void intel_pch_cpt_init_clock_gating(struct intel_display *display)
+{
+ enum pipe pipe;
+ u32 val;
+
+ /*
+ * On Ibex Peak and Cougar Point, we need to disable clock
+ * gating for the panel power sequencer or it will fail to
+ * start up when no ports are active.
+ */
+ intel_de_write(display, SOUTH_DSPCLK_GATE_D,
+ PCH_DPLSUNIT_CLOCK_GATE_DISABLE |
+ PCH_DPLUNIT_CLOCK_GATE_DISABLE |
+ PCH_CPUNIT_CLOCK_GATE_DISABLE);
+ intel_de_rmw(display, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS);
+
+ /* The below fixes the weird display corruption, a few pixels shifted
+ * downward, on (only) LVDS of some HP laptops with IVY.
+ */
+ for_each_pipe(display, pipe) {
+ val = intel_de_read(display, TRANS_CHICKEN2(pipe));
+ val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
+ val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
+ if (display->vbt.fdi_rx_polarity_inverted)
+ val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
+ val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER;
+ val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH;
+ intel_de_write(display, TRANS_CHICKEN2(pipe), val);
+ }
+
+ /* WADP0ClockGatingDisable */
+ for_each_pipe(display, pipe)
+ intel_de_write(display, TRANS_CHICKEN1(pipe),
+ TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
+}
+
+static void intel_pch_lpt_init_clock_gating(struct intel_display *display)
+{
+ /*
+ * TODO: this bit should only be enabled when really needed, then
+ * disabled when not needed anymore in order to save power.
+ */
+ if (HAS_PCH_LPT_LP(display))
+ intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, 0,
+ PCH_LP_PARTITION_LEVEL_DISABLE);
+
+ /* WADPOClockGatingDisable:hsw */
+ intel_de_rmw(display, TRANS_CHICKEN1(PIPE_A), 0,
+ TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
+}
+
+static void intel_pch_cnp_init_clock_gating(struct intel_display *display)
+{
+ /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */
+ intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, 0,
+ CNP_PWM_CGE_GATING_DISABLE);
+}
+
+void intel_pch_init_clock_gating(struct intel_display *display)
+{
+ switch (INTEL_PCH_TYPE(display)) {
+ case PCH_IBX:
+ intel_pch_ibx_init_clock_gating(display);
+ break;
+ case PCH_CPT:
+ intel_pch_cpt_init_clock_gating(display);
+ break;
+ case PCH_LPT_H:
+ case PCH_LPT_LP:
+ intel_pch_lpt_init_clock_gating(display);
+ break;
+ case PCH_CNP:
+ intel_pch_cnp_init_clock_gating(display);
+ break;
+ default:
+ break;
+ }
+}
+
static bool intel_is_virt_pch(unsigned short id,
unsigned short svendor, unsigned short sdevice)
{
diff --git a/drivers/gpu/drm/i915/display/intel_pch.h b/drivers/gpu/drm/i915/display/intel_pch.h
index 19cac7412d0a..aa971fa141e7 100644
--- a/drivers/gpu/drm/i915/display/intel_pch.h
+++ b/drivers/gpu/drm/i915/display/intel_pch.h
@@ -52,5 +52,6 @@ enum intel_pch {
#define HAS_PCH_SPLIT(display) (INTEL_PCH_TYPE(display) != PCH_NONE)
void intel_pch_detect(struct intel_display *display);
+void intel_pch_init_clock_gating(struct intel_display *display);
#endif /* __INTEL_PCH__ */
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index 076b9b356481..5390ceb21ca4 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -437,7 +437,29 @@ void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
}
static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
- struct intel_plane_state *plane_state);
+ struct intel_plane_state *plane_state)
+{
+ struct intel_display *display = to_intel_display(plane_state);
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+
+ if (!plane_state->planar_linked_plane)
+ return;
+
+ plane_state->planar_linked_plane = NULL;
+
+ if (!plane_state->is_y_plane)
+ return;
+
+ drm_WARN_ON(display->drm, plane_state->uapi.visible);
+
+ plane_state->is_y_plane = false;
+
+ crtc_state->enabled_planes &= ~BIT(plane->id);
+ crtc_state->active_planes &= ~BIT(plane->id);
+ crtc_state->update_planes |= BIT(plane->id);
+ crtc_state->data_rate[plane->id] = 0;
+ crtc_state->rel_data_rate[plane->id] = 0;
+}
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
@@ -1512,31 +1534,6 @@ static void link_nv12_planes(struct intel_crtc_state *crtc_state,
icl_link_nv12_planes(uv_plane_state, y_plane_state);
}
-static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
- struct intel_plane_state *plane_state)
-{
- struct intel_display *display = to_intel_display(plane_state);
- struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
-
- if (!plane_state->planar_linked_plane)
- return;
-
- plane_state->planar_linked_plane = NULL;
-
- if (!plane_state->is_y_plane)
- return;
-
- drm_WARN_ON(display->drm, plane_state->uapi.visible);
-
- plane_state->is_y_plane = false;
-
- crtc_state->enabled_planes &= ~BIT(plane->id);
- crtc_state->active_planes &= ~BIT(plane->id);
- crtc_state->update_planes |= BIT(plane->id);
- crtc_state->data_rate[plane->id] = 0;
- crtc_state->rel_data_rate[plane->id] = 0;
-}
-
static int icl_check_nv12_planes(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -1550,17 +1547,6 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state,
if (DISPLAY_VER(display) < 11)
return 0;
- /*
- * Destroy all old plane links and make the Y plane invisible
- * in the crtc_state->active_planes mask.
- */
- for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
- if (plane->pipe != crtc->pipe)
- continue;
-
- unlink_nv12_plane(crtc_state, plane_state);
- }
-
if (!crtc_state->nv12_planes)
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index c13116e6f17f..2f1b48cd8efd 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -49,6 +49,7 @@
#include "intel_hdmi.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
+#include "intel_quirks.h"
#include "intel_snps_phy.h"
#include "intel_step.h"
#include "intel_vblank.h"
@@ -609,6 +610,13 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp, struct intel_conn
if (intel_dp->mst_detect == DRM_DP_MST)
return;
+ if (intel_dp_is_edp(intel_dp) &&
+ intel_has_dpcd_quirk(intel_dp, QUIRK_DISABLE_EDP_PANEL_REPLAY)) {
+ drm_dbg_kms(display->drm,
+ "Panel Replay support not currently available for this setup\n");
+ return;
+ }
+
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PANEL_REPLAY_CAP_SUPPORT,
&connector->dp.panel_replay_caps.dpcd,
sizeof(connector->dp.panel_replay_caps.dpcd));
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index 1abbdd426e58..883f297d4b83 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -86,6 +86,14 @@ static void quirk_edp_limit_rate_hbr2(struct intel_display *display)
drm_info(display->drm, "Applying eDP Limit rate to HBR2 quirk\n");
}
+static void quirk_disable_edp_panel_replay(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+
+ intel_set_dpcd_quirk(intel_dp, QUIRK_DISABLE_EDP_PANEL_REPLAY);
+ drm_info(display->drm, "Applying disable Panel Replay quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -108,6 +116,8 @@ struct intel_dpcd_quirk {
#define SINK_DEVICE_ID_ANY SINK_DEVICE_ID(0, 0, 0, 0, 0, 0)
+#define DEVICE_ID_ANY 0
+
/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
struct intel_dmi_quirk {
void (*hook)(struct intel_display *display);
@@ -251,7 +261,14 @@ static const struct intel_dpcd_quirk intel_dpcd_quirks[] = {
.sink_oui = SINK_OUI(0x38, 0xec, 0x11),
.hook = quirk_fw_sync_len,
},
-
+ /* Dell XPS 14 DA14260 */
+ {
+ .device = DEVICE_ID_ANY,
+ .subsystem_vendor = 0x1028,
+ .subsystem_device = 0x0db9,
+ .sink_oui = SINK_OUI(0x00, 0x22, 0xb9),
+ .hook = quirk_disable_edp_panel_replay,
+ },
};
void intel_init_quirks(struct intel_display *display)
@@ -262,7 +279,8 @@ void intel_init_quirks(struct intel_display *display)
for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) {
struct intel_quirk *q = &intel_quirks[i];
- if (d->device == q->device &&
+ if ((d->device == q->device ||
+ q->device == DEVICE_ID_ANY) &&
(d->subsystem_vendor == q->subsystem_vendor ||
q->subsystem_vendor == PCI_ANY_ID) &&
(d->subsystem_device == q->subsystem_device ||
@@ -285,7 +303,8 @@ void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
for (i = 0; i < ARRAY_SIZE(intel_dpcd_quirks); i++) {
const struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i];
- if (d->device == q->device &&
+ if ((d->device == q->device ||
+ q->device == DEVICE_ID_ANY) &&
(d->subsystem_vendor == q->subsystem_vendor ||
q->subsystem_vendor == PCI_ANY_ID) &&
(d->subsystem_device == q->subsystem_device ||
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h
index 06da0e286c67..83214eb94b0c 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.h
+++ b/drivers/gpu/drm/i915/display/intel_quirks.h
@@ -21,6 +21,7 @@ enum intel_quirk_id {
QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK,
QUIRK_FW_SYNC_LEN,
QUIRK_EDP_LIMIT_RATE_HBR2,
+ QUIRK_DISABLE_EDP_PANEL_REPLAY,
};
void intel_init_quirks(struct intel_display *display);
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index b1f9546b8cda..d45b3bcc6ef0 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -63,7 +63,6 @@ static void skl_sagv_disable(struct intel_display *display);
struct skl_wm_params {
bool x_tiled, y_tiled;
bool rc_surface;
- bool is_planar;
u32 width;
u8 cpp;
u32 plane_pixel_rate;
@@ -1357,14 +1356,13 @@ skl_check_wm_level(struct skl_wm_level *wm, const struct skl_ddb_entry *ddb)
}
static void
-skl_check_nv12_wm_level(struct skl_wm_level *wm, struct skl_wm_level *uv_wm,
- const struct skl_ddb_entry *ddb_y, const struct skl_ddb_entry *ddb)
+skl_check_wm_level_nv12(struct skl_wm_level *wm,
+ const struct skl_ddb_entry *ddb_y,
+ const struct skl_ddb_entry *ddb)
{
if (wm->min_ddb_alloc > skl_ddb_entry_size(ddb_y) ||
- uv_wm->min_ddb_alloc > skl_ddb_entry_size(ddb)) {
+ wm->min_ddb_alloc_uv > skl_ddb_entry_size(ddb))
memset(wm, 0, sizeof(*wm));
- memset(uv_wm, 0, sizeof(*uv_wm));
- }
}
static bool skl_need_wm_copy_wa(struct intel_display *display, int level,
@@ -1391,10 +1389,9 @@ struct skl_plane_ddb_iter {
};
static void
-skl_allocate_plane_ddb(struct skl_plane_ddb_iter *iter,
- struct skl_ddb_entry *ddb,
- const struct skl_wm_level *wm,
- u64 data_rate)
+_skl_allocate_plane_ddb(struct skl_plane_ddb_iter *iter,
+ u16 min_ddb_alloc,
+ struct skl_ddb_entry *ddb, u64 data_rate)
{
u16 size, extra = 0;
@@ -1411,12 +1408,30 @@ skl_allocate_plane_ddb(struct skl_plane_ddb_iter *iter,
* to avoid skl_ddb_add_affected_planes() adding them to
* the state when other planes change their allocations.
*/
- size = wm->min_ddb_alloc + extra;
+ size = min_ddb_alloc + extra;
if (size)
iter->start = skl_ddb_entry_init(ddb, iter->start,
iter->start + size);
}
+static void
+skl_allocate_plane_ddb(struct skl_plane_ddb_iter *iter,
+ const struct skl_wm_level *wm,
+ struct skl_ddb_entry *ddb, u64 data_rate)
+{
+ _skl_allocate_plane_ddb(iter, wm->min_ddb_alloc, ddb, data_rate);
+}
+
+static void
+skl_allocate_plane_ddb_nv12(struct skl_plane_ddb_iter *iter,
+ const struct skl_wm_level *wm,
+ struct skl_ddb_entry *ddb_y, u64 data_rate_y,
+ struct skl_ddb_entry *ddb, u64 data_rate)
+{
+ _skl_allocate_plane_ddb(iter, wm->min_ddb_alloc, ddb_y, data_rate_y);
+ _skl_allocate_plane_ddb(iter, wm->min_ddb_alloc_uv, ddb, data_rate);
+}
+
static int
skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
struct intel_crtc *crtc)
@@ -1482,7 +1497,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
}
blocks += wm->wm[level].min_ddb_alloc;
- blocks += wm->uv_wm[level].min_ddb_alloc;
+ blocks += wm->wm[level].min_ddb_alloc_uv;
}
if (blocks <= iter.size) {
@@ -1523,15 +1538,13 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
continue;
if (DISPLAY_VER(display) < 11 &&
- crtc_state->nv12_planes & BIT(plane_id)) {
- skl_allocate_plane_ddb(&iter, ddb_y, &wm->wm[level],
- crtc_state->rel_data_rate_y[plane_id]);
- skl_allocate_plane_ddb(&iter, ddb, &wm->uv_wm[level],
- crtc_state->rel_data_rate[plane_id]);
- } else {
- skl_allocate_plane_ddb(&iter, ddb, &wm->wm[level],
- crtc_state->rel_data_rate[plane_id]);
- }
+ crtc_state->nv12_planes & BIT(plane_id))
+ skl_allocate_plane_ddb_nv12(&iter, &wm->wm[level],
+ ddb_y, crtc_state->rel_data_rate_y[plane_id],
+ ddb, crtc_state->rel_data_rate[plane_id]);
+ else
+ skl_allocate_plane_ddb(&iter, &wm->wm[level],
+ ddb, crtc_state->rel_data_rate[plane_id]);
if (DISPLAY_VER(display) >= 30) {
*min_ddb = wm->wm[0].min_ddb_alloc;
@@ -1557,9 +1570,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
if (DISPLAY_VER(display) < 11 &&
crtc_state->nv12_planes & BIT(plane_id))
- skl_check_nv12_wm_level(&wm->wm[level],
- &wm->uv_wm[level],
- ddb_y, ddb);
+ skl_check_wm_level_nv12(&wm->wm[level], ddb_y, ddb);
else
skl_check_wm_level(&wm->wm[level], ddb);
@@ -1675,10 +1686,9 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
wp->y_tiled = modifier != I915_FORMAT_MOD_X_TILED &&
intel_fb_is_tiled_modifier(modifier);
wp->rc_surface = intel_fb_is_ccs_modifier(modifier);
- wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
wp->width = width;
- if (color_plane == 1 && wp->is_planar)
+ if (color_plane == 1 && intel_format_info_is_yuv_semiplanar(format, modifier))
wp->width /= 2;
wp->cpp = format->cpp[color_plane];
@@ -2069,11 +2079,11 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
struct intel_plane *plane)
{
+ struct intel_display *display = to_intel_display(crtc_state);
struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane->id];
+ struct skl_wm_level uv_wm[ARRAY_SIZE(wm->wm)] = {};
struct skl_wm_params wm_params;
- int ret;
-
- wm->is_planar = true;
+ int ret, level;
/* uv plane watermarks must also be validated for NV12/Planar */
ret = skl_compute_plane_wm_params(crtc_state, plane_state,
@@ -2081,7 +2091,14 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
- skl_compute_wm_levels(crtc_state, plane, &wm_params, wm->uv_wm);
+ skl_compute_wm_levels(crtc_state, plane, &wm_params, uv_wm);
+
+ /*
+ * Only keep the min_ddb_alloc for UV as
+ * the hardware needs nothing else.
+ */
+ for (level = 0; level < display->wm.num_levels; level++)
+ wm->wm[level].min_ddb_alloc_uv = uv_wm[level].min_ddb_alloc;
return 0;
}
@@ -2304,7 +2321,6 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state)
* thing as bad via min_ddb_alloc=U16_MAX?
*/
wm->wm[level].enable = false;
- wm->uv_wm[level].enable = false;
}
}
@@ -2375,11 +2391,6 @@ static bool skl_plane_wm_equals(struct intel_display *display,
int level;
for (level = 0; level < display->wm.num_levels; level++) {
- /*
- * We don't check uv_wm as the hardware doesn't actually
- * use it. It only gets used for calculating the required
- * ddb allocation.
- */
if (!skl_wm_level_equals(&wm1->wm[level], &wm2->wm[level]))
return false;
}
@@ -2590,14 +2601,30 @@ static char enast(bool enable)
return enable ? '*' : ' ';
}
+static void
+skl_print_plane_ddb_changes(struct intel_plane *plane,
+ const struct skl_ddb_entry *old,
+ const struct skl_ddb_entry *new,
+ const char *ddb_name)
+{
+ struct intel_display *display = to_intel_display(plane);
+
+ drm_dbg_kms(display->drm,
+ "[PLANE:%d:%s] %5s (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n",
+ plane->base.base.id, plane->base.name, ddb_name,
+ old->start, old->end, new->start, new->end,
+ skl_ddb_entry_size(old), skl_ddb_entry_size(new));
+}
+
static noinline_for_stack void
-skl_print_plane_changes(struct intel_display *display,
- struct intel_plane *plane,
- const struct skl_plane_wm *old_wm,
- const struct skl_plane_wm *new_wm)
+skl_print_plane_wm_changes(struct intel_plane *plane,
+ const struct skl_plane_wm *old_wm,
+ const struct skl_plane_wm *new_wm)
{
+ struct intel_display *display = to_intel_display(plane);
+
drm_dbg_kms(display->drm,
- "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm"
+ "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm"
" -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n",
plane->base.base.id, plane->base.name,
enast(old_wm->wm[0].enable), enast(old_wm->wm[1].enable),
@@ -2616,7 +2643,7 @@ skl_print_plane_changes(struct intel_display *display,
enast(new_wm->sagv.trans_wm.enable));
drm_dbg_kms(display->drm,
- "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d"
+ "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d"
" -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n",
plane->base.base.id, plane->base.name,
enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].lines,
@@ -2643,7 +2670,7 @@ skl_print_plane_changes(struct intel_display *display,
enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines);
drm_dbg_kms(display->drm,
- "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
+ "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
" -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
plane->base.base.id, plane->base.name,
old_wm->wm[0].blocks, old_wm->wm[1].blocks,
@@ -2662,7 +2689,7 @@ skl_print_plane_changes(struct intel_display *display,
new_wm->sagv.trans_wm.blocks);
drm_dbg_kms(display->drm,
- "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
+ "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
" -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
plane->base.base.id, plane->base.name,
old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc,
@@ -2679,6 +2706,28 @@ skl_print_plane_changes(struct intel_display *display,
new_wm->trans_wm.min_ddb_alloc,
new_wm->sagv.wm0.min_ddb_alloc,
new_wm->sagv.trans_wm.min_ddb_alloc);
+
+ if (DISPLAY_VER(display) >= 11)
+ return;
+
+ drm_dbg_kms(display->drm,
+ "[PLANE:%d:%s] min_ddb_uv %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d"
+ " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n",
+ plane->base.base.id, plane->base.name,
+ old_wm->wm[0].min_ddb_alloc_uv, old_wm->wm[1].min_ddb_alloc_uv,
+ old_wm->wm[2].min_ddb_alloc_uv, old_wm->wm[3].min_ddb_alloc_uv,
+ old_wm->wm[4].min_ddb_alloc_uv, old_wm->wm[5].min_ddb_alloc_uv,
+ old_wm->wm[6].min_ddb_alloc_uv, old_wm->wm[7].min_ddb_alloc_uv,
+ old_wm->trans_wm.min_ddb_alloc_uv,
+ old_wm->sagv.wm0.min_ddb_alloc_uv,
+ old_wm->sagv.trans_wm.min_ddb_alloc_uv,
+ new_wm->wm[0].min_ddb_alloc_uv, new_wm->wm[1].min_ddb_alloc_uv,
+ new_wm->wm[2].min_ddb_alloc_uv, new_wm->wm[3].min_ddb_alloc_uv,
+ new_wm->wm[4].min_ddb_alloc_uv, new_wm->wm[5].min_ddb_alloc_uv,
+ new_wm->wm[6].min_ddb_alloc_uv, new_wm->wm[7].min_ddb_alloc_uv,
+ new_wm->trans_wm.min_ddb_alloc_uv,
+ new_wm->sagv.wm0.min_ddb_alloc_uv,
+ new_wm->sagv.trans_wm.min_ddb_alloc_uv);
}
static void
@@ -2708,13 +2757,17 @@ skl_print_wm_changes(struct intel_atomic_state *state)
old = &old_crtc_state->wm.skl.plane_ddb[plane_id];
new = &new_crtc_state->wm.skl.plane_ddb[plane_id];
- if (skl_ddb_entry_equal(old, new))
+ if (!skl_ddb_entry_equal(old, new))
+ skl_print_plane_ddb_changes(plane, old, new, "ddb");
+
+ if (DISPLAY_VER(display) >= 11)
continue;
- drm_dbg_kms(display->drm,
- "[PLANE:%d:%s] ddb (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n",
- plane->base.base.id, plane->base.name,
- old->start, old->end, new->start, new->end,
- skl_ddb_entry_size(old), skl_ddb_entry_size(new));
+
+ old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id];
+ new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id];
+
+ if (!skl_ddb_entry_equal(old, new))
+ skl_print_plane_ddb_changes(plane, old, new, "ddb_y");
}
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
@@ -2727,7 +2780,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
if (skl_plane_wm_equals(display, old_wm, new_wm))
continue;
- skl_print_plane_changes(display, plane, old_wm, new_wm);
+ skl_print_plane_wm_changes(plane, old_wm, new_wm);
}
}
}
@@ -2740,11 +2793,6 @@ static bool skl_plane_selected_wm_equals(struct intel_plane *plane,
int level;
for (level = 0; level < display->wm.num_levels; level++) {
- /*
- * We don't check uv_wm as the hardware doesn't actually
- * use it. It only gets used for calculating the required
- * ddb allocation.
- */
if (!skl_wm_level_equals(skl_plane_wm_level(old_pipe_wm, plane->id, level),
skl_plane_wm_level(new_pipe_wm, plane->id, level)))
return false;
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 36591d724638..d4db73c184e5 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -1367,7 +1367,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder,
}
tmp = 0;
- if (intel_dsi->eotp_pkt == 0)
+ if (!intel_dsi->eot_pkt)
tmp |= EOT_DISABLE;
if (intel_dsi->clock_stop)
tmp |= CLOCKSTOP;
diff --git a/drivers/gpu/drm/i915/gvt/edid.c b/drivers/gpu/drm/i915/gvt/edid.c
index 021afff1cd5d..ca5b54466a65 100644
--- a/drivers/gpu/drm/i915/gvt/edid.c
+++ b/drivers/gpu/drm/i915/gvt/edid.c
@@ -535,16 +535,7 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
i2c_edid->edid_available = true;
}
}
- } else if ((op & 0x1) == DP_AUX_I2C_WRITE) {
- /* TODO
- * We only support EDID reading from I2C_over_AUX. And
- * we do not expect the index mode to be used. Right now
- * the WRITE operation is ignored. It is good enough to
- * support the gfx driver to do EDID access.
- */
- } else {
- if (drm_WARN_ON(&i915->drm, (op & 0x1) != DP_AUX_I2C_READ))
- return;
+ } else if ((op & 0x1) == DP_AUX_I2C_READ) {
if (drm_WARN_ON(&i915->drm, msg_length != 4))
return;
if (i2c_edid->edid_available && i2c_edid->target_selected) {
@@ -553,6 +544,13 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
aux_data_for_write = (val << 16);
} else
aux_data_for_write = (0xff << 16);
+ } else {
+ /* TODO
+ * We only support EDID reading from I2C_over_AUX. And
+ * we do not expect the index mode to be used. Right now
+ * the WRITE operation is ignored. It is good enough to
+ * support the gfx driver to do EDID access.
+ */
}
/* write the return value in AUX_CH_DATA reg which includes:
* ACK of I2C_WRITE
diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c
index 5594548f51d8..390a9248d631 100644
--- a/drivers/gpu/drm/i915/i915_initial_plane.c
+++ b/drivers/gpu/drm/i915/i915_initial_plane.c
@@ -115,7 +115,8 @@ initial_plane_vma(struct drm_i915_private *i915,
* important and we should probably use that space with FBC or other
* features.
*/
- if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) &&
+ if (IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) &&
+ IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) &&
mem == i915->mm.stolen_region &&
!intel_fbdev_fb_prefer_stolen(&i915->drm, size)) {
drm_dbg_kms(&i915->drm, "Initial FB size exceeds half of stolen, discarding\n");
diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c
index 68a6f94f2a37..ee2489a2fbe7 100644
--- a/drivers/gpu/drm/i915/intel_clock_gating.c
+++ b/drivers/gpu/drm/i915/intel_clock_gating.c
@@ -33,6 +33,7 @@
#include "display/intel_display.h"
#include "display/intel_display_core.h"
#include "display/intel_display_regs.h"
+#include "display/intel_pch.h"
#include "gt/intel_engine_regs.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_mcr.h"
@@ -124,16 +125,6 @@ static void glk_init_clock_gating(struct drm_i915_private *i915)
PWM1_GATING_DIS | PWM2_GATING_DIS);
}
-static void ibx_init_clock_gating(struct drm_i915_private *i915)
-{
- /*
- * On Ibex Peak and Cougar Point, we need to disable clock
- * gating for the panel power sequencer or it will fail to
- * start up when no ports are active.
- */
- intel_uncore_write(&i915->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
-}
-
static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
{
struct intel_display *display = dev_priv->display;
@@ -202,42 +193,7 @@ static void ilk_init_clock_gating(struct drm_i915_private *i915)
g4x_disable_trickle_feed(i915);
- ibx_init_clock_gating(i915);
-}
-
-static void cpt_init_clock_gating(struct drm_i915_private *i915)
-{
- struct intel_display *display = i915->display;
- enum pipe pipe;
- u32 val;
-
- /*
- * On Ibex Peak and Cougar Point, we need to disable clock
- * gating for the panel power sequencer or it will fail to
- * start up when no ports are active.
- */
- intel_uncore_write(&i915->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE |
- PCH_DPLUNIT_CLOCK_GATE_DISABLE |
- PCH_CPUNIT_CLOCK_GATE_DISABLE);
- intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS);
- /* The below fixes the weird display corruption, a few pixels shifted
- * downward, on (only) LVDS of some HP laptops with IVY.
- */
- for_each_pipe(display, pipe) {
- val = intel_uncore_read(&i915->uncore, TRANS_CHICKEN2(pipe));
- val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
- val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
- if (display->vbt.fdi_rx_polarity_inverted)
- val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
- val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER;
- val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH;
- intel_uncore_write(&i915->uncore, TRANS_CHICKEN2(pipe), val);
- }
- /* WADP0ClockGatingDisable */
- for_each_pipe(display, pipe) {
- intel_uncore_write(&i915->uncore, TRANS_CHICKEN1(pipe),
- TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
- }
+ intel_pch_init_clock_gating(i915->display);
}
static void gen6_check_mch_setup(struct drm_i915_private *i915)
@@ -305,28 +261,11 @@ static void gen6_init_clock_gating(struct drm_i915_private *i915)
g4x_disable_trickle_feed(i915);
- cpt_init_clock_gating(i915);
+ intel_pch_init_clock_gating(i915->display);
gen6_check_mch_setup(i915);
}
-static void lpt_init_clock_gating(struct drm_i915_private *i915)
-{
- struct intel_display *display = i915->display;
-
- /*
- * TODO: this bit should only be enabled when really needed, then
- * disabled when not needed anymore in order to save power.
- */
- if (HAS_PCH_LPT_LP(display))
- intel_uncore_rmw(&i915->uncore, SOUTH_DSPCLK_GATE_D,
- 0, PCH_LP_PARTITION_LEVEL_DISABLE);
-
- /* WADPOClockGatingDisable:hsw */
- intel_uncore_rmw(&i915->uncore, TRANS_CHICKEN1(PIPE_A),
- 0, TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
-}
-
static void gen8_set_l3sqc_credits(struct drm_i915_private *i915,
int general_prio_credits,
int high_prio_credits)
@@ -360,20 +299,9 @@ static void dg2_init_clock_gating(struct drm_i915_private *i915)
SGSI_SIDECLK_DIS);
}
-static void cnp_init_clock_gating(struct drm_i915_private *i915)
-{
- struct intel_display *display = i915->display;
-
- if (!HAS_PCH_CNP(display))
- return;
-
- /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */
- intel_uncore_rmw(&i915->uncore, SOUTH_DSPCLK_GATE_D, 0, CNP_PWM_CGE_GATING_DISABLE);
-}
-
static void cfl_init_clock_gating(struct drm_i915_private *i915)
{
- cnp_init_clock_gating(i915);
+ intel_pch_init_clock_gating(i915->display);
gen9_init_clock_gating(i915);
/* WAC6entrylatency:cfl */
@@ -466,7 +394,7 @@ static void bdw_init_clock_gating(struct drm_i915_private *i915)
intel_uncore_rmw(&i915->uncore, CHICKEN_PAR2_1,
0, KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
- lpt_init_clock_gating(i915);
+ intel_pch_init_clock_gating(i915->display);
/* WaDisableDopClockGating:bdw
*
@@ -500,7 +428,7 @@ static void hsw_init_clock_gating(struct drm_i915_private *i915)
/* WaSwitchSolVfFArbitrationPriority:hsw */
intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL);
- lpt_init_clock_gating(i915);
+ intel_pch_init_clock_gating(i915->display);
}
static void ivb_init_clock_gating(struct drm_i915_private *i915)
@@ -545,7 +473,7 @@ static void ivb_init_clock_gating(struct drm_i915_private *i915)
GEN6_MBC_SNPCR_MED);
if (!HAS_PCH_NOP(display))
- cpt_init_clock_gating(i915);
+ intel_pch_init_clock_gating(display);
gen6_check_mch_setup(i915);
}
diff --git a/drivers/gpu/drm/i915/intel_step.h b/drivers/gpu/drm/i915/intel_step.h
index 22f1d6905160..2ca36eae4b5a 100644
--- a/drivers/gpu/drm/i915/intel_step.h
+++ b/drivers/gpu/drm/i915/intel_step.h
@@ -8,6 +8,8 @@
#include <linux/types.h>
+#include <drm/intel/step.h>
+
struct drm_i915_private;
struct intel_step_info {
@@ -19,61 +21,6 @@ struct intel_step_info {
u8 media_step;
};
-#define STEP_ENUM_VAL(name) STEP_##name,
-
-#define STEP_NAME_LIST(func) \
- func(A0) \
- func(A1) \
- func(A2) \
- func(A3) \
- func(B0) \
- func(B1) \
- func(B2) \
- func(B3) \
- func(C0) \
- func(C1) \
- func(C2) \
- func(C3) \
- func(D0) \
- func(D1) \
- func(D2) \
- func(D3) \
- func(E0) \
- func(E1) \
- func(E2) \
- func(E3) \
- func(F0) \
- func(F1) \
- func(F2) \
- func(F3) \
- func(G0) \
- func(G1) \
- func(G2) \
- func(G3) \
- func(H0) \
- func(H1) \
- func(H2) \
- func(H3) \
- func(I0) \
- func(I1) \
- func(I2) \
- func(I3) \
- func(J0) \
- func(J1) \
- func(J2) \
- func(J3)
-
-/*
- * Symbolic steppings that do not match the hardware. These are valid both as gt
- * and display steppings as symbolic names.
- */
-enum intel_step {
- STEP_NONE = 0,
- STEP_NAME_LIST(STEP_ENUM_VAL)
- STEP_FUTURE,
- STEP_FOREVER,
-};
-
void intel_step_init(struct drm_i915_private *i915);
const char *intel_step_name(enum intel_step step);
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 5b698d4d7a7f..170e83a8c9fc 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -399,6 +399,35 @@ static void fw_domains_get_with_thread_status(struct intel_uncore *uncore,
__gen6_gt_wait_for_thread_c0(uncore);
}
+static void
+gen6_check_for_fifo_debug(struct intel_uncore *uncore)
+{
+ u32 fifodbg;
+
+ fifodbg = __raw_uncore_read32(uncore, GTFIFODBG);
+
+ if (unlikely(fifodbg)) {
+ drm_dbg(&uncore->i915->drm, "GTFIFODBG = 0x08%x\n", fifodbg);
+ __raw_uncore_write32(uncore, GTFIFODBG, fifodbg);
+ }
+}
+
+static void
+fw_domains_get_normal_fifo(struct intel_uncore *uncore,
+ enum forcewake_domains fw_domains)
+{
+ gen6_check_for_fifo_debug(uncore);
+ fw_domains_get_normal(uncore, fw_domains);
+}
+
+static void
+fw_domains_get_with_thread_status_fifo(struct intel_uncore *uncore,
+ enum forcewake_domains fw_domains)
+{
+ gen6_check_for_fifo_debug(uncore);
+ fw_domains_get_with_thread_status(uncore, fw_domains);
+}
+
static inline u32 fifo_free_entries(struct intel_uncore *uncore)
{
u32 count = __raw_uncore_read32(uncore, GTFIFOCTL);
@@ -562,21 +591,6 @@ vlv_check_for_unclaimed_mmio(struct intel_uncore *uncore)
}
static bool
-gen6_check_for_fifo_debug(struct intel_uncore *uncore)
-{
- u32 fifodbg;
-
- fifodbg = __raw_uncore_read32(uncore, GTFIFODBG);
-
- if (unlikely(fifodbg)) {
- drm_dbg(&uncore->i915->drm, "GTFIFODBG = 0x08%x\n", fifodbg);
- __raw_uncore_write32(uncore, GTFIFODBG, fifodbg);
- }
-
- return fifodbg;
-}
-
-static bool
check_for_unclaimed_mmio(struct intel_uncore *uncore)
{
bool ret = false;
@@ -592,9 +606,6 @@ check_for_unclaimed_mmio(struct intel_uncore *uncore)
if (intel_uncore_has_dbg_unclaimed(uncore))
ret |= vlv_check_for_unclaimed_mmio(uncore);
- if (intel_uncore_has_fifo(uncore))
- ret |= gen6_check_for_fifo_debug(uncore);
-
return ret;
}
@@ -611,6 +622,9 @@ static void forcewake_early_sanitize(struct intel_uncore *uncore,
GT_FIFO_CTL_RC6_POLICY_STALL);
}
+ if (intel_uncore_has_fifo(uncore))
+ gen6_check_for_fifo_debug(uncore);
+
iosf_mbi_punit_acquire();
intel_uncore_forcewake_reset(uncore);
if (restore_forcewake) {
@@ -2155,6 +2169,14 @@ static const struct intel_uncore_fw_get uncore_get_thread_status = {
.force_wake_get = fw_domains_get_with_thread_status
};
+static const struct intel_uncore_fw_get uncore_get_normal_fifo = {
+ .force_wake_get = fw_domains_get_normal_fifo,
+};
+
+static const struct intel_uncore_fw_get uncore_get_thread_status_fifo = {
+ .force_wake_get = fw_domains_get_with_thread_status_fifo
+};
+
static int intel_uncore_fw_domains_init(struct intel_uncore *uncore)
{
struct drm_i915_private *i915 = uncore->i915;
@@ -2218,13 +2240,19 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore)
fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
- uncore->fw_get_funcs = &uncore_get_normal;
+ if (intel_uncore_has_fifo(uncore))
+ uncore->fw_get_funcs = &uncore_get_normal_fifo;
+ else
+ uncore->fw_get_funcs = &uncore_get_normal;
fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
- uncore->fw_get_funcs = &uncore_get_thread_status;
+ if (intel_uncore_has_fifo(uncore))
+ uncore->fw_get_funcs = &uncore_get_thread_status_fifo;
+ else
+ uncore->fw_get_funcs = &uncore_get_thread_status;
fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
} else if (IS_IVYBRIDGE(i915)) {
@@ -2239,7 +2267,7 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore)
* (correctly) interpreted by the test below as MT
* forcewake being disabled.
*/
- uncore->fw_get_funcs = &uncore_get_thread_status;
+ uncore->fw_get_funcs = &uncore_get_thread_status_fifo;
/* We need to init first for ECOBUS access and then
* determine later if we want to reinit, in case of MT access is
@@ -2270,7 +2298,7 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore)
FORCEWAKE, FORCEWAKE_ACK);
}
} else if (GRAPHICS_VER(i915) == 6) {
- uncore->fw_get_funcs = &uncore_get_thread_status;
+ uncore->fw_get_funcs = &uncore_get_thread_status_fifo;
fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
FORCEWAKE, FORCEWAKE_ACK);
}
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 507bf42a1aaf..514d2200751b 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -272,67 +272,6 @@ out_rpm:
return err;
}
-static int live_forcewake_domains(void *arg)
-{
-#define FW_RANGE 0x40000
- struct intel_gt *gt = arg;
- struct intel_uncore *uncore = gt->uncore;
- struct drm_i915_private *i915 = gt->i915;
- struct intel_display *display = i915->display;
- unsigned long *valid;
- u32 offset;
- int err;
-
- if (!HAS_FPGA_DBG_UNCLAIMED(display) &&
- !IS_VALLEYVIEW(i915) &&
- !IS_CHERRYVIEW(i915))
- return 0;
-
- /*
- * This test may lockup the machine or cause GPU hangs afterwards.
- */
- if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
- return 0;
-
- valid = bitmap_zalloc(FW_RANGE, GFP_KERNEL);
- if (!valid)
- return -ENOMEM;
-
- intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
-
- check_for_unclaimed_mmio(uncore);
- for (offset = 0; offset < FW_RANGE; offset += 4) {
- i915_reg_t reg = { offset };
-
- intel_uncore_posting_read_fw(uncore, reg);
- if (!check_for_unclaimed_mmio(uncore))
- set_bit(offset, valid);
- }
-
- intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
-
- err = 0;
- for_each_set_bit(offset, valid, FW_RANGE) {
- i915_reg_t reg = { offset };
-
- iosf_mbi_punit_acquire();
- intel_uncore_forcewake_reset(uncore);
- iosf_mbi_punit_release();
-
- check_for_unclaimed_mmio(uncore);
-
- intel_uncore_posting_read_fw(uncore, reg);
- if (check_for_unclaimed_mmio(uncore)) {
- pr_err("Unclaimed mmio read to register 0x%04x\n",
- offset);
- err = -EINVAL;
- }
- }
-
- bitmap_free(valid);
- return err;
-}
-
static int live_fw_table(void *arg)
{
struct intel_gt *gt = arg;
@@ -348,7 +287,6 @@ int intel_uncore_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(live_fw_table),
SUBTEST(live_forcewake_ops),
- SUBTEST(live_forcewake_domains),
};
return intel_gt_live_subtests(tests, to_gt(i915));
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index dab979287a96..49de1c22a469 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -251,6 +251,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_dbuf_bw.o \
i915-display/intel_ddi.o \
i915-display/intel_ddi_buf_trans.o \
+ i915-display/intel_de.o \
i915-display/intel_display.o \
i915-display/intel_display_conversion.o \
i915-display/intel_display_device.o \
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
index 2cf13a572ab0..0eabe2866f5f 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_step.h
@@ -6,9 +6,8 @@
#ifndef __INTEL_STEP_H__
#define __INTEL_STEP_H__
-#include "xe_step.h"
+#include "xe_step_types.h"
#define intel_step xe_step
-#define intel_step_name xe_step_name
#endif /* __INTEL_STEP_H__ */
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
index a8cfd65119e0..08d7ab933672 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
@@ -98,37 +98,6 @@ static inline u32 intel_uncore_rmw(struct intel_uncore *uncore,
return xe_mmio_rmw32(__compat_uncore_to_mmio(uncore), reg, clear, set);
}
-static inline int
-__intel_wait_for_register(struct intel_uncore *uncore, i915_reg_t i915_reg,
- u32 mask, u32 value, unsigned int fast_timeout_us,
- unsigned int slow_timeout_ms, u32 *out_value)
-{
- struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg));
- bool atomic;
-
- /*
- * Replicate the behavior from i915 here, in which sleep is not
- * performed if slow_timeout_ms == 0. This is necessary because
- * of some paths in display code where waits are done in atomic
- * context.
- */
- atomic = !slow_timeout_ms && fast_timeout_us > 0;
-
- return xe_mmio_wait32(__compat_uncore_to_mmio(uncore), reg, mask, value,
- fast_timeout_us + 1000 * slow_timeout_ms,
- out_value, atomic);
-}
-
-static inline int
-__intel_wait_for_register_fw(struct intel_uncore *uncore, i915_reg_t i915_reg,
- u32 mask, u32 value, unsigned int fast_timeout_us,
- unsigned int slow_timeout_ms, u32 *out_value)
-{
- return __intel_wait_for_register(uncore, i915_reg, mask, value,
- fast_timeout_us, slow_timeout_ms,
- out_value);
-}
-
static inline u32 intel_uncore_read_fw(struct intel_uncore *uncore,
i915_reg_t i915_reg)
{