aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r--drivers/gpu/drm/i915/display/g4x_dp.c18
-rw-r--r--drivers/gpu/drm/i915/display/g4x_hdmi.h2
-rw-r--r--drivers/gpu/drm/i915/display/hsw_ips.c271
-rw-r--r--drivers/gpu/drm/i915/display/hsw_ips.h26
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c105
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c21
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi_regs.h342
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c225
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h15
-rw-r--r--drivers/gpu/drm/i915/display/intel_backlight.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c221
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c181
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c67
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.h9
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c119
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy_regs.h162
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c25
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c176
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c42
-rw-r--r--drivers/gpu/drm/i915/display/intel_de.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c1468
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h47
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_trace.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h51
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c242
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c307
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c35
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c80
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h49
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_drrs.c115
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi_vbt.c40
-rw-r--r--drivers/gpu/drm/i915/display/intel_dvo_dev.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c241
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c25
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_fdi.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.c23
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c139
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.c144
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.c134
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.h10
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch_display.c88
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch_display.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane_initial.c7
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.c22
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c119
-rw-r--r--drivers/gpu/drm/i915/display/intel_sdvo.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy.c238
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy_regs.h75
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c65
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc_phy_regs.h280
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h34
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c54
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_vga.c9
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c195
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c34
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi_pll.c1
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi_pll_regs.h109
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi_regs.h480
91 files changed, 4750 insertions, 2527 deletions
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index f37677df6ebf..f67bbaaad8e0 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -18,6 +18,7 @@
#include "intel_fifo_underrun.h"
#include "intel_hdmi.h"
#include "intel_hotplug.h"
+#include "intel_pch_display.h"
#include "intel_pps.h"
#include "vlv_sideband.h"
@@ -333,6 +334,21 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
return ret;
}
+static void g4x_dp_get_m_n(struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ if (crtc_state->has_pch_encoder) {
+ intel_pch_transcoder_get_m1_n1(crtc, &crtc_state->dp_m_n);
+ intel_pch_transcoder_get_m2_n2(crtc, &crtc_state->dp_m2_n2);
+ } else {
+ intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
+ &crtc_state->dp_m_n);
+ intel_cpu_transcoder_get_m2_n2(crtc, crtc_state->cpu_transcoder,
+ &crtc_state->dp_m2_n2);
+ }
+}
+
static void intel_dp_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
@@ -384,7 +400,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
pipe_config->lane_count =
((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
- intel_dp_get_m_n(crtc, pipe_config);
+ g4x_dp_get_m_n(pipe_config);
if (port == PORT_A) {
if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)
diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.h b/drivers/gpu/drm/i915/display/g4x_hdmi.h
index 7aca14b602c6..db9a93bc9321 100644
--- a/drivers/gpu/drm/i915/display/g4x_hdmi.h
+++ b/drivers/gpu/drm/i915/display/g4x_hdmi.h
@@ -8,7 +8,7 @@
#include <linux/types.h>
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
enum port;
struct drm_i915_private;
diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c
new file mode 100644
index 000000000000..38014e0cc9ad
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/hsw_ips.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include "hsw_ips.h"
+#include "i915_drv.h"
+#include "i915_reg.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_pcode.h"
+
+static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+
+ if (!crtc_state->ips_enabled)
+ return;
+
+ /*
+ * We can only enable IPS after we enable a plane and wait for a vblank
+ * This function is called from post_plane_update, which is run after
+ * a vblank wait.
+ */
+ drm_WARN_ON(&i915->drm,
+ !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
+
+ if (IS_BROADWELL(i915)) {
+ drm_WARN_ON(&i915->drm,
+ snb_pcode_write(i915, DISPLAY_IPS_CONTROL,
+ IPS_ENABLE | IPS_PCODE_CONTROL));
+ /*
+ * Quoting Art Runyan: "its not safe to expect any particular
+ * value in IPS_CTL bit 31 after enabling IPS through the
+ * mailbox." Moreover, the mailbox may return a bogus state,
+ * so we need to just enable it and continue on.
+ */
+ } else {
+ intel_de_write(i915, IPS_CTL, IPS_ENABLE);
+ /*
+ * The bit only becomes 1 in the next vblank, so this wait here
+ * is essentially intel_wait_for_vblank. If we don't have this
+ * and don't wait for vblanks until the end of crtc_enable, then
+ * the HW state readout code will complain that the expected
+ * IPS_CTL value is not the one we read.
+ */
+ if (intel_de_wait_for_set(i915, IPS_CTL, IPS_ENABLE, 50))
+ drm_err(&i915->drm,
+ "Timed out waiting for IPS enable\n");
+ }
+}
+
+bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ bool need_vblank_wait = false;
+
+ if (!crtc_state->ips_enabled)
+ return need_vblank_wait;
+
+ if (IS_BROADWELL(i915)) {
+ drm_WARN_ON(&i915->drm,
+ snb_pcode_write(i915, DISPLAY_IPS_CONTROL, 0));
+ /*
+ * Wait for PCODE to finish disabling IPS. The BSpec specified
+ * 42ms timeout value leads to occasional timeouts so use 100ms
+ * instead.
+ */
+ if (intel_de_wait_for_clear(i915, IPS_CTL, IPS_ENABLE, 100))
+ drm_err(&i915->drm,
+ "Timed out waiting for IPS disable\n");
+ } else {
+ intel_de_write(i915, IPS_CTL, 0);
+ intel_de_posting_read(i915, IPS_CTL);
+ }
+
+ /* We need to wait for a vblank before we can disable the plane. */
+ need_vblank_wait = true;
+
+ return need_vblank_wait;
+}
+
+static bool hsw_ips_need_disable(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ if (!old_crtc_state->ips_enabled)
+ return false;
+
+ if (intel_crtc_needs_modeset(new_crtc_state))
+ return true;
+
+ /*
+ * Workaround : Do not read or write the pipe palette/gamma data while
+ * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+ *
+ * Disable IPS before we program the LUT.
+ */
+ if (IS_HASWELL(i915) &&
+ (new_crtc_state->uapi.color_mgmt_changed ||
+ new_crtc_state->update_pipe) &&
+ new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
+ return true;
+
+ return !new_crtc_state->ips_enabled;
+}
+
+bool hsw_ips_pre_update(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+
+ if (!hsw_ips_need_disable(state, crtc))
+ return false;
+
+ return hsw_ips_disable(old_crtc_state);
+}
+
+static bool hsw_ips_need_enable(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ if (!new_crtc_state->ips_enabled)
+ return false;
+
+ if (intel_crtc_needs_modeset(new_crtc_state))
+ return true;
+
+ /*
+ * Workaround : Do not read or write the pipe palette/gamma data while
+ * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+ *
+ * Re-enable IPS after the LUT has been programmed.
+ */
+ if (IS_HASWELL(i915) &&
+ (new_crtc_state->uapi.color_mgmt_changed ||
+ new_crtc_state->update_pipe) &&
+ new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
+ return true;
+
+ /*
+ * We can't read out IPS on broadwell, assume the worst and
+ * forcibly enable IPS on the first fastset.
+ */
+ if (new_crtc_state->update_pipe && old_crtc_state->inherited)
+ return true;
+
+ return !old_crtc_state->ips_enabled;
+}
+
+void hsw_ips_post_update(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ if (!hsw_ips_need_enable(state, crtc))
+ return;
+
+ hsw_ips_enable(new_crtc_state);
+}
+
+/* IPS only exists on ULT machines and is tied to pipe A. */
+bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
+{
+ return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
+}
+
+bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+
+ /* IPS only exists on ULT machines and is tied to pipe A. */
+ if (!hsw_crtc_supports_ips(crtc))
+ return false;
+
+ if (!i915->params.enable_ips)
+ return false;
+
+ if (crtc_state->pipe_bpp > 24)
+ return false;
+
+ /*
+ * We compare against max which means we must take
+ * the increased cdclk requirement into account when
+ * calculating the new cdclk.
+ *
+ * Should measure whether using a lower cdclk w/o IPS
+ */
+ if (IS_BROADWELL(i915) &&
+ crtc_state->pixel_rate > i915->max_cdclk_freq * 95 / 100)
+ return false;
+
+ return true;
+}
+
+int hsw_ips_compute_config(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ crtc_state->ips_enabled = false;
+
+ if (!hsw_crtc_state_ips_capable(crtc_state))
+ return 0;
+
+ /*
+ * When IPS gets enabled, the pipe CRC changes. Since IPS gets
+ * enabled and disabled dynamically based on package C states,
+ * user space can't make reliable use of the CRCs, so let's just
+ * completely disable it.
+ */
+ if (crtc_state->crc_enabled)
+ return 0;
+
+ /* IPS should be fine as long as at least one plane is enabled. */
+ if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
+ return 0;
+
+ if (IS_BROADWELL(i915)) {
+ const struct intel_cdclk_state *cdclk_state;
+
+ cdclk_state = intel_atomic_get_cdclk_state(state);
+ if (IS_ERR(cdclk_state))
+ return PTR_ERR(cdclk_state);
+
+ /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
+ if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100)
+ return 0;
+ }
+
+ crtc_state->ips_enabled = true;
+
+ return 0;
+}
+
+void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+
+ if (!hsw_crtc_supports_ips(crtc))
+ return;
+
+ if (IS_HASWELL(i915)) {
+ crtc_state->ips_enabled = intel_de_read(i915, IPS_CTL) & IPS_ENABLE;
+ } else {
+ /*
+ * We cannot readout IPS state on broadwell, set to
+ * true so we can set it to a defined state on first
+ * commit.
+ */
+ crtc_state->ips_enabled = true;
+ }
+}
diff --git a/drivers/gpu/drm/i915/display/hsw_ips.h b/drivers/gpu/drm/i915/display/hsw_ips.h
new file mode 100644
index 000000000000..4564dee497d7
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/hsw_ips.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __HSW_IPS_H__
+#define __HSW_IPS_H__
+
+#include <linux/types.h>
+
+struct intel_atomic_state;
+struct intel_crtc;
+struct intel_crtc_state;
+
+bool hsw_ips_disable(const struct intel_crtc_state *crtc_state);
+bool hsw_ips_pre_update(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+void hsw_ips_post_update(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+bool hsw_crtc_supports_ips(struct intel_crtc *crtc);
+bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state);
+int hsw_ips_compute_config(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+void hsw_ips_get_config(struct intel_crtc_state *crtc_state);
+
+#endif /* __HSW_IPS_H__ */
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 85950ff67609..a87b65cd41fd 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -125,7 +125,7 @@ static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
if (i9xx_plane_has_fbc(dev_priv, i9xx_plane))
- return dev_priv->fbc;
+ return dev_priv->fbc[INTEL_FBC_A];
else
return NULL;
}
@@ -155,51 +155,51 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
unsigned int rotation = plane_state->hw.rotation;
u32 dspcntr;
- dspcntr = DISPLAY_PLANE_ENABLE;
+ dspcntr = DISP_ENABLE;
if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
- dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+ dspcntr |= DISP_TRICKLE_FEED_DISABLE;
switch (fb->format->format) {
case DRM_FORMAT_C8:
- dspcntr |= DISPPLANE_8BPP;
+ dspcntr |= DISP_FORMAT_8BPP;
break;
case DRM_FORMAT_XRGB1555:
- dspcntr |= DISPPLANE_BGRX555;
+ dspcntr |= DISP_FORMAT_BGRX555;
break;
case DRM_FORMAT_ARGB1555:
- dspcntr |= DISPPLANE_BGRA555;
+ dspcntr |= DISP_FORMAT_BGRA555;
break;
case DRM_FORMAT_RGB565:
- dspcntr |= DISPPLANE_BGRX565;
+ dspcntr |= DISP_FORMAT_BGRX565;
break;
case DRM_FORMAT_XRGB8888:
- dspcntr |= DISPPLANE_BGRX888;
+ dspcntr |= DISP_FORMAT_BGRX888;
break;
case DRM_FORMAT_XBGR8888:
- dspcntr |= DISPPLANE_RGBX888;
+ dspcntr |= DISP_FORMAT_RGBX888;
break;
case DRM_FORMAT_ARGB8888:
- dspcntr |= DISPPLANE_BGRA888;
+ dspcntr |= DISP_FORMAT_BGRA888;
break;
case DRM_FORMAT_ABGR8888:
- dspcntr |= DISPPLANE_RGBA888;
+ dspcntr |= DISP_FORMAT_RGBA888;
break;
case DRM_FORMAT_XRGB2101010:
- dspcntr |= DISPPLANE_BGRX101010;
+ dspcntr |= DISP_FORMAT_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
- dspcntr |= DISPPLANE_RGBX101010;
+ dspcntr |= DISP_FORMAT_RGBX101010;
break;
case DRM_FORMAT_ARGB2101010:
- dspcntr |= DISPPLANE_BGRA101010;
+ dspcntr |= DISP_FORMAT_BGRA101010;
break;
case DRM_FORMAT_ABGR2101010:
- dspcntr |= DISPPLANE_RGBA101010;
+ dspcntr |= DISP_FORMAT_RGBA101010;
break;
case DRM_FORMAT_XBGR16161616F:
- dspcntr |= DISPPLANE_RGBX161616;
+ dspcntr |= DISP_FORMAT_RGBX161616;
break;
default:
MISSING_CASE(fb->format->format);
@@ -208,13 +208,13 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
if (DISPLAY_VER(dev_priv) >= 4 &&
fb->modifier == I915_FORMAT_MOD_X_TILED)
- dspcntr |= DISPPLANE_TILED;
+ dspcntr |= DISP_TILED;
if (rotation & DRM_MODE_ROTATE_180)
- dspcntr |= DISPPLANE_ROTATE_180;
+ dspcntr |= DISP_ROTATE_180;
if (rotation & DRM_MODE_REFLECT_X)
- dspcntr |= DISPPLANE_MIRROR;
+ dspcntr |= DISP_MIRROR;
return dspcntr;
}
@@ -354,13 +354,13 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 dspcntr = 0;
if (crtc_state->gamma_enable)
- dspcntr |= DISPPLANE_GAMMA_ENABLE;
+ dspcntr |= DISP_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
- dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
+ dspcntr |= DISP_PIPE_CSC_ENABLE;
if (DISPLAY_VER(dev_priv) < 5)
- dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
+ dspcntr |= DISP_PIPE_SEL(crtc->pipe);
return dspcntr;
}
@@ -437,9 +437,9 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
* program whatever is there.
*/
intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
- (crtc_y << 16) | crtc_x);
+ DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
- ((crtc_h - 1) << 16) | (crtc_w - 1));
+ DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
}
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@@ -474,20 +474,20 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
int crtc_h = drm_rect_height(&plane_state->uapi.dst);
intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
- (crtc_y << 16) | crtc_x);
+ PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
- ((crtc_h - 1) << 16) | (crtc_w - 1));
+ PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
}
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
- (y << 16) | x);
+ DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
} else if (DISPLAY_VER(dev_priv) >= 4) {
intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
linear_offset);
intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
- (y << 16) | x);
+ DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
}
/*
@@ -564,7 +564,7 @@ g4x_primary_async_flip(struct intel_plane *plane,
unsigned long irqflags;
if (async_flip)
- dspcntr |= DISPPLANE_ASYNC_FLIP;
+ dspcntr |= DISP_ASYNC_FLIP;
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
@@ -696,13 +696,12 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
- ret = val & DISPLAY_PLANE_ENABLE;
+ ret = val & DISP_ENABLE;
if (DISPLAY_VER(dev_priv) >= 5)
*pipe = plane->pipe;
else
- *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
- DISPPLANE_SEL_PIPE_SHIFT;
+ *pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
intel_display_power_put(dev_priv, power_domain, wakeref);
@@ -958,32 +957,32 @@ fail:
static int i9xx_format_to_fourcc(int format)
{
switch (format) {
- case DISPPLANE_8BPP:
+ case DISP_FORMAT_8BPP:
return DRM_FORMAT_C8;
- case DISPPLANE_BGRA555:
+ case DISP_FORMAT_BGRA555:
return DRM_FORMAT_ARGB1555;
- case DISPPLANE_BGRX555:
+ case DISP_FORMAT_BGRX555:
return DRM_FORMAT_XRGB1555;
- case DISPPLANE_BGRX565:
+ case DISP_FORMAT_BGRX565:
return DRM_FORMAT_RGB565;
default:
- case DISPPLANE_BGRX888:
+ case DISP_FORMAT_BGRX888:
return DRM_FORMAT_XRGB8888;
- case DISPPLANE_RGBX888:
+ case DISP_FORMAT_RGBX888:
return DRM_FORMAT_XBGR8888;
- case DISPPLANE_BGRA888:
+ case DISP_FORMAT_BGRA888:
return DRM_FORMAT_ARGB8888;
- case DISPPLANE_RGBA888:
+ case DISP_FORMAT_RGBA888:
return DRM_FORMAT_ABGR8888;
- case DISPPLANE_BGRX101010:
+ case DISP_FORMAT_BGRX101010:
return DRM_FORMAT_XRGB2101010;
- case DISPPLANE_RGBX101010:
+ case DISP_FORMAT_RGBX101010:
return DRM_FORMAT_XBGR2101010;
- case DISPPLANE_BGRA101010:
+ case DISP_FORMAT_BGRA101010:
return DRM_FORMAT_ARGB2101010;
- case DISPPLANE_RGBA101010:
+ case DISP_FORMAT_RGBA101010:
return DRM_FORMAT_ABGR2101010;
- case DISPPLANE_RGBX161616:
+ case DISP_FORMAT_RGBX161616:
return DRM_FORMAT_XBGR16161616F;
}
}
@@ -1021,26 +1020,26 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
if (DISPLAY_VER(dev_priv) >= 4) {
- if (val & DISPPLANE_TILED) {
+ if (val & DISP_TILED) {
plane_config->tiling = I915_TILING_X;
fb->modifier = I915_FORMAT_MOD_X_TILED;
}
- if (val & DISPPLANE_ROTATE_180)
+ if (val & DISP_ROTATE_180)
plane_config->rotation = DRM_MODE_ROTATE_180;
}
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
- val & DISPPLANE_MIRROR)
+ val & DISP_MIRROR)
plane_config->rotation |= DRM_MODE_REFLECT_X;
- pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
+ pixel_format = val & DISP_FORMAT_MASK;
fourcc = i9xx_format_to_fourcc(pixel_format);
fb->format = drm_format_info(fourcc);
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000;
+ base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
} else if (DISPLAY_VER(dev_priv) >= 4) {
if (plane_config->tiling)
offset = intel_de_read(dev_priv,
@@ -1048,15 +1047,15 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
else
offset = intel_de_read(dev_priv,
DSPLINOFF(i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000;
+ base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
} else {
base = intel_de_read(dev_priv, DSPADDR(i9xx_plane));
}
plane_config->base = base;
val = intel_de_read(dev_priv, PIPESRC(pipe));
- fb->width = ((val >> 16) & 0xfff) + 1;
- fb->height = ((val >> 0) & 0xfff) + 1;
+ fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
+ fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane));
fb->pitches[0] = val & 0xffffffc0;
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 5781e9fac8b4..13b07c6fd6be 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -29,9 +29,11 @@
#include <drm/drm_mipi_dsi.h>
#include "icl_dsi.h"
+#include "icl_dsi_regs.h"
#include "intel_atomic.h"
#include "intel_backlight.h"
#include "intel_combo_phy.h"
+#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
@@ -569,7 +571,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
/* Program T-INIT master registers */
for_each_dsi_port(port, intel_dsi->ports) {
tmp = intel_de_read(dev_priv, ICL_DSI_T_INIT_MASTER(port));
- tmp &= ~MASTER_INIT_TIMER_MASK;
+ tmp &= ~DSI_T_INIT_MASTER_MASK;
tmp |= intel_dsi->init_count;
intel_de_write(dev_priv, ICL_DSI_T_INIT_MASTER(port), tmp);
}
@@ -787,14 +789,14 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
/* program DSI operation mode */
if (is_vid_mode(intel_dsi)) {
tmp &= ~OP_MODE_MASK;
- switch (intel_dsi->video_mode_format) {
+ switch (intel_dsi->video_mode) {
default:
- MISSING_CASE(intel_dsi->video_mode_format);
+ MISSING_CASE(intel_dsi->video_mode);
fallthrough;
- case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS:
+ case NON_BURST_SYNC_EVENTS:
tmp |= VIDEO_MODE_SYNC_EVENT;
break;
- case VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE:
+ case NON_BURST_SYNC_PULSE:
tmp |= VIDEO_MODE_SYNC_PULSE;
break;
}
@@ -959,8 +961,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
/* TRANS_HSYNC register to be programmed only for video mode */
if (is_vid_mode(intel_dsi)) {
- if (intel_dsi->video_mode_format ==
- VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) {
+ if (intel_dsi->video_mode == NON_BURST_SYNC_PULSE) {
/* BSPEC: hsync size should be atleast 16 pixels */
if (hsync_size < 16)
drm_err(&dev_priv->drm,
@@ -1050,7 +1051,7 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
/* wait for transcoder to be enabled */
if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans),
- I965_PIPECONF_ACTIVE, 10))
+ PIPECONF_STATE_ENABLE, 10))
drm_err(&dev_priv->drm,
"DSI transcoder not enabled\n");
}
@@ -1232,8 +1233,6 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state,
intel_dsc_dsi_pps_write(encoder, pipe_config);
- intel_dsc_enable(pipe_config);
-
/* step6c: configure transcoder timings */
gen11_dsi_set_transcoder_timings(encoder, pipe_config);
}
@@ -1320,7 +1319,7 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
/* wait for transcoder to be disabled */
if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans),
- I965_PIPECONF_ACTIVE, 50))
+ PIPECONF_STATE_ENABLE, 50))
drm_err(&dev_priv->drm,
"DSI trancoder not disabled\n");
}
diff --git a/drivers/gpu/drm/i915/display/icl_dsi_regs.h b/drivers/gpu/drm/i915/display/icl_dsi_regs.h
new file mode 100644
index 000000000000..f78f28b8dd94
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/icl_dsi_regs.h
@@ -0,0 +1,342 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __ICL_DSI_REGS_H__
+#define __ICL_DSI_REGS_H__
+
+#include "i915_reg_defs.h"
+
+/* Gen11 DSI */
+#define _MMIO_DSI(tc, dsi0, dsi1) _MMIO_TRANS((tc) - TRANSCODER_DSI_0, \
+ dsi0, dsi1)
+#define _ICL_DSI_ESC_CLK_DIV0 0x6b090
+#define _ICL_DSI_ESC_CLK_DIV1 0x6b890
+#define ICL_DSI_ESC_CLK_DIV(port) _MMIO_PORT((port), \
+ _ICL_DSI_ESC_CLK_DIV0, \
+ _ICL_DSI_ESC_CLK_DIV1)
+#define _ICL_DPHY_ESC_CLK_DIV0 0x162190
+#define _ICL_DPHY_ESC_CLK_DIV1 0x6C190
+#define ICL_DPHY_ESC_CLK_DIV(port) _MMIO_PORT((port), \
+ _ICL_DPHY_ESC_CLK_DIV0, \
+ _ICL_DPHY_ESC_CLK_DIV1)
+#define ICL_BYTE_CLK_PER_ESC_CLK_MASK (0x1f << 16)
+#define ICL_BYTE_CLK_PER_ESC_CLK_SHIFT 16
+#define ICL_ESC_CLK_DIV_MASK 0x1ff
+#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, \
+ _DSI_CMD_FRMCTL_0,\
+ _DSI_CMD_FRMCTL_1)
+#define DSI_FRAME_UPDATE_REQUEST (1 << 31)
+#define DSI_PERIODIC_FRAME_UPDATE_ENABLE (1 << 29)
+#define DSI_NULL_PACKET_ENABLE (1 << 28)
+#define DSI_FRAME_IN_PROGRESS (1 << 0)
+
+#define _DSI_INTR_MASK_REG_0 0x6b070
+#define _DSI_INTR_MASK_REG_1 0x6b870
+#define DSI_INTR_MASK_REG(port) _MMIO_PORT(port, \
+ _DSI_INTR_MASK_REG_0,\
+ _DSI_INTR_MASK_REG_1)
+
+#define _DSI_INTR_IDENT_REG_0 0x6b074
+#define _DSI_INTR_IDENT_REG_1 0x6b874
+#define DSI_INTR_IDENT_REG(port) _MMIO_PORT(port, \
+ _DSI_INTR_IDENT_REG_0,\
+ _DSI_INTR_IDENT_REG_1)
+#define DSI_TE_EVENT (1 << 31)
+#define DSI_RX_DATA_OR_BTA_TERMINATED (1 << 30)
+#define DSI_TX_DATA (1 << 29)
+#define DSI_ULPS_ENTRY_DONE (1 << 28)
+#define DSI_NON_TE_TRIGGER_RECEIVED (1 << 27)
+#define DSI_HOST_CHKSUM_ERROR (1 << 26)
+#define DSI_HOST_MULTI_ECC_ERROR (1 << 25)
+#define DSI_HOST_SINGL_ECC_ERROR (1 << 24)
+#define DSI_HOST_CONTENTION_DETECTED (1 << 23)
+#define DSI_HOST_FALSE_CONTROL_ERROR (1 << 22)
+#define DSI_HOST_TIMEOUT_ERROR (1 << 21)
+#define DSI_HOST_LOW_POWER_TX_SYNC_ERROR (1 << 20)
+#define DSI_HOST_ESCAPE_MODE_ENTRY_ERROR (1 << 19)
+#define DSI_FRAME_UPDATE_DONE (1 << 16)
+#define DSI_PROTOCOL_VIOLATION_REPORTED (1 << 15)
+#define DSI_INVALID_TX_LENGTH (1 << 13)
+#define DSI_INVALID_VC (1 << 12)
+#define DSI_INVALID_DATA_TYPE (1 << 11)
+#define DSI_PERIPHERAL_CHKSUM_ERROR (1 << 10)
+#define DSI_PERIPHERAL_MULTI_ECC_ERROR (1 << 9)
+#define DSI_PERIPHERAL_SINGLE_ECC_ERROR (1 << 8)
+#define DSI_PERIPHERAL_CONTENTION_DETECTED (1 << 7)
+#define DSI_PERIPHERAL_FALSE_CTRL_ERROR (1 << 6)
+#define DSI_PERIPHERAL_TIMEOUT_ERROR (1 << 5)
+#define DSI_PERIPHERAL_LP_TX_SYNC_ERROR (1 << 4)
+#define DSI_PERIPHERAL_ESC_MODE_ENTRY_CMD_ERR (1 << 3)
+#define DSI_EOT_SYNC_ERROR (1 << 2)
+#define DSI_SOT_SYNC_ERROR (1 << 1)
+#define DSI_SOT_ERROR (1 << 0)
+
+/* ICL DSI MODE control */
+#define _ICL_DSI_IO_MODECTL_0 0x6B094
+#define _ICL_DSI_IO_MODECTL_1 0x6B894
+#define ICL_DSI_IO_MODECTL(port) _MMIO_PORT(port, \
+ _ICL_DSI_IO_MODECTL_0, \
+ _ICL_DSI_IO_MODECTL_1)
+#define COMBO_PHY_MODE_DSI (1 << 0)
+
+/* TGL DSI Chicken register */
+#define _TGL_DSI_CHKN_REG_0 0x6B0C0
+#define _TGL_DSI_CHKN_REG_1 0x6B8C0
+#define TGL_DSI_CHKN_REG(port) _MMIO_PORT(port, \
+ _TGL_DSI_CHKN_REG_0, \
+ _TGL_DSI_CHKN_REG_1)
+#define TGL_DSI_CHKN_LSHS_GB_MASK REG_GENMASK(15, 12)
+#define TGL_DSI_CHKN_LSHS_GB(byte_clocks) REG_FIELD_PREP(TGL_DSI_CHKN_LSHS_GB_MASK, \
+ (byte_clocks))
+#define _ICL_DSI_T_INIT_MASTER_0 0x6b088
+#define _ICL_DSI_T_INIT_MASTER_1 0x6b888
+#define ICL_DSI_T_INIT_MASTER(port) _MMIO_PORT(port, \
+ _ICL_DSI_T_INIT_MASTER_0,\
+ _ICL_DSI_T_INIT_MASTER_1)
+#define DSI_T_INIT_MASTER_MASK REG_GENMASK(15, 0)
+
+#define _DPHY_CLK_TIMING_PARAM_0 0x162180
+#define _DPHY_CLK_TIMING_PARAM_1 0x6c180
+#define DPHY_CLK_TIMING_PARAM(port) _MMIO_PORT(port, \
+ _DPHY_CLK_TIMING_PARAM_0,\
+ _DPHY_CLK_TIMING_PARAM_1)
+#define _DSI_CLK_TIMING_PARAM_0 0x6b080
+#define _DSI_CLK_TIMING_PARAM_1 0x6b880
+#define DSI_CLK_TIMING_PARAM(port) _MMIO_PORT(port, \
+ _DSI_CLK_TIMING_PARAM_0,\
+ _DSI_CLK_TIMING_PARAM_1)
+#define CLK_PREPARE_OVERRIDE (1 << 31)
+#define CLK_PREPARE(x) ((x) << 28)
+#define CLK_PREPARE_MASK (0x7 << 28)
+#define CLK_PREPARE_SHIFT 28
+#define CLK_ZERO_OVERRIDE (1 << 27)
+#define CLK_ZERO(x) ((x) << 20)
+#define CLK_ZERO_MASK (0xf << 20)
+#define CLK_ZERO_SHIFT 20
+#define CLK_PRE_OVERRIDE (1 << 19)
+#define CLK_PRE(x) ((x) << 16)
+#define CLK_PRE_MASK (0x3 << 16)
+#define CLK_PRE_SHIFT 16
+#define CLK_POST_OVERRIDE (1 << 15)
+#define CLK_POST(x) ((x) << 8)
+#define CLK_POST_MASK (0x7 << 8)
+#define CLK_POST_SHIFT 8
+#define CLK_TRAIL_OVERRIDE (1 << 7)
+#define CLK_TRAIL(x) ((x) << 0)
+#define CLK_TRAIL_MASK (0xf << 0)
+#define CLK_TRAIL_SHIFT 0
+
+#define _DPHY_DATA_TIMING_PARAM_0 0x162184
+#define _DPHY_DATA_TIMING_PARAM_1 0x6c184
+#define DPHY_DATA_TIMING_PARAM(port) _MMIO_PORT(port, \
+ _DPHY_DATA_TIMING_PARAM_0,\
+ _DPHY_DATA_TIMING_PARAM_1)
+#define _DSI_DATA_TIMING_PARAM_0 0x6B084
+#define _DSI_DATA_TIMING_PARAM_1 0x6B884
+#define DSI_DATA_TIMING_PARAM(port) _MMIO_PORT(port, \
+ _DSI_DATA_TIMING_PARAM_0,\
+ _DSI_DATA_TIMING_PARAM_1)
+#define HS_PREPARE_OVERRIDE (1 << 31)
+#define HS_PREPARE(x) ((x) << 24)
+#define HS_PREPARE_MASK (0x7 << 24)
+#define HS_PREPARE_SHIFT 24
+#define HS_ZERO_OVERRIDE (1 << 23)
+#define HS_ZERO(x) ((x) << 16)
+#define HS_ZERO_MASK (0xf << 16)
+#define HS_ZERO_SHIFT 16
+#define HS_TRAIL_OVERRIDE (1 << 15)
+#define HS_TRAIL(x) ((x) << 8)
+#define HS_TRAIL_MASK (0x7 << 8)
+#define HS_TRAIL_SHIFT 8
+#define HS_EXIT_OVERRIDE (1 << 7)
+#define HS_EXIT(x) ((x) << 0)
+#define HS_EXIT_MASK (0x7 << 0)
+#define HS_EXIT_SHIFT 0
+
+#define _DPHY_TA_TIMING_PARAM_0 0x162188
+#define _DPHY_TA_TIMING_PARAM_1 0x6c188
+#define DPHY_TA_TIMING_PARAM(port) _MMIO_PORT(port, \
+ _DPHY_TA_TIMING_PARAM_0,\
+ _DPHY_TA_TIMING_PARAM_1)
+#define _DSI_TA_TIMING_PARAM_0 0x6b098
+#define _DSI_TA_TIMING_PARAM_1 0x6b898
+#define DSI_TA_TIMING_PARAM(port) _MMIO_PORT(port, \
+ _DSI_TA_TIMING_PARAM_0,\
+ _DSI_TA_TIMING_PARAM_1)
+#define TA_SURE_OVERRIDE (1 << 31)
+#define TA_SURE(x) ((x) << 16)
+#define TA_SURE_MASK (0x1f << 16)
+#define TA_SURE_SHIFT 16
+#define TA_GO_OVERRIDE (1 << 15)
+#define TA_GO(x) ((x) << 8)
+#define TA_GO_MASK (0xf << 8)
+#define TA_GO_SHIFT 8
+#define TA_GET_OVERRIDE (1 << 7)
+#define TA_GET(x) ((x) << 0)
+#define TA_GET_MASK (0xf << 0)
+#define TA_GET_SHIFT 0
+
+/* DSI transcoder configuration */
+#define _DSI_TRANS_FUNC_CONF_0 0x6b030
+#define _DSI_TRANS_FUNC_CONF_1 0x6b830
+#define DSI_TRANS_FUNC_CONF(tc) _MMIO_DSI(tc, \
+ _DSI_TRANS_FUNC_CONF_0,\
+ _DSI_TRANS_FUNC_CONF_1)
+#define OP_MODE_MASK (0x3 << 28)
+#define OP_MODE_SHIFT 28
+#define CMD_MODE_NO_GATE (0x0 << 28)
+#define CMD_MODE_TE_GATE (0x1 << 28)
+#define VIDEO_MODE_SYNC_EVENT (0x2 << 28)
+#define VIDEO_MODE_SYNC_PULSE (0x3 << 28)
+#define TE_SOURCE_GPIO (1 << 27)
+#define LINK_READY (1 << 20)
+#define PIX_FMT_MASK (0x3 << 16)
+#define PIX_FMT_SHIFT 16
+#define PIX_FMT_RGB565 (0x0 << 16)
+#define PIX_FMT_RGB666_PACKED (0x1 << 16)
+#define PIX_FMT_RGB666_LOOSE (0x2 << 16)
+#define PIX_FMT_RGB888 (0x3 << 16)
+#define PIX_FMT_RGB101010 (0x4 << 16)
+#define PIX_FMT_RGB121212 (0x5 << 16)
+#define PIX_FMT_COMPRESSED (0x6 << 16)
+#define BGR_TRANSMISSION (1 << 15)
+#define PIX_VIRT_CHAN(x) ((x) << 12)
+#define PIX_VIRT_CHAN_MASK (0x3 << 12)
+#define PIX_VIRT_CHAN_SHIFT 12
+#define PIX_BUF_THRESHOLD_MASK (0x3 << 10)
+#define PIX_BUF_THRESHOLD_SHIFT 10
+#define PIX_BUF_THRESHOLD_1_4 (0x0 << 10)
+#define PIX_BUF_THRESHOLD_1_2 (0x1 << 10)
+#define PIX_BUF_THRESHOLD_3_4 (0x2 << 10)
+#define PIX_BUF_THRESHOLD_FULL (0x3 << 10)
+#define CONTINUOUS_CLK_MASK (0x3 << 8)
+#define CONTINUOUS_CLK_SHIFT 8
+#define CLK_ENTER_LP_AFTER_DATA (0x0 << 8)
+#define CLK_HS_OR_LP (0x2 << 8)
+#define CLK_HS_CONTINUOUS (0x3 << 8)
+#define LINK_CALIBRATION_MASK (0x3 << 4)
+#define LINK_CALIBRATION_SHIFT 4
+#define CALIBRATION_DISABLED (0x0 << 4)
+#define CALIBRATION_ENABLED_INITIAL_ONLY (0x2 << 4)
+#define CALIBRATION_ENABLED_INITIAL_PERIODIC (0x3 << 4)
+#define BLANKING_PACKET_ENABLE (1 << 2)
+#define S3D_ORIENTATION_LANDSCAPE (1 << 1)
+#define EOTP_DISABLED (1 << 0)
+
+#define _DSI_CMD_RXCTL_0 0x6b0d4
+#define _DSI_CMD_RXCTL_1 0x6b8d4
+#define DSI_CMD_RXCTL(tc) _MMIO_DSI(tc, \
+ _DSI_CMD_RXCTL_0,\
+ _DSI_CMD_RXCTL_1)
+#define READ_UNLOADS_DW (1 << 16)
+#define RECEIVED_UNASSIGNED_TRIGGER (1 << 15)
+#define RECEIVED_ACKNOWLEDGE_TRIGGER (1 << 14)
+#define RECEIVED_TEAR_EFFECT_TRIGGER (1 << 13)
+#define RECEIVED_RESET_TRIGGER (1 << 12)
+#define RECEIVED_PAYLOAD_WAS_LOST (1 << 11)
+#define RECEIVED_CRC_WAS_LOST (1 << 10)
+#define NUMBER_RX_PLOAD_DW_MASK (0xff << 0)
+#define NUMBER_RX_PLOAD_DW_SHIFT 0
+
+#define _DSI_CMD_TXCTL_0 0x6b0d0
+#define _DSI_CMD_TXCTL_1 0x6b8d0
+#define DSI_CMD_TXCTL(tc) _MMIO_DSI(tc, \
+ _DSI_CMD_TXCTL_0,\
+ _DSI_CMD_TXCTL_1)
+#define KEEP_LINK_IN_HS (1 << 24)
+#define FREE_HEADER_CREDIT_MASK (0x1f << 8)
+#define FREE_HEADER_CREDIT_SHIFT 0x8
+#define FREE_PLOAD_CREDIT_MASK (0xff << 0)
+#define FREE_PLOAD_CREDIT_SHIFT 0
+#define MAX_HEADER_CREDIT 0x10
+#define MAX_PLOAD_CREDIT 0x40
+
+#define _DSI_CMD_TXHDR_0 0x6b100
+#define _DSI_CMD_TXHDR_1 0x6b900
+#define DSI_CMD_TXHDR(tc) _MMIO_DSI(tc, \
+ _DSI_CMD_TXHDR_0,\
+ _DSI_CMD_TXHDR_1)
+#define PAYLOAD_PRESENT (1 << 31)
+#define LP_DATA_TRANSFER (1 << 30)
+#define VBLANK_FENCE (1 << 29)
+#define PARAM_WC_MASK (0xffff << 8)
+#define PARAM_WC_LOWER_SHIFT 8
+#define PARAM_WC_UPPER_SHIFT 16
+#define VC_MASK (0x3 << 6)
+#define VC_SHIFT 6
+#define DT_MASK (0x3f << 0)
+#define DT_SHIFT 0
+
+#define _DSI_CMD_TXPYLD_0 0x6b104
+#define _DSI_CMD_TXPYLD_1 0x6b904
+#define DSI_CMD_TXPYLD(tc) _MMIO_DSI(tc, \
+ _DSI_CMD_TXPYLD_0,\
+ _DSI_CMD_TXPYLD_1)
+
+#define _DSI_LP_MSG_0 0x6b0d8
+#define _DSI_LP_MSG_1 0x6b8d8
+#define DSI_LP_MSG(tc) _MMIO_DSI(tc, \
+ _DSI_LP_MSG_0,\
+ _DSI_LP_MSG_1)
+#define LPTX_IN_PROGRESS (1 << 17)
+#define LINK_IN_ULPS (1 << 16)
+#define LINK_ULPS_TYPE_LP11 (1 << 8)
+#define LINK_ENTER_ULPS (1 << 0)
+
+/* DSI timeout registers */
+#define _DSI_HSTX_TO_0 0x6b044
+#define _DSI_HSTX_TO_1 0x6b844
+#define DSI_HSTX_TO(tc) _MMIO_DSI(tc, \
+ _DSI_HSTX_TO_0,\
+ _DSI_HSTX_TO_1)
+#define HSTX_TIMEOUT_VALUE_MASK (0xffff << 16)
+#define HSTX_TIMEOUT_VALUE_SHIFT 16
+#define HSTX_TIMEOUT_VALUE(x) ((x) << 16)
+#define HSTX_TIMED_OUT (1 << 0)
+
+#define _DSI_LPRX_HOST_TO_0 0x6b048
+#define _DSI_LPRX_HOST_TO_1 0x6b848
+#define DSI_LPRX_HOST_TO(tc) _MMIO_DSI(tc, \
+ _DSI_LPRX_HOST_TO_0,\
+ _DSI_LPRX_HOST_TO_1)
+#define LPRX_TIMED_OUT (1 << 16)
+#define LPRX_TIMEOUT_VALUE_MASK (0xffff << 0)
+#define LPRX_TIMEOUT_VALUE_SHIFT 0
+#define LPRX_TIMEOUT_VALUE(x) ((x) << 0)
+
+#define _DSI_PWAIT_TO_0 0x6b040
+#define _DSI_PWAIT_TO_1 0x6b840
+#define DSI_PWAIT_TO(tc) _MMIO_DSI(tc, \
+ _DSI_PWAIT_TO_0,\
+ _DSI_PWAIT_TO_1)
+#define PRESET_TIMEOUT_VALUE_MASK (0xffff << 16)
+#define PRESET_TIMEOUT_VALUE_SHIFT 16
+#define PRESET_TIMEOUT_VALUE(x) ((x) << 16)
+#define PRESPONSE_TIMEOUT_VALUE_MASK (0xffff << 0)
+#define PRESPONSE_TIMEOUT_VALUE_SHIFT 0
+#define PRESPONSE_TIMEOUT_VALUE(x) ((x) << 0)
+
+#define _DSI_TA_TO_0 0x6b04c
+#define _DSI_TA_TO_1 0x6b84c
+#define DSI_TA_TO(tc) _MMIO_DSI(tc, \
+ _DSI_TA_TO_0,\
+ _DSI_TA_TO_1)
+#define TA_TIMED_OUT (1 << 16)
+#define TA_TIMEOUT_VALUE_MASK (0xffff << 0)
+#define TA_TIMEOUT_VALUE_SHIFT 0
+#define TA_TIMEOUT_VALUE(x) ((x) << 0)
+
+#endif /* __ICL_DSI_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index a62550711e98..e0667d163266 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -34,6 +34,8 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_plane_helper.h>
+#include "i915_drv.h"
+#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_cdclk.h"
#include "intel_display_types.h"
@@ -279,17 +281,6 @@ void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
intel_crtc_put_color_blobs(crtc_state);
}
-void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
- const struct intel_crtc_state *from_crtc_state)
-{
- drm_property_replace_blob(&crtc_state->hw.degamma_lut,
- from_crtc_state->uapi.degamma_lut);
- drm_property_replace_blob(&crtc_state->hw.gamma_lut,
- from_crtc_state->uapi.gamma_lut);
- drm_property_replace_blob(&crtc_state->hw.ctm,
- from_crtc_state->uapi.ctm);
-}
-
/**
* intel_crtc_destroy_state - destroy crtc state
* @crtc: drm crtc
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index d2700c74c9da..1dc439983dd9 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -44,8 +44,6 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
void intel_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
-void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
- const struct intel_crtc_state *from_crtc_state);
struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
void intel_atomic_state_free(struct drm_atomic_state *state);
void intel_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index c2c512cd8ec0..c53aa6a4c7a0 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -45,6 +45,7 @@
#include "intel_fb_pin.h"
#include "intel_pm.h"
#include "intel_sprite.h"
+#include "skl_scaler.h"
static void intel_plane_state_reset(struct intel_plane_state *plane_state,
struct intel_plane *plane)
@@ -109,6 +110,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL;
intel_state->flags = 0;
+ intel_state->do_async_flip = false;
/* add reference to fb */
if (intel_state->hw.fb)
@@ -321,6 +323,7 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
crtc_state->active_planes &= ~BIT(plane->id);
+ crtc_state->scaled_planes &= ~BIT(plane->id);
crtc_state->nv12_planes &= ~BIT(plane->id);
crtc_state->c8_planes &= ~BIT(plane->id);
crtc_state->data_rate[plane->id] = 0;
@@ -329,6 +332,185 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
plane_state->uapi.visible = false;
}
+/* FIXME nuke when all wm code is atomic */
+static bool intel_wm_need_update(const struct intel_plane_state *cur,
+ struct intel_plane_state *new)
+{
+ /* Update watermarks on tiling or size changes. */
+ if (new->uapi.visible != cur->uapi.visible)
+ return true;
+
+ if (!cur->hw.fb || !new->hw.fb)
+ return false;
+
+ if (cur->hw.fb->modifier != new->hw.fb->modifier ||
+ cur->hw.rotation != new->hw.rotation ||
+ drm_rect_width(&new->uapi.src) != drm_rect_width(&cur->uapi.src) ||
+ drm_rect_height(&new->uapi.src) != drm_rect_height(&cur->uapi.src) ||
+ drm_rect_width(&new->uapi.dst) != drm_rect_width(&cur->uapi.dst) ||
+ drm_rect_height(&new->uapi.dst) != drm_rect_height(&cur->uapi.dst))
+ return true;
+
+ return false;
+}
+
+static bool intel_plane_is_scaled(const struct intel_plane_state *plane_state)
+{
+ int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
+ int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
+ int dst_w = drm_rect_width(&plane_state->uapi.dst);
+ int dst_h = drm_rect_height(&plane_state->uapi.dst);
+
+ return src_w != dst_w || src_h != dst_h;
+}
+
+static bool intel_plane_do_async_flip(struct intel_plane *plane,
+ const struct intel_crtc_state *old_crtc_state,
+ const struct intel_crtc_state *new_crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
+ if (!plane->async_flip)
+ return false;
+
+ if (!new_crtc_state->uapi.async_flip)
+ return false;
+
+ /*
+ * In platforms after DISPLAY13, we might need to override
+ * first async flip in order to change watermark levels
+ * as part of optimization.
+ * So for those, we are checking if this is a first async flip.
+ * For platforms earlier than DISPLAY13 we always do async flip.
+ */
+ return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
+}
+
+static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
+ struct intel_crtc_state *new_crtc_state,
+ const struct intel_plane_state *old_plane_state,
+ struct intel_plane_state *new_plane_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
+ struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ bool mode_changed = intel_crtc_needs_modeset(new_crtc_state);
+ bool was_crtc_enabled = old_crtc_state->hw.active;
+ bool is_crtc_enabled = new_crtc_state->hw.active;
+ bool turn_off, turn_on, visible, was_visible;
+ int ret;
+
+ if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
+ ret = skl_update_scaler_plane(new_crtc_state, new_plane_state);
+ if (ret)
+ return ret;
+ }
+
+ was_visible = old_plane_state->uapi.visible;
+ visible = new_plane_state->uapi.visible;
+
+ if (!was_crtc_enabled && drm_WARN_ON(&dev_priv->drm, was_visible))
+ was_visible = false;
+
+ /*
+ * Visibility is calculated as if the crtc was on, but
+ * after scaler setup everything depends on it being off
+ * when the crtc isn't active.
+ *
+ * FIXME this is wrong for watermarks. Watermarks should also
+ * be computed as if the pipe would be active. Perhaps move
+ * per-plane wm computation to the .check_plane() hook, and
+ * only combine the results from all planes in the current place?
+ */
+ if (!is_crtc_enabled) {
+ intel_plane_set_invisible(new_crtc_state, new_plane_state);
+ visible = false;
+ }
+
+ if (!was_visible && !visible)
+ return 0;
+
+ turn_off = was_visible && (!visible || mode_changed);
+ turn_on = visible && (!was_visible || mode_changed);
+
+ drm_dbg_atomic(&dev_priv->drm,
+ "[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
+ crtc->base.base.id, crtc->base.name,
+ plane->base.base.id, plane->base.name,
+ was_visible, visible,
+ turn_off, turn_on, mode_changed);
+
+ if (turn_on) {
+ if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
+ new_crtc_state->update_wm_pre = true;
+
+ /* must disable cxsr around plane enable/disable */
+ if (plane->id != PLANE_CURSOR)
+ new_crtc_state->disable_cxsr = true;
+ } else if (turn_off) {
+ if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
+ new_crtc_state->update_wm_post = true;
+
+ /* must disable cxsr around plane enable/disable */
+ if (plane->id != PLANE_CURSOR)
+ new_crtc_state->disable_cxsr = true;
+ } else if (intel_wm_need_update(old_plane_state, new_plane_state)) {
+ if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) {
+ /* FIXME bollocks */
+ new_crtc_state->update_wm_pre = true;
+ new_crtc_state->update_wm_post = true;
+ }
+ }
+
+ if (visible || was_visible)
+ new_crtc_state->fb_bits |= plane->frontbuffer_bit;
+
+ /*
+ * ILK/SNB DVSACNTR/Sprite Enable
+ * IVB SPR_CTL/Sprite Enable
+ * "When in Self Refresh Big FIFO mode, a write to enable the
+ * plane will be internally buffered and delayed while Big FIFO
+ * mode is exiting."
+ *
+ * Which means that enabling the sprite can take an extra frame
+ * when we start in big FIFO mode (LP1+). Thus we need to drop
+ * down to LP0 and wait for vblank in order to make sure the
+ * sprite gets enabled on the next vblank after the register write.
+ * Doing otherwise would risk enabling the sprite one frame after
+ * we've already signalled flip completion. We can resume LP1+
+ * once the sprite has been enabled.
+ *
+ *
+ * WaCxSRDisabledForSpriteScaling:ivb
+ * IVB SPR_SCALE/Scaling Enable
+ * "Low Power watermarks must be disabled for at least one
+ * frame before enabling sprite scaling, and kept disabled
+ * until sprite scaling is disabled."
+ *
+ * ILK/SNB DVSASCALE/Scaling Enable
+ * "When in Self Refresh Big FIFO mode, scaling enable will be
+ * masked off while Big FIFO mode is exiting."
+ *
+ * Despite the w/a only being listed for IVB we assume that
+ * the ILK/SNB note has similar ramifications, hence we apply
+ * the w/a on all three platforms.
+ *
+ * With experimental results seems this is needed also for primary
+ * plane, not only sprite plane.
+ */
+ if (plane->id != PLANE_CURSOR &&
+ (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) ||
+ IS_IVYBRIDGE(dev_priv)) &&
+ (turn_on || (!intel_plane_is_scaled(old_plane_state) &&
+ intel_plane_is_scaled(new_plane_state))))
+ new_crtc_state->disable_lp_wm = true;
+
+ if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state))
+ new_plane_state->do_async_flip = true;
+
+ return 0;
+}
+
int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state,
const struct intel_plane_state *old_plane_state,
@@ -356,6 +538,10 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
new_crtc_state->active_planes |= BIT(plane->id);
if (new_plane_state->uapi.visible &&
+ intel_plane_is_scaled(new_plane_state))
+ new_crtc_state->scaled_planes |= BIT(plane->id);
+
+ if (new_plane_state->uapi.visible &&
intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
new_crtc_state->nv12_planes |= BIT(plane->id);
@@ -402,10 +588,11 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
+ if (new_crtc_state && intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
+ struct intel_crtc *master_crtc =
+ intel_master_crtc(new_crtc_state);
struct intel_plane *master_plane =
- intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
- plane->id);
+ intel_crtc_get_plane(master_crtc, plane->id);
new_master_plane_state =
intel_atomic_get_new_plane_state(state, master_plane);
@@ -491,7 +678,7 @@ void intel_plane_update_arm(struct intel_plane *plane,
trace_intel_plane_update_arm(&plane->base, crtc);
- if (crtc_state->uapi.async_flip && plane->async_flip)
+ if (plane_state->do_async_flip)
plane->async_flip(plane, crtc_state, plane_state, true);
else
plane->update_arm(plane, crtc_state, plane_state);
@@ -506,8 +693,8 @@ void intel_plane_disable_arm(struct intel_plane *plane,
plane->disable_arm(plane, crtc_state);
}
-void intel_update_planes_on_crtc(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
+void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@@ -535,8 +722,8 @@ void intel_update_planes_on_crtc(struct intel_atomic_state *state,
}
}
-void skl_arm_planes_on_crtc(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
+static void skl_crtc_planes_update_arm(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@@ -570,8 +757,8 @@ void skl_arm_planes_on_crtc(struct intel_atomic_state *state,
}
}
-void i9xx_arm_planes_on_crtc(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
+static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@@ -596,11 +783,23 @@ void i9xx_arm_planes_on_crtc(struct intel_atomic_state *state,
}
}
+void intel_crtc_planes_update_arm(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+
+ if (DISPLAY_VER(i915) >= 9)
+ skl_crtc_planes_update_arm(state, crtc);
+ else
+ i9xx_crtc_planes_update_arm(state, crtc);
+}
+
int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
struct intel_crtc_state *crtc_state,
int min_scale, int max_scale,
bool can_position)
{
+ struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src;
struct drm_rect *dst = &plane_state->uapi.dst;
@@ -619,7 +818,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
if (hscale < 0 || vscale < 0) {
- DRM_DEBUG_KMS("Invalid scaling of plane\n");
+ drm_dbg_kms(&i915->drm, "Invalid scaling of plane\n");
drm_rect_debug_print("src: ", src, true);
drm_rect_debug_print("dst: ", dst, false);
return -ERANGE;
@@ -631,7 +830,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
}
/* right side of the image is on the slave crtc, adjust dst to match */
- if (crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(crtc_state))
drm_rect_translate(dst, -crtc_state->pipe_src_w, 0);
/*
@@ -644,7 +843,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
if (!can_position && plane_state->uapi.visible &&
!drm_rect_equals(dst, &clip)) {
- DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
+ drm_dbg_kms(&i915->drm, "Plane must cover entire CRTC\n");
drm_rect_debug_print("dst: ", dst, false);
drm_rect_debug_print("clip: ", &clip, false);
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 7907f601598e..f4763a53541e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -16,6 +16,7 @@ struct intel_crtc;
struct intel_crtc_state;
struct intel_plane;
struct intel_plane_state;
+enum plane_id;
unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct drm_rect *dst,
@@ -43,22 +44,16 @@ void intel_plane_free(struct intel_plane *plane);
struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
void intel_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
-void intel_update_planes_on_crtc(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
-void skl_arm_planes_on_crtc(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
-void i9xx_arm_planes_on_crtc(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
+void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+void intel_crtc_planes_update_arm(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *crtc_state,
const struct intel_plane_state *old_plane_state,
struct intel_plane_state *intel_state);
int intel_plane_atomic_check(struct intel_atomic_state *state,
struct intel_plane *plane);
-int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
- struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *old_plane_state,
- struct intel_plane_state *plane_state);
int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
struct intel_plane *plane,
bool *need_cdclk_calc);
diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c
index 9523411cddd8..98f7ea44042f 100644
--- a/drivers/gpu/drm/i915/display/intel_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_backlight.c
@@ -13,6 +13,7 @@
#include "intel_dp_aux_backlight.h"
#include "intel_dsi_dcs_backlight.h"
#include "intel_panel.h"
+#include "intel_pci_config.h"
/**
* scale - scale values from one range to another
@@ -433,6 +434,8 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn
struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
struct intel_panel *panel = &connector->panel;
+ intel_backlight_set_pwm_level(old_conn_state, level);
+
panel->backlight.pwm_state.enabled = false;
pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
}
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 1ff1f1c426b2..40b5e7ed12c2 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -32,6 +32,7 @@
#include "display/intel_gmbus.h"
#include "i915_drv.h"
+#include "i915_reg.h"
#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"
@@ -595,6 +596,12 @@ parse_general_features(struct drm_i915_private *i915,
} else {
i915->vbt.orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
}
+
+ if (bdb->version >= 249 && general->afc_startup_config) {
+ i915->vbt.override_afc_startup = true;
+ i915->vbt.override_afc_startup_val = general->afc_startup_config == 0x1 ? 0x0 : 0x7;
+ }
+
drm_dbg_kms(&i915->drm,
"BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
i915->vbt.int_tv_support,
@@ -905,26 +912,6 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
i915->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames;
- switch (psr_table->lines_to_wait) {
- case 0:
- i915->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
- break;
- case 1:
- i915->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
- break;
- case 2:
- i915->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
- break;
- case 3:
- i915->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
- break;
- default:
- drm_dbg_kms(&i915->drm,
- "VBT has unknown PSR lines to wait %u\n",
- psr_table->lines_to_wait);
- break;
- }
-
/*
* New psr options 0=500us, 1=100us, 2=2500us, 3=0us
* Old decimal value is wake up time in multiples of 100 us.
@@ -2073,14 +2060,16 @@ static void parse_ddi_port(struct drm_i915_private *i915,
i915->vbt.ports[port] = devdata;
}
+static bool has_ddi_port_info(struct drm_i915_private *i915)
+{
+ return DISPLAY_VER(i915) >= 5 || IS_G4X(i915);
+}
+
static void parse_ddi_ports(struct drm_i915_private *i915)
{
struct intel_bios_encoder_data *devdata;
- if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915))
- return;
-
- if (i915->vbt.version < 155)
+ if (!has_ddi_port_info(i915))
return;
list_for_each_entry(devdata, &i915->vbt.display_devices, node)
@@ -2335,6 +2324,63 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size)
return vbt;
}
+static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915)
+{
+ u32 count, data, found, store = 0;
+ u32 static_region, oprom_offset;
+ u32 oprom_size = 0x200000;
+ u16 vbt_size;
+ u32 *vbt;
+
+ static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS);
+ static_region &= OPTIONROM_SPI_REGIONID_MASK;
+ intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region);
+
+ oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET);
+ oprom_offset &= OROM_OFFSET_MASK;
+
+ for (count = 0; count < oprom_size; count += 4) {
+ intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, oprom_offset + count);
+ data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER);
+
+ if (data == *((const u32 *)"$VBT")) {
+ found = oprom_offset + count;
+ break;
+ }
+ }
+
+ if (count >= oprom_size)
+ goto err_not_found;
+
+ /* Get VBT size and allocate space for the VBT */
+ intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found +
+ offsetof(struct vbt_header, vbt_size));
+ vbt_size = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER);
+ vbt_size &= 0xffff;
+
+ vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL);
+ if (!vbt)
+ goto err_not_found;
+
+ for (count = 0; count < vbt_size; count += 4) {
+ intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found + count);
+ data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER);
+ *(vbt + store++) = data;
+ }
+
+ if (!intel_bios_is_valid_vbt(vbt, vbt_size))
+ goto err_free_vbt;
+
+ drm_dbg_kms(&i915->drm, "Found valid VBT in SPI flash\n");
+
+ return (struct vbt_header *)vbt;
+
+err_free_vbt:
+ kfree(vbt);
+err_not_found:
+ return NULL;
+}
+
static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
@@ -2384,6 +2430,8 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
pci_unmap_rom(pdev, oprom);
+ drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
+
return vbt;
err_free_vbt:
@@ -2418,17 +2466,23 @@ void intel_bios_init(struct drm_i915_private *i915)
init_vbt_defaults(i915);
- /* If the OpRegion does not have VBT, look in PCI ROM. */
+ /*
+ * If the OpRegion does not have VBT, look in SPI flash through MMIO or
+ * PCI mapping
+ */
+ if (!vbt && IS_DGFX(i915)) {
+ oprom_vbt = spi_oprom_get_vbt(i915);
+ vbt = oprom_vbt;
+ }
+
if (!vbt) {
oprom_vbt = oprom_get_vbt(i915);
- if (!oprom_vbt)
- goto out;
-
vbt = oprom_vbt;
-
- drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
}
+ if (!vbt)
+ goto out;
+
bdb = get_bdb_header(vbt);
i915->vbt.version = bdb->version;
@@ -2596,37 +2650,10 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 *i2c_pin)
*/
bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port)
{
- const struct intel_bios_encoder_data *devdata;
- const struct child_device_config *child;
- static const struct {
- u16 dp, hdmi;
- } port_mapping[] = {
- [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
- [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
- [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
- [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
- [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, },
- };
-
- if (HAS_DDI(i915))
- return i915->vbt.ports[port];
-
- /* FIXME maybe deal with port A as well? */
- if (drm_WARN_ON(&i915->drm,
- port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
- return false;
-
- list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
- child = &devdata->child;
-
- if ((child->dvo_port == port_mapping[port].dp ||
- child->dvo_port == port_mapping[port].hdmi) &&
- (child->device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING |
- DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
- return true;
- }
+ if (WARN_ON(!has_ddi_port_info(i915)))
+ return true;
- return false;
+ return i915->vbt.ports[port];
}
/**
@@ -2638,40 +2665,18 @@ bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port)
*/
bool intel_bios_is_port_edp(struct drm_i915_private *i915, enum port port)
{
- const struct intel_bios_encoder_data *devdata;
- const struct child_device_config *child;
- static const short port_mapping[] = {
- [PORT_B] = DVO_PORT_DPB,
- [PORT_C] = DVO_PORT_DPC,
- [PORT_D] = DVO_PORT_DPD,
- [PORT_E] = DVO_PORT_DPE,
- [PORT_F] = DVO_PORT_DPF,
- };
-
- if (HAS_DDI(i915)) {
- const struct intel_bios_encoder_data *devdata;
-
- devdata = intel_bios_encoder_data_lookup(i915, port);
+ const struct intel_bios_encoder_data *devdata =
+ intel_bios_encoder_data_lookup(i915, port);
- return devdata && intel_bios_encoder_supports_edp(devdata);
- }
-
- list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
- child = &devdata->child;
-
- if (child->dvo_port == port_mapping[port] &&
- (child->device_type & DEVICE_TYPE_eDP_BITS) ==
- (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
- return true;
- }
-
- return false;
+ return devdata && intel_bios_encoder_supports_edp(devdata);
}
-static bool child_dev_is_dp_dual_mode(const struct child_device_config *child)
+static bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata)
{
- if ((child->device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) !=
- (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
+ const struct child_device_config *child = &devdata->child;
+
+ if (!intel_bios_encoder_supports_dp(devdata) ||
+ !intel_bios_encoder_supports_hdmi(devdata))
return false;
if (dvo_port_type(child->dvo_port) == DVO_PORT_DPA)
@@ -2688,40 +2693,10 @@ static bool child_dev_is_dp_dual_mode(const struct child_device_config *child)
bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *i915,
enum port port)
{
- static const struct {
- u16 dp, hdmi;
- } port_mapping[] = {
- /*
- * Buggy VBTs may declare DP ports as having
- * HDMI type dvo_port :( So let's check both.
- */
- [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
- [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
- [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
- [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
- [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, },
- };
- const struct intel_bios_encoder_data *devdata;
-
- if (HAS_DDI(i915)) {
- const struct intel_bios_encoder_data *devdata;
-
- devdata = intel_bios_encoder_data_lookup(i915, port);
+ const struct intel_bios_encoder_data *devdata =
+ intel_bios_encoder_data_lookup(i915, port);
- return devdata && child_dev_is_dp_dual_mode(&devdata->child);
- }
-
- if (port == PORT_A || port >= ARRAY_SIZE(port_mapping))
- return false;
-
- list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
- if ((devdata->child.dvo_port == port_mapping[port].dp ||
- devdata->child.dvo_port == port_mapping[port].hdmi) &&
- child_dev_is_dp_dual_mode(&devdata->child))
- return true;
- }
-
- return false;
+ return devdata && intel_bios_encoder_supports_dp_dual_mode(devdata);
}
/**
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 2da4aacc956b..ad1564ca7269 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -5,10 +5,12 @@
#include <drm/drm_atomic_state_helper.h>
+#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_bw.h"
#include "intel_cdclk.h"
#include "intel_display_types.h"
+#include "intel_mchbar_regs.h"
#include "intel_pcode.h"
#include "intel_pm.h"
@@ -75,10 +77,9 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
u16 dclk;
int ret;
- ret = sandybridge_pcode_read(dev_priv,
- ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
- ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
- &val, &val2);
+ ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
+ ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
+ &val, &val2);
if (ret)
return ret;
@@ -102,10 +103,8 @@ static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv,
int ret;
int i;
- ret = sandybridge_pcode_read(dev_priv,
- ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
- ADL_PCODE_MEM_SS_READ_PSF_GV_INFO,
- &val, NULL);
+ ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
+ ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL);
if (ret)
return ret;
@@ -675,6 +674,49 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state)
return to_intel_bw_state(bw_state);
}
+static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe];
+ enum plane_id plane_id;
+
+ memset(&crtc_bw->used_bw, 0, sizeof(crtc_bw->used_bw));
+
+ if (!crtc_state->hw.active)
+ return;
+
+ for_each_plane_id_on_crtc(crtc, plane_id) {
+ const struct skl_ddb_entry *ddb_y =
+ &crtc_state->wm.skl.plane_ddb_y[plane_id];
+ const struct skl_ddb_entry *ddb_uv =
+ &crtc_state->wm.skl.plane_ddb_uv[plane_id];
+ unsigned int data_rate = crtc_state->data_rate[plane_id];
+ unsigned int dbuf_mask = 0;
+ enum dbuf_slice slice;
+
+ dbuf_mask |= skl_ddb_dbuf_slice_mask(i915, ddb_y);
+ dbuf_mask |= skl_ddb_dbuf_slice_mask(i915, ddb_uv);
+
+ /*
+ * FIXME: To calculate that more properly we probably
+ * need to split per plane data_rate into data_rate_y
+ * and data_rate_uv for multiplanar formats in order not
+ * to get accounted those twice if they happen to reside
+ * on different slices.
+ * However for pre-icl this would work anyway because
+ * we have only single slice and for icl+ uv plane has
+ * non-zero data rate.
+ * So in worst case those calculation are a bit
+ * pessimistic, which shouldn't pose any significant
+ * problem anyway.
+ */
+ for_each_dbuf_slice_in_mask(i915, slice, dbuf_mask)
+ crtc_bw->used_bw[slice] += data_rate;
+ }
+}
+
int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
@@ -687,50 +729,13 @@ int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
int i;
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- enum plane_id plane_id;
- struct intel_dbuf_bw *crtc_bw;
-
new_bw_state = intel_atomic_get_bw_state(state);
if (IS_ERR(new_bw_state))
return PTR_ERR(new_bw_state);
old_bw_state = intel_atomic_get_old_bw_state(state);
- crtc_bw = &new_bw_state->dbuf_bw[crtc->pipe];
-
- memset(&crtc_bw->used_bw, 0, sizeof(crtc_bw->used_bw));
-
- if (!crtc_state->hw.active)
- continue;
-
- for_each_plane_id_on_crtc(crtc, plane_id) {
- const struct skl_ddb_entry *plane_alloc =
- &crtc_state->wm.skl.plane_ddb_y[plane_id];
- const struct skl_ddb_entry *uv_plane_alloc =
- &crtc_state->wm.skl.plane_ddb_uv[plane_id];
- unsigned int data_rate = crtc_state->data_rate[plane_id];
- unsigned int dbuf_mask = 0;
- enum dbuf_slice slice;
-
- dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, plane_alloc);
- dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, uv_plane_alloc);
-
- /*
- * FIXME: To calculate that more properly we probably
- * need to to split per plane data_rate into data_rate_y
- * and data_rate_uv for multiplanar formats in order not
- * to get accounted those twice if they happen to reside
- * on different slices.
- * However for pre-icl this would work anyway because
- * we have only single slice and for icl+ uv plane has
- * non-zero data rate.
- * So in worst case those calculation are a bit
- * pessimistic, which shouldn't pose any significant
- * problem anyway.
- */
- for_each_dbuf_slice_in_mask(dev_priv, slice, dbuf_mask)
- crtc_bw->used_bw[slice] += data_rate;
- }
+ skl_crtc_calc_dbuf_bw(new_bw_state, crtc_state);
}
if (!old_bw_state)
@@ -811,25 +816,11 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state)
return 0;
}
-int intel_bw_atomic_check(struct intel_atomic_state *state)
+static u16 icl_qgv_points_mask(struct drm_i915_private *i915)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
- struct intel_crtc_state *new_crtc_state, *old_crtc_state;
- struct intel_bw_state *new_bw_state = NULL;
- const struct intel_bw_state *old_bw_state = NULL;
- unsigned int data_rate;
- unsigned int num_active_planes;
- struct intel_crtc *crtc;
- int i, ret;
- u32 allowed_points = 0;
- unsigned int max_bw_point = 0, max_bw = 0;
- unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
- unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
- u32 mask = 0;
-
- /* FIXME earlier gens need some checks too */
- if (DISPLAY_VER(dev_priv) < 11)
- return 0;
+ unsigned int num_psf_gv_points = i915->max_bw[0].num_psf_gv_points;
+ unsigned int num_qgv_points = i915->max_bw[0].num_qgv_points;
+ u16 mask = 0;
/*
* We can _not_ use the whole ADLS_QGV_PT_MASK here, as PCode rejects
@@ -842,6 +833,16 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
if (num_psf_gv_points > 0)
mask |= REG_GENMASK(num_psf_gv_points - 1, 0) << ADLS_PSF_PT_SHIFT;
+ return mask;
+}
+
+static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *changed)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
+ struct intel_crtc *crtc;
+ int i;
+
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
unsigned int old_data_rate =
@@ -852,6 +853,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
intel_bw_crtc_num_active_planes(old_crtc_state);
unsigned int new_active_planes =
intel_bw_crtc_num_active_planes(new_crtc_state);
+ struct intel_bw_state *new_bw_state;
/*
* Avoid locking the bw state when
@@ -868,14 +870,53 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
new_bw_state->data_rate[crtc->pipe] = new_data_rate;
new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;
- drm_dbg_kms(&dev_priv->drm,
- "pipe %c data rate %u num active planes %u\n",
- pipe_name(crtc->pipe),
+ *changed = true;
+
+ drm_dbg_kms(&i915->drm,
+ "[CRTC:%d:%s] data rate %u num active planes %u\n",
+ crtc->base.base.id, crtc->base.name,
new_bw_state->data_rate[crtc->pipe],
new_bw_state->num_active_planes[crtc->pipe]);
}
- if (!new_bw_state)
+ return 0;
+}
+
+int intel_bw_atomic_check(struct intel_atomic_state *state)
+{
+ struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ const struct intel_bw_state *old_bw_state;
+ struct intel_bw_state *new_bw_state;
+ unsigned int data_rate;
+ unsigned int num_active_planes;
+ int i, ret;
+ u32 allowed_points = 0;
+ unsigned int max_bw_point = 0, max_bw = 0;
+ unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
+ unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
+ bool changed = false;
+
+ /* FIXME earlier gens need some checks too */
+ if (DISPLAY_VER(dev_priv) < 11)
+ return 0;
+
+ ret = intel_bw_check_data_rate(state, &changed);
+ if (ret)
+ return ret;
+
+ old_bw_state = intel_atomic_get_old_bw_state(state);
+ new_bw_state = intel_atomic_get_new_bw_state(state);
+
+ if (new_bw_state &&
+ intel_can_enable_sagv(dev_priv, old_bw_state) !=
+ intel_can_enable_sagv(dev_priv, new_bw_state))
+ changed = true;
+
+ /*
+ * If none of our inputs (data rates, number of active
+ * planes, SAGV yes/no) changed then nothing to do here.
+ */
+ if (!changed)
return 0;
ret = intel_atomic_lock_global_state(&new_bw_state->base);
@@ -959,9 +1000,9 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
* We store the ones which need to be masked as that is what PCode
* actually accepts as a parameter.
*/
- new_bw_state->qgv_points_mask = ~allowed_points & mask;
+ new_bw_state->qgv_points_mask = ~allowed_points &
+ icl_qgv_points_mask(dev_priv);
- old_bw_state = intel_atomic_get_old_bw_state(state);
/*
* If the actual mask had changed we need to make sure that
* the commits are serialized(in case this is a nomodeset, nonblocking)
diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
index 46c6eecbd917..0ceaed1c9656 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -30,19 +30,19 @@ struct intel_bw_state {
*/
u8 pipe_sagv_reject;
+ /* bitmask of active pipes */
+ u8 active_pipes;
+
/*
* Current QGV points mask, which restricts
* some particular SAGV states, not to confuse
* with pipe_sagv_mask.
*/
- u8 qgv_points_mask;
+ u16 qgv_points_mask;
unsigned int data_rate[I915_MAX_PIPES];
u8 num_active_planes[I915_MAX_PIPES];
- /* bitmask of active pipes */
- u8 active_pipes;
-
int min_cdclk;
};
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index c30cf8d2b835..8888fda8b701 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -23,6 +23,7 @@
#include <linux/time.h>
+#include "hsw_ips.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_audio.h"
@@ -31,6 +32,8 @@
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
+#include "intel_mchbar_regs.h"
+#include "intel_pci_config.h"
#include "intel_pcode.h"
#include "intel_psr.h"
#include "vlv_sideband.h"
@@ -63,6 +66,17 @@
* dividers can be programmed correctly.
*/
+struct intel_cdclk_funcs {
+ void (*get_cdclk)(struct drm_i915_private *i915,
+ struct intel_cdclk_config *cdclk_config);
+ void (*set_cdclk)(struct drm_i915_private *i915,
+ const struct intel_cdclk_config *cdclk_config,
+ enum pipe pipe);
+ int (*bw_calc_min_cdclk)(struct intel_atomic_state *state);
+ int (*modeset_calc_cdclk)(struct intel_cdclk_state *state);
+ u8 (*calc_voltage_level)(int cdclk);
+};
+
void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,
struct intel_cdclk_config *cdclk_config)
{
@@ -793,8 +807,7 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
"trying to change cdclk frequency with cdclk not enabled\n"))
return;
- ret = sandybridge_pcode_write(dev_priv,
- BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
+ ret = snb_pcode_write(dev_priv, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
if (ret) {
drm_err(&dev_priv->drm,
"failed to inform pcode about cdclk change\n");
@@ -822,8 +835,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n");
- sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
- cdclk_config->voltage_level);
+ snb_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
+ cdclk_config->voltage_level);
intel_de_write(dev_priv, CDCLK_FREQ,
DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
@@ -1126,8 +1139,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
intel_de_posting_read(dev_priv, CDCLK_CTL);
/* inform PCU of the change */
- sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
- cdclk_config->voltage_level);
+ snb_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
+ cdclk_config->voltage_level);
intel_update_cdclk(dev_priv);
}
@@ -1145,7 +1158,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
goto sanitize;
intel_update_cdclk(dev_priv);
- intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK");
+ intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
/* Is PLL enabled and locked ? */
if (dev_priv->cdclk.hw.vco == 0 ||
@@ -1614,7 +1627,7 @@ static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)
/* Timeout 200us */
if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1))
- DRM_ERROR("timeout waiting for FREQ change request ack\n");
+ drm_err(&dev_priv->drm, "timeout waiting for FREQ change request ack\n");
val &= ~BXT_DE_PLL_FREQ_REQ;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
@@ -1705,10 +1718,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
* BSpec requires us to wait up to 150usec, but that leads to
* timeouts; the 2ms used here is based on experiment.
*/
- ret = sandybridge_pcode_write_timeout(dev_priv,
- HSW_PCODE_DE_WRITE_FREQ_REQ,
- 0x80000000, 150, 2);
-
+ ret = snb_pcode_write_timeout(dev_priv,
+ HSW_PCODE_DE_WRITE_FREQ_REQ,
+ 0x80000000, 150, 2);
if (ret) {
drm_err(&dev_priv->drm,
"Failed to inform PCU about cdclk change (err %d, freq %d)\n",
@@ -1769,8 +1781,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe));
if (DISPLAY_VER(dev_priv) >= 11) {
- ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
- cdclk_config->voltage_level);
+ ret = snb_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
+ cdclk_config->voltage_level);
} else {
/*
* The timeout isn't specified, the 2ms used here is based on
@@ -1778,10 +1790,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
* FIXME: Waiting for the request completion could be delayed
* until the next PCODE request based on BSpec.
*/
- ret = sandybridge_pcode_write_timeout(dev_priv,
- HSW_PCODE_DE_WRITE_FREQ_REQ,
- cdclk_config->voltage_level,
- 150, 2);
+ ret = snb_pcode_write_timeout(dev_priv,
+ HSW_PCODE_DE_WRITE_FREQ_REQ,
+ cdclk_config->voltage_level,
+ 150, 2);
}
if (ret) {
@@ -1807,7 +1819,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
int cdclk, clock, vco;
intel_update_cdclk(dev_priv);
- intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK");
+ intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
if (dev_priv->cdclk.hw.vco == 0 ||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
@@ -2047,13 +2059,14 @@ static bool intel_cdclk_changed(const struct intel_cdclk_config *a,
a->voltage_level != b->voltage_level;
}
-void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config,
+void intel_cdclk_dump_config(struct drm_i915_private *i915,
+ const struct intel_cdclk_config *cdclk_config,
const char *context)
{
- DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n",
- context, cdclk_config->cdclk, cdclk_config->vco,
- cdclk_config->ref, cdclk_config->bypass,
- cdclk_config->voltage_level);
+ drm_dbg_kms(&i915->drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n",
+ context, cdclk_config->cdclk, cdclk_config->vco,
+ cdclk_config->ref, cdclk_config->bypass,
+ cdclk_config->voltage_level);
}
/**
@@ -2077,7 +2090,7 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv,
if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->cdclk_funcs->set_cdclk))
return;
- intel_dump_cdclk_config(cdclk_config, "Changing CDCLK to");
+ intel_cdclk_dump_config(dev_priv, cdclk_config, "Changing CDCLK to");
for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -2120,8 +2133,8 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv,
if (drm_WARN(&dev_priv->drm,
intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config),
"cdclk state doesn't match!\n")) {
- intel_dump_cdclk_config(&dev_priv->cdclk.hw, "[hw state]");
- intel_dump_cdclk_config(cdclk_config, "[sw state]");
+ intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "[hw state]");
+ intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]");
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h
index fc638522e445..df66f66fbad0 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -8,7 +8,6 @@
#include <linux/types.h>
-#include "i915_drv.h"
#include "intel_display.h"
#include "intel_global_state.h"
@@ -16,6 +15,11 @@ struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc_state;
+struct intel_cdclk_config {
+ unsigned int cdclk, vco, ref, bypass;
+ u8 voltage_level;
+};
+
struct intel_cdclk_state {
struct intel_global_state base;
@@ -58,7 +62,8 @@ bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b);
void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state);
void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state);
-void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config,
+void intel_cdclk_dump_config(struct drm_i915_private *i915,
+ const struct intel_cdclk_config *cdclk_config,
const char *context);
int intel_modeset_calc_cdclk(struct intel_atomic_state *state);
void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index de3ded1e327a..e94ec57260f1 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -28,6 +28,25 @@
#include "intel_dpll.h"
#include "vlv_dsi_pll.h"
+struct intel_color_funcs {
+ int (*color_check)(struct intel_crtc_state *crtc_state);
+ /*
+ * Program double buffered color management registers during
+ * vblank evasion. The registers should then latch during the
+ * next vblank start, alongside any other double buffered registers
+ * involved with the same commit.
+ */
+ void (*color_commit)(const struct intel_crtc_state *crtc_state);
+ /*
+ * Load LUTs (and other single buffered color management
+ * registers). Will (hopefully) be called during the vblank
+ * following the latching of any double buffered registers
+ * involved with the same commit.
+ */
+ void (*load_luts)(const struct intel_crtc_state *crtc_state);
+ void (*read_luts)(struct intel_crtc_state *crtc_state);
+};
+
#define CTM_COEFF_SIGN (1ULL << 63)
#define CTM_COEFF_1_0 (1ULL << 32)
@@ -160,29 +179,29 @@ static void ilk_update_pipe_csc(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- intel_de_write(dev_priv, PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
- intel_de_write(dev_priv, PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
- intel_de_write(dev_priv, PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
- intel_de_write(dev_priv, PIPE_CSC_COEFF_RY_GY(pipe),
- coeff[0] << 16 | coeff[1]);
- intel_de_write(dev_priv, PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
+ intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_RY_GY(pipe),
+ coeff[0] << 16 | coeff[1]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
- intel_de_write(dev_priv, PIPE_CSC_COEFF_RU_GU(pipe),
- coeff[3] << 16 | coeff[4]);
- intel_de_write(dev_priv, PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
+ intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_RU_GU(pipe),
+ coeff[3] << 16 | coeff[4]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
- intel_de_write(dev_priv, PIPE_CSC_COEFF_RV_GV(pipe),
- coeff[6] << 16 | coeff[7]);
- intel_de_write(dev_priv, PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
+ intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_RV_GV(pipe),
+ coeff[6] << 16 | coeff[7]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
if (DISPLAY_VER(dev_priv) >= 7) {
- intel_de_write(dev_priv, PIPE_CSC_POSTOFF_HI(pipe),
- postoff[0]);
- intel_de_write(dev_priv, PIPE_CSC_POSTOFF_ME(pipe),
- postoff[1]);
- intel_de_write(dev_priv, PIPE_CSC_POSTOFF_LO(pipe),
- postoff[2]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_POSTOFF_HI(pipe),
+ postoff[0]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_POSTOFF_ME(pipe),
+ postoff[1]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_POSTOFF_LO(pipe),
+ postoff[2]);
}
}
@@ -194,28 +213,28 @@ static void icl_update_output_csc(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
- coeff[0] << 16 | coeff[1]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
- coeff[2] << 16);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
+ coeff[0] << 16 | coeff[1]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
+ coeff[2] << 16);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
- coeff[3] << 16 | coeff[4]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
- coeff[5] << 16);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
+ coeff[3] << 16 | coeff[4]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
+ coeff[5] << 16);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
- coeff[6] << 16 | coeff[7]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
- coeff[8] << 16);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
+ coeff[6] << 16 | coeff[7]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
+ coeff[8] << 16);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
- intel_de_write(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
+ intel_de_write_fw(dev_priv, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
}
static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
@@ -319,8 +338,8 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
ilk_csc_off_zero);
}
- intel_de_write(dev_priv, PIPE_CSC_MODE(crtc->pipe),
- crtc_state->csc_mode);
+ intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
+ crtc_state->csc_mode);
}
static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
@@ -346,8 +365,8 @@ static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
ilk_csc_postoff_limited_range);
}
- intel_de_write(dev_priv, PIPE_CSC_MODE(crtc->pipe),
- crtc_state->csc_mode);
+ intel_de_write_fw(dev_priv, PIPE_CSC_MODE(crtc->pipe),
+ crtc_state->csc_mode);
}
static void chv_load_cgm_csc(struct intel_crtc *crtc,
@@ -377,16 +396,16 @@ static void chv_load_cgm_csc(struct intel_crtc *crtc,
coeffs[i] |= (abs_coeff >> 20) & 0xfff;
}
- intel_de_write(dev_priv, CGM_PIPE_CSC_COEFF01(pipe),
- coeffs[1] << 16 | coeffs[0]);
- intel_de_write(dev_priv, CGM_PIPE_CSC_COEFF23(pipe),
- coeffs[3] << 16 | coeffs[2]);
- intel_de_write(dev_priv, CGM_PIPE_CSC_COEFF45(pipe),
- coeffs[5] << 16 | coeffs[4]);
- intel_de_write(dev_priv, CGM_PIPE_CSC_COEFF67(pipe),
- coeffs[7] << 16 | coeffs[6]);
- intel_de_write(dev_priv, CGM_PIPE_CSC_COEFF8(pipe),
- coeffs[8]);
+ intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF01(pipe),
+ coeffs[1] << 16 | coeffs[0]);
+ intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF23(pipe),
+ coeffs[3] << 16 | coeffs[2]);
+ intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF45(pipe),
+ coeffs[5] << 16 | coeffs[4]);
+ intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF67(pipe),
+ coeffs[7] << 16 | coeffs[6]);
+ intel_de_write_fw(dev_priv, CGM_PIPE_CSC_COEFF8(pipe),
+ coeffs[8]);
}
/* convert hw value with given bit_precision to lut property val */
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index f628e0542933..4dfe77351b8b 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -4,6 +4,7 @@
*/
#include "intel_combo_phy.h"
+#include "intel_combo_phy_regs.h"
#include "intel_de.h"
#include "intel_display_types.h"
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
new file mode 100644
index 000000000000..2ed65193ca19
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __INTEL_COMBO_PHY_REGS__
+#define __INTEL_COMBO_PHY_REGS__
+
+#include "i915_reg_defs.h"
+
+#define _ICL_COMBOPHY_A 0x162000
+#define _ICL_COMBOPHY_B 0x6C000
+#define _EHL_COMBOPHY_C 0x160000
+#define _RKL_COMBOPHY_D 0x161000
+#define _ADL_COMBOPHY_E 0x16B000
+
+#define _ICL_COMBOPHY(phy) _PICK(phy, _ICL_COMBOPHY_A, \
+ _ICL_COMBOPHY_B, \
+ _EHL_COMBOPHY_C, \
+ _RKL_COMBOPHY_D, \
+ _ADL_COMBOPHY_E)
+
+/* ICL Port CL_DW registers */
+#define _ICL_PORT_CL_DW(dw, phy) (_ICL_COMBOPHY(phy) + \
+ 4 * (dw))
+
+#define ICL_PORT_CL_DW5(phy) _MMIO(_ICL_PORT_CL_DW(5, phy))
+#define CL_POWER_DOWN_ENABLE (1 << 4)
+#define SUS_CLOCK_CONFIG (3 << 0)
+
+#define ICL_PORT_CL_DW10(phy) _MMIO(_ICL_PORT_CL_DW(10, phy))
+#define PG_SEQ_DELAY_OVERRIDE_MASK (3 << 25)
+#define PG_SEQ_DELAY_OVERRIDE_SHIFT 25
+#define PG_SEQ_DELAY_OVERRIDE_ENABLE (1 << 24)
+#define PWR_UP_ALL_LANES (0x0 << 4)
+#define PWR_DOWN_LN_3_2_1 (0xe << 4)
+#define PWR_DOWN_LN_3_2 (0xc << 4)
+#define PWR_DOWN_LN_3 (0x8 << 4)
+#define PWR_DOWN_LN_2_1_0 (0x7 << 4)
+#define PWR_DOWN_LN_1_0 (0x3 << 4)
+#define PWR_DOWN_LN_3_1 (0xa << 4)
+#define PWR_DOWN_LN_3_1_0 (0xb << 4)
+#define PWR_DOWN_LN_MASK (0xf << 4)
+#define PWR_DOWN_LN_SHIFT 4
+#define EDP4K2K_MODE_OVRD_EN (1 << 3)
+#define EDP4K2K_MODE_OVRD_OPTIMIZED (1 << 2)
+
+#define ICL_PORT_CL_DW12(phy) _MMIO(_ICL_PORT_CL_DW(12, phy))
+#define ICL_LANE_ENABLE_AUX (1 << 0)
+
+/* ICL Port COMP_DW registers */
+#define _ICL_PORT_COMP 0x100
+#define _ICL_PORT_COMP_DW(dw, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_COMP + 4 * (dw))
+
+#define ICL_PORT_COMP_DW0(phy) _MMIO(_ICL_PORT_COMP_DW(0, phy))
+#define COMP_INIT (1 << 31)
+
+#define ICL_PORT_COMP_DW1(phy) _MMIO(_ICL_PORT_COMP_DW(1, phy))
+
+#define ICL_PORT_COMP_DW3(phy) _MMIO(_ICL_PORT_COMP_DW(3, phy))
+#define PROCESS_INFO_DOT_0 (0 << 26)
+#define PROCESS_INFO_DOT_1 (1 << 26)
+#define PROCESS_INFO_DOT_4 (2 << 26)
+#define PROCESS_INFO_MASK (7 << 26)
+#define PROCESS_INFO_SHIFT 26
+#define VOLTAGE_INFO_0_85V (0 << 24)
+#define VOLTAGE_INFO_0_95V (1 << 24)
+#define VOLTAGE_INFO_1_05V (2 << 24)
+#define VOLTAGE_INFO_MASK (3 << 24)
+#define VOLTAGE_INFO_SHIFT 24
+
+#define ICL_PORT_COMP_DW8(phy) _MMIO(_ICL_PORT_COMP_DW(8, phy))
+#define IREFGEN (1 << 24)
+
+#define ICL_PORT_COMP_DW9(phy) _MMIO(_ICL_PORT_COMP_DW(9, phy))
+
+#define ICL_PORT_COMP_DW10(phy) _MMIO(_ICL_PORT_COMP_DW(10, phy))
+
+/* ICL Port PCS registers */
+#define _ICL_PORT_PCS_AUX 0x300
+#define _ICL_PORT_PCS_GRP 0x600
+#define _ICL_PORT_PCS_LN(ln) (0x800 + (ln) * 0x100)
+#define _ICL_PORT_PCS_DW_AUX(dw, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_PCS_AUX + 4 * (dw))
+#define _ICL_PORT_PCS_DW_GRP(dw, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_PCS_GRP + 4 * (dw))
+#define _ICL_PORT_PCS_DW_LN(dw, ln, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_PCS_LN(ln) + 4 * (dw))
+#define ICL_PORT_PCS_DW1_AUX(phy) _MMIO(_ICL_PORT_PCS_DW_AUX(1, phy))
+#define ICL_PORT_PCS_DW1_GRP(phy) _MMIO(_ICL_PORT_PCS_DW_GRP(1, phy))
+#define ICL_PORT_PCS_DW1_LN(ln, phy) _MMIO(_ICL_PORT_PCS_DW_LN(1, ln, phy))
+#define DCC_MODE_SELECT_MASK (0x3 << 20)
+#define DCC_MODE_SELECT_CONTINUOSLY (0x3 << 20)
+#define COMMON_KEEPER_EN (1 << 26)
+#define LATENCY_OPTIM_MASK (0x3 << 2)
+#define LATENCY_OPTIM_VAL(x) ((x) << 2)
+
+/* ICL Port TX registers */
+#define _ICL_PORT_TX_AUX 0x380
+#define _ICL_PORT_TX_GRP 0x680
+#define _ICL_PORT_TX_LN(ln) (0x880 + (ln) * 0x100)
+
+#define _ICL_PORT_TX_DW_AUX(dw, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_TX_AUX + 4 * (dw))
+#define _ICL_PORT_TX_DW_GRP(dw, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_TX_GRP + 4 * (dw))
+#define _ICL_PORT_TX_DW_LN(dw, ln, phy) (_ICL_COMBOPHY(phy) + \
+ _ICL_PORT_TX_LN(ln) + 4 * (dw))
+
+#define ICL_PORT_TX_DW2_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(2, phy))
+#define ICL_PORT_TX_DW2_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(2, phy))
+#define ICL_PORT_TX_DW2_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(2, ln, phy))
+#define SWING_SEL_UPPER(x) (((x) >> 3) << 15)
+#define SWING_SEL_UPPER_MASK (1 << 15)
+#define SWING_SEL_LOWER(x) (((x) & 0x7) << 11)
+#define SWING_SEL_LOWER_MASK (0x7 << 11)
+#define FRC_LATENCY_OPTIM_MASK (0x7 << 8)
+#define FRC_LATENCY_OPTIM_VAL(x) ((x) << 8)
+#define RCOMP_SCALAR(x) ((x) << 0)
+#define RCOMP_SCALAR_MASK (0xFF << 0)
+
+#define ICL_PORT_TX_DW4_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(4, phy))
+#define ICL_PORT_TX_DW4_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(4, phy))
+#define ICL_PORT_TX_DW4_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(4, ln, phy))
+#define LOADGEN_SELECT (1 << 31)
+#define POST_CURSOR_1(x) ((x) << 12)
+#define POST_CURSOR_1_MASK (0x3F << 12)
+#define POST_CURSOR_2(x) ((x) << 6)
+#define POST_CURSOR_2_MASK (0x3F << 6)
+#define CURSOR_COEFF(x) ((x) << 0)
+#define CURSOR_COEFF_MASK (0x3F << 0)
+
+#define ICL_PORT_TX_DW5_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(5, phy))
+#define ICL_PORT_TX_DW5_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(5, phy))
+#define ICL_PORT_TX_DW5_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(5, ln, phy))
+#define TX_TRAINING_EN (1 << 31)
+#define TAP2_DISABLE (1 << 30)
+#define TAP3_DISABLE (1 << 29)
+#define SCALING_MODE_SEL(x) ((x) << 18)
+#define SCALING_MODE_SEL_MASK (0x7 << 18)
+#define RTERM_SELECT(x) ((x) << 3)
+#define RTERM_SELECT_MASK (0x7 << 3)
+
+#define ICL_PORT_TX_DW7_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(7, phy))
+#define ICL_PORT_TX_DW7_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(7, phy))
+#define ICL_PORT_TX_DW7_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(7, ln, phy))
+#define N_SCALAR(x) ((x) << 24)
+#define N_SCALAR_MASK (0x7F << 24)
+
+#define ICL_PORT_TX_DW8_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(8, phy))
+#define ICL_PORT_TX_DW8_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(8, phy))
+#define ICL_PORT_TX_DW8_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(8, ln, phy))
+#define ICL_PORT_TX_DW8_ODCC_CLK_SEL REG_BIT(31)
+#define ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK REG_GENMASK(30, 29)
+#define ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2 REG_FIELD_PREP(ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK, 0x1)
+
+#define _ICL_DPHY_CHKN_REG 0x194
+#define ICL_DPHY_CHKN(port) _MMIO(_ICL_COMBOPHY(port) + _ICL_DPHY_CHKN_REG)
+#define ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP REG_BIT(7)
+
+#endif /* __INTEL_COMBO_PHY_REGS__ */
diff --git a/drivers/gpu/drm/i915/display/intel_crt.h b/drivers/gpu/drm/i915/display/intel_crt.h
index 6c5c44600cbd..c6071efd93ce 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.h
+++ b/drivers/gpu/drm/i915/display/intel_crt.h
@@ -6,7 +6,7 @@
#ifndef __INTEL_CRT_H__
#define __INTEL_CRT_H__
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
enum pipe;
struct drm_encoder;
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 16c3ca66d9f0..08ee3e17ee5c 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -12,6 +12,7 @@
#include <drm/drm_plane_helper.h>
#include <drm/drm_vblank_work.h>
+#include "i915_irq.h"
#include "i915_vgpu.h"
#include "i9xx_plane.h"
#include "icl_dsi.h"
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 16d34685d83f..2ade8fdd9bdd 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -51,16 +51,16 @@ static u32 intel_cursor_position(const struct intel_plane_state *plane_state)
u32 pos = 0;
if (x < 0) {
- pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
+ pos |= CURSOR_POS_X_SIGN;
x = -x;
}
- pos |= x << CURSOR_X_SHIFT;
+ pos |= CURSOR_POS_X(x);
if (y < 0) {
- pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
+ pos |= CURSOR_POS_Y_SIGN;
y = -y;
}
- pos |= y << CURSOR_Y_SHIFT;
+ pos |= CURSOR_POS_Y(y);
return pos;
}
@@ -180,7 +180,7 @@ static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 cntl = 0;
if (crtc_state->gamma_enable)
- cntl |= CURSOR_GAMMA_ENABLE;
+ cntl |= CURSOR_PIPE_GAMMA_ENABLE;
return cntl;
}
@@ -264,7 +264,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
cntl = plane_state->ctl |
i845_cursor_ctl_crtc(crtc_state);
- size = (height << 12) | width;
+ size = CURSOR_HEIGHT(height) | CURSOR_WIDTH(width);
base = intel_cursor_base(plane_state);
pos = intel_cursor_position(plane_state);
@@ -280,7 +280,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
plane->cursor.cntl != cntl) {
intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0);
intel_de_write_fw(dev_priv, CURBASE(PIPE_A), base);
- intel_de_write_fw(dev_priv, CURSIZE, size);
+ intel_de_write_fw(dev_priv, CURSIZE(PIPE_A), size);
intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl);
@@ -340,13 +340,13 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
return cntl;
if (crtc_state->gamma_enable)
- cntl = MCURSOR_GAMMA_ENABLE;
+ cntl = MCURSOR_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
cntl |= MCURSOR_PIPE_CSC_ENABLE;
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
- cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
+ cntl |= MCURSOR_PIPE_SEL(crtc->pipe);
return cntl;
}
@@ -502,7 +502,7 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
i9xx_cursor_ctl_crtc(crtc_state);
if (width != height)
- fbc_ctl = CUR_FBC_CTL_EN | (height - 1);
+ fbc_ctl = CUR_FBC_EN | CUR_FBC_HEIGHT(height - 1);
base = intel_cursor_base(plane_state);
pos = intel_cursor_position(plane_state);
@@ -586,13 +586,12 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
val = intel_de_read(dev_priv, CURCNTR(plane->pipe));
- ret = val & MCURSOR_MODE;
+ ret = val & MCURSOR_MODE_MASK;
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
*pipe = plane->pipe;
else
- *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
- MCURSOR_PIPE_SELECT_SHIFT;
+ *pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val);
intel_display_power_put(dev_priv, power_domain, wakeref);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index cab505277595..e4260806c2a4 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -32,6 +32,7 @@
#include "intel_audio.h"
#include "intel_backlight.h"
#include "intel_combo_phy.h"
+#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
@@ -56,6 +57,7 @@
#include "intel_snps_phy.h"
#include "intel_sprite.h"
#include "intel_tc.h"
+#include "intel_tc_phy_regs.h"
#include "intel_vdsc.h"
#include "intel_vrr.h"
#include "skl_scaler.h"
@@ -2287,116 +2289,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state)
OVERLAP_PIXELS_MASK, dss1);
}
-static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,
- struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- const struct drm_connector_state *conn_state)
-{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
- bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
-
- intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
- crtc_state->lane_count);
-
- /*
- * We only configure what the register value will be here. Actual
- * enabling happens during link training farther down.
- */
- intel_ddi_init_dp_buf_reg(encoder, crtc_state);
-
- /*
- * 1. Enable Power Wells
- *
- * This was handled at the beginning of intel_atomic_commit_tail(),
- * before we called down into this function.
- */
-
- /* 2. Enable Panel Power if PPS is required */
- intel_pps_on(intel_dp);
-
- /*
- * 3. Enable the port PLL.
- */
- intel_ddi_enable_clock(encoder, crtc_state);
-
- /* 4. Enable IO power */
- if (!intel_tc_port_in_tbt_alt_mode(dig_port))
- dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
- dig_port->ddi_io_power_domain);
-
- /*
- * 5. The rest of the below are substeps under the bspec's "Enable and
- * Train Display Port" step. Note that steps that are specific to
- * MST will be handled by intel_mst_pre_enable_dp() before/after it
- * calls into this function. Also intel_mst_pre_enable_dp() only calls
- * us when active_mst_links==0, so any steps designated for "single
- * stream or multi-stream master transcoder" can just be performed
- * unconditionally here.
- */
-
- /*
- * 5.a Configure Transcoder Clock Select to direct the Port clock to the
- * Transcoder.
- */
- intel_ddi_enable_pipe_clock(encoder, crtc_state);
-
- /* 5.b Configure transcoder for DP 2.0 128b/132b */
- intel_ddi_config_transcoder_dp2(encoder, crtc_state);
-
- /*
- * 5.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
- * Transport Select
- */
- intel_ddi_config_transcoder_func(encoder, crtc_state);
-
- /*
- * 5.d Configure & enable DP_TP_CTL with link training pattern 1
- * selected
- *
- * This will be handled by the intel_dp_start_link_train() farther
- * down this function.
- */
-
- /* 5.e Configure voltage swing and related IO settings */
- encoder->set_signal_levels(encoder, crtc_state);
-
- if (!is_mst)
- intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
-
- intel_dp_configure_protocol_converter(intel_dp, crtc_state);
- intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
- /*
- * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
- * in the FEC_CONFIGURATION register to 1 before initiating link
- * training
- */
- intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
- intel_dp_check_frl_training(intel_dp);
- intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
-
- /*
- * 5.h Follow DisplayPort specification training sequence (see notes for
- * failure handling)
- * 5.i If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle
- * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
- * (timeout after 800 us)
- */
- intel_dp_start_link_train(intel_dp, crtc_state);
-
- /* 5.j Set DP_TP_CTL link training to Normal */
- if (!is_trans_port_sync_mode(crtc_state))
- intel_dp_stop_link_train(intel_dp, crtc_state);
-
- /* 5.k Configure and enable FEC if needed */
- intel_ddi_enable_fec(encoder, crtc_state);
-
- intel_dsc_dp_pps_write(encoder, crtc_state);
-
- intel_dsc_enable(crtc_state);
-}
-
static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@@ -2470,6 +2362,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
*/
intel_ddi_enable_pipe_clock(encoder, crtc_state);
+ if (HAS_DP20(dev_priv))
+ intel_ddi_config_transcoder_dp2(encoder, crtc_state);
+
/*
* 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
* Transport Select
@@ -2530,9 +2425,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_enable_fec(encoder, crtc_state);
intel_dsc_dp_pps_write(encoder, crtc_state);
-
- if (!crtc_state->bigjoiner)
- intel_dsc_enable(crtc_state);
}
static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -2598,9 +2490,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_enable_pipe_clock(encoder, crtc_state);
intel_dsc_dp_pps_write(encoder, crtc_state);
-
- if (!crtc_state->bigjoiner)
- intel_dsc_enable(crtc_state);
}
static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -2610,9 +2499,7 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- if (IS_DG2(dev_priv))
- dg2_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
- else if (DISPLAY_VER(dev_priv) >= 12)
+ if (DISPLAY_VER(dev_priv) >= 12)
tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
else
hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
@@ -2620,11 +2507,8 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
/* MST will call a setting of MSA after an allocating of Virtual Channel
* from MST encoder pre_enable callback.
*/
- if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
+ if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
intel_ddi_set_dp_msa(crtc_state, conn_state);
-
- intel_dp_set_m_n(crtc_state, M1_N1);
- }
}
static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
@@ -2819,6 +2703,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
bool is_tc_port = intel_phy_is_tc(dev_priv, phy);
+ struct intel_crtc *slave_crtc;
if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
intel_crtc_vblank_off(old_crtc_state);
@@ -2837,9 +2722,8 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
ilk_pfit_disable(old_crtc_state);
}
- if (old_crtc_state->bigjoiner_linked_crtc) {
- struct intel_crtc *slave_crtc =
- old_crtc_state->bigjoiner_linked_crtc;
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc,
+ intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) {
const struct intel_crtc_state *old_slave_crtc_state =
intel_atomic_get_old_crtc_state(state, slave_crtc);
@@ -3042,7 +2926,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
{
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
- if (!crtc_state->bigjoiner_slave)
+ if (!intel_crtc_is_bigjoiner_slave(crtc_state))
intel_ddi_enable_transcoder_func(encoder, crtc_state);
intel_vrr_enable(encoder, crtc_state);
@@ -3157,6 +3041,7 @@ intel_ddi_update_prepare(struct intel_atomic_state *state,
struct intel_encoder *encoder,
struct intel_crtc *crtc)
{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
crtc ? intel_atomic_get_new_crtc_state(state, crtc) : NULL;
int required_lanes = crtc_state ? crtc_state->lane_count : 1;
@@ -3166,11 +3051,12 @@ intel_ddi_update_prepare(struct intel_atomic_state *state,
intel_tc_port_get_link(enc_to_dig_port(encoder),
required_lanes);
if (crtc_state && crtc_state->hw.active) {
- struct intel_crtc *slave_crtc = crtc_state->bigjoiner_linked_crtc;
+ struct intel_crtc *slave_crtc;
intel_update_active_dpll(state, crtc, encoder);
- if (slave_crtc)
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
+ intel_crtc_bigjoiner_slave_pipes(crtc_state))
intel_update_active_dpll(state, slave_crtc, encoder);
}
}
@@ -3215,10 +3101,23 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
crtc_state->lane_lat_optim_mask);
}
+static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ enum tc_port tc_port = intel_port_to_tc(i915, encoder->port);
+ int ln;
+
+ for (ln = 0; ln < 2; ln++) {
+ intel_de_write(i915, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln));
+ intel_de_rmw(i915, DKL_PCS_DW5(tc_port), DKL_PCS_DW5_CORE_SOFTRESET, 0);
+ }
+}
+
static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
- struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port;
u32 dp_tp_ctl, ddi_buf_ctl;
@@ -3254,6 +3153,10 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
+ if (IS_ALDERLAKE_P(dev_priv) &&
+ (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port)))
+ adlp_tbt_to_dp_alt_switch_wa(encoder);
+
intel_dp->DP |= DDI_BUF_CTL_ENABLE;
intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -3471,7 +3374,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
pipe_config->lane_count =
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
- intel_dp_get_m_n(crtc, pipe_config);
+
+ intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
+ &pipe_config->dp_m_n);
+ intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder,
+ &pipe_config->dp_m2_n2);
if (DISPLAY_VER(dev_priv) >= 11) {
i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);
@@ -3508,7 +3415,8 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->mst_master_transcoder =
REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp);
- intel_dp_get_m_n(crtc, pipe_config);
+ intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
+ &pipe_config->dp_m_n);
pipe_config->infoframes.enable |=
intel_hdmi_infoframes_enabled(encoder, pipe_config);
@@ -3797,8 +3705,8 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1,
const struct intel_link_m_n *m_n_2)
{
return m_n_1->tu == m_n_2->tu &&
- m_n_1->gmch_m == m_n_2->gmch_m &&
- m_n_1->gmch_n == m_n_2->gmch_n &&
+ m_n_1->data_m == m_n_2->data_m &&
+ m_n_1->data_n == m_n_2->data_n &&
m_n_1->link_m == m_n_2->link_m &&
m_n_1->link_n == m_n_2->link_n;
}
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index c2fea6562917..d39076facdce 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -6,7 +6,7 @@
#ifndef __INTEL_DDI_H__
#define __INTEL_DDI_H__
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
struct drm_connector_state;
struct drm_i915_private;
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 ed62c35e1518..934a9f9e7dab 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -985,15 +985,15 @@ static const struct intel_ddi_buf_trans adlp_dkl_phy_trans_dp_hbr2_hbr3 = {
};
static const union intel_ddi_buf_trans_entry _dg2_snps_trans[] = {
- { .snps = { 26, 0, 0 } }, /* VS 0, pre-emph 0 */
- { .snps = { 33, 0, 6 } }, /* VS 0, pre-emph 1 */
- { .snps = { 38, 0, 12 } }, /* VS 0, pre-emph 2 */
- { .snps = { 43, 0, 19 } }, /* VS 0, pre-emph 3 */
- { .snps = { 39, 0, 0 } }, /* VS 1, pre-emph 0 */
- { .snps = { 44, 0, 8 } }, /* VS 1, pre-emph 1 */
- { .snps = { 47, 0, 15 } }, /* VS 1, pre-emph 2 */
- { .snps = { 52, 0, 0 } }, /* VS 2, pre-emph 0 */
- { .snps = { 51, 0, 10 } }, /* VS 2, pre-emph 1 */
+ { .snps = { 25, 0, 0 } }, /* VS 0, pre-emph 0 */
+ { .snps = { 32, 0, 6 } }, /* VS 0, pre-emph 1 */
+ { .snps = { 35, 0, 10 } }, /* VS 0, pre-emph 2 */
+ { .snps = { 43, 0, 17 } }, /* VS 0, pre-emph 3 */
+ { .snps = { 35, 0, 0 } }, /* VS 1, pre-emph 0 */
+ { .snps = { 45, 0, 8 } }, /* VS 1, pre-emph 1 */
+ { .snps = { 48, 0, 14 } }, /* VS 1, pre-emph 2 */
+ { .snps = { 47, 0, 0 } }, /* VS 2, pre-emph 0 */
+ { .snps = { 55, 0, 7 } }, /* VS 2, pre-emph 1 */
{ .snps = { 62, 0, 0 } }, /* VS 3, pre-emph 0 */
};
@@ -1005,21 +1005,21 @@ static const struct intel_ddi_buf_trans dg2_snps_trans = {
static const union intel_ddi_buf_trans_entry _dg2_snps_trans_uhbr[] = {
{ .snps = { 62, 0, 0 } }, /* preset 0 */
- { .snps = { 56, 0, 6 } }, /* preset 1 */
- { .snps = { 51, 0, 11 } }, /* preset 2 */
- { .snps = { 48, 0, 14 } }, /* preset 3 */
- { .snps = { 43, 0, 19 } }, /* preset 4 */
+ { .snps = { 55, 0, 7 } }, /* preset 1 */
+ { .snps = { 50, 0, 12 } }, /* preset 2 */
+ { .snps = { 44, 0, 18 } }, /* preset 3 */
+ { .snps = { 35, 0, 21 } }, /* preset 4 */
{ .snps = { 59, 3, 0 } }, /* preset 5 */
{ .snps = { 53, 3, 6 } }, /* preset 6 */
- { .snps = { 49, 3, 10 } }, /* preset 7 */
- { .snps = { 45, 3, 14 } }, /* preset 8 */
- { .snps = { 42, 3, 17 } }, /* preset 9 */
+ { .snps = { 48, 3, 11 } }, /* preset 7 */
+ { .snps = { 42, 5, 15 } }, /* preset 8 */
+ { .snps = { 37, 5, 20 } }, /* preset 9 */
{ .snps = { 56, 6, 0 } }, /* preset 10 */
- { .snps = { 50, 6, 6 } }, /* preset 11 */
- { .snps = { 47, 6, 9 } }, /* preset 12 */
- { .snps = { 42, 6, 14 } }, /* preset 13 */
- { .snps = { 46, 8, 8 } }, /* preset 14 */
- { .snps = { 56, 3, 3 } }, /* preset 15 */
+ { .snps = { 48, 7, 7 } }, /* preset 11 */
+ { .snps = { 45, 7, 10 } }, /* preset 12 */
+ { .snps = { 39, 8, 15 } }, /* preset 13 */
+ { .snps = { 48, 14, 0 } }, /* preset 14 */
+ { .snps = { 45, 4, 4 } }, /* preset 15 */
};
static const struct intel_ddi_buf_trans dg2_snps_trans_uhbr = {
diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h
index 9d8c177aa228..9c104f65e4c8 100644
--- a/drivers/gpu/drm/i915/display/intel_de.h
+++ b/drivers/gpu/drm/i915/display/intel_de.h
@@ -7,7 +7,6 @@
#define __INTEL_DE_H__
#include "i915_drv.h"
-#include "i915_reg.h"
#include "i915_trace.h"
#include "intel_uncore.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 7d558217ca16..80b19c304c43 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -74,6 +74,7 @@
#include "g4x_dp.h"
#include "g4x_hdmi.h"
+#include "hsw_ips.h"
#include "i915_drv.h"
#include "icl_dsi.h"
#include "intel_acpi.h"
@@ -112,15 +113,13 @@
#include "i9xx_plane.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
+#include "vlv_dsi.h"
#include "vlv_dsi_pll.h"
+#include "vlv_dsi_regs.h"
#include "vlv_sideband.h"
-#include "vlv_dsi.h"
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
-static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
- const struct intel_link_m_n *m_n,
- const struct intel_link_m_n *m2_n2);
static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state);
static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state);
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);
@@ -340,10 +339,38 @@ is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
is_trans_port_sync_slave(crtc_state);
}
-static struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state)
+static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state)
+{
+ return ffs(crtc_state->bigjoiner_pipes) - 1;
+}
+
+u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state)
+{
+ return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state));
+}
+
+bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state)
{
- if (crtc_state->bigjoiner_slave)
- return crtc_state->bigjoiner_linked_crtc;
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ return crtc_state->bigjoiner_pipes &&
+ crtc->pipe != bigjoiner_master_pipe(crtc_state);
+}
+
+bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ return crtc_state->bigjoiner_pipes &&
+ crtc->pipe == bigjoiner_master_pipe(crtc_state);
+}
+
+struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ if (intel_crtc_is_bigjoiner_slave(crtc_state))
+ return intel_crtc_for_pipe(i915, bigjoiner_master_pipe(crtc_state));
else
return to_intel_crtc(crtc_state->uapi.crtc);
}
@@ -353,16 +380,10 @@ static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
{
i915_reg_t reg = PIPEDSL(pipe);
u32 line1, line2;
- u32 line_mask;
-
- if (DISPLAY_VER(dev_priv) == 2)
- line_mask = DSL_LINEMASK_GEN2;
- else
- line_mask = DSL_LINEMASK_GEN3;
- line1 = intel_de_read(dev_priv, reg) & line_mask;
+ line1 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
msleep(5);
- line2 = intel_de_read(dev_priv, reg) & line_mask;
+ line2 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
return line1 != line2;
}
@@ -397,13 +418,11 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
if (DISPLAY_VER(dev_priv) >= 4) {
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
- i915_reg_t reg = PIPECONF(cpu_transcoder);
/* Wait for the Pipe State to go off */
- if (intel_de_wait_for_clear(dev_priv, reg,
- I965_PIPECONF_ACTIVE, 100))
- drm_WARN(&dev_priv->drm, 1,
- "pipe_off wait timed out\n");
+ if (intel_de_wait_for_clear(dev_priv, PIPECONF(cpu_transcoder),
+ PIPECONF_STATE_ENABLE, 100))
+ drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n");
} else {
intel_wait_for_pipe_scanline_stopped(crtc);
}
@@ -763,8 +782,11 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc,
crtc_state->data_rate[plane->id] = 0;
crtc_state->min_cdclk[plane->id] = 0;
- if (plane->id == PLANE_PRIMARY)
- hsw_disable_ips(crtc_state);
+ if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 &&
+ hsw_ips_disable(crtc_state)) {
+ crtc_state->ips_enabled = false;
+ intel_crtc_wait_for_next_vblank(crtc);
+ }
/*
* Vblank time updates from the shadow to live plane control register
@@ -1101,72 +1123,6 @@ static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state)
intel_de_write(dev_priv, PF_WIN_SZ(pipe), width << 16 | height);
}
-void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
-
- if (!crtc_state->ips_enabled)
- return;
-
- /*
- * We can only enable IPS after we enable a plane and wait for a vblank
- * This function is called from post_plane_update, which is run after
- * a vblank wait.
- */
- drm_WARN_ON(dev, !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
-
- if (IS_BROADWELL(dev_priv)) {
- drm_WARN_ON(dev, sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL,
- IPS_ENABLE | IPS_PCODE_CONTROL));
- /* Quoting Art Runyan: "its not safe to expect any particular
- * value in IPS_CTL bit 31 after enabling IPS through the
- * mailbox." Moreover, the mailbox may return a bogus state,
- * so we need to just enable it and continue on.
- */
- } else {
- intel_de_write(dev_priv, IPS_CTL, IPS_ENABLE);
- /* The bit only becomes 1 in the next vblank, so this wait here
- * is essentially intel_wait_for_vblank. If we don't have this
- * and don't wait for vblanks until the end of crtc_enable, then
- * the HW state readout code will complain that the expected
- * IPS_CTL value is not the one we read. */
- if (intel_de_wait_for_set(dev_priv, IPS_CTL, IPS_ENABLE, 50))
- drm_err(&dev_priv->drm,
- "Timed out waiting for IPS enable\n");
- }
-}
-
-void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
-
- if (!crtc_state->ips_enabled)
- return;
-
- if (IS_BROADWELL(dev_priv)) {
- drm_WARN_ON(dev,
- sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
- /*
- * Wait for PCODE to finish disabling IPS. The BSpec specified
- * 42ms timeout value leads to occasional timeouts so use 100ms
- * instead.
- */
- if (intel_de_wait_for_clear(dev_priv, IPS_CTL, IPS_ENABLE, 100))
- drm_err(&dev_priv->drm,
- "Timed out waiting for IPS disable\n");
- } else {
- intel_de_write(dev_priv, IPS_CTL, 0);
- intel_de_posting_read(dev_priv, IPS_CTL);
- }
-
- /* We need to wait for a vblank before we can disable the plane. */
- intel_crtc_wait_for_next_vblank(crtc);
-}
-
static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc)
{
if (crtc->overlay)
@@ -1177,67 +1133,6 @@ static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc)
*/
}
-static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_state,
- const struct intel_crtc_state *new_crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
- if (!old_crtc_state->ips_enabled)
- return false;
-
- if (intel_crtc_needs_modeset(new_crtc_state))
- return true;
-
- /*
- * Workaround : Do not read or write the pipe palette/gamma data while
- * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
- *
- * Disable IPS before we program the LUT.
- */
- if (IS_HASWELL(dev_priv) &&
- (new_crtc_state->uapi.color_mgmt_changed ||
- new_crtc_state->update_pipe) &&
- new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
- return true;
-
- return !new_crtc_state->ips_enabled;
-}
-
-static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_state,
- const struct intel_crtc_state *new_crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
- if (!new_crtc_state->ips_enabled)
- return false;
-
- if (intel_crtc_needs_modeset(new_crtc_state))
- return true;
-
- /*
- * Workaround : Do not read or write the pipe palette/gamma data while
- * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
- *
- * Re-enable IPS after the LUT has been programmed.
- */
- if (IS_HASWELL(dev_priv) &&
- (new_crtc_state->uapi.color_mgmt_changed ||
- new_crtc_state->update_pipe) &&
- new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
- return true;
-
- /*
- * We can't read out IPS on broadwell, assume the worst and
- * forcibly enable IPS on the first fastset.
- */
- if (new_crtc_state->update_pipe && old_crtc_state->inherited)
- return true;
-
- return !old_crtc_state->ips_enabled;
-}
-
static bool needs_nv12_wa(const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
@@ -1332,9 +1227,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
if (new_crtc_state->update_wm_post && new_crtc_state->hw.active)
intel_update_watermarks(dev_priv);
- if (hsw_post_update_enable_ips(old_crtc_state, new_crtc_state))
- hsw_enable_ips(new_crtc_state);
-
+ hsw_ips_post_update(state, crtc);
intel_fbc_post_update(state, crtc);
intel_drrs_page_flip(state, crtc);
@@ -1369,7 +1262,8 @@ static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
if (plane->enable_flip_done &&
plane->pipe == crtc->pipe &&
- update_planes & BIT(plane->id))
+ update_planes & BIT(plane->id) &&
+ plane_state->do_async_flip)
plane->enable_flip_done(plane);
}
}
@@ -1387,7 +1281,8 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state,
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
if (plane->disable_flip_done &&
plane->pipe == crtc->pipe &&
- update_planes & BIT(plane->id))
+ update_planes & BIT(plane->id) &&
+ plane_state->do_async_flip)
plane->disable_flip_done(plane);
}
}
@@ -1435,8 +1330,8 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
intel_psr_pre_plane_update(state, crtc);
- if (hsw_pre_update_disable_ips(old_crtc_state, new_crtc_state))
- hsw_disable_ips(old_crtc_state);
+ if (hsw_ips_pre_update(state, crtc))
+ intel_crtc_wait_for_next_vblank(crtc);
if (intel_fbc_pre_update(state, crtc))
intel_crtc_wait_for_next_vblank(crtc);
@@ -1817,6 +1712,26 @@ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_stat
plane->disable_arm(plane, crtc_state);
}
+static void ilk_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+
+ if (crtc_state->has_pch_encoder) {
+ intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
+ &crtc_state->fdi_m_n);
+ } else if (intel_crtc_has_dp_encoder(crtc_state)) {
+ intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
+ &crtc_state->dp_m_n);
+ intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
+ &crtc_state->dp_m2_n2);
+ }
+
+ intel_set_transcoder_timings(crtc_state);
+
+ ilk_set_pipeconf(crtc_state);
+}
+
static void ilk_crtc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -1841,27 +1756,16 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
- if (intel_crtc_has_dp_encoder(new_crtc_state))
- intel_dp_set_m_n(new_crtc_state, M1_N1);
+ ilk_configure_cpu_transcoder(new_crtc_state);
- intel_set_transcoder_timings(new_crtc_state);
intel_set_pipe_src_size(new_crtc_state);
- if (new_crtc_state->has_pch_encoder)
- intel_cpu_transcoder_set_m_n(new_crtc_state,
- &new_crtc_state->fdi_m_n, NULL);
-
- ilk_set_pipeconf(new_crtc_state);
-
crtc->active = true;
intel_encoders_pre_enable(state, crtc);
if (new_crtc_state->has_pch_encoder) {
- /* Note: FDI PLL enabling _must_ be done before we enable the
- * cpu pipes, hence this is separate from all the other fdi/pch
- * enabling. */
- ilk_fdi_pll_enable(new_crtc_state);
+ ilk_pch_pre_enable(state, crtc);
} else {
assert_fdi_tx_disabled(dev_priv, pipe);
assert_fdi_rx_disabled(dev_priv, pipe);
@@ -1905,12 +1809,6 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
}
-/* IPS only exists on ULT machines and is tied to pipe A. */
-static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
-{
- return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
-}
-
static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv,
enum pipe pipe, bool apply)
{
@@ -1974,42 +1872,46 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
- struct intel_crtc_state *master_crtc_state;
- struct intel_crtc *master_crtc;
- struct drm_connector_state *conn_state;
- struct drm_connector *conn;
- struct intel_encoder *encoder = NULL;
- int i;
-
- master_crtc = intel_master_crtc(crtc_state);
- master_crtc_state = intel_atomic_get_new_crtc_state(state, master_crtc);
-
- for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
- if (conn_state->crtc != &master_crtc->base)
- continue;
-
- encoder = to_intel_encoder(conn_state->best_encoder);
- break;
- }
+ struct intel_crtc *master_crtc = intel_master_crtc(crtc_state);
/*
* Enable sequence steps 1-7 on bigjoiner master
*/
- if (crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(crtc_state))
intel_encoders_pre_pll_enable(state, master_crtc);
if (crtc_state->shared_dpll)
intel_enable_shared_dpll(crtc_state);
- if (crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(crtc_state))
intel_encoders_pre_enable(state, master_crtc);
+}
- /* need to enable VDSC, which we skipped in pre-enable */
- intel_dsc_enable(crtc_state);
+static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- if (DISPLAY_VER(dev_priv) >= 13)
- intel_uncompressed_joiner_enable(crtc_state);
+ if (crtc_state->has_pch_encoder) {
+ intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
+ &crtc_state->fdi_m_n);
+ } else if (intel_crtc_has_dp_encoder(crtc_state)) {
+ intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
+ &crtc_state->dp_m_n);
+ intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
+ &crtc_state->dp_m2_n2);
+ }
+
+ intel_set_transcoder_timings(crtc_state);
+
+ if (cpu_transcoder != TRANSCODER_EDP)
+ intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
+ crtc_state->pixel_multiplier - 1);
+
+ hsw_set_frame_start_delay(crtc_state);
+
+ hsw_set_transconf(crtc_state);
}
static void hsw_crtc_enable(struct intel_atomic_state *state,
@@ -2036,25 +1938,18 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
}
+ intel_dsc_enable(new_crtc_state);
+
+ if (DISPLAY_VER(dev_priv) >= 13)
+ intel_uncompressed_joiner_enable(new_crtc_state);
+
intel_set_pipe_src_size(new_crtc_state);
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
bdw_set_pipemisc(new_crtc_state);
- if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
- intel_set_transcoder_timings(new_crtc_state);
-
- if (cpu_transcoder != TRANSCODER_EDP)
- intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
- new_crtc_state->pixel_multiplier - 1);
-
- if (new_crtc_state->has_pch_encoder)
- intel_cpu_transcoder_set_m_n(new_crtc_state,
- &new_crtc_state->fdi_m_n, NULL);
-
- hsw_set_frame_start_delay(new_crtc_state);
-
- hsw_set_transconf(new_crtc_state);
- }
+ if (!intel_crtc_is_bigjoiner_slave(new_crtc_state) &&
+ !transcoder_is_dsi(cpu_transcoder))
+ hsw_configure_cpu_transcoder(new_crtc_state);
crtc->active = true;
@@ -2093,7 +1988,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
icl_pipe_mbus_enable(crtc, dbuf_state->joined_mbus);
}
- if (new_crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
intel_crtc_vblank_on(new_crtc_state);
intel_encoders_enable(state, crtc);
@@ -2178,7 +2073,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
* FIXME collapse everything to one hook.
* Need care with mst->ddi interactions.
*/
- if (!old_crtc_state->bigjoiner_slave) {
+ if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
intel_encoders_disable(state, crtc);
intel_encoders_post_disable(state, crtc);
}
@@ -2441,6 +2336,23 @@ static void modeset_put_crtc_power_domains(struct intel_crtc *crtc,
domains);
}
+static void i9xx_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+
+ if (intel_crtc_has_dp_encoder(crtc_state)) {
+ intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
+ &crtc_state->dp_m_n);
+ intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
+ &crtc_state->dp_m2_n2);
+ }
+
+ intel_set_transcoder_timings(crtc_state);
+
+ i9xx_set_pipeconf(crtc_state);
+}
+
static void valleyview_crtc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -2452,10 +2364,8 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
return;
- if (intel_crtc_has_dp_encoder(new_crtc_state))
- intel_dp_set_m_n(new_crtc_state, M1_N1);
+ i9xx_configure_cpu_transcoder(new_crtc_state);
- intel_set_transcoder_timings(new_crtc_state);
intel_set_pipe_src_size(new_crtc_state);
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
@@ -2463,8 +2373,6 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
intel_de_write(dev_priv, CHV_CANVAS(pipe), 0);
}
- i9xx_set_pipeconf(new_crtc_state);
-
crtc->active = true;
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
@@ -2504,14 +2412,10 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
return;
- if (intel_crtc_has_dp_encoder(new_crtc_state))
- intel_dp_set_m_n(new_crtc_state, M1_N1);
+ i9xx_configure_cpu_transcoder(new_crtc_state);
- intel_set_transcoder_timings(new_crtc_state);
intel_set_pipe_src_size(new_crtc_state);
- i9xx_set_pipeconf(new_crtc_state);
-
crtc->active = true;
if (DISPLAY_VER(dev_priv) != 2)
@@ -2757,77 +2661,6 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
}
}
-bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
- /* IPS only exists on ULT machines and is tied to pipe A. */
- if (!hsw_crtc_supports_ips(crtc))
- return false;
-
- if (!dev_priv->params.enable_ips)
- return false;
-
- if (crtc_state->pipe_bpp > 24)
- return false;
-
- /*
- * We compare against max which means we must take
- * the increased cdclk requirement into account when
- * calculating the new cdclk.
- *
- * Should measure whether using a lower cdclk w/o IPS
- */
- if (IS_BROADWELL(dev_priv) &&
- crtc_state->pixel_rate > dev_priv->max_cdclk_freq * 95 / 100)
- return false;
-
- return true;
-}
-
-static int hsw_compute_ips_config(struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *dev_priv =
- to_i915(crtc_state->uapi.crtc->dev);
- struct intel_atomic_state *state =
- to_intel_atomic_state(crtc_state->uapi.state);
-
- crtc_state->ips_enabled = false;
-
- if (!hsw_crtc_state_ips_capable(crtc_state))
- return 0;
-
- /*
- * When IPS gets enabled, the pipe CRC changes. Since IPS gets
- * enabled and disabled dynamically based on package C states,
- * user space can't make reliable use of the CRCs, so let's just
- * completely disable it.
- */
- if (crtc_state->crc_enabled)
- return 0;
-
- /* IPS should be fine as long as at least one plane is enabled. */
- if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
- return 0;
-
- if (IS_BROADWELL(dev_priv)) {
- const struct intel_cdclk_state *cdclk_state;
-
- cdclk_state = intel_atomic_get_cdclk_state(state);
- if (IS_ERR(cdclk_state))
- return PTR_ERR(cdclk_state);
-
- /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
- if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100)
- return 0;
- }
-
- crtc_state->ips_enabled = true;
-
- return 0;
-}
-
static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
{
const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -3085,7 +2918,7 @@ intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
m_n->tu = 64;
compute_m_n(data_clock,
link_clock * nlanes * 8,
- &m_n->gmch_m, &m_n->gmch_n,
+ &m_n->data_m, &m_n->data_n,
constant_n);
compute_m_n(pixel_clock, link_clock,
@@ -3116,99 +2949,66 @@ static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
}
}
-static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
- const struct intel_link_m_n *m_n)
+void intel_zero_m_n(struct intel_link_m_n *m_n)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- enum pipe pipe = crtc->pipe;
+ /* corresponds to 0 register value */
+ memset(m_n, 0, sizeof(*m_n));
+ m_n->tu = 1;
+}
- intel_de_write(dev_priv, PCH_TRANS_DATA_M1(pipe),
- TU_SIZE(m_n->tu) | m_n->gmch_m);
- intel_de_write(dev_priv, PCH_TRANS_DATA_N1(pipe), m_n->gmch_n);
- intel_de_write(dev_priv, PCH_TRANS_LINK_M1(pipe), m_n->link_m);
- intel_de_write(dev_priv, PCH_TRANS_LINK_N1(pipe), m_n->link_n);
+void intel_set_m_n(struct drm_i915_private *i915,
+ const struct intel_link_m_n *m_n,
+ i915_reg_t data_m_reg, i915_reg_t data_n_reg,
+ i915_reg_t link_m_reg, i915_reg_t link_n_reg)
+{
+ intel_de_write(i915, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m);
+ intel_de_write(i915, data_n_reg, m_n->data_n);
+ intel_de_write(i915, link_m_reg, m_n->link_m);
+ /*
+ * On BDW+ writing LINK_N arms the double buffered update
+ * of all the M/N registers, so it must be written last.
+ */
+ intel_de_write(i915, link_n_reg, m_n->link_n);
}
-static bool transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
- enum transcoder transcoder)
+bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
+ enum transcoder transcoder)
{
if (IS_HASWELL(dev_priv))
return transcoder == TRANSCODER_EDP;
- /*
- * Strictly speaking some registers are available before
- * gen7, but we only support DRRS on gen7+
- */
- return DISPLAY_VER(dev_priv) == 7 || IS_CHERRYVIEW(dev_priv);
+ return IS_DISPLAY_VER(dev_priv, 5, 7) || IS_CHERRYVIEW(dev_priv);
}
-static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
- const struct intel_link_m_n *m_n,
- const struct intel_link_m_n *m2_n2)
+void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
+ enum transcoder transcoder,
+ const struct intel_link_m_n *m_n)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- enum transcoder transcoder = crtc_state->cpu_transcoder;
- if (DISPLAY_VER(dev_priv) >= 5) {
- intel_de_write(dev_priv, PIPE_DATA_M1(transcoder),
- TU_SIZE(m_n->tu) | m_n->gmch_m);
- intel_de_write(dev_priv, PIPE_DATA_N1(transcoder),
- m_n->gmch_n);
- intel_de_write(dev_priv, PIPE_LINK_M1(transcoder),
- m_n->link_m);
- intel_de_write(dev_priv, PIPE_LINK_N1(transcoder),
- m_n->link_n);
- /*
- * M2_N2 registers are set only if DRRS is supported
- * (to make sure the registers are not unnecessarily accessed).
- */
- if (m2_n2 && crtc_state->has_drrs &&
- transcoder_has_m2_n2(dev_priv, transcoder)) {
- intel_de_write(dev_priv, PIPE_DATA_M2(transcoder),
- TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
- intel_de_write(dev_priv, PIPE_DATA_N2(transcoder),
- m2_n2->gmch_n);
- intel_de_write(dev_priv, PIPE_LINK_M2(transcoder),
- m2_n2->link_m);
- intel_de_write(dev_priv, PIPE_LINK_N2(transcoder),
- m2_n2->link_n);
- }
- } else {
- intel_de_write(dev_priv, PIPE_DATA_M_G4X(pipe),
- TU_SIZE(m_n->tu) | m_n->gmch_m);
- intel_de_write(dev_priv, PIPE_DATA_N_G4X(pipe), m_n->gmch_n);
- intel_de_write(dev_priv, PIPE_LINK_M_G4X(pipe), m_n->link_m);
- intel_de_write(dev_priv, PIPE_LINK_N_G4X(pipe), m_n->link_n);
- }
+ if (DISPLAY_VER(dev_priv) >= 5)
+ intel_set_m_n(dev_priv, m_n,
+ PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
+ PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
+ else
+ intel_set_m_n(dev_priv, m_n,
+ PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
+ PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe));
}
-void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, enum link_m_n_set m_n)
+void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc,
+ enum transcoder transcoder,
+ const struct intel_link_m_n *m_n)
{
- const struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL;
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-
- if (m_n == M1_N1) {
- dp_m_n = &crtc_state->dp_m_n;
- dp_m2_n2 = &crtc_state->dp_m2_n2;
- } else if (m_n == M2_N2) {
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- /*
- * M2_N2 registers are not supported. Hence m2_n2 divider value
- * needs to be programmed into M1_N1.
- */
- dp_m_n = &crtc_state->dp_m2_n2;
- } else {
- drm_err(&i915->drm, "Unsupported divider value\n");
+ if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder))
return;
- }
- if (crtc_state->has_pch_encoder)
- intel_pch_transcoder_set_m_n(crtc_state, &crtc_state->dp_m_n);
- else
- intel_cpu_transcoder_set_m_n(crtc_state, dp_m_n, dp_m2_n2);
+ intel_set_m_n(dev_priv, m_n,
+ PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
+ PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
}
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
@@ -3279,7 +3079,8 @@ static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
* always be the user's requested size.
*/
intel_de_write(dev_priv, PIPESRC(pipe),
- ((crtc_state->pipe_src_w - 1) << 16) | (crtc_state->pipe_src_h - 1));
+ PIPESRC_WIDTH(crtc_state->pipe_src_w - 1) |
+ PIPESRC_HEIGHT(crtc_state->pipe_src_h - 1));
}
static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
@@ -3350,21 +3151,19 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
u32 tmp;
tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe));
- pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
- pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->pipe_src_w = REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1;
+ pipe_config->pipe_src_h = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, tmp) + 1;
}
static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- u32 pipeconf;
-
- pipeconf = 0;
+ u32 pipeconf = 0;
/* we keep both pipes enabled on 830 */
if (IS_I830(dev_priv))
- pipeconf |= intel_de_read(dev_priv, PIPECONF(crtc->pipe)) & PIPECONF_ENABLE;
+ pipeconf |= PIPECONF_ENABLE;
if (crtc_state->double_wide)
pipeconf |= PIPECONF_DOUBLE_WIDE;
@@ -3379,13 +3178,13 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
switch (crtc_state->pipe_bpp) {
case 18:
- pipeconf |= PIPECONF_6BPC;
+ pipeconf |= PIPECONF_BPC_6;
break;
case 24:
- pipeconf |= PIPECONF_8BPC;
+ pipeconf |= PIPECONF_BPC_8;
break;
case 30:
- pipeconf |= PIPECONF_10BPC;
+ pipeconf |= PIPECONF_BPC_10;
break;
default:
/* Case prevented by intel_choose_pipe_bpp_dither. */
@@ -3400,7 +3199,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
else
pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
} else {
- pipeconf |= PIPECONF_PROGRESSIVE;
+ pipeconf |= PIPECONF_INTERLACE_PROGRESSIVE;
}
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
@@ -3543,11 +3342,11 @@ static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
- if (tmp & DISPPLANE_GAMMA_ENABLE)
+ if (tmp & DISP_PIPE_GAMMA_ENABLE)
crtc_state->gamma_enable = true;
if (!HAS_GMCH(dev_priv) &&
- tmp & DISPPLANE_PIPE_CSC_ENABLE)
+ tmp & DISP_PIPE_CSC_ENABLE)
crtc_state->csc_enable = true;
}
@@ -3578,16 +3377,17 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
IS_CHERRYVIEW(dev_priv)) {
switch (tmp & PIPECONF_BPC_MASK) {
- case PIPECONF_6BPC:
+ case PIPECONF_BPC_6:
pipe_config->pipe_bpp = 18;
break;
- case PIPECONF_8BPC:
+ case PIPECONF_BPC_8:
pipe_config->pipe_bpp = 24;
break;
- case PIPECONF_10BPC:
+ case PIPECONF_BPC_10:
pipe_config->pipe_bpp = 30;
break;
default:
+ MISSING_CASE(tmp);
break;
}
}
@@ -3596,8 +3396,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
(tmp & PIPECONF_COLOR_RANGE_SELECT))
pipe_config->limited_color_range = true;
- pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_I9XX) >>
- PIPECONF_GAMMA_MODE_SHIFT;
+ pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_I9XX, tmp);
if (IS_CHERRYVIEW(dev_priv))
pipe_config->cgm_mode = intel_de_read(dev_priv,
@@ -3684,16 +3483,16 @@ static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)
switch (crtc_state->pipe_bpp) {
case 18:
- val |= PIPECONF_6BPC;
+ val |= PIPECONF_BPC_6;
break;
case 24:
- val |= PIPECONF_8BPC;
+ val |= PIPECONF_BPC_8;
break;
case 30:
- val |= PIPECONF_10BPC;
+ val |= PIPECONF_BPC_10;
break;
case 36:
- val |= PIPECONF_12BPC;
+ val |= PIPECONF_BPC_12;
break;
default:
/* Case prevented by intel_choose_pipe_bpp_dither. */
@@ -3701,12 +3500,12 @@ static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)
}
if (crtc_state->dither)
- val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
+ val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP;
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
- val |= PIPECONF_INTERLACED_ILK;
+ val |= PIPECONF_INTERLACE_IF_ID_ILK;
else
- val |= PIPECONF_PROGRESSIVE;
+ val |= PIPECONF_INTERLACE_PF_PD_ILK;
/*
* This would end up with an odd purple hue over
@@ -3738,12 +3537,12 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
u32 val = 0;
if (IS_HASWELL(dev_priv) && crtc_state->dither)
- val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
+ val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP;
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
- val |= PIPECONF_INTERLACED_ILK;
+ val |= PIPECONF_INTERLACE_IF_ID_ILK;
else
- val |= PIPECONF_PROGRESSIVE;
+ val |= PIPECONF_INTERLACE_PF_PD_ILK;
if (IS_HASWELL(dev_priv) &&
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
@@ -3765,18 +3564,18 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
switch (crtc_state->pipe_bpp) {
case 18:
- val |= PIPEMISC_6_BPC;
+ val |= PIPEMISC_BPC_6;
break;
case 24:
- val |= PIPEMISC_8_BPC;
+ val |= PIPEMISC_BPC_8;
break;
case 30:
- val |= PIPEMISC_10_BPC;
+ val |= PIPEMISC_BPC_10;
break;
case 36:
/* Port output 12BPC defined for ADLP+ */
if (DISPLAY_VER(dev_priv) > 12)
- val |= PIPEMISC_12_BPC_ADLP;
+ val |= PIPEMISC_BPC_12_ADLP;
break;
default:
MISSING_CASE(crtc_state->pipe_bpp);
@@ -3812,7 +3611,7 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
}
intel_de_rmw(dev_priv, PIPE_MISC2(crtc->pipe),
- PIPE_MISC2_UNDERRUN_BUBBLE_COUNTER_MASK,
+ PIPE_MISC2_BUBBLE_COUNTER_MASK,
scaler_in_use ? PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN :
PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS);
}
@@ -3828,11 +3627,11 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
switch (tmp & PIPEMISC_BPC_MASK) {
- case PIPEMISC_6_BPC:
+ case PIPEMISC_BPC_6:
return 18;
- case PIPEMISC_8_BPC:
+ case PIPEMISC_BPC_8:
return 24;
- case PIPEMISC_10_BPC:
+ case PIPEMISC_BPC_10:
return 30;
/*
* PORT OUTPUT 12 BPC defined for ADLP+.
@@ -3844,7 +3643,7 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
* on older platforms, need to find a workaround for 12 BPC
* MIPI DSI HW readout.
*/
- case PIPEMISC_12_BPC_ADLP:
+ case PIPEMISC_BPC_12_ADLP:
if (DISPLAY_VER(dev_priv) > 12)
return 36;
fallthrough;
@@ -3865,83 +3664,47 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp)
return DIV_ROUND_UP(bps, link_bw * 8);
}
-static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
- struct intel_link_m_n *m_n)
+void intel_get_m_n(struct drm_i915_private *i915,
+ struct intel_link_m_n *m_n,
+ i915_reg_t data_m_reg, i915_reg_t data_n_reg,
+ i915_reg_t link_m_reg, i915_reg_t link_n_reg)
{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- enum pipe pipe = crtc->pipe;
-
- m_n->link_m = intel_de_read(dev_priv, PCH_TRANS_LINK_M1(pipe));
- m_n->link_n = intel_de_read(dev_priv, PCH_TRANS_LINK_N1(pipe));
- m_n->gmch_m = intel_de_read(dev_priv, PCH_TRANS_DATA_M1(pipe))
- & ~TU_SIZE_MASK;
- m_n->gmch_n = intel_de_read(dev_priv, PCH_TRANS_DATA_N1(pipe));
- m_n->tu = ((intel_de_read(dev_priv, PCH_TRANS_DATA_M1(pipe))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+ m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK;
+ m_n->link_n = intel_de_read(i915, link_n_reg) & DATA_LINK_M_N_MASK;
+ m_n->data_m = intel_de_read(i915, data_m_reg) & DATA_LINK_M_N_MASK;
+ m_n->data_n = intel_de_read(i915, data_n_reg) & DATA_LINK_M_N_MASK;
+ m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, data_m_reg)) + 1;
}
-static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
- enum transcoder transcoder,
- struct intel_link_m_n *m_n,
- struct intel_link_m_n *m2_n2)
+void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
+ enum transcoder transcoder,
+ struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- if (DISPLAY_VER(dev_priv) >= 5) {
- m_n->link_m = intel_de_read(dev_priv,
- PIPE_LINK_M1(transcoder));
- m_n->link_n = intel_de_read(dev_priv,
- PIPE_LINK_N1(transcoder));
- m_n->gmch_m = intel_de_read(dev_priv,
- PIPE_DATA_M1(transcoder))
- & ~TU_SIZE_MASK;
- m_n->gmch_n = intel_de_read(dev_priv,
- PIPE_DATA_N1(transcoder));
- m_n->tu = ((intel_de_read(dev_priv, PIPE_DATA_M1(transcoder))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
-
- if (m2_n2 && transcoder_has_m2_n2(dev_priv, transcoder)) {
- m2_n2->link_m = intel_de_read(dev_priv,
- PIPE_LINK_M2(transcoder));
- m2_n2->link_n = intel_de_read(dev_priv,
- PIPE_LINK_N2(transcoder));
- m2_n2->gmch_m = intel_de_read(dev_priv,
- PIPE_DATA_M2(transcoder))
- & ~TU_SIZE_MASK;
- m2_n2->gmch_n = intel_de_read(dev_priv,
- PIPE_DATA_N2(transcoder));
- m2_n2->tu = ((intel_de_read(dev_priv, PIPE_DATA_M2(transcoder))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
- }
- } else {
- m_n->link_m = intel_de_read(dev_priv, PIPE_LINK_M_G4X(pipe));
- m_n->link_n = intel_de_read(dev_priv, PIPE_LINK_N_G4X(pipe));
- m_n->gmch_m = intel_de_read(dev_priv, PIPE_DATA_M_G4X(pipe))
- & ~TU_SIZE_MASK;
- m_n->gmch_n = intel_de_read(dev_priv, PIPE_DATA_N_G4X(pipe));
- m_n->tu = ((intel_de_read(dev_priv, PIPE_DATA_M_G4X(pipe))
- & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
- }
-}
-
-void intel_dp_get_m_n(struct intel_crtc *crtc,
- struct intel_crtc_state *pipe_config)
-{
- if (pipe_config->has_pch_encoder)
- intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
+ if (DISPLAY_VER(dev_priv) >= 5)
+ intel_get_m_n(dev_priv, m_n,
+ PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
+ PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
else
- intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
- &pipe_config->dp_m_n,
- &pipe_config->dp_m2_n2);
+ intel_get_m_n(dev_priv, m_n,
+ PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
+ PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe));
}
-void ilk_get_fdi_m_n_config(struct intel_crtc *crtc,
- struct intel_crtc_state *pipe_config)
+void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
+ enum transcoder transcoder,
+ struct intel_link_m_n *m_n)
{
- intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
- &pipe_config->fdi_m_n, NULL);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+ if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder))
+ return;
+
+ intel_get_m_n(dev_priv, m_n,
+ PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
+ PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
}
static void ilk_get_pfit_pos_size(struct intel_crtc_state *crtc_state,
@@ -4037,16 +3800,16 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
goto out;
switch (tmp & PIPECONF_BPC_MASK) {
- case PIPECONF_6BPC:
+ case PIPECONF_BPC_6:
pipe_config->pipe_bpp = 18;
break;
- case PIPECONF_8BPC:
+ case PIPECONF_BPC_8:
pipe_config->pipe_bpp = 24;
break;
- case PIPECONF_10BPC:
+ case PIPECONF_BPC_10:
pipe_config->pipe_bpp = 30;
break;
- case PIPECONF_12BPC:
+ case PIPECONF_BPC_12:
pipe_config->pipe_bpp = 36;
break;
default:
@@ -4066,8 +3829,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
break;
}
- pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_ILK) >>
- PIPECONF_GAMMA_MODE_SHIFT;
+ pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_ILK, tmp);
pipe_config->csc_mode = intel_de_read(dev_priv,
PIPE_CSC_MODE(crtc->pipe));
@@ -4117,19 +3879,20 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
return tmp & TRANS_DDI_FUNC_ENABLE;
}
-static u8 enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv)
+static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
+ u8 *master_pipes, u8 *slave_pipes)
{
- u8 master_pipes = 0, slave_pipes = 0;
struct intel_crtc *crtc;
- for_each_intel_crtc(&dev_priv->drm, crtc) {
+ *master_pipes = 0;
+ *slave_pipes = 0;
+
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc,
+ bigjoiner_pipes(dev_priv)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
intel_wakeref_t wakeref;
- if ((bigjoiner_pipes(dev_priv) & BIT(pipe)) == 0)
- continue;
-
power_domain = intel_dsc_power_domain(crtc, (enum transcoder) pipe);
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
@@ -4138,9 +3901,9 @@ static u8 enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv)
continue;
if (tmp & MASTER_BIG_JOINER_ENABLE)
- master_pipes |= BIT(pipe);
+ *master_pipes |= BIT(pipe);
else
- slave_pipes |= BIT(pipe);
+ *slave_pipes |= BIT(pipe);
}
if (DISPLAY_VER(dev_priv) < 13)
@@ -4151,18 +3914,47 @@ static u8 enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv)
u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
if (tmp & UNCOMPRESSED_JOINER_MASTER)
- master_pipes |= BIT(pipe);
+ *master_pipes |= BIT(pipe);
if (tmp & UNCOMPRESSED_JOINER_SLAVE)
- slave_pipes |= BIT(pipe);
+ *slave_pipes |= BIT(pipe);
}
}
/* Bigjoiner pipes should always be consecutive master and slave */
- drm_WARN(&dev_priv->drm, slave_pipes != master_pipes << 1,
+ drm_WARN(&dev_priv->drm, *slave_pipes != *master_pipes << 1,
"Bigjoiner misconfigured (master pipes 0x%x, slave pipes 0x%x)\n",
- master_pipes, slave_pipes);
+ *master_pipes, *slave_pipes);
+}
+
+static enum pipe get_bigjoiner_master_pipe(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
+{
+ if ((slave_pipes & BIT(pipe)) == 0)
+ return pipe;
- return slave_pipes;
+ /* ignore everything above our pipe */
+ master_pipes &= ~GENMASK(7, pipe);
+
+ /* highest remaining bit should be our master pipe */
+ return fls(master_pipes) - 1;
+}
+
+static u8 get_bigjoiner_slave_pipes(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
+{
+ enum pipe master_pipe, next_master_pipe;
+
+ master_pipe = get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes);
+
+ if ((master_pipes & BIT(master_pipe)) == 0)
+ return 0;
+
+ /* ignore our master pipe and everything below it */
+ master_pipes &= ~GENMASK(master_pipe, 0);
+ /* make sure a high bit is set for the ffs() */
+ master_pipes |= BIT(7);
+ /* lowest remaining bit should be the next master pipe */
+ next_master_pipe = ffs(master_pipes) - 1;
+
+ return slave_pipes & GENMASK(next_master_pipe - 1, master_pipe);
}
static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
@@ -4181,6 +3973,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = to_i915(dev);
u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv);
enum transcoder cpu_transcoder;
+ u8 master_pipes, slave_pipes;
u8 enabled_transcoders = 0;
/*
@@ -4232,8 +4025,10 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
enabled_transcoders |= BIT(cpu_transcoder);
/* bigjoiner slave -> consider the master pipe's transcoder as well */
- if (enabled_bigjoiner_pipes(dev_priv) & BIT(crtc->pipe)) {
- cpu_transcoder = (enum transcoder) crtc->pipe - 1;
+ enabled_bigjoiner_pipes(dev_priv, &master_pipes, &slave_pipes);
+ if (slave_pipes & BIT(crtc->pipe)) {
+ cpu_transcoder = (enum transcoder)
+ get_bigjoiner_master_pipe(crtc->pipe, master_pipes, slave_pipes);
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
enabled_transcoders |= BIT(cpu_transcoder);
}
@@ -4358,6 +4153,24 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
return transcoder_is_dsi(pipe_config->cpu_transcoder);
}
+static void intel_bigjoiner_get_config(struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ u8 master_pipes, slave_pipes;
+ enum pipe pipe = crtc->pipe;
+
+ enabled_bigjoiner_pipes(i915, &master_pipes, &slave_pipes);
+
+ if (((master_pipes | slave_pipes) & BIT(pipe)) == 0)
+ return;
+
+ crtc_state->bigjoiner = true;
+ crtc_state->bigjoiner_pipes =
+ BIT(get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes)) |
+ get_bigjoiner_slave_pipes(pipe, master_pipes, slave_pipes);
+}
+
static bool hsw_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
@@ -4380,13 +4193,12 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
active = true;
}
- intel_dsc_get_config(pipe_config);
- if (DISPLAY_VER(dev_priv) >= 13 && !pipe_config->dsc.compression_enable)
- intel_uncompressed_joiner_get_config(pipe_config);
-
if (!active)
goto out;
+ intel_dsc_get_config(pipe_config);
+ intel_bigjoiner_get_config(pipe_config);
+
if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
DISPLAY_VER(dev_priv) >= 11)
intel_get_transcoder_timings(crtc, pipe_config);
@@ -4443,19 +4255,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
ilk_get_pfit_config(pipe_config);
}
- if (hsw_crtc_supports_ips(crtc)) {
- if (IS_HASWELL(dev_priv))
- pipe_config->ips_enabled = intel_de_read(dev_priv,
- IPS_CTL) & IPS_ENABLE;
- else {
- /*
- * We cannot readout IPS state on broadwell, set to
- * true so we can set it to a defined state on first
- * commit.
- */
- pipe_config->ips_enabled = true;
- }
- }
+ hsw_ips_get_config(pipe_config);
if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
@@ -4867,169 +4667,6 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
return mode;
}
-/**
- * intel_wm_need_update - Check whether watermarks need updating
- * @cur: current plane state
- * @new: new plane state
- *
- * Check current plane state versus the new one to determine whether
- * watermarks need to be recalculated.
- *
- * Returns true or false.
- */
-static bool intel_wm_need_update(const struct intel_plane_state *cur,
- struct intel_plane_state *new)
-{
- /* Update watermarks on tiling or size changes. */
- if (new->uapi.visible != cur->uapi.visible)
- return true;
-
- if (!cur->hw.fb || !new->hw.fb)
- return false;
-
- if (cur->hw.fb->modifier != new->hw.fb->modifier ||
- cur->hw.rotation != new->hw.rotation ||
- drm_rect_width(&new->uapi.src) != drm_rect_width(&cur->uapi.src) ||
- drm_rect_height(&new->uapi.src) != drm_rect_height(&cur->uapi.src) ||
- drm_rect_width(&new->uapi.dst) != drm_rect_width(&cur->uapi.dst) ||
- drm_rect_height(&new->uapi.dst) != drm_rect_height(&cur->uapi.dst))
- return true;
-
- return false;
-}
-
-static bool needs_scaling(const struct intel_plane_state *state)
-{
- int src_w = drm_rect_width(&state->uapi.src) >> 16;
- int src_h = drm_rect_height(&state->uapi.src) >> 16;
- int dst_w = drm_rect_width(&state->uapi.dst);
- int dst_h = drm_rect_height(&state->uapi.dst);
-
- return (src_w != dst_w || src_h != dst_h);
-}
-
-int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
- struct intel_crtc_state *new_crtc_state,
- const struct intel_plane_state *old_plane_state,
- struct intel_plane_state *new_plane_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- bool mode_changed = intel_crtc_needs_modeset(new_crtc_state);
- bool was_crtc_enabled = old_crtc_state->hw.active;
- bool is_crtc_enabled = new_crtc_state->hw.active;
- bool turn_off, turn_on, visible, was_visible;
- int ret;
-
- if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
- ret = skl_update_scaler_plane(new_crtc_state, new_plane_state);
- if (ret)
- return ret;
- }
-
- was_visible = old_plane_state->uapi.visible;
- visible = new_plane_state->uapi.visible;
-
- if (!was_crtc_enabled && drm_WARN_ON(&dev_priv->drm, was_visible))
- was_visible = false;
-
- /*
- * Visibility is calculated as if the crtc was on, but
- * after scaler setup everything depends on it being off
- * when the crtc isn't active.
- *
- * FIXME this is wrong for watermarks. Watermarks should also
- * be computed as if the pipe would be active. Perhaps move
- * per-plane wm computation to the .check_plane() hook, and
- * only combine the results from all planes in the current place?
- */
- if (!is_crtc_enabled) {
- intel_plane_set_invisible(new_crtc_state, new_plane_state);
- visible = false;
- }
-
- if (!was_visible && !visible)
- return 0;
-
- turn_off = was_visible && (!visible || mode_changed);
- turn_on = visible && (!was_visible || mode_changed);
-
- drm_dbg_atomic(&dev_priv->drm,
- "[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
- crtc->base.base.id, crtc->base.name,
- plane->base.base.id, plane->base.name,
- was_visible, visible,
- turn_off, turn_on, mode_changed);
-
- if (turn_on) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
- new_crtc_state->update_wm_pre = true;
-
- /* must disable cxsr around plane enable/disable */
- if (plane->id != PLANE_CURSOR)
- new_crtc_state->disable_cxsr = true;
- } else if (turn_off) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
- new_crtc_state->update_wm_post = true;
-
- /* must disable cxsr around plane enable/disable */
- if (plane->id != PLANE_CURSOR)
- new_crtc_state->disable_cxsr = true;
- } else if (intel_wm_need_update(old_plane_state, new_plane_state)) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) {
- /* FIXME bollocks */
- new_crtc_state->update_wm_pre = true;
- new_crtc_state->update_wm_post = true;
- }
- }
-
- if (visible || was_visible)
- new_crtc_state->fb_bits |= plane->frontbuffer_bit;
-
- /*
- * ILK/SNB DVSACNTR/Sprite Enable
- * IVB SPR_CTL/Sprite Enable
- * "When in Self Refresh Big FIFO mode, a write to enable the
- * plane will be internally buffered and delayed while Big FIFO
- * mode is exiting."
- *
- * Which means that enabling the sprite can take an extra frame
- * when we start in big FIFO mode (LP1+). Thus we need to drop
- * down to LP0 and wait for vblank in order to make sure the
- * sprite gets enabled on the next vblank after the register write.
- * Doing otherwise would risk enabling the sprite one frame after
- * we've already signalled flip completion. We can resume LP1+
- * once the sprite has been enabled.
- *
- *
- * WaCxSRDisabledForSpriteScaling:ivb
- * IVB SPR_SCALE/Scaling Enable
- * "Low Power watermarks must be disabled for at least one
- * frame before enabling sprite scaling, and kept disabled
- * until sprite scaling is disabled."
- *
- * ILK/SNB DVSASCALE/Scaling Enable
- * "When in Self Refresh Big FIFO mode, scaling enable will be
- * masked off while Big FIFO mode is exiting."
- *
- * Despite the w/a only being listed for IVB we assume that
- * the ILK/SNB note has similar ramifications, hence we apply
- * the w/a on all three platforms.
- *
- * With experimental results seems this is needed also for primary
- * plane, not only sprite plane.
- */
- if (plane->id != PLANE_CURSOR &&
- (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) ||
- IS_IVYBRIDGE(dev_priv)) &&
- (turn_on || (!needs_scaling(old_plane_state) &&
- needs_scaling(new_plane_state))))
- new_crtc_state->disable_lp_wm = true;
-
- return 0;
-}
-
static bool encoders_cloneable(const struct intel_encoder *a,
const struct intel_encoder *b)
{
@@ -5289,7 +4926,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
if (mode_changed && crtc_state->hw.enable &&
!drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {
- ret = dev_priv->dpll_funcs->crtc_compute_clock(crtc_state);
+ ret = intel_dpll_crtc_compute_clock(crtc_state);
if (ret)
return ret;
}
@@ -5340,7 +4977,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
}
if (HAS_IPS(dev_priv)) {
- ret = hsw_compute_ips_config(crtc_state);
+ ret = hsw_ips_compute_config(state, crtc);
if (ret)
return ret;
}
@@ -5491,9 +5128,9 @@ intel_dump_m_n_config(const struct intel_crtc_state *pipe_config,
struct drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
drm_dbg_kms(&i915->drm,
- "%s: lanes: %i; gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
+ "%s: lanes: %i; data_m: %u, data_n: %u, link_m: %u, link_n: %u, tu: %u\n",
id, lane_count,
- m_n->gmch_m, m_n->gmch_n,
+ m_n->data_m, m_n->data_n,
m_n->link_m, m_n->link_n, m_n->tu);
}
@@ -5642,9 +5279,10 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
transcoder_name(pipe_config->master_transcoder),
pipe_config->sync_mode_slaves_mask);
- drm_dbg_kms(&dev_priv->drm, "bigjoiner: %s\n",
- pipe_config->bigjoiner_slave ? "slave" :
- pipe_config->bigjoiner ? "master" : "no");
+ drm_dbg_kms(&dev_priv->drm, "bigjoiner: %s, pipes: 0x%x\n",
+ intel_crtc_is_bigjoiner_slave(pipe_config) ? "slave" :
+ intel_crtc_is_bigjoiner_master(pipe_config) ? "master" : "no",
+ pipe_config->bigjoiner_pipes);
drm_dbg_kms(&dev_priv->drm, "splitter: %s, link count %d, overlap %d\n",
enableddisabled(pipe_config->splitter.enable),
@@ -5658,11 +5296,11 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
if (intel_crtc_has_dp_encoder(pipe_config)) {
intel_dump_m_n_config(pipe_config, "dp m_n",
- pipe_config->lane_count, &pipe_config->dp_m_n);
- if (pipe_config->has_drrs)
- intel_dump_m_n_config(pipe_config, "dp m2_n2",
- pipe_config->lane_count,
- &pipe_config->dp_m2_n2);
+ pipe_config->lane_count,
+ &pipe_config->dp_m_n);
+ intel_dump_m_n_config(pipe_config, "dp m2_n2",
+ pipe_config->lane_count,
+ &pipe_config->dp_m2_n2);
}
drm_dbg_kms(&dev_priv->drm,
@@ -5841,35 +5479,42 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
static void
intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
- struct intel_crtc_state *crtc_state)
+ struct intel_crtc *crtc)
{
- const struct intel_crtc_state *master_crtc_state;
- struct intel_crtc *master_crtc;
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
- master_crtc = intel_master_crtc(crtc_state);
- master_crtc_state = intel_atomic_get_new_crtc_state(state, master_crtc);
+ WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
- /* No need to copy state if the master state is unchanged */
- if (master_crtc_state)
- intel_crtc_copy_color_blobs(crtc_state, master_crtc_state);
+ drm_property_replace_blob(&crtc_state->hw.degamma_lut,
+ crtc_state->uapi.degamma_lut);
+ drm_property_replace_blob(&crtc_state->hw.gamma_lut,
+ crtc_state->uapi.gamma_lut);
+ drm_property_replace_blob(&crtc_state->hw.ctm,
+ crtc_state->uapi.ctm);
}
static void
-intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *state,
- struct intel_crtc_state *crtc_state)
+intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+
crtc_state->hw.enable = crtc_state->uapi.enable;
crtc_state->hw.active = crtc_state->uapi.active;
crtc_state->hw.mode = crtc_state->uapi.mode;
crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter;
- intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc_state);
+ intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
}
static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
{
- if (crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(crtc_state))
return;
crtc_state->uapi.enable = crtc_state->hw.enable;
@@ -5880,7 +5525,6 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
- /* copy color blobs to uapi */
drm_property_replace_blob(&crtc_state->uapi.degamma_lut,
crtc_state->hw.degamma_lut);
drm_property_replace_blob(&crtc_state->uapi.gamma_lut,
@@ -5889,51 +5533,79 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
crtc_state->hw.ctm);
}
+static void
+copy_bigjoiner_crtc_state_nomodeset(struct intel_atomic_state *state,
+ struct intel_crtc *slave_crtc)
+{
+ struct intel_crtc_state *slave_crtc_state =
+ intel_atomic_get_new_crtc_state(state, slave_crtc);
+ struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
+ const struct intel_crtc_state *master_crtc_state =
+ intel_atomic_get_new_crtc_state(state, master_crtc);
+
+ drm_property_replace_blob(&slave_crtc_state->hw.degamma_lut,
+ master_crtc_state->hw.degamma_lut);
+ drm_property_replace_blob(&slave_crtc_state->hw.gamma_lut,
+ master_crtc_state->hw.gamma_lut);
+ drm_property_replace_blob(&slave_crtc_state->hw.ctm,
+ master_crtc_state->hw.ctm);
+
+ slave_crtc_state->uapi.color_mgmt_changed = master_crtc_state->uapi.color_mgmt_changed;
+}
+
static int
-copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
- const struct intel_crtc_state *from_crtc_state)
+copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
+ struct intel_crtc *slave_crtc)
{
+ struct intel_crtc_state *slave_crtc_state =
+ intel_atomic_get_new_crtc_state(state, slave_crtc);
+ struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
+ const struct intel_crtc_state *master_crtc_state =
+ intel_atomic_get_new_crtc_state(state, master_crtc);
struct intel_crtc_state *saved_state;
- saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
+ saved_state = kmemdup(master_crtc_state, sizeof(*saved_state), GFP_KERNEL);
if (!saved_state)
return -ENOMEM;
- saved_state->uapi = crtc_state->uapi;
- saved_state->scaler_state = crtc_state->scaler_state;
- saved_state->shared_dpll = crtc_state->shared_dpll;
- saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
- saved_state->crc_enabled = crtc_state->crc_enabled;
+ /* preserve some things from the slave's original crtc state */
+ saved_state->uapi = slave_crtc_state->uapi;
+ saved_state->scaler_state = slave_crtc_state->scaler_state;
+ saved_state->shared_dpll = slave_crtc_state->shared_dpll;
+ saved_state->dpll_hw_state = slave_crtc_state->dpll_hw_state;
+ saved_state->crc_enabled = slave_crtc_state->crc_enabled;
- intel_crtc_free_hw_state(crtc_state);
- memcpy(crtc_state, saved_state, sizeof(*crtc_state));
+ intel_crtc_free_hw_state(slave_crtc_state);
+ memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
kfree(saved_state);
/* Re-init hw state */
- memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
- crtc_state->hw.enable = from_crtc_state->hw.enable;
- crtc_state->hw.active = from_crtc_state->hw.active;
- crtc_state->hw.pipe_mode = from_crtc_state->hw.pipe_mode;
- crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
+ memset(&slave_crtc_state->hw, 0, sizeof(slave_crtc_state->hw));
+ slave_crtc_state->hw.enable = master_crtc_state->hw.enable;
+ slave_crtc_state->hw.active = master_crtc_state->hw.active;
+ slave_crtc_state->hw.mode = master_crtc_state->hw.mode;
+ slave_crtc_state->hw.pipe_mode = master_crtc_state->hw.pipe_mode;
+ slave_crtc_state->hw.adjusted_mode = master_crtc_state->hw.adjusted_mode;
+ slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter;
+
+ copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
/* Some fixups */
- crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
- crtc_state->uapi.connectors_changed = from_crtc_state->uapi.connectors_changed;
- crtc_state->uapi.active_changed = from_crtc_state->uapi.active_changed;
- crtc_state->nv12_planes = crtc_state->c8_planes = crtc_state->update_planes = 0;
- crtc_state->bigjoiner_linked_crtc = to_intel_crtc(from_crtc_state->uapi.crtc);
- crtc_state->bigjoiner_slave = true;
- crtc_state->cpu_transcoder = from_crtc_state->cpu_transcoder;
- crtc_state->has_audio = from_crtc_state->has_audio;
+ slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
+ slave_crtc_state->uapi.connectors_changed = master_crtc_state->uapi.connectors_changed;
+ slave_crtc_state->uapi.active_changed = master_crtc_state->uapi.active_changed;
+ slave_crtc_state->cpu_transcoder = master_crtc_state->cpu_transcoder;
+ slave_crtc_state->has_audio = master_crtc_state->has_audio;
return 0;
}
static int
intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
- struct intel_crtc_state *crtc_state)
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_crtc_state *saved_state;
@@ -5963,7 +5635,7 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
memcpy(crtc_state, saved_state, sizeof(*crtc_state));
kfree(saved_state);
- intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
+ intel_crtc_copy_uapi_to_hw_state_modeset(state, crtc);
return 0;
}
@@ -6189,8 +5861,8 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n,
bool exact)
{
return m_n->tu == m2_n2->tu &&
- intel_compare_m_n(m_n->gmch_m, m_n->gmch_n,
- m2_n2->gmch_m, m2_n2->gmch_n, exact) &&
+ intel_compare_m_n(m_n->data_m, m_n->data_n,
+ m2_n2->data_m, m2_n2->data_n, exact) &&
intel_compare_m_n(m_n->link_m, m_n->link_n,
m2_n2->link_m, m2_n2->link_n, exact);
}
@@ -6389,16 +6061,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
&pipe_config->name,\
!fastset)) { \
pipe_config_mismatch(fastset, crtc, __stringify(name), \
- "(expected tu %i gmch %i/%i link %i/%i, " \
- "found tu %i, gmch %i/%i link %i/%i)", \
+ "(expected tu %i data %i/%i link %i/%i, " \
+ "found tu %i, data %i/%i link %i/%i)", \
current_config->name.tu, \
- current_config->name.gmch_m, \
- current_config->name.gmch_n, \
+ current_config->name.data_m, \
+ current_config->name.data_n, \
current_config->name.link_m, \
current_config->name.link_n, \
pipe_config->name.tu, \
- pipe_config->name.gmch_m, \
- pipe_config->name.gmch_n, \
+ pipe_config->name.data_m, \
+ pipe_config->name.data_n, \
pipe_config->name.link_m, \
pipe_config->name.link_n); \
ret = false; \
@@ -6416,22 +6088,22 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
!intel_compare_link_m_n(&current_config->alt_name, \
&pipe_config->name, !fastset)) { \
pipe_config_mismatch(fastset, crtc, __stringify(name), \
- "(expected tu %i gmch %i/%i link %i/%i, " \
- "or tu %i gmch %i/%i link %i/%i, " \
- "found tu %i, gmch %i/%i link %i/%i)", \
+ "(expected tu %i data %i/%i link %i/%i, " \
+ "or tu %i data %i/%i link %i/%i, " \
+ "found tu %i, data %i/%i link %i/%i)", \
current_config->name.tu, \
- current_config->name.gmch_m, \
- current_config->name.gmch_n, \
+ current_config->name.data_m, \
+ current_config->name.data_n, \
current_config->name.link_m, \
current_config->name.link_n, \
current_config->alt_name.tu, \
- current_config->alt_name.gmch_m, \
- current_config->alt_name.gmch_n, \
+ current_config->alt_name.data_m, \
+ current_config->alt_name.data_n, \
current_config->alt_name.link_m, \
current_config->alt_name.link_n, \
pipe_config->name.tu, \
- pipe_config->name.gmch_m, \
- pipe_config->name.gmch_n, \
+ pipe_config->name.data_m, \
+ pipe_config->name.data_n, \
pipe_config->name.link_m, \
pipe_config->name.link_n); \
ret = false; \
@@ -6510,13 +6182,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_I(lane_count);
PIPE_CONF_CHECK_X(lane_lat_optim_mask);
- if (DISPLAY_VER(dev_priv) < 8) {
- PIPE_CONF_CHECK_M_N(dp_m_n);
-
- if (current_config->has_drrs)
- PIPE_CONF_CHECK_M_N(dp_m2_n2);
- } else
+ if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) {
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
+ } else {
+ PIPE_CONF_CHECK_M_N(dp_m_n);
+ PIPE_CONF_CHECK_M_N(dp_m2_n2);
+ }
PIPE_CONF_CHECK_X(output_types);
@@ -6642,6 +6313,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
+ PIPE_CONF_CHECK_X(dpll_hw_state.div0);
PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
@@ -6693,8 +6365,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_X(sync_mode_slaves_mask);
PIPE_CONF_CHECK_I(master_transcoder);
PIPE_CONF_CHECK_BOOL(bigjoiner);
- PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
- PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
+ PIPE_CONF_CHECK_X(bigjoiner_pipes);
PIPE_CONF_CHECK_I(dsc.compression_enable);
PIPE_CONF_CHECK_I(dsc.dsc_split);
@@ -7480,20 +7151,25 @@ static int intel_crtc_add_bigjoiner_planes(struct intel_atomic_state *state,
static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
int i;
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- int ret;
+ struct intel_crtc *other;
- if (!crtc_state->bigjoiner)
- continue;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, other,
+ crtc_state->bigjoiner_pipes) {
+ int ret;
- ret = intel_crtc_add_bigjoiner_planes(state, crtc,
- crtc_state->bigjoiner_linked_crtc);
- if (ret)
- return ret;
+ if (crtc == other)
+ continue;
+
+ ret = intel_crtc_add_bigjoiner_planes(state, crtc, other);
+ if (ret)
+ return ret;
+ }
}
return 0;
@@ -7595,67 +7271,123 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
return false;
}
-static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_crtc_state *old_crtc_state,
- struct intel_crtc_state *new_crtc_state)
+static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
+ u8 pipes)
{
- struct intel_crtc_state *slave_crtc_state, *master_crtc_state;
- struct intel_crtc *slave_crtc, *master_crtc;
+ const struct intel_crtc_state *new_crtc_state;
+ struct intel_crtc *crtc;
+ int i;
- /* slave being enabled, is master is still claiming this crtc? */
- if (old_crtc_state->bigjoiner_slave) {
- slave_crtc = crtc;
- master_crtc = old_crtc_state->bigjoiner_linked_crtc;
- master_crtc_state = intel_atomic_get_new_crtc_state(state, master_crtc);
- if (!master_crtc_state || !intel_crtc_needs_modeset(master_crtc_state))
- goto claimed;
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ if (new_crtc_state->hw.enable &&
+ pipes & BIT(crtc->pipe) &&
+ intel_crtc_needs_modeset(new_crtc_state))
+ return true;
}
- if (!new_crtc_state->bigjoiner)
+ return false;
+}
+
+static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
+ struct intel_crtc *master_crtc)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *master_crtc_state =
+ intel_atomic_get_new_crtc_state(state, master_crtc);
+ struct intel_crtc *slave_crtc;
+ u8 slave_pipes;
+
+ /*
+ * TODO: encoder.compute_config() may be the best
+ * place to populate the bitmask for the master crtc.
+ * For now encoder.compute_config() just flags things
+ * as needing bigjoiner and we populate the bitmask
+ * here.
+ */
+ WARN_ON(master_crtc_state->bigjoiner_pipes);
+
+ if (!master_crtc_state->bigjoiner)
return 0;
- slave_crtc = intel_dsc_get_bigjoiner_secondary(crtc);
- if (!slave_crtc) {
- DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "
- "CRTC + 1 to be used, doesn't exist\n",
- crtc->base.base.id, crtc->base.name);
+ slave_pipes = BIT(master_crtc->pipe + 1);
+
+ if (slave_pipes & ~bigjoiner_pipes(i915)) {
+ drm_dbg_kms(&i915->drm,
+ "[CRTC:%d:%s] Cannot act as big joiner master "
+ "(need 0x%x as slave pipes, only 0x%x possible)\n",
+ master_crtc->base.base.id, master_crtc->base.name,
+ slave_pipes, bigjoiner_pipes(i915));
return -EINVAL;
}
- new_crtc_state->bigjoiner_linked_crtc = slave_crtc;
- slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave_crtc);
- master_crtc = crtc;
- if (IS_ERR(slave_crtc_state))
- return PTR_ERR(slave_crtc_state);
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, slave_pipes) {
+ struct intel_crtc_state *slave_crtc_state;
+ int ret;
+
+ slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave_crtc);
+ if (IS_ERR(slave_crtc_state))
+ return PTR_ERR(slave_crtc_state);
- /* master being enabled, slave was already configured? */
- if (slave_crtc_state->uapi.enable)
- goto claimed;
+ /* master being enabled, slave was already configured? */
+ if (slave_crtc_state->uapi.enable) {
+ drm_dbg_kms(&i915->drm,
+ "[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
+ "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
+ slave_crtc->base.base.id, slave_crtc->base.name,
+ master_crtc->base.base.id, master_crtc->base.name);
+ return -EINVAL;
+ }
+
+ /*
+ * The state copy logic assumes the master crtc gets processed
+ * before the slave crtc during the main compute_config loop.
+ * This works because the crtcs are created in pipe order,
+ * and the hardware requires master pipe < slave pipe as well.
+ * Should that change we need to rethink the logic.
+ */
+ if (WARN_ON(drm_crtc_index(&master_crtc->base) >
+ drm_crtc_index(&slave_crtc->base)))
+ return -EINVAL;
- DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
- slave_crtc->base.base.id, slave_crtc->base.name);
+ drm_dbg_kms(&i915->drm,
+ "[CRTC:%d:%s] Used as slave for big joiner master [CRTC:%d:%s]\n",
+ slave_crtc->base.base.id, slave_crtc->base.name,
+ master_crtc->base.base.id, master_crtc->base.name);
- return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+ master_crtc_state->bigjoiner_pipes =
+ BIT(master_crtc->pipe) | BIT(slave_crtc->pipe);
+ slave_crtc_state->bigjoiner_pipes =
+ BIT(master_crtc->pipe) | BIT(slave_crtc->pipe);
-claimed:
- DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
- "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
- slave_crtc->base.base.id, slave_crtc->base.name,
- master_crtc->base.base.id, master_crtc->base.name);
- return -EINVAL;
+ ret = copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static void kill_bigjoiner_slave(struct intel_atomic_state *state,
- struct intel_crtc_state *master_crtc_state)
+ struct intel_crtc *master_crtc)
{
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc_state->bigjoiner_linked_crtc);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *master_crtc_state =
+ intel_atomic_get_new_crtc_state(state, master_crtc);
+ struct intel_crtc *slave_crtc;
+
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
+ intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
+ struct intel_crtc_state *slave_crtc_state =
+ intel_atomic_get_new_crtc_state(state, slave_crtc);
- slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
- slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
- slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
- intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
+ slave_crtc_state->bigjoiner = false;
+ slave_crtc_state->bigjoiner_pipes = 0;
+
+ intel_crtc_copy_uapi_to_hw_state_modeset(state, slave_crtc);
+ }
+
+ master_crtc_state->bigjoiner = false;
+ master_crtc_state->bigjoiner_pipes = 0;
}
/**
@@ -7805,34 +7537,37 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
+ u8 affected_pipes = 0;
+ u8 modeset_pipes = 0;
int i;
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- struct intel_crtc_state *linked_crtc_state;
- struct intel_crtc *linked_crtc;
- int ret;
+ affected_pipes |= crtc_state->bigjoiner_pipes;
+ if (intel_crtc_needs_modeset(crtc_state))
+ modeset_pipes |= crtc_state->bigjoiner_pipes;
+ }
- if (!crtc_state->bigjoiner)
- continue;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, affected_pipes) {
+ crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+ }
- linked_crtc = crtc_state->bigjoiner_linked_crtc;
- linked_crtc_state = intel_atomic_get_crtc_state(&state->base, linked_crtc);
- if (IS_ERR(linked_crtc_state))
- return PTR_ERR(linked_crtc_state);
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, modeset_pipes) {
+ int ret;
- if (!intel_crtc_needs_modeset(crtc_state))
- continue;
+ crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
- linked_crtc_state->uapi.mode_changed = true;
+ crtc_state->uapi.mode_changed = true;
- ret = drm_atomic_add_affected_connectors(&state->base,
- &linked_crtc->base);
+ ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base);
if (ret)
return ret;
- ret = intel_atomic_add_affected_planes(state, linked_crtc);
+ ret = intel_atomic_add_affected_planes(state, crtc);
if (ret)
return ret;
}
@@ -7840,8 +7575,8 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
/* Kill old bigjoiner link, we may re-establish afterwards */
if (intel_crtc_needs_modeset(crtc_state) &&
- crtc_state->bigjoiner && !crtc_state->bigjoiner_slave)
- kill_bigjoiner_slave(state, crtc_state);
+ intel_crtc_is_bigjoiner_master(crtc_state))
+ kill_bigjoiner_slave(state, crtc);
}
return 0;
@@ -7866,6 +7601,10 @@ static int intel_atomic_check(struct drm_device *dev,
new_crtc_state, i) {
if (new_crtc_state->inherited != old_crtc_state->inherited)
new_crtc_state->uapi.mode_changed = true;
+
+ if (new_crtc_state->uapi.scaling_filter !=
+ old_crtc_state->uapi.scaling_filter)
+ new_crtc_state->uapi.mode_changed = true;
}
intel_vrr_check_modeset(state);
@@ -7881,30 +7620,30 @@ static int intel_atomic_check(struct drm_device *dev,
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
if (!intel_crtc_needs_modeset(new_crtc_state)) {
- /* Light copy */
- intel_crtc_copy_uapi_to_hw_state_nomodeset(state, new_crtc_state);
-
+ if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
+ copy_bigjoiner_crtc_state_nomodeset(state, crtc);
+ else
+ intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
continue;
}
- if (!new_crtc_state->uapi.enable) {
- if (!new_crtc_state->bigjoiner_slave) {
- intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state);
- any_ms = true;
- }
+ if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
+ drm_WARN_ON(&dev_priv->drm, new_crtc_state->uapi.enable);
continue;
}
- ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
+ ret = intel_crtc_prepare_cleared_state(state, crtc);
if (ret)
goto fail;
+ if (!new_crtc_state->hw.enable)
+ continue;
+
ret = intel_modeset_pipe_config(state, new_crtc_state);
if (ret)
goto fail;
- ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state,
- new_crtc_state);
+ ret = intel_atomic_check_bigjoiner(state, crtc);
if (ret)
goto fail;
}
@@ -7958,10 +7697,7 @@ static int intel_atomic_check(struct drm_device *dev,
}
if (new_crtc_state->bigjoiner) {
- struct intel_crtc_state *linked_crtc_state =
- intel_atomic_get_new_crtc_state(state, new_crtc_state->bigjoiner_linked_crtc);
-
- if (intel_crtc_needs_modeset(linked_crtc_state)) {
+ if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes)) {
new_crtc_state->uapi.mode_changed = true;
new_crtc_state->update_pipe = false;
}
@@ -8141,9 +7877,6 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
if (DISPLAY_VER(dev_priv) >= 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
hsw_set_linetime_wm(new_crtc_state);
-
- if (DISPLAY_VER(dev_priv) >= 11)
- icl_set_pipe_chicken(new_crtc_state);
}
static void commit_pipe_pre_planes(struct intel_atomic_state *state,
@@ -8208,7 +7941,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
dev_priv->display->crtc_enable(state, crtc);
- if (new_crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
return;
/* vblanks work again, re-enable pipe CRC. */
@@ -8218,7 +7951,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
static void intel_update_crtc(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_crtc_state *new_crtc_state =
@@ -8235,21 +7968,22 @@ static void intel_update_crtc(struct intel_atomic_state *state,
if (new_crtc_state->update_pipe)
intel_encoders_update_pipe(state, crtc);
+
+ if (DISPLAY_VER(i915) >= 11 &&
+ new_crtc_state->update_pipe)
+ icl_set_pipe_chicken(new_crtc_state);
}
intel_fbc_update(state, crtc);
- intel_update_planes_on_crtc(state, crtc);
+ intel_crtc_planes_update_noarm(state, crtc);
/* Perform vblank evasion around commit operation */
intel_pipe_update_start(new_crtc_state);
commit_pipe_pre_planes(state, crtc);
- if (DISPLAY_VER(dev_priv) >= 9)
- skl_arm_planes_on_crtc(state, crtc);
- else
- i9xx_arm_planes_on_crtc(state, crtc);
+ intel_crtc_planes_update_arm(state, crtc);
commit_pipe_post_planes(state, crtc);
@@ -8325,7 +8059,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
*/
if (!is_trans_port_sync_slave(old_crtc_state) &&
!intel_dp_mst_is_slave_trans(old_crtc_state) &&
- !old_crtc_state->bigjoiner_slave)
+ !intel_crtc_is_bigjoiner_slave(old_crtc_state))
continue;
intel_old_crtc_state_disables(state, old_crtc_state,
@@ -8440,7 +8174,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
is_trans_port_sync_master(new_crtc_state) ||
- (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave))
+ intel_crtc_is_bigjoiner_master(new_crtc_state))
continue;
modeset_pipes &= ~BIT(pipe);
@@ -8967,10 +8701,8 @@ static u32 intel_encoder_possible_crtcs(struct intel_encoder *encoder)
struct intel_crtc *crtc;
u32 possible_crtcs = 0;
- for_each_intel_crtc(dev, crtc) {
- if (encoder->pipe_mask & BIT(crtc->pipe))
- possible_crtcs |= drm_crtc_mask(&crtc->base);
- }
+ for_each_intel_crtc_in_pipe_mask(dev, crtc, encoder->pipe_mask)
+ possible_crtcs |= drm_crtc_mask(&crtc->base);
return possible_crtcs;
}
@@ -9026,6 +8758,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
intel_ddi_init(dev_priv, PORT_B);
intel_ddi_init(dev_priv, PORT_C);
intel_ddi_init(dev_priv, PORT_D_XELPD);
+ intel_ddi_init(dev_priv, PORT_TC1);
} else if (IS_ALDERLAKE_P(dev_priv)) {
intel_ddi_init(dev_priv, PORT_A);
intel_ddi_init(dev_priv, PORT_B);
@@ -9478,7 +9211,7 @@ void intel_modeset_init_hw(struct drm_i915_private *i915)
cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state);
intel_update_cdclk(i915);
- intel_dump_cdclk_config(&i915->cdclk.hw, "Current CDCLK");
+ intel_cdclk_dump_config(i915, &i915->cdclk.hw, "Current CDCLK");
cdclk_state->logical = cdclk_state->actual = i915->cdclk.hw;
}
@@ -9980,8 +9713,7 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
udelay(150); /* wait for warmup */
}
- intel_de_write(dev_priv, PIPECONF(pipe),
- PIPECONF_ENABLE | PIPECONF_PROGRESSIVE);
+ intel_de_write(dev_priv, PIPECONF(pipe), PIPECONF_ENABLE);
intel_de_posting_read(dev_priv, PIPECONF(pipe));
intel_wait_for_pipe_scanline_moving(crtc);
@@ -9995,18 +9727,15 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
pipe_name(pipe));
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_A)) &
- DISPLAY_PLANE_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_B)) &
- DISPLAY_PLANE_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_C)) &
- DISPLAY_PLANE_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE);
+ intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE_MASK);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE);
+ intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE_MASK);
intel_de_write(dev_priv, PIPECONF(pipe), 0);
intel_de_posting_read(dev_priv, PIPECONF(pipe));
@@ -10156,7 +9885,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
/* Adjust the state of the output pipe according to whether we
* have active connectors/encoders. */
if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc) &&
- !crtc_state->bigjoiner_slave)
+ !intel_crtc_is_bigjoiner_slave(crtc_state))
intel_crtc_disable_noatomic(crtc, ctx);
if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
@@ -10369,12 +10098,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
/* read out to slave crtc as well for bigjoiner */
if (crtc_state->bigjoiner) {
+ struct intel_crtc *slave_crtc;
+
/* encoder should read be linked to bigjoiner master */
- WARN_ON(crtc_state->bigjoiner_slave);
+ WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
- crtc = crtc_state->bigjoiner_linked_crtc;
- crtc_state = to_intel_crtc_state(crtc->base.state);
- intel_encoder_get_config(encoder, crtc_state);
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc,
+ intel_crtc_bigjoiner_slave_pipes(crtc_state)) {
+ struct intel_crtc_state *slave_crtc_state;
+
+ slave_crtc_state = to_intel_crtc_state(slave_crtc->base.state);
+ intel_encoder_get_config(encoder, slave_crtc_state);
+ }
}
} else {
encoder->base.crtc = NULL;
@@ -10673,6 +10408,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
vlv_wm_sanitize(dev_priv);
} else if (DISPLAY_VER(dev_priv) >= 9) {
skl_wm_get_hw_state(dev_priv);
+ skl_wm_sanitize(dev_priv);
} else if (HAS_PCH_SPLIT(dev_priv)) {
ilk_wm_get_hw_state(dev_priv);
}
@@ -10688,6 +10424,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
}
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
+
+ intel_power_domains_sanitize_state(dev_priv);
}
void intel_display_resume(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index b61b75248ded..11d6134c53c8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -27,7 +27,8 @@
#include <drm/drm_util.h>
-enum link_m_n_set;
+#include "i915_reg_defs.h"
+
enum drm_scaling_filter;
struct dpll;
struct drm_connector;
@@ -317,8 +318,8 @@ enum aux_ch {
/* Used by dp and fdi links */
struct intel_link_m_n {
u32 tu;
- u32 gmch_m;
- u32 gmch_n;
+ u32 data_m;
+ u32 data_n;
u32 link_m;
u32 link_n;
};
@@ -429,11 +430,11 @@ enum hpd_pin {
&(dev)->mode_config.crtc_list, \
base.head)
-#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \
+#define for_each_intel_crtc_in_pipe_mask(dev, intel_crtc, pipe_mask) \
list_for_each_entry(intel_crtc, \
&(dev)->mode_config.crtc_list, \
base.head) \
- for_each_if((crtc_mask) & drm_crtc_mask(&intel_crtc->base))
+ for_each_if((pipe_mask) & BIT(intel_crtc->pipe))
#define for_each_intel_encoder(dev, intel_encoder) \
list_for_each_entry(intel_encoder, \
@@ -554,6 +555,10 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
bool bigjoiner);
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
+bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state);
+u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state);
+struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state);
void intel_plane_destroy(struct drm_plane *plane);
void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state);
@@ -605,18 +610,32 @@ bool intel_fuzzy_clock_check(int clock1, int clock2);
void intel_display_prepare_reset(struct drm_i915_private *dev_priv);
void intel_display_finish_reset(struct drm_i915_private *dev_priv);
-void intel_dp_get_m_n(struct intel_crtc *crtc,
- struct intel_crtc_state *pipe_config);
-void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state,
- enum link_m_n_set m_n);
-void ilk_get_fdi_m_n_config(struct intel_crtc *crtc,
- struct intel_crtc_state *pipe_config);
+void intel_zero_m_n(struct intel_link_m_n *m_n);
+void intel_set_m_n(struct drm_i915_private *i915,
+ const struct intel_link_m_n *m_n,
+ i915_reg_t data_m_reg, i915_reg_t data_n_reg,
+ i915_reg_t link_m_reg, i915_reg_t link_n_reg);
+void intel_get_m_n(struct drm_i915_private *i915,
+ struct intel_link_m_n *m_n,
+ i915_reg_t data_m_reg, i915_reg_t data_n_reg,
+ i915_reg_t link_m_reg, i915_reg_t link_n_reg);
+bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
+ enum transcoder transcoder);
+void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
+ enum transcoder cpu_transcoder,
+ const struct intel_link_m_n *m_n);
+void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc,
+ enum transcoder cpu_transcoder,
+ const struct intel_link_m_n *m_n);
+void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
+ enum transcoder cpu_transcoder,
+ struct intel_link_m_n *m_n);
+void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
+ enum transcoder cpu_transcoder,
+ struct intel_link_m_n *m_n);
void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
-bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state);
-void hsw_enable_ips(const struct intel_crtc_state *crtc_state);
-void hsw_disable_ips(const struct intel_crtc_state *crtc_state);
enum intel_display_power_domain intel_port_to_power_domain(enum port port);
enum intel_display_power_domain
intel_aux_power_domain(struct intel_digital_port *dig_port);
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 572445299b04..ffe6822d7414 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -16,6 +16,7 @@
#include "intel_dp_mst.h"
#include "intel_drrs.h"
#include "intel_fbc.h"
+#include "intel_fbdev.h"
#include "intel_hdcp.h"
#include "intel_hdmi.h"
#include "intel_pm.h"
@@ -78,7 +79,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
if (DISPLAY_VER(dev_priv) >= 9)
/* no global SR status; inspect per-plane WM */;
else if (HAS_PCH_SPLIT(dev_priv))
- sr_enabled = intel_de_read(dev_priv, WM1_LP_ILK) & WM1_LP_SR_EN;
+ sr_enabled = intel_de_read(dev_priv, WM1_LP_ILK) & WM_LP_ENABLE;
else if (IS_I965GM(dev_priv) || IS_G4X(dev_priv) ||
IS_I945G(dev_priv) || IS_I945GM(dev_priv))
sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF) & FW_BLC_SELF_EN;
@@ -124,9 +125,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
struct drm_framebuffer *drm_fb;
#ifdef CONFIG_DRM_FBDEV_EMULATION
- if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) {
- fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb);
-
+ fbdev_fb = intel_fbdev_framebuffer(dev_priv->fbdev);
+ if (fbdev_fb) {
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
fbdev_fb->base.width,
fbdev_fb->base.height,
@@ -474,8 +474,8 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
* reg for DC3CO debugging and validation,
* but TGL DMC f/w is using DMC_DEBUG3 reg for DC3CO counter.
*/
- seq_printf(m, "DC3CO count: %d\n",
- intel_de_read(dev_priv, DMC_DEBUG3));
+ seq_printf(m, "DC3CO count: %d\n", intel_de_read(dev_priv, IS_DGFX(dev_priv) ?
+ DG1_DMC_DEBUG3 : TGL_DMC_DEBUG3));
} else {
dc5_reg = IS_BROXTON(dev_priv) ? BXT_DMC_DC3_DC5_COUNT :
SKL_DMC_DC3_DC5_COUNT;
@@ -923,23 +923,23 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
yesno(crtc_state->uapi.active),
DRM_MODE_ARG(&crtc_state->uapi.mode));
- if (crtc_state->hw.enable) {
- seq_printf(m, "\thw: active=%s, adjusted_mode=" DRM_MODE_FMT "\n",
- yesno(crtc_state->hw.active),
- DRM_MODE_ARG(&crtc_state->hw.adjusted_mode));
+ seq_printf(m, "\thw: enable=%s, active=%s\n",
+ yesno(crtc_state->hw.enable), yesno(crtc_state->hw.active));
+ seq_printf(m, "\tadjusted_mode=" DRM_MODE_FMT "\n",
+ DRM_MODE_ARG(&crtc_state->hw.adjusted_mode));
+ seq_printf(m, "\tpipe__mode=" DRM_MODE_FMT "\n",
+ DRM_MODE_ARG(&crtc_state->hw.pipe_mode));
- seq_printf(m, "\tpipe src size=%dx%d, dither=%s, bpp=%d\n",
- crtc_state->pipe_src_w, crtc_state->pipe_src_h,
- yesno(crtc_state->dither), crtc_state->pipe_bpp);
+ seq_printf(m, "\tpipe src size=%dx%d, dither=%s, bpp=%d\n",
+ crtc_state->pipe_src_w, crtc_state->pipe_src_h,
+ yesno(crtc_state->dither), crtc_state->pipe_bpp);
- intel_scaler_info(m, crtc);
- }
+ intel_scaler_info(m, crtc);
if (crtc_state->bigjoiner)
- seq_printf(m, "\tLinked to [CRTC:%d:%s] as a %s\n",
- crtc_state->bigjoiner_linked_crtc->base.base.id,
- crtc_state->bigjoiner_linked_crtc->base.name,
- crtc_state->bigjoiner_slave ? "slave" : "master");
+ seq_printf(m, "\tLinked to 0x%x pipes as a %s\n",
+ crtc_state->bigjoiner_pipes,
+ intel_crtc_is_bigjoiner_slave(crtc_state) ? "slave" : "master");
for_each_intel_encoder_mask(&dev_priv->drm, encoder,
crtc_state->uapi.encoder_mask)
@@ -1015,6 +1015,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
seq_printf(m, " wrpll: 0x%08x\n", pll->state.hw_state.wrpll);
seq_printf(m, " cfgcr0: 0x%08x\n", pll->state.hw_state.cfgcr0);
seq_printf(m, " cfgcr1: 0x%08x\n", pll->state.hw_state.cfgcr1);
+ seq_printf(m, " div0: 0x%08x\n", pll->state.hw_state.div0);
seq_printf(m, " mg_refclkin_ctl: 0x%08x\n",
pll->state.hw_state.mg_refclkin_ctl);
seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
@@ -2402,6 +2403,9 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector)
*/
void intel_crtc_debugfs_add(struct drm_crtc *crtc)
{
- if (crtc->debugfs_entry)
- crtc_updates_add(crtc);
+ if (!crtc->debugfs_entry)
+ return;
+
+ crtc_updates_add(crtc);
+ intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc));
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 05babdcf5f2e..9ebae7ac3235 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -7,6 +7,7 @@
#include "i915_irq.h"
#include "intel_cdclk.h"
#include "intel_combo_phy.h"
+#include "intel_combo_phy_regs.h"
#include "intel_crt.h"
#include "intel_de.h"
#include "intel_display_power.h"
@@ -15,6 +16,7 @@
#include "intel_dpio_phy.h"
#include "intel_dpll.h"
#include "intel_hotplug.h"
+#include "intel_mchbar_regs.h"
#include "intel_pch_refclk.h"
#include "intel_pcode.h"
#include "intel_pm.h"
@@ -682,9 +684,8 @@ static void icl_tc_cold_exit(struct drm_i915_private *i915)
int ret, tries = 0;
while (1) {
- ret = sandybridge_pcode_write_timeout(i915,
- ICL_PCODE_EXIT_TCCOLD,
- 0, 250, 1);
+ ret = snb_pcode_write_timeout(i915, ICL_PCODE_EXIT_TCCOLD, 0,
+ 250, 1);
if (ret != -EAGAIN || ++tries == 3)
break;
msleep(1);
@@ -4052,8 +4053,7 @@ tgl_tc_cold_request(struct drm_i915_private *i915, bool block)
* Spec states that we should timeout the request after 200us
* but the function below will timeout after 500us
*/
- ret = sandybridge_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val,
- &high_val);
+ ret = snb_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, &high_val);
if (ret == 0) {
if (block &&
(low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED))
@@ -5468,8 +5468,7 @@ static u32 hsw_read_dcomp(struct drm_i915_private *dev_priv)
static void hsw_write_dcomp(struct drm_i915_private *dev_priv, u32 val)
{
if (IS_HASWELL(dev_priv)) {
- if (sandybridge_pcode_write(dev_priv,
- GEN6_PCODE_WRITE_D_COMP, val))
+ if (snb_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
drm_dbg_kms(&dev_priv->drm,
"Failed to write to D_COMP\n");
} else {
@@ -5582,7 +5581,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
intel_update_cdclk(dev_priv);
- intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK");
+ intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
}
/*
@@ -6216,6 +6215,37 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915)
}
/**
+ * intel_power_domains_sanitize_state - sanitize power domains state
+ * @i915: i915 device instance
+ *
+ * Sanitize the power domains state during driver loading and system resume.
+ * The function will disable all display power wells that BIOS has enabled
+ * without a user for it (any user for a power well has taken a reference
+ * on it by the time this function is called, after the state of all the
+ * pipe, encoder, etc. HW resources have been sanitized).
+ */
+void intel_power_domains_sanitize_state(struct drm_i915_private *i915)
+{
+ struct i915_power_domains *power_domains = &i915->power_domains;
+ struct i915_power_well *power_well;
+
+ mutex_lock(&power_domains->lock);
+
+ for_each_power_well_reverse(i915, power_well) {
+ if (power_well->desc->always_on || power_well->count ||
+ !power_well->desc->ops->is_enabled(i915, power_well))
+ continue;
+
+ drm_dbg_kms(&i915->drm,
+ "BIOS left unused %s power well enabled, disabling it\n",
+ power_well->desc->name);
+ intel_power_well_disable(i915, power_well);
+ }
+
+ mutex_unlock(&power_domains->lock);
+}
+
+/**
* intel_power_domains_enable - enable toggling of display power wells
* @i915: i915 device instance
*
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 686d18eaa24c..f6d0e6e73c6d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -7,7 +7,6 @@
#define __INTEL_DISPLAY_POWER_H__
#include "intel_runtime_pm.h"
-#include "i915_reg.h"
enum dpio_channel;
enum dpio_phy;
@@ -219,6 +218,7 @@ void intel_power_domains_disable(struct drm_i915_private *dev_priv);
void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
enum i915_drm_suspend_mode);
void intel_power_domains_resume(struct drm_i915_private *dev_priv);
+void intel_power_domains_sanitize_state(struct drm_i915_private *dev_priv);
void intel_display_power_suspend_late(struct drm_i915_private *i915);
void intel_display_power_resume_early(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h
index 4043e1276383..f05f0f9b5103 100644
--- a/drivers/gpu/drm/i915/display/intel_display_trace.h
+++ b/drivers/gpu/drm/i915/display/intel_display_trace.h
@@ -13,6 +13,7 @@
#include <linux/tracepoint.h>
#include "i915_drv.h"
+#include "i915_irq.h"
#include "intel_crtc.h"
#include "intel_display_types.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 41e3dd25a78f..b50d0e6efe21 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -26,7 +26,6 @@
#ifndef __INTEL_DISPLAY_TYPES_H__
#define __INTEL_DISPLAY_TYPES_H__
-#include <linux/async.h>
#include <linux/i2c.h>
#include <linux/pm_qos.h>
#include <linux/pwm.h>
@@ -38,7 +37,6 @@
#include <drm/drm_crtc.h>
#include <drm/drm_dsc.h>
#include <drm/drm_encoder.h>
-#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_rect.h>
@@ -145,25 +143,6 @@ struct intel_framebuffer {
struct i915_address_space *dpt_vm;
};
-struct intel_fbdev {
- struct drm_fb_helper helper;
- struct intel_framebuffer *fb;
- struct i915_vma *vma;
- unsigned long vma_flags;
- async_cookie_t cookie;
- int preferred_bpp;
-
- /* Whether or not fbdev hpd processing is temporarily suspended */
- bool hpd_suspended : 1;
- /* Set when a hotplug was received while HPD processing was
- * suspended
- */
- bool hpd_waiting : 1;
-
- /* Protects hpd_suspended */
- struct mutex hpd_lock;
-};
-
enum intel_hotplug_state {
INTEL_HOTPLUG_UNCHANGED,
INTEL_HOTPLUG_CHANGED,
@@ -634,6 +613,9 @@ struct intel_plane_state {
struct intel_fb_view view;
+ /* Indicates if async flip is required */
+ bool do_async_flip;
+
/* Plane pxp decryption state */
bool decrypt;
@@ -1165,6 +1147,7 @@ struct intel_crtc_state {
/* bitmask of actually visible planes (enum plane_id) */
u8 active_planes;
+ u8 scaled_planes;
u8 nv12_planes;
u8 c8_planes;
@@ -1199,11 +1182,8 @@ struct intel_crtc_state {
/* enable pipe big joiner? */
bool bigjoiner;
- /* big joiner slave crtc? */
- bool bigjoiner_slave;
-
- /* linked crtc for bigjoiner, either slave or master */
- struct intel_crtc *bigjoiner_linked_crtc;
+ /* big joiner pipe bitmask */
+ u8 bigjoiner_pipes;
/* Display Stream compression state */
struct {
@@ -1442,25 +1422,6 @@ struct intel_hdmi {
};
struct intel_dp_mst_encoder;
-/*
- * enum link_m_n_set:
- * When platform provides two set of M_N registers for dp, we can
- * program them and switch between them incase of DRRS.
- * But When only one such register is provided, we have to program the
- * required divider value on that registers itself based on the DRRS state.
- *
- * M1_N1 : Program dp_m_n on M1_N1 registers
- * dp_m2_n2 on M2_N2 registers (If supported)
- *
- * M2_N2 : Program dp_m2_n2 on M1_N1 registers
- * M2_N2 registers are not supported
- */
-
-enum link_m_n_set {
- /* Sets the m1_n1 and m2_n2 */
- M1_N1 = 0,
- M2_N2
-};
struct intel_dp_compliance_data {
unsigned long edid;
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index a69b28d65a9b..7616a3906b9e 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -43,9 +43,9 @@
__stringify(major) "_" \
__stringify(minor) ".bin"
-#define GEN12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
+#define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000
-#define GEN13_DMC_MAX_FW_SIZE 0x20000
+#define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
#define ADLP_DMC_PATH DMC_PATH(adlp, 2, 14)
#define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 14)
@@ -684,23 +684,23 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
if (IS_ALDERLAKE_P(dev_priv)) {
dmc->fw_path = ADLP_DMC_PATH;
dmc->required_version = ADLP_DMC_VERSION_REQUIRED;
- dmc->max_fw_size = GEN13_DMC_MAX_FW_SIZE;
+ dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE;
} else if (IS_ALDERLAKE_S(dev_priv)) {
dmc->fw_path = ADLS_DMC_PATH;
dmc->required_version = ADLS_DMC_VERSION_REQUIRED;
- dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
+ dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_DG1(dev_priv)) {
dmc->fw_path = DG1_DMC_PATH;
dmc->required_version = DG1_DMC_VERSION_REQUIRED;
- dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
+ dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_ROCKETLAKE(dev_priv)) {
dmc->fw_path = RKL_DMC_PATH;
dmc->required_version = RKL_DMC_VERSION_REQUIRED;
- dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
+ dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(dev_priv) >= 12) {
dmc->fw_path = TGL_DMC_PATH;
dmc->required_version = TGL_DMC_VERSION_REQUIRED;
- dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
+ dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(dev_priv) == 11) {
dmc->fw_path = ICL_DMC_PATH;
dmc->required_version = ICL_DMC_VERSION_REQUIRED;
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
index b20f3441ca60..7c590309a3a9 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc.h
@@ -6,7 +6,7 @@
#ifndef __INTEL_DMC_H__
#define __INTEL_DMC_H__
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
#include "intel_wakeref.h"
#include <linux/workqueue.h>
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 36ab58c25b64..1046e7fe310a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -46,6 +46,7 @@
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_backlight.h"
+#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
@@ -72,8 +73,6 @@
#include "intel_vdsc.h"
#include "intel_vrr.h"
-#define DP_DPRX_ESI_LEN 14
-
/* DP DSC throughput values used for slice count calculations KPixels/s */
#define DP_DSC_PEAK_PIXEL_RATE 2720000
#define DP_DSC_MAX_ENC_THROUGHPUT_0 340000
@@ -705,7 +704,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
i915->max_cdclk_freq * 48 /
intel_dp_mode_to_fec_clock(mode_clock);
- DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
+ drm_dbg_kms(&i915->drm, "Max big joiner bpp: %u\n", max_bpp_bigjoiner);
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
}
@@ -887,9 +886,8 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
return MODE_CLOCK_HIGH;
/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
- tmds_clock = target_clock;
- if (drm_mode_is_420_only(info, mode))
- tmds_clock /= 2;
+ tmds_clock = intel_hdmi_tmds_clock(target_clock, 8,
+ drm_mode_is_420_only(info, mode));
if (intel_dp->dfp.min_tmds_clock &&
tmds_clock < intel_dp->dfp.min_tmds_clock)
@@ -1140,21 +1138,12 @@ static bool intel_dp_hdmi_ycbcr420(struct intel_dp *intel_dp,
intel_dp->dfp.ycbcr_444_to_420);
}
-static int intel_dp_hdmi_tmds_clock(struct intel_dp *intel_dp,
- const struct intel_crtc_state *crtc_state, int bpc)
-{
- int clock = crtc_state->hw.adjusted_mode.crtc_clock * bpc / 8;
-
- if (intel_dp_hdmi_ycbcr420(intel_dp, crtc_state))
- clock /= 2;
-
- return clock;
-}
-
static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state, int bpc)
{
- int tmds_clock = intel_dp_hdmi_tmds_clock(intel_dp, crtc_state, bpc);
+ int clock = crtc_state->hw.adjusted_mode.crtc_clock;
+ int tmds_clock = intel_hdmi_tmds_clock(clock, bpc,
+ intel_dp_hdmi_ycbcr420(intel_dp, crtc_state));
if (intel_dp->dfp.min_tmds_clock &&
tmds_clock < intel_dp->dfp.min_tmds_clock)
@@ -1167,14 +1156,13 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
return true;
}
-static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp,
- const struct intel_crtc_state *crtc_state,
- int bpc)
+static bool intel_dp_hdmi_bpc_possible(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ int bpc)
{
- return intel_hdmi_deep_color_possible(crtc_state, bpc,
- intel_dp->has_hdmi_sink,
- intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
+ return intel_hdmi_bpc_possible(crtc_state, bpc, intel_dp->has_hdmi_sink,
+ intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc);
}
@@ -1192,7 +1180,7 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp,
if (intel_dp->dfp.min_tmds_clock) {
for (; bpc >= 10; bpc -= 2) {
- if (intel_dp_hdmi_deep_color_possible(intel_dp, crtc_state, bpc))
+ if (intel_dp_hdmi_bpc_possible(intel_dp, crtc_state, bpc))
break;
}
}
@@ -1897,7 +1885,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* FIXME: abstract this better */
if (pipe_config->splitter.enable)
- pipe_config->dp_m_n.gmch_m *= pipe_config->splitter.link_count;
+ pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count;
if (!HAS_DDI(dev_priv))
g4x_dp_set_clock(encoder, pipe_config);
@@ -2813,11 +2801,22 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
}
static bool
-intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
+intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi)
+{
+ return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4;
+}
+
+static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4])
{
- return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI,
- sink_irq_vector, DP_DPRX_ESI_LEN) ==
- DP_DPRX_ESI_LEN;
+ int retry;
+
+ for (retry = 0; retry < 3; retry++) {
+ if (drm_dp_dpcd_write(&intel_dp->aux, DP_SINK_COUNT_ESI + 1,
+ &esi[1], 3) == 3)
+ return true;
+ }
+
+ return false;
}
bool
@@ -2909,7 +2908,8 @@ out:
}
static ssize_t
-intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_infoframe,
+intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
+ const struct hdmi_drm_infoframe *drm_infoframe,
struct dp_sdp *sdp,
size_t size)
{
@@ -2925,12 +2925,12 @@ intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_in
len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf));
if (len < 0) {
- DRM_DEBUG_KMS("buffer size is smaller than hdr metadata infoframe\n");
+ drm_dbg_kms(&i915->drm, "buffer size is smaller than hdr metadata infoframe\n");
return -ENOSPC;
}
if (len != infoframe_size) {
- DRM_DEBUG_KMS("wrong static hdr metadata size\n");
+ drm_dbg_kms(&i915->drm, "wrong static hdr metadata size\n");
return -ENOSPC;
}
@@ -3003,7 +3003,8 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
sizeof(sdp));
break;
case HDMI_PACKET_TYPE_GAMUT_METADATA:
- len = intel_dp_hdr_metadata_infoframe_sdp_pack(&crtc_state->infoframes.drm.drm,
+ len = intel_dp_hdr_metadata_infoframe_sdp_pack(dev_priv,
+ &crtc_state->infoframes.drm.drm,
&sdp, sizeof(sdp));
break;
default:
@@ -3411,22 +3412,22 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
switch (data->phy_pattern) {
case DP_PHY_TEST_PATTERN_NONE:
- DRM_DEBUG_KMS("Disable Phy Test Pattern\n");
+ drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0);
break;
case DP_PHY_TEST_PATTERN_D10_2:
- DRM_DEBUG_KMS("Set D10.2 Phy Test Pattern\n");
+ drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2);
break;
case DP_PHY_TEST_PATTERN_ERROR_COUNT:
- DRM_DEBUG_KMS("Set Error Count Phy Test Pattern\n");
+ drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE |
DDI_DP_COMP_CTL_SCRAMBLED_0);
break;
case DP_PHY_TEST_PATTERN_PRBS7:
- DRM_DEBUG_KMS("Set PRBS7 Phy Test Pattern\n");
+ drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7);
break;
@@ -3436,7 +3437,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
* current firmware of DPR-100 could not set it, so hardcoding
* now for complaince test.
*/
- DRM_DEBUG_KMS("Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
+ drm_dbg_kms(&dev_priv->drm,
+ "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
pattern_val = 0x3e0f83e0;
intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val);
pattern_val = 0x0f83e0f8;
@@ -3453,7 +3455,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
* current firmware of DPR-100 could not set it, so hardcoding
* now for complaince test.
*/
- DRM_DEBUG_KMS("Set HBR2 compliance Phy Test Pattern\n");
+ drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n");
pattern_val = 0xFB;
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 |
@@ -3522,13 +3524,14 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest;
u8 link_status[DP_LINK_STATUS_SIZE];
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
link_status) < 0) {
- DRM_DEBUG_KMS("failed to get link status\n");
+ drm_dbg_kms(&i915->drm, "failed to get link status\n");
return;
}
@@ -3553,11 +3556,12 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest;
if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) {
- DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n");
+ drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n");
return DP_TEST_NAK;
}
@@ -3614,15 +3618,63 @@ update_status:
"Could not write test response to sink\n");
}
+static bool intel_dp_link_ok(struct intel_dp *intel_dp,
+ u8 link_status[DP_LINK_STATUS_SIZE])
+{
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ bool uhbr = intel_dp->link_rate >= 1000000;
+ bool ok;
+
+ if (uhbr)
+ ok = drm_dp_128b132b_lane_channel_eq_done(link_status,
+ intel_dp->lane_count);
+ else
+ ok = drm_dp_channel_eq_ok(link_status, intel_dp->lane_count);
+
+ if (ok)
+ return true;
+
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] %s link not ok, retraining\n",
+ encoder->base.base.id, encoder->base.name,
+ uhbr ? "128b/132b" : "8b/10b");
+
+ return false;
+}
+
static void
-intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, bool *handled)
+intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack)
{
- drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, handled);
+ bool handled = false;
- if (esi[1] & DP_CP_IRQ) {
- intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
- *handled = true;
- }
+ drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled);
+ if (handled)
+ ack[1] |= esi[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY);
+
+ if (esi[1] & DP_CP_IRQ) {
+ intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
+ ack[1] |= DP_CP_IRQ;
+ }
+}
+
+static bool intel_dp_mst_link_status(struct intel_dp *intel_dp)
+{
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ u8 link_status[DP_LINK_STATUS_SIZE] = {};
+ const size_t esi_link_status_size = DP_LINK_STATUS_SIZE - 2;
+
+ if (drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS_ESI, link_status,
+ esi_link_status_size) != esi_link_status_size) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to read link status\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ return intel_dp_link_ok(intel_dp, link_status);
}
/**
@@ -3647,20 +3699,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
for (;;) {
- /*
- * The +2 is because DP_DPRX_ESI_LEN is 14, but we then
- * pass in "esi+10" to drm_dp_channel_eq_ok(), which
- * takes a 6-byte array. So we actually need 16 bytes
- * here.
- *
- * Somebody who knows what the limits actually are
- * should check this, but for now this is at least
- * harmless and avoids a valid compiler warning about
- * using more of the array than we have allocated.
- */
- u8 esi[DP_DPRX_ESI_LEN+2] = {};
- bool handled;
- int retry;
+ u8 esi[4] = {};
+ u8 ack[4] = {};
if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) {
drm_dbg_kms(&i915->drm,
@@ -3670,30 +3710,22 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
break;
}
- /* check link status - esi[10] = 0x200c */
+ drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi);
+
if (intel_dp->active_mst_links > 0 && link_ok &&
- !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
- drm_dbg_kms(&i915->drm,
- "channel EQ not ok, retraining\n");
- link_ok = false;
+ esi[3] & LINK_STATUS_CHANGED) {
+ if (!intel_dp_mst_link_status(intel_dp))
+ link_ok = false;
+ ack[3] |= LINK_STATUS_CHANGED;
}
- drm_dbg_kms(&i915->drm, "got esi %3ph\n", esi);
+ intel_dp_mst_hpd_irq(intel_dp, esi, ack);
- intel_dp_mst_hpd_irq(intel_dp, esi, &handled);
-
- if (!handled)
+ if (!memchr_inv(ack, 0, sizeof(ack)))
break;
- for (retry = 0; retry < 3; retry++) {
- int wret;
-
- wret = drm_dp_dpcd_write(&intel_dp->aux,
- DP_SINK_COUNT_ESI+1,
- &esi[1], 3);
- if (wret == 3)
- break;
- }
+ if (!intel_dp_ack_sink_irq_esi(intel_dp, ack))
+ drm_dbg_kms(&i915->drm, "Failed to ack ESI\n");
}
return link_ok;
@@ -3756,8 +3788,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
intel_dp->lane_count))
return false;
- /* Retrain if Channel EQ or CR not ok */
- return !drm_dp_channel_eq_ok(link_status, intel_dp->lane_count);
+ /* Retrain if link not ok */
+ return !intel_dp_link_ok(intel_dp, link_status);
}
static bool intel_dp_has_connector(struct intel_dp *intel_dp,
@@ -3787,14 +3819,14 @@ static bool intel_dp_has_connector(struct intel_dp *intel_dp,
static int intel_dp_prep_link_retrain(struct intel_dp *intel_dp,
struct drm_modeset_acquire_ctx *ctx,
- u32 *crtc_mask)
+ u8 *pipe_mask)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
int ret = 0;
- *crtc_mask = 0;
+ *pipe_mask = 0;
if (!intel_dp_needs_link_retrain(intel_dp))
return 0;
@@ -3828,12 +3860,12 @@ static int intel_dp_prep_link_retrain(struct intel_dp *intel_dp,
!try_wait_for_completion(&conn_state->commit->hw_done))
continue;
- *crtc_mask |= drm_crtc_mask(&crtc->base);
+ *pipe_mask |= BIT(crtc->pipe);
}
drm_connector_list_iter_end(&conn_iter);
if (!intel_dp_needs_link_retrain(intel_dp))
- *crtc_mask = 0;
+ *pipe_mask = 0;
return ret;
}
@@ -3852,7 +3884,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *crtc;
- u32 crtc_mask;
+ u8 pipe_mask;
int ret;
if (!intel_dp_is_connected(intel_dp))
@@ -3863,17 +3895,17 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
if (ret)
return ret;
- ret = intel_dp_prep_link_retrain(intel_dp, ctx, &crtc_mask);
+ ret = intel_dp_prep_link_retrain(intel_dp, ctx, &pipe_mask);
if (ret)
return ret;
- if (crtc_mask == 0)
+ if (pipe_mask == 0)
return 0;
drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link\n",
encoder->base.base.id, encoder->base.name);
- for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -3884,7 +3916,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), false);
}
- for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -3901,7 +3933,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
break;
}
- for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -3919,14 +3951,14 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
struct drm_modeset_acquire_ctx *ctx,
- u32 *crtc_mask)
+ u8 *pipe_mask)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
int ret = 0;
- *crtc_mask = 0;
+ *pipe_mask = 0;
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
@@ -3957,7 +3989,7 @@ static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
!try_wait_for_completion(&conn_state->commit->hw_done))
continue;
- *crtc_mask |= drm_crtc_mask(&crtc->base);
+ *pipe_mask |= BIT(crtc->pipe);
}
drm_connector_list_iter_end(&conn_iter);
@@ -3970,7 +4002,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *crtc;
- u32 crtc_mask;
+ u8 pipe_mask;
int ret;
ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
@@ -3978,17 +4010,17 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder,
if (ret)
return ret;
- ret = intel_dp_prep_phy_test(intel_dp, ctx, &crtc_mask);
+ ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask);
if (ret)
return ret;
- if (crtc_mask == 0)
+ if (pipe_mask == 0)
return 0;
drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n",
encoder->base.base.id, encoder->base.name);
- for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
+ for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -4974,6 +5006,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
mutex_lock(&dev->mode_config.mutex);
edid = drm_get_edid(connector, &intel_dp->aux.ddc);
+ if (!edid) {
+ /* Fallback to EDID from ACPI OpRegion, if any */
+ edid = intel_opregion_get_edid(intel_connector);
+ if (edid)
+ drm_dbg_kms(&dev_priv->drm,
+ "[CONNECTOR:%d:%s] Using OpRegion EDID\n",
+ connector->base.id, connector->name);
+ }
if (edid) {
if (drm_add_edid_modes(connector, edid)) {
drm_connector_update_edid_property(connector, edid);
@@ -5048,8 +5088,8 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
intel_connector = container_of(work, typeof(*intel_connector),
modeset_retry_work);
connector = &intel_connector->base;
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
- connector->name);
+ drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id,
+ connector->name);
/* Grab the locks before changing connector property*/
mutex_lock(&connector->dev->mode_config.mutex);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index b64145a3869a..d457e17bdc57 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -8,8 +8,6 @@
#include <linux/types.h>
-#include "i915_reg.h"
-
enum intel_output_format;
enum pipe;
enum port;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c
index 5fbb767fcd63..2bc119374555 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c
@@ -10,7 +10,7 @@
#include "intel_pps.h"
#include "intel_tc.h"
-u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
+static u32 intel_dp_aux_pack(const u8 *src, int src_bytes)
{
int i;
u32 v = 0;
@@ -22,7 +22,7 @@ u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
return v;
}
-static void intel_dp_unpack_aux(u32 src, u8 *dst, int dst_bytes)
+static void intel_dp_aux_unpack(u32 src, u8 *dst, int dst_bytes)
{
int i;
@@ -267,7 +267,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
for (i = 0; i < send_bytes; i += 4)
intel_uncore_write(uncore,
ch_data[i >> 2],
- intel_dp_pack_aux(send + i,
+ intel_dp_aux_pack(send + i,
send_bytes - i));
/* Send the command and wait for it to complete */
@@ -352,7 +352,7 @@ done:
recv_bytes = recv_size;
for (i = 0; i < recv_bytes; i += 4)
- intel_dp_unpack_aux(intel_uncore_read(uncore, ch_data[i >> 2]),
+ intel_dp_aux_unpack(intel_uncore_read(uncore, ch_data[i >> 2]),
recv + i, recv_bytes - i);
ret = recv_bytes;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.h b/drivers/gpu/drm/i915/display/intel_dp_aux.h
index 4afbe76217b9..738577537bc7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.h
@@ -6,12 +6,8 @@
#ifndef __INTEL_DP_AUX_H__
#define __INTEL_DP_AUX_H__
-#include <linux/types.h>
-
struct intel_dp;
-u32 intel_dp_pack_aux(const u8 *src, int src_bytes);
-
void intel_dp_aux_fini(struct intel_dp *intel_dp);
void intel_dp_aux_init(struct intel_dp *intel_dp);
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 9451f336f28f..5d98773efd1b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -712,7 +712,7 @@ static bool intel_dp_adjust_request_changed(const struct intel_crtc_state *crtc_
return false;
}
-static void
+void
intel_dp_dump_link_status(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy,
const u8 link_status[DP_LINK_STATUS_SIZE])
{
@@ -996,6 +996,23 @@ static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp,
return drm_dp_dpcd_write(&intel_dp->aux, reg, &val, 1) == 1;
}
+static int
+intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ u8 sink_status;
+ int ret;
+
+ ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_SINK_STATUS, &sink_status);
+ if (ret != 1) {
+ drm_dbg_kms(&i915->drm, "Failed to read sink status\n");
+ return ret < 0 ? ret : -EIO;
+ }
+
+ return sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION ? 1 : 0;
+}
+
/**
* intel_dp_stop_link_train - stop link training
* @intel_dp: DP struct
@@ -1015,11 +1032,21 @@ static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp,
void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+
intel_dp->link_trained = true;
intel_dp_disable_dpcd_training_pattern(intel_dp, DP_PHY_DPRX);
intel_dp_program_link_training_pattern(intel_dp, crtc_state, DP_PHY_DPRX,
DP_TRAINING_PATTERN_DISABLE);
+
+ if (intel_dp_is_uhbr(crtc_state) &&
+ wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) {
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] 128b/132b intra-hop not clearing\n",
+ encoder->base.base.id, encoder->base.name);
+ }
}
static bool
@@ -1083,8 +1110,6 @@ intel_dp_link_train_all_phys(struct intel_dp *intel_dp,
bool ret = true;
int i;
- intel_dp_prepare_link_train(intel_dp, crtc_state);
-
for (i = lttpr_count - 1; i >= 0; i--) {
enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);
@@ -1104,6 +1129,272 @@ intel_dp_link_train_all_phys(struct intel_dp *intel_dp,
return ret;
}
+/*
+ * 128b/132b DP LANEx_EQ_DONE Sequence (DP 2.0 E11 3.5.2.16.1)
+ */
+static bool
+intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ u8 link_status[DP_LINK_STATUS_SIZE];
+ int delay_us;
+ int try, max_tries = 20;
+ unsigned long deadline;
+ bool timeout = false;
+
+ /*
+ * Reset signal levels. Start transmitting 128b/132b TPS1.
+ *
+ * Put DPRX and LTTPRs (if any) into intra-hop AUX mode by writing TPS1
+ * in DP_TRAINING_PATTERN_SET.
+ */
+ if (!intel_dp_reset_link_train(intel_dp, crtc_state, DP_PHY_DPRX,
+ DP_TRAINING_PATTERN_1)) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to start 128b/132b TPS1\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ delay_us = drm_dp_128b132b_read_aux_rd_interval(&intel_dp->aux);
+
+ /* Read the initial TX FFE settings. */
+ if (drm_dp_dpcd_read_link_status(&intel_dp->aux, link_status) < 0) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to read TX FFE presets\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ /* Update signal levels and training set as requested. */
+ intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, link_status);
+ if (!intel_dp_update_link_train(intel_dp, crtc_state, DP_PHY_DPRX)) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to set initial TX FFE settings\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ /* Start transmitting 128b/132b TPS2. */
+ if (!intel_dp_set_link_train(intel_dp, crtc_state, DP_PHY_DPRX,
+ DP_TRAINING_PATTERN_2)) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to start 128b/132b TPS2\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ /* Time budget for the LANEx_EQ_DONE Sequence */
+ deadline = jiffies + msecs_to_jiffies_timeout(400);
+
+ for (try = 0; try < max_tries; try++) {
+ usleep_range(delay_us, 2 * delay_us);
+
+ /*
+ * The delay may get updated. The transmitter shall read the
+ * delay before link status during link training.
+ */
+ delay_us = drm_dp_128b132b_read_aux_rd_interval(&intel_dp->aux);
+
+ if (drm_dp_dpcd_read_link_status(&intel_dp->aux, link_status) < 0) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to read link status\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (drm_dp_128b132b_link_training_failed(link_status)) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Downstream link training failure\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (drm_dp_128b132b_lane_channel_eq_done(link_status, crtc_state->lane_count)) {
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] Lane channel eq done\n",
+ encoder->base.base.id, encoder->base.name);
+ break;
+ }
+
+ if (timeout) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Lane channel eq timeout\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (time_after(jiffies, deadline))
+ timeout = true; /* try one last time after deadline */
+
+ /* Update signal levels and training set as requested. */
+ intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, link_status);
+ if (!intel_dp_update_link_train(intel_dp, crtc_state, DP_PHY_DPRX)) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to update TX FFE settings\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+ }
+
+ if (try == max_tries) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Max loop count reached\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ for (;;) {
+ if (time_after(jiffies, deadline))
+ timeout = true; /* try one last time after deadline */
+
+ if (drm_dp_dpcd_read_link_status(&intel_dp->aux, link_status) < 0) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to read link status\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (drm_dp_128b132b_link_training_failed(link_status)) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Downstream link training failure\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (drm_dp_128b132b_eq_interlane_align_done(link_status)) {
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] Interlane align done\n",
+ encoder->base.base.id, encoder->base.name);
+ break;
+ }
+
+ if (timeout) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Interlane align timeout\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ usleep_range(2000, 3000);
+ }
+
+ return true;
+}
+
+/*
+ * 128b/132b DP LANEx_CDS_DONE Sequence (DP 2.0 E11 3.5.2.16.2)
+ */
+static bool
+intel_dp_128b132b_lane_cds(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ int lttpr_count)
+{
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ u8 link_status[DP_LINK_STATUS_SIZE];
+ unsigned long deadline;
+
+ if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
+ DP_TRAINING_PATTERN_2_CDS) != 1) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to start 128b/132b TPS2 CDS\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ /* Time budget for the LANEx_CDS_DONE Sequence */
+ deadline = jiffies + msecs_to_jiffies_timeout((lttpr_count + 1) * 20);
+
+ for (;;) {
+ bool timeout = false;
+
+ if (time_after(jiffies, deadline))
+ timeout = true; /* try one last time after deadline */
+
+ usleep_range(2000, 3000);
+
+ if (drm_dp_dpcd_read_link_status(&intel_dp->aux, link_status) < 0) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Failed to read link status\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (drm_dp_128b132b_eq_interlane_align_done(link_status) &&
+ drm_dp_128b132b_cds_interlane_align_done(link_status) &&
+ drm_dp_128b132b_lane_symbol_locked(link_status, crtc_state->lane_count)) {
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] CDS interlane align done\n",
+ encoder->base.base.id, encoder->base.name);
+ break;
+ }
+
+ if (drm_dp_128b132b_link_training_failed(link_status)) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] Downstream link training failure\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (timeout) {
+ intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status);
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] CDS timeout\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+ }
+
+ /* FIXME: Should DP_TRAINING_PATTERN_DISABLE be written first? */
+ if (intel_dp->set_idle_link_train)
+ intel_dp->set_idle_link_train(intel_dp, crtc_state);
+
+ return true;
+}
+
+/*
+ * 128b/132b link training sequence. (DP 2.0 E11 SCR on link training.)
+ */
+static bool
+intel_dp_128b132b_link_train(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ int lttpr_count)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_connector *connector = intel_dp->attached_connector;
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ bool passed = false;
+
+ if (wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) {
+ drm_err(&i915->drm,
+ "[ENCODER:%d:%s] 128b/132b intra-hop not clear\n",
+ encoder->base.base.id, encoder->base.name);
+ return false;
+ }
+
+ if (intel_dp_128b132b_lane_eq(intel_dp, crtc_state) &&
+ intel_dp_128b132b_lane_cds(intel_dp, crtc_state, lttpr_count))
+ passed = true;
+
+ drm_dbg_kms(&i915->drm,
+ "[CONNECTOR:%d:%s][ENCODER:%d:%s] 128b/132b Link Training %s at link rate = %d, lane count = %d\n",
+ connector->base.base.id, connector->base.name,
+ encoder->base.base.id, encoder->base.name,
+ passed ? "passed" : "failed",
+ crtc_state->port_clock, crtc_state->lane_count);
+
+ return passed;
+}
+
/**
* intel_dp_start_link_train - start link training
* @intel_dp: DP struct
@@ -1117,6 +1408,7 @@ intel_dp_link_train_all_phys(struct intel_dp *intel_dp,
void intel_dp_start_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
+ bool passed;
/*
* TODO: Reiniting LTTPRs here won't be needed once proper connector
* HW state readout is added.
@@ -1127,6 +1419,13 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
/* Still continue with enabling the port and link training. */
lttpr_count = 0;
- if (!intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count))
+ intel_dp_prepare_link_train(intel_dp, crtc_state);
+
+ if (intel_dp_is_uhbr(crtc_state))
+ passed = intel_dp_128b132b_link_train(intel_dp, crtc_state, lttpr_count);
+ else
+ passed = intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count);
+
+ if (!passed)
intel_dp_schedule_fallback_link_training(intel_dp, crtc_state);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index dbfb15705aaa..dc1556b46b85 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -29,6 +29,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
+void
+intel_dp_dump_link_status(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy,
+ const u8 link_status[DP_LINK_STATUS_SIZE]);
+
/* Get the TPSx symbol type of the value programmed to DP_TRAINING_PATTERN_SET */
static inline u8 intel_dp_training_pattern_symbol(u8 pattern)
{
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b8bc7d397c81..e30e698aa684 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -99,6 +99,29 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
return 0;
}
+static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
+ struct intel_dp *intel_dp = &intel_mst->primary->dp;
+ struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
+ struct drm_dp_mst_topology_state *topology_state;
+ u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ?
+ DP_CAP_ANSI_128B132B : DP_CAP_ANSI_8B10B;
+
+ topology_state = drm_atomic_get_mst_topology_state(conn_state->state, mgr);
+ if (IS_ERR(topology_state)) {
+ drm_dbg_kms(&i915->drm, "slot update failed\n");
+ return PTR_ERR(topology_state);
+ }
+
+ drm_dp_mst_update_slots(topology_state, link_coding_cap);
+
+ return 0;
+}
+
static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
@@ -155,6 +178,10 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
if (ret)
return ret;
+ ret = intel_dp_mst_update_slots(encoder, pipe_config, conn_state);
+ if (ret)
+ return ret;
+
pipe_config->limited_color_range =
intel_dp_limited_color_range(pipe_config, conn_state);
@@ -357,6 +384,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
struct intel_connector *connector =
to_intel_connector(old_conn_state->connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ int start_slot = intel_dp_is_uhbr(old_crtc_state) ? 0 : 1;
int ret;
drm_dbg_kms(&i915->drm, "active links %d\n",
@@ -366,7 +394,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
- ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
+ ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, start_slot);
if (ret) {
drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
}
@@ -475,6 +503,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
+ int start_slot = intel_dp_is_uhbr(pipe_config) ? 0 : 1;
int ret;
bool first_mst_stream;
@@ -509,7 +538,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
intel_dp->active_mst_links++;
- ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, 1);
+ ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr, start_slot);
/*
* Before Gen 12 this is not done as part of
@@ -522,8 +551,6 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_enable_pipe_clock(encoder, pipe_config);
intel_ddi_set_dp_msa(pipe_config, conn_state);
-
- intel_dp_set_m_n(pipe_config, M1_N1);
}
static void intel_mst_enable_dp(struct intel_atomic_state *state,
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index 1ce0c171f4fb..14f5ffe27d05 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -16,6 +16,10 @@
#include "intel_snps_phy.h"
#include "vlv_sideband.h"
+struct intel_dpll_funcs {
+ int (*crtc_compute_clock)(struct intel_crtc_state *crtc_state);
+};
+
struct intel_limit {
struct {
int min, max;
@@ -1400,6 +1404,14 @@ static const struct intel_dpll_funcs i8xx_dpll_funcs = {
.crtc_compute_clock = i8xx_crtc_compute_clock,
};
+int intel_dpll_crtc_compute_clock(struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+
+ return i915->dpll_funcs->crtc_compute_clock(crtc_state);
+}
+
void
intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv)
{
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h
index 1af0ac43cca4..69b06a9e473e 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll.h
@@ -15,6 +15,7 @@ struct intel_crtc_state;
enum pipe;
void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv);
+int intel_dpll_crtc_compute_clock(struct intel_crtc_state *crtc_state);
int vlv_calc_dpll_params(int refclk, struct dpll *clock);
int pnv_calc_dpll_params(int refclk, struct dpll *clock);
int i9xx_calc_dpll_params(int refclk, struct dpll *clock);
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index fc8fda77483a..569903d47aea 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -28,6 +28,7 @@
#include "intel_dpll_mgr.h"
#include "intel_pch_refclk.h"
#include "intel_tc.h"
+#include "intel_tc_phy_regs.h"
/**
* DOC: Display PLLs
@@ -49,6 +50,41 @@
* commit phase.
*/
+/* platform specific hooks for managing DPLLs */
+struct intel_shared_dpll_funcs {
+ /*
+ * Hook for enabling the pll, called from intel_enable_shared_dpll() if
+ * the pll is not already enabled.
+ */
+ void (*enable)(struct drm_i915_private *i915,
+ struct intel_shared_dpll *pll);
+
+ /*
+ * Hook for disabling the pll, called from intel_disable_shared_dpll()
+ * only when it is safe to disable the pll, i.e., there are no more
+ * tracked users for it.
+ */
+ void (*disable)(struct drm_i915_private *i915,
+ struct intel_shared_dpll *pll);
+
+ /*
+ * Hook for reading the values currently programmed to the DPLL
+ * registers. This is used for initial hw state readout and state
+ * verification after a mode set.
+ */
+ bool (*get_hw_state)(struct drm_i915_private *i915,
+ struct intel_shared_dpll *pll,
+ struct intel_dpll_hw_state *hw_state);
+
+ /*
+ * Hook for calculating the pll's output frequency based on its passed
+ * in state.
+ */
+ int (*get_freq)(struct drm_i915_private *i915,
+ const struct intel_shared_dpll *pll,
+ const struct intel_dpll_hw_state *pll_state);
+};
+
struct intel_dpll_mgr {
const struct dpll_info *dpll_info;
@@ -2712,6 +2748,9 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
pll_state->cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL;
else
pll_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
+
+ if (i915->vbt.override_afc_startup)
+ pll_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->vbt.override_afc_startup_val);
}
static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
@@ -2913,6 +2952,11 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
DKL_PLL_DIV0_PROP_COEFF(prop_coeff) |
DKL_PLL_DIV0_FBPREDIV(m1div) |
DKL_PLL_DIV0_FBDIV_INT(m2div_int);
+ if (dev_priv->vbt.override_afc_startup) {
+ u8 val = dev_priv->vbt.override_afc_startup_val;
+
+ pll_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val);
+ }
pll_state->mg_pll_div1 = DKL_PLL_DIV1_IREF_TRIM(iref_trim) |
DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt);
@@ -3412,10 +3456,10 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
hw_state->mg_pll_div0 = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port));
- hw_state->mg_pll_div0 &= (DKL_PLL_DIV0_INTEG_COEFF_MASK |
- DKL_PLL_DIV0_PROP_COEFF_MASK |
- DKL_PLL_DIV0_FBPREDIV_MASK |
- DKL_PLL_DIV0_FBDIV_INT_MASK);
+ val = DKL_PLL_DIV0_MASK;
+ if (dev_priv->vbt.override_afc_startup)
+ val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
+ hw_state->mg_pll_div0 &= val;
hw_state->mg_pll_div1 = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port));
hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK |
@@ -3477,6 +3521,10 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
TGL_DPLL_CFGCR0(id));
hw_state->cfgcr1 = intel_de_read(dev_priv,
TGL_DPLL_CFGCR1(id));
+ if (dev_priv->vbt.override_afc_startup) {
+ hw_state->div0 = intel_de_read(dev_priv, TGL_DPLL0_DIV0(id));
+ hw_state->div0 &= TGL_DPLL0_DIV0_AFC_STARTUP_MASK;
+ }
} else {
if (IS_JSL_EHL(dev_priv) && id == DPLL_ID_EHL_DPLL4) {
hw_state->cfgcr0 = intel_de_read(dev_priv,
@@ -3518,7 +3566,7 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv,
{
struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
const enum intel_dpll_id id = pll->info->id;
- i915_reg_t cfgcr0_reg, cfgcr1_reg;
+ i915_reg_t cfgcr0_reg, cfgcr1_reg, div0_reg = INVALID_MMIO_REG;
if (IS_ALDERLAKE_S(dev_priv)) {
cfgcr0_reg = ADLS_DPLL_CFGCR0(id);
@@ -3532,6 +3580,7 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv,
} else if (DISPLAY_VER(dev_priv) >= 12) {
cfgcr0_reg = TGL_DPLL_CFGCR0(id);
cfgcr1_reg = TGL_DPLL_CFGCR1(id);
+ div0_reg = TGL_DPLL0_DIV0(id);
} else {
if (IS_JSL_EHL(dev_priv) && id == DPLL_ID_EHL_DPLL4) {
cfgcr0_reg = ICL_DPLL_CFGCR0(4);
@@ -3544,6 +3593,12 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv,
intel_de_write(dev_priv, cfgcr0_reg, hw_state->cfgcr0);
intel_de_write(dev_priv, cfgcr1_reg, hw_state->cfgcr1);
+ drm_WARN_ON_ONCE(&dev_priv->drm, dev_priv->vbt.override_afc_startup &&
+ !i915_mmio_reg_valid(div0_reg));
+ if (dev_priv->vbt.override_afc_startup &&
+ i915_mmio_reg_valid(div0_reg))
+ intel_de_rmw(dev_priv, div0_reg, TGL_DPLL0_DIV0_AFC_STARTUP_MASK,
+ hw_state->div0);
intel_de_posting_read(dev_priv, cfgcr1_reg);
}
@@ -3631,13 +3686,11 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv,
val |= hw_state->mg_clktop2_hsclkctl;
intel_de_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
- val = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port));
- val &= ~(DKL_PLL_DIV0_INTEG_COEFF_MASK |
- DKL_PLL_DIV0_PROP_COEFF_MASK |
- DKL_PLL_DIV0_FBPREDIV_MASK |
- DKL_PLL_DIV0_FBDIV_INT_MASK);
- val |= hw_state->mg_pll_div0;
- intel_de_write(dev_priv, DKL_PLL_DIV0(tc_port), val);
+ val = DKL_PLL_DIV0_MASK;
+ if (dev_priv->vbt.override_afc_startup)
+ val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
+ intel_de_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val,
+ hw_state->mg_pll_div0);
val = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port));
val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK |
@@ -3876,13 +3929,14 @@ static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
const struct intel_dpll_hw_state *hw_state)
{
drm_dbg_kms(&dev_priv->drm,
- "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
+ "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, div0: 0x%x, "
"mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
"mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
"mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
"mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
"mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
hw_state->cfgcr0, hw_state->cfgcr1,
+ hw_state->div0,
hw_state->mg_refclkin_ctl,
hw_state->mg_clktop2_coreclkctl1,
hw_state->mg_clktop2_hsclkctl,
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index ef2889753807..ba2fdfce1579 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -44,6 +44,7 @@ struct intel_crtc;
struct intel_crtc_state;
struct intel_encoder;
struct intel_shared_dpll;
+struct intel_shared_dpll_funcs;
/**
* enum intel_dpll_id - possible DPLL ids
@@ -207,6 +208,9 @@ struct intel_dpll_hw_state {
/* icl */
u32 cfgcr0;
+ /* tgl */
+ u32 div0;
+
/* bxt */
u32 ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, pcsdw12;
@@ -252,51 +256,6 @@ struct intel_shared_dpll_state {
};
/**
- * struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs
- */
-struct intel_shared_dpll_funcs {
- /**
- * @enable:
- *
- * Hook for enabling the pll, called from intel_enable_shared_dpll()
- * if the pll is not already enabled.
- */
- void (*enable)(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll);
-
- /**
- * @disable:
- *
- * Hook for disabling the pll, called from intel_disable_shared_dpll()
- * only when it is safe to disable the pll, i.e., there are no more
- * tracked users for it.
- */
- void (*disable)(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll);
-
- /**
- * @get_hw_state:
- *
- * Hook for reading the values currently programmed to the DPLL
- * registers. This is used for initial hw state readout and state
- * verification after a mode set.
- */
- bool (*get_hw_state)(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state);
-
- /**
- * @get_freq:
- *
- * Hook for calculating the pll's output frequency based on its
- * passed in state.
- */
- int (*get_freq)(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state);
-};
-
-/**
* struct dpll_info - display PLL platform specific info
*/
struct dpll_info {
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index c2f8f853db90..05dd7dba3a5c 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -3,11 +3,13 @@
* Copyright © 2021 Intel Corporation
*/
+#include "gem/i915_gem_domain.h"
+#include "gt/gen8_ppgtt.h"
+
#include "i915_drv.h"
#include "intel_display_types.h"
#include "intel_dpt.h"
#include "intel_fb.h"
-#include "gt/gen8_ppgtt.h"
struct i915_dpt {
struct i915_address_space vm;
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index c1439fcb5a95..fa715b8ea310 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -47,17 +47,13 @@
* requested by userspace.
*/
-void
-intel_drrs_compute_config(struct intel_dp *intel_dp,
- struct intel_crtc_state *pipe_config,
- int output_bpp, bool constant_n)
+static bool can_enable_drrs(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config)
{
- struct intel_connector *intel_connector = intel_dp->attached_connector;
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- int pixel_clock;
+ const struct drm_i915_private *i915 = to_i915(connector->base.dev);
if (pipe_config->vrr.enable)
- return;
+ return false;
/*
* DRRS and PSR can't be enable together, so giving preference to PSR
@@ -66,15 +62,30 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
* after intel_psr_compute_config().
*/
if (pipe_config->has_psr)
- return;
+ return false;
- if (!intel_connector->panel.downclock_mode ||
- dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
+ return connector->panel.downclock_mode &&
+ i915->drrs.type == SEAMLESS_DRRS_SUPPORT;
+}
+
+void
+intel_drrs_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ int output_bpp, bool constant_n)
+{
+ struct intel_connector *connector = intel_dp->attached_connector;
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ int pixel_clock;
+
+ if (!can_enable_drrs(connector, pipe_config)) {
+ if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
+ intel_zero_m_n(&pipe_config->dp_m2_n2);
return;
+ }
pipe_config->has_drrs = true;
- pixel_clock = intel_connector->panel.downclock_mode->clock;
+ pixel_clock = connector->panel.downclock_mode->clock;
if (pipe_config->splitter.enable)
pixel_clock /= pipe_config->splitter.link_count;
@@ -84,7 +95,42 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
/* FIXME: abstract this better */
if (pipe_config->splitter.enable)
- pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
+ pipe_config->dp_m2_n2.data_m *= pipe_config->splitter.link_count;
+}
+
+static void
+intel_drrs_set_refresh_rate_pipeconf(const struct intel_crtc_state *crtc_state,
+ enum drrs_refresh_rate_type refresh_type)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+ u32 val, bit;
+
+ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ bit = PIPECONF_EDP_RR_MODE_SWITCH_VLV;
+ else
+ bit = PIPECONF_EDP_RR_MODE_SWITCH;
+
+ val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder));
+
+ if (refresh_type == DRRS_LOW_RR)
+ val |= bit;
+ else
+ val &= ~bit;
+
+ intel_de_write(dev_priv, PIPECONF(cpu_transcoder), val);
+}
+
+static void
+intel_drrs_set_refresh_rate_m_n(const struct intel_crtc_state *crtc_state,
+ enum drrs_refresh_rate_type refresh_type)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ intel_cpu_transcoder_set_m1_n1(crtc, crtc_state->cpu_transcoder,
+ refresh_type == DRRS_LOW_RR ?
+ &crtc_state->dp_m2_n2 : &crtc_state->dp_m_n);
}
static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
@@ -120,37 +166,10 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
return;
}
- if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
- switch (refresh_type) {
- case DRRS_HIGH_RR:
- intel_dp_set_m_n(crtc_state, M1_N1);
- break;
- case DRRS_LOW_RR:
- intel_dp_set_m_n(crtc_state, M2_N2);
- break;
- case DRRS_MAX_RR:
- default:
- drm_err(&dev_priv->drm,
- "Unsupported refreshrate type\n");
- }
- } else if (DISPLAY_VER(dev_priv) > 6) {
- i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
- u32 val;
-
- val = intel_de_read(dev_priv, reg);
- if (refresh_type == DRRS_LOW_RR) {
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
- else
- val |= PIPECONF_EDP_RR_MODE_SWITCH;
- } else {
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
- else
- val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
- }
- intel_de_write(dev_priv, reg, val);
- }
+ if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv))
+ intel_drrs_set_refresh_rate_m_n(crtc_state, refresh_type);
+ else if (DISPLAY_VER(dev_priv) > 6)
+ intel_drrs_set_refresh_rate_pipeconf(crtc_state, refresh_type);
dev_priv->drrs.refresh_rate_type = refresh_type;
@@ -405,6 +424,7 @@ intel_drrs_init(struct intel_connector *connector,
struct drm_display_mode *fixed_mode)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_encoder *encoder = connector->encoder;
struct drm_display_mode *downclock_mode = NULL;
INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work);
@@ -416,6 +436,13 @@ intel_drrs_init(struct intel_connector *connector,
return NULL;
}
+ if ((DISPLAY_VER(dev_priv) < 8 && !HAS_GMCH(dev_priv)) &&
+ encoder->port != PORT_A) {
+ drm_dbg_kms(&dev_priv->drm,
+ "DRRS only supported on eDP port A\n");
+ return NULL;
+ }
+
if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
return NULL;
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index 83a69a4a4fea..b34a67309976 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -4,6 +4,8 @@
*
*/
+#include "gem/i915_gem_internal.h"
+
#include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h
index 654a11f24b80..6cb9c580cdca 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.h
+++ b/drivers/gpu/drm/i915/display/intel_dsb.h
@@ -8,7 +8,7 @@
#include <linux/types.h>
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
struct intel_crtc_state;
struct i915_vma;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi.h b/drivers/gpu/drm/i915/display/intel_dsi.h
index a3a906cb097e..eafef0a87fea 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.h
+++ b/drivers/gpu/drm/i915/display/intel_dsi.h
@@ -79,8 +79,8 @@ struct intel_dsi {
*/
enum mipi_dsi_pixel_format pixel_format;
- /* video mode format for MIPI_VIDEO_MODE_FORMAT register */
- u32 video_mode_format;
+ /* NON_BURST_SYNC_PULSE, NON_BURST_SYNC_EVENTS, or BURST_MODE */
+ int video_mode;
/* eot for MIPI_EOT_DISABLE register */
u8 eotp_pkt;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index 0da91849efde..6b4a27372c82 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -39,10 +39,12 @@
#include <video/mipi_display.h>
#include "i915_drv.h"
+#include "i915_reg.h"
#include "intel_display_types.h"
#include "intel_dsi.h"
#include "intel_dsi_vbt.h"
#include "vlv_dsi.h"
+#include "vlv_dsi_regs.h"
#include "vlv_sideband.h"
#define MIPI_TRANSFER_MODE_SHIFT 0
@@ -426,24 +428,16 @@ static void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,
const u16 slave_addr)
{
struct drm_device *drm_dev = intel_dsi->base.base.dev;
- struct device *dev = drm_dev->dev;
- struct acpi_device *acpi_dev;
- struct list_head resource_list;
- struct i2c_adapter_lookup lookup;
-
- acpi_dev = ACPI_COMPANION(dev);
- if (acpi_dev) {
- memset(&lookup, 0, sizeof(lookup));
- lookup.slave_addr = slave_addr;
- lookup.intel_dsi = intel_dsi;
- lookup.dev_handle = acpi_device_handle(acpi_dev);
-
- INIT_LIST_HEAD(&resource_list);
- acpi_dev_get_resources(acpi_dev, &resource_list,
- i2c_adapter_lookup,
- &lookup);
- acpi_dev_free_resource_list(&resource_list);
- }
+ struct acpi_device *adev = ACPI_COMPANION(drm_dev->dev);
+ struct i2c_adapter_lookup lookup = {
+ .slave_addr = slave_addr,
+ .intel_dsi = intel_dsi,
+ .dev_handle = acpi_device_handle(adev),
+ };
+ LIST_HEAD(resource_list);
+
+ acpi_dev_get_resources(adev, &resource_list, i2c_adapter_lookup, &lookup);
+ acpi_dev_free_resource_list(&resource_list);
}
#else
static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,
@@ -682,11 +676,11 @@ void intel_dsi_log_params(struct intel_dsi *intel_dsi)
drm_dbg_kms(&i915->drm, "Lane count %d\n", intel_dsi->lane_count);
drm_dbg_kms(&i915->drm, "DPHY param reg 0x%x\n", intel_dsi->dphy_reg);
drm_dbg_kms(&i915->drm, "Video mode format %s\n",
- intel_dsi->video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE ?
+ intel_dsi->video_mode == NON_BURST_SYNC_PULSE ?
"non-burst with sync pulse" :
- intel_dsi->video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS ?
+ intel_dsi->video_mode == NON_BURST_SYNC_EVENTS ?
"non-burst with sync events" :
- intel_dsi->video_mode_format == VIDEO_MODE_BURST ?
+ intel_dsi->video_mode == BURST_MODE ?
"burst" : "<unknown>");
drm_dbg_kms(&i915->drm, "Burst mode ratio %d\n",
intel_dsi->burst_mode_ratio);
@@ -746,7 +740,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
intel_dsi->dual_link = mipi_config->dual_link;
intel_dsi->pixel_overlap = mipi_config->pixel_overlap;
intel_dsi->operation_mode = mipi_config->is_cmd_mode;
- intel_dsi->video_mode_format = mipi_config->video_transfer_mode;
+ intel_dsi->video_mode = mipi_config->video_transfer_mode;
intel_dsi->escape_clk_div = mipi_config->byte_clk_sel;
intel_dsi->lp_rx_timeout = mipi_config->lp_rx_timeout;
intel_dsi->hs_tx_timeout = mipi_config->hs_tx_timeout;
@@ -777,7 +771,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
* Target ddr frequency from VBT / non burst ddr freq
* multiply by 100 to preserve remainder
*/
- if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
+ if (intel_dsi->video_mode == BURST_MODE) {
if (mipi_config->target_burst_mode_freq) {
u32 bitrate = intel_dsi_bitrate(intel_dsi);
diff --git a/drivers/gpu/drm/i915/display/intel_dvo_dev.h b/drivers/gpu/drm/i915/display/intel_dvo_dev.h
index 94a6ae1e0292..d96c3cc46e50 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo_dev.h
+++ b/drivers/gpu/drm/i915/display/intel_dvo_dev.h
@@ -27,7 +27,7 @@
#include <drm/drm_crtc.h>
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
struct intel_dvo_device {
const char *name;
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index c4b3d76341f3..a307b4993bcf 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -7,6 +7,7 @@
* DOC: display pinning helpers
*/
+#include "gem/i915_gem_domain.h"
#include "gem/i915_gem_object.h"
#include "i915_drv.h"
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index c0a973eeb405..87f4af3fd523 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -49,6 +49,14 @@
#include "intel_fbc.h"
#include "intel_frontbuffer.h"
+#define for_each_fbc_id(__dev_priv, __fbc_id) \
+ for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \
+ for_each_if(INTEL_INFO(__dev_priv)->display.fbc_mask & BIT(__fbc_id))
+
+#define for_each_intel_fbc(__dev_priv, __fbc, __fbc_id) \
+ for_each_fbc_id((__dev_priv), (__fbc_id)) \
+ for_each_if((__fbc) = (__dev_priv)->fbc[(__fbc_id)])
+
struct intel_fbc_funcs {
void (*activate)(struct intel_fbc *fbc);
void (*deactivate)(struct intel_fbc *fbc);
@@ -85,6 +93,8 @@ struct intel_fbc {
struct drm_mm_node compressed_fb;
struct drm_mm_node compressed_llb;
+ enum intel_fbc_id id;
+
u8 limit;
bool false_color;
@@ -454,10 +464,10 @@ static void ilk_fbc_activate(struct intel_fbc *fbc)
struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915;
- intel_de_write(i915, ILK_DPFC_FENCE_YOFF,
+ intel_de_write(i915, ILK_DPFC_FENCE_YOFF(fbc->id),
fbc_state->fence_y_offset);
- intel_de_write(i915, ILK_DPFC_CONTROL,
+ intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
}
@@ -467,28 +477,28 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc)
u32 dpfc_ctl;
/* Disable compression */
- dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL);
+ dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL(fbc->id));
if (dpfc_ctl & DPFC_CTL_EN) {
dpfc_ctl &= ~DPFC_CTL_EN;
- intel_de_write(i915, ILK_DPFC_CONTROL, dpfc_ctl);
+ intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
}
}
static bool ilk_fbc_is_active(struct intel_fbc *fbc)
{
- return intel_de_read(fbc->i915, ILK_DPFC_CONTROL) & DPFC_CTL_EN;
+ return intel_de_read(fbc->i915, ILK_DPFC_CONTROL(fbc->id)) & DPFC_CTL_EN;
}
static bool ilk_fbc_is_compressing(struct intel_fbc *fbc)
{
- return intel_de_read(fbc->i915, ILK_DPFC_STATUS) & DPFC_COMP_SEG_MASK;
+ return intel_de_read(fbc->i915, ILK_DPFC_STATUS(fbc->id)) & DPFC_COMP_SEG_MASK;
}
static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
- intel_de_write(i915, ILK_DPFC_CB_BASE, fbc->compressed_fb.start);
+ intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), fbc->compressed_fb.start);
}
static const struct intel_fbc_funcs ilk_fbc_funcs = {
@@ -524,8 +534,8 @@ static void snb_fbc_nuke(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
- intel_de_write(i915, MSG_FBC_REND_STATE, FBC_REND_NUKE);
- intel_de_posting_read(i915, MSG_FBC_REND_STATE);
+ intel_de_write(i915, MSG_FBC_REND_STATE(fbc->id), FBC_REND_NUKE);
+ intel_de_posting_read(i915, MSG_FBC_REND_STATE(fbc->id));
}
static const struct intel_fbc_funcs snb_fbc_funcs = {
@@ -547,7 +557,7 @@ static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
val |= FBC_STRIDE_OVERRIDE |
FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
- intel_de_write(i915, GLK_FBC_STRIDE, val);
+ intel_de_write(i915, GLK_FBC_STRIDE(fbc->id), val);
}
static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
@@ -598,19 +608,19 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)
if (to_gt(i915)->ggtt->num_fences)
snb_fbc_program_fence(fbc);
- intel_de_write(i915, ILK_DPFC_CONTROL,
+ intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | ivb_dpfc_ctl(fbc));
}
static bool ivb_fbc_is_compressing(struct intel_fbc *fbc)
{
- return intel_de_read(fbc->i915, ILK_DPFC_STATUS2) & DPFC_COMP_SEG_MASK_IVB;
+ return intel_de_read(fbc->i915, ILK_DPFC_STATUS2(fbc->id)) & DPFC_COMP_SEG_MASK_IVB;
}
static void ivb_fbc_set_false_color(struct intel_fbc *fbc,
bool enable)
{
- intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL,
+ intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0);
}
@@ -810,16 +820,16 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
void intel_fbc_cleanup(struct drm_i915_private *i915)
{
- struct intel_fbc *fbc = i915->fbc;
-
- if (!fbc)
- return;
+ struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
- mutex_lock(&fbc->lock);
- __intel_fbc_cleanup_cfb(fbc);
- mutex_unlock(&fbc->lock);
+ for_each_intel_fbc(i915, fbc, fbc_id) {
+ mutex_lock(&fbc->lock);
+ __intel_fbc_cleanup_cfb(fbc);
+ mutex_unlock(&fbc->lock);
- kfree(fbc);
+ kfree(fbc);
+ }
}
static bool stride_is_valid(const struct intel_plane_state *plane_state)
@@ -1115,7 +1125,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
/* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
if (DISPLAY_VER(i915) >= 11 &&
- (plane_state->view.color_plane[0].y + drm_rect_height(&plane_state->uapi.src)) & 3) {
+ (plane_state->view.color_plane[0].y +
+ (drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) {
plane_state->no_fbc_reason = "plane end Y offset misaligned";
return false;
}
@@ -1305,15 +1316,10 @@ static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc)
return fbc->possible_framebuffer_bits;
}
-void intel_fbc_invalidate(struct drm_i915_private *i915,
- unsigned int frontbuffer_bits,
- enum fb_op_origin origin)
+static void __intel_fbc_invalidate(struct intel_fbc *fbc,
+ unsigned int frontbuffer_bits,
+ enum fb_op_origin origin)
{
- struct intel_fbc *fbc = i915->fbc;
-
- if (!fbc)
- return;
-
if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
return;
@@ -1327,14 +1333,22 @@ void intel_fbc_invalidate(struct drm_i915_private *i915,
mutex_unlock(&fbc->lock);
}
-void intel_fbc_flush(struct drm_i915_private *i915,
- unsigned int frontbuffer_bits, enum fb_op_origin origin)
+void intel_fbc_invalidate(struct drm_i915_private *i915,
+ unsigned int frontbuffer_bits,
+ enum fb_op_origin origin)
{
- struct intel_fbc *fbc = i915->fbc;
+ struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
- if (!fbc)
- return;
+ for_each_intel_fbc(i915, fbc, fbc_id)
+ __intel_fbc_invalidate(fbc, frontbuffer_bits, origin);
+
+}
+static void __intel_fbc_flush(struct intel_fbc *fbc,
+ unsigned int frontbuffer_bits,
+ enum fb_op_origin origin)
+{
mutex_lock(&fbc->lock);
fbc->busy_bits &= ~frontbuffer_bits;
@@ -1354,6 +1368,17 @@ out:
mutex_unlock(&fbc->lock);
}
+void intel_fbc_flush(struct drm_i915_private *i915,
+ unsigned int frontbuffer_bits,
+ enum fb_op_origin origin)
+{
+ struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
+
+ for_each_intel_fbc(i915, fbc, fbc_id)
+ __intel_fbc_flush(fbc, frontbuffer_bits, origin);
+}
+
int intel_fbc_atomic_check(struct intel_atomic_state *state)
{
struct intel_plane_state *plane_state;
@@ -1483,15 +1508,15 @@ void intel_fbc_update(struct intel_atomic_state *state,
*/
void intel_fbc_global_disable(struct drm_i915_private *i915)
{
- struct intel_fbc *fbc = i915->fbc;
-
- if (!fbc)
- return;
+ struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
- mutex_lock(&fbc->lock);
- if (fbc->state.plane)
- __intel_fbc_disable(fbc);
- mutex_unlock(&fbc->lock);
+ for_each_intel_fbc(i915, fbc, fbc_id) {
+ mutex_lock(&fbc->lock);
+ if (fbc->state.plane)
+ __intel_fbc_disable(fbc);
+ mutex_unlock(&fbc->lock);
+ }
}
static void intel_fbc_underrun_work_fn(struct work_struct *work)
@@ -1516,19 +1541,9 @@ out:
mutex_unlock(&fbc->lock);
}
-/*
- * intel_fbc_reset_underrun - reset FBC fifo underrun status.
- * @i915: the i915 device
- *
- * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
- * want to re-enable FBC after an underrun to increase test coverage.
- */
-void intel_fbc_reset_underrun(struct drm_i915_private *i915)
+static void __intel_fbc_reset_underrun(struct intel_fbc *fbc)
{
- struct intel_fbc *fbc = i915->fbc;
-
- if (!fbc)
- return;
+ struct drm_i915_private *i915 = fbc->i915;
cancel_work_sync(&fbc->underrun_work);
@@ -1544,6 +1559,38 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915)
mutex_unlock(&fbc->lock);
}
+/*
+ * intel_fbc_reset_underrun - reset FBC fifo underrun status.
+ * @i915: the i915 device
+ *
+ * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
+ * want to re-enable FBC after an underrun to increase test coverage.
+ */
+void intel_fbc_reset_underrun(struct drm_i915_private *i915)
+{
+ struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
+
+ for_each_intel_fbc(i915, fbc, fbc_id)
+ __intel_fbc_reset_underrun(fbc);
+}
+
+static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
+{
+ /*
+ * There's no guarantee that underrun_detected won't be set to true
+ * right after this check and before the work is scheduled, but that's
+ * not a problem since we'll check it again under the work function
+ * while FBC is locked. This check here is just to prevent us from
+ * unnecessarily scheduling the work, and it relies on the fact that we
+ * never switch underrun_detect back to false after it's true.
+ */
+ if (READ_ONCE(fbc->underrun_detected))
+ return;
+
+ schedule_work(&fbc->underrun_work);
+}
+
/**
* intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun
* @i915: i915 device
@@ -1560,21 +1607,11 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915)
*/
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)
{
- struct intel_fbc *fbc = i915->fbc;
-
- if (!fbc)
- return;
-
- /* There's no guarantee that underrun_detected won't be set to true
- * right after this check and before the work is scheduled, but that's
- * not a problem since we'll check it again under the work function
- * while FBC is locked. This check here is just to prevent us from
- * unnecessarily scheduling the work, and it relies on the fact that we
- * never switch underrun_detect back to false after it's true. */
- if (READ_ONCE(fbc->underrun_detected))
- return;
+ struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
- schedule_work(&fbc->underrun_work);
+ for_each_intel_fbc(i915, fbc, fbc_id)
+ __intel_fbc_handle_fifo_underrun_irq(fbc);
}
/*
@@ -1622,7 +1659,8 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
}
-static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
+static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915,
+ enum intel_fbc_id fbc_id)
{
struct intel_fbc *fbc;
@@ -1630,6 +1668,7 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
if (!fbc)
return NULL;
+ fbc->id = fbc_id;
fbc->i915 = i915;
INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
mutex_init(&fbc->lock);
@@ -1658,32 +1697,35 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
*/
void intel_fbc_init(struct drm_i915_private *i915)
{
- struct intel_fbc *fbc;
+ enum intel_fbc_id fbc_id;
if (!drm_mm_initialized(&i915->mm.stolen))
- mkwrite_device_info(i915)->display.has_fbc = false;
+ mkwrite_device_info(i915)->display.fbc_mask = 0;
if (need_fbc_vtd_wa(i915))
- mkwrite_device_info(i915)->display.has_fbc = false;
+ mkwrite_device_info(i915)->display.fbc_mask = 0;
i915->params.enable_fbc = intel_sanitize_fbc_option(i915);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
i915->params.enable_fbc);
- if (!HAS_FBC(i915))
- return;
+ for_each_fbc_id(i915, fbc_id) {
+ struct intel_fbc *fbc;
- fbc = intel_fbc_create(i915);
- if (!fbc)
- return;
+ fbc = intel_fbc_create(i915, fbc_id);
+ if (!fbc)
+ continue;
- /* We still don't have any sort of hardware state readout for FBC, so
- * deactivate it in case the BIOS activated it to make sure software
- * matches the hardware state. */
- if (intel_fbc_hw_is_active(fbc))
- intel_fbc_hw_deactivate(fbc);
+ /*
+ * We still don't have any sort of hardware state readout
+ * for FBC, so deactivate it in case the BIOS activated it
+ * to make sure software matches the hardware state.
+ */
+ if (intel_fbc_hw_is_active(fbc))
+ intel_fbc_hw_deactivate(fbc);
- i915->fbc = fbc;
+ i915->fbc[fbc->id] = fbc;
+ }
}
static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
@@ -1759,25 +1801,32 @@ DEFINE_SIMPLE_ATTRIBUTE(intel_fbc_debugfs_false_color_fops,
intel_fbc_debugfs_false_color_set,
"%llu\n");
-static void intel_fbc_debugfs_add(struct intel_fbc *fbc)
+static void intel_fbc_debugfs_add(struct intel_fbc *fbc,
+ struct dentry *parent)
{
- struct drm_i915_private *i915 = fbc->i915;
- struct drm_minor *minor = i915->drm.primary;
-
- debugfs_create_file("i915_fbc_status", 0444,
- minor->debugfs_root, fbc,
- &intel_fbc_debugfs_status_fops);
+ debugfs_create_file("i915_fbc_status", 0444, parent,
+ fbc, &intel_fbc_debugfs_status_fops);
if (fbc->funcs->set_false_color)
- debugfs_create_file("i915_fbc_false_color", 0644,
- minor->debugfs_root, fbc,
- &intel_fbc_debugfs_false_color_fops);
+ debugfs_create_file("i915_fbc_false_color", 0644, parent,
+ fbc, &intel_fbc_debugfs_false_color_fops);
}
+void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc)
+{
+ struct intel_plane *plane = to_intel_plane(crtc->base.primary);
+
+ if (plane->fbc)
+ intel_fbc_debugfs_add(plane->fbc, crtc->base.debugfs_entry);
+}
+
+/* FIXME: remove this once igt is on board with per-crtc stuff */
void intel_fbc_debugfs_register(struct drm_i915_private *i915)
{
- struct intel_fbc *fbc = i915->fbc;
+ struct drm_minor *minor = i915->drm.primary;
+ struct intel_fbc *fbc;
+ fbc = i915->fbc[INTEL_FBC_A];
if (fbc)
- intel_fbc_debugfs_add(fbc);
+ intel_fbc_debugfs_add(fbc, minor->debugfs_root);
}
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h
index 07ad0411fcc3..8c5a7339a27f 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc.h
@@ -17,6 +17,12 @@ struct intel_fbc;
struct intel_plane;
struct intel_plane_state;
+enum intel_fbc_id {
+ INTEL_FBC_A,
+
+ I915_MAX_FBCS,
+};
+
int intel_fbc_atomic_check(struct intel_atomic_state *state);
bool intel_fbc_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
@@ -36,6 +42,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane);
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915);
void intel_fbc_reset_underrun(struct drm_i915_private *i915);
+void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
void intel_fbc_debugfs_register(struct drm_i915_private *i915);
#endif /* __INTEL_FBC_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 41d279db2be6..fd5bc7acf08d 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -50,6 +50,23 @@
#include "intel_fbdev.h"
#include "intel_frontbuffer.h"
+struct intel_fbdev {
+ struct drm_fb_helper helper;
+ struct intel_framebuffer *fb;
+ struct i915_vma *vma;
+ unsigned long vma_flags;
+ async_cookie_t cookie;
+ int preferred_bpp;
+
+ /* Whether or not fbdev hpd processing is temporarily suspended */
+ bool hpd_suspended: 1;
+ /* Set when a hotplug was received while HPD processing was suspended */
+ bool hpd_waiting: 1;
+
+ /* Protects hpd_suspended */
+ struct mutex hpd_lock;
+};
+
static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
{
return ifbdev->fb->frontbuffer;
@@ -680,3 +697,11 @@ void intel_fbdev_restore_mode(struct drm_device *dev)
if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
intel_fbdev_invalidate(ifbdev);
}
+
+struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
+{
+ if (!fbdev || !fbdev->helper.fb)
+ return NULL;
+
+ return to_intel_framebuffer(fbdev->helper.fb);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h
index de7c84250eb5..0e95e9472fa3 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
@@ -10,6 +10,8 @@
struct drm_device;
struct drm_i915_private;
+struct intel_fbdev;
+struct intel_framebuffer;
#ifdef CONFIG_DRM_FBDEV_EMULATION
int intel_fbdev_init(struct drm_device *dev);
@@ -19,6 +21,7 @@ void intel_fbdev_fini(struct drm_i915_private *dev_priv);
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
void intel_fbdev_output_poll_changed(struct drm_device *dev);
void intel_fbdev_restore_mode(struct drm_device *dev);
+struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev);
#else
static inline int intel_fbdev_init(struct drm_device *dev)
{
@@ -48,6 +51,10 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
static inline void intel_fbdev_restore_mode(struct drm_device *dev)
{
}
+static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
+{
+ return NULL;
+}
#endif
#endif /* __INTEL_FBDEV_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c
index 3d6e22923601..4e4b43669b14 100644
--- a/drivers/gpu/drm/i915/display/intel_fdi.c
+++ b/drivers/gpu/drm/i915/display/intel_fdi.c
@@ -10,6 +10,11 @@
#include "intel_display_types.h"
#include "intel_fdi.h"
+struct intel_fdi_funcs {
+ void (*fdi_link_train)(struct intel_crtc *crtc,
+ const struct intel_crtc_state *crtc_state);
+};
+
static void assert_fdi_tx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c
index 3b8b84177085..2fad03250661 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -98,11 +98,21 @@ static const struct gmbus_pin gmbus_pins_dg1[] = {
[GMBUS_PIN_4_CNP] = { "dpd", GPIOE },
};
+static const struct gmbus_pin gmbus_pins_dg2[] = {
+ [GMBUS_PIN_1_BXT] = { "dpa", GPIOB },
+ [GMBUS_PIN_2_BXT] = { "dpb", GPIOC },
+ [GMBUS_PIN_3_BXT] = { "dpc", GPIOD },
+ [GMBUS_PIN_4_CNP] = { "dpd", GPIOE },
+ [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ },
+};
+
/* pin is expected to be valid */
static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
unsigned int pin)
{
- if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
+ if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG2)
+ return &gmbus_pins_dg2[pin];
+ else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
return &gmbus_pins_dg1[pin];
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
return &gmbus_pins_icp[pin];
@@ -123,7 +133,9 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
{
unsigned int size;
- if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
+ if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG2)
+ size = ARRAY_SIZE(gmbus_pins_dg2);
+ else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
size = ARRAY_SIZE(gmbus_pins_dg1);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
size = ARRAY_SIZE(gmbus_pins_icp);
@@ -931,13 +943,6 @@ struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
return &dev_priv->gmbus[pin].adapter;
}
-void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
-{
- struct intel_gmbus *bus = to_intel_gmbus(adapter);
-
- bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed;
-}
-
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.h b/drivers/gpu/drm/i915/display/intel_gmbus.h
index b96212b85425..8edc2e99cf53 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.h
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.h
@@ -41,7 +41,6 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter);
struct i2c_adapter *
intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin);
-void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter);
void intel_gmbus_reset(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 4509fe7438e8..e1ecf38db0ef 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -297,8 +297,7 @@ static int intel_hdcp_load_keys(struct drm_i915_private *dev_priv)
* Mailbox interface.
*/
if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
- ret = sandybridge_pcode_write(dev_priv,
- SKL_PCODE_LOAD_HDCP_KEYS, 1);
+ ret = snb_pcode_write(dev_priv, SKL_PCODE_LOAD_HDCP_KEYS, 1);
if (ret) {
drm_err(&dev_priv->drm,
"Failed to initiate HDCP key load (%d)\n",
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 52f6dc248453..1aa5bdc7b0dc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1869,7 +1869,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
return MODE_OK;
}
-static int intel_hdmi_tmds_clock(int clock, int bpc, bool ycbcr420_output)
+int intel_hdmi_tmds_clock(int clock, int bpc, bool ycbcr420_output)
{
/* YCBCR420 TMDS rate requirement is half the pixel clock */
if (ycbcr420_output)
@@ -1935,25 +1935,30 @@ intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock,
{
struct drm_i915_private *i915 = to_i915(connector->dev);
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
- enum drm_mode_status status;
+ enum drm_mode_status status = MODE_OK;
+ int bpc;
+
+ /*
+ * Try all color depths since valid port clock range
+ * can have holes. Any mode that can be used with at
+ * least one color depth is accepted.
+ */
+ for (bpc = 12; bpc >= 8; bpc -= 2) {
+ int tmds_clock = intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output);
- /* check if we can do 8bpc */
- status = hdmi_port_clock_valid(hdmi, intel_hdmi_tmds_clock(clock, 8, ycbcr420_output),
- true, has_hdmi_sink);
+ if (!intel_hdmi_source_bpc_possible(i915, bpc))
+ continue;
+
+ if (!intel_hdmi_sink_bpc_possible(connector, bpc, has_hdmi_sink, ycbcr420_output))
+ continue;
- /* if we can't do 8bpc we may still be able to do 12bpc */
- if (status != MODE_OK &&
- intel_hdmi_source_bpc_possible(i915, 12) &&
- intel_hdmi_sink_bpc_possible(connector, 12, has_hdmi_sink, ycbcr420_output))
- status = hdmi_port_clock_valid(hdmi, intel_hdmi_tmds_clock(clock, 12, ycbcr420_output),
- true, has_hdmi_sink);
+ status = hdmi_port_clock_valid(hdmi, tmds_clock, true, has_hdmi_sink);
+ if (status == MODE_OK)
+ return MODE_OK;
+ }
- /* if we can't do 8,12bpc we may still be able to do 10bpc */
- if (status != MODE_OK &&
- intel_hdmi_source_bpc_possible(i915, 10) &&
- intel_hdmi_sink_bpc_possible(connector, 10, has_hdmi_sink, ycbcr420_output))
- status = hdmi_port_clock_valid(hdmi, intel_hdmi_tmds_clock(clock, 10, ycbcr420_output),
- true, has_hdmi_sink);
+ /* can never happen */
+ drm_WARN_ON(&i915->drm, status == MODE_OK);
return status;
}
@@ -2002,17 +2007,14 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
return intel_mode_valid_max_plane_size(dev_priv, mode, false);
}
-bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
- int bpc, bool has_hdmi_sink, bool ycbcr420_output)
+bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
+ int bpc, bool has_hdmi_sink, bool ycbcr420_output)
{
struct drm_atomic_state *state = crtc_state->uapi.state;
struct drm_connector_state *connector_state;
struct drm_connector *connector;
int i;
- if (crtc_state->pipe_bpp < bpc * 3)
- return false;
-
for_each_new_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc_state->uapi.crtc)
continue;
@@ -2024,8 +2026,7 @@ bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
return true;
}
-static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
- int bpc)
+static bool hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc)
{
struct drm_i915_private *dev_priv =
to_i915(crtc_state->uapi.crtc->dev);
@@ -2039,7 +2040,7 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
* HDMI deep color affects the clocks, so it's only possible
* when not cloning with other encoder types.
*/
- if (crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI))
+ if (bpc > 8 && crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI))
return false;
/* Display Wa_1405510057:icl,ehl */
@@ -2049,35 +2050,50 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
adjusted_mode->crtc_hblank_start) % 8 == 2)
return false;
- return intel_hdmi_deep_color_possible(crtc_state, bpc,
- crtc_state->has_hdmi_sink,
- intel_hdmi_is_ycbcr420(crtc_state));
+ return intel_hdmi_bpc_possible(crtc_state, bpc, crtc_state->has_hdmi_sink,
+ intel_hdmi_is_ycbcr420(crtc_state));
}
static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
- int clock)
+ int clock, bool respect_downstream_limits)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
bool ycbcr420_output = intel_hdmi_is_ycbcr420(crtc_state);
int bpc;
- for (bpc = 12; bpc >= 10; bpc -= 2) {
- if (hdmi_deep_color_possible(crtc_state, bpc) &&
- hdmi_port_clock_valid(intel_hdmi,
- intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output),
- true, crtc_state->has_hdmi_sink) == MODE_OK)
+ /*
+ * pipe_bpp could already be below 8bpc due to FDI
+ * bandwidth constraints. HDMI minimum is 8bpc however.
+ */
+ bpc = max(crtc_state->pipe_bpp / 3, 8);
+
+ /*
+ * We will never exceed downstream TMDS clock limits while
+ * attempting deep color. If the user insists on forcing an
+ * out of spec mode they will have to be satisfied with 8bpc.
+ */
+ if (!respect_downstream_limits)
+ bpc = 8;
+
+ for (; bpc >= 8; bpc -= 2) {
+ int tmds_clock = intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output);
+
+ if (hdmi_bpc_possible(crtc_state, bpc) &&
+ hdmi_port_clock_valid(intel_hdmi, tmds_clock,
+ respect_downstream_limits,
+ crtc_state->has_hdmi_sink) == MODE_OK)
return bpc;
}
- return 8;
+ return -EINVAL;
}
static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
- struct intel_crtc_state *crtc_state)
+ struct intel_crtc_state *crtc_state,
+ bool respect_downstream_limits)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int bpc, clock = adjusted_mode->crtc_clock;
@@ -2085,31 +2101,25 @@ static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
clock *= 2;
- bpc = intel_hdmi_compute_bpc(encoder, crtc_state, clock);
+ bpc = intel_hdmi_compute_bpc(encoder, crtc_state, clock,
+ respect_downstream_limits);
+ if (bpc < 0)
+ return bpc;
- crtc_state->port_clock = intel_hdmi_tmds_clock(clock, bpc,
- intel_hdmi_is_ycbcr420(crtc_state));
+ crtc_state->port_clock =
+ intel_hdmi_tmds_clock(clock, bpc, intel_hdmi_is_ycbcr420(crtc_state));
/*
* pipe_bpp could already be below 8bpc due to
* FDI bandwidth constraints. We shouldn't bump it
- * back up to 8bpc in that case.
+ * back up to the HDMI minimum 8bpc in that case.
*/
- if (crtc_state->pipe_bpp > bpc * 3)
- crtc_state->pipe_bpp = bpc * 3;
+ crtc_state->pipe_bpp = min(crtc_state->pipe_bpp, bpc * 3);
drm_dbg_kms(&i915->drm,
"picking %d bpc for HDMI output (pipe bpp: %d)\n",
bpc, crtc_state->pipe_bpp);
- if (hdmi_port_clock_valid(intel_hdmi, crtc_state->port_clock,
- false, crtc_state->has_hdmi_sink) != MODE_OK) {
- drm_dbg_kms(&i915->drm,
- "unsupported HDMI clock (%d kHz), rejecting mode\n",
- crtc_state->port_clock);
- return -EINVAL;
- }
-
return 0;
}
@@ -2170,7 +2180,8 @@ intel_hdmi_output_format(struct intel_connector *connector,
static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
- const struct drm_connector_state *conn_state)
+ const struct drm_connector_state *conn_state,
+ bool respect_downstream_limits)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
@@ -2187,7 +2198,7 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
}
- ret = intel_hdmi_compute_clock(encoder, crtc_state);
+ ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
if (ret) {
if (intel_hdmi_is_ycbcr420(crtc_state) ||
!connector->base.ycbcr_420_allowed ||
@@ -2195,7 +2206,7 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
return ret;
crtc_state->output_format = intel_hdmi_output_format(connector, true);
- ret = intel_hdmi_compute_clock(encoder, crtc_state);
+ ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
}
return ret;
@@ -2231,9 +2242,19 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
pipe_config->has_audio =
intel_hdmi_has_audio(encoder, pipe_config, conn_state);
- ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state);
+ /*
+ * Try to respect downstream TMDS clock limits first, if
+ * that fails assume the user might know something we don't.
+ */
+ ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state, true);
if (ret)
+ ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state, false);
+ if (ret) {
+ drm_dbg_kms(&dev_priv->drm,
+ "unsupported HDMI clock (%d kHz), rejecting mode\n",
+ pipe_config->hw.adjusted_mode.crtc_clock);
return ret;
+ }
if (intel_hdmi_is_ycbcr420(pipe_config)) {
ret = intel_panel_fitting(pipe_config, conn_state);
@@ -2359,6 +2380,14 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
"DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
drm_dp_get_dual_mode_type_name(type),
hdmi->dp_dual_mode.max_tmds_clock);
+
+ /* Older VBTs are often buggy and can't be trusted :( Play it safe. */
+ if ((DISPLAY_VER(dev_priv) >= 8 || IS_HASWELL(dev_priv)) &&
+ !intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "Ignoring DP dual mode adaptor max TMDS clock for native HDMI port\n");
+ hdmi->dp_dual_mode.max_tmds_clock = 0;
+ }
}
static bool
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index 2bf440eb400a..93f65a917c36 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -9,8 +9,6 @@
#include <linux/hdmi.h>
#include <linux/types.h>
-#include "i915_reg.h"
-
struct drm_connector;
struct drm_encoder;
struct drm_i915_private;
@@ -46,8 +44,9 @@ void intel_read_infoframe(struct intel_encoder *encoder,
union hdmi_infoframe *frame);
bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
-bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, int bpc,
- bool has_hdmi_sink, bool ycbcr420_output);
+bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
+ int bpc, bool has_hdmi_sink, bool ycbcr420_output);
+int intel_hdmi_tmds_clock(int clock, int bpc, bool ycbcr420_output);
int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width,
int num_slices, int output_format, bool hdmi_all_bpp,
int hdmi_max_chunk_bytes);
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c
index 955f6d07b0e1..8204126d17f9 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include "i915_drv.h"
+#include "i915_irq.h"
#include "intel_display_types.h"
#include "intel_hotplug.h"
@@ -213,12 +214,6 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
}
}
-static void intel_hpd_irq_setup(struct drm_i915_private *i915)
-{
- if (i915->display_irqs_enabled && i915->hotplug_funcs)
- i915->hotplug_funcs->hpd_irq_setup(i915);
-}
-
static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
@@ -281,13 +276,13 @@ intel_encoder_hotplug(struct intel_encoder *encoder,
ret = true;
if (ret) {
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s (epoch counter %llu->%llu)\n",
- connector->base.base.id,
- connector->base.name,
- drm_get_connector_status_name(old_status),
- drm_get_connector_status_name(connector->base.status),
- old_epoch_counter,
- connector->base.epoch_counter);
+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to %s (epoch counter %llu->%llu)\n",
+ connector->base.base.id,
+ connector->base.name,
+ drm_get_connector_status_name(old_status),
+ drm_get_connector_status_name(connector->base.status),
+ old_epoch_counter,
+ connector->base.epoch_counter);
return INTEL_HOTPLUG_CHANGED;
}
return INTEL_HOTPLUG_UNCHANGED;
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index 012f13e034bf..76357c9b76e4 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -78,11 +78,12 @@ static const char *lspcon_mode_name(enum drm_lspcon_mode mode)
static bool lspcon_detect_vendor(struct intel_lspcon *lspcon)
{
struct intel_dp *dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(dp);
struct drm_dp_dpcd_ident *ident;
u32 vendor_oui;
if (drm_dp_read_desc(&dp->aux, &dp->desc, drm_dp_is_branch(dp->dpcd))) {
- DRM_ERROR("Can't read description\n");
+ drm_err(&i915->drm, "Can't read description\n");
return false;
}
@@ -93,16 +94,16 @@ static bool lspcon_detect_vendor(struct intel_lspcon *lspcon)
switch (vendor_oui) {
case LSPCON_VENDOR_MCA_OUI:
lspcon->vendor = LSPCON_VENDOR_MCA;
- DRM_DEBUG_KMS("Vendor: Mega Chips\n");
+ drm_dbg_kms(&i915->drm, "Vendor: Mega Chips\n");
break;
case LSPCON_VENDOR_PARADE_OUI:
lspcon->vendor = LSPCON_VENDOR_PARADE;
- DRM_DEBUG_KMS("Vendor: Parade Tech\n");
+ drm_dbg_kms(&i915->drm, "Vendor: Parade Tech\n");
break;
default:
- DRM_ERROR("Invalid/Unknown vendor OUI\n");
+ drm_err(&i915->drm, "Invalid/Unknown vendor OUI\n");
return false;
}
@@ -119,21 +120,19 @@ static u32 get_hdr_status_reg(struct intel_lspcon *lspcon)
void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon)
{
- struct intel_digital_port *dig_port =
- container_of(lspcon, struct intel_digital_port, lspcon);
- struct drm_device *dev = dig_port->base.base.dev;
- struct intel_dp *dp = lspcon_to_intel_dp(lspcon);
+ struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 hdr_caps;
int ret;
- ret = drm_dp_dpcd_read(&dp->aux, get_hdr_status_reg(lspcon),
+ ret = drm_dp_dpcd_read(&intel_dp->aux, get_hdr_status_reg(lspcon),
&hdr_caps, 1);
if (ret < 0) {
- drm_dbg_kms(dev, "HDR capability detection failed\n");
+ drm_dbg_kms(&i915->drm, "HDR capability detection failed\n");
lspcon->hdr_supported = false;
} else if (hdr_caps & 0x1) {
- drm_dbg_kms(dev, "LSPCON capable of HDR\n");
+ drm_dbg_kms(&i915->drm, "LSPCON capable of HDR\n");
lspcon->hdr_supported = true;
}
}
@@ -141,11 +140,12 @@ void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon)
static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
{
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
enum drm_lspcon_mode current_mode;
struct i2c_adapter *adapter = &intel_dp->aux.ddc;
if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode)) {
- DRM_DEBUG_KMS("Error reading LSPCON mode\n");
+ drm_dbg_kms(&i915->drm, "Error reading LSPCON mode\n");
return DRM_LSPCON_MODE_INVALID;
}
return current_mode;
@@ -154,22 +154,24 @@ static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
enum drm_lspcon_mode mode)
{
+ struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
enum drm_lspcon_mode current_mode;
current_mode = lspcon_get_current_mode(lspcon);
if (current_mode == mode)
goto out;
- DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",
- lspcon_mode_name(mode));
+ drm_dbg_kms(&i915->drm, "Waiting for LSPCON mode %s to settle\n",
+ lspcon_mode_name(mode));
wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
if (current_mode != mode)
- DRM_ERROR("LSPCON mode hasn't settled\n");
+ drm_err(&i915->drm, "LSPCON mode hasn't settled\n");
out:
- DRM_DEBUG_KMS("Current LSPCON mode %s\n",
- lspcon_mode_name(current_mode));
+ drm_dbg_kms(&i915->drm, "Current LSPCON mode %s\n",
+ lspcon_mode_name(current_mode));
return current_mode;
}
@@ -178,44 +180,47 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon,
enum drm_lspcon_mode mode)
{
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int err;
enum drm_lspcon_mode current_mode;
struct i2c_adapter *adapter = &intel_dp->aux.ddc;
err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode);
if (err) {
- DRM_ERROR("Error reading LSPCON mode\n");
+ drm_err(&i915->drm, "Error reading LSPCON mode\n");
return err;
}
if (current_mode == mode) {
- DRM_DEBUG_KMS("Current mode = desired LSPCON mode\n");
+ drm_dbg_kms(&i915->drm, "Current mode = desired LSPCON mode\n");
return 0;
}
err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, adapter, mode);
if (err < 0) {
- DRM_ERROR("LSPCON mode change failed\n");
+ drm_err(&i915->drm, "LSPCON mode change failed\n");
return err;
}
lspcon->mode = mode;
- DRM_DEBUG_KMS("LSPCON mode changed done\n");
+ drm_dbg_kms(&i915->drm, "LSPCON mode changed done\n");
return 0;
}
static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon)
{
+ struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 rev;
if (drm_dp_dpcd_readb(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV,
&rev) != 1) {
- DRM_DEBUG_KMS("Native AUX CH down\n");
+ drm_dbg_kms(&i915->drm, "Native AUX CH down\n");
return false;
}
- DRM_DEBUG_KMS("Native AUX CH up, DPCD version: %d.%d\n",
- rev >> 4, rev & 0xf);
+ drm_dbg_kms(&i915->drm, "Native AUX CH up, DPCD version: %d.%d\n",
+ rev >> 4, rev & 0xf);
return true;
}
@@ -225,6 +230,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
int retry;
enum drm_dp_dual_mode_type adaptor_type;
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct i2c_adapter *adapter = &intel_dp->aux.ddc;
enum drm_lspcon_mode expected_mode;
@@ -242,13 +248,13 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
}
if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) {
- DRM_DEBUG_KMS("No LSPCON detected, found %s\n",
- drm_dp_get_dual_mode_type_name(adaptor_type));
+ drm_dbg_kms(&i915->drm, "No LSPCON detected, found %s\n",
+ drm_dp_get_dual_mode_type_name(adaptor_type));
return false;
}
/* Yay ... got a LSPCON device */
- DRM_DEBUG_KMS("LSPCON detected\n");
+ drm_dbg_kms(&i915->drm, "LSPCON detected\n");
lspcon->mode = lspcon_wait_mode(lspcon, expected_mode);
/*
@@ -258,7 +264,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
*/
if (lspcon->mode != DRM_LSPCON_MODE_PCON) {
if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) {
- DRM_ERROR("LSPCON mode change to PCON failed\n");
+ drm_err(&i915->drm, "LSPCON mode change to PCON failed\n");
return false;
}
}
@@ -268,13 +274,14 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon)
{
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
unsigned long start = jiffies;
while (1) {
if (intel_digital_port_connected(&dig_port->base)) {
- DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u ms\n",
- jiffies_to_msecs(jiffies - start));
+ drm_dbg_kms(&i915->drm, "LSPCON recovering in PCON mode after %u ms\n",
+ jiffies_to_msecs(jiffies - start));
return;
}
@@ -284,7 +291,7 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon)
usleep_range(10000, 15000);
}
- DRM_DEBUG_KMS("LSPCON DP descriptor mismatch after resume\n");
+ drm_dbg_kms(&i915->drm, "LSPCON DP descriptor mismatch after resume\n");
}
static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
@@ -301,7 +308,7 @@ static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
ret = drm_dp_dpcd_read(aux, LSPCON_PARADE_AVI_IF_CTRL,
&avi_if_ctrl, 1);
if (ret < 0) {
- DRM_ERROR("Failed to read AVI IF control\n");
+ drm_err(aux->drm_dev, "Failed to read AVI IF control\n");
return false;
}
@@ -309,7 +316,7 @@ static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
return true;
}
- DRM_ERROR("Parade FW not ready to accept AVI IF\n");
+ drm_err(aux->drm_dev, "Parade FW not ready to accept AVI IF\n");
return false;
}
@@ -324,8 +331,8 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
while (block_count < 4) {
if (!lspcon_parade_fw_ready(aux)) {
- DRM_DEBUG_KMS("LSPCON FW not ready, block %d\n",
- block_count);
+ drm_dbg_kms(aux->drm_dev, "LSPCON FW not ready, block %d\n",
+ block_count);
return false;
}
@@ -333,8 +340,8 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
data = avi_buf + block_count * 8;
ret = drm_dp_dpcd_write(aux, reg, data, 8);
if (ret < 0) {
- DRM_ERROR("Failed to write AVI IF block %d\n",
- block_count);
+ drm_err(aux->drm_dev, "Failed to write AVI IF block %d\n",
+ block_count);
return false;
}
@@ -348,15 +355,15 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count;
ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1);
if (ret < 0) {
- DRM_ERROR("Failed to update (0x%x), block %d\n",
- reg, block_count);
+ drm_err(aux->drm_dev, "Failed to update (0x%x), block %d\n",
+ reg, block_count);
return false;
}
block_count++;
}
- DRM_DEBUG_KMS("Wrote AVI IF blocks successfully\n");
+ drm_dbg_kms(aux->drm_dev, "Wrote AVI IF blocks successfully\n");
return true;
}
@@ -378,14 +385,14 @@ static bool _lspcon_write_avi_infoframe_parade(struct drm_dp_aux *aux,
*/
if (len > LSPCON_PARADE_AVI_IF_DATA_SIZE - 1) {
- DRM_ERROR("Invalid length of infoframes\n");
+ drm_err(aux->drm_dev, "Invalid length of infoframes\n");
return false;
}
memcpy(&avi_if[1], frame, len);
if (!_lspcon_parade_write_infoframe_blocks(aux, avi_if)) {
- DRM_DEBUG_KMS("Failed to write infoframe blocks\n");
+ drm_dbg_kms(aux->drm_dev, "Failed to write infoframe blocks\n");
return false;
}
@@ -412,7 +419,7 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
mdelay(50);
continue;
} else {
- DRM_ERROR("DPCD write failed at:0x%x\n", reg);
+ drm_err(aux->drm_dev, "DPCD write failed at:0x%x\n", reg);
return false;
}
}
@@ -423,7 +430,7 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
reg = LSPCON_MCA_AVI_IF_CTRL;
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) {
- DRM_ERROR("DPCD read failed, address 0x%x\n", reg);
+ drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false;
}
@@ -433,19 +440,19 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
ret = drm_dp_dpcd_write(aux, reg, &val, 1);
if (ret < 0) {
- DRM_ERROR("DPCD read failed, address 0x%x\n", reg);
+ drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false;
}
val = 0;
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) {
- DRM_ERROR("DPCD read failed, address 0x%x\n", reg);
+ drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false;
}
if (val == LSPCON_MCA_AVI_IF_HANDLED)
- DRM_DEBUG_KMS("AVI IF handled by FW\n");
+ drm_dbg_kms(aux->drm_dev, "AVI IF handled by FW\n");
return true;
}
@@ -457,6 +464,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
{
bool ret = true;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder);
switch (type) {
@@ -469,7 +477,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
frame, len);
break;
case HDMI_PACKET_TYPE_GAMUT_METADATA:
- drm_dbg_kms(encoder->base.dev, "Update HDR metadata for lspcon\n");
+ drm_dbg_kms(&i915->drm, "Update HDR metadata for lspcon\n");
/* It uses the legacy hsw implementation for the same */
hsw_write_infoframe(encoder, crtc_state, type, frame, len);
break;
@@ -478,7 +486,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
}
if (!ret) {
- DRM_ERROR("Failed to write infoframes\n");
+ drm_err(&i915->drm, "Failed to write infoframes\n");
return;
}
}
@@ -504,11 +512,12 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
u8 buf[VIDEO_DIP_DATA_SIZE];
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_lspcon *lspcon = &dig_port->lspcon;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
if (!lspcon->active) {
- DRM_ERROR("Writing infoframes while LSPCON disabled ?\n");
+ drm_err(&i915->drm, "Writing infoframes while LSPCON disabled ?\n");
return;
}
@@ -518,7 +527,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
conn_state->connector,
adjusted_mode);
if (ret < 0) {
- DRM_ERROR("couldn't fill AVI infoframe\n");
+ drm_err(&i915->drm, "couldn't fill AVI infoframe\n");
return;
}
@@ -559,7 +568,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf));
if (ret < 0) {
- DRM_ERROR("Failed to pack AVI IF\n");
+ drm_err(&i915->drm, "Failed to pack AVI IF\n");
return;
}
@@ -575,7 +584,7 @@ static bool _lspcon_read_avi_infoframe_enabled_mca(struct drm_dp_aux *aux)
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) {
- DRM_ERROR("DPCD read failed, address 0x%x\n", reg);
+ drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false;
}
@@ -590,7 +599,7 @@ static bool _lspcon_read_avi_infoframe_enabled_parade(struct drm_dp_aux *aux)
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) {
- DRM_ERROR("DPCD read failed, address 0x%x\n", reg);
+ drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false;
}
@@ -634,31 +643,32 @@ void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon)
bool lspcon_init(struct intel_digital_port *dig_port)
{
- struct intel_dp *dp = &dig_port->dp;
+ struct intel_dp *intel_dp = &dig_port->dp;
struct intel_lspcon *lspcon = &dig_port->lspcon;
- struct drm_connector *connector = &dp->attached_connector->base;
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct drm_connector *connector = &intel_dp->attached_connector->base;
lspcon->active = false;
lspcon->mode = DRM_LSPCON_MODE_INVALID;
if (!lspcon_probe(lspcon)) {
- DRM_ERROR("Failed to probe lspcon\n");
+ drm_err(&i915->drm, "Failed to probe lspcon\n");
return false;
}
- if (drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd) != 0) {
- DRM_ERROR("LSPCON DPCD read failed\n");
+ if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0) {
+ drm_err(&i915->drm, "LSPCON DPCD read failed\n");
return false;
}
if (!lspcon_detect_vendor(lspcon)) {
- DRM_ERROR("LSPCON vendor detection failed\n");
+ drm_err(&i915->drm, "LSPCON vendor detection failed\n");
return false;
}
connector->ycbcr_420_allowed = true;
lspcon->active = true;
- DRM_DEBUG_KMS("Success: LSPCON init\n");
+ drm_dbg_kms(&i915->drm, "Success: LSPCON init\n");
return true;
}
@@ -674,16 +684,16 @@ void lspcon_resume(struct intel_digital_port *dig_port)
{
struct intel_lspcon *lspcon = &dig_port->lspcon;
struct drm_device *dev = dig_port->base.base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
+ struct drm_i915_private *i915 = to_i915(dev);
enum drm_lspcon_mode expected_mode;
- if (!intel_bios_is_lspcon_present(dev_priv, dig_port->base.port))
+ if (!intel_bios_is_lspcon_present(i915, dig_port->base.port))
return;
if (!lspcon->active) {
if (!lspcon_init(dig_port)) {
- DRM_ERROR("LSPCON init failed on port %c\n",
- port_name(dig_port->base.port));
+ drm_err(&i915->drm, "LSPCON init failed on port %c\n",
+ port_name(dig_port->base.port));
return;
}
}
@@ -699,7 +709,7 @@ void lspcon_resume(struct intel_digital_port *dig_port)
return;
if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON))
- DRM_ERROR("LSPCON resume failed\n");
+ drm_err(&i915->drm, "LSPCON resume failed\n");
else
- DRM_DEBUG_KMS("LSPCON resume success\n");
+ drm_dbg_kms(&i915->drm, "LSPCON resume success\n");
}
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.h b/drivers/gpu/drm/i915/display/intel_lvds.h
index bc9c8b84ba2f..9d3372dc503f 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.h
+++ b/drivers/gpu/drm/i915/display/intel_lvds.h
@@ -8,7 +8,7 @@
#include <linux/types.h>
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
enum pipe;
struct drm_i915_private;
diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c
index 0065111593a6..f31e8c3f8ce0 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.c
+++ b/drivers/gpu/drm/i915/display/intel_opregion.c
@@ -35,6 +35,7 @@
#include "intel_backlight.h"
#include "intel_display_types.h"
#include "intel_opregion.h"
+#include "intel_pci_config.h"
#define OPREGION_HEADER_OFFSET 0
#define OPREGION_ACPI_OFFSET 0x100
@@ -46,10 +47,11 @@
#define OPREGION_ASLE_EXT_OFFSET 0x1C00
#define OPREGION_SIGNATURE "IntelGraphicsMem"
-#define MBOX_ACPI (1<<0)
-#define MBOX_SWSCI (1<<1)
-#define MBOX_ASLE (1<<2)
-#define MBOX_ASLE_EXT (1<<4)
+#define MBOX_ACPI BIT(0) /* Mailbox #1 */
+#define MBOX_SWSCI BIT(1) /* Mailbox #2 (obsolete from v2.x) */
+#define MBOX_ASLE BIT(2) /* Mailbox #3 */
+#define MBOX_ASLE_EXT BIT(4) /* Mailbox #5 */
+#define MBOX_BACKLIGHT BIT(5) /* Mailbox #2 (valid from v3.x) */
struct opregion_header {
u8 signature[16];
@@ -195,6 +197,8 @@ struct opregion_asle_ext {
#define ASLE_IUER_WINDOWS_BTN (1 << 1)
#define ASLE_IUER_POWER_BTN (1 << 0)
+#define ASLE_PHED_EDID_VALID_MASK 0x3
+
/* Software System Control Interrupt (SWSCI) */
#define SWSCI_SCIC_INDICATOR (1 << 0)
#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
@@ -242,14 +246,10 @@ struct opregion_asle_ext {
#define MAX_DSLP 1500
-static int swsci(struct drm_i915_private *dev_priv,
- u32 function, u32 parm, u32 *parm_out)
+static int check_swsci_function(struct drm_i915_private *i915, u32 function)
{
- struct opregion_swsci *swsci = dev_priv->opregion.swsci;
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
- u32 main_function, sub_function, scic;
- u16 swsci_val;
- u32 dslp;
+ struct opregion_swsci *swsci = i915->opregion.swsci;
+ u32 main_function, sub_function;
if (!swsci)
return -ENODEV;
@@ -261,15 +261,31 @@ static int swsci(struct drm_i915_private *dev_priv,
/* Check if we can call the function. See swsci_setup for details. */
if (main_function == SWSCI_SBCB) {
- if ((dev_priv->opregion.swsci_sbcb_sub_functions &
+ if ((i915->opregion.swsci_sbcb_sub_functions &
(1 << sub_function)) == 0)
return -EINVAL;
} else if (main_function == SWSCI_GBDA) {
- if ((dev_priv->opregion.swsci_gbda_sub_functions &
+ if ((i915->opregion.swsci_gbda_sub_functions &
(1 << sub_function)) == 0)
return -EINVAL;
}
+ return 0;
+}
+
+static int swsci(struct drm_i915_private *dev_priv,
+ u32 function, u32 parm, u32 *parm_out)
+{
+ struct opregion_swsci *swsci = dev_priv->opregion.swsci;
+ struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ u32 scic, dslp;
+ u16 swsci_val;
+ int ret;
+
+ ret = check_swsci_function(dev_priv, function);
+ if (ret)
+ return ret;
+
/* Driver sleep timeout in ms. */
dslp = swsci->dslp;
if (!dslp) {
@@ -343,11 +359,17 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
u32 parm = 0;
u32 type = 0;
u32 port;
+ int ret;
/* don't care about old stuff for now */
if (!HAS_DDI(dev_priv))
return 0;
+ /* Avoid port out of bounds checks if SWSCI isn't there. */
+ ret = check_swsci_function(dev_priv, SWSCI_SBCB_DISPLAY_POWER_STATE);
+ if (ret)
+ return ret;
+
if (intel_encoder->type == INTEL_OUTPUT_DSI)
port = 0;
else
@@ -360,6 +382,21 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
port++;
}
+ /*
+ * The port numbering and mapping here is bizarre. The now-obsolete
+ * swsci spec supports ports numbered [0..4]. Port E is handled as a
+ * special case, but port F and beyond are not. The functionality is
+ * supposed to be obsolete for new platforms. Just bail out if the port
+ * number is out of bounds after mapping.
+ */
+ if (port > 4) {
+ drm_dbg_kms(&dev_priv->drm,
+ "[ENCODER:%d:%s] port %c (index %u) out of bounds for display power state notification\n",
+ intel_encoder->base.base.id, intel_encoder->base.name,
+ port_name(intel_encoder->port), port);
+ return -EINVAL;
+ }
+
if (!enable)
parm |= 4 << 8;
@@ -896,9 +933,17 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
}
if (mboxes & MBOX_SWSCI) {
- drm_dbg(&dev_priv->drm, "SWSCI supported\n");
- opregion->swsci = base + OPREGION_SWSCI_OFFSET;
- swsci_setup(dev_priv);
+ u8 major = opregion->header->over.major;
+
+ if (major >= 3) {
+ drm_err(&dev_priv->drm, "SWSCI Mailbox #2 present for opregion v3.x, ignoring\n");
+ } else {
+ if (major >= 2)
+ drm_dbg(&dev_priv->drm, "SWSCI Mailbox #2 present for opregion v2.x\n");
+ drm_dbg(&dev_priv->drm, "SWSCI supported\n");
+ opregion->swsci = base + OPREGION_SWSCI_OFFSET;
+ swsci_setup(dev_priv);
+ }
}
if (mboxes & MBOX_ASLE) {
@@ -908,8 +953,14 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
opregion->asle->ardy = ASLE_ARDY_NOT_READY;
}
- if (mboxes & MBOX_ASLE_EXT)
+ if (mboxes & MBOX_ASLE_EXT) {
drm_dbg(&dev_priv->drm, "ASLE extension supported\n");
+ opregion->asle_ext = base + OPREGION_ASLE_EXT_OFFSET;
+ }
+
+ if (mboxes & MBOX_BACKLIGHT) {
+ drm_dbg(&dev_priv->drm, "Mailbox #2 for backlight present\n");
+ }
if (intel_load_vbt_firmware(dev_priv) == 0)
goto out;
@@ -1036,6 +1087,54 @@ intel_opregion_get_panel_type(struct drm_i915_private *dev_priv)
return ret - 1;
}
+/**
+ * intel_opregion_get_edid - Fetch EDID from ACPI OpRegion mailbox #5
+ * @intel_connector: eDP connector
+ *
+ * This reads the ACPI Opregion mailbox #5 to extract the EDID that is passed
+ * to it.
+ *
+ * Returns:
+ * The EDID in the OpRegion, or NULL if there is none or it's invalid.
+ *
+ */
+struct edid *intel_opregion_get_edid(struct intel_connector *intel_connector)
+{
+ struct drm_connector *connector = &intel_connector->base;
+ struct drm_i915_private *i915 = to_i915(connector->dev);
+ struct intel_opregion *opregion = &i915->opregion;
+ const void *in_edid;
+ const struct edid *edid;
+ struct edid *new_edid;
+ int len;
+
+ if (!opregion->asle_ext)
+ return NULL;
+
+ in_edid = opregion->asle_ext->bddc;
+
+ /* Validity corresponds to number of 128-byte blocks */
+ len = (opregion->asle_ext->phed & ASLE_PHED_EDID_VALID_MASK) * 128;
+ if (!len || !memchr_inv(in_edid, 0, len))
+ return NULL;
+
+ edid = in_edid;
+
+ if (len < EDID_LENGTH * (1 + edid->extensions)) {
+ drm_dbg_kms(&i915->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5): too short\n");
+ return NULL;
+ }
+ new_edid = drm_edid_duplicate(edid);
+ if (!new_edid)
+ return NULL;
+ if (!drm_edid_is_valid(new_edid)) {
+ kfree(new_edid);
+ drm_dbg_kms(&i915->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5)\n");
+ return NULL;
+ }
+ return new_edid;
+}
+
void intel_opregion_register(struct drm_i915_private *i915)
{
struct intel_opregion *opregion = &i915->opregion;
@@ -1129,6 +1228,7 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
opregion->acpi = NULL;
opregion->swsci = NULL;
opregion->asle = NULL;
+ opregion->asle_ext = NULL;
opregion->vbt = NULL;
opregion->lid_state = NULL;
}
diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h b/drivers/gpu/drm/i915/display/intel_opregion.h
index 4aa68ffbd30e..82cc0ba34af7 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.h
+++ b/drivers/gpu/drm/i915/display/intel_opregion.h
@@ -29,12 +29,14 @@
#include <linux/pci.h>
struct drm_i915_private;
+struct intel_connector;
struct intel_encoder;
struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
+struct opregion_asle_ext;
struct intel_opregion {
struct opregion_header *header;
@@ -43,6 +45,7 @@ struct intel_opregion {
u32 swsci_gbda_sub_functions;
u32 swsci_sbcb_sub_functions;
struct opregion_asle *asle;
+ struct opregion_asle_ext *asle_ext;
void *rvda;
void *vbt_firmware;
const void *vbt;
@@ -71,6 +74,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
int intel_opregion_notify_adapter(struct drm_i915_private *dev_priv,
pci_power_t state);
int intel_opregion_get_panel_type(struct drm_i915_private *dev_priv);
+struct edid *intel_opregion_get_edid(struct intel_connector *connector);
#else /* CONFIG_ACPI*/
@@ -117,6 +121,12 @@ static inline int intel_opregion_get_panel_type(struct drm_i915_private *dev)
return -ENODEV;
}
+static inline struct edid *
+intel_opregion_get_edid(struct intel_connector *connector)
+{
+ return NULL;
+}
+
#endif /* CONFIG_ACPI */
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c
index 1a376e9a1ff3..76845d34ad0c 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.c
+++ b/drivers/gpu/drm/i915/display/intel_overlay.c
@@ -28,6 +28,7 @@
#include <drm/drm_fourcc.h>
+#include "gem/i915_gem_internal.h"
#include "gem/i915_gem_pm.h"
#include "gt/intel_gpu_commands.h"
#include "gt/intel_ring.h"
@@ -38,6 +39,7 @@
#include "intel_display_types.h"
#include "intel_frontbuffer.h"
#include "intel_overlay.h"
+#include "intel_pci_config.h"
/* Limits for overlay size. According to intel doc, the real limits are:
* Y width: 4095, UV width (planar): 2047, Y height: 2047,
@@ -959,6 +961,9 @@ static int check_overlay_dst(struct intel_overlay *overlay,
const struct intel_crtc_state *pipe_config =
overlay->crtc->config;
+ if (rec->dst_height == 0 || rec->dst_width == 0)
+ return -EINVAL;
+
if (rec->dst_x < pipe_config->pipe_src_w &&
rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w &&
rec->dst_y < pipe_config->pipe_src_h &&
diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c
index a55c4bfacd0d..9192769e3337 100644
--- a/drivers/gpu/drm/i915/display/intel_pch_display.c
+++ b/drivers/gpu/drm/i915/display/intel_pch_display.c
@@ -88,6 +88,50 @@ static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
pipe_name(pipe));
}
+static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc,
+ const struct intel_link_m_n *m_n)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe = crtc->pipe;
+
+ intel_set_m_n(dev_priv, m_n,
+ PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe),
+ PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe));
+}
+
+static void intel_pch_transcoder_set_m2_n2(struct intel_crtc *crtc,
+ const struct intel_link_m_n *m_n)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe = crtc->pipe;
+
+ intel_set_m_n(dev_priv, m_n,
+ PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe),
+ PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe));
+}
+
+void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe = crtc->pipe;
+
+ intel_get_m_n(dev_priv, m_n,
+ PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe),
+ PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe));
+}
+
+void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe = crtc->pipe;
+
+ intel_get_m_n(dev_priv, m_n,
+ PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe),
+ PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe));
+}
+
static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state,
enum pipe pch_transcoder)
{
@@ -157,20 +201,20 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
*/
val &= ~PIPECONF_BPC_MASK;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
- val |= PIPECONF_8BPC;
+ val |= PIPECONF_BPC_8;
else
val |= pipeconf_val & PIPECONF_BPC_MASK;
}
val &= ~TRANS_INTERLACE_MASK;
- if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) {
+ if ((pipeconf_val & PIPECONF_INTERLACE_MASK_ILK) == PIPECONF_INTERLACE_IF_ID_ILK) {
if (HAS_PCH_IBX(dev_priv) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
- val |= TRANS_LEGACY_INTERLACED_ILK;
+ val |= TRANS_INTERLACE_LEGACY_VSYNC_IBX;
else
- val |= TRANS_INTERLACED;
+ val |= TRANS_INTERLACE_INTERLACED;
} else {
- val |= TRANS_PROGRESSIVE;
+ val |= TRANS_INTERLACE_PROGRESSIVE;
}
intel_de_write(dev_priv, reg, val | TRANS_ENABLE);
@@ -211,6 +255,20 @@ static void ilk_disable_pch_transcoder(struct intel_crtc *crtc)
}
}
+void ilk_pch_pre_enable(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ const struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ /*
+ * Note: FDI PLL enabling _must_ be done before we enable the
+ * cpu pipes, hence this is separate from all the other fdi/pch
+ * enabling.
+ */
+ ilk_fdi_pll_enable(crtc_state);
+}
+
/*
* Enable PCH resources required for PCH ports:
* - PCH PLLs
@@ -264,6 +322,10 @@ void ilk_pch_enable(struct intel_atomic_state *state,
/* set transcoder timing, panel must allow it */
assert_pps_unlocked(dev_priv, pipe);
+ if (intel_crtc_has_dp_encoder(crtc_state)) {
+ intel_pch_transcoder_set_m1_n1(crtc, &crtc_state->dp_m_n);
+ intel_pch_transcoder_set_m2_n2(crtc, &crtc_state->dp_m2_n2);
+ }
ilk_pch_transcoder_set_timings(crtc_state, pipe);
intel_fdi_normal_train(crtc);
@@ -279,7 +341,8 @@ void ilk_pch_enable(struct intel_atomic_state *state,
temp = intel_de_read(dev_priv, reg);
temp &= ~(TRANS_DP_PORT_SEL_MASK |
- TRANS_DP_SYNC_MASK |
+ TRANS_DP_VSYNC_ACTIVE_HIGH |
+ TRANS_DP_HSYNC_ACTIVE_HIGH |
TRANS_DP_BPC_MASK);
temp |= TRANS_DP_OUTPUT_ENABLE;
temp |= bpc << 9; /* same format but at 11:9 */
@@ -371,7 +434,8 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
FDI_DP_PORT_WIDTH_SHIFT) + 1;
- ilk_get_fdi_m_n_config(crtc, crtc_state);
+ intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
+ &crtc_state->fdi_m_n);
if (HAS_PCH_IBX(dev_priv)) {
/*
@@ -422,11 +486,10 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
val = TRANS_ENABLE;
pipeconf_val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder));
- if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) ==
- PIPECONF_INTERLACED_ILK)
- val |= TRANS_INTERLACED;
+ if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) == PIPECONF_INTERLACE_IF_ID_ILK)
+ val |= TRANS_INTERLACE_INTERLACED;
else
- val |= TRANS_PROGRESSIVE;
+ val |= TRANS_INTERLACE_PROGRESSIVE;
intel_de_write(dev_priv, LPT_TRANSCONF, val);
if (intel_de_wait_for_set(dev_priv, LPT_TRANSCONF,
@@ -495,7 +558,8 @@ void lpt_pch_get_config(struct intel_crtc_state *crtc_state)
crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
FDI_DP_PORT_WIDTH_SHIFT) + 1;
- ilk_get_fdi_m_n_config(crtc, crtc_state);
+ intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
+ &crtc_state->fdi_m_n);
crtc_state->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
}
diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.h b/drivers/gpu/drm/i915/display/intel_pch_display.h
index 2c387fe3a467..749473d99320 100644
--- a/drivers/gpu/drm/i915/display/intel_pch_display.h
+++ b/drivers/gpu/drm/i915/display/intel_pch_display.h
@@ -9,7 +9,10 @@
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
+struct intel_link_m_n;
+void ilk_pch_pre_enable(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
void ilk_pch_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void ilk_pch_disable(struct intel_atomic_state *state,
@@ -24,4 +27,9 @@ void lpt_pch_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void lpt_pch_get_config(struct intel_crtc_state *crtc_state);
+void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n);
+void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
+ struct intel_link_m_n *m_n);
+
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
index 543877998078..d7b1de4cc205 100644
--- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
+++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
@@ -166,8 +166,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc_state *crtc_state =
- to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
to_intel_plane(crtc->base.primary);
struct intel_plane_state *plane_state =
@@ -204,11 +202,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
* pretend the BIOS never had it enabled.
*/
intel_plane_disable_noatomic(crtc, plane);
- if (crtc_state->bigjoiner) {
- struct intel_crtc *slave =
- crtc_state->bigjoiner_linked_crtc;
- intel_plane_disable_noatomic(slave, to_intel_plane(slave->base.primary));
- }
return;
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index e9c679bb1b2e..9c986e8932f8 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -1131,16 +1131,20 @@ intel_pps_readout_hw_state(struct intel_dp *intel_dp, struct edp_power_seq *seq)
}
static void
-intel_pps_dump_state(const char *state_name, const struct edp_power_seq *seq)
+intel_pps_dump_state(struct intel_dp *intel_dp, const char *state_name,
+ const struct edp_power_seq *seq)
{
- DRM_DEBUG_KMS("%s t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
- state_name,
- seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ drm_dbg_kms(&i915->drm, "%s t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+ state_name,
+ seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12);
}
static void
intel_pps_verify_state(struct intel_dp *intel_dp)
{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct edp_power_seq hw;
struct edp_power_seq *sw = &intel_dp->pps.pps_delays;
@@ -1148,9 +1152,9 @@ intel_pps_verify_state(struct intel_dp *intel_dp)
if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 ||
hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) {
- DRM_ERROR("PPS state mismatch\n");
- intel_pps_dump_state("sw", sw);
- intel_pps_dump_state("hw", &hw);
+ drm_err(&i915->drm, "PPS state mismatch\n");
+ intel_pps_dump_state(intel_dp, "sw", sw);
+ intel_pps_dump_state(intel_dp, "hw", &hw);
}
}
@@ -1168,7 +1172,7 @@ static void pps_init_delays(struct intel_dp *intel_dp)
intel_pps_readout_hw_state(intel_dp, &cur);
- intel_pps_dump_state("cur", &cur);
+ intel_pps_dump_state(intel_dp, "cur", &cur);
vbt = dev_priv->vbt.edp.pps;
/* On Toshiba Satellite P50-C-18C system the VBT T12 delay
@@ -1200,7 +1204,7 @@ static void pps_init_delays(struct intel_dp *intel_dp)
* too. */
spec.t11_t12 = (510 + 100) * 10;
- intel_pps_dump_state("vbt", &vbt);
+ intel_pps_dump_state(intel_dp, "vbt", &vbt);
/* Use the max of the register settings and vbt. If both are
* unset, fall back to the spec limits. */
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index a1a663f362e7..2e0b092f4b6b 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1063,31 +1063,28 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
intel_dp->psr.active = true;
}
-static void intel_psr_enable_source(struct intel_dp *intel_dp)
+static u32 wa_16013835468_bit_get(struct intel_dp *intel_dp)
+{
+ switch (intel_dp->psr.pipe) {
+ case PIPE_A:
+ return LATENCY_REPORTING_REMOVED_PIPE_A;
+ case PIPE_B:
+ return LATENCY_REPORTING_REMOVED_PIPE_B;
+ case PIPE_C:
+ return LATENCY_REPORTING_REMOVED_PIPE_C;
+ default:
+ MISSING_CASE(intel_dp->psr.pipe);
+ return 0;
+ }
+}
+
+static void intel_psr_enable_source(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
u32 mask;
- if (intel_dp->psr.psr2_enabled && DISPLAY_VER(dev_priv) == 9) {
- i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
- u32 chicken = intel_de_read(dev_priv, reg);
-
- chicken |= PSR2_VSC_ENABLE_PROG_HEADER |
- PSR2_ADD_VERTICAL_LINE_COUNT;
- intel_de_write(dev_priv, reg, chicken);
- }
-
- /*
- * Wa_16014451276:adlp
- * All supported adlp panels have 1-based X granularity, this may
- * cause issues if non-supported panels are used.
- */
- if (IS_ALDERLAKE_P(dev_priv) &&
- intel_dp->psr.psr2_enabled)
- intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0,
- ADLP_1_BASED_X_GRANULARITY);
-
/*
* Per Spec: Avoid continuous PSR exit by masking MEMUP and HPD also
* mask LPSP to avoid dependency on other drivers that might block
@@ -1126,18 +1123,47 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp)
intel_dp->psr.psr2_sel_fetch_enabled ?
IGNORE_PSR2_HW_TRACKING : 0);
- /* Wa_16011168373:adl-p */
- if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) &&
- intel_dp->psr.psr2_enabled)
- intel_de_rmw(dev_priv,
- TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder),
- TRANS_SET_CONTEXT_LATENCY_MASK,
- TRANS_SET_CONTEXT_LATENCY_VALUE(1));
+ if (intel_dp->psr.psr2_enabled) {
+ if (DISPLAY_VER(dev_priv) == 9)
+ intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0,
+ PSR2_VSC_ENABLE_PROG_HEADER |
+ PSR2_ADD_VERTICAL_LINE_COUNT);
- /* Wa_16012604467:adlp */
- if (IS_ALDERLAKE_P(dev_priv) && intel_dp->psr.psr2_enabled)
- intel_de_rmw(dev_priv, CLKGATE_DIS_MISC, 0,
- CLKGATE_DIS_MISC_DMASC_GATING_DIS);
+ /*
+ * Wa_16014451276:adlp
+ * All supported adlp panels have 1-based X granularity, this may
+ * cause issues if non-supported panels are used.
+ */
+ if (IS_ALDERLAKE_P(dev_priv))
+ intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0,
+ ADLP_1_BASED_X_GRANULARITY);
+
+ /* Wa_16011168373:adl-p */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
+ intel_de_rmw(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder),
+ TRANS_SET_CONTEXT_LATENCY_MASK,
+ TRANS_SET_CONTEXT_LATENCY_VALUE(1));
+
+ /* Wa_16012604467:adlp */
+ if (IS_ALDERLAKE_P(dev_priv))
+ intel_de_rmw(dev_priv, CLKGATE_DIS_MISC, 0,
+ CLKGATE_DIS_MISC_DMASC_GATING_DIS);
+
+ /* Wa_16013835468:tgl[b0+], dg1 */
+ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_B0, STEP_FOREVER) ||
+ IS_DG1(dev_priv)) {
+ u16 vtotal, vblank;
+
+ vtotal = crtc_state->uapi.adjusted_mode.crtc_vtotal -
+ crtc_state->uapi.adjusted_mode.crtc_vdisplay;
+ vblank = crtc_state->uapi.adjusted_mode.crtc_vblank_end -
+ crtc_state->uapi.adjusted_mode.crtc_vblank_start;
+ if (vblank > vtotal)
+ intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, 0,
+ wa_16013835468_bit_get(intel_dp));
+ }
+ }
}
static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
@@ -1202,7 +1228,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_write_dp_vsc_sdp(encoder, crtc_state, &crtc_state->psr_vsc);
intel_snps_phy_update_psr_power_state(dev_priv, phy, true);
intel_psr_enable_sink(intel_dp);
- intel_psr_enable_source(intel_dp);
+ intel_psr_enable_source(intel_dp, crtc_state);
intel_dp->psr.enabled = true;
intel_dp->psr.paused = false;
@@ -1290,17 +1316,24 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
DIS_RAM_BYPASS_PSR2_MAN_TRACK, 0);
- /* Wa_16011168373:adl-p */
- if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) &&
- intel_dp->psr.psr2_enabled)
- intel_de_rmw(dev_priv,
- TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder),
- TRANS_SET_CONTEXT_LATENCY_MASK, 0);
-
- /* Wa_16012604467:adlp */
- if (IS_ALDERLAKE_P(dev_priv) && intel_dp->psr.psr2_enabled)
- intel_de_rmw(dev_priv, CLKGATE_DIS_MISC,
- CLKGATE_DIS_MISC_DMASC_GATING_DIS, 0);
+ if (intel_dp->psr.psr2_enabled) {
+ /* Wa_16011168373:adl-p */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
+ intel_de_rmw(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder),
+ TRANS_SET_CONTEXT_LATENCY_MASK, 0);
+
+ /* Wa_16012604467:adlp */
+ if (IS_ALDERLAKE_P(dev_priv))
+ intel_de_rmw(dev_priv, CLKGATE_DIS_MISC,
+ CLKGATE_DIS_MISC_DMASC_GATING_DIS, 0);
+
+ /* Wa_16013835468:tgl[b0+], dg1 */
+ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_B0, STEP_FOREVER) ||
+ IS_DG1(dev_priv))
+ intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1,
+ wa_16013835468_bit_get(intel_dp), 0);
+ }
intel_snps_phy_update_psr_power_state(dev_priv, phy, false);
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.h b/drivers/gpu/drm/i915/display/intel_sdvo.h
index 72065e4360d5..2868852c85f2 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.h
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.h
@@ -8,7 +8,7 @@
#include <linux/types.h>
-#include "i915_reg.h"
+#include "i915_reg_defs.h"
struct drm_i915_private;
enum pipe;
diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 09f405e4d363..7e6245b97fed 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -10,6 +10,7 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_snps_phy.h"
+#include "intel_snps_phy_regs.h"
/**
* DOC: Synopsis PHY support
@@ -23,18 +24,18 @@
* since it is not handled by the shared DPLL framework as on other platforms.
*/
-void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv)
+void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
{
enum phy phy;
for_each_phy_masked(phy, ~0) {
- if (!intel_phy_is_snps(dev_priv, phy))
+ if (!intel_phy_is_snps(i915, phy))
continue;
- if (intel_de_wait_for_clear(dev_priv, ICL_PHY_MISC(phy),
+ if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
DG2_PHY_DP_TX_ACK_MASK, 25))
- DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n",
- phy);
+ drm_err(&i915->drm, "SNPS PHY %c failed to calibrate after 25ms.\n",
+ phy_name(phy));
}
}
@@ -250,197 +251,6 @@ static const struct intel_mpllb_state * const dg2_dp_100_tables[] = {
};
/*
- * Basic DP link rates with 38.4 MHz reference clock.
- */
-
-static const struct intel_mpllb_state dg2_dp_rbr_38_4 = {
- .clock = 162000,
- .ref_control =
- REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
- .mpllb_cp =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
- .mpllb_div =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
- .mpllb_div2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 304),
- .mpllb_fracn1 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
- .mpllb_fracn2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 49152),
-};
-
-static const struct intel_mpllb_state dg2_dp_hbr1_38_4 = {
- .clock = 270000,
- .ref_control =
- REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
- .mpllb_cp =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
- .mpllb_div =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
- .mpllb_div2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 248),
- .mpllb_fracn1 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
- .mpllb_fracn2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40960),
-};
-
-static const struct intel_mpllb_state dg2_dp_hbr2_38_4 = {
- .clock = 540000,
- .ref_control =
- REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
- .mpllb_cp =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
- .mpllb_div =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
- .mpllb_div2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 248),
- .mpllb_fracn1 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
- .mpllb_fracn2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40960),
-};
-
-static const struct intel_mpllb_state dg2_dp_hbr3_38_4 = {
- .clock = 810000,
- .ref_control =
- REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
- .mpllb_cp =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 26) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
- .mpllb_div =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
- .mpllb_div2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 388),
- .mpllb_fracn1 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
- .mpllb_fracn2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 61440),
-};
-
-static const struct intel_mpllb_state dg2_dp_uhbr10_38_4 = {
- .clock = 1000000,
- .ref_control =
- REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
- .mpllb_cp =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 26) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
- .mpllb_div =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SHIM_DIV32_CLK_SEL, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
- .mpllb_div2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 488),
- .mpllb_fracn1 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 3),
- .mpllb_fracn2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 27306),
-
- /*
- * SSC will be enabled, DP UHBR has a minimum SSC requirement.
- */
- .mpllb_sscen =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 76800),
- .mpllb_sscstep =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 129024),
-};
-
-static const struct intel_mpllb_state dg2_dp_uhbr13_38_4 = {
- .clock = 1350000,
- .ref_control =
- REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
- .mpllb_cp =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 56) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
- .mpllb_div =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 3),
- .mpllb_div2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 670),
- .mpllb_fracn1 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
- .mpllb_fracn2 =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 36864),
-
- /*
- * SSC will be enabled, DP UHBR has a minimum SSC requirement.
- */
- .mpllb_sscen =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 103680),
- .mpllb_sscstep =
- REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 174182),
-};
-
-static const struct intel_mpllb_state * const dg2_dp_38_4_tables[] = {
- &dg2_dp_rbr_38_4,
- &dg2_dp_hbr1_38_4,
- &dg2_dp_hbr2_38_4,
- &dg2_dp_hbr3_38_4,
- &dg2_dp_uhbr10_38_4,
- &dg2_dp_uhbr13_38_4,
- NULL,
-};
-
-/*
* eDP link rates with 100 MHz reference clock.
*/
@@ -748,22 +558,7 @@ intel_mpllb_tables_get(struct intel_crtc_state *crtc_state,
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
return dg2_edp_tables;
} else if (intel_crtc_has_dp_encoder(crtc_state)) {
- /*
- * FIXME: Initially we're just enabling the "combo" outputs on
- * port A-D. The MPLLB for those ports takes an input from the
- * "Display Filter PLL" which always has an output frequency
- * of 100 MHz, hence the use of the _100 tables below.
- *
- * Once we enable port TC1 it will either use the same 100 MHz
- * "Display Filter PLL" (when strapped to support a native
- * display connection) or different 38.4 MHz "Filter PLL" when
- * strapped to support a USB connection, so we'll need to check
- * that to determine which table to use.
- */
- if (0)
- return dg2_dp_38_4_tables;
- else
- return dg2_dp_100_tables;
+ return dg2_dp_100_tables;
} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
return dg2_hdmi_tables;
}
@@ -775,6 +570,7 @@ intel_mpllb_tables_get(struct intel_crtc_state *crtc_state,
int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
struct intel_encoder *encoder)
{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
const struct intel_mpllb_state * const *tables;
int i;
@@ -786,8 +582,8 @@ int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
* until we have a proper algorithm under a valid
* license.
*/
- DRM_DEBUG_KMS("Can't support HDMI link rate %d\n",
- crtc_state->port_clock);
+ drm_dbg_kms(&i915->drm, "Can't support HDMI link rate %d\n",
+ crtc_state->port_clock);
return -EINVAL;
}
}
@@ -854,7 +650,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
* dp_mpllb_state interface signal.
*/
if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5))
- DRM_ERROR("Port %c PLL not locked\n", phy_name(phy));
+ drm_dbg_kms(&dev_priv->drm, "Port %c PLL not locked\n", phy_name(phy));
/*
* 11. If the frequency will result in a change to the voltage
@@ -867,8 +663,8 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
void intel_mpllb_disable(struct intel_encoder *encoder)
{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ enum phy phy = intel_port_to_phy(i915, encoder->port);
i915_reg_t enable_reg = (phy <= PHY_D ?
DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
@@ -881,21 +677,21 @@ void intel_mpllb_disable(struct intel_encoder *encoder)
*/
/* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */
- intel_uncore_rmw(&dev_priv->uncore, enable_reg, PLL_ENABLE, 0);
+ intel_uncore_rmw(&i915->uncore, enable_reg, PLL_ENABLE, 0);
/*
* 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0".
* This will allow the PLL to stop running.
*/
- intel_uncore_rmw(&dev_priv->uncore, SNPS_PHY_MPLLB_DIV(phy),
+ intel_uncore_rmw(&i915->uncore, SNPS_PHY_MPLLB_DIV(phy),
SNPS_PHY_MPLLB_FORCE_EN, 0);
/*
* 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment
* (dp_txX_ack) that the new transmitter setting request is completed.
*/
- if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_LOCK, 5))
- DRM_ERROR("Port %c PLL not locked\n", phy_name(phy));
+ if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 5))
+ drm_err(&i915->drm, "Port %c PLL not locked\n", phy_name(phy));
/*
* 6. If the frequency will result in a change to the voltage
diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy_regs.h b/drivers/gpu/drm/i915/display/intel_snps_phy_regs.h
new file mode 100644
index 000000000000..0543465aaf14
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy_regs.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __INTEL_SNPS_PHY_REGS__
+#define __INTEL_SNPS_PHY_REGS__
+
+#include "i915_reg_defs.h"
+
+#define _SNPS_PHY_A_BASE 0x168000
+#define _SNPS_PHY_B_BASE 0x169000
+#define _SNPS_PHY(phy) _PHY(phy, \
+ _SNPS_PHY_A_BASE, \
+ _SNPS_PHY_B_BASE)
+#define _SNPS2(phy, reg) (_SNPS_PHY(phy) - \
+ _SNPS_PHY_A_BASE + (reg))
+#define _MMIO_SNPS(phy, reg) _MMIO(_SNPS2(phy, reg))
+#define _MMIO_SNPS_LN(ln, phy, reg) _MMIO(_SNPS2(phy, \
+ (reg) + (ln) * 0x10))
+
+#define SNPS_PHY_MPLLB_CP(phy) _MMIO_SNPS(phy, 0x168000)
+#define SNPS_PHY_MPLLB_CP_INT REG_GENMASK(31, 25)
+#define SNPS_PHY_MPLLB_CP_INT_GS REG_GENMASK(23, 17)
+#define SNPS_PHY_MPLLB_CP_PROP REG_GENMASK(15, 9)
+#define SNPS_PHY_MPLLB_CP_PROP_GS REG_GENMASK(7, 1)
+
+#define SNPS_PHY_MPLLB_DIV(phy) _MMIO_SNPS(phy, 0x168004)
+#define SNPS_PHY_MPLLB_FORCE_EN REG_BIT(31)
+#define SNPS_PHY_MPLLB_DIV_CLK_EN REG_BIT(30)
+#define SNPS_PHY_MPLLB_DIV5_CLK_EN REG_BIT(29)
+#define SNPS_PHY_MPLLB_V2I REG_GENMASK(27, 26)
+#define SNPS_PHY_MPLLB_FREQ_VCO REG_GENMASK(25, 24)
+#define SNPS_PHY_MPLLB_DIV_MULTIPLIER REG_GENMASK(23, 16)
+#define SNPS_PHY_MPLLB_PMIX_EN REG_BIT(10)
+#define SNPS_PHY_MPLLB_DP2_MODE REG_BIT(9)
+#define SNPS_PHY_MPLLB_WORD_DIV2_EN REG_BIT(8)
+#define SNPS_PHY_MPLLB_TX_CLK_DIV REG_GENMASK(7, 5)
+#define SNPS_PHY_MPLLB_SHIM_DIV32_CLK_SEL REG_BIT(0)
+
+#define SNPS_PHY_MPLLB_FRACN1(phy) _MMIO_SNPS(phy, 0x168008)
+#define SNPS_PHY_MPLLB_FRACN_EN REG_BIT(31)
+#define SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN REG_BIT(30)
+#define SNPS_PHY_MPLLB_FRACN_DEN REG_GENMASK(15, 0)
+
+#define SNPS_PHY_MPLLB_FRACN2(phy) _MMIO_SNPS(phy, 0x16800C)
+#define SNPS_PHY_MPLLB_FRACN_REM REG_GENMASK(31, 16)
+#define SNPS_PHY_MPLLB_FRACN_QUOT REG_GENMASK(15, 0)
+
+#define SNPS_PHY_MPLLB_SSCEN(phy) _MMIO_SNPS(phy, 0x168014)
+#define SNPS_PHY_MPLLB_SSC_EN REG_BIT(31)
+#define SNPS_PHY_MPLLB_SSC_UP_SPREAD REG_BIT(30)
+#define SNPS_PHY_MPLLB_SSC_PEAK REG_GENMASK(29, 10)
+
+#define SNPS_PHY_MPLLB_SSCSTEP(phy) _MMIO_SNPS(phy, 0x168018)
+#define SNPS_PHY_MPLLB_SSC_STEPSIZE REG_GENMASK(31, 11)
+
+#define SNPS_PHY_MPLLB_DIV2(phy) _MMIO_SNPS(phy, 0x16801C)
+#define SNPS_PHY_MPLLB_HDMI_PIXEL_CLK_DIV REG_GENMASK(19, 18)
+#define SNPS_PHY_MPLLB_HDMI_DIV REG_GENMASK(17, 15)
+#define SNPS_PHY_MPLLB_REF_CLK_DIV REG_GENMASK(14, 12)
+#define SNPS_PHY_MPLLB_MULTIPLIER REG_GENMASK(11, 0)
+
+#define SNPS_PHY_REF_CONTROL(phy) _MMIO_SNPS(phy, 0x168188)
+#define SNPS_PHY_REF_CONTROL_REF_RANGE REG_GENMASK(31, 27)
+
+#define SNPS_PHY_TX_REQ(phy) _MMIO_SNPS(phy, 0x168200)
+#define SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR REG_GENMASK(31, 30)
+
+#define SNPS_PHY_TX_EQ(ln, phy) _MMIO_SNPS_LN(ln, phy, 0x168300)
+#define SNPS_PHY_TX_EQ_MAIN REG_GENMASK(23, 18)
+#define SNPS_PHY_TX_EQ_POST REG_GENMASK(15, 10)
+#define SNPS_PHY_TX_EQ_PRE REG_GENMASK(7, 2)
+
+#endif /* __INTEL_SNPS_PHY_REGS__ */
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 2357a1301f48..2d71294aaceb 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -53,6 +53,7 @@
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
{
+ struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src;
u32 src_x, src_y, src_w, src_h, hsub, vsub;
@@ -94,14 +95,14 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
hsub = vsub = max(hsub, vsub);
if (src_x % hsub || src_w % hsub) {
- DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
- src_x, src_w, hsub, yesno(rotated));
+ drm_dbg_kms(&i915->drm, "src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
+ src_x, src_w, hsub, yesno(rotated));
return -EINVAL;
}
if (src_y % vsub || src_h % vsub) {
- DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
- src_y, src_h, vsub, yesno(rotated));
+ drm_dbg_kms(&i915->drm, "src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
+ src_y, src_h, vsub, yesno(rotated));
return -EINVAL;
}
@@ -313,7 +314,7 @@ static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 sprctl = 0;
if (crtc_state->gamma_enable)
- sprctl |= SP_GAMMA_ENABLE;
+ sprctl |= SP_PIPE_GAMMA_ENABLE;
return sprctl;
}
@@ -436,9 +437,9 @@ vlv_sprite_update_noarm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
plane_state->view.color_plane[0].mapping_stride);
intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id),
- (crtc_y << 16) | crtc_x);
+ SP_POS_Y(crtc_y) | SP_POS_X(crtc_x));
intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
- ((crtc_h - 1) << 16) | (crtc_w - 1));
+ SP_HEIGHT(crtc_h - 1) | SP_WIDTH(crtc_w - 1));
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
@@ -479,7 +480,8 @@ vlv_sprite_update_arm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset);
- intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), (y << 16) | x);
+ intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id),
+ SP_OFFSET_Y(y) | SP_OFFSET_X(x));
/*
* The control register self-arms if the plane was previously
@@ -700,7 +702,7 @@ static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 sprctl = 0;
if (crtc_state->gamma_enable)
- sprctl |= SPRITE_GAMMA_ENABLE;
+ sprctl |= SPRITE_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
sprctl |= SPRITE_PIPE_CSC_ENABLE;
@@ -770,7 +772,7 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
}
if (!ivb_need_sprite_gamma(plane_state))
- sprctl |= SPRITE_INT_GAMMA_DISABLE;
+ sprctl |= SPRITE_PLANE_GAMMA_DISABLE;
if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
@@ -863,14 +865,18 @@ ivb_sprite_update_noarm(struct intel_plane *plane,
unsigned long irqflags;
if (crtc_w != src_w || crtc_h != src_h)
- sprscale = SPRITE_SCALE_ENABLE | ((src_w - 1) << 16) | (src_h - 1);
+ sprscale = SPRITE_SCALE_ENABLE |
+ SPRITE_SRC_WIDTH(src_w - 1) |
+ SPRITE_SRC_HEIGHT(src_h - 1);
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
plane_state->view.color_plane[0].mapping_stride);
- intel_de_write_fw(dev_priv, SPRPOS(pipe), (crtc_y << 16) | crtc_x);
- intel_de_write_fw(dev_priv, SPRSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1));
+ intel_de_write_fw(dev_priv, SPRPOS(pipe),
+ SPRITE_POS_Y(crtc_y) | SPRITE_POS_X(crtc_x));
+ intel_de_write_fw(dev_priv, SPRSIZE(pipe),
+ SPRITE_HEIGHT(crtc_h - 1) | SPRITE_WIDTH(crtc_w - 1));
if (IS_IVYBRIDGE(dev_priv))
intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
@@ -907,10 +913,12 @@ ivb_sprite_update_arm(struct intel_plane *plane,
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
* register */
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- intel_de_write_fw(dev_priv, SPROFFSET(pipe), (y << 16) | x);
+ intel_de_write_fw(dev_priv, SPROFFSET(pipe),
+ SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x));
} else {
intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset);
- intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), (y << 16) | x);
+ intel_de_write_fw(dev_priv, SPRTILEOFF(pipe),
+ SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x));
}
/*
@@ -1047,7 +1055,7 @@ static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 dvscntr = 0;
if (crtc_state->gamma_enable)
- dvscntr |= DVS_GAMMA_ENABLE;
+ dvscntr |= DVS_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
dvscntr |= DVS_PIPE_CSC_ENABLE;
@@ -1199,14 +1207,18 @@ g4x_sprite_update_noarm(struct intel_plane *plane,
unsigned long irqflags;
if (crtc_w != src_w || crtc_h != src_h)
- dvsscale = DVS_SCALE_ENABLE | ((src_w - 1) << 16) | (src_h - 1);
+ dvsscale = DVS_SCALE_ENABLE |
+ DVS_SRC_WIDTH(src_w - 1) |
+ DVS_SRC_HEIGHT(src_h - 1);
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
plane_state->view.color_plane[0].mapping_stride);
- intel_de_write_fw(dev_priv, DVSPOS(pipe), (crtc_y << 16) | crtc_x);
- intel_de_write_fw(dev_priv, DVSSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1));
+ intel_de_write_fw(dev_priv, DVSPOS(pipe),
+ DVS_POS_Y(crtc_y) | DVS_POS_X(crtc_x));
+ intel_de_write_fw(dev_priv, DVSSIZE(pipe),
+ DVS_HEIGHT(crtc_h - 1) | DVS_WIDTH(crtc_w - 1));
intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@@ -1321,6 +1333,7 @@ static int
g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
+ struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
const struct drm_rect *src = &plane_state->uapi.src;
const struct drm_rect *dst = &plane_state->uapi.dst;
@@ -1346,7 +1359,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
if (src_h & 1) {
- DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
+ drm_dbg_kms(&i915->drm, "Source height must be even with interlaced modes\n");
return -EINVAL;
}
min_height = 6;
@@ -1358,20 +1371,20 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
if (src_w < min_width || src_h < min_height ||
src_w > 2048 || src_h > 2048) {
- DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
- src_w, src_h, min_width, min_height, 2048, 2048);
+ drm_dbg_kms(&i915->drm, "Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
+ src_w, src_h, min_width, min_height, 2048, 2048);
return -EINVAL;
}
if (width_bytes > 4096) {
- DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
- width_bytes, 4096);
+ drm_dbg_kms(&i915->drm, "Fetch width (%d) exceeds hardware max with scaling (%u)\n",
+ width_bytes, 4096);
return -EINVAL;
}
if (stride > 4096) {
- DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
- stride, 4096);
+ drm_dbg_kms(&i915->drm, "Stride (%u) exceeds hardware max with scaling (%u)\n",
+ stride, 4096);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 40faa18947c9..fc037c027ea5 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -4,10 +4,12 @@
*/
#include "i915_drv.h"
+#include "i915_reg.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_dp_mst.h"
#include "intel_tc.h"
+#include "intel_tc_phy_regs.h"
static const char *tc_port_mode_name(enum tc_port_mode mode)
{
@@ -345,10 +347,11 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port)
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);
+ enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
struct intel_uncore *uncore = &i915->uncore;
u32 val;
- val = intel_uncore_read(uncore, TCSS_DDI_STATUS(dig_port->tc_phy_fia_idx));
+ val = intel_uncore_read(uncore, TCSS_DDI_STATUS(tc_port));
if (val == 0xffffffff) {
drm_dbg_kms(&i915->drm,
"Port %s: PHY in TCCOLD, assuming not complete\n",
@@ -690,6 +693,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_encoder *encoder = &dig_port->base;
+ intel_wakeref_t tc_cold_wref;
+ enum intel_display_power_domain domain;
int active_links = 0;
mutex_lock(&dig_port->tc_lock);
@@ -701,12 +706,11 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
- if (active_links) {
- enum intel_display_power_domain domain;
- intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port, &domain);
- dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
+ tc_cold_wref = tc_cold_block(dig_port, &domain);
+ dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
+ if (active_links) {
if (!icl_tc_phy_is_connected(dig_port))
drm_dbg_kms(&i915->drm,
"Port %s: PHY disconnected with %d active link(s)\n",
@@ -715,10 +719,23 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
dig_port->tc_lock_wakeref = tc_cold_block(dig_port,
&dig_port->tc_lock_power_domain);
-
- tc_cold_unblock(dig_port, domain, tc_cold_wref);
+ } else {
+ /*
+ * TBT-alt is the default mode in any case the PHY ownership is not
+ * held (regardless of the sink's connected live state), so
+ * we'll just switch to disconnected mode from it here without
+ * a note.
+ */
+ if (dig_port->tc_mode != TC_PORT_TBT_ALT)
+ drm_dbg_kms(&i915->drm,
+ "Port %s: PHY left in %s mode on disabled port, disconnecting it\n",
+ dig_port->tc_port_name,
+ tc_port_mode_name(dig_port->tc_mode));
+ icl_tc_phy_disconnect(dig_port);
}
+ tc_cold_unblock(dig_port, domain, tc_cold_wref);
+
drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
dig_port->tc_port_name,
tc_port_mode_name(dig_port->tc_mode));
diff --git a/drivers/gpu/drm/i915/display/intel_tc_phy_regs.h b/drivers/gpu/drm/i915/display/intel_tc_phy_regs.h
new file mode 100644
index 000000000000..5a545086f959
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_tc_phy_regs.h
@@ -0,0 +1,280 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __INTEL_TC_PHY_REGS__
+#define __INTEL_TC_PHY_REGS__
+
+#include "i915_reg_defs.h"
+
+#define MG_PHY_PORT_LN(ln, tc_port, ln0p1, ln0p2, ln1p1) \
+ _MMIO(_PORT(tc_port, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))
+
+#define MG_TX_LINK_PARAMS_TX1LN0_PORT1 0x16812C
+#define MG_TX_LINK_PARAMS_TX1LN1_PORT1 0x16852C
+#define MG_TX_LINK_PARAMS_TX1LN0_PORT2 0x16912C
+#define MG_TX_LINK_PARAMS_TX1LN1_PORT2 0x16952C
+#define MG_TX1_LINK_PARAMS(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_LINK_PARAMS_TX1LN0_PORT1, \
+ MG_TX_LINK_PARAMS_TX1LN0_PORT2, \
+ MG_TX_LINK_PARAMS_TX1LN1_PORT1)
+
+#define MG_TX_LINK_PARAMS_TX2LN0_PORT1 0x1680AC
+#define MG_TX_LINK_PARAMS_TX2LN1_PORT1 0x1684AC
+#define MG_TX_LINK_PARAMS_TX2LN0_PORT2 0x1690AC
+#define MG_TX_LINK_PARAMS_TX2LN1_PORT2 0x1694AC
+#define MG_TX2_LINK_PARAMS(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_LINK_PARAMS_TX2LN0_PORT1, \
+ MG_TX_LINK_PARAMS_TX2LN0_PORT2, \
+ MG_TX_LINK_PARAMS_TX2LN1_PORT1)
+#define CRI_USE_FS32 (1 << 5)
+
+#define MG_TX_PISO_READLOAD_TX1LN0_PORT1 0x16814C
+#define MG_TX_PISO_READLOAD_TX1LN1_PORT1 0x16854C
+#define MG_TX_PISO_READLOAD_TX1LN0_PORT2 0x16914C
+#define MG_TX_PISO_READLOAD_TX1LN1_PORT2 0x16954C
+#define MG_TX1_PISO_READLOAD(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_PISO_READLOAD_TX1LN0_PORT1, \
+ MG_TX_PISO_READLOAD_TX1LN0_PORT2, \
+ MG_TX_PISO_READLOAD_TX1LN1_PORT1)
+
+#define MG_TX_PISO_READLOAD_TX2LN0_PORT1 0x1680CC
+#define MG_TX_PISO_READLOAD_TX2LN1_PORT1 0x1684CC
+#define MG_TX_PISO_READLOAD_TX2LN0_PORT2 0x1690CC
+#define MG_TX_PISO_READLOAD_TX2LN1_PORT2 0x1694CC
+#define MG_TX2_PISO_READLOAD(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_PISO_READLOAD_TX2LN0_PORT1, \
+ MG_TX_PISO_READLOAD_TX2LN0_PORT2, \
+ MG_TX_PISO_READLOAD_TX2LN1_PORT1)
+#define CRI_CALCINIT (1 << 1)
+
+#define MG_TX_SWINGCTRL_TX1LN0_PORT1 0x168148
+#define MG_TX_SWINGCTRL_TX1LN1_PORT1 0x168548
+#define MG_TX_SWINGCTRL_TX1LN0_PORT2 0x169148
+#define MG_TX_SWINGCTRL_TX1LN1_PORT2 0x169548
+#define MG_TX1_SWINGCTRL(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_SWINGCTRL_TX1LN0_PORT1, \
+ MG_TX_SWINGCTRL_TX1LN0_PORT2, \
+ MG_TX_SWINGCTRL_TX1LN1_PORT1)
+
+#define MG_TX_SWINGCTRL_TX2LN0_PORT1 0x1680C8
+#define MG_TX_SWINGCTRL_TX2LN1_PORT1 0x1684C8
+#define MG_TX_SWINGCTRL_TX2LN0_PORT2 0x1690C8
+#define MG_TX_SWINGCTRL_TX2LN1_PORT2 0x1694C8
+#define MG_TX2_SWINGCTRL(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_SWINGCTRL_TX2LN0_PORT1, \
+ MG_TX_SWINGCTRL_TX2LN0_PORT2, \
+ MG_TX_SWINGCTRL_TX2LN1_PORT1)
+#define CRI_TXDEEMPH_OVERRIDE_17_12(x) ((x) << 0)
+#define CRI_TXDEEMPH_OVERRIDE_17_12_MASK (0x3F << 0)
+
+#define MG_TX_DRVCTRL_TX1LN0_TXPORT1 0x168144
+#define MG_TX_DRVCTRL_TX1LN1_TXPORT1 0x168544
+#define MG_TX_DRVCTRL_TX1LN0_TXPORT2 0x169144
+#define MG_TX_DRVCTRL_TX1LN1_TXPORT2 0x169544
+#define MG_TX_DRVCTRL_TX1LN0_TXPORT3 0x16A144
+#define MG_TX_DRVCTRL_TX1LN1_TXPORT3 0x16A544
+#define MG_TX_DRVCTRL_TX1LN0_TXPORT4 0x16B144
+#define MG_TX_DRVCTRL_TX1LN1_TXPORT4 0x16B544
+#define MG_TX1_DRVCTRL(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_DRVCTRL_TX1LN0_TXPORT1, \
+ MG_TX_DRVCTRL_TX1LN0_TXPORT2, \
+ MG_TX_DRVCTRL_TX1LN1_TXPORT1)
+
+#define MG_TX_DRVCTRL_TX2LN0_PORT1 0x1680C4
+#define MG_TX_DRVCTRL_TX2LN1_PORT1 0x1684C4
+#define MG_TX_DRVCTRL_TX2LN0_PORT2 0x1690C4
+#define MG_TX_DRVCTRL_TX2LN1_PORT2 0x1694C4
+#define MG_TX2_DRVCTRL(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_DRVCTRL_TX2LN0_PORT1, \
+ MG_TX_DRVCTRL_TX2LN0_PORT2, \
+ MG_TX_DRVCTRL_TX2LN1_PORT1)
+#define CRI_TXDEEMPH_OVERRIDE_11_6(x) ((x) << 24)
+#define CRI_TXDEEMPH_OVERRIDE_11_6_MASK (0x3F << 24)
+#define CRI_TXDEEMPH_OVERRIDE_EN (1 << 22)
+#define CRI_TXDEEMPH_OVERRIDE_5_0(x) ((x) << 16)
+#define CRI_TXDEEMPH_OVERRIDE_5_0_MASK (0x3F << 16)
+#define CRI_LOADGEN_SEL(x) ((x) << 12)
+#define CRI_LOADGEN_SEL_MASK (0x3 << 12)
+
+#define MG_CLKHUB_LN0_PORT1 0x16839C
+#define MG_CLKHUB_LN1_PORT1 0x16879C
+#define MG_CLKHUB_LN0_PORT2 0x16939C
+#define MG_CLKHUB_LN1_PORT2 0x16979C
+#define MG_CLKHUB(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_CLKHUB_LN0_PORT1, \
+ MG_CLKHUB_LN0_PORT2, \
+ MG_CLKHUB_LN1_PORT1)
+#define CFG_LOW_RATE_LKREN_EN (1 << 11)
+
+#define MG_TX_DCC_TX1LN0_PORT1 0x168110
+#define MG_TX_DCC_TX1LN1_PORT1 0x168510
+#define MG_TX_DCC_TX1LN0_PORT2 0x169110
+#define MG_TX_DCC_TX1LN1_PORT2 0x169510
+#define MG_TX1_DCC(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_DCC_TX1LN0_PORT1, \
+ MG_TX_DCC_TX1LN0_PORT2, \
+ MG_TX_DCC_TX1LN1_PORT1)
+#define MG_TX_DCC_TX2LN0_PORT1 0x168090
+#define MG_TX_DCC_TX2LN1_PORT1 0x168490
+#define MG_TX_DCC_TX2LN0_PORT2 0x169090
+#define MG_TX_DCC_TX2LN1_PORT2 0x169490
+#define MG_TX2_DCC(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_TX_DCC_TX2LN0_PORT1, \
+ MG_TX_DCC_TX2LN0_PORT2, \
+ MG_TX_DCC_TX2LN1_PORT1)
+#define CFG_AMI_CK_DIV_OVERRIDE_VAL(x) ((x) << 25)
+#define CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK (0x3 << 25)
+#define CFG_AMI_CK_DIV_OVERRIDE_EN (1 << 24)
+
+#define MG_DP_MODE_LN0_ACU_PORT1 0x1683A0
+#define MG_DP_MODE_LN1_ACU_PORT1 0x1687A0
+#define MG_DP_MODE_LN0_ACU_PORT2 0x1693A0
+#define MG_DP_MODE_LN1_ACU_PORT2 0x1697A0
+#define MG_DP_MODE(ln, tc_port) \
+ MG_PHY_PORT_LN(ln, tc_port, MG_DP_MODE_LN0_ACU_PORT1, \
+ MG_DP_MODE_LN0_ACU_PORT2, \
+ MG_DP_MODE_LN1_ACU_PORT1)
+#define MG_DP_MODE_CFG_DP_X2_MODE (1 << 7)
+#define MG_DP_MODE_CFG_DP_X1_MODE (1 << 6)
+
+#define FIA1_BASE 0x163000
+#define FIA2_BASE 0x16E000
+#define FIA3_BASE 0x16F000
+#define _FIA(fia) _PICK((fia), FIA1_BASE, FIA2_BASE, FIA3_BASE)
+#define _MMIO_FIA(fia, off) _MMIO(_FIA(fia) + (off))
+
+/* ICL PHY DFLEX registers */
+#define PORT_TX_DFLEXDPMLE1(fia) _MMIO_FIA((fia), 0x008C0)
+#define DFLEXDPMLE1_DPMLETC_MASK(idx) (0xf << (4 * (idx)))
+#define DFLEXDPMLE1_DPMLETC_ML0(idx) (1 << (4 * (idx)))
+#define DFLEXDPMLE1_DPMLETC_ML1_0(idx) (3 << (4 * (idx)))
+#define DFLEXDPMLE1_DPMLETC_ML3(idx) (8 << (4 * (idx)))
+#define DFLEXDPMLE1_DPMLETC_ML3_2(idx) (12 << (4 * (idx)))
+#define DFLEXDPMLE1_DPMLETC_ML3_0(idx) (15 << (4 * (idx)))
+
+#define _MG_REFCLKIN_CTL_PORT1 0x16892C
+#define _MG_REFCLKIN_CTL_PORT2 0x16992C
+#define MG_REFCLKIN_CTL_OD_2_MUX(x) ((x) << 8)
+#define MG_REFCLKIN_CTL_OD_2_MUX_MASK (0x7 << 8)
+#define MG_REFCLKIN_CTL(tc_port) _MMIO_PORT((tc_port), \
+ _MG_REFCLKIN_CTL_PORT1, \
+ _MG_REFCLKIN_CTL_PORT2)
+
+#define _MG_CLKTOP2_CORECLKCTL1_PORT1 0x1688D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT2 0x1698D8
+#define MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x) ((x) << 16)
+#define MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO_MASK (0xff << 16)
+#define MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x) ((x) << 8)
+#define MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK (0xff << 8)
+#define MG_CLKTOP2_CORECLKCTL1(tc_port) _MMIO_PORT((tc_port), \
+ _MG_CLKTOP2_CORECLKCTL1_PORT1, \
+ _MG_CLKTOP2_CORECLKCTL1_PORT2)
+
+#define _MG_CLKTOP2_HSCLKCTL_PORT1 0x1688D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT2 0x1698D4
+#define MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x) ((x) << 16)
+#define MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK (0x1 << 16)
+#define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x) ((x) << 14)
+#define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK (0x3 << 14)
+#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK (0x3 << 12)
+#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2 (0 << 12)
+#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3 (1 << 12)
+#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5 (2 << 12)
+#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7 (3 << 12)
+#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x) ((x) << 8)
+#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT 8
+#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK (0xf << 8)
+#define MG_CLKTOP2_HSCLKCTL(tc_port) _MMIO_PORT((tc_port), \
+ _MG_CLKTOP2_HSCLKCTL_PORT1, \
+ _MG_CLKTOP2_HSCLKCTL_PORT2)
+
+#define _MG_PLL_DIV0_PORT1 0x168A00
+#define _MG_PLL_DIV0_PORT2 0x169A00
+#define MG_PLL_DIV0_FRACNEN_H (1 << 30)
+#define MG_PLL_DIV0_FBDIV_FRAC_MASK (0x3fffff << 8)
+#define MG_PLL_DIV0_FBDIV_FRAC_SHIFT 8
+#define MG_PLL_DIV0_FBDIV_FRAC(x) ((x) << 8)
+#define MG_PLL_DIV0_FBDIV_INT_MASK (0xff << 0)
+#define MG_PLL_DIV0_FBDIV_INT(x) ((x) << 0)
+#define MG_PLL_DIV0(tc_port) _MMIO_PORT((tc_port), _MG_PLL_DIV0_PORT1, \
+ _MG_PLL_DIV0_PORT2)
+
+#define _MG_PLL_DIV1_PORT1 0x168A04
+#define _MG_PLL_DIV1_PORT2 0x169A04
+#define MG_PLL_DIV1_IREF_NDIVRATIO(x) ((x) << 16)
+#define MG_PLL_DIV1_DITHER_DIV_1 (0 << 12)
+#define MG_PLL_DIV1_DITHER_DIV_2 (1 << 12)
+#define MG_PLL_DIV1_DITHER_DIV_4 (2 << 12)
+#define MG_PLL_DIV1_DITHER_DIV_8 (3 << 12)
+#define MG_PLL_DIV1_NDIVRATIO(x) ((x) << 4)
+#define MG_PLL_DIV1_FBPREDIV_MASK (0xf << 0)
+#define MG_PLL_DIV1_FBPREDIV(x) ((x) << 0)
+#define MG_PLL_DIV1(tc_port) _MMIO_PORT((tc_port), _MG_PLL_DIV1_PORT1, \
+ _MG_PLL_DIV1_PORT2)
+
+#define _MG_PLL_LF_PORT1 0x168A08
+#define _MG_PLL_LF_PORT2 0x169A08
+#define MG_PLL_LF_TDCTARGETCNT(x) ((x) << 24)
+#define MG_PLL_LF_AFCCNTSEL_256 (0 << 20)
+#define MG_PLL_LF_AFCCNTSEL_512 (1 << 20)
+#define MG_PLL_LF_GAINCTRL(x) ((x) << 16)
+#define MG_PLL_LF_INT_COEFF(x) ((x) << 8)
+#define MG_PLL_LF_PROP_COEFF(x) ((x) << 0)
+#define MG_PLL_LF(tc_port) _MMIO_PORT((tc_port), _MG_PLL_LF_PORT1, \
+ _MG_PLL_LF_PORT2)
+
+#define _MG_PLL_FRAC_LOCK_PORT1 0x168A0C
+#define _MG_PLL_FRAC_LOCK_PORT2 0x169A0C
+#define MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 (1 << 18)
+#define MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 (1 << 16)
+#define MG_PLL_FRAC_LOCK_LOCKTHRESH(x) ((x) << 11)
+#define MG_PLL_FRAC_LOCK_DCODITHEREN (1 << 10)
+#define MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN (1 << 8)
+#define MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x) ((x) << 0)
+#define MG_PLL_FRAC_LOCK(tc_port) _MMIO_PORT((tc_port), \
+ _MG_PLL_FRAC_LOCK_PORT1, \
+ _MG_PLL_FRAC_LOCK_PORT2)
+
+#define _MG_PLL_SSC_PORT1 0x168A10
+#define _MG_PLL_SSC_PORT2 0x169A10
+#define MG_PLL_SSC_EN (1 << 28)
+#define MG_PLL_SSC_TYPE(x) ((x) << 26)
+#define MG_PLL_SSC_STEPLENGTH(x) ((x) << 16)
+#define MG_PLL_SSC_STEPNUM(x) ((x) << 10)
+#define MG_PLL_SSC_FLLEN (1 << 9)
+#define MG_PLL_SSC_STEPSIZE(x) ((x) << 0)
+#define MG_PLL_SSC(tc_port) _MMIO_PORT((tc_port), _MG_PLL_SSC_PORT1, \
+ _MG_PLL_SSC_PORT2)
+
+#define _MG_PLL_BIAS_PORT1 0x168A14
+#define _MG_PLL_BIAS_PORT2 0x169A14
+#define MG_PLL_BIAS_BIAS_GB_SEL(x) ((x) << 30)
+#define MG_PLL_BIAS_BIAS_GB_SEL_MASK (0x3 << 30)
+#define MG_PLL_BIAS_INIT_DCOAMP(x) ((x) << 24)
+#define MG_PLL_BIAS_INIT_DCOAMP_MASK (0x3f << 24)
+#define MG_PLL_BIAS_BIAS_BONUS(x) ((x) << 16)
+#define MG_PLL_BIAS_BIAS_BONUS_MASK (0xff << 16)
+#define MG_PLL_BIAS_BIASCAL_EN (1 << 15)
+#define MG_PLL_BIAS_CTRIM(x) ((x) << 8)
+#define MG_PLL_BIAS_CTRIM_MASK (0x1f << 8)
+#define MG_PLL_BIAS_VREF_RDAC(x) ((x) << 5)
+#define MG_PLL_BIAS_VREF_RDAC_MASK (0x7 << 5)
+#define MG_PLL_BIAS_IREFTRIM(x) ((x) << 0)
+#define MG_PLL_BIAS_IREFTRIM_MASK (0x1f << 0)
+#define MG_PLL_BIAS(tc_port) _MMIO_PORT((tc_port), _MG_PLL_BIAS_PORT1, \
+ _MG_PLL_BIAS_PORT2)
+
+#define _MG_PLL_TDC_COLDST_BIAS_PORT1 0x168A18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT2 0x169A18
+#define MG_PLL_TDC_COLDST_IREFINT_EN (1 << 27)
+#define MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x) ((x) << 17)
+#define MG_PLL_TDC_COLDST_COLDSTART (1 << 16)
+#define MG_PLL_TDC_TDCOVCCORR_EN (1 << 2)
+#define MG_PLL_TDC_TDCSEL(x) ((x) << 0)
+#define MG_PLL_TDC_COLDST_BIAS(tc_port) _MMIO_PORT((tc_port), \
+ _MG_PLL_TDC_COLDST_BIAS_PORT1, \
+ _MG_PLL_TDC_COLDST_BIAS_PORT2)
+
+#endif /* __INTEL_TC_PHY_REGS__ */
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index f043d85ba64d..b9397d9363c5 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -162,6 +162,14 @@ struct bdb_general_features {
u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */
u8 dp_ssc_dongle_supported:1;
u8 rsvd11:2; /* finish byte */
+
+ /* bits 6 */
+ u8 tc_hpd_retry_timeout:7; /* 242 */
+ u8 rsvd12:1;
+
+ /* bits 7 */
+ u8 afc_startup_config:2;/* 249 */
+ u8 rsvd13:6;
} __packed;
/*
@@ -226,32 +234,6 @@ struct bdb_general_features {
#define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1)
#define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0)
-/*
- * Bits we care about when checking for DEVICE_TYPE_eDP. Depending on the
- * system, the other bits may or may not be set for eDP outputs.
- */
-#define DEVICE_TYPE_eDP_BITS \
- (DEVICE_TYPE_INTERNAL_CONNECTOR | \
- DEVICE_TYPE_MIPI_OUTPUT | \
- DEVICE_TYPE_COMPOSITE_OUTPUT | \
- DEVICE_TYPE_DUAL_CHANNEL | \
- DEVICE_TYPE_LVDS_SIGNALING | \
- DEVICE_TYPE_TMDS_DVI_SIGNALING | \
- DEVICE_TYPE_VIDEO_SIGNALING | \
- DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
- DEVICE_TYPE_ANALOG_OUTPUT)
-
-#define DEVICE_TYPE_DP_DUAL_MODE_BITS \
- (DEVICE_TYPE_INTERNAL_CONNECTOR | \
- DEVICE_TYPE_MIPI_OUTPUT | \
- DEVICE_TYPE_COMPOSITE_OUTPUT | \
- DEVICE_TYPE_LVDS_SIGNALING | \
- DEVICE_TYPE_TMDS_DVI_SIGNALING | \
- DEVICE_TYPE_VIDEO_SIGNALING | \
- DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
- DEVICE_TYPE_DIGITAL_OUTPUT | \
- DEVICE_TYPE_ANALOG_OUTPUT)
-
#define DEVICE_CFG_NONE 0x00
#define DEVICE_CFG_12BIT_DVOB 0x01
#define DEVICE_CFG_12BIT_DVOC 0x02
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 9b05f93ed8bc..545eff5bf158 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -341,19 +341,14 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- enum pipe pipe = crtc->pipe;
if (!INTEL_INFO(i915)->display.has_dsc)
return false;
- /* On TGL, DSC is supported on all Pipes */
if (DISPLAY_VER(i915) >= 12)
return true;
- if (DISPLAY_VER(i915) >= 11 &&
- (pipe != PIPE_A || cpu_transcoder == TRANSCODER_EDP ||
- cpu_transcoder == TRANSCODER_DSI_0 ||
- cpu_transcoder == TRANSCODER_DSI_1))
+ if (DISPLAY_VER(i915) >= 11 && cpu_transcoder != TRANSCODER_A)
return true;
return false;
@@ -1112,18 +1107,6 @@ static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_tran
ICL_PIPE_DSS_CTL2(crtc->pipe) : DSS_CTL2;
}
-struct intel_crtc *
-intel_dsc_get_bigjoiner_secondary(const struct intel_crtc *primary_crtc)
-{
- return intel_crtc_for_pipe(to_i915(primary_crtc->base.dev), primary_crtc->pipe + 1);
-}
-
-static struct intel_crtc *
-intel_dsc_get_bigjoiner_primary(const struct intel_crtc *secondary_crtc)
-{
- return intel_crtc_for_pipe(to_i915(secondary_crtc->base.dev), secondary_crtc->pipe - 1);
-}
-
void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -1131,7 +1114,7 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
u32 dss_ctl1_val = 0;
if (crtc_state->bigjoiner && !crtc_state->dsc.compression_enable) {
- if (crtc_state->bigjoiner_slave)
+ if (intel_crtc_is_bigjoiner_slave(crtc_state))
dss_ctl1_val |= UNCOMPRESSED_JOINER_SLAVE;
else
dss_ctl1_val |= UNCOMPRESSED_JOINER_MASTER;
@@ -1159,7 +1142,7 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
}
if (crtc_state->bigjoiner) {
dss_ctl1_val |= BIG_JOINER_ENABLE;
- if (!crtc_state->bigjoiner_slave)
+ if (!intel_crtc_is_bigjoiner_slave(crtc_state))
dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
}
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
@@ -1179,25 +1162,6 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
}
}
-void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- u32 dss_ctl1;
-
- dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder));
- if (dss_ctl1 & UNCOMPRESSED_JOINER_MASTER) {
- crtc_state->bigjoiner = true;
- crtc_state->bigjoiner_linked_crtc = intel_dsc_get_bigjoiner_secondary(crtc);
- drm_WARN_ON(&dev_priv->drm, !crtc_state->bigjoiner_linked_crtc);
- } else if (dss_ctl1 & UNCOMPRESSED_JOINER_SLAVE) {
- crtc_state->bigjoiner = true;
- crtc_state->bigjoiner_slave = true;
- crtc_state->bigjoiner_linked_crtc = intel_dsc_get_bigjoiner_primary(crtc);
- drm_WARN_ON(&dev_priv->drm, !crtc_state->bigjoiner_linked_crtc);
- }
-}
-
void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -1228,18 +1192,6 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
(dss_ctl1 & JOINER_ENABLE);
- if (dss_ctl1 & BIG_JOINER_ENABLE) {
- crtc_state->bigjoiner = true;
-
- if (!(dss_ctl1 & MASTER_BIG_JOINER_ENABLE)) {
- crtc_state->bigjoiner_slave = true;
- crtc_state->bigjoiner_linked_crtc = intel_dsc_get_bigjoiner_primary(crtc);
- } else {
- crtc_state->bigjoiner_linked_crtc = intel_dsc_get_bigjoiner_secondary(crtc);
- }
- drm_WARN_ON(&dev_priv->drm, !crtc_state->bigjoiner_linked_crtc);
- }
-
/* FIXME: add more state readout as needed */
/* PPS1 */
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 4ec75f715986..8763f00fa7e2 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -18,7 +18,6 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
void intel_dsc_enable(const struct intel_crtc_state *crtc_state);
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
int intel_dsc_compute_params(struct intel_crtc_state *pipe_config);
-void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state);
void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
enum intel_display_power_domain
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder);
diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
index fa779f7ea415..b5d058404c14 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -7,6 +7,7 @@
#include <linux/vgaarb.h>
#include <drm/i915_drm.h>
+#include <video/vga.h>
#include "i915_drv.h"
#include "intel_de.h"
@@ -34,9 +35,9 @@ void intel_vga_disable(struct drm_i915_private *dev_priv)
/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
- outb(SR01, VGA_SR_INDEX);
- sr1 = inb(VGA_SR_DATA);
- outb(sr1 | 1 << 5, VGA_SR_DATA);
+ outb(0x01, VGA_SEQ_I);
+ sr1 = inb(VGA_SEQ_D);
+ outb(sr1 | VGA_SR01_SCREEN_OFF, VGA_SEQ_D);
vga_put(pdev, VGA_RSRC_LEGACY_IO);
udelay(300);
@@ -92,7 +93,7 @@ void intel_vga_reset_io_mem(struct drm_i915_private *i915)
* and error messages.
*/
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
- outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
+ outb(inb(VGA_MIS_R), VGA_MIS_W);
vga_put(pdev, VGA_RSRC_LEGACY_IO);
}
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 93a385396512..1223075595ff 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -961,6 +961,7 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
static u32 skl_surf_address(const struct intel_plane_state *plane_state,
int color_plane)
{
+ struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
u32 offset = plane_state->view.color_plane[color_plane].offset;
@@ -969,11 +970,11 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state,
* The DPT object contains only one vma, so the VMA's offset
* within the DPT is always 0.
*/
- WARN_ON(plane_state->dpt_vma->node.start);
- WARN_ON(offset & 0x1fffff);
+ drm_WARN_ON(&i915->drm, plane_state->dpt_vma->node.start);
+ drm_WARN_ON(&i915->drm, offset & 0x1fffff);
return offset >> 9;
} else {
- WARN_ON(offset & 0xfff);
+ drm_WARN_ON(&i915->drm, offset & 0xfff);
return offset;
}
}
@@ -992,6 +993,54 @@ static u32 skl_plane_surf(const struct intel_plane_state *plane_state,
return plane_surf;
}
+static u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state,
+ int color_plane)
+{
+ struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
+ int aux_plane = skl_main_to_aux_plane(fb, color_plane);
+ u32 aux_dist;
+
+ if (!aux_plane)
+ return 0;
+
+ aux_dist = skl_surf_address(plane_state, aux_plane) -
+ skl_surf_address(plane_state, color_plane);
+
+ if (DISPLAY_VER(i915) < 12)
+ aux_dist |= PLANE_AUX_STRIDE(skl_plane_stride(plane_state, aux_plane));
+
+ return aux_dist;
+}
+
+static u32 skl_plane_keyval(const struct intel_plane_state *plane_state)
+{
+ const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+
+ return key->min_value;
+}
+
+static u32 skl_plane_keymax(const struct intel_plane_state *plane_state)
+{
+ const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+ u8 alpha = plane_state->hw.alpha >> 8;
+
+ return (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
+}
+
+static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state)
+{
+ const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+ u8 alpha = plane_state->hw.alpha >> 8;
+ u32 keymsk;
+
+ keymsk = key->channel_mask & 0x7ffffff;
+ if (alpha < 0xff)
+ keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
+
+ return keymsk;
+}
+
static void icl_plane_csc_load_black(struct intel_plane *plane)
{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
@@ -1016,15 +1065,24 @@ static void icl_plane_csc_load_black(struct intel_plane *plane)
intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
}
+static int skl_plane_color_plane(const struct intel_plane_state *plane_state)
+{
+ /* Program the UV plane on planar master */
+ if (plane_state->planar_linked_plane && !plane_state->planar_slave)
+ return 1;
+ else
+ return 0;
+}
+
static void
-skl_program_plane_noarm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state,
- int color_plane)
+skl_plane_update_noarm(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
+ int color_plane = skl_plane_color_plane(plane_state);
u32 stride = skl_plane_stride(plane_state, color_plane);
const struct drm_framebuffer *fb = plane_state->hw.fb;
int crtc_x = plane_state->uapi.dst.x1;
@@ -1048,11 +1106,12 @@ skl_program_plane_noarm(struct intel_plane *plane,
if (plane_state->force_black)
icl_plane_csc_load_black(plane);
- intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride);
+ intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
+ PLANE_STRIDE_(stride));
intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
- (crtc_y << 16) | crtc_x);
+ PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
- ((src_h - 1) << 16) | (src_w - 1));
+ PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
@@ -1076,21 +1135,17 @@ skl_program_plane_noarm(struct intel_plane *plane,
}
static void
-skl_program_plane_arm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state,
- int color_plane)
+skl_plane_update_arm(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
- const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
- const struct drm_framebuffer *fb = plane_state->hw.fb;
- int aux_plane = skl_main_to_aux_plane(fb, color_plane);
+ int color_plane = skl_plane_color_plane(plane_state);
u32 x = plane_state->view.color_plane[color_plane].x;
u32 y = plane_state->view.color_plane[color_plane].y;
- u32 keymsk, keymax, aux_dist = 0, plane_color_ctl = 0;
- u8 alpha = plane_state->hw.alpha >> 8;
+ u32 plane_color_ctl = 0;
u32 plane_ctl = plane_state->ctl;
unsigned long irqflags;
@@ -1100,36 +1155,22 @@ skl_program_plane_arm(struct intel_plane *plane,
plane_color_ctl = plane_state->color_ctl |
glk_plane_color_ctl_crtc(crtc_state);
- keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
-
- keymsk = key->channel_mask & 0x7ffffff;
- if (alpha < 0xff)
- keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
-
- if (aux_plane) {
- aux_dist = skl_surf_address(plane_state, aux_plane) -
- skl_surf_address(plane_state, color_plane);
-
- if (DISPLAY_VER(dev_priv) < 12)
- aux_dist |= skl_plane_stride(plane_state, aux_plane);
- }
-
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id),
- key->min_value);
- intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk);
- intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
+ intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
+ intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
+ intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
- (y << 16) | x);
+ PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
- intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
+ intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
+ skl_plane_aux_dist(plane_state, color_plane));
if (DISPLAY_VER(dev_priv) < 11)
intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
- (plane_state->view.color_plane[1].y << 16) |
- plane_state->view.color_plane[1].x);
+ PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
+ PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
if (DISPLAY_VER(dev_priv) >= 10)
intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
@@ -1182,34 +1223,6 @@ skl_plane_async_flip(struct intel_plane *plane,
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-static void
-skl_plane_update_noarm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state)
-{
- int color_plane = 0;
-
- if (plane_state->planar_linked_plane && !plane_state->planar_slave)
- /* Program the UV plane on planar master */
- color_plane = 1;
-
- skl_program_plane_noarm(plane, crtc_state, plane_state, color_plane);
-}
-
-static void
-skl_plane_update_arm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state)
-{
- int color_plane = 0;
-
- if (plane_state->planar_linked_plane && !plane_state->planar_slave)
- /* Program the UV plane on planar master */
- color_plane = 1;
-
- skl_program_plane_arm(plane, crtc_state, plane_state, color_plane);
-}
-
static bool intel_format_is_p01x(u32 format)
{
switch (format) {
@@ -1338,6 +1351,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
{
+ struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int rotation = plane_state->hw.rotation;
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
@@ -1347,7 +1361,7 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s
src_w & 3 &&
(rotation == DRM_MODE_ROTATE_270 ||
rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
- DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
+ drm_dbg_kms(&i915->drm, "src width must be multiple of 4 for rotated planar YUV\n");
return -EINVAL;
}
@@ -1816,20 +1830,27 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
return 0;
}
+static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
+{
+ return pipe - PIPE_A + INTEL_FBC_A;
+}
+
static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
- enum pipe pipe, enum plane_id plane_id)
+ enum intel_fbc_id fbc_id, enum plane_id plane_id)
{
- if (!HAS_FBC(dev_priv))
+ if ((INTEL_INFO(dev_priv)->display.fbc_mask & BIT(fbc_id)) == 0)
return false;
- return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
+ return plane_id == PLANE_PRIMARY;
}
static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
enum pipe pipe, enum plane_id plane_id)
{
- if (skl_plane_has_fbc(dev_priv, pipe, plane_id))
- return dev_priv->fbc;
+ enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
+
+ if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
+ return dev_priv->fbc[fbc_id];
else
return NULL;
}
@@ -2282,16 +2303,17 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
if (DISPLAY_VER(dev_priv) >= 11)
- pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK;
+ pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL;
else
- pixel_format = val & PLANE_CTL_FORMAT_MASK;
+ pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL;
if (DISPLAY_VER(dev_priv) >= 10) {
- alpha = intel_de_read(dev_priv,
- PLANE_COLOR_CTL(pipe, plane_id));
- alpha &= PLANE_COLOR_ALPHA_MASK;
+ u32 color_ctl;
+
+ color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
+ alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl);
} else {
- alpha = val & PLANE_CTL_ALPHA_MASK;
+ alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val);
}
fourcc = skl_format_to_fourcc(pixel_format,
@@ -2355,22 +2377,19 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
if (drm_rotation_90_or_270(plane_config->rotation))
goto error;
- base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000;
+ base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK;
plane_config->base = base;
offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
- fb->height = ((val >> 16) & 0xffff) + 1;
- fb->width = ((val >> 0) & 0xffff) + 1;
+ fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1;
+ fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1;
val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
- if (DISPLAY_VER(dev_priv) >= 13)
- fb->pitches[0] = (val & PLANE_STRIDE_MASK_XELPD) * stride_mult;
- else
- fb->pitches[0] = (val & PLANE_STRIDE_MASK) * stride_mult;
+ fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult;
aligned_height = intel_fb_align_height(fb, 0, fb->height);
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 20141f33ed64..0d936f658b3f 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -44,6 +44,7 @@
#include "skl_scaler.h"
#include "vlv_dsi.h"
#include "vlv_dsi_pll.h"
+#include "vlv_dsi_regs.h"
#include "vlv_sideband.h"
/* return pixels in terms of txbyteclkhs */
@@ -1492,7 +1493,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
*/
if (is_vid_mode(intel_dsi) &&
- intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
+ intel_dsi->video_mode == BURST_MODE) {
intel_de_write(dev_priv, MIPI_HS_TX_TIMEOUT(port),
txbyteclkhs(adjusted_mode->crtc_htotal, bpp, intel_dsi->lane_count, intel_dsi->burst_mode_ratio) + 1);
} else {
@@ -1568,12 +1569,33 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
intel_de_write(dev_priv, MIPI_CLK_LANE_SWITCH_TIME_CNT(port),
intel_dsi->clk_lp_to_hs_count << LP_HS_SSW_CNT_SHIFT | intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
- if (is_vid_mode(intel_dsi))
- /* Some panels might have resolution which is not a
+ if (is_vid_mode(intel_dsi)) {
+ u32 fmt = intel_dsi->video_frmt_cfg_bits | IP_TG_CONFIG;
+
+ /*
+ * Some panels might have resolution which is not a
* multiple of 64 like 1366 x 768. Enable RANDOM
- * resolution support for such panels by default */
- intel_de_write(dev_priv, MIPI_VIDEO_MODE_FORMAT(port),
- intel_dsi->video_frmt_cfg_bits | intel_dsi->video_mode_format | IP_TG_CONFIG | RANDOM_DPI_DISPLAY_RESOLUTION);
+ * resolution support for such panels by default.
+ */
+ fmt |= RANDOM_DPI_DISPLAY_RESOLUTION;
+
+ switch (intel_dsi->video_mode) {
+ default:
+ MISSING_CASE(intel_dsi->video_mode);
+ fallthrough;
+ case NON_BURST_SYNC_EVENTS:
+ fmt |= VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS;
+ break;
+ case NON_BURST_SYNC_PULSE:
+ fmt |= VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE;
+ break;
+ case BURST_MODE:
+ fmt |= VIDEO_MODE_BURST;
+ break;
+ }
+
+ intel_de_write(dev_priv, MIPI_VIDEO_MODE_FORMAT(port), fmt);
+ }
}
}
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c
index 1b81797dd02e..df880f44700a 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c
@@ -32,6 +32,7 @@
#include "intel_display_types.h"
#include "intel_dsi.h"
#include "vlv_dsi_pll.h"
+#include "vlv_dsi_pll_regs.h"
#include "vlv_sideband.h"
static const u16 lfsr_converts[] = {
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll_regs.h b/drivers/gpu/drm/i915/display/vlv_dsi_pll_regs.h
new file mode 100644
index 000000000000..45590e14e54b
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll_regs.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __VLV_DSI_PLL_REGS_H__
+#define __VLV_DSI_PLL_REGS_H__
+
+#include "vlv_dsi_regs.h"
+
+#define MIPIO_TXESC_CLK_DIV1 _MMIO(0x160004)
+#define GLK_TX_ESC_CLK_DIV1_MASK 0x3FF
+#define MIPIO_TXESC_CLK_DIV2 _MMIO(0x160008)
+#define GLK_TX_ESC_CLK_DIV2_MASK 0x3FF
+
+#define BXT_MAX_VAR_OUTPUT_KHZ 39500
+
+#define BXT_MIPI_CLOCK_CTL _MMIO(0x46090)
+#define BXT_MIPI1_DIV_SHIFT 26
+#define BXT_MIPI2_DIV_SHIFT 10
+#define BXT_MIPI_DIV_SHIFT(port) \
+ _MIPI_PORT(port, BXT_MIPI1_DIV_SHIFT, \
+ BXT_MIPI2_DIV_SHIFT)
+
+/* TX control divider to select actual TX clock output from (8x/var) */
+#define BXT_MIPI1_TX_ESCLK_SHIFT 26
+#define BXT_MIPI2_TX_ESCLK_SHIFT 10
+#define BXT_MIPI_TX_ESCLK_SHIFT(port) \
+ _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_SHIFT, \
+ BXT_MIPI2_TX_ESCLK_SHIFT)
+#define BXT_MIPI1_TX_ESCLK_FIXDIV_MASK (0x3F << 26)
+#define BXT_MIPI2_TX_ESCLK_FIXDIV_MASK (0x3F << 10)
+#define BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port) \
+ _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_FIXDIV_MASK, \
+ BXT_MIPI2_TX_ESCLK_FIXDIV_MASK)
+#define BXT_MIPI_TX_ESCLK_DIVIDER(port, val) \
+ (((val) & 0x3F) << BXT_MIPI_TX_ESCLK_SHIFT(port))
+/* RX upper control divider to select actual RX clock output from 8x */
+#define BXT_MIPI1_RX_ESCLK_UPPER_SHIFT 21
+#define BXT_MIPI2_RX_ESCLK_UPPER_SHIFT 5
+#define BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port) \
+ _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_SHIFT, \
+ BXT_MIPI2_RX_ESCLK_UPPER_SHIFT)
+#define BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK (3 << 21)
+#define BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK (3 << 5)
+#define BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port) \
+ _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_UPPER_FIXDIV_MASK, \
+ BXT_MIPI2_RX_ESCLK_UPPER_FIXDIV_MASK)
+#define BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, val) \
+ (((val) & 3) << BXT_MIPI_RX_ESCLK_UPPER_SHIFT(port))
+/* 8/3X divider to select the actual 8/3X clock output from 8x */
+#define BXT_MIPI1_8X_BY3_SHIFT 19
+#define BXT_MIPI2_8X_BY3_SHIFT 3
+#define BXT_MIPI_8X_BY3_SHIFT(port) \
+ _MIPI_PORT(port, BXT_MIPI1_8X_BY3_SHIFT, \
+ BXT_MIPI2_8X_BY3_SHIFT)
+#define BXT_MIPI1_8X_BY3_DIVIDER_MASK (3 << 19)
+#define BXT_MIPI2_8X_BY3_DIVIDER_MASK (3 << 3)
+#define BXT_MIPI_8X_BY3_DIVIDER_MASK(port) \
+ _MIPI_PORT(port, BXT_MIPI1_8X_BY3_DIVIDER_MASK, \
+ BXT_MIPI2_8X_BY3_DIVIDER_MASK)
+#define BXT_MIPI_8X_BY3_DIVIDER(port, val) \
+ (((val) & 3) << BXT_MIPI_8X_BY3_SHIFT(port))
+/* RX lower control divider to select actual RX clock output from 8x */
+#define BXT_MIPI1_RX_ESCLK_LOWER_SHIFT 16
+#define BXT_MIPI2_RX_ESCLK_LOWER_SHIFT 0
+#define BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port) \
+ _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_SHIFT, \
+ BXT_MIPI2_RX_ESCLK_LOWER_SHIFT)
+#define BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK (3 << 16)
+#define BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK (3 << 0)
+#define BXT_MIPI_RX_ESCLK_LOWER_FIXDIV_MASK(port) \
+ _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_LOWER_FIXDIV_MASK, \
+ BXT_MIPI2_RX_ESCLK_LOWER_FIXDIV_MASK)
+#define BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, val) \
+ (((val) & 3) << BXT_MIPI_RX_ESCLK_LOWER_SHIFT(port))
+
+#define RX_DIVIDER_BIT_1_2 0x3
+#define RX_DIVIDER_BIT_3_4 0xC
+
+#define BXT_DSI_PLL_CTL _MMIO(0x161000)
+#define BXT_DSI_PLL_PVD_RATIO_SHIFT 16
+#define BXT_DSI_PLL_PVD_RATIO_MASK (3 << BXT_DSI_PLL_PVD_RATIO_SHIFT)
+#define BXT_DSI_PLL_PVD_RATIO_1 (1 << BXT_DSI_PLL_PVD_RATIO_SHIFT)
+#define BXT_DSIC_16X_BY1 (0 << 10)
+#define BXT_DSIC_16X_BY2 (1 << 10)
+#define BXT_DSIC_16X_BY3 (2 << 10)
+#define BXT_DSIC_16X_BY4 (3 << 10)
+#define BXT_DSIC_16X_MASK (3 << 10)
+#define BXT_DSIA_16X_BY1 (0 << 8)
+#define BXT_DSIA_16X_BY2 (1 << 8)
+#define BXT_DSIA_16X_BY3 (2 << 8)
+#define BXT_DSIA_16X_BY4 (3 << 8)
+#define BXT_DSIA_16X_MASK (3 << 8)
+#define BXT_DSI_FREQ_SEL_SHIFT 8
+#define BXT_DSI_FREQ_SEL_MASK (0xF << BXT_DSI_FREQ_SEL_SHIFT)
+
+#define BXT_DSI_PLL_RATIO_MAX 0x7D
+#define BXT_DSI_PLL_RATIO_MIN 0x22
+#define GLK_DSI_PLL_RATIO_MAX 0x6F
+#define GLK_DSI_PLL_RATIO_MIN 0x22
+#define BXT_DSI_PLL_RATIO_MASK 0xFF
+#define BXT_REF_CLOCK_KHZ 19200
+
+#define BXT_DSI_PLL_ENABLE _MMIO(0x46080)
+#define BXT_DSI_PLL_DO_ENABLE (1 << 31)
+#define BXT_DSI_PLL_LOCKED (1 << 30)
+
+#endif /* __VLV_DSI_PLL_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_regs.h b/drivers/gpu/drm/i915/display/vlv_dsi_regs.h
new file mode 100644
index 000000000000..356e51515346
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/vlv_dsi_regs.h
@@ -0,0 +1,480 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __VLV_DSI_REGS_H__
+#define __VLV_DSI_REGS_H__
+
+#include "i915_reg_defs.h"
+
+#define VLV_MIPI_BASE VLV_DISPLAY_BASE
+#define BXT_MIPI_BASE 0x60000
+
+#define _MIPI_PORT(port, a, c) (((port) == PORT_A) ? a : c) /* ports A and C only */
+#define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c))
+
+/* BXT MIPI mode configure */
+#define _BXT_MIPIA_TRANS_HACTIVE 0x6B0F8
+#define _BXT_MIPIC_TRANS_HACTIVE 0x6B8F8
+#define BXT_MIPI_TRANS_HACTIVE(tc) _MMIO_MIPI(tc, \
+ _BXT_MIPIA_TRANS_HACTIVE, _BXT_MIPIC_TRANS_HACTIVE)
+
+#define _BXT_MIPIA_TRANS_VACTIVE 0x6B0FC
+#define _BXT_MIPIC_TRANS_VACTIVE 0x6B8FC
+#define BXT_MIPI_TRANS_VACTIVE(tc) _MMIO_MIPI(tc, \
+ _BXT_MIPIA_TRANS_VACTIVE, _BXT_MIPIC_TRANS_VACTIVE)
+
+#define _BXT_MIPIA_TRANS_VTOTAL 0x6B100
+#define _BXT_MIPIC_TRANS_VTOTAL 0x6B900
+#define BXT_MIPI_TRANS_VTOTAL(tc) _MMIO_MIPI(tc, \
+ _BXT_MIPIA_TRANS_VTOTAL, _BXT_MIPIC_TRANS_VTOTAL)
+
+#define BXT_P_DSI_REGULATOR_CFG _MMIO(0x160020)
+#define STAP_SELECT (1 << 0)
+
+#define BXT_P_DSI_REGULATOR_TX_CTRL _MMIO(0x160054)
+#define HS_IO_CTRL_SELECT (1 << 0)
+
+#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190)
+#define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700)
+#define MIPI_PORT_CTRL(port) _MMIO_MIPI(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL)
+
+ /* BXT port control */
+#define _BXT_MIPIA_PORT_CTRL 0x6B0C0
+#define _BXT_MIPIC_PORT_CTRL 0x6B8C0
+#define BXT_MIPI_PORT_CTRL(tc) _MMIO_MIPI(tc, _BXT_MIPIA_PORT_CTRL, _BXT_MIPIC_PORT_CTRL)
+
+#define DPI_ENABLE (1 << 31) /* A + C */
+#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27
+#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27)
+#define DUAL_LINK_MODE_SHIFT 26
+#define DUAL_LINK_MODE_MASK (1 << 26)
+#define DUAL_LINK_MODE_FRONT_BACK (0 << 26)
+#define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26)
+#define DITHERING_ENABLE (1 << 25) /* A + C */
+#define FLOPPED_HSTX (1 << 23)
+#define DE_INVERT (1 << 19) /* XXX */
+#define MIPIA_FLISDSI_DELAY_COUNT_SHIFT 18
+#define MIPIA_FLISDSI_DELAY_COUNT_MASK (0xf << 18)
+#define AFE_LATCHOUT (1 << 17)
+#define LP_OUTPUT_HOLD (1 << 16)
+#define MIPIC_FLISDSI_DELAY_COUNT_HIGH_SHIFT 15
+#define MIPIC_FLISDSI_DELAY_COUNT_HIGH_MASK (1 << 15)
+#define MIPIC_MIPI4DPHY_DELAY_COUNT_SHIFT 11
+#define MIPIC_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 11)
+#define CSB_SHIFT 9
+#define CSB_MASK (3 << 9)
+#define CSB_20MHZ (0 << 9)
+#define CSB_10MHZ (1 << 9)
+#define CSB_40MHZ (2 << 9)
+#define BANDGAP_MASK (1 << 8)
+#define BANDGAP_PNW_CIRCUIT (0 << 8)
+#define BANDGAP_LNC_CIRCUIT (1 << 8)
+#define MIPIC_FLISDSI_DELAY_COUNT_LOW_SHIFT 5
+#define MIPIC_FLISDSI_DELAY_COUNT_LOW_MASK (7 << 5)
+#define TEARING_EFFECT_DELAY (1 << 4) /* A + C */
+#define TEARING_EFFECT_SHIFT 2 /* A + C */
+#define TEARING_EFFECT_MASK (3 << 2)
+#define TEARING_EFFECT_OFF (0 << 2)
+#define TEARING_EFFECT_DSI (1 << 2)
+#define TEARING_EFFECT_GPIO (2 << 2)
+#define LANE_CONFIGURATION_SHIFT 0
+#define LANE_CONFIGURATION_MASK (3 << 0)
+#define LANE_CONFIGURATION_4LANE (0 << 0)
+#define LANE_CONFIGURATION_DUAL_LINK_A (1 << 0)
+#define LANE_CONFIGURATION_DUAL_LINK_B (2 << 0)
+
+#define _MIPIA_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61194)
+#define _MIPIC_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704)
+#define MIPI_TEARING_CTRL(port) _MMIO_MIPI(port, _MIPIA_TEARING_CTRL, _MIPIC_TEARING_CTRL)
+#define TEARING_EFFECT_DELAY_SHIFT 0
+#define TEARING_EFFECT_DELAY_MASK (0xffff << 0)
+
+/* XXX: all bits reserved */
+#define _MIPIA_AUTOPWG (VLV_DISPLAY_BASE + 0x611a0)
+
+/* MIPI DSI Controller and D-PHY registers */
+
+#define _MIPIA_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb000)
+#define _MIPIC_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb800)
+#define MIPI_DEVICE_READY(port) _MMIO_MIPI(port, _MIPIA_DEVICE_READY, _MIPIC_DEVICE_READY)
+#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */
+#define ULPS_STATE_MASK (3 << 1)
+#define ULPS_STATE_ENTER (2 << 1)
+#define ULPS_STATE_EXIT (1 << 1)
+#define ULPS_STATE_NORMAL_OPERATION (0 << 1)
+#define DEVICE_READY (1 << 0)
+
+#define _MIPIA_INTR_STAT (dev_priv->mipi_mmio_base + 0xb004)
+#define _MIPIC_INTR_STAT (dev_priv->mipi_mmio_base + 0xb804)
+#define MIPI_INTR_STAT(port) _MMIO_MIPI(port, _MIPIA_INTR_STAT, _MIPIC_INTR_STAT)
+#define _MIPIA_INTR_EN (dev_priv->mipi_mmio_base + 0xb008)
+#define _MIPIC_INTR_EN (dev_priv->mipi_mmio_base + 0xb808)
+#define MIPI_INTR_EN(port) _MMIO_MIPI(port, _MIPIA_INTR_EN, _MIPIC_INTR_EN)
+#define TEARING_EFFECT (1 << 31)
+#define SPL_PKT_SENT_INTERRUPT (1 << 30)
+#define GEN_READ_DATA_AVAIL (1 << 29)
+#define LP_GENERIC_WR_FIFO_FULL (1 << 28)
+#define HS_GENERIC_WR_FIFO_FULL (1 << 27)
+#define RX_PROT_VIOLATION (1 << 26)
+#define RX_INVALID_TX_LENGTH (1 << 25)
+#define ACK_WITH_NO_ERROR (1 << 24)
+#define TURN_AROUND_ACK_TIMEOUT (1 << 23)
+#define LP_RX_TIMEOUT (1 << 22)
+#define HS_TX_TIMEOUT (1 << 21)
+#define DPI_FIFO_UNDERRUN (1 << 20)
+#define LOW_CONTENTION (1 << 19)
+#define HIGH_CONTENTION (1 << 18)
+#define TXDSI_VC_ID_INVALID (1 << 17)
+#define TXDSI_DATA_TYPE_NOT_RECOGNISED (1 << 16)
+#define TXCHECKSUM_ERROR (1 << 15)
+#define TXECC_MULTIBIT_ERROR (1 << 14)
+#define TXECC_SINGLE_BIT_ERROR (1 << 13)
+#define TXFALSE_CONTROL_ERROR (1 << 12)
+#define RXDSI_VC_ID_INVALID (1 << 11)
+#define RXDSI_DATA_TYPE_NOT_REGOGNISED (1 << 10)
+#define RXCHECKSUM_ERROR (1 << 9)
+#define RXECC_MULTIBIT_ERROR (1 << 8)
+#define RXECC_SINGLE_BIT_ERROR (1 << 7)
+#define RXFALSE_CONTROL_ERROR (1 << 6)
+#define RXHS_RECEIVE_TIMEOUT_ERROR (1 << 5)
+#define RX_LP_TX_SYNC_ERROR (1 << 4)
+#define RXEXCAPE_MODE_ENTRY_ERROR (1 << 3)
+#define RXEOT_SYNC_ERROR (1 << 2)
+#define RXSOT_SYNC_ERROR (1 << 1)
+#define RXSOT_ERROR (1 << 0)
+
+#define _MIPIA_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb00c)
+#define _MIPIC_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb80c)
+#define MIPI_DSI_FUNC_PRG(port) _MMIO_MIPI(port, _MIPIA_DSI_FUNC_PRG, _MIPIC_DSI_FUNC_PRG)
+#define CMD_MODE_DATA_WIDTH_MASK (7 << 13)
+#define CMD_MODE_NOT_SUPPORTED (0 << 13)
+#define CMD_MODE_DATA_WIDTH_16_BIT (1 << 13)
+#define CMD_MODE_DATA_WIDTH_9_BIT (2 << 13)
+#define CMD_MODE_DATA_WIDTH_8_BIT (3 << 13)
+#define CMD_MODE_DATA_WIDTH_OPTION1 (4 << 13)
+#define CMD_MODE_DATA_WIDTH_OPTION2 (5 << 13)
+#define VID_MODE_FORMAT_MASK (0xf << 7)
+#define VID_MODE_NOT_SUPPORTED (0 << 7)
+#define VID_MODE_FORMAT_RGB565 (1 << 7)
+#define VID_MODE_FORMAT_RGB666_PACKED (2 << 7)
+#define VID_MODE_FORMAT_RGB666 (3 << 7)
+#define VID_MODE_FORMAT_RGB888 (4 << 7)
+#define CMD_MODE_CHANNEL_NUMBER_SHIFT 5
+#define CMD_MODE_CHANNEL_NUMBER_MASK (3 << 5)
+#define VID_MODE_CHANNEL_NUMBER_SHIFT 3
+#define VID_MODE_CHANNEL_NUMBER_MASK (3 << 3)
+#define DATA_LANES_PRG_REG_SHIFT 0
+#define DATA_LANES_PRG_REG_MASK (7 << 0)
+
+#define _MIPIA_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb010)
+#define _MIPIC_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb810)
+#define MIPI_HS_TX_TIMEOUT(port) _MMIO_MIPI(port, _MIPIA_HS_TX_TIMEOUT, _MIPIC_HS_TX_TIMEOUT)
+#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff
+
+#define _MIPIA_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb014)
+#define _MIPIC_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb814)
+#define MIPI_LP_RX_TIMEOUT(port) _MMIO_MIPI(port, _MIPIA_LP_RX_TIMEOUT, _MIPIC_LP_RX_TIMEOUT)
+#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff
+
+#define _MIPIA_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb018)
+#define _MIPIC_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb818)
+#define MIPI_TURN_AROUND_TIMEOUT(port) _MMIO_MIPI(port, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIC_TURN_AROUND_TIMEOUT)
+#define TURN_AROUND_TIMEOUT_MASK 0x3f
+
+#define _MIPIA_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb01c)
+#define _MIPIC_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb81c)
+#define MIPI_DEVICE_RESET_TIMER(port) _MMIO_MIPI(port, _MIPIA_DEVICE_RESET_TIMER, _MIPIC_DEVICE_RESET_TIMER)
+#define DEVICE_RESET_TIMER_MASK 0xffff
+
+#define _MIPIA_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb020)
+#define _MIPIC_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb820)
+#define MIPI_DPI_RESOLUTION(port) _MMIO_MIPI(port, _MIPIA_DPI_RESOLUTION, _MIPIC_DPI_RESOLUTION)
+#define VERTICAL_ADDRESS_SHIFT 16
+#define VERTICAL_ADDRESS_MASK (0xffff << 16)
+#define HORIZONTAL_ADDRESS_SHIFT 0
+#define HORIZONTAL_ADDRESS_MASK 0xffff
+
+#define _MIPIA_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb024)
+#define _MIPIC_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb824)
+#define MIPI_DBI_FIFO_THROTTLE(port) _MMIO_MIPI(port, _MIPIA_DBI_FIFO_THROTTLE, _MIPIC_DBI_FIFO_THROTTLE)
+#define DBI_FIFO_EMPTY_HALF (0 << 0)
+#define DBI_FIFO_EMPTY_QUARTER (1 << 0)
+#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0)
+
+/* regs below are bits 15:0 */
+#define _MIPIA_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb028)
+#define _MIPIC_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb828)
+#define MIPI_HSYNC_PADDING_COUNT(port) _MMIO_MIPI(port, _MIPIA_HSYNC_PADDING_COUNT, _MIPIC_HSYNC_PADDING_COUNT)
+
+#define _MIPIA_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb02c)
+#define _MIPIC_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb82c)
+#define MIPI_HBP_COUNT(port) _MMIO_MIPI(port, _MIPIA_HBP_COUNT, _MIPIC_HBP_COUNT)
+
+#define _MIPIA_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb030)
+#define _MIPIC_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb830)
+#define MIPI_HFP_COUNT(port) _MMIO_MIPI(port, _MIPIA_HFP_COUNT, _MIPIC_HFP_COUNT)
+
+#define _MIPIA_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb034)
+#define _MIPIC_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb834)
+#define MIPI_HACTIVE_AREA_COUNT(port) _MMIO_MIPI(port, _MIPIA_HACTIVE_AREA_COUNT, _MIPIC_HACTIVE_AREA_COUNT)
+
+#define _MIPIA_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb038)
+#define _MIPIC_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb838)
+#define MIPI_VSYNC_PADDING_COUNT(port) _MMIO_MIPI(port, _MIPIA_VSYNC_PADDING_COUNT, _MIPIC_VSYNC_PADDING_COUNT)
+
+#define _MIPIA_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb03c)
+#define _MIPIC_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb83c)
+#define MIPI_VBP_COUNT(port) _MMIO_MIPI(port, _MIPIA_VBP_COUNT, _MIPIC_VBP_COUNT)
+
+#define _MIPIA_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb040)
+#define _MIPIC_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb840)
+#define MIPI_VFP_COUNT(port) _MMIO_MIPI(port, _MIPIA_VFP_COUNT, _MIPIC_VFP_COUNT)
+
+#define _MIPIA_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb044)
+#define _MIPIC_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb844)
+#define MIPI_HIGH_LOW_SWITCH_COUNT(port) _MMIO_MIPI(port, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIC_HIGH_LOW_SWITCH_COUNT)
+
+#define _MIPIA_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb048)
+#define _MIPIC_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb848)
+#define MIPI_DPI_CONTROL(port) _MMIO_MIPI(port, _MIPIA_DPI_CONTROL, _MIPIC_DPI_CONTROL)
+#define DPI_LP_MODE (1 << 6)
+#define BACKLIGHT_OFF (1 << 5)
+#define BACKLIGHT_ON (1 << 4)
+#define COLOR_MODE_OFF (1 << 3)
+#define COLOR_MODE_ON (1 << 2)
+#define TURN_ON (1 << 1)
+#define SHUTDOWN (1 << 0)
+
+#define _MIPIA_DPI_DATA (dev_priv->mipi_mmio_base + 0xb04c)
+#define _MIPIC_DPI_DATA (dev_priv->mipi_mmio_base + 0xb84c)
+#define MIPI_DPI_DATA(port) _MMIO_MIPI(port, _MIPIA_DPI_DATA, _MIPIC_DPI_DATA)
+#define COMMAND_BYTE_SHIFT 0
+#define COMMAND_BYTE_MASK (0x3f << 0)
+
+#define _MIPIA_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb050)
+#define _MIPIC_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb850)
+#define MIPI_INIT_COUNT(port) _MMIO_MIPI(port, _MIPIA_INIT_COUNT, _MIPIC_INIT_COUNT)
+#define MASTER_INIT_TIMER_SHIFT 0
+#define MASTER_INIT_TIMER_MASK (0xffff << 0)
+
+#define _MIPIA_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb054)
+#define _MIPIC_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb854)
+#define MIPI_MAX_RETURN_PKT_SIZE(port) _MMIO_MIPI(port, \
+ _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIC_MAX_RETURN_PKT_SIZE)
+#define MAX_RETURN_PKT_SIZE_SHIFT 0
+#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0)
+
+#define _MIPIA_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb058)
+#define _MIPIC_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb858)
+#define MIPI_VIDEO_MODE_FORMAT(port) _MMIO_MIPI(port, _MIPIA_VIDEO_MODE_FORMAT, _MIPIC_VIDEO_MODE_FORMAT)
+#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4)
+#define DISABLE_VIDEO_BTA (1 << 3)
+#define IP_TG_CONFIG (1 << 2)
+#define VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE (1 << 0)
+#define VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (2 << 0)
+#define VIDEO_MODE_BURST (3 << 0)
+
+#define _MIPIA_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb05c)
+#define _MIPIC_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb85c)
+#define MIPI_EOT_DISABLE(port) _MMIO_MIPI(port, _MIPIA_EOT_DISABLE, _MIPIC_EOT_DISABLE)
+#define BXT_DEFEATURE_DPI_FIFO_CTR (1 << 9)
+#define BXT_DPHY_DEFEATURE_EN (1 << 8)
+#define LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 7)
+#define HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 6)
+#define LOW_CONTENTION_RECOVERY_DISABLE (1 << 5)
+#define HIGH_CONTENTION_RECOVERY_DISABLE (1 << 4)
+#define TXDSI_TYPE_NOT_RECOGNISED_ERROR_RECOVERY_DISABLE (1 << 3)
+#define TXECC_MULTIBIT_ERROR_RECOVERY_DISABLE (1 << 2)
+#define CLOCKSTOP (1 << 1)
+#define EOT_DISABLE (1 << 0)
+
+#define _MIPIA_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb060)
+#define _MIPIC_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb860)
+#define MIPI_LP_BYTECLK(port) _MMIO_MIPI(port, _MIPIA_LP_BYTECLK, _MIPIC_LP_BYTECLK)
+#define LP_BYTECLK_SHIFT 0
+#define LP_BYTECLK_MASK (0xffff << 0)
+
+#define _MIPIA_TLPX_TIME_COUNT (dev_priv->mipi_mmio_base + 0xb0a4)
+#define _MIPIC_TLPX_TIME_COUNT (dev_priv->mipi_mmio_base + 0xb8a4)
+#define MIPI_TLPX_TIME_COUNT(port) _MMIO_MIPI(port, _MIPIA_TLPX_TIME_COUNT, _MIPIC_TLPX_TIME_COUNT)
+
+#define _MIPIA_CLK_LANE_TIMING (dev_priv->mipi_mmio_base + 0xb098)
+#define _MIPIC_CLK_LANE_TIMING (dev_priv->mipi_mmio_base + 0xb898)
+#define MIPI_CLK_LANE_TIMING(port) _MMIO_MIPI(port, _MIPIA_CLK_LANE_TIMING, _MIPIC_CLK_LANE_TIMING)
+
+/* bits 31:0 */
+#define _MIPIA_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb064)
+#define _MIPIC_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb864)
+#define MIPI_LP_GEN_DATA(port) _MMIO_MIPI(port, _MIPIA_LP_GEN_DATA, _MIPIC_LP_GEN_DATA)
+
+/* bits 31:0 */
+#define _MIPIA_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb068)
+#define _MIPIC_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb868)
+#define MIPI_HS_GEN_DATA(port) _MMIO_MIPI(port, _MIPIA_HS_GEN_DATA, _MIPIC_HS_GEN_DATA)
+
+#define _MIPIA_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb06c)
+#define _MIPIC_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb86c)
+#define MIPI_LP_GEN_CTRL(port) _MMIO_MIPI(port, _MIPIA_LP_GEN_CTRL, _MIPIC_LP_GEN_CTRL)
+#define _MIPIA_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb070)
+#define _MIPIC_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb870)
+#define MIPI_HS_GEN_CTRL(port) _MMIO_MIPI(port, _MIPIA_HS_GEN_CTRL, _MIPIC_HS_GEN_CTRL)
+#define LONG_PACKET_WORD_COUNT_SHIFT 8
+#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8)
+#define SHORT_PACKET_PARAM_SHIFT 8
+#define SHORT_PACKET_PARAM_MASK (0xffff << 8)
+#define VIRTUAL_CHANNEL_SHIFT 6
+#define VIRTUAL_CHANNEL_MASK (3 << 6)
+#define DATA_TYPE_SHIFT 0
+#define DATA_TYPE_MASK (0x3f << 0)
+/* data type values, see include/video/mipi_display.h */
+
+#define _MIPIA_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb074)
+#define _MIPIC_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb874)
+#define MIPI_GEN_FIFO_STAT(port) _MMIO_MIPI(port, _MIPIA_GEN_FIFO_STAT, _MIPIC_GEN_FIFO_STAT)
+#define DPI_FIFO_EMPTY (1 << 28)
+#define DBI_FIFO_EMPTY (1 << 27)
+#define LP_CTRL_FIFO_EMPTY (1 << 26)
+#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25)
+#define LP_CTRL_FIFO_FULL (1 << 24)
+#define HS_CTRL_FIFO_EMPTY (1 << 18)
+#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17)
+#define HS_CTRL_FIFO_FULL (1 << 16)
+#define LP_DATA_FIFO_EMPTY (1 << 10)
+#define LP_DATA_FIFO_HALF_EMPTY (1 << 9)
+#define LP_DATA_FIFO_FULL (1 << 8)
+#define HS_DATA_FIFO_EMPTY (1 << 2)
+#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
+#define HS_DATA_FIFO_FULL (1 << 0)
+
+#define _MIPIA_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb078)
+#define _MIPIC_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb878)
+#define MIPI_HS_LP_DBI_ENABLE(port) _MMIO_MIPI(port, _MIPIA_HS_LS_DBI_ENABLE, _MIPIC_HS_LS_DBI_ENABLE)
+#define DBI_HS_LP_MODE_MASK (1 << 0)
+#define DBI_LP_MODE (1 << 0)
+#define DBI_HS_MODE (0 << 0)
+
+#define _MIPIA_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb080)
+#define _MIPIC_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb880)
+#define MIPI_DPHY_PARAM(port) _MMIO_MIPI(port, _MIPIA_DPHY_PARAM, _MIPIC_DPHY_PARAM)
+#define EXIT_ZERO_COUNT_SHIFT 24
+#define EXIT_ZERO_COUNT_MASK (0x3f << 24)
+#define TRAIL_COUNT_SHIFT 16
+#define TRAIL_COUNT_MASK (0x1f << 16)
+#define CLK_ZERO_COUNT_SHIFT 8
+#define CLK_ZERO_COUNT_MASK (0xff << 8)
+#define PREPARE_COUNT_SHIFT 0
+#define PREPARE_COUNT_MASK (0x3f << 0)
+
+#define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084)
+#define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884)
+#define MIPI_DBI_BW_CTRL(port) _MMIO_MIPI(port, _MIPIA_DBI_BW_CTRL, _MIPIC_DBI_BW_CTRL)
+
+#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base + 0xb088)
+#define _MIPIC_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base + 0xb888)
+#define MIPI_CLK_LANE_SWITCH_TIME_CNT(port) _MMIO_MIPI(port, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIC_CLK_LANE_SWITCH_TIME_CNT)
+#define LP_HS_SSW_CNT_SHIFT 16
+#define LP_HS_SSW_CNT_MASK (0xffff << 16)
+#define HS_LP_PWR_SW_CNT_SHIFT 0
+#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0)
+
+#define _MIPIA_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb08c)
+#define _MIPIC_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb88c)
+#define MIPI_STOP_STATE_STALL(port) _MMIO_MIPI(port, _MIPIA_STOP_STATE_STALL, _MIPIC_STOP_STATE_STALL)
+#define STOP_STATE_STALL_COUNTER_SHIFT 0
+#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0)
+
+#define _MIPIA_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb090)
+#define _MIPIC_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb890)
+#define MIPI_INTR_STAT_REG_1(port) _MMIO_MIPI(port, _MIPIA_INTR_STAT_REG_1, _MIPIC_INTR_STAT_REG_1)
+#define _MIPIA_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb094)
+#define _MIPIC_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb894)
+#define MIPI_INTR_EN_REG_1(port) _MMIO_MIPI(port, _MIPIA_INTR_EN_REG_1, _MIPIC_INTR_EN_REG_1)
+#define RX_CONTENTION_DETECTED (1 << 0)
+
+/* XXX: only pipe A ?!? */
+#define MIPIA_DBI_TYPEC_CTRL (dev_priv->mipi_mmio_base + 0xb100)
+#define DBI_TYPEC_ENABLE (1 << 31)
+#define DBI_TYPEC_WIP (1 << 30)
+#define DBI_TYPEC_OPTION_SHIFT 28
+#define DBI_TYPEC_OPTION_MASK (3 << 28)
+#define DBI_TYPEC_FREQ_SHIFT 24
+#define DBI_TYPEC_FREQ_MASK (0xf << 24)
+#define DBI_TYPEC_OVERRIDE (1 << 8)
+#define DBI_TYPEC_OVERRIDE_COUNTER_SHIFT 0
+#define DBI_TYPEC_OVERRIDE_COUNTER_MASK (0xff << 0)
+
+/* MIPI adapter registers */
+
+#define _MIPIA_CTRL (dev_priv->mipi_mmio_base + 0xb104)
+#define _MIPIC_CTRL (dev_priv->mipi_mmio_base + 0xb904)
+#define MIPI_CTRL(port) _MMIO_MIPI(port, _MIPIA_CTRL, _MIPIC_CTRL)
+#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */
+#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5)
+#define ESCAPE_CLOCK_DIVIDER_1 (0 << 5)
+#define ESCAPE_CLOCK_DIVIDER_2 (1 << 5)
+#define ESCAPE_CLOCK_DIVIDER_4 (2 << 5)
+#define READ_REQUEST_PRIORITY_SHIFT 3
+#define READ_REQUEST_PRIORITY_MASK (3 << 3)
+#define READ_REQUEST_PRIORITY_LOW (0 << 3)
+#define READ_REQUEST_PRIORITY_HIGH (3 << 3)
+#define RGB_FLIP_TO_BGR (1 << 2)
+
+#define BXT_PIPE_SELECT_SHIFT 7
+#define BXT_PIPE_SELECT_MASK (7 << 7)
+#define BXT_PIPE_SELECT(pipe) ((pipe) << 7)
+#define GLK_PHY_STATUS_PORT_READY (1 << 31) /* RO */
+#define GLK_ULPS_NOT_ACTIVE (1 << 30) /* RO */
+#define GLK_MIPIIO_RESET_RELEASED (1 << 28)
+#define GLK_CLOCK_LANE_STOP_STATE (1 << 27) /* RO */
+#define GLK_DATA_LANE_STOP_STATE (1 << 26) /* RO */
+#define GLK_LP_WAKE (1 << 22)
+#define GLK_LP11_LOW_PWR_MODE (1 << 21)
+#define GLK_LP00_LOW_PWR_MODE (1 << 20)
+#define GLK_FIREWALL_ENABLE (1 << 16)
+#define BXT_PIXEL_OVERLAP_CNT_MASK (0xf << 10)
+#define BXT_PIXEL_OVERLAP_CNT_SHIFT 10
+#define BXT_DSC_ENABLE (1 << 3)
+#define BXT_RGB_FLIP (1 << 2)
+#define GLK_MIPIIO_PORT_POWERED (1 << 1) /* RO */
+#define GLK_MIPIIO_ENABLE (1 << 0)
+
+#define _MIPIA_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb108)
+#define _MIPIC_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb908)
+#define MIPI_DATA_ADDRESS(port) _MMIO_MIPI(port, _MIPIA_DATA_ADDRESS, _MIPIC_DATA_ADDRESS)
+#define DATA_MEM_ADDRESS_SHIFT 5
+#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5)
+#define DATA_VALID (1 << 0)
+
+#define _MIPIA_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb10c)
+#define _MIPIC_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb90c)
+#define MIPI_DATA_LENGTH(port) _MMIO_MIPI(port, _MIPIA_DATA_LENGTH, _MIPIC_DATA_LENGTH)
+#define DATA_LENGTH_SHIFT 0
+#define DATA_LENGTH_MASK (0xfffff << 0)
+
+#define _MIPIA_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb110)
+#define _MIPIC_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb910)
+#define MIPI_COMMAND_ADDRESS(port) _MMIO_MIPI(port, _MIPIA_COMMAND_ADDRESS, _MIPIC_COMMAND_ADDRESS)
+#define COMMAND_MEM_ADDRESS_SHIFT 5
+#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5)
+#define AUTO_PWG_ENABLE (1 << 2)
+#define MEMORY_WRITE_DATA_FROM_PIPE_RENDERING (1 << 1)
+#define COMMAND_VALID (1 << 0)
+
+#define _MIPIA_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb114)
+#define _MIPIC_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb914)
+#define MIPI_COMMAND_LENGTH(port) _MMIO_MIPI(port, _MIPIA_COMMAND_LENGTH, _MIPIC_COMMAND_LENGTH)
+#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */
+#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n)))
+
+#define _MIPIA_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb118)
+#define _MIPIC_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb918)
+#define MIPI_READ_DATA_RETURN(port, n) _MMIO(_MIPI(port, _MIPIA_READ_DATA_RETURN0, _MIPIC_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */
+
+#define _MIPIA_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb138)
+#define _MIPIC_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb938)
+#define MIPI_READ_DATA_VALID(port) _MMIO_MIPI(port, _MIPIA_READ_DATA_VALID, _MIPIC_READ_DATA_VALID)
+#define READ_DATA_VALID(n) (1 << (n))
+
+#endif /* __VLV_DSI_REGS_H__ */