summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/Makefile3
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_csr.h21
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c50
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c53
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c85
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c30
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c94
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c (renamed from drivers/gpu/drm/i915/display/intel_csr.c)333
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h21
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c71
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c69
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c86
-rw-r--r--drivers/gpu/drm/i915/display/intel_qp_tables.c309
-rw-r--r--drivers/gpu/drm/i915/display/intel_qp_tables.h14
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c152
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c105
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gtt.h3
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c8
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c17
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c8
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c12
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c4
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h152
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c2
-rw-r--r--drivers/gpu/drm/i915/i915_vma.h7
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c2
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.h2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c303
-rw-r--r--drivers/gpu/drm/i915/intel_pm.h4
38 files changed, 1633 insertions, 462 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index d0d936d9137b..6947495bf34b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -201,10 +201,10 @@ i915-y += \
display/intel_combo_phy.o \
display/intel_connector.o \
display/intel_crtc.o \
- display/intel_csr.o \
display/intel_cursor.o \
display/intel_display.o \
display/intel_display_power.o \
+ display/intel_dmc.o \
display/intel_dpio_phy.o \
display/intel_dpll.o \
display/intel_dpll_mgr.o \
@@ -263,6 +263,7 @@ i915-y += \
display/intel_lvds.o \
display/intel_panel.o \
display/intel_pps.o \
+ display/intel_qp_tables.o \
display/intel_sdvo.o \
display/intel_tv.o \
display/intel_vdsc.o \
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index ce544e20f35c..16812488c5dd 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -363,10 +363,19 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
enum port port;
int afe_clk_khz;
- u32 esc_clk_div_m;
+ int theo_word_clk, act_word_clk;
+ u32 esc_clk_div_m, esc_clk_div_m_phy;
afe_clk_khz = afe_clk(encoder, crtc_state);
- esc_clk_div_m = DIV_ROUND_UP(afe_clk_khz, DSI_MAX_ESC_CLK);
+
+ if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) {
+ theo_word_clk = DIV_ROUND_UP(afe_clk_khz, 8 * DSI_MAX_ESC_CLK);
+ act_word_clk = max(3, theo_word_clk + (theo_word_clk + 1) % 2);
+ esc_clk_div_m = act_word_clk * 8;
+ esc_clk_div_m_phy = (act_word_clk - 1) / 2;
+ } else {
+ esc_clk_div_m = DIV_ROUND_UP(afe_clk_khz, DSI_MAX_ESC_CLK);
+ }
for_each_dsi_port(port, intel_dsi->ports) {
intel_de_write(dev_priv, ICL_DSI_ESC_CLK_DIV(port),
@@ -379,6 +388,14 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
intel_de_posting_read(dev_priv, ICL_DPHY_ESC_CLK_DIV(port));
}
+
+ if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) {
+ for_each_dsi_port(port, intel_dsi->ports) {
+ intel_de_write(dev_priv, ADL_MIPIO_DW(port, 8),
+ esc_clk_div_m_phy & TX_ESC_CLK_DIV_PHY);
+ intel_de_posting_read(dev_priv, ADL_MIPIO_DW(port, 8));
+ }
+ }
}
static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 88f424020a5f..b4e7ac51aa31 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -187,6 +187,26 @@ intel_connector_needs_modeset(struct intel_atomic_state *state,
new_conn_state->crtc)));
}
+/**
+ * intel_any_crtc_needs_modeset - check if any CRTC needs a modeset
+ * @state: the atomic state corresponding to this modeset
+ *
+ * Returns true if any CRTC in @state needs a modeset.
+ */
+bool intel_any_crtc_needs_modeset(struct intel_atomic_state *state)
+{
+ struct intel_crtc *crtc;
+ struct intel_crtc_state *crtc_state;
+ int i;
+
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
+ if (intel_crtc_needs_modeset(crtc_state))
+ return true;
+ }
+
+ return false;
+}
+
struct intel_digital_connector_state *
intel_atomic_get_digital_connector_state(struct intel_atomic_state *state,
struct intel_connector *connector)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 62a3365ed5e6..d2700c74c9da 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -35,6 +35,7 @@ struct drm_connector_state *
intel_digital_connector_duplicate_state(struct drm_connector *connector);
bool intel_connector_needs_modeset(struct intel_atomic_state *state,
struct drm_connector *connector);
+bool intel_any_crtc_needs_modeset(struct intel_atomic_state *state);
struct intel_digital_connector_state *
intel_atomic_get_digital_connector_state(struct intel_atomic_state *state,
struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index a35435083b60..bfb398f0432e 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -162,7 +162,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
{
struct intel_qgv_info qi = {};
bool is_y_tile = true; /* assume y tile may be used */
- int num_channels = dev_priv->dram_info.num_channels;
+ int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels);
int deinterleave;
int ipqdepth, ipqdepthpch;
int dclk_max;
@@ -267,7 +267,7 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
- if (IS_ALDERLAKE_S(dev_priv))
+ if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv))
icl_get_bw_info(dev_priv, &adls_sa_info);
else if (IS_ROCKETLAKE(dev_priv))
icl_get_bw_info(dev_priv, &rkl_sa_info);
diff --git a/drivers/gpu/drm/i915/display/intel_csr.h b/drivers/gpu/drm/i915/display/intel_csr.h
deleted file mode 100644
index 03c64f8af7ab..000000000000
--- a/drivers/gpu/drm/i915/display/intel_csr.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2019 Intel Corporation
- */
-
-#ifndef __INTEL_CSR_H__
-#define __INTEL_CSR_H__
-
-struct drm_i915_private;
-
-#define CSR_VERSION(major, minor) ((major) << 16 | (minor))
-#define CSR_VERSION_MAJOR(version) ((version) >> 16)
-#define CSR_VERSION_MINOR(version) ((version) & 0xffff)
-
-void intel_csr_ucode_init(struct drm_i915_private *i915);
-void intel_csr_load_program(struct drm_i915_private *i915);
-void intel_csr_ucode_fini(struct drm_i915_private *i915);
-void intel_csr_ucode_suspend(struct drm_i915_private *i915);
-void intel_csr_ucode_resume(struct drm_i915_private *i915);
-
-#endif /* __INTEL_CSR_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index eccbdd42d223..4d6f1a206f56 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -249,15 +249,48 @@ static u32 icl_pll_to_ddi_clk_sel(struct intel_encoder *encoder,
}
}
+static u32 ddi_buf_phy_link_rate(int port_clock)
+{
+ switch (port_clock) {
+ case 162000:
+ return DDI_BUF_PHY_LINK_RATE(0);
+ case 216000:
+ return DDI_BUF_PHY_LINK_RATE(4);
+ case 243000:
+ return DDI_BUF_PHY_LINK_RATE(5);
+ case 270000:
+ return DDI_BUF_PHY_LINK_RATE(1);
+ case 324000:
+ return DDI_BUF_PHY_LINK_RATE(6);
+ case 432000:
+ return DDI_BUF_PHY_LINK_RATE(7);
+ case 540000:
+ return DDI_BUF_PHY_LINK_RATE(2);
+ case 810000:
+ return DDI_BUF_PHY_LINK_RATE(3);
+ default:
+ MISSING_CASE(port_clock);
+ return DDI_BUF_PHY_LINK_RATE(0);
+ }
+}
+
static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+ enum phy phy = intel_port_to_phy(i915, encoder->port);
intel_dp->DP = dig_port->saved_port_bits |
DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count);
+
+ if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) {
+ intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock);
+ if (dig_port->tc_mode != TC_PORT_TBT_ALT)
+ intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;
+ }
}
static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
@@ -979,6 +1012,8 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
if (DISPLAY_VER(dev_priv) >= 12) {
if (intel_phy_is_combo(dev_priv, phy))
tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
+ else if (IS_ALDERLAKE_P(dev_priv))
+ adlp_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
else
tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
} else if (DISPLAY_VER(dev_priv) == 11) {
@@ -1425,7 +1460,10 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
return;
- ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
+ if (IS_ALDERLAKE_P(dev_priv))
+ ddi_translations = adlp_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
+ else
+ ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
@@ -3157,6 +3195,9 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
/* In HDMI/DVI mode, the port width, and swing/emphasis values
* are ignored so nothing special needs to be done besides
* enabling the port.
+ *
+ * On ADL_P the PHY link rate and lane count must be programmed but
+ * these are both 0 for HDMI.
*/
intel_de_write(dev_priv, DDI_BUF_CTL(port),
dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE);
@@ -4688,9 +4729,12 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
dig_port->hpd_pulse = intel_dp_hpd_pulse;
- /* Splitter enable for eDP MSO is supported for pipe A only. */
- if (dig_port->dp.mso_link_count)
+ /* Splitter enable for eDP MSO is limited to certain pipes. */
+ if (dig_port->dp.mso_link_count) {
encoder->pipe_mask = BIT(PIPE_A);
+ if (IS_ALDERLAKE_P(dev_priv))
+ encoder->pipe_mask |= BIT(PIPE_B);
+ }
}
/* In theory we don't need the encoder->type check, but leave it just in
diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index 7bcdd5c12028..8bfd00f49f2a 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -735,6 +735,34 @@ static const struct cnl_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr2_hbr
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
};
+static const struct tgl_dkl_phy_ddi_buf_trans adlp_dkl_phy_dp_ddi_trans_hbr[] = {
+ /* VS pre-emp Non-trans mV Pre-emph dB */
+ { 0x7, 0x0, 0x01 }, /* 0 0 400mV 0 dB */
+ { 0x5, 0x0, 0x06 }, /* 0 1 400mV 3.5 dB */
+ { 0x2, 0x0, 0x0B }, /* 0 2 400mV 6 dB */
+ { 0x0, 0x0, 0x17 }, /* 0 3 400mV 9.5 dB */
+ { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
+ { 0x2, 0x0, 0x08 }, /* 1 1 600mV 3.5 dB */
+ { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
+ { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
+ { 0x0, 0x0, 0x0B }, /* 2 1 800mV 3.5 dB */
+ { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB */
+};
+
+static const struct tgl_dkl_phy_ddi_buf_trans adlp_dkl_phy_dp_ddi_trans_hbr2_hbr3[] = {
+ /* VS pre-emp Non-trans mV Pre-emph dB */
+ { 0x7, 0x0, 0x00 }, /* 0 0 400mV 0 dB */
+ { 0x5, 0x0, 0x04 }, /* 0 1 400mV 3.5 dB */
+ { 0x2, 0x0, 0x0A }, /* 0 2 400mV 6 dB */
+ { 0x0, 0x0, 0x18 }, /* 0 3 400mV 9.5 dB */
+ { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
+ { 0x2, 0x0, 0x06 }, /* 1 1 600mV 3.5 dB */
+ { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
+ { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
+ { 0x0, 0x0, 0x09 }, /* 2 1 800mV 3.5 dB */
+ { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB */
+};
+
bool is_hobl_buf_trans(const struct cnl_ddi_buf_trans *table)
{
return table == tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
@@ -1348,6 +1376,31 @@ tgl_get_dkl_buf_trans(struct intel_encoder *encoder,
return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
}
+static const struct tgl_dkl_phy_ddi_buf_trans *
+adlp_get_dkl_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (crtc_state->port_clock > 270000) {
+ *n_entries = ARRAY_SIZE(adlp_dkl_phy_dp_ddi_trans_hbr2_hbr3);
+ return adlp_dkl_phy_dp_ddi_trans_hbr2_hbr3;
+ }
+
+ *n_entries = ARRAY_SIZE(adlp_dkl_phy_dp_ddi_trans_hbr);
+ return adlp_dkl_phy_dp_ddi_trans_hbr;
+}
+
+const struct tgl_dkl_phy_ddi_buf_trans *
+adlp_get_dkl_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else
+ return adlp_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *default_entry)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h
index f8f0ef87e977..4c2efab38642 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h
@@ -67,6 +67,10 @@ bxt_get_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries);
+const struct tgl_dkl_phy_ddi_buf_trans *
+adlp_get_dkl_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries);
const struct cnl_ddi_buf_trans *
tgl_get_combo_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 384ff0bb6e19..890030e544ca 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -79,9 +79,9 @@
#include "intel_cdclk.h"
#include "intel_color.h"
#include "intel_crtc.h"
-#include "intel_csr.h"
#include "intel_de.h"
#include "intel_display_types.h"
+#include "intel_dmc.h"
#include "intel_dp_link_training.h"
#include "intel_fbc.h"
#include "intel_fdi.h"
@@ -3675,7 +3675,9 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy)
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
{
- if (IS_TIGERLAKE(dev_priv))
+ if (IS_ALDERLAKE_P(dev_priv))
+ return phy >= PHY_F && phy <= PHY_I;
+ else if (IS_TIGERLAKE(dev_priv))
return phy >= PHY_D && phy <= PHY_I;
else if (IS_ICELAKE(dev_priv))
return phy >= PHY_C && phy <= PHY_F;
@@ -5714,8 +5716,12 @@ static void hsw_set_pipeconf(const struct intel_crtc_state *crtc_state)
static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ const struct intel_crtc_scaler_state *scaler_state =
+ &crtc_state->scaler_state;
+
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 val = 0;
+ int i;
switch (crtc_state->pipe_bpp) {
case 18:
@@ -5754,6 +5760,23 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
if (DISPLAY_VER(dev_priv) >= 12)
val |= PIPEMISC_PIXEL_ROUNDING_TRUNC;
+ if (IS_ALDERLAKE_P(dev_priv)) {
+ bool scaler_in_use = false;
+
+ for (i = 0; i < crtc->num_scalers; i++) {
+ if (!scaler_state->scalers[i].in_use)
+ continue;
+
+ scaler_in_use = true;
+ break;
+ }
+
+ intel_de_rmw(dev_priv, PIPE_MISC2(crtc->pipe),
+ PIPE_MISC2_UNDERRUN_BUBBLE_COUNTER_MASK,
+ scaler_in_use ? PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN :
+ PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS);
+ }
+
intel_de_write(dev_priv, PIPEMISC(crtc->pipe), val);
}
@@ -8750,6 +8773,38 @@ static void verify_wm_state(struct intel_crtc *crtc,
hw_wm_level->lines);
}
+ hw_wm_level = &hw->wm.planes[plane->id].sagv.wm0;
+ sw_wm_level = &sw_wm->planes[plane->id].sagv.wm0;
+
+ if (HAS_HW_SAGV_WM(dev_priv) &&
+ !skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
+ drm_err(&dev_priv->drm,
+ "[PLANE:%d:%s] mismatch in SAGV WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
+ plane->base.base.id, plane->base.name,
+ sw_wm_level->enable,
+ sw_wm_level->blocks,
+ sw_wm_level->lines,
+ hw_wm_level->enable,
+ hw_wm_level->blocks,
+ hw_wm_level->lines);
+ }
+
+ hw_wm_level = &hw->wm.planes[plane->id].sagv.trans_wm;
+ sw_wm_level = &sw_wm->planes[plane->id].sagv.trans_wm;
+
+ if (HAS_HW_SAGV_WM(dev_priv) &&
+ !skl_wm_level_equals(hw_wm_level, sw_wm_level)) {
+ drm_err(&dev_priv->drm,
+ "[PLANE:%d:%s] mismatch in SAGV trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n",
+ plane->base.base.id, plane->base.name,
+ sw_wm_level->enable,
+ sw_wm_level->blocks,
+ sw_wm_level->lines,
+ hw_wm_level->enable,
+ hw_wm_level->blocks,
+ hw_wm_level->lines);
+ }
+
/* DDB */
hw_ddb_entry = &hw->ddb_y[plane->id];
sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb_y[plane->id];
@@ -9923,6 +9978,9 @@ static int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
+ if (intel_any_crtc_needs_modeset(state))
+ any_ms = true;
+
if (any_ms) {
ret = intel_modeset_checks(state);
if (ret)
@@ -11219,7 +11277,14 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
- if (IS_ALDERLAKE_S(dev_priv)) {
+ if (IS_ALDERLAKE_P(dev_priv)) {
+ intel_ddi_init(dev_priv, PORT_A);
+ intel_ddi_init(dev_priv, PORT_B);
+ intel_ddi_init(dev_priv, PORT_TC1);
+ intel_ddi_init(dev_priv, PORT_TC2);
+ intel_ddi_init(dev_priv, PORT_TC3);
+ intel_ddi_init(dev_priv, PORT_TC4);
+ } else if (IS_ALDERLAKE_S(dev_priv)) {
intel_ddi_init(dev_priv, PORT_A);
intel_ddi_init(dev_priv, PORT_TC1);
intel_ddi_init(dev_priv, PORT_TC2);
@@ -12183,7 +12248,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
if (!HAS_DISPLAY(i915))
return 0;
- intel_csr_ucode_init(i915);
+ intel_dmc_ucode_init(i915);
i915->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0);
i915->flip_wq = alloc_workqueue("i915_flip", WQ_HIGHPRI |
@@ -12195,15 +12260,15 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
ret = intel_cdclk_init(i915);
if (ret)
- goto cleanup_vga_client_pw_domain_csr;
+ goto cleanup_vga_client_pw_domain_dmc;
ret = intel_dbuf_init(i915);
if (ret)
- goto cleanup_vga_client_pw_domain_csr;
+ goto cleanup_vga_client_pw_domain_dmc;
ret = intel_bw_init(i915);
if (ret)
- goto cleanup_vga_client_pw_domain_csr;
+ goto cleanup_vga_client_pw_domain_dmc;
init_llist_head(&i915->atomic_helper.free_list);
INIT_WORK(&i915->atomic_helper.free_work,
@@ -12215,8 +12280,8 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
return 0;
-cleanup_vga_client_pw_domain_csr:
- intel_csr_ucode_fini(i915);
+cleanup_vga_client_pw_domain_dmc:
+ intel_dmc_ucode_fini(i915);
intel_power_domains_driver_remove(i915);
intel_vga_unregister(i915);
cleanup_bios:
@@ -13295,7 +13360,7 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
/* part #3: call after gem init */
void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915)
{
- intel_csr_ucode_fini(i915);
+ intel_dmc_ucode_fini(i915);
intel_power_domains_driver_remove(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index d77a0ab5cacf..94e5cbd86e77 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -7,11 +7,11 @@
#include <drm/drm_fourcc.h>
#include "i915_debugfs.h"
-#include "intel_csr.h"
#include "intel_display_debugfs.h"
#include "intel_display_power.h"
#include "intel_de.h"
#include "intel_display_types.h"
+#include "intel_dmc.h"
#include "intel_dp.h"
#include "intel_fbc.h"
#include "intel_hdcp.h"
@@ -532,24 +532,24 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
intel_wakeref_t wakeref;
- struct intel_csr *csr;
+ struct intel_dmc *dmc;
i915_reg_t dc5_reg, dc6_reg = {};
- if (!HAS_CSR(dev_priv))
+ if (!HAS_DMC(dev_priv))
return -ENODEV;
- csr = &dev_priv->csr;
+ dmc = &dev_priv->dmc;
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
- seq_printf(m, "fw loaded: %s\n", yesno(csr->dmc_payload != NULL));
- seq_printf(m, "path: %s\n", csr->fw_path);
+ seq_printf(m, "fw loaded: %s\n", yesno(dmc->dmc_payload));
+ seq_printf(m, "path: %s\n", dmc->fw_path);
- if (!csr->dmc_payload)
+ if (!dmc->dmc_payload)
goto out;
- seq_printf(m, "version: %d.%d\n", CSR_VERSION_MAJOR(csr->version),
- CSR_VERSION_MINOR(csr->version));
+ seq_printf(m, "version: %d.%d\n", DMC_VERSION_MAJOR(dmc->version),
+ DMC_VERSION_MINOR(dmc->version));
if (DISPLAY_VER(dev_priv) >= 12) {
if (IS_DGFX(dev_priv)) {
@@ -568,10 +568,10 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
seq_printf(m, "DC3CO count: %d\n",
intel_de_read(dev_priv, DMC_DEBUG3));
} else {
- dc5_reg = IS_BROXTON(dev_priv) ? BXT_CSR_DC3_DC5_COUNT :
- SKL_CSR_DC3_DC5_COUNT;
+ dc5_reg = IS_BROXTON(dev_priv) ? BXT_DMC_DC3_DC5_COUNT :
+ SKL_DMC_DC3_DC5_COUNT;
if (!IS_GEMINILAKE(dev_priv) && !IS_BROXTON(dev_priv))
- dc6_reg = SKL_CSR_DC5_DC6_COUNT;
+ dc6_reg = SKL_DMC_DC5_DC6_COUNT;
}
seq_printf(m, "DC3 -> DC5 count: %d\n",
@@ -582,10 +582,10 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
out:
seq_printf(m, "program base: 0x%08x\n",
- intel_de_read(dev_priv, CSR_PROGRAM(0)));
+ intel_de_read(dev_priv, DMC_PROGRAM(0)));
seq_printf(m, "ssp base: 0x%08x\n",
- intel_de_read(dev_priv, CSR_SSP_BASE));
- seq_printf(m, "htp: 0x%08x\n", intel_de_read(dev_priv, CSR_HTP_SKL));
+ intel_de_read(dev_priv, DMC_SSP_BASE));
+ seq_printf(m, "htp: 0x%08x\n", intel_de_read(dev_priv, DMC_HTP_SKL));
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 54c6d65011ee..2f7d1664c473 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -9,10 +9,10 @@
#include "i915_irq.h"
#include "intel_cdclk.h"
#include "intel_combo_phy.h"
-#include "intel_csr.h"
#include "intel_display_power.h"
#include "intel_de.h"
#include "intel_display_types.h"
+#include "intel_dmc.h"
#include "intel_dpio_phy.h"
#include "intel_hotplug.h"
#include "intel_pm.h"
@@ -619,11 +619,9 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
* or need to enable AUX on a legacy TypeC port as part of the TC-cold
* exit sequence.
*/
- timeout_expected = is_tbt;
- if (DISPLAY_VER(dev_priv) == 11 && dig_port->tc_legacy_port) {
+ timeout_expected = is_tbt || intel_tc_cold_requires_aux_pw(dig_port);
+ if (DISPLAY_VER(dev_priv) == 11 && dig_port->tc_legacy_port)
icl_tc_cold_exit(dev_priv);
- timeout_expected = true;
- }
hsw_wait_for_power_well_enable(dev_priv, power_well, timeout_expected);
@@ -829,8 +827,8 @@ static void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv)
drm_dbg_kms(&dev_priv->drm,
"Resetting DC state tracking from %02x to %02x\n",
- dev_priv->csr.dc_state, val);
- dev_priv->csr.dc_state = val;
+ dev_priv->dmc.dc_state, val);
+ dev_priv->dmc.dc_state = val;
}
/**
@@ -865,8 +863,8 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm,
- state & ~dev_priv->csr.allowed_dc_mask))
- state &= dev_priv->csr.allowed_dc_mask;
+ state & ~dev_priv->dmc.allowed_dc_mask))
+ state &= dev_priv->dmc.allowed_dc_mask;
val = intel_de_read(dev_priv, DC_STATE_EN);
mask = gen9_dc_mask(dev_priv);
@@ -874,16 +872,16 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
val & mask, state);
/* Check if DMC is ignoring our DC state requests */
- if ((val & mask) != dev_priv->csr.dc_state)
+ if ((val & mask) != dev_priv->dmc.dc_state)
drm_err(&dev_priv->drm, "DC state mismatch (0x%x -> 0x%x)\n",
- dev_priv->csr.dc_state, val & mask);
+ dev_priv->dmc.dc_state, val & mask);
val &= ~mask;
val |= state;
gen9_write_dc_state(dev_priv, val);
- dev_priv->csr.dc_state = val & mask;
+ dev_priv->dmc.dc_state = val & mask;
}
static u32
@@ -902,7 +900,7 @@ sanitize_target_dc_state(struct drm_i915_private *dev_priv,
if (target_dc_state != states[i])
continue;
- if (dev_priv->csr.allowed_dc_mask & target_dc_state)
+ if (dev_priv->dmc.allowed_dc_mask & target_dc_state)
break;
target_dc_state = states[i + 1];
@@ -958,15 +956,15 @@ static void bxt_disable_dc9(struct drm_i915_private *dev_priv)
intel_pps_unlock_regs_wa(dev_priv);
}
-static void assert_csr_loaded(struct drm_i915_private *dev_priv)
+static void assert_dmc_loaded(struct drm_i915_private *dev_priv)
{
drm_WARN_ONCE(&dev_priv->drm,
- !intel_de_read(dev_priv, CSR_PROGRAM(0)),
- "CSR program storage start is NULL\n");
- drm_WARN_ONCE(&dev_priv->drm, !intel_de_read(dev_priv, CSR_SSP_BASE),
- "CSR SSP Base Not fine\n");
- drm_WARN_ONCE(&dev_priv->drm, !intel_de_read(dev_priv, CSR_HTP_SKL),
- "CSR HTP Not fine\n");
+ !intel_de_read(dev_priv, DMC_PROGRAM(0)),
+ "DMC program storage start is NULL\n");
+ drm_WARN_ONCE(&dev_priv->drm, !intel_de_read(dev_priv, DMC_SSP_BASE),
+ "DMC SSP Base Not fine\n");
+ drm_WARN_ONCE(&dev_priv->drm, !intel_de_read(dev_priv, DMC_HTP_SKL),
+ "DMC HTP Not fine\n");
}
static struct i915_power_well *
@@ -1016,7 +1014,7 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
state = sanitize_target_dc_state(dev_priv, state);
- if (state == dev_priv->csr.target_dc_state)
+ if (state == dev_priv->dmc.target_dc_state)
goto unlock;
dc_off_enabled = power_well->desc->ops->is_enabled(dev_priv,
@@ -1028,7 +1026,7 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
if (!dc_off_enabled)
power_well->desc->ops->enable(dev_priv, power_well);
- dev_priv->csr.target_dc_state = state;
+ dev_priv->dmc.target_dc_state = state;
if (!dc_off_enabled)
power_well->desc->ops->disable(dev_priv, power_well);
@@ -1057,7 +1055,7 @@ static void assert_can_enable_dc5(struct drm_i915_private *dev_priv)
"DC5 already programmed to be enabled.\n");
assert_rpm_wakelock_held(&dev_priv->runtime_pm);
- assert_csr_loaded(dev_priv);
+ assert_dmc_loaded(dev_priv);
}
static void gen9_enable_dc5(struct drm_i915_private *dev_priv)
@@ -1084,7 +1082,7 @@ static void assert_can_enable_dc6(struct drm_i915_private *dev_priv)
DC_STATE_EN_UPTO_DC6),
"DC6 already programmed to be enabled.\n");
- assert_csr_loaded(dev_priv);
+ assert_dmc_loaded(dev_priv);
}
static void skl_enable_dc6(struct drm_i915_private *dev_priv)
@@ -1181,7 +1179,7 @@ static void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
{
struct intel_cdclk_config cdclk_config = {};
- if (dev_priv->csr.target_dc_state == DC_STATE_EN_DC3CO) {
+ if (dev_priv->dmc.target_dc_state == DC_STATE_EN_DC3CO) {
tgl_disable_dc3co(dev_priv);
return;
}
@@ -1220,10 +1218,10 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- if (!dev_priv->csr.dmc_payload)
+ if (!dev_priv->dmc.dmc_payload)
return;
- switch (dev_priv->csr.target_dc_state) {
+ switch (dev_priv->dmc.target_dc_state) {
case DC_STATE_EN_DC3CO:
tgl_enable_dc3co(dev_priv);
break;
@@ -5090,10 +5088,10 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
dev_priv->params.disable_power_well =
sanitize_disable_power_well_option(dev_priv,
dev_priv->params.disable_power_well);
- dev_priv->csr.allowed_dc_mask =
+ dev_priv->dmc.allowed_dc_mask =
get_allowed_dc_mask(dev_priv, dev_priv->params.enable_dc);
- dev_priv->csr.target_dc_state =
+ dev_priv->dmc.target_dc_state =
sanitize_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
BUILD_BUG_ON(POWER_DOMAIN_NUM > 64);
@@ -5245,6 +5243,9 @@ static void gen12_dbuf_slices_config(struct drm_i915_private *dev_priv)
{
enum dbuf_slice slice;
+ if (IS_ALDERLAKE_P(dev_priv))
+ return;
+
for_each_dbuf_slice(dev_priv, slice)
intel_de_rmw(dev_priv, DBUF_CTL_S(slice),
DBUF_TRACKER_STATE_SERVICE_MASK,
@@ -5256,6 +5257,9 @@ static void icl_mbus_init(struct drm_i915_private *dev_priv)
unsigned long abox_regs = INTEL_INFO(dev_priv)->abox_mask;
u32 mask, val, i;
+ if (IS_ALDERLAKE_P(dev_priv))
+ return;
+
mask = MBUS_ABOX_BT_CREDIT_POOL1_MASK |
MBUS_ABOX_BT_CREDIT_POOL2_MASK |
MBUS_ABOX_B_CREDIT_MASK |
@@ -5573,8 +5577,8 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
gen9_dbuf_enable(dev_priv);
- if (resume && dev_priv->csr.dmc_payload)
- intel_csr_load_program(dev_priv);
+ if (resume && dev_priv->dmc.dmc_payload)
+ intel_dmc_load_program(dev_priv);
}
static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
@@ -5640,8 +5644,8 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume
gen9_dbuf_enable(dev_priv);
- if (resume && dev_priv->csr.dmc_payload)
- intel_csr_load_program(dev_priv);
+ if (resume && dev_priv->dmc.dmc_payload)
+ intel_dmc_load_program(dev_priv);
}
static void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
@@ -5706,8 +5710,8 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
/* 6. Enable DBUF */
gen9_dbuf_enable(dev_priv);
- if (resume && dev_priv->csr.dmc_payload)
- intel_csr_load_program(dev_priv);
+ if (resume && dev_priv->dmc.dmc_payload)
+ intel_dmc_load_program(dev_priv);
}
static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
@@ -5863,8 +5867,8 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) >= 12)
tgl_bw_buddy_init(dev_priv);
- if (resume && dev_priv->csr.dmc_payload)
- intel_csr_load_program(dev_priv);
+ if (resume && dev_priv->dmc.dmc_payload)
+ intel_dmc_load_program(dev_priv);
/* Wa_14011508470 */
if (DISPLAY_VER(dev_priv) == 12) {
@@ -6218,13 +6222,13 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
/*
* In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9
* support don't manually deinit the power domains. This also means the
- * CSR/DMC firmware will stay active, it will power down any HW
+ * DMC firmware will stay active, it will power down any HW
* resources as required and also enable deeper system power states
* that would be blocked if the firmware was inactive.
*/
- if (!(i915->csr.allowed_dc_mask & DC_STATE_EN_DC9) &&
+ if (!(i915->dmc.allowed_dc_mask & DC_STATE_EN_DC9) &&
suspend_mode == I915_DRM_SUSPEND_IDLE &&
- i915->csr.dmc_payload) {
+ i915->dmc.dmc_payload) {
intel_display_power_flush_work(i915);
intel_power_domains_verify_state(i915);
return;
@@ -6414,19 +6418,19 @@ void intel_display_power_resume(struct drm_i915_private *i915)
if (DISPLAY_VER(i915) >= 11) {
bxt_disable_dc9(i915);
icl_display_core_init(i915, true);
- if (i915->csr.dmc_payload) {
- if (i915->csr.allowed_dc_mask &
+ if (i915->dmc.dmc_payload) {
+ if (i915->dmc.allowed_dc_mask &
DC_STATE_EN_UPTO_DC6)
skl_enable_dc6(i915);
- else if (i915->csr.allowed_dc_mask &
+ else if (i915->dmc.allowed_dc_mask &
DC_STATE_EN_UPTO_DC5)
gen9_enable_dc5(i915);
}
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
bxt_disable_dc9(i915);
bxt_display_core_init(i915, true);
- if (i915->csr.dmc_payload &&
- (i915->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5))
+ if (i915->dmc.dmc_payload &&
+ (i915->dmc.allowed_dc_mask & DC_STATE_EN_UPTO_DC5))
gen9_enable_dc5(i915);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_disable_pc8(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 9c0adfc60c6f..ce05475ad560 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1498,7 +1498,7 @@ struct intel_psr {
bool sink_not_reliable;
bool irq_aux_error;
u16 su_x_granularity;
- bool dc3co_enabled;
+ u32 dc3co_exitline;
u32 dc3co_exit_delay;
struct delayed_work dc3co_work;
struct drm_dp_vsc_sdp vsc;
diff --git a/drivers/gpu/drm/i915/display/intel_csr.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 26a922d34263..560574dd929a 100644
--- a/drivers/gpu/drm/i915/display/intel_csr.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -26,14 +26,13 @@
#include "i915_drv.h"
#include "i915_reg.h"
-#include "intel_csr.h"
#include "intel_de.h"
+#include "intel_dmc.h"
/**
- * DOC: csr support for dmc
+ * DOC: DMC Firmware Support
*
- * Display Context Save and Restore (CSR) firmware support added from gen9
- * onwards to drive newly added DMC (Display microcontroller) in display
+ * From gen9 onwards we have newly added DMC (Display microcontroller) in display
* engine to save and restore the state of display engine when it enter into
* low-power state and comes back to normal.
*/
@@ -44,55 +43,55 @@
__stringify(major) "_" \
__stringify(minor) ".bin"
-#define GEN12_CSR_MAX_FW_SIZE ICL_CSR_MAX_FW_SIZE
+#define GEN12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
-#define ADLS_CSR_PATH DMC_PATH(adls, 2, 01)
-#define ADLS_CSR_VERSION_REQUIRED CSR_VERSION(2, 1)
-MODULE_FIRMWARE(ADLS_CSR_PATH);
+#define ADLS_DMC_PATH DMC_PATH(adls, 2, 01)
+#define ADLS_DMC_VERSION_REQUIRED DMC_VERSION(2, 1)
+MODULE_FIRMWARE(ADLS_DMC_PATH);
-#define DG1_CSR_PATH DMC_PATH(dg1, 2, 02)
-#define DG1_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
-MODULE_FIRMWARE(DG1_CSR_PATH);
+#define DG1_DMC_PATH DMC_PATH(dg1, 2, 02)
+#define DG1_DMC_VERSION_REQUIRED DMC_VERSION(2, 2)
+MODULE_FIRMWARE(DG1_DMC_PATH);
-#define RKL_CSR_PATH DMC_PATH(rkl, 2, 02)
-#define RKL_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
-MODULE_FIRMWARE(RKL_CSR_PATH);
+#define RKL_DMC_PATH DMC_PATH(rkl, 2, 02)
+#define RKL_DMC_VERSION_REQUIRED DMC_VERSION(2, 2)
+MODULE_FIRMWARE(RKL_DMC_PATH);
-#define TGL_CSR_PATH DMC_PATH(tgl, 2, 08)
-#define TGL_CSR_VERSION_REQUIRED CSR_VERSION(2, 8)
-MODULE_FIRMWARE(TGL_CSR_PATH);
+#define TGL_DMC_PATH DMC_PATH(tgl, 2, 08)
+#define TGL_DMC_VERSION_REQUIRED DMC_VERSION(2, 8)
+MODULE_FIRMWARE(TGL_DMC_PATH);
-#define ICL_CSR_PATH DMC_PATH(icl, 1, 09)
-#define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 9)
-#define ICL_CSR_MAX_FW_SIZE 0x6000
-MODULE_FIRMWARE(ICL_CSR_PATH);
+#define ICL_DMC_PATH DMC_PATH(icl, 1, 09)
+#define ICL_DMC_VERSION_REQUIRED DMC_VERSION(1, 9)
+#define ICL_DMC_MAX_FW_SIZE 0x6000
+MODULE_FIRMWARE(ICL_DMC_PATH);
-#define CNL_CSR_PATH DMC_PATH(cnl, 1, 07)
-#define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7)
-#define CNL_CSR_MAX_FW_SIZE GLK_CSR_MAX_FW_SIZE
-MODULE_FIRMWARE(CNL_CSR_PATH);
+#define CNL_DMC_PATH DMC_PATH(cnl, 1, 07)
+#define CNL_DMC_VERSION_REQUIRED DMC_VERSION(1, 7)
+#define CNL_DMC_MAX_FW_SIZE GLK_DMC_MAX_FW_SIZE
+MODULE_FIRMWARE(CNL_DMC_PATH);
-#define GLK_CSR_PATH DMC_PATH(glk, 1, 04)
-#define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4)
-#define GLK_CSR_MAX_FW_SIZE 0x4000
-MODULE_FIRMWARE(GLK_CSR_PATH);
+#define GLK_DMC_PATH DMC_PATH(glk, 1, 04)
+#define GLK_DMC_VERSION_REQUIRED DMC_VERSION(1, 4)
+#define GLK_DMC_MAX_FW_SIZE 0x4000
+MODULE_FIRMWARE(GLK_DMC_PATH);
-#define KBL_CSR_PATH DMC_PATH(kbl, 1, 04)
-#define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4)
-#define KBL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE
-MODULE_FIRMWARE(KBL_CSR_PATH);
+#define KBL_DMC_PATH DMC_PATH(kbl, 1, 04)
+#define KBL_DMC_VERSION_REQUIRED DMC_VERSION(1, 4)
+#define KBL_DMC_MAX_FW_SIZE BXT_DMC_MAX_FW_SIZE
+MODULE_FIRMWARE(KBL_DMC_PATH);
-#define SKL_CSR_PATH DMC_PATH(skl, 1, 27)
-#define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 27)
-#define SKL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE
-MODULE_FIRMWARE(SKL_CSR_PATH);
+#define SKL_DMC_PATH DMC_PATH(skl, 1, 27)
+#define SKL_DMC_VERSION_REQUIRED DMC_VERSION(1, 27)
+#define SKL_DMC_MAX_FW_SIZE BXT_DMC_MAX_FW_SIZE
+MODULE_FIRMWARE(SKL_DMC_PATH);
-#define BXT_CSR_PATH DMC_PATH(bxt, 1, 07)
-#define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7)
-#define BXT_CSR_MAX_FW_SIZE 0x3000
-MODULE_FIRMWARE(BXT_CSR_PATH);
+#define BXT_DMC_PATH DMC_PATH(bxt, 1, 07)
+#define BXT_DMC_VERSION_REQUIRED DMC_VERSION(1, 7)
+#define BXT_DMC_MAX_FW_SIZE 0x3000
+MODULE_FIRMWARE(BXT_DMC_PATH);
-#define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF
+#define DMC_DEFAULT_FW_OFFSET 0xFFFFFFFF
#define PACKAGE_MAX_FW_INFO_ENTRIES 20
#define PACKAGE_V2_MAX_FW_INFO_ENTRIES 32
#define DMC_V1_MAX_MMIO_COUNT 8
@@ -303,47 +302,47 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
}
/**
- * intel_csr_load_program() - write the firmware from memory to register.
+ * intel_dmc_load_program() - write the firmware from memory to register.
* @dev_priv: i915 drm device.
*
- * CSR firmware is read from a .bin file and kept in internal memory one time.
+ * DMC firmware is read from a .bin file and kept in internal memory one time.
* Everytime display comes back from low power state this function is called to
* copy the firmware from internal memory to registers.
*/
-void intel_csr_load_program(struct drm_i915_private *dev_priv)
+void intel_dmc_load_program(struct drm_i915_private *dev_priv)
{
- u32 *payload = dev_priv->csr.dmc_payload;
+ u32 *payload = dev_priv->dmc.dmc_payload;
u32 i, fw_size;
- if (!HAS_CSR(dev_priv)) {
+ if (!HAS_DMC(dev_priv)) {
drm_err(&dev_priv->drm,
- "No CSR support available for this platform\n");
+ "No DMC support available for this platform\n");
return;
}
- if (!dev_priv->csr.dmc_payload) {
+ if (!dev_priv->dmc.dmc_payload) {
drm_err(&dev_priv->drm,
"Tried to program CSR with empty payload\n");
return;
}
- fw_size = dev_priv->csr.dmc_fw_size;
+ fw_size = dev_priv->dmc.dmc_fw_size;
assert_rpm_wakelock_held(&dev_priv->runtime_pm);
preempt_disable();
for (i = 0; i < fw_size; i++)
- intel_uncore_write_fw(&dev_priv->uncore, CSR_PROGRAM(i),
+ intel_uncore_write_fw(&dev_priv->uncore, DMC_PROGRAM(i),
payload[i]);
preempt_enable();
- for (i = 0; i < dev_priv->csr.mmio_count; i++) {
- intel_de_write(dev_priv, dev_priv->csr.mmioaddr[i],
- dev_priv->csr.mmiodata[i]);
+ for (i = 0; i < dev_priv->dmc.mmio_count; i++) {
+ intel_de_write(dev_priv, dev_priv->dmc.mmioaddr[i],
+ dev_priv->dmc.mmiodata[i]);
}
- dev_priv->csr.dc_state = 0;
+ dev_priv->dmc.dc_state = 0;
gen9_set_dc_state_debugmask(dev_priv);
}
@@ -357,7 +356,7 @@ static u32 find_dmc_fw_offset(const struct intel_fw_info *fw_info,
const struct stepping_info *si,
u8 package_ver)
{
- u32 dmc_offset = CSR_DEFAULT_FW_OFFSET;
+ u32 dmc_offset = DMC_DEFAULT_FW_OFFSET;
unsigned int i;
for (i = 0; i < num_entries; i++) {
@@ -392,17 +391,17 @@ static u32 find_dmc_fw_offset(const struct intel_fw_info *fw_info,
return dmc_offset;
}
-static u32 parse_csr_fw_dmc(struct intel_csr *csr,
- const struct intel_dmc_header_base *dmc_header,
- size_t rem_size)
+static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
+ const struct intel_dmc_header_base *dmc_header,
+ size_t rem_size)
{
unsigned int header_len_bytes, dmc_header_size, payload_size, i;
const u32 *mmioaddr, *mmiodata;
u32 mmio_count, mmio_count_max;
u8 *payload;
- BUILD_BUG_ON(ARRAY_SIZE(csr->mmioaddr) < DMC_V3_MAX_MMIO_COUNT ||
- ARRAY_SIZE(csr->mmioaddr) < DMC_V1_MAX_MMIO_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(dmc->mmioaddr) < DMC_V3_MAX_MMIO_COUNT ||
+ ARRAY_SIZE(dmc->mmioaddr) < DMC_V1_MAX_MMIO_COUNT);
/*
* Check if we can access common fields, we will checkc again below
@@ -458,16 +457,16 @@ static u32 parse_csr_fw_dmc(struct intel_csr *csr,
}
for (i = 0; i < mmio_count; i++) {
- if (mmioaddr[i] < CSR_MMIO_START_RANGE ||
- mmioaddr[i] > CSR_MMIO_END_RANGE) {
+ if (mmioaddr[i] < DMC_MMIO_START_RANGE ||
+ mmioaddr[i] > DMC_MMIO_END_RANGE) {
DRM_ERROR("DMC firmware has wrong mmio address 0x%x\n",
mmioaddr[i]);
return 0;
}
- csr->mmioaddr[i] = _MMIO(mmioaddr[i]);
- csr->mmiodata[i] = mmiodata[i];
+ dmc->mmioaddr[i] = _MMIO(mmioaddr[i]);
+ dmc->mmiodata[i] = mmiodata[i];
}
- csr->mmio_count = mmio_count;
+ dmc->mmio_count = mmio_count;
rem_size -= header_len_bytes;
@@ -476,20 +475,20 @@ static u32 parse_csr_fw_dmc(struct intel_csr *csr,
if (rem_size < payload_size)
goto error_truncated;
- if (payload_size > csr->max_fw_size) {
+ if (payload_size > dmc->max_fw_size) {
DRM_ERROR("DMC FW too big (%u bytes)\n", payload_size);
return 0;
}
- csr->dmc_fw_size = dmc_header->fw_size;
+ dmc->dmc_fw_size = dmc_header->fw_size;
- csr->dmc_payload = kmalloc(payload_size, GFP_KERNEL);
- if (!csr->dmc_payload) {
+ dmc->dmc_payload = kmalloc(payload_size, GFP_KERNEL);
+ if (!dmc->dmc_payload) {
DRM_ERROR("Memory allocation failed for dmc payload\n");
return 0;
}
payload = (u8 *)(dmc_header) + header_len_bytes;
- memcpy(csr->dmc_payload, payload, payload_size);
+ memcpy(dmc->dmc_payload, payload, payload_size);
return header_len_bytes + payload_size;
@@ -499,7 +498,7 @@ error_truncated:
}
static u32
-parse_csr_fw_package(struct intel_csr *csr,
+parse_dmc_fw_package(struct intel_dmc *dmc,
const struct intel_package_header *package_header,
const struct stepping_info *si,
size_t rem_size)
@@ -543,7 +542,7 @@ parse_csr_fw_package(struct intel_csr *csr,
((u8 *)package_header + sizeof(*package_header));
dmc_offset = find_dmc_fw_offset(fw_info, num_entries, si,
package_header->header_ver);
- if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
+ if (dmc_offset == DMC_DEFAULT_FW_OFFSET) {
DRM_ERROR("DMC firmware not supported for %c stepping\n",
si->stepping);
return 0;
@@ -558,7 +557,7 @@ error_truncated:
}
/* Return number of bytes parsed or 0 on error */
-static u32 parse_csr_fw_css(struct intel_csr *csr,
+static u32 parse_dmc_fw_css(struct intel_dmc *dmc,
struct intel_css_header *css_header,
size_t rem_size)
{
@@ -575,29 +574,29 @@ static u32 parse_csr_fw_css(struct intel_csr *csr,
return 0;
}
- if (csr->required_version &&
- css_header->version != csr->required_version) {
+ if (dmc->required_version &&
+ css_header->version != dmc->required_version) {
DRM_INFO("Refusing to load DMC firmware v%u.%u,"
" please use v%u.%u\n",
- CSR_VERSION_MAJOR(css_header->version),
- CSR_VERSION_MINOR(css_header->version),
- CSR_VERSION_MAJOR(csr->required_version),
- CSR_VERSION_MINOR(csr->required_version));
+ DMC_VERSION_MAJOR(css_header->version),
+ DMC_VERSION_MINOR(css_header->version),
+ DMC_VERSION_MAJOR(dmc->required_version),
+ DMC_VERSION_MINOR(dmc->required_version));
return 0;
}
- csr->version = css_header->version;
+ dmc->version = css_header->version;
return sizeof(struct intel_css_header);
}
-static void parse_csr_fw(struct drm_i915_private *dev_priv,
+static void parse_dmc_fw(struct drm_i915_private *dev_priv,
const struct firmware *fw)
{
struct intel_css_header *css_header;
struct intel_package_header *package_header;
struct intel_dmc_header_base *dmc_header;
- struct intel_csr *csr = &dev_priv->csr;
+ struct intel_dmc *dmc = &dev_priv->dmc;
const struct stepping_info *si = intel_get_stepping_info(dev_priv);
u32 readcount = 0;
u32 r;
@@ -607,7 +606,7 @@ static void parse_csr_fw(struct drm_i915_private *dev_priv,
/* Extract CSS Header information */
css_header = (struct intel_css_header *)fw->data;
- r = parse_csr_fw_css(csr, css_header, fw->size);
+ r = parse_dmc_fw_css(dmc, css_header, fw->size);
if (!r)
return;
@@ -615,7 +614,7 @@ static void parse_csr_fw(struct drm_i915_private *dev_priv,
/* Extract Package Header information */
package_header = (struct intel_package_header *)&fw->data[readcount];
- r = parse_csr_fw_package(csr, package_header, si, fw->size - readcount);
+ r = parse_dmc_fw_package(dmc, package_header, si, fw->size - readcount);
if (!r)
return;
@@ -623,49 +622,49 @@ static void parse_csr_fw(struct drm_i915_private *dev_priv,
/* Extract dmc_header information */
dmc_header = (struct intel_dmc_header_base *)&fw->data[readcount];
- parse_csr_fw_dmc(csr, dmc_header, fw->size - readcount);
+ parse_dmc_fw_header(dmc, dmc_header, fw->size - readcount);
}
-static void intel_csr_runtime_pm_get(struct drm_i915_private *dev_priv)
+static void intel_dmc_runtime_pm_get(struct drm_i915_private *dev_priv)
{
- drm_WARN_ON(&dev_priv->drm, dev_priv->csr.wakeref);
- dev_priv->csr.wakeref =
+ drm_WARN_ON(&dev_priv->drm, dev_priv->dmc.wakeref);
+ dev_priv->dmc.wakeref =
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
}
-static void intel_csr_runtime_pm_put(struct drm_i915_private *dev_priv)
+static void intel_dmc_runtime_pm_put(struct drm_i915_private *dev_priv)
{
intel_wakeref_t wakeref __maybe_unused =
- fetch_and_zero(&dev_priv->csr.wakeref);
+ fetch_and_zero(&dev_priv->dmc.wakeref);
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
}
-static void csr_load_work_fn(struct work_struct *work)
+static void dmc_load_work_fn(struct work_struct *work)
{
struct drm_i915_private *dev_priv;
- struct intel_csr *csr;
+ struct intel_dmc *dmc;
const struct firmware *fw = NULL;
- dev_priv = container_of(work, typeof(*dev_priv), csr.work);
- csr = &dev_priv->csr;
+ dev_priv = container_of(work, typeof(*dev_priv), dmc.work);
+ dmc = &dev_priv->dmc;
- request_firmware(&fw, dev_priv->csr.fw_path, dev_priv->drm.dev);
- parse_csr_fw(dev_priv, fw);
+ request_firmware(&fw, dev_priv->dmc.fw_path, dev_priv->drm.dev);
+ parse_dmc_fw(dev_priv, fw);
- if (dev_priv->csr.dmc_payload) {
- intel_csr_load_program(dev_priv);
- intel_csr_runtime_pm_put(dev_priv);
+ if (dev_priv->dmc.dmc_payload) {
+ intel_dmc_load_program(dev_priv);
+ intel_dmc_runtime_pm_put(dev_priv);
drm_info(&dev_priv->drm,
"Finished loading DMC firmware %s (v%u.%u)\n",
- dev_priv->csr.fw_path, CSR_VERSION_MAJOR(csr->version),
- CSR_VERSION_MINOR(csr->version));
+ dev_priv->dmc.fw_path, DMC_VERSION_MAJOR(dmc->version),
+ DMC_VERSION_MINOR(dmc->version));
} else {
drm_notice(&dev_priv->drm,
"Failed to load DMC firmware %s."
" Disabling runtime power management.\n",
- csr->fw_path);
+ dmc->fw_path);
drm_notice(&dev_priv->drm, "DMC firmware homepage: %s",
INTEL_UC_FIRMWARE_URL);
}
@@ -674,152 +673,152 @@ static void csr_load_work_fn(struct work_struct *work)
}
/**
- * intel_csr_ucode_init() - initialize the firmware loading.
+ * intel_dmc_ucode_init() - initialize the firmware loading.
* @dev_priv: i915 drm device.
*
* This function is called at the time of loading the display driver to read
* firmware from a .bin file and copied into a internal memory.
*/
-void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
+void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
{
- struct intel_csr *csr = &dev_priv->csr;
+ struct intel_dmc *dmc = &dev_priv->dmc;
- INIT_WORK(&dev_priv->csr.work, csr_load_work_fn);
+ INIT_WORK(&dev_priv->dmc.work, dmc_load_work_fn);
- if (!HAS_CSR(dev_priv))
+ if (!HAS_DMC(dev_priv))
return;
/*
- * Obtain a runtime pm reference, until CSR is loaded, to avoid entering
+ * Obtain a runtime pm reference, until DMC is loaded, to avoid entering
* runtime-suspend.
*
* On error, we return with the rpm wakeref held to prevent runtime
- * suspend as runtime suspend *requires* a working CSR for whatever
+ * suspend as runtime suspend *requires* a working DMC for whatever
* reason.
*/
- intel_csr_runtime_pm_get(dev_priv);
+ intel_dmc_runtime_pm_get(dev_priv);
if (IS_ALDERLAKE_S(dev_priv)) {
- csr->fw_path = ADLS_CSR_PATH;
- csr->required_version = ADLS_CSR_VERSION_REQUIRED;
- csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
+ dmc->fw_path = ADLS_DMC_PATH;
+ dmc->required_version = ADLS_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
} else if (IS_DG1(dev_priv)) {
- csr->fw_path = DG1_CSR_PATH;
- csr->required_version = DG1_CSR_VERSION_REQUIRED;
- csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
+ dmc->fw_path = DG1_DMC_PATH;
+ dmc->required_version = DG1_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
} else if (IS_ROCKETLAKE(dev_priv)) {
- csr->fw_path = RKL_CSR_PATH;
- csr->required_version = RKL_CSR_VERSION_REQUIRED;
- csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
+ dmc->fw_path = RKL_DMC_PATH;
+ dmc->required_version = RKL_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(dev_priv) >= 12) {
- csr->fw_path = TGL_CSR_PATH;
- csr->required_version = TGL_CSR_VERSION_REQUIRED;
- csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
+ dmc->fw_path = TGL_DMC_PATH;
+ dmc->required_version = TGL_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(dev_priv) == 11) {
- csr->fw_path = ICL_CSR_PATH;
- csr->required_version = ICL_CSR_VERSION_REQUIRED;
- csr->max_fw_size = ICL_CSR_MAX_FW_SIZE;
+ dmc->fw_path = ICL_DMC_PATH;
+ dmc->required_version = ICL_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = ICL_DMC_MAX_FW_SIZE;
} else if (IS_CANNONLAKE(dev_priv)) {
- csr->fw_path = CNL_CSR_PATH;
- csr->required_version = CNL_CSR_VERSION_REQUIRED;
- csr->max_fw_size = CNL_CSR_MAX_FW_SIZE;
+ dmc->fw_path = CNL_DMC_PATH;
+ dmc->required_version = CNL_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = CNL_DMC_MAX_FW_SIZE;
} else if (IS_GEMINILAKE(dev_priv)) {
- csr->fw_path = GLK_CSR_PATH;
- csr->required_version = GLK_CSR_VERSION_REQUIRED;
- csr->max_fw_size = GLK_CSR_MAX_FW_SIZE;
+ dmc->fw_path = GLK_DMC_PATH;
+ dmc->required_version = GLK_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = GLK_DMC_MAX_FW_SIZE;
} else if (IS_KABYLAKE(dev_priv) ||
IS_COFFEELAKE(dev_priv) ||
IS_COMETLAKE(dev_priv)) {
- csr->fw_path = KBL_CSR_PATH;
- csr->required_version = KBL_CSR_VERSION_REQUIRED;
- csr->max_fw_size = KBL_CSR_MAX_FW_SIZE;
+ dmc->fw_path = KBL_DMC_PATH;
+ dmc->required_version = KBL_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = KBL_DMC_MAX_FW_SIZE;
} else if (IS_SKYLAKE(dev_priv)) {
- csr->fw_path = SKL_CSR_PATH;
- csr->required_version = SKL_CSR_VERSION_REQUIRED;
- csr->max_fw_size = SKL_CSR_MAX_FW_SIZE;
+ dmc->fw_path = SKL_DMC_PATH;
+ dmc->required_version = SKL_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = SKL_DMC_MAX_FW_SIZE;
} else if (IS_BROXTON(dev_priv)) {
- csr->fw_path = BXT_CSR_PATH;
- csr->required_version = BXT_CSR_VERSION_REQUIRED;
- csr->max_fw_size = BXT_CSR_MAX_FW_SIZE;
+ dmc->fw_path = BXT_DMC_PATH;
+ dmc->required_version = BXT_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = BXT_DMC_MAX_FW_SIZE;
}
if (dev_priv->params.dmc_firmware_path) {
if (strlen(dev_priv->params.dmc_firmware_path) == 0) {
- csr->fw_path = NULL;
+ dmc->fw_path = NULL;
drm_info(&dev_priv->drm,
- "Disabling CSR firmware and runtime PM\n");
+ "Disabling DMC firmware and runtime PM\n");
return;
}
- csr->fw_path = dev_priv->params.dmc_firmware_path;
+ dmc->fw_path = dev_priv->params.dmc_firmware_path;
/* Bypass version check for firmware override. */
- csr->required_version = 0;
+ dmc->required_version = 0;
}
- if (csr->fw_path == NULL) {
+ if (!dmc->fw_path) {
drm_dbg_kms(&dev_priv->drm,
- "No known CSR firmware for platform, disabling runtime PM\n");
+ "No known DMC firmware for platform, disabling runtime PM\n");
return;
}
- drm_dbg_kms(&dev_priv->drm, "Loading %s\n", csr->fw_path);
- schedule_work(&dev_priv->csr.work);
+ drm_dbg_kms(&dev_priv->drm, "Loading %s\n", dmc->fw_path);
+ schedule_work(&dev_priv->dmc.work);
}
/**
- * intel_csr_ucode_suspend() - prepare CSR firmware before system suspend
+ * intel_dmc_ucode_suspend() - prepare DMC firmware before system suspend
* @dev_priv: i915 drm device
*
* Prepare the DMC firmware before entering system suspend. This includes
* flushing pending work items and releasing any resources acquired during
* init.
*/
-void intel_csr_ucode_suspend(struct drm_i915_private *dev_priv)
+void intel_dmc_ucode_suspend(struct drm_i915_private *dev_priv)
{
- if (!HAS_CSR(dev_priv))
+ if (!HAS_DMC(dev_priv))
return;
- flush_work(&dev_priv->csr.work);
+ flush_work(&dev_priv->dmc.work);
/* Drop the reference held in case DMC isn't loaded. */
- if (!dev_priv->csr.dmc_payload)
- intel_csr_runtime_pm_put(dev_priv);
+ if (!dev_priv->dmc.dmc_payload)
+ intel_dmc_runtime_pm_put(dev_priv);
}
/**
- * intel_csr_ucode_resume() - init CSR firmware during system resume
+ * intel_dmc_ucode_resume() - init DMC firmware during system resume
* @dev_priv: i915 drm device
*
* Reinitialize the DMC firmware during system resume, reacquiring any
- * resources released in intel_csr_ucode_suspend().
+ * resources released in intel_dmc_ucode_suspend().
*/
-void intel_csr_ucode_resume(struct drm_i915_private *dev_priv)
+void intel_dmc_ucode_resume(struct drm_i915_private *dev_priv)
{
- if (!HAS_CSR(dev_priv))
+ if (!HAS_DMC(dev_priv))
return;
/*
* Reacquire the reference to keep RPM disabled in case DMC isn't
* loaded.
*/
- if (!dev_priv->csr.dmc_payload)
- intel_csr_runtime_pm_get(dev_priv);
+ if (!dev_priv->dmc.dmc_payload)
+ intel_dmc_runtime_pm_get(dev_priv);
}
/**
- * intel_csr_ucode_fini() - unload the CSR firmware.
+ * intel_dmc_ucode_fini() - unload the DMC firmware.
* @dev_priv: i915 drm device.
*
* Firmmware unloading includes freeing the internal memory and reset the
* firmware loading status.
*/
-void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
+void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv)
{
- if (!HAS_CSR(dev_priv))
+ if (!HAS_DMC(dev_priv))
return;
- intel_csr_ucode_suspend(dev_priv);
- drm_WARN_ON(&dev_priv->drm, dev_priv->csr.wakeref);
+ intel_dmc_ucode_suspend(dev_priv);
+ drm_WARN_ON(&dev_priv->drm, dev_priv->dmc.wakeref);
- kfree(dev_priv->csr.dmc_payload);
+ kfree(dev_priv->dmc.dmc_payload);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
new file mode 100644
index 000000000000..57dd99da0ced
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dmc.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef __INTEL_DMC_H__
+#define __INTEL_DMC_H__
+
+struct drm_i915_private;
+
+#define DMC_VERSION(major, minor) ((major) << 16 | (minor))
+#define DMC_VERSION_MAJOR(version) ((version) >> 16)
+#define DMC_VERSION_MINOR(version) ((version) & 0xffff)
+
+void intel_dmc_ucode_init(struct drm_i915_private *i915);
+void intel_dmc_load_program(struct drm_i915_private *i915);
+void intel_dmc_ucode_fini(struct drm_i915_private *i915);
+void intel_dmc_ucode_suspend(struct drm_i915_private *i915);
+void intel_dmc_ucode_resume(struct drm_i915_private *i915);
+
+#endif /* __INTEL_DMC_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 6bf6f1ec13ed..08bceae40aa8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -128,49 +128,13 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable)
return drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) == 1;
}
-/**
- * intel_dp_init_lttpr_and_dprx_caps - detect LTTPR and DPRX caps, init the LTTPR link training mode
- * @intel_dp: Intel DP struct
- *
- * Read the LTTPR common and DPRX capabilities and switch to non-transparent
- * link training mode if any is detected and read the PHY capabilities for all
- * detected LTTPRs. In case of an LTTPR detection error or if the number of
- * LTTPRs is more than is supported (8), fall back to the no-LTTPR,
- * transparent mode link training mode.
- *
- * Returns:
- * >0 if LTTPRs were detected and the non-transparent LT mode was set. The
- * DPRX capabilities are read out.
- * 0 if no LTTPRs or more than 8 LTTPRs were detected or in case of a
- * detection failure and the transparent LT mode was set. The DPRX
- * capabilities are read out.
- * <0 Reading out the DPRX capabilities failed.
- */
-int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
+static int intel_dp_init_lttpr(struct intel_dp *intel_dp)
{
int lttpr_count;
- bool ret;
int i;
- ret = intel_dp_read_lttpr_common_caps(intel_dp);
-
- /* The DPTX shall read the DPRX caps after LTTPR detection. */
- if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) {
- intel_dp_reset_lttpr_common_caps(intel_dp);
- return -EIO;
- }
-
- if (!ret)
- return 0;
-
- /*
- * The 0xF0000-0xF02FF range is only valid if the DPCD revision is
- * at least 1.4.
- */
- if (intel_dp->dpcd[DP_DPCD_REV] < 0x14) {
- intel_dp_reset_lttpr_common_caps(intel_dp);
+ if (!intel_dp_read_lttpr_common_caps(intel_dp))
return 0;
- }
lttpr_count = drm_dp_lttpr_count(intel_dp->lttpr_common_caps);
/*
@@ -211,6 +175,37 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
return lttpr_count;
}
+
+/**
+ * intel_dp_init_lttpr_and_dprx_caps - detect LTTPR and DPRX caps, init the LTTPR link training mode
+ * @intel_dp: Intel DP struct
+ *
+ * Read the LTTPR common and DPRX capabilities and switch to non-transparent
+ * link training mode if any is detected and read the PHY capabilities for all
+ * detected LTTPRs. In case of an LTTPR detection error or if the number of
+ * LTTPRs is more than is supported (8), fall back to the no-LTTPR,
+ * transparent mode link training mode.
+ *
+ * Returns:
+ * >0 if LTTPRs were detected and the non-transparent LT mode was set. The
+ * DPRX capabilities are read out.
+ * 0 if no LTTPRs or more than 8 LTTPRs were detected or in case of a
+ * detection failure and the transparent LT mode was set. The DPRX
+ * capabilities are read out.
+ * <0 Reading out the DPRX capabilities failed.
+ */
+int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
+{
+ int lttpr_count = intel_dp_init_lttpr(intel_dp);
+
+ /* The DPTX shall read the DPRX caps after LTTPR detection. */
+ if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) {
+ intel_dp_reset_lttpr_common_caps(intel_dp);
+ return -EIO;
+ }
+
+ return lttpr_count;
+}
EXPORT_SYMBOL(intel_dp_init_lttpr_and_dprx_caps);
static u8 dp_voltage_max(u8 preemph)
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 18bfe8d09277..71ac57670043 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -149,6 +149,16 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
pll->info->name, onoff(state), onoff(cur_state));
}
+static enum tc_port icl_pll_id_to_tc_port(enum intel_dpll_id id)
+{
+ return TC_PORT_1 + id - DPLL_ID_ICL_MGPLL1;
+}
+
+enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port)
+{
+ return tc_port - TC_PORT_1 + DPLL_ID_ICL_MGPLL1;
+}
+
static i915_reg_t
intel_combo_pll_enable_reg(struct drm_i915_private *i915,
struct intel_shared_dpll *pll)
@@ -161,6 +171,19 @@ intel_combo_pll_enable_reg(struct drm_i915_private *i915,
return CNL_DPLL_ENABLE(pll->info->id);
}
+static i915_reg_t
+intel_tc_pll_enable_reg(struct drm_i915_private *i915,
+ struct intel_shared_dpll *pll)
+{
+ const enum intel_dpll_id id = pll->info->id;
+ enum tc_port tc_port = icl_pll_id_to_tc_port(id);
+
+ if (IS_ALDERLAKE_P(i915))
+ return ADLP_PORTTC_PLL_ENABLE(tc_port);
+
+ return MG_PLL_ENABLE(tc_port);
+}
+
/**
* intel_prepare_shared_dpll - call a dpll's prepare hook
* @crtc_state: CRTC, and its state, which has a shared dpll
@@ -3120,16 +3143,6 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
pll_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
}
-static enum tc_port icl_pll_id_to_tc_port(enum intel_dpll_id id)
-{
- return id - DPLL_ID_ICL_MGPLL1;
-}
-
-enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port)
-{
- return tc_port + DPLL_ID_ICL_MGPLL1;
-}
-
static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
u32 *target_dco_khz,
struct intel_dpll_hw_state *state,
@@ -3728,12 +3741,14 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *dev_priv,
bool ret = false;
u32 val;
+ i915_reg_t enable_reg = intel_tc_pll_enable_reg(dev_priv, pll);
+
wakeref = intel_display_power_get_if_enabled(dev_priv,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, MG_PLL_ENABLE(tc_port));
+ val = intel_de_read(dev_priv, enable_reg);
if (!(val & PLL_ENABLE))
goto out;
@@ -3797,7 +3812,7 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, MG_PLL_ENABLE(tc_port));
+ val = intel_de_read(dev_priv, intel_tc_pll_enable_reg(dev_priv, pll));
if (!(val & PLL_ENABLE))
goto out;
@@ -4169,8 +4184,7 @@ static void tbt_pll_enable(struct drm_i915_private *dev_priv,
static void mg_pll_enable(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll)
{
- i915_reg_t enable_reg =
- MG_PLL_ENABLE(icl_pll_id_to_tc_port(pll->info->id));
+ i915_reg_t enable_reg = intel_tc_pll_enable_reg(dev_priv, pll);
icl_pll_power_enable(dev_priv, pll, enable_reg);
@@ -4249,8 +4263,7 @@ static void tbt_pll_disable(struct drm_i915_private *dev_priv,
static void mg_pll_disable(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll)
{
- i915_reg_t enable_reg =
- MG_PLL_ENABLE(icl_pll_id_to_tc_port(pll->info->id));
+ i915_reg_t enable_reg = intel_tc_pll_enable_reg(dev_priv, pll);
icl_pll_disable(dev_priv, pll, enable_reg);
}
@@ -4416,6 +4429,26 @@ static const struct intel_dpll_mgr adls_pll_mgr = {
.dump_hw_state = icl_dump_hw_state,
};
+static const struct dpll_info adlp_plls[] = {
+ { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
+ { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
+ { "TBT PLL", &tbt_pll_funcs, DPLL_ID_ICL_TBTPLL, 0 },
+ { "TC PLL 1", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
+ { "TC PLL 2", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
+ { "TC PLL 3", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
+ { "TC PLL 4", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
+ { },
+};
+
+static const struct intel_dpll_mgr adlp_pll_mgr = {
+ .dpll_info = adlp_plls,
+ .get_dplls = icl_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 = icl_dump_hw_state,
+};
+
/**
* intel_shared_dpll_init - Initialize shared DPLLs
* @dev: drm device
@@ -4429,7 +4462,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
const struct dpll_info *dpll_info;
int i;
- if (IS_ALDERLAKE_S(dev_priv))
+ if (IS_ALDERLAKE_P(dev_priv))
+ dpll_mgr = &adlp_pll_mgr;
+ else if (IS_ALDERLAKE_S(dev_priv))
dpll_mgr = &adls_pll_mgr;
else if (IS_DG1(dev_priv))
dpll_mgr = &dg1_pll_mgr;
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index a005c68889e7..c60a81a81c09 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -355,8 +355,17 @@ static int intel_fb_offset_to_xy(int *x, int *y,
unsigned int height;
u32 alignment;
- if (DISPLAY_VER(i915) >= 12 &&
- is_semiplanar_uv_plane(fb, color_plane))
+ /*
+ * All DPT color planes must be 512*4k aligned (the amount mapped by a
+ * single DPT page). For ADL_P CCS FBs this only works by requiring
+ * the allocated offsets to be 2MB aligned. Once supoort to remap
+ * such FBs is added we can remove this requirement, as then all the
+ * planes can be remapped to an aligned offset.
+ */
+ if (IS_ALDERLAKE_P(i915) && is_ccs_modifier(fb->modifier))
+ alignment = 512 * 4096;
+ else if (DISPLAY_VER(i915) >= 12 &&
+ is_semiplanar_uv_plane(fb, color_plane))
alignment = intel_tile_row_size(fb, color_plane);
else if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
alignment = intel_tile_size(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index acaf3d459821..1b27af872ba1 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -638,7 +638,7 @@ unlock:
static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp)
{
- if (!intel_dp->psr.dc3co_enabled)
+ if (!intel_dp->psr.dc3co_exitline)
return;
cancel_delayed_work(&intel_dp->psr.dc3co_work);
@@ -646,12 +646,26 @@ static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp)
tgl_psr2_disable_dc3co(intel_dp);
}
+static bool
+dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum port port = dig_port->base.port;
+
+ if (IS_ALDERLAKE_P(dev_priv))
+ return pipe <= PIPE_B && port <= PORT_B;
+ else
+ return pipe == PIPE_A && port == PORT_A;
+}
+
static void
tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
const u32 crtc_vdisplay = crtc_state->uapi.adjusted_mode.crtc_vdisplay;
- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u32 exit_scanlines;
@@ -669,12 +683,10 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
if (crtc_state->enable_psr2_sel_fetch)
return;
- if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC3CO))
+ if (!(dev_priv->dmc.allowed_dc_mask & DC_STATE_EN_DC3CO))
return;
- /* B.Specs:49196 DC3CO only works with pipeA and DDIA.*/
- if (to_intel_crtc(crtc_state->uapi.crtc)->pipe != PIPE_A ||
- dig_port->base.port != PORT_A)
+ if (!dc3co_is_pipe_port_compatible(intel_dp, crtc_state))
return;
/*
@@ -753,6 +765,15 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
+ /*
+ * We are missing the implementation of some workarounds to enabled PSR2
+ * in Alderlake_P, until ready PSR2 should be kept disabled.
+ */
+ if (IS_ALDERLAKE_P(dev_priv)) {
+ drm_dbg_kms(&dev_priv->drm, "PSR2 is missing the implementation of workarounds\n");
+ return false;
+ }
+
if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 not supported in transcoder %s\n",
@@ -1010,7 +1031,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
psr_irq_control(intel_dp);
- if (crtc_state->dc3co_exitline) {
+ if (intel_dp->psr.dc3co_exitline) {
u32 val;
/*
@@ -1019,7 +1040,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
*/
val = intel_de_read(dev_priv, EXITLINE(cpu_transcoder));
val &= ~EXITLINE_MASK;
- val |= crtc_state->dc3co_exitline << EXITLINE_SHIFT;
+ val |= intel_dp->psr.dc3co_exitline << EXITLINE_SHIFT;
val |= EXITLINE_ENABLE;
intel_de_write(dev_priv, EXITLINE(cpu_transcoder), val);
}
@@ -1030,27 +1051,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
IGNORE_PSR2_HW_TRACKING : 0);
}
-static void intel_psr_enable_locked(struct intel_dp *intel_dp,
- const struct intel_crtc_state *crtc_state,
- const struct drm_connector_state *conn_state)
+static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
{
- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- struct intel_encoder *encoder = &dig_port->base;
u32 val;
- drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
-
- intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
- intel_dp->psr.busy_frontbuffer_bits = 0;
- intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
- intel_dp->psr.dc3co_enabled = !!crtc_state->dc3co_exitline;
- intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
- /* DC5/DC6 requires at least 6 idle frames */
- val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
- intel_dp->psr.dc3co_exit_delay = val;
- intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
-
/*
* If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
* will still keep the error set even after the reset done in the
@@ -1071,9 +1076,36 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.sink_not_reliable = true;
drm_dbg_kms(&dev_priv->drm,
"PSR interruption error set, not enabling PSR\n");
- return;
+ return false;
}
+ return true;
+}
+
+static void intel_psr_enable_locked(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ const struct drm_connector_state *conn_state)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
+ u32 val;
+
+ drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
+
+ intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
+ intel_dp->psr.busy_frontbuffer_bits = 0;
+ intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+ intel_dp->psr.transcoder = crtc_state->cpu_transcoder;
+ /* DC5/DC6 requires at least 6 idle frames */
+ val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
+ intel_dp->psr.dc3co_exit_delay = val;
+ intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline;
+ intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
+
+ if (!psr_interrupt_error_check(intel_dp))
+ return;
+
drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
intel_dp->psr.psr2_enabled ? "2" : "1");
intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
@@ -1818,7 +1850,7 @@ tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
{
mutex_lock(&intel_dp->psr.lock);
- if (!intel_dp->psr.dc3co_enabled)
+ if (!intel_dp->psr.dc3co_exitline)
goto unlock;
if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active)
diff --git a/drivers/gpu/drm/i915/display/intel_qp_tables.c b/drivers/gpu/drm/i915/display/intel_qp_tables.c
new file mode 100644
index 000000000000..c626a24fe98f
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_qp_tables.c
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include <drm/drm_dsc.h>
+
+#include "i915_utils.h"
+#include "intel_qp_tables.h"
+
+/* from BPP 6 to 24 in steps of 0.5 */
+#define RC_RANGE_QP444_8BPC_MAX_NUM_BPP 37
+
+/* from BPP 6 to 30 in steps of 0.5 */
+#define RC_RANGE_QP444_10BPC_MAX_NUM_BPP 49
+
+/* from BPP 6 to 36 in steps of 0.5 */
+#define RC_RANGE_QP444_12BPC_MAX_NUM_BPP 61
+
+/*
+ * These qp tables are as per the C model
+ * and it has the rows pointing to bpps which increment
+ * in steps of 0.5
+ * We do not support fractional bpps as of today,
+ * hence we would skip the fractional bpps during
+ * our references for qp calclulations.
+ */
+static const u8 rc_range_minqp444_8bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_8BPC_MAX_NUM_BPP] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
+ 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0 },
+ { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,
+ 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0 },
+ { 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5,
+ 5, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1 },
+ { 14, 14, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 10, 10, 9, 9, 9, 8, 8,
+ 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3 }
+};
+
+static const u8 rc_range_maxqp444_8bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_8BPC_MAX_NUM_BPP] = {
+ { 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 6, 6, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 8, 7, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 3, 3, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3,
+ 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 },
+ { 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3,
+ 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 },
+ { 10, 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 5, 5, 4, 4, 4, 4, 3,
+ 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 },
+ { 11, 11, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 5,
+ 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 12, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 7, 6, 6, 5, 5, 5,
+ 5, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 12, 12, 11, 11, 10, 10, 10, 10, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 6,
+ 5, 5, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7,
+ 6, 6, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1 },
+ { 12, 12, 12, 12, 11, 11, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7,
+ 6, 6, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1 },
+ { 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 8, 8, 8,
+ 8, 7, 7, 6, 6, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 2, 2, 2 },
+ { 15, 15, 14, 14, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 9,
+ 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4 }
+};
+
+static const u8 rc_range_minqp444_10bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_10BPC_MAX_NUM_BPP] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 7, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3,
+ 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3,
+ 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4,
+ 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0 },
+ { 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5,
+ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0 },
+ { 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5,
+ 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 0,
+ 0, 0, 0 },
+ { 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5,
+ 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1,
+ 1, 0, 0 },
+ { 10, 9, 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
+ 1, 1, 0 },
+ { 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6,
+ 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1,
+ 1, 1, 1 },
+ { 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8,
+ 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2,
+ 2, 1, 1, 1 },
+ { 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
+ 8, 8, 8, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2,
+ 2, 2, 2, 1 },
+ { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 10, 10, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4,
+ 4, 3, 3, 3, 3, 2, 2, 2, 2, 1 },
+ { 18, 18, 17, 17, 16, 16, 16, 16, 15, 15, 14, 14, 14, 14, 13, 13, 13,
+ 12, 12, 12, 11, 11, 11, 11, 10, 10, 9, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7,
+ 7, 6, 6, 5, 5, 5, 5, 4, 4, 3, 3, 3 }
+};
+
+static const u8 rc_range_maxqp444_10bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_10BPC_MAX_NUM_BPP] = {
+ { 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 10, 10, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3,
+ 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 },
+ { 12, 11, 11, 10, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 7, 6, 6, 5, 5, 5, 4,
+ 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0 },
+ { 12, 12, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 8, 7, 7, 6,
+ 6, 6, 5, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0 },
+ { 13, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8, 7,
+ 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 13, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 9, 8, 8,
+ 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
+ 2, 2, 1, 1, 1, 1, 0, 0 },
+ { 13, 13, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 8, 8,
+ 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1 },
+ { 14, 14, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 10, 9, 9,
+ 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3,
+ 3, 2, 2, 2, 1, 1, 1, 1 },
+ { 15, 15, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 11, 11, 10, 10, 9,
+ 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3,
+ 3, 3, 2, 2, 2, 2, 1, 1 },
+ { 16, 15, 15, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 10,
+ 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4,
+ 4, 3, 3, 3, 2, 2, 2, 2, 1 },
+ { 16, 16, 15, 15, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 11,
+ 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5,
+ 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 },
+ { 16, 16, 16, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12,
+ 11, 11, 11, 10, 10, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
+ 5, 4, 4, 4, 4, 3, 3, 2, 2, 2 },
+ { 16, 16, 16, 16, 15, 15, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 12,
+ 11, 11, 11, 10, 10, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
+ 5, 4, 4, 4, 4, 3, 3, 3, 3, 2 },
+ { 17, 17, 17, 17, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 12,
+ 12, 12, 12, 11, 11, 10, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 6,
+ 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2 },
+ { 19, 19, 18, 18, 17, 17, 17, 17, 16, 16, 15, 15, 15, 15, 14, 14, 14,
+ 13, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 10, 10, 10, 9, 9, 8, 8, 8,
+ 8, 8, 7, 7, 6, 6, 6, 6, 5, 5, 4, 4, 4 }
+};
+
+static const u8 rc_range_minqp444_12bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_12BPC_MAX_NUM_BPP] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 11, 10, 10, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3,
+ 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 11, 11, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 7, 6, 6, 6, 6, 6, 5, 5, 5,
+ 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 13, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 9, 8, 7, 7, 7,
+ 7, 5, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 13, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 9, 8, 8,
+ 8, 8, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 13, 13, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 9, 9, 9,
+ 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3,
+ 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 13, 13, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10,
+ 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4,
+ 4, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 13, 13, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 10, 10, 10, 10, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5,
+ 5, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 14, 13, 13, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 10, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 5,
+ 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 0 },
+ { 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12,
+ 12, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7,
+ 6, 6, 6, 5, 5, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1 },
+ { 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 12, 12, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8,
+ 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1 },
+ { 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 12, 12, 12, 12, 12, 12, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8,
+ 7, 7, 7, 7, 6, 6, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1 },
+ { 17, 17, 17, 17, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 14, 14, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 10, 10, 9, 9, 9, 9, 8, 8,
+ 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 1 },
+ { 22, 22, 21, 21, 20, 20, 20, 20, 19, 19, 18, 18, 18, 18, 17, 17, 17, 16, 16,
+ 16, 15, 15, 15, 15, 14, 14, 13, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 11,
+ 10, 10, 9, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 3 }
+};
+
+static const u8 rc_range_maxqp444_12bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_12BPC_MAX_NUM_BPP] = {
+ { 12, 12, 12, 12, 12, 12, 11, 11, 11, 10, 9, 9, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4,
+ 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 14, 14, 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 9, 9, 9, 8, 8, 7, 7, 7, 7, 5,
+ 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 16, 15, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 11, 10, 10, 9, 9,
+ 9, 7, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 16, 16, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 12, 11, 11, 10,
+ 10, 10, 8, 8, 8, 8, 8, 7, 7, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2,
+ 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 17, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 13, 12, 12, 11, 10,
+ 10, 10, 10, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 17, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12, 11,
+ 11, 11, 11, 9, 9, 9, 9, 8, 8, 8, 8, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 3,
+ 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 17, 17, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 13, 12, 12, 11,
+ 11, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5,
+ 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0 },
+ { 18, 18, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 14, 13, 13, 12,
+ 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6,
+ 6, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1 },
+ { 19, 19, 18, 18, 17, 17, 17, 17, 17, 17, 16, 16, 16, 15, 15, 14, 14, 13, 13,
+ 13, 13, 13, 12, 12, 12, 12, 11, 11, 10, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6,
+ 6, 6, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1 },
+ { 20, 19, 19, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 16, 16, 15, 14, 14, 13,
+ 13, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7,
+ 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 1 },
+ { 20, 20, 19, 19, 18, 18, 18, 18, 18, 18, 17, 17, 17, 16, 16, 15, 15, 14, 14,
+ 14, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9,
+ 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2 },
+ { 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 15, 15,
+ 15, 14, 14, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
+ 9, 8, 8, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 2, 2, 2 },
+ { 20, 20, 20, 20, 19, 19, 19, 19, 19, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15,
+ 15, 14, 14, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
+ 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 2, 2, 2 },
+ { 21, 21, 21, 21, 20, 20, 19, 19, 19, 19, 18, 18, 18, 18, 17, 17, 16, 16, 16,
+ 16, 15, 15, 14, 14, 14, 14, 13, 13, 12, 12, 12, 12, 11, 11, 10, 10, 10, 10,
+ 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 2 },
+ { 23, 23, 22, 22, 21, 21, 21, 21, 20, 20, 19, 19, 19, 19, 18, 18, 18, 17, 17,
+ 17, 16, 16, 16, 16, 15, 15, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 12, 12,
+ 11, 11, 10, 10, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 6, 6, 6, 6, 5, 5, 4 }
+};
+
+#define PARAM_TABLE(_minmax, _bpc, _row, _col) do { \
+ if (bpc == (_bpc)) \
+ return rc_range_##_minmax##qp444_##_bpc##bpc[_row][_col]; \
+} while (0)
+
+u8 intel_lookup_range_min_qp(int bpc, int buf_i, int bpp_i)
+{
+ PARAM_TABLE(min, 8, buf_i, bpp_i);
+ PARAM_TABLE(min, 10, buf_i, bpp_i);
+ PARAM_TABLE(min, 12, buf_i, bpp_i);
+
+ MISSING_CASE(bpc);
+ return 0;
+}
+
+u8 intel_lookup_range_max_qp(int bpc, int buf_i, int bpp_i)
+{
+ PARAM_TABLE(max, 8, buf_i, bpp_i);
+ PARAM_TABLE(max, 10, buf_i, bpp_i);
+ PARAM_TABLE(max, 12, buf_i, bpp_i);
+
+ MISSING_CASE(bpc);
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_qp_tables.h b/drivers/gpu/drm/i915/display/intel_qp_tables.h
new file mode 100644
index 000000000000..9fb3c36bd7c6
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_qp_tables.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#ifndef _INTEL_QP_TABLES_H_
+#define _INTEL_QP_TABLES_H_
+
+#include <linux/types.h>
+
+u8 intel_lookup_range_min_qp(int bpc, int buf_i, int bpp_i);
+u8 intel_lookup_range_max_qp(int bpc, int buf_i, int bpp_i);
+
+#endif
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index e325463acddd..c23c210a55f5 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -26,9 +26,7 @@ static const char *tc_port_mode_name(enum tc_port_mode mode)
static enum intel_display_power_domain
tc_cold_get_power_domain(struct intel_digital_port *dig_port)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-
- if (DISPLAY_VER(i915) == 11)
+ if (intel_tc_cold_requires_aux_pw(dig_port))
return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
else
return POWER_DOMAIN_TC_COLD_OFF;
@@ -205,7 +203,7 @@ static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port,
dig_port->tc_legacy_port = !dig_port->tc_legacy_port;
}
-static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port)
+static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_uncore *uncore = &i915->uncore;
@@ -238,6 +236,40 @@ static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port)
return mask;
}
+static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
+ u32 isr_bit = i915->hotplug.pch_hpd[dig_port->base.hpd_pin];
+ struct intel_uncore *uncore = &i915->uncore;
+ u32 val, mask = 0;
+
+ val = intel_uncore_read(uncore, TCSS_DDI_STATUS(tc_port));
+ if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT)
+ mask |= BIT(TC_PORT_DP_ALT);
+ if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT)
+ mask |= BIT(TC_PORT_TBT_ALT);
+
+ if (intel_uncore_read(uncore, SDEISR) & isr_bit)
+ mask |= BIT(TC_PORT_LEGACY);
+
+ /* The sink can be connected only in a single mode. */
+ if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1))
+ tc_port_fixup_legacy_flag(dig_port, mask);
+
+ return mask;
+}
+
+static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ if (IS_ALDERLAKE_P(i915))
+ return adl_tc_port_live_status_mask(dig_port);
+
+ return icl_tc_port_live_status_mask(dig_port);
+}
+
static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
@@ -256,6 +288,33 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port)
return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx);
}
+static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_uncore *uncore = &i915->uncore;
+ u32 val;
+
+ val = intel_uncore_read(uncore, TCSS_DDI_STATUS(dig_port->tc_phy_fia_idx));
+ if (val == 0xffffffff) {
+ drm_dbg_kms(&i915->drm,
+ "Port %s: PHY in TCCOLD, assuming not complete\n",
+ dig_port->tc_port_name);
+ return false;
+ }
+
+ return val & TCSS_DDI_STATUS_READY;
+}
+
+static bool tc_phy_status_complete(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ if (IS_ALDERLAKE_P(i915))
+ return adl_tc_phy_status_complete(dig_port);
+
+ return icl_tc_phy_status_complete(dig_port);
+}
+
static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
bool take)
{
@@ -280,7 +339,7 @@ static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
intel_uncore_write(uncore,
PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val);
- if (!take && wait_for(!icl_tc_phy_status_complete(dig_port), 10))
+ if (!take && wait_for(!tc_phy_status_complete(dig_port), 10))
drm_dbg_kms(&i915->drm,
"Port %s: PHY complete clear timed out\n",
dig_port->tc_port_name);
@@ -288,6 +347,34 @@ static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
return true;
}
+static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
+ bool take)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_uncore *uncore = &i915->uncore;
+ enum port port = dig_port->base.port;
+ u32 val;
+
+ val = intel_uncore_read(uncore, DDI_BUF_CTL(port));
+ if (take)
+ val |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;
+ else
+ val &= ~DDI_BUF_CTL_TC_PHY_OWNERSHIP;
+ intel_uncore_write(uncore, DDI_BUF_CTL(port), val);
+
+ return true;
+}
+
+static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ if (IS_ALDERLAKE_P(i915))
+ return adl_tc_phy_take_ownership(dig_port, take);
+
+ return icl_tc_phy_take_ownership(dig_port, take);
+}
+
static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
@@ -306,6 +393,27 @@ static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port)
return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
}
+static bool adl_tc_phy_is_owned(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_uncore *uncore = &i915->uncore;
+ enum port port = dig_port->base.port;
+ u32 val;
+
+ val = intel_uncore_read(uncore, DDI_BUF_CTL(port));
+ return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP;
+}
+
+static bool tc_phy_is_owned(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ if (IS_ALDERLAKE_P(i915))
+ return adl_tc_phy_is_owned(dig_port);
+
+ return icl_tc_phy_is_owned(dig_port);
+}
+
/*
* This function implements the first part of the Connect Flow described by our
* specification, Gen11 TypeC Programming chapter. The rest of the flow (reading
@@ -323,13 +431,13 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
int max_lanes;
- if (!icl_tc_phy_status_complete(dig_port)) {
+ if (!tc_phy_status_complete(dig_port)) {
drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n",
dig_port->tc_port_name);
goto out_set_tbt_alt_mode;
}
- if (!icl_tc_phy_take_ownership(dig_port, true) &&
+ if (!tc_phy_take_ownership(dig_port, true) &&
!drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port))
goto out_set_tbt_alt_mode;
@@ -364,7 +472,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
return;
out_release_phy:
- icl_tc_phy_take_ownership(dig_port, false);
+ tc_phy_take_ownership(dig_port, false);
out_set_tbt_alt_mode:
dig_port->tc_mode = TC_PORT_TBT_ALT;
}
@@ -380,7 +488,7 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port)
/* Nothing to do, we never disconnect from legacy mode */
break;
case TC_PORT_DP_ALT:
- icl_tc_phy_take_ownership(dig_port, false);
+ tc_phy_take_ownership(dig_port, false);
dig_port->tc_mode = TC_PORT_TBT_ALT;
break;
case TC_PORT_TBT_ALT:
@@ -395,13 +503,13 @@ static bool icl_tc_phy_is_connected(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
- if (!icl_tc_phy_status_complete(dig_port)) {
+ if (!tc_phy_status_complete(dig_port)) {
drm_dbg_kms(&i915->drm, "Port %s: PHY status not complete\n",
dig_port->tc_port_name);
return dig_port->tc_mode == TC_PORT_TBT_ALT;
}
- if (!icl_tc_phy_is_owned(dig_port)) {
+ if (!tc_phy_is_owned(dig_port)) {
drm_dbg_kms(&i915->drm, "Port %s: PHY not owned\n",
dig_port->tc_port_name);
@@ -419,8 +527,8 @@ intel_tc_port_get_current_mode(struct intel_digital_port *dig_port)
u32 live_status_mask = tc_port_live_status_mask(dig_port);
enum tc_port_mode mode;
- if (!icl_tc_phy_is_owned(dig_port) ||
- drm_WARN_ON(&i915->drm, !icl_tc_phy_status_complete(dig_port)))
+ if (!tc_phy_is_owned(dig_port) ||
+ drm_WARN_ON(&i915->drm, !tc_phy_status_complete(dig_port)))
return TC_PORT_TBT_ALT;
mode = dig_port->tc_legacy_port ? TC_PORT_LEGACY : TC_PORT_DP_ALT;
@@ -442,7 +550,7 @@ intel_tc_port_get_target_mode(struct intel_digital_port *dig_port)
if (live_status_mask)
return fls(live_status_mask) - 1;
- return icl_tc_phy_status_complete(dig_port) &&
+ return tc_phy_status_complete(dig_port) &&
dig_port->tc_legacy_port ? TC_PORT_LEGACY :
TC_PORT_TBT_ALT;
}
@@ -454,7 +562,7 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
enum tc_port_mode old_tc_mode = dig_port->tc_mode;
intel_display_power_flush_work(i915);
- if (DISPLAY_VER(i915) != 11 || !dig_port->tc_legacy_port) {
+ if (!intel_tc_cold_requires_aux_pw(dig_port)) {
enum intel_display_power_domain aux_domain;
bool aux_powered;
@@ -624,13 +732,11 @@ tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig
if (!INTEL_INFO(i915)->display.has_modular_fia)
return false;
- /* TODO: check if in real HW MODULAR_FIA_MASK is set, if so remove this block */
- if (IS_ALDERLAKE_P(i915))
- return true;
-
+ mutex_lock(&dig_port->tc_lock);
wakeref = tc_cold_block(dig_port);
val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1));
tc_cold_unblock(dig_port, wakeref);
+ mutex_unlock(&dig_port->tc_lock);
drm_WARN_ON(&i915->drm, val == 0xffffffff);
@@ -673,3 +779,11 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
dig_port->tc_link_refcount = 0;
tc_port_load_fia_params(i915, dig_port);
}
+
+bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+
+ return (DISPLAY_VER(i915) == 11 && dig_port->tc_legacy_port) ||
+ IS_ALDERLAKE_P(i915);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h
index b619e4736f85..0eacbd76ec15 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.h
+++ b/drivers/gpu/drm/i915/display/intel_tc.h
@@ -29,4 +29,6 @@ bool intel_tc_port_ref_held(struct intel_digital_port *dig_port);
void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy);
+bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port);
+
#endif /* __INTEL_TC_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index efc3184d8315..19cd9531c115 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -5,12 +5,13 @@
* Author: Gaurav K Singh <gaurav.k.singh@intel.com>
* Manasi Navare <manasi.d.navare@intel.com>
*/
-
+#include <linux/limits.h>
#include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dsi.h"
#include "intel_vdsc.h"
+#include "intel_qp_tables.h"
enum ROW_INDEX_BPP {
ROW_INDEX_6BPP = 0,
@@ -373,12 +374,81 @@ static bool is_pipe_dsc(const struct intel_crtc_state *crtc_state)
return true;
}
+static void
+calculate_rc_params(struct rc_parameters *rc,
+ struct drm_dsc_config *vdsc_cfg)
+{
+ int bpc = vdsc_cfg->bits_per_component;
+ int bpp = vdsc_cfg->bits_per_pixel >> 4;
+ int ofs_und6[] = { 0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 };
+ int ofs_und8[] = { 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12 };
+ int ofs_und12[] = { 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12 };
+ int ofs_und15[] = { 10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12 };
+ int qp_bpc_modifier = (bpc - 8) * 2;
+ u32 res, buf_i, bpp_i;
+
+ if (vdsc_cfg->slice_height >= 8)
+ rc->first_line_bpg_offset =
+ 12 + DIV_ROUND_UP((9 * min(34, vdsc_cfg->slice_height - 8)), 100);
+ else
+ rc->first_line_bpg_offset = 2 * (vdsc_cfg->slice_height - 1);
+
+ /* Our hw supports only 444 modes as of today */
+ if (bpp >= 12)
+ rc->initial_offset = 2048;
+ else if (bpp >= 10)
+ rc->initial_offset = 5632 - DIV_ROUND_UP(((bpp - 10) * 3584), 2);
+ else if (bpp >= 8)
+ rc->initial_offset = 6144 - DIV_ROUND_UP(((bpp - 8) * 512), 2);
+ else
+ rc->initial_offset = 6144;
+
+ /* initial_xmit_delay = rc_model_size/2/compression_bpp */
+ rc->initial_xmit_delay = DIV_ROUND_UP(DSC_RC_MODEL_SIZE_CONST, 2 * bpp);
+
+ rc->flatness_min_qp = 3 + qp_bpc_modifier;
+ rc->flatness_max_qp = 12 + qp_bpc_modifier;
+
+ rc->rc_quant_incr_limit0 = 11 + qp_bpc_modifier;
+ rc->rc_quant_incr_limit1 = 11 + qp_bpc_modifier;
+
+ bpp_i = (2 * (bpp - 6));
+ for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
+ /* Read range_minqp and range_max_qp from qp tables */
+ rc->rc_range_params[buf_i].range_min_qp =
+ intel_lookup_range_min_qp(bpc, buf_i, bpp_i);
+ rc->rc_range_params[buf_i].range_max_qp =
+ intel_lookup_range_max_qp(bpc, buf_i, bpp_i);
+
+ /* Calculate range_bgp_offset */
+ if (bpp <= 6) {
+ rc->rc_range_params[buf_i].range_bpg_offset = ofs_und6[buf_i];
+ } else if (bpp <= 8) {
+ res = DIV_ROUND_UP(((bpp - 6) * (ofs_und8[buf_i] - ofs_und6[buf_i])), 2);
+ rc->rc_range_params[buf_i].range_bpg_offset =
+ ofs_und6[buf_i] + res;
+ } else if (bpp <= 12) {
+ rc->rc_range_params[buf_i].range_bpg_offset =
+ ofs_und8[buf_i];
+ } else if (bpp <= 15) {
+ res = DIV_ROUND_UP(((bpp - 12) * (ofs_und15[buf_i] - ofs_und12[buf_i])), 3);
+ rc->rc_range_params[buf_i].range_bpg_offset =
+ ofs_und12[buf_i] + res;
+ } else {
+ rc->rc_range_params[buf_i].range_bpg_offset =
+ ofs_und15[buf_i];
+ }
+ }
+}
+
int intel_dsc_compute_params(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config;
u16 compressed_bpp = pipe_config->dsc.compressed_bpp;
const struct rc_parameters *rc_params;
+ struct rc_parameters *rc = NULL;
u8 i = 0;
vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
@@ -413,9 +483,24 @@ int intel_dsc_compute_params(struct intel_encoder *encoder,
vdsc_cfg->rc_buf_thresh[13] = 0x7D;
}
- rc_params = get_rc_params(compressed_bpp, vdsc_cfg->bits_per_component);
- if (!rc_params)
- return -EINVAL;
+ /*
+ * From XE_LPD onwards we supports compression bpps in steps of 1
+ * upto uncompressed bpp-1, hence add calculations for all the rc
+ * parameters
+ */
+ if (DISPLAY_VER(dev_priv) >= 13) {
+ rc = kmalloc(sizeof(*rc), GFP_KERNEL);
+ if (!rc)
+ return -ENOMEM;
+
+ calculate_rc_params(rc, vdsc_cfg);
+ rc_params = rc;
+ } else {
+ rc_params = get_rc_params(compressed_bpp,
+ vdsc_cfg->bits_per_component);
+ if (!rc_params)
+ return -EINVAL;
+ }
vdsc_cfg->first_line_bpg_offset = rc_params->first_line_bpg_offset;
vdsc_cfg->initial_xmit_delay = rc_params->initial_xmit_delay;
@@ -441,20 +526,20 @@ int intel_dsc_compute_params(struct intel_encoder *encoder,
/*
* BitsPerComponent value determines mux_word_size:
- * When BitsPerComponent is 12bpc, muxWordSize will be equal to 64 bits
- * When BitsPerComponent is 8 or 10bpc, muxWordSize will be equal to
- * 48 bits
+ * When BitsPerComponent is less than or 10bpc, muxWordSize will be equal to
+ * 48 bits otherwise 64
*/
- if (vdsc_cfg->bits_per_component == 8 ||
- vdsc_cfg->bits_per_component == 10)
+ if (vdsc_cfg->bits_per_component <= 10)
vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
- else if (vdsc_cfg->bits_per_component == 12)
+ else
vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
/* InitialScaleValue is a 6 bit value with 3 fractional bits (U3.3) */
vdsc_cfg->initial_scale_value = (vdsc_cfg->rc_model_size << 3) /
(vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset);
+ kfree(rc);
+
return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
index 79f565aeb8c0..441644f2506a 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -356,6 +356,7 @@ struct i915_ppgtt {
#define i915_is_ggtt(vm) ((vm)->is_ggtt)
#define i915_is_dpt(vm) ((vm)->is_dpt)
+#define i915_is_ggtt_or_dpt(vm) (i915_is_ggtt(vm) || i915_is_dpt(vm))
int __must_check
i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww);
@@ -390,7 +391,7 @@ static inline struct i915_ppgtt *
i915_vm_to_ppgtt(struct i915_address_space *vm)
{
BUILD_BUG_ON(offsetof(struct i915_ppgtt, vm));
- GEM_BUG_ON(i915_is_ggtt(vm));
+ GEM_BUG_ON(i915_is_ggtt_or_dpt(vm));
return container_of(vm, struct i915_ppgtt, vm);
}
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index dda320749c65..33496397a74f 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -3342,9 +3342,9 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
MMIO_D(_MMIO(_PLANE_SURF_3_A), D_SKL_PLUS);
MMIO_D(_MMIO(_PLANE_SURF_3_B), D_SKL_PLUS);
- MMIO_D(CSR_SSP_BASE, D_SKL_PLUS);
- MMIO_D(CSR_HTP_SKL, D_SKL_PLUS);
- MMIO_D(CSR_LAST_WRITE, D_SKL_PLUS);
+ MMIO_D(DMC_SSP_BASE, D_SKL_PLUS);
+ MMIO_D(DMC_HTP_SKL, D_SKL_PLUS);
+ MMIO_D(DMC_LAST_WRITE, D_SKL_PLUS);
MMIO_DFH(BDW_SCRATCH1, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
@@ -3655,7 +3655,7 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt)
* otherwise, need to update cmd_reg_handler in cmd_parser.c
*/
static struct gvt_mmio_block mmio_blocks[] = {
- {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
+ {D_SKL_PLUS, _MMIO(DMC_MMIO_START_RANGE), 0x3000, NULL, NULL},
{D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
{D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
pvinfo_mmio_read, pvinfo_mmio_write},
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b654b7498bcd..bb42ecc47ed0 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -124,6 +124,17 @@ stringify_page_sizes(unsigned int page_sizes, char *buf, size_t len)
}
}
+static const char *stringify_vma_type(const struct i915_vma *vma)
+{
+ if (i915_vma_is_ggtt(vma))
+ return "ggtt";
+
+ if (i915_vma_is_dpt(vma))
+ return "dpt";
+
+ return "ppgtt";
+}
+
void
i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
@@ -156,11 +167,11 @@ i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
if (i915_vma_is_pinned(vma))
pin_count++;
- seq_printf(m, " (%sgtt offset: %08llx, size: %08llx, pages: %s",
- i915_vma_is_ggtt(vma) ? "g" : "pp",
+ seq_printf(m, " (%s offset: %08llx, size: %08llx, pages: %s",
+ stringify_vma_type(vma),
vma->node.start, vma->node.size,
stringify_page_sizes(vma->page_sizes.gtt, NULL, 0));
- if (i915_vma_is_ggtt(vma)) {
+ if (i915_vma_is_ggtt(vma) || i915_vma_is_dpt(vma)) {
switch (vma->ggtt_view.type) {
case I915_GGTT_VIEW_NORMAL:
seq_puts(m, ", normal");
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index db513f93f0f5..22688ed4b1c3 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -49,7 +49,7 @@
#include "display/intel_acpi.h"
#include "display/intel_bw.h"
#include "display/intel_cdclk.h"
-#include "display/intel_csr.h"
+#include "display/intel_dmc.h"
#include "display/intel_display_types.h"
#include "display/intel_dp.h"
#include "display/intel_fbdev.h"
@@ -1043,7 +1043,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
intel_suspend_encoders(i915);
intel_shutdown_encoders(i915);
- intel_csr_ucode_suspend(i915);
+ intel_dmc_ucode_suspend(i915);
/*
* The only requirement is to reboot with display DC states disabled,
@@ -1124,7 +1124,7 @@ static int i915_drm_suspend(struct drm_device *dev)
dev_priv->suspend_count++;
- intel_csr_ucode_suspend(dev_priv);
+ intel_dmc_ucode_suspend(dev_priv);
enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
@@ -1226,7 +1226,7 @@ static int i915_drm_resume(struct drm_device *dev)
i915_ggtt_resume(&dev_priv->ggtt);
- intel_csr_ucode_resume(dev_priv);
+ intel_dmc_ucode_resume(dev_priv);
i915_restore_display(dev_priv);
intel_pps_unlock_regs_wa(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 374372773b48..a5441bfb654b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -328,7 +328,7 @@ struct drm_i915_display_funcs {
void (*read_luts)(struct intel_crtc_state *crtc_state);
};
-struct intel_csr {
+struct intel_dmc {
struct work_struct work;
const char *fw_path;
u32 required_version;
@@ -582,6 +582,8 @@ i915_fence_timeout(const struct drm_i915_private *i915)
/* Amount of SAGV/QGV points, BSpec precisely defines this */
#define I915_NUM_QGV_POINTS 8
+#define HAS_HW_SAGV_WM(i915) (DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))
+
struct ddi_vbt_port_info {
/* Non-NULL if port present. */
struct intel_bios_encoder_data *devdata;
@@ -817,7 +819,7 @@ struct drm_i915_private {
struct intel_wopcm wopcm;
- struct intel_csr csr;
+ struct intel_dmc dmc;
struct intel_gmbus gmbus[GMBUS_NUM_PINS];
@@ -1655,7 +1657,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define HAS_RPS(dev_priv) (INTEL_INFO(dev_priv)->has_rps)
-#define HAS_CSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_csr)
+#define HAS_DMC(dev_priv) (INTEL_INFO(dev_priv)->display.has_dmc)
#define HAS_MSO(i915) (INTEL_GEN(i915) >= 12)
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 99ca242ec13b..8b964e355cb5 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -36,7 +36,7 @@
#include <drm/drm_print.h>
-#include "display/intel_csr.h"
+#include "display/intel_dmc.h"
#include "display/intel_overlay.h"
#include "gem/i915_gem_context.h"
@@ -788,14 +788,14 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
- if (HAS_CSR(m->i915)) {
- struct intel_csr *csr = &m->i915->csr;
+ if (HAS_DMC(m->i915)) {
+ struct intel_dmc *dmc = &m->i915->dmc;
err_printf(m, "DMC loaded: %s\n",
- yesno(csr->dmc_payload != NULL));
+ yesno(dmc->dmc_payload));
err_printf(m, "DMC fw version: %d.%d\n",
- CSR_VERSION_MAJOR(csr->version),
- CSR_VERSION_MINOR(csr->version));
+ DMC_VERSION_MAJOR(dmc->version),
+ DMC_VERSION_MINOR(dmc->version));
}
err_printf(m, "RPM wakelock: %s\n", yesno(error->wakelock));
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 1680062a2149..600cadd3a1c9 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -643,7 +643,7 @@ static const struct intel_device_info chv_info = {
GEN8_FEATURES, \
GEN(9), \
GEN9_DEFAULT_PAGE_SIZES, \
- .display.has_csr = 1, \
+ .display.has_dmc = 1, \
.has_gt_uc = 1, \
.display.has_hdcp = 1, \
.display.has_ipc = 1, \
@@ -698,7 +698,7 @@ static const struct intel_device_info skl_gt4_info = {
.display.has_psr = 1, \
.display.has_psr_hw_tracking = 1, \
.has_runtime_pm = 1, \
- .display.has_csr = 1, \
+ .display.has_dmc = 1, \
.has_rc6 = 1, \
.has_rps = true, \
.display.has_dp_mst = 1, \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 07cca3b423bc..d4debb3ec485 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2929,6 +2929,15 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define MBUS_BBOX_CTL_S1 _MMIO(0x45040)
#define MBUS_BBOX_CTL_S2 _MMIO(0x45044)
+#define MBUS_CTL _MMIO(0x4438C)
+#define MBUS_JOIN REG_BIT(31)
+#define MBUS_HASHING_MODE_MASK REG_BIT(30)
+#define MBUS_HASHING_MODE_2x2 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
+#define MBUS_HASHING_MODE_1x4 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
+#define MBUS_JOIN_PIPE_SELECT_MASK REG_GENMASK(28, 26)
+#define MBUS_JOIN_PIPE_SELECT(pipe) REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
+#define MBUS_JOIN_PIPE_SELECT_NONE MBUS_JOIN_PIPE_SELECT(7)
+
#define HDPORT_STATE _MMIO(0x45050)
#define HDPORT_DPLL_USED_MASK REG_GENMASK(15, 12)
#define HDPORT_DDI_USED(phy) REG_BIT(2 * (phy) + 1)
@@ -6146,6 +6155,13 @@ enum {
#define PIPEMISC_DITHER_TYPE_SP (0 << 2)
#define PIPEMISC(pipe) _MMIO_PIPE2(pipe, _PIPE_MISC_A)
+#define _PIPE_MISC2_A 0x7002C
+#define _PIPE_MISC2_B 0x7102C
+#define PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN (0x50 << 24)
+#define PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS (0x14 << 24)
+#define PIPE_MISC2_UNDERRUN_BUBBLE_COUNTER_MASK (0xff << 24)
+#define PIPE_MISC2(pipe) _MMIO_PIPE2(pipe, _PIPE_MISC2_A)
+
/* Skylake+ pipe bottom (background) color */
#define _SKL_BOTTOM_COLOR_A 0x70034
#define SKL_BOTTOM_COLOR_GAMMA_ENABLE (1 << 31)
@@ -6420,16 +6436,28 @@ enum {
/* Watermark register definitions for SKL */
#define _CUR_WM_A_0 0x70140
#define _CUR_WM_B_0 0x71140
+#define _CUR_WM_SAGV_A 0x70158
+#define _CUR_WM_SAGV_B 0x71158
+#define _CUR_WM_SAGV_TRANS_A 0x7015C
+#define _CUR_WM_SAGV_TRANS_B 0x7115C
+#define _CUR_WM_TRANS_A 0x70168
+#define _CUR_WM_TRANS_B 0x71168
#define _PLANE_WM_1_A_0 0x70240
#define _PLANE_WM_1_B_0 0x71240
#define _PLANE_WM_2_A_0 0x70340
#define _PLANE_WM_2_B_0 0x71340
-#define _PLANE_WM_TRANS_1_A_0 0x70268
-#define _PLANE_WM_TRANS_1_B_0 0x71268
-#define _PLANE_WM_TRANS_2_A_0 0x70368
-#define _PLANE_WM_TRANS_2_B_0 0x71368
-#define _CUR_WM_TRANS_A_0 0x70168
-#define _CUR_WM_TRANS_B_0 0x71168
+#define _PLANE_WM_SAGV_1_A 0x70258
+#define _PLANE_WM_SAGV_1_B 0x71258
+#define _PLANE_WM_SAGV_2_A 0x70358
+#define _PLANE_WM_SAGV_2_B 0x71358
+#define _PLANE_WM_SAGV_TRANS_1_A 0x7025C
+#define _PLANE_WM_SAGV_TRANS_1_B 0x7125C
+#define _PLANE_WM_SAGV_TRANS_2_A 0x7035C
+#define _PLANE_WM_SAGV_TRANS_2_B 0x7135C
+#define _PLANE_WM_TRANS_1_A 0x70268
+#define _PLANE_WM_TRANS_1_B 0x71268
+#define _PLANE_WM_TRANS_2_A 0x70368
+#define _PLANE_WM_TRANS_2_B 0x71368
#define PLANE_WM_EN (1 << 31)
#define PLANE_WM_IGNORE_LINES (1 << 30)
#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
@@ -6437,19 +6465,32 @@ enum {
#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0)
#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level)))
-#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A_0, _CUR_WM_TRANS_B_0)
-
+#define CUR_WM_SAGV(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_A, _CUR_WM_SAGV_B)
+#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B)
+#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A, _CUR_WM_TRANS_B)
#define _PLANE_WM_1(pipe) _PIPE(pipe, _PLANE_WM_1_A_0, _PLANE_WM_1_B_0)
#define _PLANE_WM_2(pipe) _PIPE(pipe, _PLANE_WM_2_A_0, _PLANE_WM_2_B_0)
-#define _PLANE_WM_BASE(pipe, plane) \
- _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
-#define PLANE_WM(pipe, plane, level) \
- _MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
-#define _PLANE_WM_TRANS_1(pipe) \
- _PIPE(pipe, _PLANE_WM_TRANS_1_A_0, _PLANE_WM_TRANS_1_B_0)
-#define _PLANE_WM_TRANS_2(pipe) \
- _PIPE(pipe, _PLANE_WM_TRANS_2_A_0, _PLANE_WM_TRANS_2_B_0)
-#define PLANE_WM_TRANS(pipe, plane) \
+#define _PLANE_WM_BASE(pipe, plane) \
+ _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
+#define PLANE_WM(pipe, plane, level) \
+ _MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
+#define _PLANE_WM_SAGV_1(pipe) \
+ _PIPE(pipe, _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B)
+#define _PLANE_WM_SAGV_2(pipe) \
+ _PIPE(pipe, _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B)
+#define PLANE_WM_SAGV(pipe, plane) \
+ _MMIO(_PLANE(plane, _PLANE_WM_SAGV_1(pipe), _PLANE_WM_SAGV_2(pipe)))
+#define _PLANE_WM_SAGV_TRANS_1(pipe) \
+ _PIPE(pipe, _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B)
+#define _PLANE_WM_SAGV_TRANS_2(pipe) \
+ _PIPE(pipe, _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B)
+#define PLANE_WM_SAGV_TRANS(pipe, plane) \
+ _MMIO(_PLANE(plane, _PLANE_WM_SAGV_TRANS_1(pipe), _PLANE_WM_SAGV_TRANS_2(pipe)))
+#define _PLANE_WM_TRANS_1(pipe) \
+ _PIPE(pipe, _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B)
+#define _PLANE_WM_TRANS_2(pipe) \
+ _PIPE(pipe, _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B)
+#define PLANE_WM_TRANS(pipe, plane) \
_MMIO(_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe)))
/* define the Watermark register on Ironlake */
@@ -7268,7 +7309,7 @@ enum {
#define _PLANE_BUF_CFG_1_B 0x7127c
#define _PLANE_BUF_CFG_2_B 0x7137c
-#define DDB_ENTRY_MASK 0x7FF /* skl+: 10 bits, icl+ 11 bits */
+#define DDB_ENTRY_MASK 0xFFF /* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
#define DDB_ENTRY_END_SHIFT 16
#define _PLANE_BUF_CFG_1(pipe) \
_PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
@@ -7680,20 +7721,20 @@ enum {
#define GAMMA_MODE_MODE_SPLIT (3 << 0) /* ivb-bdw */
#define GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED (3 << 0) /* icl + */
-/* DMC/CSR */
-#define CSR_PROGRAM(i) _MMIO(0x80000 + (i) * 4)
-#define CSR_SSP_BASE_ADDR_GEN9 0x00002FC0
-#define CSR_HTP_ADDR_SKL 0x00500034
-#define CSR_SSP_BASE _MMIO(0x8F074)
-#define CSR_HTP_SKL _MMIO(0x8F004)
-#define CSR_LAST_WRITE _MMIO(0x8F034)
-#define CSR_LAST_WRITE_VALUE 0xc003b400
-/* MMIO address range for CSR program (0x80000 - 0x82FFF) */
-#define CSR_MMIO_START_RANGE 0x80000
-#define CSR_MMIO_END_RANGE 0x8FFFF
-#define SKL_CSR_DC3_DC5_COUNT _MMIO(0x80030)
-#define SKL_CSR_DC5_DC6_COUNT _MMIO(0x8002C)
-#define BXT_CSR_DC3_DC5_COUNT _MMIO(0x80038)
+/* DMC */
+#define DMC_PROGRAM(i) _MMIO(0x80000 + (i) * 4)
+#define DMC_SSP_BASE_ADDR_GEN9 0x00002FC0
+#define DMC_HTP_ADDR_SKL 0x00500034
+#define DMC_SSP_BASE _MMIO(0x8F074)
+#define DMC_HTP_SKL _MMIO(0x8F004)
+#define DMC_LAST_WRITE _MMIO(0x8F034)
+#define DMC_LAST_WRITE_VALUE 0xc003b400
+/* MMIO address range for DMC program (0x80000 - 0x82FFF) */
+#define DMC_MMIO_START_RANGE 0x80000
+#define DMC_MMIO_END_RANGE 0x8FFFF
+#define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030)
+#define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C)
+#define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038)
#define TGL_DMC_DEBUG_DC5_COUNT _MMIO(0x101084)
#define TGL_DMC_DEBUG_DC6_COUNT _MMIO(0x101088)
#define DG1_DMC_DEBUG_DC5_COUNT _MMIO(0x134154)
@@ -8103,13 +8144,29 @@ enum {
#define DISP_DATA_PARTITION_5_6 (1 << 6)
#define DISP_IPC_ENABLE (1 << 3)
-#define _DBUF_CTL_S1 0x45008
-#define _DBUF_CTL_S2 0x44FE8
-#define DBUF_CTL_S(slice) _MMIO(_PICK_EVEN(slice, _DBUF_CTL_S1, _DBUF_CTL_S2))
+/*
+ * The below are numbered starting from "S1" on gen11/gen12, but starting
+ * with gen13 display, the bspec switches to a 0-based numbering scheme
+ * (although the addresses stay the same so new S0 = old S1, new S1 = old S2).
+ * We'll just use the 0-based numbering here for all platforms since it's the
+ * way things will be named by the hardware team going forward, plus it's more
+ * consistent with how most of the rest of our registers are named.
+ */
+#define _DBUF_CTL_S0 0x45008
+#define _DBUF_CTL_S1 0x44FE8
+#define _DBUF_CTL_S2 0x44300
+#define _DBUF_CTL_S3 0x44304
+#define DBUF_CTL_S(slice) _MMIO(_PICK(slice, \
+ _DBUF_CTL_S0, \
+ _DBUF_CTL_S1, \
+ _DBUF_CTL_S2, \
+ _DBUF_CTL_S3))
#define DBUF_POWER_REQUEST REG_BIT(31)
#define DBUF_POWER_STATE REG_BIT(30)
#define DBUF_TRACKER_STATE_SERVICE_MASK REG_GENMASK(23, 19)
#define DBUF_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
+#define DBUF_MIN_TRACKER_STATE_SERVICE_MASK REG_GENMASK(18, 16) /* ADL-P+ */
+#define DBUF_MIN_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */
#define GEN7_MSG_CTL _MMIO(0x45010)
#define WAIT_FOR_PCH_RESET_ACK (1 << 1)
@@ -10116,8 +10173,10 @@ enum skl_power_gate {
#define DDI_BUF_CTL_ENABLE (1 << 31)
#define DDI_BUF_TRANS_SELECT(n) ((n) << 24)
#define DDI_BUF_EMP_MASK (0xf << 24)
+#define DDI_BUF_PHY_LINK_RATE(r) ((r) << 20)
#define DDI_BUF_PORT_REVERSAL (1 << 16)
#define DDI_BUF_IS_IDLE (1 << 7)
+#define DDI_BUF_CTL_TC_PHY_OWNERSHIP REG_BIT(6)
#define DDI_A_4_LANES (1 << 4)
#define DDI_PORT_WIDTH(width) (((width) - 1) << 1)
#define DDI_PORT_WIDTH_MASK (7 << 1)
@@ -10480,6 +10539,14 @@ enum skl_power_gate {
#define DG1_DPLL_ENABLE(pll) _MMIO_PLL3(pll, DPLL0_ENABLE, DPLL1_ENABLE, \
_MG_PLL1_ENABLE, _MG_PLL2_ENABLE)
+/* ADL-P Type C PLL */
+#define PORTTC1_PLL_ENABLE 0x46038
+#define PORTTC2_PLL_ENABLE 0x46040
+
+#define ADLP_PORTTC_PLL_ENABLE(tc_port) _MMIO_PORT((tc_port), \
+ PORTTC1_PLL_ENABLE, \
+ PORTTC2_PLL_ENABLE)
+
#define _MG_REFCLKIN_CTL_PORT1 0x16892C
#define _MG_REFCLKIN_CTL_PORT2 0x16992C
#define _MG_REFCLKIN_CTL_PORT3 0x16A92C
@@ -11268,6 +11335,12 @@ enum skl_power_gate {
#define ICL_ESC_CLK_DIV_SHIFT 0
#define DSI_MAX_ESC_CLK 20000 /* in KHz */
+#define _ADL_MIPIO_REG 0x180
+#define ADL_MIPIO_DW(port, dw) _MMIO(_ICL_COMBOPHY(port) + _ADL_MIPIO_REG + 4 * (dw))
+#define TX_ESC_CLK_DIV_PHY_SEL REGBIT(16)
+#define TX_ESC_CLK_DIV_PHY_MASK REG_GENMASK(23, 16)
+#define TX_ESC_CLK_DIV_PHY REG_FIELD_PREP(TX_ESC_CLK_DIV_PHY_MASK, 0x7f)
+
#define _DSI_CMD_FRMCTL_0 0x6b034
#define _DSI_CMD_FRMCTL_1 0x6b834
#define DSI_CMD_FRMCTL(port) _MMIO_PORT(port, \
@@ -12553,6 +12626,15 @@ enum skl_power_gate {
#define DP_PIN_ASSIGNMENT_MASK(idx) (0xf << ((idx) * 4))
#define DP_PIN_ASSIGNMENT(idx, x) ((x) << ((idx) * 4))
+#define _TCSS_DDI_STATUS_1 0x161500
+#define _TCSS_DDI_STATUS_2 0x161504
+#define TCSS_DDI_STATUS(tc) _MMIO(_PICK_EVEN(tc, \
+ _TCSS_DDI_STATUS_1, \
+ _TCSS_DDI_STATUS_2))
+#define TCSS_DDI_STATUS_READY REG_BIT(2)
+#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT REG_BIT(1)
+#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT REG_BIT(0)
+
/* This register controls the Display State Buffer (DSB) engines. */
#define _DSBSL_INSTANCE_BASE 0x70B00
#define DSBSL_INSTANCE(pipe, id) (_DSBSL_INSTANCE_BASE + \
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 07490db51cdc..37a00992cec5 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -274,7 +274,7 @@ i915_vma_instance(struct drm_i915_gem_object *obj,
{
struct i915_vma *vma;
- GEM_BUG_ON(view && !i915_is_ggtt(vm));
+ GEM_BUG_ON(view && !i915_is_ggtt_or_dpt(vm));
GEM_BUG_ON(!atomic_read(&vm->open));
spin_lock(&obj->vma.lock);
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 8df784a026d2..dc6926d89626 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -68,6 +68,11 @@ static inline bool i915_vma_is_ggtt(const struct i915_vma *vma)
return test_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma));
}
+static inline bool i915_vma_is_dpt(const struct i915_vma *vma)
+{
+ return i915_is_dpt(vma->vm);
+}
+
static inline bool i915_vma_has_ggtt_write(const struct i915_vma *vma)
{
return test_bit(I915_VMA_GGTT_WRITE_BIT, __i915_vma_flags(vma));
@@ -158,7 +163,7 @@ i915_vma_compare(struct i915_vma *vma,
{
ptrdiff_t cmp;
- GEM_BUG_ON(view && !i915_is_ggtt(vm));
+ GEM_BUG_ON(view && !i915_is_ggtt_or_dpt(vm));
cmp = ptrdiff(vma->vm, vm);
if (cmp)
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 8cb58a238c68..e16599b67b83 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -353,7 +353,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
info->display.has_fbc = 0;
if (INTEL_GEN(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
- info->display.has_csr = 0;
+ info->display.has_dmc = 0;
if (INTEL_GEN(dev_priv) >= 10 &&
(dfsm & CNL_DFSM_DISPLAY_DSC_DISABLE))
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index e98b36959736..1390fad5ec06 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -141,7 +141,7 @@ enum intel_ppgtt_type {
#define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \
/* Keep in alphabetical order */ \
func(cursor_needs_physical); \
- func(has_csr); \
+ func(has_dmc); \
func(has_ddi); \
func(has_dp_mst); \
func(has_dsb); \
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 15d9a64e7b4c..00f3dead20ad 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2983,7 +2983,9 @@ static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv,
int ilk_wm_max_level(const struct drm_i915_private *dev_priv)
{
/* how many WM levels are we expecting */
- if (DISPLAY_VER(dev_priv) >= 9)
+ if (HAS_HW_SAGV_WM(dev_priv))
+ return 5;
+ else if (DISPLAY_VER(dev_priv) >= 9)
return 7;
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
return 4;
@@ -4011,8 +4013,9 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
* latter from the plane commit hooks (especially in the legacy
* cursor case)
*/
- pipe_wm->use_sagv_wm = DISPLAY_VER(dev_priv) >= 12 &&
- intel_can_enable_sagv(dev_priv, new_bw_state);
+ pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(dev_priv) &&
+ DISPLAY_VER(dev_priv) >= 12 &&
+ intel_can_enable_sagv(dev_priv, new_bw_state);
}
if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
@@ -4054,6 +4057,20 @@ skl_ddb_entry_for_slices(struct drm_i915_private *dev_priv, u8 slice_mask,
WARN_ON(ddb->end > INTEL_INFO(dev_priv)->dbuf.size);
}
+static unsigned int mbus_ddb_offset(struct drm_i915_private *i915, u8 slice_mask)
+{
+ struct skl_ddb_entry ddb;
+
+ if (slice_mask & (BIT(DBUF_S1) | BIT(DBUF_S2)))
+ slice_mask = BIT(DBUF_S1);
+ else if (slice_mask & (BIT(DBUF_S3) | BIT(DBUF_S4)))
+ slice_mask = BIT(DBUF_S3);
+
+ skl_ddb_entry_for_slices(i915, slice_mask, &ddb);
+
+ return ddb.start;
+}
+
u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *dev_priv,
const struct skl_ddb_entry *entry)
{
@@ -4146,6 +4163,7 @@ skl_crtc_allocate_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc)
struct intel_crtc_state *crtc_state;
struct skl_ddb_entry ddb_slices;
enum pipe pipe = crtc->pipe;
+ unsigned int mbus_offset;
u32 ddb_range_size;
u32 dbuf_slice_mask;
u32 start, end;
@@ -4160,6 +4178,7 @@ skl_crtc_allocate_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc)
dbuf_slice_mask = new_dbuf_state->slices[pipe];
skl_ddb_entry_for_slices(dev_priv, dbuf_slice_mask, &ddb_slices);
+ mbus_offset = mbus_ddb_offset(dev_priv, dbuf_slice_mask);
ddb_range_size = skl_ddb_entry_size(&ddb_slices);
intel_crtc_dbuf_weights(new_dbuf_state, pipe,
@@ -4168,11 +4187,11 @@ skl_crtc_allocate_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc)
start = ddb_range_size * weight_start / weight_total;
end = ddb_range_size * weight_end / weight_total;
- new_dbuf_state->ddb[pipe].start = ddb_slices.start + start;
- new_dbuf_state->ddb[pipe].end = ddb_slices.start + end;
-
+ new_dbuf_state->ddb[pipe].start = ddb_slices.start - mbus_offset + start;
+ new_dbuf_state->ddb[pipe].end = ddb_slices.start - mbus_offset + end;
out:
- if (skl_ddb_entry_equal(&old_dbuf_state->ddb[pipe],
+ if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe] &&
+ skl_ddb_entry_equal(&old_dbuf_state->ddb[pipe],
&new_dbuf_state->ddb[pipe]))
return 0;
@@ -4184,7 +4203,12 @@ out:
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
- crtc_state->wm.skl.ddb = new_dbuf_state->ddb[pipe];
+ /*
+ * Used for checking overlaps, so we need absolute
+ * offsets instead of MBUS relative offsets.
+ */
+ crtc_state->wm.skl.ddb.start = mbus_offset + new_dbuf_state->ddb[pipe].start;
+ crtc_state->wm.skl.ddb.end = mbus_offset + new_dbuf_state->ddb[pipe].end;
drm_dbg_kms(&dev_priv->drm,
"[CRTC:%d:%s] dbuf slices 0x%x -> 0x%x, ddb (%d - %d) -> (%d - %d), active pipes 0x%x -> 0x%x\n",
@@ -4242,7 +4266,6 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
static void skl_ddb_entry_init_from_hw(struct drm_i915_private *dev_priv,
struct skl_ddb_entry *entry, u32 reg)
{
-
entry->start = reg & DDB_ENTRY_MASK;
entry->end = (reg >> DDB_ENTRY_END_SHIFT) & DDB_ENTRY_MASK;
@@ -4367,6 +4390,7 @@ skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state,
struct dbuf_slice_conf_entry {
u8 active_pipes;
u8 dbuf_mask[I915_MAX_PIPES];
+ bool join_mbus;
};
/*
@@ -4555,6 +4579,137 @@ static const struct dbuf_slice_conf_entry tgl_allowed_dbufs[] =
{}
};
+static const struct dbuf_slice_conf_entry adlp_allowed_dbufs[] = {
+ {
+ .active_pipes = BIT(PIPE_A),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ .join_mbus = true,
+ },
+ {
+ .active_pipes = BIT(PIPE_B),
+ .dbuf_mask = {
+ [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ .join_mbus = true,
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_B),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_C),
+ .dbuf_mask = {
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_C),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_B) | BIT(PIPE_C),
+ .dbuf_mask = {
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_B) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_C) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_C) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {
+ .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
+ .dbuf_mask = {
+ [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ [PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_C] = BIT(DBUF_S3) | BIT(DBUF_S4),
+ [PIPE_D] = BIT(DBUF_S1) | BIT(DBUF_S2),
+ },
+ },
+ {}
+
+};
+
+static bool check_mbus_joined(u8 active_pipes,
+ const struct dbuf_slice_conf_entry *dbuf_slices)
+{
+ int i;
+
+ for (i = 0; i < dbuf_slices[i].active_pipes; i++) {
+ if (dbuf_slices[i].active_pipes == active_pipes)
+ return dbuf_slices[i].join_mbus;
+ }
+ return false;
+}
+
+static bool adlp_check_mbus_joined(u8 active_pipes)
+{
+ return check_mbus_joined(active_pipes, adlp_allowed_dbufs);
+}
+
static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes,
const struct dbuf_slice_conf_entry *dbuf_slices)
{
@@ -4594,12 +4749,19 @@ static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes)
return compute_dbuf_slices(pipe, active_pipes, tgl_allowed_dbufs);
}
+static u32 adlp_compute_dbuf_slices(enum pipe pipe, u32 active_pipes)
+{
+ return compute_dbuf_slices(pipe, active_pipes, adlp_allowed_dbufs);
+}
+
static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- if (DISPLAY_VER(dev_priv) == 12)
+ if (IS_ALDERLAKE_P(dev_priv))
+ return adlp_compute_dbuf_slices(pipe, active_pipes);
+ else if (DISPLAY_VER(dev_priv) == 12)
return tgl_compute_dbuf_slices(pipe, active_pipes);
else if (DISPLAY_VER(dev_priv) == 11)
return icl_compute_dbuf_slices(pipe, active_pipes);
@@ -5619,6 +5781,13 @@ void skl_write_plane_wm(struct intel_plane *plane,
skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id),
skl_plane_trans_wm(pipe_wm, plane_id));
+ if (HAS_HW_SAGV_WM(dev_priv)) {
+ skl_write_wm_level(dev_priv, PLANE_WM_SAGV(pipe, plane_id),
+ &wm->sagv.wm0);
+ skl_write_wm_level(dev_priv, PLANE_WM_SAGV_TRANS(pipe, plane_id),
+ &wm->sagv.trans_wm);
+ }
+
if (DISPLAY_VER(dev_priv) >= 11) {
skl_ddb_entry_write(dev_priv,
PLANE_BUF_CFG(pipe, plane_id), ddb_y);
@@ -5652,6 +5821,15 @@ void skl_write_cursor_wm(struct intel_plane *plane,
skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe),
skl_plane_trans_wm(pipe_wm, plane_id));
+ if (HAS_HW_SAGV_WM(dev_priv)) {
+ const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+
+ skl_write_wm_level(dev_priv, CUR_WM_SAGV(pipe),
+ &wm->sagv.wm0);
+ skl_write_wm_level(dev_priv, CUR_WM_SAGV_TRANS(pipe),
+ &wm->sagv.trans_wm);
+ }
+
skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb);
}
@@ -5813,16 +5991,29 @@ skl_compute_ddb(struct intel_atomic_state *state)
new_dbuf_state->enabled_slices = intel_dbuf_enabled_slices(new_dbuf_state);
- if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices) {
+ if (IS_ALDERLAKE_P(dev_priv))
+ new_dbuf_state->joined_mbus = adlp_check_mbus_joined(new_dbuf_state->active_pipes);
+
+ if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices ||
+ old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
ret = intel_atomic_serialize_global_state(&new_dbuf_state->base);
if (ret)
return ret;
+ if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
+ /* TODO: Implement vblank synchronized MBUS joining changes */
+ ret = intel_modeset_all_pipes(state);
+ if (ret)
+ return ret;
+ }
+
drm_dbg_kms(&dev_priv->drm,
- "Enabled dbuf slices 0x%x -> 0x%x (total dbuf slices 0x%x)\n",
+ "Enabled dbuf slices 0x%x -> 0x%x (total dbuf slices 0x%x), mbus joined? %s->%s\n",
old_dbuf_state->enabled_slices,
new_dbuf_state->enabled_slices,
- INTEL_INFO(dev_priv)->dbuf.slice_mask);
+ INTEL_INFO(dev_priv)->dbuf.slice_mask,
+ yesno(old_dbuf_state->joined_mbus),
+ yesno(new_dbuf_state->joined_mbus));
}
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
@@ -6016,6 +6207,15 @@ static bool skl_plane_selected_wm_equals(struct intel_plane *plane,
return false;
}
+ if (HAS_HW_SAGV_WM(i915)) {
+ const struct skl_plane_wm *old_wm = &old_pipe_wm->planes[plane->id];
+ const struct skl_plane_wm *new_wm = &new_pipe_wm->planes[plane->id];
+
+ if (!skl_wm_level_equals(&old_wm->sagv.wm0, &new_wm->sagv.wm0) ||
+ !skl_wm_level_equals(&old_wm->sagv.trans_wm, &new_wm->sagv.trans_wm))
+ return false;
+ }
+
return skl_wm_level_equals(skl_plane_trans_wm(old_pipe_wm, plane->id),
skl_plane_trans_wm(new_pipe_wm, plane->id));
}
@@ -6234,7 +6434,25 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
skl_wm_level_from_reg_val(val, &wm->trans_wm);
- if (DISPLAY_VER(dev_priv) >= 12) {
+ if (HAS_HW_SAGV_WM(dev_priv)) {
+ if (plane_id != PLANE_CURSOR)
+ val = intel_uncore_read(&dev_priv->uncore,
+ PLANE_WM_SAGV(pipe, plane_id));
+ else
+ val = intel_uncore_read(&dev_priv->uncore,
+ CUR_WM_SAGV(pipe));
+
+ skl_wm_level_from_reg_val(val, &wm->sagv.wm0);
+
+ if (plane_id != PLANE_CURSOR)
+ val = intel_uncore_read(&dev_priv->uncore,
+ PLANE_WM_SAGV_TRANS(pipe, plane_id));
+ else
+ val = intel_uncore_read(&dev_priv->uncore,
+ CUR_WM_SAGV_TRANS(pipe));
+
+ skl_wm_level_from_reg_val(val, &wm->sagv.trans_wm);
+ } else if (DISPLAY_VER(dev_priv) >= 12) {
wm->sagv.wm0 = wm->wm[0];
wm->sagv.trans_wm = wm->trans_wm;
}
@@ -6247,10 +6465,14 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
to_intel_dbuf_state(dev_priv->dbuf.obj.state);
struct intel_crtc *crtc;
+ if (IS_ALDERLAKE_P(dev_priv))
+ dbuf_state->joined_mbus = intel_de_read(dev_priv, MBUS_CTL) & MBUS_JOIN;
+
for_each_intel_crtc(&dev_priv->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
enum pipe pipe = crtc->pipe;
+ unsigned int mbus_offset;
enum plane_id plane_id;
skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
@@ -6276,13 +6498,20 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state);
- crtc_state->wm.skl.ddb = dbuf_state->ddb[pipe];
+ /*
+ * Used for checking overlaps, so we need absolute
+ * offsets instead of MBUS relative offsets.
+ */
+ mbus_offset = mbus_ddb_offset(dev_priv, dbuf_state->slices[pipe]);
+ crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start;
+ crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end;
drm_dbg_kms(&dev_priv->drm,
- "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x\n",
+ "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n",
crtc->base.base.id, crtc->base.name,
dbuf_state->slices[pipe], dbuf_state->ddb[pipe].start,
- dbuf_state->ddb[pipe].end, dbuf_state->active_pipes);
+ dbuf_state->ddb[pipe].end, dbuf_state->active_pipes,
+ yesno(dbuf_state->joined_mbus));
}
dbuf_state->enabled_slices = dev_priv->dbuf.enabled_slices;
@@ -7816,6 +8045,45 @@ int intel_dbuf_init(struct drm_i915_private *dev_priv)
return 0;
}
+/*
+ * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state before
+ * update the request state of all DBUS slices.
+ */
+static void update_mbus_pre_enable(struct intel_atomic_state *state)
+{
+ struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ u32 mbus_ctl, dbuf_min_tracker_val;
+ enum dbuf_slice slice;
+ const struct intel_dbuf_state *dbuf_state =
+ intel_atomic_get_new_dbuf_state(state);
+
+ if (!IS_ALDERLAKE_P(dev_priv))
+ return;
+
+ /*
+ * TODO: Implement vblank synchronized MBUS joining changes.
+ * Must be properly coordinated with dbuf reprogramming.
+ */
+ if (dbuf_state->joined_mbus) {
+ mbus_ctl = MBUS_HASHING_MODE_1x4 | MBUS_JOIN |
+ MBUS_JOIN_PIPE_SELECT_NONE;
+ dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(3);
+ } else {
+ mbus_ctl = MBUS_HASHING_MODE_2x2 |
+ MBUS_JOIN_PIPE_SELECT_NONE;
+ dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(1);
+ }
+
+ intel_de_rmw(dev_priv, MBUS_CTL,
+ MBUS_HASHING_MODE_MASK | MBUS_JOIN |
+ MBUS_JOIN_PIPE_SELECT_MASK, mbus_ctl);
+
+ for_each_dbuf_slice(dev_priv, slice)
+ intel_de_rmw(dev_priv, DBUF_CTL_S(slice),
+ DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
+ dbuf_min_tracker_val);
+}
+
void intel_dbuf_pre_plane_update(struct intel_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
@@ -7830,6 +8098,7 @@ void intel_dbuf_pre_plane_update(struct intel_atomic_state *state)
WARN_ON(!new_dbuf_state->base.changed);
+ update_mbus_pre_enable(state);
gen9_dbuf_slices_update(dev_priv,
old_dbuf_state->enabled_slices |
new_dbuf_state->enabled_slices);
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index 669c8d505677..91f23b7f0af2 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -78,13 +78,11 @@ struct intel_dbuf_state {
struct skl_ddb_entry ddb[I915_MAX_PIPES];
unsigned int weight[I915_MAX_PIPES];
u8 slices[I915_MAX_PIPES];
-
u8 enabled_slices;
u8 active_pipes;
+ bool joined_mbus;
};
-int intel_dbuf_init(struct drm_i915_private *dev_priv);
-
struct intel_dbuf_state *
intel_atomic_get_dbuf_state(struct intel_atomic_state *state);