summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2024-10-15 17:58:56 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2024-10-15 17:58:56 +0300
commitd9fd0bed132993e4e57c6a0896d893c3938e6618 (patch)
treec35a9f50c5f301a1b2c06ff230db8ce846b68265
parentfc6a1e84b28c35ee1ae941e486e53d8e8b00e1b5 (diff)
parent750a95407bcb5787359d3cd5d0c9de092a0a1efd (diff)
Merge remote-tracking branch 'drm_intel_push/drm-intel-next' into drm-tip
-rw-r--r--Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon8
-rw-r--r--drivers/gpu/drm/i915/Makefile6
-rw-r--r--drivers/gpu/drm/i915/display/g4x_dp.c39
-rw-r--r--drivers/gpu/drm/i915/display/g4x_dp.h5
-rw-r--r--drivers/gpu/drm/i915/display/hsw_ips.c2
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c22
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_wm.c204
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_wm.h4
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_alpm.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c197
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h19
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c158
-rw-r--r--drivers/gpu/drm/i915/display/intel_bo.c59
-rw-r--r--drivers/gpu/drm/i915/display/intel_bo.h27
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c1177
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.h28
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c226
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c69
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.h12
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c104
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_de.h11
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c818
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h56
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_core.h10
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c320
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.h9
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_driver.c37
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_irq.c305
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_irq.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_limits.h10
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_params.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_params.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c101
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_map.c134
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_well.c249
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_well.h15
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_snapshot.c72
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_snapshot.h16
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_trace.h55
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h184
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c425
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h30
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc_wl.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c803
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h23
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_hdcp.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c36
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c90
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_test.c765
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_test.h23
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_tunnel.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_drrs.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.c139
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dvo.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c152
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_bo.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_bo.h10
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c27
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev_fb.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev_fb.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_fdi.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_fifo_underrun.c30
-rw-r--r--drivers/gpu/drm/i915/display/intel_frontbuffer.c66
-rw-r--r--drivers/gpu/drm/i915/display/intel_frontbuffer.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c727
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc.c40
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc.h9
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c44
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_shim.h137
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug_irq.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_link_bw.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_setup.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.c18
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.h25
-rw-r--r--drivers/gpu/drm/i915/display/intel_pipe_crc.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane_initial.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.c188
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.h12
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c107
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr_regs.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_quirks.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_sdvo.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c27
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite_uapi.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_tv.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_vblank.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc_regs.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_vga.c45
-rw-r--r--drivers/gpu/drm/i915/display/intel_vga.h14
-rw-r--r--drivers/gpu/drm/i915/display/intel_wm.c26
-rw-r--r--drivers/gpu/drm/i915/display/intel_wm.h6
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c402
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.c30
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.h4
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c3
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_pm.c2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_shrinker.c2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_stolen.c2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_ttm.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_breadcrumbs.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_irq.c24
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_pm.h12
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_regs.h5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_reset.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_tlb.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_workarounds.c9
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_log.c2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_huc.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.c1
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/opregion.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/page_track.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c2
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c6
-rw-r--r--drivers/gpu/drm/i915/i915_driver.c24
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c25
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.h11
-rw-r--r--drivers/gpu/drm/i915/i915_hwmon.c40
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c326
-rw-r--r--drivers/gpu/drm/i915/i915_irq.h40
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c4
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h454
-rw-r--r--drivers/gpu/drm/i915/i915_reg_defs.h10
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c3
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h2
-rw-r--r--drivers/gpu/drm/i915/i915_utils.h2
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c4
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.h1
-rw-r--r--drivers/gpu/drm/i915/intel_mchbar_regs.h4
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c8
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.h15
-rw-r--r--drivers/gpu/drm/i915/intel_wakeref.c14
-rw-r--r--drivers/gpu/drm/i915/intel_wakeref.h18
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp.c6
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp.h4
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c6
-rw-r--r--drivers/gpu/drm/i915/soc/intel_dram.c4
-rw-r--r--drivers/gpu/drm/i915/soc/intel_pch.c5
-rw-r--r--drivers/gpu/drm/i915/soc/intel_rom.c160
-rw-r--r--drivers/gpu/drm/i915/soc/intel_rom.h25
-rw-r--r--drivers/gpu/drm/xe/Makefile6
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h1
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h17
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h64
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h12
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h11
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h14
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h5
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h17
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h24
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h4
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h10
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h6
-rw-r--r--drivers/gpu/drm/xe/display/ext/i915_irq.c33
-rw-r--r--drivers/gpu/drm/xe/display/intel_bo.c84
-rw-r--r--drivers/gpu/drm/xe/display/intel_fb_bo.c19
-rw-r--r--drivers/gpu/drm/xe/display/intel_fb_bo.h24
-rw-r--r--drivers/gpu/drm/xe/display/intel_fbdev_fb.c12
-rw-r--r--drivers/gpu/drm/xe/display/xe_display.c19
-rw-r--r--drivers/gpu/drm/xe/display/xe_fb_pin.c12
-rw-r--r--drivers/gpu/drm/xe/display/xe_hdcp_gsc.c44
-rw-r--r--drivers/gpu/drm/xe/display/xe_plane_initial.c4
-rw-r--r--drivers/gpu/drm/xe/xe_bo.h2
-rw-r--r--drivers/gpu/drm/xe/xe_bo_types.h3
-rw-r--r--include/drm/intel/i915_pciids.h54
193 files changed, 6617 insertions, 4749 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
index be4141a7522f..a885e5316d02 100644
--- a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
+++ b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
@@ -83,3 +83,11 @@ Contact: intel-gfx@lists.freedesktop.org
Description: RO. Fan speed of device in RPM.
Only supported for particular Intel i915 graphics platforms.
+
+What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon<i>/temp1_input
+Date: November 2024
+KernelVersion: 6.12
+Contact: intel-gfx@lists.freedesktop.org
+Description: RO. GPU package temperature in millidegree Celsius.
+
+ Only supported for particular Intel i915 graphics platforms.
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c63fa2133ccb..e033bcaef4f3 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -51,7 +51,8 @@ i915-y += \
i915-y += \
soc/intel_dram.o \
soc/intel_gmch.o \
- soc/intel_pch.o
+ soc/intel_pch.o \
+ soc/intel_rom.o
# core library code
i915-y += \
@@ -225,6 +226,7 @@ i915-y += \
display/intel_atomic_plane.o \
display/intel_audio.o \
display/intel_bios.o \
+ display/intel_bo.o \
display/intel_bw.o \
display/intel_cdclk.o \
display/intel_color.o \
@@ -242,6 +244,7 @@ i915-y += \
display/intel_display_power_well.o \
display/intel_display_reset.o \
display/intel_display_rps.o \
+ display/intel_display_snapshot.o \
display/intel_display_wa.o \
display/intel_dmc.o \
display/intel_dmc_wl.o \
@@ -325,6 +328,7 @@ i915-y += \
display/intel_dp_hdcp.o \
display/intel_dp_link_training.o \
display/intel_dp_mst.o \
+ display/intel_dp_test.o \
display/intel_dsi.o \
display/intel_dsi_dcs_backlight.o \
display/intel_dsi_vbt.o \
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index 526c8c4d7b53..440fb3002f28 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -19,6 +19,7 @@
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_dp_link_training.h"
+#include "intel_dp_test.h"
#include "intel_dpio_phy.h"
#include "intel_encoder.h"
#include "intel_fifo_underrun.h"
@@ -477,12 +478,8 @@ intel_dp_link_down(struct intel_encoder *encoder,
msleep(intel_dp->pps.panel_power_down_delay);
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- intel_wakeref_t wakeref;
-
- with_intel_pps_lock(intel_dp, wakeref)
- intel_dp->pps.active_pipe = INVALID_PIPE;
- }
+ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ vlv_pps_port_disable(encoder, old_crtc_state);
}
static void g4x_dp_audio_enable(struct intel_encoder *encoder,
@@ -694,7 +691,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
with_intel_pps_lock(intel_dp, wakeref) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- vlv_pps_init(encoder, pipe_config);
+ vlv_pps_port_enable_unlocked(encoder, pipe_config);
intel_dp_enable_port(intel_dp, pipe_config);
@@ -1172,12 +1169,8 @@ intel_dp_hotplug(struct intel_encoder *encoder,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
enum intel_hotplug_state state;
- if (intel_dp->compliance.test_active &&
- intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
- intel_dp_phy_test(encoder);
- /* just do the PHY test and nothing else */
+ if (intel_dp_test_phy(intel_dp))
return INTEL_HOTPLUG_UNCHANGED;
- }
state = intel_encoder_hotplug(encoder, connector);
@@ -1249,20 +1242,6 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
kfree(enc_to_dig_port(to_intel_encoder(encoder)));
}
-enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
-{
- struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *dev_priv = to_i915(display->drm);
- struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
- enum pipe pipe;
-
- if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
- encoder->port, &pipe))
- return pipe;
-
- return INVALID_PIPE;
-}
-
static void intel_dp_encoder_reset(struct drm_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder->dev);
@@ -1273,12 +1252,8 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
intel_dp->reset_link_params = true;
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- intel_wakeref_t wakeref;
-
- with_intel_pps_lock(intel_dp, wakeref)
- intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
- }
+ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ vlv_pps_pipe_reset(intel_dp);
intel_pps_encoder_reset(intel_dp);
}
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.h b/drivers/gpu/drm/i915/display/g4x_dp.h
index a10638ab749c..c75e64ae79b7 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.h
+++ b/drivers/gpu/drm/i915/display/g4x_dp.h
@@ -19,7 +19,6 @@ struct intel_encoder;
#ifdef I915
const struct dpll *vlv_get_dpll(struct drm_i915_private *i915);
-enum pipe vlv_active_pipe(struct intel_dp *intel_dp);
void g4x_dp_set_clock(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config);
bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
@@ -32,10 +31,6 @@ static inline const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
{
return NULL;
}
-static inline int vlv_active_pipe(struct intel_dp *intel_dp)
-{
- return 0;
-}
static inline void g4x_dp_set_clock(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c
index 611a7d6ef80c..c571c6e76d4a 100644
--- a/drivers/gpu/drm/i915/display/hsw_ips.c
+++ b/drivers/gpu/drm/i915/display/hsw_ips.c
@@ -3,6 +3,8 @@
* Copyright © 2022 Intel Corporation
*/
+#include <linux/debugfs.h>
+
#include "hsw_ips.h"
#include "i915_drv.h"
#include "i915_reg.h"
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 9447f7229b60..17a1e3801a85 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -416,7 +416,8 @@ static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
return DIV_ROUND_UP(pixel_rate * num, den);
}
-static void i9xx_plane_update_noarm(struct intel_plane *plane,
+static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -444,7 +445,8 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
}
}
-static void i9xx_plane_update_arm(struct intel_plane *plane,
+static void i9xx_plane_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -507,7 +509,8 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
-static void i830_plane_update_arm(struct intel_plane *plane,
+static void i830_plane_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -517,11 +520,12 @@ static void i830_plane_update_arm(struct intel_plane *plane,
* Additional breakage on i830 causes register reads to return
* the last latched value instead of the last written value [ALM026].
*/
- i9xx_plane_update_noarm(plane, crtc_state, plane_state);
- i9xx_plane_update_arm(plane, crtc_state, plane_state);
+ i9xx_plane_update_noarm(dsb, plane, crtc_state, plane_state);
+ i9xx_plane_update_arm(dsb, plane, crtc_state, plane_state);
}
-static void i9xx_plane_disable_arm(struct intel_plane *plane,
+static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
@@ -549,7 +553,8 @@ static void i9xx_plane_disable_arm(struct intel_plane *plane,
}
static void
-g4x_primary_async_flip(struct intel_plane *plane,
+g4x_primary_async_flip(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip)
@@ -569,7 +574,8 @@ g4x_primary_async_flip(struct intel_plane *plane,
}
static void
-vlv_primary_async_flip(struct intel_plane *plane,
+vlv_primary_async_flip(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip)
diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c
index 15cda57fbc91..e3b13886177a 100644
--- a/drivers/gpu/drm/i915/display/i9xx_wm.c
+++ b/drivers/gpu/drm/i915/display/i9xx_wm.c
@@ -7,13 +7,23 @@
#include "i915_reg.h"
#include "i9xx_wm.h"
#include "intel_atomic.h"
+#include "intel_bo.h"
#include "intel_display.h"
#include "intel_display_trace.h"
+#include "intel_fb.h"
#include "intel_mchbar_regs.h"
#include "intel_wm.h"
#include "skl_watermark.h"
#include "vlv_sideband.h"
+struct intel_watermark_params {
+ u16 fifo_size;
+ u16 max_wm;
+ u8 default_wm;
+ u8 guard_size;
+ u8 cacheline_size;
+};
+
/* used in computing the new watermarks state */
struct intel_wm_config {
unsigned int num_pipes_active;
@@ -136,6 +146,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
{
+ struct intel_display *display = &dev_priv->display;
bool was_enabled;
u32 val;
@@ -177,7 +188,7 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl
return false;
}
- trace_intel_memory_cxsr(dev_priv, was_enabled, enable);
+ trace_intel_memory_cxsr(display, was_enabled, enable);
drm_dbg_kms(&dev_priv->drm, "memory self-refresh is %s (was %s)\n",
str_enabled_disabled(enable),
@@ -695,6 +706,76 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
}
}
+static bool i9xx_wm_need_update(const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *new_plane_state)
+{
+ /* Update watermarks on tiling or size changes. */
+ if (old_plane_state->uapi.visible != new_plane_state->uapi.visible)
+ return true;
+
+ if (!old_plane_state->hw.fb || !new_plane_state->hw.fb)
+ return false;
+
+ if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier ||
+ old_plane_state->hw.rotation != new_plane_state->hw.rotation ||
+ drm_rect_width(&old_plane_state->uapi.src) != drm_rect_width(&new_plane_state->uapi.src) ||
+ drm_rect_height(&old_plane_state->uapi.src) != drm_rect_height(&new_plane_state->uapi.src) ||
+ drm_rect_width(&old_plane_state->uapi.dst) != drm_rect_width(&new_plane_state->uapi.dst) ||
+ drm_rect_height(&old_plane_state->uapi.dst) != drm_rect_height(&new_plane_state->uapi.dst))
+ return true;
+
+ return false;
+}
+
+static void i9xx_wm_compute(struct intel_crtc_state *new_crtc_state,
+ const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *new_plane_state)
+{
+ bool turn_off, turn_on, visible, was_visible, mode_changed;
+
+ mode_changed = intel_crtc_needs_modeset(new_crtc_state);
+ was_visible = old_plane_state->uapi.visible;
+ visible = new_plane_state->uapi.visible;
+
+ if (!was_visible && !visible)
+ return;
+
+ turn_off = was_visible && (!visible || mode_changed);
+ turn_on = visible && (!was_visible || mode_changed);
+
+ /* FIXME nuke when all wm code is atomic */
+ if (turn_on) {
+ new_crtc_state->update_wm_pre = true;
+ } else if (turn_off) {
+ new_crtc_state->update_wm_post = true;
+ } else if (i9xx_wm_need_update(old_plane_state, new_plane_state)) {
+ /* FIXME bollocks */
+ new_crtc_state->update_wm_pre = true;
+ new_crtc_state->update_wm_post = true;
+ }
+}
+
+static int i9xx_compute_watermarks(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+ const struct intel_plane_state *old_plane_state;
+ const struct intel_plane_state *new_plane_state;
+ struct intel_plane *plane;
+ int i;
+
+ for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
+ new_plane_state, i) {
+ if (plane->pipe != crtc->pipe)
+ continue;
+
+ i9xx_wm_compute(new_crtc_state, old_plane_state, new_plane_state);
+ }
+
+ return 0;
+}
+
/*
* Documentation says:
* "If the line size is small, the TLB fetches can get in the way of the
@@ -715,10 +796,11 @@ static unsigned int g4x_tlb_miss_wa(int fifo_size, int width, int cpp)
static void g4x_write_wm_values(struct drm_i915_private *dev_priv,
const struct g4x_wm_values *wm)
{
+ struct intel_display *display = &dev_priv->display;
enum pipe pipe;
for_each_pipe(dev_priv, pipe)
- trace_g4x_wm(intel_crtc_for_pipe(dev_priv, pipe), wm);
+ trace_g4x_wm(intel_crtc_for_pipe(display, pipe), wm);
intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
FW_WM(wm->sr.plane, SR) |
@@ -747,10 +829,11 @@ static void g4x_write_wm_values(struct drm_i915_private *dev_priv,
static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
const struct vlv_wm_values *wm)
{
+ struct intel_display *display = &dev_priv->display;
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
- trace_vlv_wm(intel_crtc_for_pipe(dev_priv, pipe), wm);
+ trace_vlv_wm(intel_crtc_for_pipe(display, pipe), wm);
intel_uncore_write(&dev_priv->uncore, VLV_DDL(pipe),
(wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) |
@@ -1276,6 +1359,22 @@ out:
return 0;
}
+static int g4x_compute_watermarks(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ int ret;
+
+ ret = g4x_compute_pipe_wm(state, crtc);
+ if (ret)
+ return ret;
+
+ ret = g4x_compute_intermediate_wm(state, crtc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static void g4x_merge_wm(struct drm_i915_private *dev_priv,
struct g4x_wm_values *wm)
{
@@ -1902,6 +2001,22 @@ out:
return 0;
}
+static int vlv_compute_watermarks(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ int ret;
+
+ ret = vlv_compute_pipe_wm(state, crtc);
+ if (ret)
+ return ret;
+
+ ret = vlv_compute_intermediate_wm(state, crtc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static void vlv_merge_wm(struct drm_i915_private *dev_priv,
struct vlv_wm_values *wm)
{
@@ -2088,12 +2203,13 @@ static void i965_update_wm(struct drm_i915_private *dev_priv)
static struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915,
enum i9xx_plane_id i9xx_plane)
{
+ struct intel_display *display = &i915->display;
struct intel_plane *plane;
for_each_intel_plane(&i915->drm, plane) {
if (plane->id == PLANE_PRIMARY &&
plane->i9xx_plane == i9xx_plane)
- return intel_crtc_for_pipe(i915, plane->pipe);
+ return intel_crtc_for_pipe(display, plane->pipe);
}
return NULL;
@@ -2172,12 +2288,12 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv)
crtc = single_enabled_crtc(dev_priv);
if (IS_I915GM(dev_priv) && crtc) {
- struct drm_i915_gem_object *obj;
+ struct drm_gem_object *obj;
- obj = intel_fb_obj(crtc->base.primary->state->fb);
+ obj = intel_fb_bo(crtc->base.primary->state->fb);
/* self-refresh seems busted with untiled */
- if (!i915_gem_object_is_tiled(obj))
+ if (!intel_bo_is_tiled(obj))
crtc = NULL;
}
@@ -2878,8 +2994,9 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
- struct intel_pipe_wm *a = &new_crtc_state->wm.ilk.intermediate;
- const struct intel_pipe_wm *b = &old_crtc_state->wm.ilk.optimal;
+ struct intel_pipe_wm *intermediate = &new_crtc_state->wm.ilk.intermediate;
+ const struct intel_pipe_wm *optimal = &new_crtc_state->wm.ilk.optimal;
+ const struct intel_pipe_wm *active = &old_crtc_state->wm.ilk.optimal;
int level;
/*
@@ -2887,25 +3004,29 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state,
* currently active watermarks to get values that are safe both before
* and after the vblank.
*/
- *a = new_crtc_state->wm.ilk.optimal;
+ *intermediate = *optimal;
if (!new_crtc_state->hw.active ||
intel_crtc_needs_modeset(new_crtc_state) ||
state->skip_intermediate_wm)
return 0;
- a->pipe_enabled |= b->pipe_enabled;
- a->sprites_enabled |= b->sprites_enabled;
- a->sprites_scaled |= b->sprites_scaled;
+ intermediate->pipe_enabled |= active->pipe_enabled;
+ intermediate->sprites_enabled |= active->sprites_enabled;
+ intermediate->sprites_scaled |= active->sprites_scaled;
for (level = 0; level < dev_priv->display.wm.num_levels; level++) {
- struct intel_wm_level *a_wm = &a->wm[level];
- const struct intel_wm_level *b_wm = &b->wm[level];
-
- a_wm->enable &= b_wm->enable;
- a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val);
- a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val);
- a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val);
- a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val);
+ struct intel_wm_level *intermediate_wm = &intermediate->wm[level];
+ const struct intel_wm_level *active_wm = &active->wm[level];
+
+ intermediate_wm->enable &= active_wm->enable;
+ intermediate_wm->pri_val = max(intermediate_wm->pri_val,
+ active_wm->pri_val);
+ intermediate_wm->spr_val = max(intermediate_wm->spr_val,
+ active_wm->spr_val);
+ intermediate_wm->cur_val = max(intermediate_wm->cur_val,
+ active_wm->cur_val);
+ intermediate_wm->fbc_val = max(intermediate_wm->fbc_val,
+ active_wm->fbc_val);
}
/*
@@ -2914,19 +3035,35 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state,
* there's no safe way to transition from the old state to
* the new state, so we need to fail the atomic transaction.
*/
- if (!ilk_validate_pipe_wm(dev_priv, a))
+ if (!ilk_validate_pipe_wm(dev_priv, intermediate))
return -EINVAL;
/*
* If our intermediate WM are identical to the final WM, then we can
* omit the post-vblank programming; only update if it's different.
*/
- if (memcmp(a, &new_crtc_state->wm.ilk.optimal, sizeof(*a)) != 0)
+ if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0)
new_crtc_state->wm.need_postvbl_update = true;
return 0;
}
+static int ilk_compute_watermarks(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ int ret;
+
+ ret = ilk_compute_pipe_wm(state, crtc);
+ if (ret)
+ return ret;
+
+ ret = ilk_compute_intermediate_wm(state, crtc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
/*
* Merge the watermarks from all active pipes for a specific level.
*/
@@ -3265,7 +3402,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
dev_priv->display.wm.hw = *results;
}
-bool ilk_disable_lp_wm(struct drm_i915_private *dev_priv)
+bool ilk_disable_cxsr(struct drm_i915_private *dev_priv)
{
return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
}
@@ -3716,6 +3853,7 @@ static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv)
static void g4x_wm_sanitize(struct drm_i915_private *dev_priv)
{
+ struct intel_display *display = &dev_priv->display;
struct intel_plane *plane;
struct intel_crtc *crtc;
@@ -3723,7 +3861,7 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv)
for_each_intel_plane(&dev_priv->drm, plane) {
struct intel_crtc *crtc =
- intel_crtc_for_pipe(dev_priv, plane->pipe);
+ intel_crtc_for_pipe(display, plane->pipe);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane_state *plane_state =
@@ -3871,6 +4009,7 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv)
static void vlv_wm_sanitize(struct drm_i915_private *dev_priv)
{
+ struct intel_display *display = &dev_priv->display;
struct intel_plane *plane;
struct intel_crtc *crtc;
@@ -3878,7 +4017,7 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv)
for_each_intel_plane(&dev_priv->drm, plane) {
struct intel_crtc *crtc =
- intel_crtc_for_pipe(dev_priv, plane->pipe);
+ intel_crtc_for_pipe(display, plane->pipe);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane_state *plane_state =
@@ -3971,16 +4110,14 @@ static void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv)
}
static const struct intel_wm_funcs ilk_wm_funcs = {
- .compute_pipe_wm = ilk_compute_pipe_wm,
- .compute_intermediate_wm = ilk_compute_intermediate_wm,
+ .compute_watermarks = ilk_compute_watermarks,
.initial_watermarks = ilk_initial_watermarks,
.optimize_watermarks = ilk_optimize_watermarks,
.get_hw_state = ilk_wm_get_hw_state,
};
static const struct intel_wm_funcs vlv_wm_funcs = {
- .compute_pipe_wm = vlv_compute_pipe_wm,
- .compute_intermediate_wm = vlv_compute_intermediate_wm,
+ .compute_watermarks = vlv_compute_watermarks,
.initial_watermarks = vlv_initial_watermarks,
.optimize_watermarks = vlv_optimize_watermarks,
.atomic_update_watermarks = vlv_atomic_update_fifo,
@@ -3988,26 +4125,29 @@ static const struct intel_wm_funcs vlv_wm_funcs = {
};
static const struct intel_wm_funcs g4x_wm_funcs = {
- .compute_pipe_wm = g4x_compute_pipe_wm,
- .compute_intermediate_wm = g4x_compute_intermediate_wm,
+ .compute_watermarks = g4x_compute_watermarks,
.initial_watermarks = g4x_initial_watermarks,
.optimize_watermarks = g4x_optimize_watermarks,
.get_hw_state = g4x_wm_get_hw_state_and_sanitize,
};
static const struct intel_wm_funcs pnv_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = pnv_update_wm,
};
static const struct intel_wm_funcs i965_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = i965_update_wm,
};
static const struct intel_wm_funcs i9xx_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = i9xx_update_wm,
};
static const struct intel_wm_funcs i845_wm_funcs = {
+ .compute_watermarks = i9xx_compute_watermarks,
.update_wm = i845_update_wm,
};
diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.h b/drivers/gpu/drm/i915/display/i9xx_wm.h
index de0920730ab2..06ac37c6c94b 100644
--- a/drivers/gpu/drm/i915/display/i9xx_wm.h
+++ b/drivers/gpu/drm/i915/display/i9xx_wm.h
@@ -13,12 +13,12 @@ struct intel_crtc_state;
struct intel_plane_state;
#ifdef I915
-bool ilk_disable_lp_wm(struct drm_i915_private *i915);
+bool ilk_disable_cxsr(struct drm_i915_private *i915);
void ilk_wm_sanitize(struct drm_i915_private *i915);
bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable);
void i9xx_wm_init(struct drm_i915_private *i915);
#else
-static inline bool ilk_disable_lp_wm(struct drm_i915_private *i915)
+static inline bool ilk_disable_cxsr(struct drm_i915_private *i915)
{
return false;
}
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 293efc1f841d..87a27d91d15d 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -29,6 +29,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fixed.h>
#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_probe_helper.h>
#include "i915_reg.h"
#include "icl_dsi.h"
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
index 186cf4833f71..55f3ae1e68c9 100644
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -3,6 +3,8 @@
* Copyright 2024, Intel Corporation.
*/
+#include <linux/debugfs.h>
+
#include "intel_alpm.h"
#include "intel_crtc.h"
#include "intel_de.h"
@@ -330,7 +332,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
ALPM_CTL_AUX_LESS_WAKE_TIME(intel_dp->alpm_parameters.aux_less_wake_lines);
intel_de_write(display,
- PORT_ALPM_CTL(display, port),
+ PORT_ALPM_CTL(port),
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
@@ -338,7 +340,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
intel_dp->alpm_parameters.silence_period_sym_clocks));
intel_de_write(display,
- PORT_ALPM_LFPS_CTL(display, port),
+ PORT_ALPM_LFPS_CTL(port),
PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) |
PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 12d6ed940751..03dc54c802d3 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -266,7 +266,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
crtc_state->update_pipe = false;
crtc_state->update_m_n = false;
crtc_state->update_lrr = false;
- crtc_state->disable_lp_wm = false;
crtc_state->disable_cxsr = false;
crtc_state->update_wm_pre = false;
crtc_state->update_wm_post = false;
@@ -277,7 +276,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
crtc_state->fb_bits = 0;
crtc_state->update_planes = 0;
crtc_state->dsb_color_vblank = NULL;
- crtc_state->dsb_color_commit = NULL;
+ crtc_state->dsb_commit = NULL;
+ crtc_state->use_dsb = false;
return &crtc_state->uapi;
}
@@ -312,7 +312,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
drm_WARN_ON(crtc->dev, crtc_state->dsb_color_vblank);
- drm_WARN_ON(crtc->dev, crtc_state->dsb_color_commit);
+ drm_WARN_ON(crtc->dev, crtc_state->dsb_commit);
__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
intel_crtc_free_hw_state(crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index e979786aa5cf..b7e462075ded 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -35,9 +35,10 @@
#include <linux/dma-resv.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_gem_atomic_helper.h>
#include "i915_config.h"
#include "i9xx_plane_regs.h"
@@ -391,28 +392,6 @@ 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;
@@ -492,6 +471,61 @@ static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state
return old_ctl != new_ctl;
}
+static bool ilk_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
+ const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *new_plane_state)
+{
+ struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
+ bool old_visible = old_plane_state->uapi.visible;
+ bool new_visible = new_plane_state->uapi.visible;
+ bool modeset, turn_on;
+
+ if (plane->id == PLANE_CURSOR)
+ return false;
+
+ modeset = intel_crtc_needs_modeset(new_crtc_state);
+ turn_on = new_visible && (!old_visible || modeset);
+
+ /*
+ * 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.
+ *
+ * With experimental results seems this is needed also for primary
+ * plane, not only sprite plane.
+ */
+ if (turn_on)
+ return true;
+
+ /*
+ * 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.
+ */
+ return !intel_plane_is_scaled(old_plane_state) &&
+ intel_plane_is_scaled(new_plane_state);
+}
+
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,
@@ -546,20 +580,6 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
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;
- } else if (turn_off) {
- if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
- new_crtc_state->update_wm_post = 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;
@@ -567,45 +587,9 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
new_crtc_state->disable_cxsr = true;
- /*
- * 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 ((IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) &&
+ ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
+ new_crtc_state->disable_cxsr = true;
if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
new_crtc_state->do_async_flip = true;
@@ -710,13 +694,13 @@ intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
int intel_plane_atomic_check(struct intel_atomic_state *state,
struct intel_plane *plane)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_plane_state *new_plane_state =
intel_atomic_get_new_plane_state(state, plane);
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
const struct intel_plane_state *new_primary_crtc_plane_state;
- struct intel_crtc *crtc = intel_crtc_for_pipe(i915, plane->pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_crtc_state *new_crtc_state =
@@ -790,7 +774,8 @@ skl_next_plane_to_commit(struct intel_atomic_state *state,
return NULL;
}
-void intel_plane_update_noarm(struct intel_plane *plane,
+void intel_plane_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -799,10 +784,11 @@ void intel_plane_update_noarm(struct intel_plane *plane,
trace_intel_plane_update_noarm(plane, crtc);
if (plane->update_noarm)
- plane->update_noarm(plane, crtc_state, plane_state);
+ plane->update_noarm(dsb, plane, crtc_state, plane_state);
}
-void intel_plane_async_flip(struct intel_plane *plane,
+void intel_plane_async_flip(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip)
@@ -810,34 +796,37 @@ void intel_plane_async_flip(struct intel_plane *plane,
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
trace_intel_plane_async_flip(plane, crtc, async_flip);
- plane->async_flip(plane, crtc_state, plane_state, async_flip);
+ plane->async_flip(dsb, plane, crtc_state, plane_state, async_flip);
}
-void intel_plane_update_arm(struct intel_plane *plane,
+void intel_plane_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
if (crtc_state->do_async_flip && plane->async_flip) {
- intel_plane_async_flip(plane, crtc_state, plane_state, true);
+ intel_plane_async_flip(dsb, plane, crtc_state, plane_state, true);
return;
}
trace_intel_plane_update_arm(plane, crtc);
- plane->update_arm(plane, crtc_state, plane_state);
+ plane->update_arm(dsb, plane, crtc_state, plane_state);
}
-void intel_plane_disable_arm(struct intel_plane *plane,
+void intel_plane_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
trace_intel_plane_disable_arm(plane, crtc);
- plane->disable_arm(plane, crtc_state);
+ plane->disable_arm(dsb, plane, crtc_state);
}
-void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
+void intel_crtc_planes_update_noarm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *new_crtc_state =
@@ -862,11 +851,13 @@ void intel_crtc_planes_update_noarm(struct intel_atomic_state *state,
/* TODO: for mailbox updates this should be skipped */
if (new_plane_state->uapi.visible ||
new_plane_state->planar_slave)
- intel_plane_update_noarm(plane, new_crtc_state, new_plane_state);
+ intel_plane_update_noarm(dsb, plane,
+ new_crtc_state, new_plane_state);
}
}
-static void skl_crtc_planes_update_arm(struct intel_atomic_state *state,
+static void skl_crtc_planes_update_arm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *old_crtc_state =
@@ -893,13 +884,14 @@ static void skl_crtc_planes_update_arm(struct intel_atomic_state *state,
*/
if (new_plane_state->uapi.visible ||
new_plane_state->planar_slave)
- intel_plane_update_arm(plane, new_crtc_state, new_plane_state);
+ intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
else
- intel_plane_disable_arm(plane, new_crtc_state);
+ intel_plane_disable_arm(dsb, plane, new_crtc_state);
}
}
-static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state,
+static void i9xx_crtc_planes_update_arm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *new_crtc_state =
@@ -919,21 +911,22 @@ static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state,
* would have to be called here as well.
*/
if (new_plane_state->uapi.visible)
- intel_plane_update_arm(plane, new_crtc_state, new_plane_state);
+ intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
else
- intel_plane_disable_arm(plane, new_crtc_state);
+ intel_plane_disable_arm(dsb, plane, new_crtc_state);
}
}
-void intel_crtc_planes_update_arm(struct intel_atomic_state *state,
+void intel_crtc_planes_update_arm(struct intel_dsb *dsb,
+ 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);
+ skl_crtc_planes_update_arm(dsb, state, crtc);
else
- i9xx_crtc_planes_update_arm(state, crtc);
+ i9xx_crtc_planes_update_arm(dsb, state, crtc);
}
int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
@@ -1114,8 +1107,8 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
- struct drm_i915_gem_object *obj = intel_fb_obj(new_plane_state->hw.fb);
- struct drm_i915_gem_object *old_obj = intel_fb_obj(old_plane_state->hw.fb);
+ struct drm_gem_object *obj = intel_fb_bo(new_plane_state->hw.fb);
+ struct drm_gem_object *old_obj = intel_fb_bo(old_plane_state->hw.fb);
int ret;
if (old_obj) {
@@ -1135,7 +1128,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
* can safely continue.
*/
if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) {
- ret = add_dma_resv_fences(intel_bo_to_drm_bo(old_obj)->resv,
+ ret = add_dma_resv_fences(old_obj->resv,
&new_plane_state->uapi);
if (ret < 0)
return ret;
@@ -1195,7 +1188,7 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
struct intel_atomic_state *state =
to_intel_atomic_state(old_plane_state->uapi.state);
struct drm_i915_private *dev_priv = to_i915(plane->dev);
- struct drm_i915_gem_object *obj = intel_fb_obj(old_plane_state->hw.fb);
+ struct drm_gem_object *obj = intel_fb_bo(old_plane_state->hw.fb);
if (!obj)
return;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 6c4fe3596465..0f982f452ff3 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -14,6 +14,7 @@ struct drm_rect;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
+struct intel_dsb;
struct intel_plane;
struct intel_plane_state;
enum plane_id;
@@ -32,26 +33,32 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
struct intel_crtc *crtc);
void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
const struct intel_plane_state *from_plane_state);
-void intel_plane_async_flip(struct intel_plane *plane,
+void intel_plane_async_flip(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip);
-void intel_plane_update_noarm(struct intel_plane *plane,
+void intel_plane_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
-void intel_plane_update_arm(struct intel_plane *plane,
+void intel_plane_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
-void intel_plane_disable_arm(struct intel_plane *plane,
+void intel_plane_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state);
struct intel_plane *intel_plane_alloc(void);
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_crtc_planes_update_noarm(struct intel_atomic_state *state,
+void intel_crtc_planes_update_noarm(struct intel_dsb *dsb,
+ struct intel_atomic_state *state,
struct intel_crtc *crtc);
-void intel_crtc_planes_update_arm(struct intel_atomic_state *state,
+void intel_crtc_planes_update_arm(struct intel_dsb *dsbx,
+ 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,
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index f5e7eefab2f1..32aa9ec1a204 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -982,12 +982,12 @@ static unsigned long i915_audio_component_get_power(struct device *kdev)
{
struct intel_display *display = to_intel_display(kdev);
struct drm_i915_private *i915 = to_i915(display->drm);
- intel_wakeref_t ret;
+ intel_wakeref_t wakeref;
/* Catch potential impedance mismatches before they occur! */
BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long));
- ret = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK);
+ wakeref = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK);
if (i915->display.audio.power_refcount++ == 0) {
if (DISPLAY_VER(i915) >= 9) {
@@ -1007,7 +1007,7 @@ static unsigned long i915_audio_component_get_power(struct device *kdev)
0, AUD_PIN_BUF_ENABLE);
}
- return ret;
+ return (unsigned long)wakeref;
}
static void i915_audio_component_put_power(struct device *kdev,
@@ -1015,13 +1015,14 @@ static void i915_audio_component_put_power(struct device *kdev,
{
struct intel_display *display = to_intel_display(kdev);
struct drm_i915_private *i915 = to_i915(display->drm);
+ intel_wakeref_t wakeref = (intel_wakeref_t)cookie;
/* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */
if (--i915->display.audio.power_refcount == 0)
if (IS_GEMINILAKE(i915))
glk_force_audio_cdclk(i915, false);
- intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, cookie);
+ intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, wakeref);
}
static void i915_audio_component_codec_wake_override(struct device *kdev,
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index bed485374ab0..9967b65e3cf6 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -25,6 +25,7 @@
*
*/
+#include <linux/debugfs.h>
#include <linux/firmware.h>
#include <drm/display/drm_dp_helper.h>
@@ -32,12 +33,12 @@
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>
+#include "soc/intel_rom.h"
+
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_gmbus.h"
-#include "intel_uncore.h"
#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"
@@ -1705,8 +1706,8 @@ parse_mipi_config(struct intel_display *display,
return;
}
- drm_dbg(display->drm, "Found MIPI Config block, panel index = %d\n",
- panel_type);
+ drm_dbg_kms(display->drm, "Found MIPI Config block, panel index = %d\n",
+ panel_type);
/*
* get hold of the correct configuration block and pps data as per
@@ -2066,8 +2067,8 @@ parse_mipi_sequence(struct intel_display *display,
return;
}
- drm_dbg(display->drm, "Found MIPI sequence block v%u\n",
- sequence->version);
+ drm_dbg_kms(display->drm, "Found MIPI sequence block v%u\n",
+ sequence->version);
seq_data = find_panel_sequence_block(display, sequence, panel_type, &seq_size);
if (!seq_data)
@@ -2113,7 +2114,7 @@ parse_mipi_sequence(struct intel_display *display,
fixup_mipi_sequences(display, panel);
- drm_dbg(display->drm, "MIPI related VBT parsing complete\n");
+ drm_dbg_kms(display->drm, "MIPI related VBT parsing complete\n");
return;
err:
@@ -2770,9 +2771,9 @@ static bool child_device_size_valid(struct intel_display *display, int size)
expected_size = child_device_expected_size(display->vbt.version);
if (expected_size < 0) {
expected_size = sizeof(struct child_device_config);
- drm_dbg(display->drm,
- "Expected child device config size for VBT version %u not known; assuming %d\n",
- display->vbt.version, expected_size);
+ drm_dbg_kms(display->drm,
+ "Expected child device config size for VBT version %u not known; assuming %d\n",
+ display->vbt.version, expected_size);
}
/* Flag an error for unexpected size, but continue anyway. */
@@ -2963,6 +2964,9 @@ static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
return _vbt + vbt->bdb_offset;
}
+static const char vbt_signature[] = "$VBT";
+static const int vbt_signature_len = 4;
+
/**
* intel_bios_is_valid_vbt - does the given buffer contain a valid VBT
* @display: display device
@@ -2985,7 +2989,7 @@ bool intel_bios_is_valid_vbt(struct intel_display *display,
return false;
}
- if (memcmp(vbt->signature, "$VBT", 4)) {
+ if (memcmp(vbt->signature, vbt_signature, vbt_signature_len)) {
drm_dbg_kms(display->drm, "VBT invalid signature\n");
return false;
}
@@ -3052,131 +3056,59 @@ static struct vbt_header *firmware_get_vbt(struct intel_display *display,
return vbt;
}
-static u32 intel_spi_read(struct intel_uncore *uncore, u32 offset)
-{
- intel_uncore_write(uncore, PRIMARY_SPI_ADDRESS, offset);
-
- return intel_uncore_read(uncore, PRIMARY_SPI_TRIGGER);
-}
-
-static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display,
- size_t *size)
-{
- struct drm_i915_private *i915 = to_i915(display->drm);
- 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) {
- data = intel_spi_read(&i915->uncore, oprom_offset + count);
- 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 */
- vbt_size = intel_spi_read(&i915->uncore,
- found + offsetof(struct vbt_header, vbt_size));
- 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)
- *(vbt + store++) = intel_spi_read(&i915->uncore, found + count);
-
- if (!intel_bios_is_valid_vbt(display, vbt, vbt_size))
- goto err_free_vbt;
-
- drm_dbg_kms(display->drm, "Found valid VBT in SPI flash\n");
-
- if (size)
- *size = vbt_size;
-
- return (struct vbt_header *)vbt;
-
-err_free_vbt:
- kfree(vbt);
-err_not_found:
- return NULL;
-}
-
static struct vbt_header *oprom_get_vbt(struct intel_display *display,
- size_t *sizep)
+ struct intel_rom *rom,
+ size_t *size, const char *type)
{
- struct pci_dev *pdev = to_pci_dev(display->drm->dev);
- void __iomem *p = NULL, *oprom;
struct vbt_header *vbt;
- u16 vbt_size;
- size_t i, size;
+ size_t vbt_size;
+ loff_t offset;
- oprom = pci_map_rom(pdev, &size);
- if (!oprom)
+ if (!rom)
return NULL;
- /* Scour memory looking for the VBT signature. */
- for (i = 0; i + 4 < size; i += 4) {
- if (ioread32(oprom + i) != *((const u32 *)"$VBT"))
- continue;
-
- p = oprom + i;
- size -= i;
- break;
- }
+ BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1);
+ BUILD_BUG_ON(vbt_signature_len != sizeof(u32));
- if (!p)
- goto err_unmap_oprom;
+ offset = intel_rom_find(rom, *(const u32 *)vbt_signature);
+ if (offset < 0)
+ goto err_free_rom;
- if (sizeof(struct vbt_header) > size) {
- drm_dbg(display->drm, "VBT header incomplete\n");
- goto err_unmap_oprom;
+ if (sizeof(struct vbt_header) > intel_rom_size(rom) - offset) {
+ drm_dbg_kms(display->drm, "VBT header incomplete\n");
+ goto err_free_rom;
}
- vbt_size = ioread16(p + offsetof(struct vbt_header, vbt_size));
- if (vbt_size > size) {
- drm_dbg(display->drm,
- "VBT incomplete (vbt_size overflows)\n");
- goto err_unmap_oprom;
+ BUILD_BUG_ON(sizeof(vbt->vbt_size) != sizeof(u16));
+
+ vbt_size = intel_rom_read16(rom, offset + offsetof(struct vbt_header, vbt_size));
+ if (vbt_size > intel_rom_size(rom) - offset) {
+ drm_dbg_kms(display->drm, "VBT incomplete (vbt_size overflows)\n");
+ goto err_free_rom;
}
- /* The rest will be validated by intel_bios_is_valid_vbt() */
- vbt = kmalloc(vbt_size, GFP_KERNEL);
+ vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL);
if (!vbt)
- goto err_unmap_oprom;
+ goto err_free_rom;
- memcpy_fromio(vbt, p, vbt_size);
+ intel_rom_read_block(rom, vbt, offset, vbt_size);
if (!intel_bios_is_valid_vbt(display, vbt, vbt_size))
goto err_free_vbt;
- pci_unmap_rom(pdev, oprom);
+ drm_dbg_kms(display->drm, "Found valid VBT in %s\n", type);
- if (sizep)
- *sizep = vbt_size;
+ if (size)
+ *size = vbt_size;
- drm_dbg_kms(display->drm, "Found valid VBT in PCI ROM\n");
+ intel_rom_free(rom);
return vbt;
err_free_vbt:
kfree(vbt);
-err_unmap_oprom:
- pci_unmap_rom(pdev, oprom);
-
+err_free_rom:
+ intel_rom_free(rom);
return NULL;
}
@@ -3198,11 +3130,11 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display
*/
if (!vbt && IS_DGFX(i915))
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
- vbt = spi_oprom_get_vbt(display, sizep);
+ vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash");
if (!vbt)
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
- vbt = oprom_get_vbt(display, sizep);
+ vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM");
return vbt;
}
diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c
new file mode 100644
index 000000000000..fbd16d7b58d9
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_bo.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: MIT
+/* Copyright © 2024 Intel Corporation */
+
+#include "gem/i915_gem_mman.h"
+#include "gem/i915_gem_object.h"
+#include "gem/i915_gem_object_frontbuffer.h"
+#include "i915_debugfs.h"
+#include "intel_bo.h"
+
+bool intel_bo_is_tiled(struct drm_gem_object *obj)
+{
+ return i915_gem_object_is_tiled(to_intel_bo(obj));
+}
+
+bool intel_bo_is_userptr(struct drm_gem_object *obj)
+{
+ return i915_gem_object_is_userptr(to_intel_bo(obj));
+}
+
+bool intel_bo_is_shmem(struct drm_gem_object *obj)
+{
+ return i915_gem_object_is_shmem(to_intel_bo(obj));
+}
+
+bool intel_bo_is_protected(struct drm_gem_object *obj)
+{
+ return i915_gem_object_is_protected(to_intel_bo(obj));
+}
+
+void intel_bo_flush_if_display(struct drm_gem_object *obj)
+{
+ i915_gem_object_flush_if_display(to_intel_bo(obj));
+}
+
+int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+ return i915_gem_fb_mmap(to_intel_bo(obj), vma);
+}
+
+int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size)
+{
+ return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size);
+}
+
+struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj)
+{
+ return i915_gem_object_get_frontbuffer(to_intel_bo(obj));
+}
+
+struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
+ struct intel_frontbuffer *front)
+{
+ return i915_gem_object_set_frontbuffer(to_intel_bo(obj), front);
+}
+
+void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
+{
+ i915_debugfs_describe_obj(m, to_intel_bo(obj));
+}
diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h
new file mode 100644
index 000000000000..ea7a2253aaa5
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_bo.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2024 Intel Corporation */
+
+#ifndef __INTEL_BO__
+#define __INTEL_BO__
+
+#include <linux/types.h>
+
+struct drm_gem_object;
+struct seq_file;
+struct vm_area_struct;
+
+bool intel_bo_is_tiled(struct drm_gem_object *obj);
+bool intel_bo_is_userptr(struct drm_gem_object *obj);
+bool intel_bo_is_shmem(struct drm_gem_object *obj);
+bool intel_bo_is_protected(struct drm_gem_object *obj);
+void intel_bo_flush_if_display(struct drm_gem_object *obj);
+int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
+int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size);
+
+struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj);
+struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
+ struct intel_frontbuffer *front);
+
+void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj);
+
+#endif /* __INTEL_BO__ */
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index aa3ba66c5307..fa1c2012b10c 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -21,6 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/debugfs.h>
#include <linux/time.h>
#include <drm/drm_fixed.h>
@@ -112,81 +113,81 @@
*/
struct intel_cdclk_funcs {
- void (*get_cdclk)(struct drm_i915_private *i915,
+ void (*get_cdclk)(struct intel_display *display,
struct intel_cdclk_config *cdclk_config);
- void (*set_cdclk)(struct drm_i915_private *i915,
+ void (*set_cdclk)(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe);
int (*modeset_calc_cdclk)(struct intel_atomic_state *state);
u8 (*calc_voltage_level)(int cdclk);
};
-void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,
+void intel_cdclk_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- dev_priv->display.funcs.cdclk->get_cdclk(dev_priv, cdclk_config);
+ display->funcs.cdclk->get_cdclk(display, cdclk_config);
}
-static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv,
+static void intel_cdclk_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
- dev_priv->display.funcs.cdclk->set_cdclk(dev_priv, cdclk_config, pipe);
+ display->funcs.cdclk->set_cdclk(display, cdclk_config, pipe);
}
static int intel_cdclk_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
- return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(state);
+ return display->funcs.cdclk->modeset_calc_cdclk(state);
}
-static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv,
+static u8 intel_cdclk_calc_voltage_level(struct intel_display *display,
int cdclk)
{
- return dev_priv->display.funcs.cdclk->calc_voltage_level(cdclk);
+ return display->funcs.cdclk->calc_voltage_level(cdclk);
}
-static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv,
+static void fixed_133mhz_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
cdclk_config->cdclk = 133333;
}
-static void fixed_200mhz_get_cdclk(struct drm_i915_private *dev_priv,
+static void fixed_200mhz_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
cdclk_config->cdclk = 200000;
}
-static void fixed_266mhz_get_cdclk(struct drm_i915_private *dev_priv,
+static void fixed_266mhz_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
cdclk_config->cdclk = 266667;
}
-static void fixed_333mhz_get_cdclk(struct drm_i915_private *dev_priv,
+static void fixed_333mhz_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
cdclk_config->cdclk = 333333;
}
-static void fixed_400mhz_get_cdclk(struct drm_i915_private *dev_priv,
+static void fixed_400mhz_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
cdclk_config->cdclk = 400000;
}
-static void fixed_450mhz_get_cdclk(struct drm_i915_private *dev_priv,
+static void fixed_450mhz_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
cdclk_config->cdclk = 450000;
}
-static void i85x_get_cdclk(struct drm_i915_private *dev_priv,
+static void i85x_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
u16 hpllcc = 0;
/*
@@ -225,10 +226,10 @@ static void i85x_get_cdclk(struct drm_i915_private *dev_priv,
}
}
-static void i915gm_get_cdclk(struct drm_i915_private *dev_priv,
+static void i915gm_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
u16 gcfgc = 0;
pci_read_config_word(pdev, GCFGC, &gcfgc);
@@ -249,10 +250,10 @@ static void i915gm_get_cdclk(struct drm_i915_private *dev_priv,
}
}
-static void i945gm_get_cdclk(struct drm_i915_private *dev_priv,
+static void i945gm_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
u16 gcfgc = 0;
pci_read_config_word(pdev, GCFGC, &gcfgc);
@@ -273,7 +274,7 @@ static void i945gm_get_cdclk(struct drm_i915_private *dev_priv,
}
}
-static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)
+static unsigned int intel_hpll_vco(struct intel_display *display)
{
static const unsigned int blb_vco[8] = {
[0] = 3200000,
@@ -312,6 +313,7 @@ static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)
[4] = 2666667,
[5] = 4266667,
};
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
const unsigned int *vco_table;
unsigned int vco;
u8 tmp = 0;
@@ -330,23 +332,23 @@ static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)
else
return 0;
- tmp = intel_de_read(dev_priv,
+ tmp = intel_de_read(display,
IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO);
vco = vco_table[tmp & 0x7];
if (vco == 0)
- drm_err(&dev_priv->drm, "Bad HPLL VCO (HPLLVCO=0x%02x)\n",
+ drm_err(display->drm, "Bad HPLL VCO (HPLLVCO=0x%02x)\n",
tmp);
else
- drm_dbg_kms(&dev_priv->drm, "HPLL VCO %u kHz\n", vco);
+ drm_dbg_kms(display->drm, "HPLL VCO %u kHz\n", vco);
return vco;
}
-static void g33_get_cdclk(struct drm_i915_private *dev_priv,
+static void g33_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
static const u8 div_3200[] = { 12, 10, 8, 7, 5, 16 };
static const u8 div_4000[] = { 14, 12, 10, 8, 6, 20 };
static const u8 div_4800[] = { 20, 14, 12, 10, 8, 24 };
@@ -355,7 +357,7 @@ static void g33_get_cdclk(struct drm_i915_private *dev_priv,
unsigned int cdclk_sel;
u16 tmp = 0;
- cdclk_config->vco = intel_hpll_vco(dev_priv);
+ cdclk_config->vco = intel_hpll_vco(display);
pci_read_config_word(pdev, GCFGC, &tmp);
@@ -386,16 +388,16 @@ static void g33_get_cdclk(struct drm_i915_private *dev_priv,
return;
fail:
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n",
cdclk_config->vco, tmp);
cdclk_config->cdclk = 190476;
}
-static void pnv_get_cdclk(struct drm_i915_private *dev_priv,
+static void pnv_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
u16 gcfgc = 0;
pci_read_config_word(pdev, GCFGC, &gcfgc);
@@ -414,7 +416,7 @@ static void pnv_get_cdclk(struct drm_i915_private *dev_priv,
cdclk_config->cdclk = 200000;
break;
default:
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Unknown pnv display core clock 0x%04x\n", gcfgc);
fallthrough;
case GC_DISPLAY_CLOCK_133_MHZ_PNV:
@@ -426,10 +428,10 @@ static void pnv_get_cdclk(struct drm_i915_private *dev_priv,
}
}
-static void i965gm_get_cdclk(struct drm_i915_private *dev_priv,
+static void i965gm_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
static const u8 div_3200[] = { 16, 10, 8 };
static const u8 div_4000[] = { 20, 12, 10 };
static const u8 div_5333[] = { 24, 16, 14 };
@@ -437,7 +439,7 @@ static void i965gm_get_cdclk(struct drm_i915_private *dev_priv,
unsigned int cdclk_sel;
u16 tmp = 0;
- cdclk_config->vco = intel_hpll_vco(dev_priv);
+ cdclk_config->vco = intel_hpll_vco(display);
pci_read_config_word(pdev, GCFGC, &tmp);
@@ -465,20 +467,20 @@ static void i965gm_get_cdclk(struct drm_i915_private *dev_priv,
return;
fail:
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n",
cdclk_config->vco, tmp);
cdclk_config->cdclk = 200000;
}
-static void gm45_get_cdclk(struct drm_i915_private *dev_priv,
+static void gm45_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
unsigned int cdclk_sel;
u16 tmp = 0;
- cdclk_config->vco = intel_hpll_vco(dev_priv);
+ cdclk_config->vco = intel_hpll_vco(display);
pci_read_config_word(pdev, GCFGC, &tmp);
@@ -494,7 +496,7 @@ static void gm45_get_cdclk(struct drm_i915_private *dev_priv,
cdclk_config->cdclk = cdclk_sel ? 320000 : 228571;
break;
default:
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n",
cdclk_config->vco, tmp);
cdclk_config->cdclk = 222222;
@@ -502,15 +504,16 @@ static void gm45_get_cdclk(struct drm_i915_private *dev_priv,
}
}
-static void hsw_get_cdclk(struct drm_i915_private *dev_priv,
+static void hsw_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+ u32 lcpll = intel_de_read(display, LCPLL_CTL);
u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;
if (lcpll & LCPLL_CD_SOURCE_FCLK)
cdclk_config->cdclk = 800000;
- else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
+ else if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT)
cdclk_config->cdclk = 450000;
else if (freq == LCPLL_CLK_FREQ_450)
cdclk_config->cdclk = 450000;
@@ -520,8 +523,9 @@ static void hsw_get_cdclk(struct drm_i915_private *dev_priv,
cdclk_config->cdclk = 540000;
}
-static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
+static int vlv_calc_cdclk(struct intel_display *display, int min_cdclk)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int freq_320 = (dev_priv->hpll_freq << 1) % 320000 != 0 ?
333333 : 320000;
@@ -540,8 +544,10 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
return 200000;
}
-static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk)
+static u8 vlv_calc_voltage_level(struct intel_display *display, int cdclk)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
if (IS_VALLEYVIEW(dev_priv)) {
if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
return 2;
@@ -559,9 +565,10 @@ static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk)
}
}
-static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
+static void vlv_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 val;
vlv_iosf_sb_get(dev_priv,
@@ -585,8 +592,9 @@ static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
DSPFREQGUAR_SHIFT_CHV;
}
-static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
+static void vlv_program_pfi_credits(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
unsigned int credits, default_credits;
if (IS_CHERRYVIEW(dev_priv))
@@ -594,7 +602,7 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
else
default_credits = PFI_CREDIT(8);
- if (dev_priv->display.cdclk.hw.cdclk >= dev_priv->czclk_freq) {
+ if (display->cdclk.hw.cdclk >= dev_priv->czclk_freq) {
/* CHV suggested value is 31 or 63 */
if (IS_CHERRYVIEW(dev_priv))
credits = PFI_CREDIT_63;
@@ -608,24 +616,25 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
* WA - write default credits before re-programming
* FIXME: should we also set the resend bit here?
*/
- intel_de_write(dev_priv, GCI_CONTROL,
+ intel_de_write(display, GCI_CONTROL,
VGA_FAST_MODE_DISABLE | default_credits);
- intel_de_write(dev_priv, GCI_CONTROL,
+ intel_de_write(display, GCI_CONTROL,
VGA_FAST_MODE_DISABLE | credits | PFI_CREDIT_RESEND);
/*
* FIXME is this guaranteed to clear
* immediately or should we poll for it?
*/
- drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, GCI_CONTROL) & PFI_CREDIT_RESEND);
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, GCI_CONTROL) & PFI_CREDIT_RESEND);
}
-static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
+static void vlv_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int cdclk = cdclk_config->cdclk;
u32 val, cmd = cdclk_config->voltage_level;
intel_wakeref_t wakeref;
@@ -662,7 +671,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &
DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
50)) {
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"timed out waiting for CDclk change\n");
}
@@ -681,7 +690,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
50))
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"timed out waiting for CDclk change\n");
}
@@ -704,17 +713,18 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
BIT(VLV_IOSF_SB_BUNIT) |
BIT(VLV_IOSF_SB_PUNIT));
- intel_update_cdclk(dev_priv);
+ intel_update_cdclk(display);
- vlv_program_pfi_credits(dev_priv);
+ vlv_program_pfi_credits(display);
intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
}
-static void chv_set_cdclk(struct drm_i915_private *dev_priv,
+static void chv_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int cdclk = cdclk_config->cdclk;
u32 val, cmd = cdclk_config->voltage_level;
intel_wakeref_t wakeref;
@@ -746,15 +756,15 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &
DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
50)) {
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"timed out waiting for CDclk change\n");
}
vlv_punit_put(dev_priv);
- intel_update_cdclk(dev_priv);
+ intel_update_cdclk(display);
- vlv_program_pfi_credits(dev_priv);
+ vlv_program_pfi_credits(display);
intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
}
@@ -786,15 +796,15 @@ static u8 bdw_calc_voltage_level(int cdclk)
}
}
-static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
+static void bdw_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL);
+ u32 lcpll = intel_de_read(display, LCPLL_CTL);
u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;
if (lcpll & LCPLL_CD_SOURCE_FCLK)
cdclk_config->cdclk = 800000;
- else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
+ else if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT)
cdclk_config->cdclk = 450000;
else if (freq == LCPLL_CLK_FREQ_450)
cdclk_config->cdclk = 450000;
@@ -830,15 +840,16 @@ static u32 bdw_cdclk_freq_sel(int cdclk)
}
}
-static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
+static void bdw_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int cdclk = cdclk_config->cdclk;
int ret;
- if (drm_WARN(&dev_priv->drm,
- (intel_de_read(dev_priv, LCPLL_CTL) &
+ if (drm_WARN(display->drm,
+ (intel_de_read(display, LCPLL_CTL) &
(LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |
LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |
@@ -848,39 +859,39 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
ret = snb_pcode_write(&dev_priv->uncore, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
if (ret) {
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"failed to inform pcode about cdclk change\n");
return;
}
- intel_de_rmw(dev_priv, LCPLL_CTL,
+ intel_de_rmw(display, LCPLL_CTL,
0, LCPLL_CD_SOURCE_FCLK);
/*
* According to the spec, it should be enough to poll for this 1 us.
* However, extensive testing shows that this can take longer.
*/
- if (wait_for_us(intel_de_read(dev_priv, LCPLL_CTL) &
+ if (wait_for_us(intel_de_read(display, LCPLL_CTL) &
LCPLL_CD_SOURCE_FCLK_DONE, 100))
- drm_err(&dev_priv->drm, "Switching to FCLK failed\n");
+ drm_err(display->drm, "Switching to FCLK failed\n");
- intel_de_rmw(dev_priv, LCPLL_CTL,
+ intel_de_rmw(display, LCPLL_CTL,
LCPLL_CLK_FREQ_MASK, bdw_cdclk_freq_sel(cdclk));
- intel_de_rmw(dev_priv, LCPLL_CTL,
+ intel_de_rmw(display, LCPLL_CTL,
LCPLL_CD_SOURCE_FCLK, 0);
- if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) &
+ if (wait_for_us((intel_de_read(display, LCPLL_CTL) &
LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
- drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n");
+ drm_err(display->drm, "Switching back to LCPLL failed\n");
snb_pcode_write(&dev_priv->uncore, HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level);
- intel_de_write(dev_priv, CDCLK_FREQ,
+ intel_de_write(display, CDCLK_FREQ,
DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
- intel_update_cdclk(dev_priv);
+ intel_update_cdclk(display);
}
static int skl_calc_cdclk(int min_cdclk, int vco)
@@ -918,7 +929,7 @@ static u8 skl_calc_voltage_level(int cdclk)
return 0;
}
-static void skl_dpll0_update(struct drm_i915_private *dev_priv,
+static void skl_dpll0_update(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
u32 val;
@@ -926,16 +937,16 @@ static void skl_dpll0_update(struct drm_i915_private *dev_priv,
cdclk_config->ref = 24000;
cdclk_config->vco = 0;
- val = intel_de_read(dev_priv, LCPLL1_CTL);
+ val = intel_de_read(display, LCPLL1_CTL);
if ((val & LCPLL_PLL_ENABLE) == 0)
return;
- if (drm_WARN_ON(&dev_priv->drm, (val & LCPLL_PLL_LOCK) == 0))
+ if (drm_WARN_ON(display->drm, (val & LCPLL_PLL_LOCK) == 0))
return;
- val = intel_de_read(dev_priv, DPLL_CTRL1);
+ val = intel_de_read(display, DPLL_CTRL1);
- if (drm_WARN_ON(&dev_priv->drm,
+ if (drm_WARN_ON(display->drm,
(val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
DPLL_CTRL1_SSC(SKL_DPLL0) |
DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) !=
@@ -959,19 +970,19 @@ static void skl_dpll0_update(struct drm_i915_private *dev_priv,
}
}
-static void skl_get_cdclk(struct drm_i915_private *dev_priv,
+static void skl_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
u32 cdctl;
- skl_dpll0_update(dev_priv, cdclk_config);
+ skl_dpll0_update(display, cdclk_config);
cdclk_config->cdclk = cdclk_config->bypass = cdclk_config->ref;
if (cdclk_config->vco == 0)
goto out;
- cdctl = intel_de_read(dev_priv, CDCLK_CTL);
+ cdctl = intel_de_read(display, CDCLK_CTL);
if (cdclk_config->vco == 8640000) {
switch (cdctl & CDCLK_FREQ_SEL_MASK) {
@@ -1026,19 +1037,19 @@ static int skl_cdclk_decimal(int cdclk)
return DIV_ROUND_CLOSEST(cdclk - 1000, 500);
}
-static void skl_set_preferred_cdclk_vco(struct drm_i915_private *i915, int vco)
+static void skl_set_preferred_cdclk_vco(struct intel_display *display, int vco)
{
- bool changed = i915->display.cdclk.skl_preferred_vco_freq != vco;
+ bool changed = display->cdclk.skl_preferred_vco_freq != vco;
- i915->display.cdclk.skl_preferred_vco_freq = vco;
+ display->cdclk.skl_preferred_vco_freq = vco;
if (changed)
- intel_update_max_cdclk(i915);
+ intel_update_max_cdclk(display);
}
-static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco)
+static u32 skl_dpll0_link_rate(struct intel_display *display, int vco)
{
- drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
+ drm_WARN_ON(display->drm, vco != 8100000 && vco != 8640000);
/*
* We always enable DPLL0 with the lowest link rate possible, but still
@@ -1055,47 +1066,47 @@ static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco)
return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0);
}
-static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
+static void skl_dpll0_enable(struct intel_display *display, int vco)
{
- intel_de_rmw(dev_priv, DPLL_CTRL1,
+ intel_de_rmw(display, DPLL_CTRL1,
DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
DPLL_CTRL1_SSC(SKL_DPLL0) |
DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0),
DPLL_CTRL1_OVERRIDE(SKL_DPLL0) |
- skl_dpll0_link_rate(dev_priv, vco));
- intel_de_posting_read(dev_priv, DPLL_CTRL1);
+ skl_dpll0_link_rate(display, vco));
+ intel_de_posting_read(display, DPLL_CTRL1);
- intel_de_rmw(dev_priv, LCPLL1_CTL,
+ intel_de_rmw(display, LCPLL1_CTL,
0, LCPLL_PLL_ENABLE);
- if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
- drm_err(&dev_priv->drm, "DPLL0 not locked\n");
+ if (intel_de_wait_for_set(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
+ drm_err(display->drm, "DPLL0 not locked\n");
- dev_priv->display.cdclk.hw.vco = vco;
+ display->cdclk.hw.vco = vco;
/* We'll want to keep using the current vco from now on. */
- skl_set_preferred_cdclk_vco(dev_priv, vco);
+ skl_set_preferred_cdclk_vco(display, vco);
}
-static void skl_dpll0_disable(struct drm_i915_private *dev_priv)
+static void skl_dpll0_disable(struct intel_display *display)
{
- intel_de_rmw(dev_priv, LCPLL1_CTL,
+ intel_de_rmw(display, LCPLL1_CTL,
LCPLL_PLL_ENABLE, 0);
- if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n");
+ if (intel_de_wait_for_clear(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
+ drm_err(display->drm, "Couldn't disable DPLL0\n");
- dev_priv->display.cdclk.hw.vco = 0;
+ display->cdclk.hw.vco = 0;
}
-static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
+static u32 skl_cdclk_freq_sel(struct intel_display *display,
int cdclk, int vco)
{
switch (cdclk) {
default:
- drm_WARN_ON(&dev_priv->drm,
- cdclk != dev_priv->display.cdclk.hw.bypass);
- drm_WARN_ON(&dev_priv->drm, vco != 0);
+ drm_WARN_ON(display->drm,
+ cdclk != display->cdclk.hw.bypass);
+ drm_WARN_ON(display->drm, vco != 0);
fallthrough;
case 308571:
case 337500:
@@ -1111,10 +1122,11 @@ static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
}
}
-static void skl_set_cdclk(struct drm_i915_private *dev_priv,
+static void skl_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int cdclk = cdclk_config->cdclk;
int vco = cdclk_config->vco;
u32 freq_select, cdclk_ctl;
@@ -1128,7 +1140,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
* use the corresponding VCO freq as that always leads to using the
* minimum 308MHz CDCLK.
*/
- drm_WARN_ON_ONCE(&dev_priv->drm,
+ drm_WARN_ON_ONCE(display->drm,
IS_SKYLAKE(dev_priv) && vco == 8640000);
ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
@@ -1136,54 +1148,54 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
if (ret) {
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Failed to inform PCU about cdclk change (%d)\n", ret);
return;
}
- freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco);
+ freq_select = skl_cdclk_freq_sel(display, cdclk, vco);
- if (dev_priv->display.cdclk.hw.vco != 0 &&
- dev_priv->display.cdclk.hw.vco != vco)
- skl_dpll0_disable(dev_priv);
+ if (display->cdclk.hw.vco != 0 &&
+ display->cdclk.hw.vco != vco)
+ skl_dpll0_disable(display);
- cdclk_ctl = intel_de_read(dev_priv, CDCLK_CTL);
+ cdclk_ctl = intel_de_read(display, CDCLK_CTL);
- if (dev_priv->display.cdclk.hw.vco != vco) {
+ if (display->cdclk.hw.vco != vco) {
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
- intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
+ intel_de_write(display, CDCLK_CTL, cdclk_ctl);
}
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl |= CDCLK_DIVMUX_CD_OVERRIDE;
- intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
- intel_de_posting_read(dev_priv, CDCLK_CTL);
+ intel_de_write(display, CDCLK_CTL, cdclk_ctl);
+ intel_de_posting_read(display, CDCLK_CTL);
- if (dev_priv->display.cdclk.hw.vco != vco)
- skl_dpll0_enable(dev_priv, vco);
+ if (display->cdclk.hw.vco != vco)
+ skl_dpll0_enable(display, vco);
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
- intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
+ intel_de_write(display, CDCLK_CTL, cdclk_ctl);
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
- intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
+ intel_de_write(display, CDCLK_CTL, cdclk_ctl);
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~CDCLK_DIVMUX_CD_OVERRIDE;
- intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
- intel_de_posting_read(dev_priv, CDCLK_CTL);
+ intel_de_write(display, CDCLK_CTL, cdclk_ctl);
+ intel_de_posting_read(display, CDCLK_CTL);
/* inform PCU of the change */
snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
- intel_update_cdclk(dev_priv);
+ intel_update_cdclk(display);
}
-static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
+static void skl_sanitize_cdclk(struct intel_display *display)
{
u32 cdctl, expected;
@@ -1192,15 +1204,15 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
* There is SWF18 scratchpad register defined which is set by the
* pre-os which can be used by the OS drivers to check the status
*/
- if ((intel_de_read(dev_priv, SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
+ if ((intel_de_read(display, SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
goto sanitize;
- intel_update_cdclk(dev_priv);
- intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");
+ intel_update_cdclk(display);
+ intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK");
/* Is PLL enabled and locked ? */
- if (dev_priv->display.cdclk.hw.vco == 0 ||
- dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass)
+ if (display->cdclk.hw.vco == 0 ||
+ display->cdclk.hw.cdclk == display->cdclk.hw.bypass)
goto sanitize;
/* DPLL okay; verify the cdclock
@@ -1209,60 +1221,60 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
* decimal part is programmed wrong from BIOS where pre-os does not
* enable display. Verify the same as well.
*/
- cdctl = intel_de_read(dev_priv, CDCLK_CTL);
+ cdctl = intel_de_read(display, CDCLK_CTL);
expected = (cdctl & CDCLK_FREQ_SEL_MASK) |
- skl_cdclk_decimal(dev_priv->display.cdclk.hw.cdclk);
+ skl_cdclk_decimal(display->cdclk.hw.cdclk);
if (cdctl == expected)
/* All well; nothing to sanitize */
return;
sanitize:
- drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");
+ drm_dbg_kms(display->drm, "Sanitizing cdclk programmed by pre-os\n");
/* force cdclk programming */
- dev_priv->display.cdclk.hw.cdclk = 0;
+ display->cdclk.hw.cdclk = 0;
/* force full PLL disable + enable */
- dev_priv->display.cdclk.hw.vco = ~0;
+ display->cdclk.hw.vco = ~0;
}
-static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv)
+static void skl_cdclk_init_hw(struct intel_display *display)
{
struct intel_cdclk_config cdclk_config;
- skl_sanitize_cdclk(dev_priv);
+ skl_sanitize_cdclk(display);
- if (dev_priv->display.cdclk.hw.cdclk != 0 &&
- dev_priv->display.cdclk.hw.vco != 0) {
+ if (display->cdclk.hw.cdclk != 0 &&
+ display->cdclk.hw.vco != 0) {
/*
* Use the current vco as our initial
* guess as to what the preferred vco is.
*/
- if (dev_priv->display.cdclk.skl_preferred_vco_freq == 0)
- skl_set_preferred_cdclk_vco(dev_priv,
- dev_priv->display.cdclk.hw.vco);
+ if (display->cdclk.skl_preferred_vco_freq == 0)
+ skl_set_preferred_cdclk_vco(display,
+ display->cdclk.hw.vco);
return;
}
- cdclk_config = dev_priv->display.cdclk.hw;
+ cdclk_config = display->cdclk.hw;
- cdclk_config.vco = dev_priv->display.cdclk.skl_preferred_vco_freq;
+ cdclk_config.vco = display->cdclk.skl_preferred_vco_freq;
if (cdclk_config.vco == 0)
cdclk_config.vco = 8100000;
cdclk_config.cdclk = skl_calc_cdclk(0, cdclk_config.vco);
cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk);
- skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
+ skl_set_cdclk(display, &cdclk_config, INVALID_PIPE);
}
-static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
+static void skl_cdclk_uninit_hw(struct intel_display *display)
{
- struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw;
+ struct intel_cdclk_config cdclk_config = display->cdclk.hw;
cdclk_config.cdclk = cdclk_config.bypass;
cdclk_config.vco = 0;
cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk);
- skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
+ skl_set_cdclk(display, &cdclk_config, INVALID_PIPE);
}
struct intel_cdclk_vals {
@@ -1470,37 +1482,37 @@ static int cdclk_divider(int cdclk, int vco, u16 waveform)
cdclk * cdclk_squash_len);
}
-static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
+static int bxt_calc_cdclk(struct intel_display *display, int min_cdclk)
{
- const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
+ const struct intel_cdclk_vals *table = display->cdclk.table;
int i;
for (i = 0; table[i].refclk; i++)
- if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&
+ if (table[i].refclk == display->cdclk.hw.ref &&
table[i].cdclk >= min_cdclk)
return table[i].cdclk;
- drm_WARN(&dev_priv->drm, 1,
+ drm_WARN(display->drm, 1,
"Cannot satisfy minimum cdclk %d with refclk %u\n",
- min_cdclk, dev_priv->display.cdclk.hw.ref);
+ min_cdclk, display->cdclk.hw.ref);
return 0;
}
-static int bxt_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
+static int bxt_calc_cdclk_pll_vco(struct intel_display *display, int cdclk)
{
- const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
+ const struct intel_cdclk_vals *table = display->cdclk.table;
int i;
- if (cdclk == dev_priv->display.cdclk.hw.bypass)
+ if (cdclk == display->cdclk.hw.bypass)
return 0;
for (i = 0; table[i].refclk; i++)
- if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&
+ if (table[i].refclk == display->cdclk.hw.ref &&
table[i].cdclk == cdclk)
- return dev_priv->display.cdclk.hw.ref * table[i].ratio;
+ return display->cdclk.hw.ref * table[i].ratio;
- drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",
- cdclk, dev_priv->display.cdclk.hw.ref);
+ drm_WARN(display->drm, 1, "cdclk %d not valid for refclk %u\n",
+ cdclk, display->cdclk.hw.ref);
return 0;
}
@@ -1582,10 +1594,10 @@ static u8 rplu_calc_voltage_level(int cdclk)
rplu_voltage_level_max_cdclk);
}
-static void icl_readout_refclk(struct drm_i915_private *dev_priv,
+static void icl_readout_refclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
- u32 dssm = intel_de_read(dev_priv, SKL_DSSM) & ICL_DSSM_CDCLK_PLL_REFCLK_MASK;
+ u32 dssm = intel_de_read(display, SKL_DSSM) & ICL_DSSM_CDCLK_PLL_REFCLK_MASK;
switch (dssm) {
default:
@@ -1603,19 +1615,20 @@ static void icl_readout_refclk(struct drm_i915_private *dev_priv,
}
}
-static void bxt_de_pll_readout(struct drm_i915_private *dev_priv,
+static void bxt_de_pll_readout(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 val, ratio;
if (IS_DG2(dev_priv))
cdclk_config->ref = 38400;
- else if (DISPLAY_VER(dev_priv) >= 11)
- icl_readout_refclk(dev_priv, cdclk_config);
+ else if (DISPLAY_VER(display) >= 11)
+ icl_readout_refclk(display, cdclk_config);
else
cdclk_config->ref = 19200;
- val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE);
+ val = intel_de_read(display, BXT_DE_PLL_ENABLE);
if ((val & BXT_DE_PLL_PLL_ENABLE) == 0 ||
(val & BXT_DE_PLL_LOCK) == 0) {
/*
@@ -1630,26 +1643,26 @@ static void bxt_de_pll_readout(struct drm_i915_private *dev_priv,
* DISPLAY_VER >= 11 have the ratio directly in the PLL enable register,
* gen9lp had it in a separate PLL control register.
*/
- if (DISPLAY_VER(dev_priv) >= 11)
+ if (DISPLAY_VER(display) >= 11)
ratio = val & ICL_CDCLK_PLL_RATIO_MASK;
else
- ratio = intel_de_read(dev_priv, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK;
+ ratio = intel_de_read(display, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK;
cdclk_config->vco = ratio * cdclk_config->ref;
}
-static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
+static void bxt_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
u32 squash_ctl = 0;
u32 divider;
int div;
- bxt_de_pll_readout(dev_priv, cdclk_config);
+ bxt_de_pll_readout(display, cdclk_config);
- if (DISPLAY_VER(dev_priv) >= 12)
+ if (DISPLAY_VER(display) >= 12)
cdclk_config->bypass = cdclk_config->ref / 2;
- else if (DISPLAY_VER(dev_priv) >= 11)
+ else if (DISPLAY_VER(display) >= 11)
cdclk_config->bypass = 50000;
else
cdclk_config->bypass = cdclk_config->ref;
@@ -1659,7 +1672,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
goto out;
}
- divider = intel_de_read(dev_priv, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
+ divider = intel_de_read(display, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
switch (divider) {
case BXT_CDCLK_CD2X_DIV_SEL_1:
@@ -1679,8 +1692,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
return;
}
- if (HAS_CDCLK_SQUASH(dev_priv))
- squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL);
+ if (HAS_CDCLK_SQUASH(display))
+ squash_ctl = intel_de_read(display, CDCLK_SQUASH_CTL);
if (squash_ctl & CDCLK_SQUASH_ENABLE) {
u16 waveform;
@@ -1696,107 +1709,107 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
}
out:
- if (DISPLAY_VER(dev_priv) >= 20)
- cdclk_config->joined_mbus = intel_de_read(dev_priv, MBUS_CTL) & MBUS_JOIN;
+ if (DISPLAY_VER(display) >= 20)
+ cdclk_config->joined_mbus = intel_de_read(display, MBUS_CTL) & MBUS_JOIN;
/*
* Can't read this out :( Let's assume it's
* at least what the CDCLK frequency requires.
*/
cdclk_config->voltage_level =
- intel_cdclk_calc_voltage_level(dev_priv, cdclk_config->cdclk);
+ intel_cdclk_calc_voltage_level(display, cdclk_config->cdclk);
}
-static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
+static void bxt_de_pll_disable(struct intel_display *display)
{
- intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, 0);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, 0);
/* Timeout 200us */
- if (intel_de_wait_for_clear(dev_priv,
+ if (intel_de_wait_for_clear(display,
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "timeout waiting for DE PLL unlock\n");
+ drm_err(display->drm, "timeout waiting for DE PLL unlock\n");
- dev_priv->display.cdclk.hw.vco = 0;
+ display->cdclk.hw.vco = 0;
}
-static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
+static void bxt_de_pll_enable(struct intel_display *display, int vco)
{
- int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);
+ int ratio = DIV_ROUND_CLOSEST(vco, display->cdclk.hw.ref);
- intel_de_rmw(dev_priv, BXT_DE_PLL_CTL,
+ intel_de_rmw(display, BXT_DE_PLL_CTL,
BXT_DE_PLL_RATIO_MASK, BXT_DE_PLL_RATIO(ratio));
- intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
/* Timeout 200us */
- if (intel_de_wait_for_set(dev_priv,
+ if (intel_de_wait_for_set(display,
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "timeout waiting for DE PLL lock\n");
+ drm_err(display->drm, "timeout waiting for DE PLL lock\n");
- dev_priv->display.cdclk.hw.vco = vco;
+ display->cdclk.hw.vco = vco;
}
-static void icl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
+static void icl_cdclk_pll_disable(struct intel_display *display)
{
- intel_de_rmw(dev_priv, BXT_DE_PLL_ENABLE,
+ intel_de_rmw(display, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_PLL_ENABLE, 0);
/* Timeout 200us */
- if (intel_de_wait_for_clear(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL unlock\n");
+ if (intel_de_wait_for_clear(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
+ drm_err(display->drm, "timeout waiting for CDCLK PLL unlock\n");
- dev_priv->display.cdclk.hw.vco = 0;
+ display->cdclk.hw.vco = 0;
}
-static void icl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
+static void icl_cdclk_pll_enable(struct intel_display *display, int vco)
{
- int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);
+ int ratio = DIV_ROUND_CLOSEST(vco, display->cdclk.hw.ref);
u32 val;
val = ICL_CDCLK_PLL_RATIO(ratio);
- intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, val);
val |= BXT_DE_PLL_PLL_ENABLE;
- intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, val);
/* Timeout 200us */
- if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL lock\n");
+ if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
+ drm_err(display->drm, "timeout waiting for CDCLK PLL lock\n");
- dev_priv->display.cdclk.hw.vco = vco;
+ display->cdclk.hw.vco = vco;
}
-static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)
+static void adlp_cdclk_pll_crawl(struct intel_display *display, int vco)
{
- int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);
+ int ratio = DIV_ROUND_CLOSEST(vco, display->cdclk.hw.ref);
u32 val;
/* Write PLL ratio without disabling */
val = ICL_CDCLK_PLL_RATIO(ratio) | BXT_DE_PLL_PLL_ENABLE;
- intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, val);
/* Submit freq change request */
val |= BXT_DE_PLL_FREQ_REQ;
- intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, val);
/* Timeout 200us */
- if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE,
+ if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1))
- drm_err(&dev_priv->drm, "timeout waiting for FREQ change request ack\n");
+ drm_err(display->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);
+ intel_de_write(display, BXT_DE_PLL_ENABLE, val);
- dev_priv->display.cdclk.hw.vco = vco;
+ display->cdclk.hw.vco = vco;
}
-static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
+static u32 bxt_cdclk_cd2x_pipe(struct intel_display *display, enum pipe pipe)
{
- if (DISPLAY_VER(dev_priv) >= 12) {
+ if (DISPLAY_VER(display) >= 12) {
if (pipe == INVALID_PIPE)
return TGL_CDCLK_CD2X_PIPE_NONE;
else
return TGL_CDCLK_CD2X_PIPE(pipe);
- } else if (DISPLAY_VER(dev_priv) >= 11) {
+ } else if (DISPLAY_VER(display) >= 11) {
if (pipe == INVALID_PIPE)
return ICL_CDCLK_CD2X_PIPE_NONE;
else
@@ -1809,15 +1822,15 @@ static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe
}
}
-static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
+static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display,
int cdclk, int vco, u16 waveform)
{
/* cdclk = vco / 2 / div{1,1.5,2,4} */
switch (cdclk_divider(cdclk, vco, waveform)) {
default:
- drm_WARN_ON(&dev_priv->drm,
- cdclk != dev_priv->display.cdclk.hw.bypass);
- drm_WARN_ON(&dev_priv->drm, vco != 0);
+ drm_WARN_ON(display->drm,
+ cdclk != display->cdclk.hw.bypass);
+ drm_WARN_ON(display->drm, vco != 0);
fallthrough;
case 2:
return BXT_CDCLK_CD2X_DIV_SEL_1;
@@ -1830,47 +1843,47 @@ static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
}
}
-static u16 cdclk_squash_waveform(struct drm_i915_private *dev_priv,
+static u16 cdclk_squash_waveform(struct intel_display *display,
int cdclk)
{
- const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
+ const struct intel_cdclk_vals *table = display->cdclk.table;
int i;
- if (cdclk == dev_priv->display.cdclk.hw.bypass)
+ if (cdclk == display->cdclk.hw.bypass)
return 0;
for (i = 0; table[i].refclk; i++)
- if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&
+ if (table[i].refclk == display->cdclk.hw.ref &&
table[i].cdclk == cdclk)
return table[i].waveform;
- drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",
- cdclk, dev_priv->display.cdclk.hw.ref);
+ drm_WARN(display->drm, 1, "cdclk %d not valid for refclk %u\n",
+ cdclk, display->cdclk.hw.ref);
return 0xffff;
}
-static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco)
+static void icl_cdclk_pll_update(struct intel_display *display, int vco)
{
- if (i915->display.cdclk.hw.vco != 0 &&
- i915->display.cdclk.hw.vco != vco)
- icl_cdclk_pll_disable(i915);
+ if (display->cdclk.hw.vco != 0 &&
+ display->cdclk.hw.vco != vco)
+ icl_cdclk_pll_disable(display);
- if (i915->display.cdclk.hw.vco != vco)
- icl_cdclk_pll_enable(i915, vco);
+ if (display->cdclk.hw.vco != vco)
+ icl_cdclk_pll_enable(display, vco);
}
-static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco)
+static void bxt_cdclk_pll_update(struct intel_display *display, int vco)
{
- if (i915->display.cdclk.hw.vco != 0 &&
- i915->display.cdclk.hw.vco != vco)
- bxt_de_pll_disable(i915);
+ if (display->cdclk.hw.vco != 0 &&
+ display->cdclk.hw.vco != vco)
+ bxt_de_pll_disable(display);
- if (i915->display.cdclk.hw.vco != vco)
- bxt_de_pll_enable(i915, vco);
+ if (display->cdclk.hw.vco != vco)
+ bxt_de_pll_enable(display, vco);
}
-static void dg2_cdclk_squash_program(struct drm_i915_private *i915,
+static void dg2_cdclk_squash_program(struct intel_display *display,
u16 waveform)
{
u32 squash_ctl = 0;
@@ -1879,7 +1892,7 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915,
squash_ctl = CDCLK_SQUASH_ENABLE |
CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
- intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl);
+ intel_de_write(display, CDCLK_SQUASH_CTL, squash_ctl);
}
static bool cdclk_pll_is_unknown(unsigned int vco)
@@ -1892,38 +1905,40 @@ static bool cdclk_pll_is_unknown(unsigned int vco)
return vco == ~0;
}
-static bool mdclk_source_is_cdclk_pll(struct drm_i915_private *i915)
+static bool mdclk_source_is_cdclk_pll(struct intel_display *display)
{
- return DISPLAY_VER(i915) >= 20;
+ return DISPLAY_VER(display) >= 20;
}
-static u32 xe2lpd_mdclk_source_sel(struct drm_i915_private *i915)
+static u32 xe2lpd_mdclk_source_sel(struct intel_display *display)
{
- if (mdclk_source_is_cdclk_pll(i915))
+ if (mdclk_source_is_cdclk_pll(display))
return MDCLK_SOURCE_SEL_CDCLK_PLL;
return MDCLK_SOURCE_SEL_CD2XCLK;
}
-int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
+int intel_mdclk_cdclk_ratio(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config)
{
- if (mdclk_source_is_cdclk_pll(i915))
+ if (mdclk_source_is_cdclk_pll(display))
return DIV_ROUND_UP(cdclk_config->vco, cdclk_config->cdclk);
/* Otherwise, source for MDCLK is CD2XCLK. */
return 2;
}
-static void xe2lpd_mdclk_cdclk_ratio_program(struct drm_i915_private *i915,
+static void xe2lpd_mdclk_cdclk_ratio_program(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
intel_dbuf_mdclk_cdclk_ratio_update(i915,
- intel_mdclk_cdclk_ratio(i915, cdclk_config),
+ intel_mdclk_cdclk_ratio(display, cdclk_config),
cdclk_config->joined_mbus);
}
-static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915,
+static bool cdclk_compute_crawl_and_squash_midpoint(struct intel_display *display,
const struct intel_cdclk_config *old_cdclk_config,
const struct intel_cdclk_config *new_cdclk_config,
struct intel_cdclk_config *mid_cdclk_config)
@@ -1936,11 +1951,11 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91
return false;
/* Return if both Squash and Crawl are not present */
- if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915))
+ if (!HAS_CDCLK_CRAWL(display) || !HAS_CDCLK_SQUASH(display))
return false;
- old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk);
- new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk);
+ old_waveform = cdclk_squash_waveform(display, old_cdclk_config->cdclk);
+ new_waveform = cdclk_squash_waveform(display, new_cdclk_config->cdclk);
/* Return if Squash only or Crawl only is the desired action */
if (old_cdclk_config->vco == 0 || new_cdclk_config->vco == 0 ||
@@ -1957,7 +1972,7 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91
* Should not happen currently. We might need more midpoint
* transitions if we need to also change the cd2x divider.
*/
- if (drm_WARN_ON(&i915->drm, old_div != new_div))
+ if (drm_WARN_ON(display->drm, old_div != new_div))
return false;
*mid_cdclk_config = *new_cdclk_config;
@@ -1986,37 +2001,40 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91
/* make sure the mid clock came out sane */
- drm_WARN_ON(&i915->drm, mid_cdclk_config->cdclk <
+ drm_WARN_ON(display->drm, mid_cdclk_config->cdclk <
min(old_cdclk_config->cdclk, new_cdclk_config->cdclk));
- drm_WARN_ON(&i915->drm, mid_cdclk_config->cdclk >
- i915->display.cdclk.max_cdclk_freq);
- drm_WARN_ON(&i915->drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) !=
+ drm_WARN_ON(display->drm, mid_cdclk_config->cdclk >
+ display->cdclk.max_cdclk_freq);
+ drm_WARN_ON(display->drm, cdclk_squash_waveform(display, mid_cdclk_config->cdclk) !=
mid_waveform);
return true;
}
-static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv)
+static bool pll_enable_wa_needed(struct intel_display *display)
{
- return (DISPLAY_VER_FULL(dev_priv) == IP_VER(20, 0) ||
- DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 0) ||
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
+ return (DISPLAY_VER_FULL(display) == IP_VER(20, 0) ||
+ DISPLAY_VER_FULL(display) == IP_VER(14, 0) ||
IS_DG2(dev_priv)) &&
- dev_priv->display.cdclk.hw.vco > 0;
+ display->cdclk.hw.vco > 0;
}
-static u32 bxt_cdclk_ctl(struct drm_i915_private *i915,
+static u32 bxt_cdclk_ctl(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
int cdclk = cdclk_config->cdclk;
int vco = cdclk_config->vco;
u16 waveform;
u32 val;
- waveform = cdclk_squash_waveform(i915, cdclk);
+ waveform = cdclk_squash_waveform(display, cdclk);
- val = bxt_cdclk_cd2x_div_sel(i915, cdclk, vco, waveform) |
- bxt_cdclk_cd2x_pipe(i915, pipe);
+ val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform) |
+ bxt_cdclk_cd2x_pipe(display, pipe);
/*
* Disable SSA Precharge when CD clock frequency < 500 MHz,
@@ -2026,50 +2044,52 @@ static u32 bxt_cdclk_ctl(struct drm_i915_private *i915,
cdclk >= 500000)
val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
- if (DISPLAY_VER(i915) >= 20)
- val |= xe2lpd_mdclk_source_sel(i915);
+ if (DISPLAY_VER(display) >= 20)
+ val |= xe2lpd_mdclk_source_sel(display);
else
val |= skl_cdclk_decimal(cdclk);
return val;
}
-static void _bxt_set_cdclk(struct drm_i915_private *dev_priv,
+static void _bxt_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
int cdclk = cdclk_config->cdclk;
int vco = cdclk_config->vco;
- if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 &&
- !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) {
- if (dev_priv->display.cdclk.hw.vco != vco)
- adlp_cdclk_pll_crawl(dev_priv, vco);
- } else if (DISPLAY_VER(dev_priv) >= 11) {
+ if (HAS_CDCLK_CRAWL(display) && display->cdclk.hw.vco > 0 && vco > 0 &&
+ !cdclk_pll_is_unknown(display->cdclk.hw.vco)) {
+ if (display->cdclk.hw.vco != vco)
+ adlp_cdclk_pll_crawl(display, vco);
+ } else if (DISPLAY_VER(display) >= 11) {
/* wa_15010685871: dg2, mtl */
- if (pll_enable_wa_needed(dev_priv))
- dg2_cdclk_squash_program(dev_priv, 0);
+ if (pll_enable_wa_needed(display))
+ dg2_cdclk_squash_program(display, 0);
- icl_cdclk_pll_update(dev_priv, vco);
- } else
- bxt_cdclk_pll_update(dev_priv, vco);
+ icl_cdclk_pll_update(display, vco);
+ } else {
+ bxt_cdclk_pll_update(display, vco);
+ }
- if (HAS_CDCLK_SQUASH(dev_priv)) {
- u16 waveform = cdclk_squash_waveform(dev_priv, cdclk);
+ if (HAS_CDCLK_SQUASH(display)) {
+ u16 waveform = cdclk_squash_waveform(display, cdclk);
- dg2_cdclk_squash_program(dev_priv, waveform);
+ dg2_cdclk_squash_program(display, waveform);
}
- intel_de_write(dev_priv, CDCLK_CTL, bxt_cdclk_ctl(dev_priv, cdclk_config, pipe));
+ intel_de_write(display, CDCLK_CTL, bxt_cdclk_ctl(display, cdclk_config, pipe));
if (pipe != INVALID_PIPE)
- intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe));
+ intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe));
}
-static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
+static void bxt_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_cdclk_config mid_cdclk_config;
int cdclk = cdclk_config->cdclk;
int ret = 0;
@@ -2080,9 +2100,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
* mailbox communication, skip
* this step.
*/
- if (DISPLAY_VER(dev_priv) >= 14 || IS_DG2(dev_priv))
+ if (DISPLAY_VER(display) >= 14 || IS_DG2(dev_priv))
/* NOOP */;
- else if (DISPLAY_VER(dev_priv) >= 11)
+ else if (DISPLAY_VER(display) >= 11)
ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE,
@@ -2097,35 +2117,35 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
0x80000000, 150, 2);
if (ret) {
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Failed to inform PCU about cdclk change (err %d, freq %d)\n",
ret, cdclk);
return;
}
- if (DISPLAY_VER(dev_priv) >= 20 && cdclk < dev_priv->display.cdclk.hw.cdclk)
- xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config);
+ if (DISPLAY_VER(display) >= 20 && cdclk < display->cdclk.hw.cdclk)
+ xe2lpd_mdclk_cdclk_ratio_program(display, cdclk_config);
- if (cdclk_compute_crawl_and_squash_midpoint(dev_priv, &dev_priv->display.cdclk.hw,
+ if (cdclk_compute_crawl_and_squash_midpoint(display, &display->cdclk.hw,
cdclk_config, &mid_cdclk_config)) {
- _bxt_set_cdclk(dev_priv, &mid_cdclk_config, pipe);
- _bxt_set_cdclk(dev_priv, cdclk_config, pipe);
+ _bxt_set_cdclk(display, &mid_cdclk_config, pipe);
+ _bxt_set_cdclk(display, cdclk_config, pipe);
} else {
- _bxt_set_cdclk(dev_priv, cdclk_config, pipe);
+ _bxt_set_cdclk(display, cdclk_config, pipe);
}
- if (DISPLAY_VER(dev_priv) >= 20 && cdclk > dev_priv->display.cdclk.hw.cdclk)
- xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config);
+ if (DISPLAY_VER(display) >= 20 && cdclk > display->cdclk.hw.cdclk)
+ xe2lpd_mdclk_cdclk_ratio_program(display, cdclk_config);
- if (DISPLAY_VER(dev_priv) >= 14)
+ if (DISPLAY_VER(display) >= 14)
/*
* NOOP - No Pcode communication needed for
* Display versions 14 and beyond
*/;
- else if (DISPLAY_VER(dev_priv) >= 11 && !IS_DG2(dev_priv))
+ else if (DISPLAY_VER(display) >= 11 && !IS_DG2(dev_priv))
ret = snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
- if (DISPLAY_VER(dev_priv) < 11) {
+ if (DISPLAY_VER(display) < 11) {
/*
* The timeout isn't specified, the 2ms used here is based on
* experiment.
@@ -2138,42 +2158,42 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
150, 2);
}
if (ret) {
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"PCode CDCLK freq set failed, (err %d, freq %d)\n",
ret, cdclk);
return;
}
- intel_update_cdclk(dev_priv);
+ intel_update_cdclk(display);
- if (DISPLAY_VER(dev_priv) >= 11)
+ if (DISPLAY_VER(display) >= 11)
/*
* Can't read out the voltage level :(
* Let's just assume everything is as expected.
*/
- dev_priv->display.cdclk.hw.voltage_level = cdclk_config->voltage_level;
+ display->cdclk.hw.voltage_level = cdclk_config->voltage_level;
}
-static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
+static void bxt_sanitize_cdclk(struct intel_display *display)
{
u32 cdctl, expected;
int cdclk, vco;
- intel_update_cdclk(dev_priv);
- intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");
+ intel_update_cdclk(display);
+ intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK");
- if (dev_priv->display.cdclk.hw.vco == 0 ||
- dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass)
+ if (display->cdclk.hw.vco == 0 ||
+ display->cdclk.hw.cdclk == display->cdclk.hw.bypass)
goto sanitize;
/* Make sure this is a legal cdclk value for the platform */
- cdclk = bxt_calc_cdclk(dev_priv, dev_priv->display.cdclk.hw.cdclk);
- if (cdclk != dev_priv->display.cdclk.hw.cdclk)
+ cdclk = bxt_calc_cdclk(display, display->cdclk.hw.cdclk);
+ if (cdclk != display->cdclk.hw.cdclk)
goto sanitize;
/* Make sure the VCO is correct for the cdclk */
- vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
- if (vco != dev_priv->display.cdclk.hw.vco)
+ vco = bxt_calc_cdclk_pll_vco(display, cdclk);
+ if (vco != display->cdclk.hw.vco)
goto sanitize;
/*
@@ -2181,129 +2201,133 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
* set reserved MBZ bits in CDCLK_CTL at least during exiting from S4,
* so sanitize this register.
*/
- cdctl = intel_de_read(dev_priv, CDCLK_CTL);
- expected = bxt_cdclk_ctl(dev_priv, &dev_priv->display.cdclk.hw, INVALID_PIPE);
+ cdctl = intel_de_read(display, CDCLK_CTL);
+ expected = bxt_cdclk_ctl(display, &display->cdclk.hw, INVALID_PIPE);
/*
* Let's ignore the pipe field, since BIOS could have configured the
* dividers both synching to an active pipe, or asynchronously
* (PIPE_NONE).
*/
- cdctl &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE);
- expected &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE);
+ cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
+ expected &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
if (cdctl == expected)
/* All well; nothing to sanitize */
return;
sanitize:
- drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");
+ drm_dbg_kms(display->drm, "Sanitizing cdclk programmed by pre-os\n");
/* force cdclk programming */
- dev_priv->display.cdclk.hw.cdclk = 0;
+ display->cdclk.hw.cdclk = 0;
/* force full PLL disable + enable */
- dev_priv->display.cdclk.hw.vco = ~0;
+ display->cdclk.hw.vco = ~0;
}
-static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv)
+static void bxt_cdclk_init_hw(struct intel_display *display)
{
struct intel_cdclk_config cdclk_config;
- bxt_sanitize_cdclk(dev_priv);
+ bxt_sanitize_cdclk(display);
- if (dev_priv->display.cdclk.hw.cdclk != 0 &&
- dev_priv->display.cdclk.hw.vco != 0)
+ if (display->cdclk.hw.cdclk != 0 &&
+ display->cdclk.hw.vco != 0)
return;
- cdclk_config = dev_priv->display.cdclk.hw;
+ cdclk_config = display->cdclk.hw;
/*
* FIXME:
* - The initial CDCLK needs to be read from VBT.
* Need to make this change after VBT has changes for BXT.
*/
- cdclk_config.cdclk = bxt_calc_cdclk(dev_priv, 0);
- cdclk_config.vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk_config.cdclk);
+ cdclk_config.cdclk = bxt_calc_cdclk(display, 0);
+ cdclk_config.vco = bxt_calc_cdclk_pll_vco(display, cdclk_config.cdclk);
cdclk_config.voltage_level =
- intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk);
+ intel_cdclk_calc_voltage_level(display, cdclk_config.cdclk);
- bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
+ bxt_set_cdclk(display, &cdclk_config, INVALID_PIPE);
}
-static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
+static void bxt_cdclk_uninit_hw(struct intel_display *display)
{
- struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw;
+ struct intel_cdclk_config cdclk_config = display->cdclk.hw;
cdclk_config.cdclk = cdclk_config.bypass;
cdclk_config.vco = 0;
cdclk_config.voltage_level =
- intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk);
+ intel_cdclk_calc_voltage_level(display, cdclk_config.cdclk);
- bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
+ bxt_set_cdclk(display, &cdclk_config, INVALID_PIPE);
}
/**
* intel_cdclk_init_hw - Initialize CDCLK hardware
- * @i915: i915 device
+ * @display: display instance
*
- * Initialize CDCLK. This consists mainly of initializing dev_priv->display.cdclk.hw and
+ * Initialize CDCLK. This consists mainly of initializing display->cdclk.hw and
* sanitizing the state of the hardware if needed. This is generally done only
* during the display core initialization sequence, after which the DMC will
* take care of turning CDCLK off/on as needed.
*/
-void intel_cdclk_init_hw(struct drm_i915_private *i915)
+void intel_cdclk_init_hw(struct intel_display *display)
{
- if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915))
- bxt_cdclk_init_hw(i915);
- else if (DISPLAY_VER(i915) == 9)
- skl_cdclk_init_hw(i915);
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
+ if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915))
+ bxt_cdclk_init_hw(display);
+ else if (DISPLAY_VER(display) == 9)
+ skl_cdclk_init_hw(display);
}
/**
* intel_cdclk_uninit_hw - Uninitialize CDCLK hardware
- * @i915: i915 device
+ * @display: display instance
*
* Uninitialize CDCLK. This is done only during the display core
* uninitialization sequence.
*/
-void intel_cdclk_uninit_hw(struct drm_i915_private *i915)
+void intel_cdclk_uninit_hw(struct intel_display *display)
{
- if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915))
- bxt_cdclk_uninit_hw(i915);
- else if (DISPLAY_VER(i915) == 9)
- skl_cdclk_uninit_hw(i915);
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
+ if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915))
+ bxt_cdclk_uninit_hw(display);
+ else if (DISPLAY_VER(display) == 9)
+ skl_cdclk_uninit_hw(display);
}
-static bool intel_cdclk_can_crawl_and_squash(struct drm_i915_private *i915,
+static bool intel_cdclk_can_crawl_and_squash(struct intel_display *display,
const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b)
{
u16 old_waveform;
u16 new_waveform;
- drm_WARN_ON(&i915->drm, cdclk_pll_is_unknown(a->vco));
+ drm_WARN_ON(display->drm, cdclk_pll_is_unknown(a->vco));
if (a->vco == 0 || b->vco == 0)
return false;
- if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915))
+ if (!HAS_CDCLK_CRAWL(display) || !HAS_CDCLK_SQUASH(display))
return false;
- old_waveform = cdclk_squash_waveform(i915, a->cdclk);
- new_waveform = cdclk_squash_waveform(i915, b->cdclk);
+ old_waveform = cdclk_squash_waveform(display, a->cdclk);
+ new_waveform = cdclk_squash_waveform(display, b->cdclk);
return a->vco != b->vco &&
old_waveform != new_waveform;
}
-static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv,
+static bool intel_cdclk_can_crawl(struct intel_display *display,
const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b)
{
int a_div, b_div;
- if (!HAS_CDCLK_CRAWL(dev_priv))
+ if (!HAS_CDCLK_CRAWL(display))
return false;
/*
@@ -2319,7 +2343,7 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv,
a->ref == b->ref;
}
-static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv,
+static bool intel_cdclk_can_squash(struct intel_display *display,
const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b)
{
@@ -2329,7 +2353,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv,
* the moment all platforms with squasher use a fixed cd2x
* divider.
*/
- if (!HAS_CDCLK_SQUASH(dev_priv))
+ if (!HAS_CDCLK_SQUASH(display))
return false;
return a->cdclk != b->cdclk &&
@@ -2358,7 +2382,7 @@ bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,
/**
* intel_cdclk_can_cd2x_update - Determine if changing between the two CDCLK
* configurations requires only a cd2x divider update
- * @dev_priv: i915 device
+ * @display: display instance
* @a: first CDCLK configuration
* @b: second CDCLK configuration
*
@@ -2366,12 +2390,14 @@ bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,
* True if changing between the two CDCLK configurations
* can be done with just a cd2x divider update, false if not.
*/
-static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
+static bool intel_cdclk_can_cd2x_update(struct intel_display *display,
const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
/* Older hw doesn't have the capability */
- if (DISPLAY_VER(dev_priv) < 10 && !IS_BROXTON(dev_priv))
+ if (DISPLAY_VER(display) < 10 && !IS_BROXTON(dev_priv))
return false;
/*
@@ -2380,7 +2406,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
* the moment all platforms with squasher use a fixed cd2x
* divider.
*/
- if (HAS_CDCLK_SQUASH(dev_priv))
+ if (HAS_CDCLK_SQUASH(display))
return false;
return a->cdclk != b->cdclk &&
@@ -2404,23 +2430,24 @@ static bool intel_cdclk_changed(const struct intel_cdclk_config *a,
a->voltage_level != b->voltage_level;
}
-void intel_cdclk_dump_config(struct drm_i915_private *i915,
+void intel_cdclk_dump_config(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
const char *context)
{
- drm_dbg_kms(&i915->drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n",
+ drm_dbg_kms(display->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);
}
-static void intel_pcode_notify(struct drm_i915_private *i915,
+static void intel_pcode_notify(struct intel_display *display,
u8 voltage_level,
u8 active_pipe_count,
u16 cdclk,
bool cdclk_update_valid,
bool pipe_count_update_valid)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
int ret;
u32 update_mask = 0;
@@ -2441,26 +2468,27 @@ static void intel_pcode_notify(struct drm_i915_private *i915,
SKL_CDCLK_READY_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE, 3);
if (ret)
- drm_err(&i915->drm,
+ drm_err(display->drm,
"Failed to inform PCU about display config (err %d)\n",
ret);
}
-static void intel_set_cdclk(struct drm_i915_private *dev_priv,
+static void intel_set_cdclk(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe, const char *context)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder;
- if (!intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config))
+ if (!intel_cdclk_changed(&display->cdclk.hw, cdclk_config))
return;
- if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->display.funcs.cdclk->set_cdclk))
+ if (drm_WARN_ON_ONCE(display->drm, !display->funcs.cdclk->set_cdclk))
return;
- intel_cdclk_dump_config(dev_priv, cdclk_config, context);
+ intel_cdclk_dump_config(display, cdclk_config, context);
- for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
+ for_each_intel_encoder_with_psr(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_psr_pause(intel_dp);
@@ -2473,24 +2501,24 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv,
* functions use cdclk. Not all platforms/ports do,
* but we'll lock them all for simplicity.
*/
- mutex_lock(&dev_priv->display.gmbus.mutex);
- for_each_intel_dp(&dev_priv->drm, encoder) {
+ mutex_lock(&display->gmbus.mutex);
+ for_each_intel_dp(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
mutex_lock_nest_lock(&intel_dp->aux.hw_mutex,
- &dev_priv->display.gmbus.mutex);
+ &display->gmbus.mutex);
}
- intel_cdclk_set_cdclk(dev_priv, cdclk_config, pipe);
+ intel_cdclk_set_cdclk(display, cdclk_config, pipe);
- for_each_intel_dp(&dev_priv->drm, encoder) {
+ for_each_intel_dp(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
mutex_unlock(&intel_dp->aux.hw_mutex);
}
- mutex_unlock(&dev_priv->display.gmbus.mutex);
+ mutex_unlock(&display->gmbus.mutex);
- for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
+ for_each_intel_encoder_with_psr(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_psr_resume(intel_dp);
@@ -2498,17 +2526,17 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv,
intel_audio_cdclk_change_post(dev_priv);
- if (drm_WARN(&dev_priv->drm,
- intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config),
+ if (drm_WARN(display->drm,
+ intel_cdclk_changed(&display->cdclk.hw, cdclk_config),
"cdclk state doesn't match!\n")) {
- intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "[hw state]");
- intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]");
+ intel_cdclk_dump_config(display, &display->cdclk.hw, "[hw state]");
+ intel_cdclk_dump_config(display, cdclk_config, "[sw state]");
}
}
static void intel_cdclk_pcode_pre_notify(struct intel_atomic_state *state)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
const struct intel_cdclk_state *old_cdclk_state =
intel_atomic_get_old_cdclk_state(state);
const struct intel_cdclk_state *new_cdclk_state =
@@ -2547,13 +2575,13 @@ static void intel_cdclk_pcode_pre_notify(struct intel_atomic_state *state)
if (update_pipe_count)
num_active_pipes = hweight8(new_cdclk_state->active_pipes);
- intel_pcode_notify(i915, voltage_level, num_active_pipes, cdclk,
+ intel_pcode_notify(display, voltage_level, num_active_pipes, cdclk,
change_cdclk, update_pipe_count);
}
static void intel_cdclk_pcode_post_notify(struct intel_atomic_state *state)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
const struct intel_cdclk_state *new_cdclk_state =
intel_atomic_get_new_cdclk_state(state);
const struct intel_cdclk_state *old_cdclk_state =
@@ -2584,7 +2612,7 @@ static void intel_cdclk_pcode_post_notify(struct intel_atomic_state *state)
if (update_pipe_count)
num_active_pipes = hweight8(new_cdclk_state->active_pipes);
- intel_pcode_notify(i915, voltage_level, num_active_pipes, cdclk,
+ intel_pcode_notify(display, voltage_level, num_active_pipes, cdclk,
update_cdclk, update_pipe_count);
}
@@ -2609,7 +2637,8 @@ bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state)
void
intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
+ struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_cdclk_state *old_cdclk_state =
intel_atomic_get_old_cdclk_state(state);
const struct intel_cdclk_state *new_cdclk_state =
@@ -2646,9 +2675,9 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
*/
cdclk_config.joined_mbus = old_cdclk_state->actual.joined_mbus;
- drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
+ drm_WARN_ON(display->drm, !new_cdclk_state->base.changed);
- intel_set_cdclk(i915, &cdclk_config, pipe,
+ intel_set_cdclk(display, &cdclk_config, pipe,
"Pre changing CDCLK to");
}
@@ -2662,7 +2691,8 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
void
intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
+ struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_cdclk_state *old_cdclk_state =
intel_atomic_get_old_cdclk_state(state);
const struct intel_cdclk_state *new_cdclk_state =
@@ -2682,20 +2712,21 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
else
pipe = INVALID_PIPE;
- drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
+ drm_WARN_ON(display->drm, !new_cdclk_state->base.changed);
- intel_set_cdclk(i915, &new_cdclk_state->actual, pipe,
+ intel_set_cdclk(display, &new_cdclk_state->actual, pipe,
"Post changing CDCLK to");
}
static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int pixel_rate = crtc_state->pixel_rate;
- if (DISPLAY_VER(dev_priv) >= 10)
+ if (DISPLAY_VER(display) >= 10)
return DIV_ROUND_UP(pixel_rate, 2);
- else if (DISPLAY_VER(dev_priv) == 9 ||
+ else if (DISPLAY_VER(display) == 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
return pixel_rate;
else if (IS_CHERRYVIEW(dev_priv))
@@ -2709,11 +2740,11 @@ static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
static int intel_planes_min_cdclk(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);
+ struct intel_display *display = to_intel_display(crtc);
struct intel_plane *plane;
int min_cdclk = 0;
- for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane)
+ for_each_intel_plane_on_crtc(display->drm, crtc, plane)
min_cdclk = max(crtc_state->min_cdclk[plane->id], min_cdclk);
return min_cdclk;
@@ -2722,7 +2753,7 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)
static int intel_vdsc_min_cdclk(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_display *display = to_intel_display(crtc);
int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
int min_cdclk = 0;
@@ -2751,7 +2782,7 @@ static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
* Since PPC = 2 with bigjoiner
* => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits
*/
- int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24;
+ int bigjoiner_interface_bits = DISPLAY_VER(display) >= 14 ? 36 : 24;
int min_cdclk_bj =
(fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) *
pixel_clock) / (2 * bigjoiner_interface_bits);
@@ -2764,8 +2795,8 @@ static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv =
- to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int min_cdclk;
if (!crtc_state->hw.enable)
@@ -2786,10 +2817,10 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
crtc_state->has_audio &&
crtc_state->port_clock >= 540000 &&
crtc_state->lane_count == 4) {
- if (DISPLAY_VER(dev_priv) == 10) {
+ if (DISPLAY_VER(display) == 10) {
/* Display WA #1145: glk */
min_cdclk = max(316800, min_cdclk);
- } else if (DISPLAY_VER(dev_priv) == 9 || IS_BROADWELL(dev_priv)) {
+ } else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv)) {
/* Display WA #1144: skl,bxt */
min_cdclk = max(432000, min_cdclk);
}
@@ -2799,7 +2830,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
* According to BSpec, "The CD clock frequency must be at least twice
* the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
*/
- if (crtc_state->has_audio && DISPLAY_VER(dev_priv) >= 9)
+ if (crtc_state->has_audio && DISPLAY_VER(display) >= 9)
min_cdclk = max(2 * 96000, min_cdclk);
/*
@@ -2841,7 +2872,8 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
static int intel_compute_min_cdclk(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_cdclk_state *cdclk_state =
intel_atomic_get_new_cdclk_state(state);
const struct intel_bw_state *bw_state;
@@ -2884,7 +2916,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)
min_cdclk = max(cdclk_state->force_min_cdclk,
cdclk_state->bw_min_cdclk);
- for_each_pipe(dev_priv, pipe)
+ for_each_pipe(display, pipe)
min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);
/*
@@ -2899,10 +2931,10 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)
!is_power_of_2(cdclk_state->active_pipes))
min_cdclk = max(2 * 96000, min_cdclk);
- if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) {
- drm_dbg_kms(&dev_priv->drm,
+ if (min_cdclk > display->cdclk.max_cdclk_freq) {
+ drm_dbg_kms(display->drm,
"required cdclk (%d kHz) exceeds max (%d kHz)\n",
- min_cdclk, dev_priv->display.cdclk.max_cdclk_freq);
+ min_cdclk, display->cdclk.max_cdclk_freq);
return -EINVAL;
}
@@ -2924,7 +2956,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)
*/
static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_cdclk_state *cdclk_state =
intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
@@ -2952,7 +2984,7 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
}
min_voltage_level = 0;
- for_each_pipe(dev_priv, pipe)
+ for_each_pipe(display, pipe)
min_voltage_level = max(cdclk_state->min_voltage_level[pipe],
min_voltage_level);
@@ -2961,7 +2993,7 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_cdclk_state *cdclk_state =
intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk;
@@ -2970,18 +3002,18 @@ static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state)
if (min_cdclk < 0)
return min_cdclk;
- cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
+ cdclk = vlv_calc_cdclk(display, min_cdclk);
cdclk_state->logical.cdclk = cdclk;
cdclk_state->logical.voltage_level =
- vlv_calc_voltage_level(dev_priv, cdclk);
+ vlv_calc_voltage_level(display, cdclk);
if (!cdclk_state->active_pipes) {
- cdclk = vlv_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk);
+ cdclk = vlv_calc_cdclk(display, cdclk_state->force_min_cdclk);
cdclk_state->actual.cdclk = cdclk;
cdclk_state->actual.voltage_level =
- vlv_calc_voltage_level(dev_priv, cdclk);
+ vlv_calc_voltage_level(display, cdclk);
} else {
cdclk_state->actual = cdclk_state->logical;
}
@@ -3020,7 +3052,7 @@ static int bdw_modeset_calc_cdclk(struct intel_atomic_state *state)
static int skl_dpll0_vco(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_cdclk_state *cdclk_state =
intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
@@ -3029,7 +3061,7 @@ static int skl_dpll0_vco(struct intel_atomic_state *state)
vco = cdclk_state->logical.vco;
if (!vco)
- vco = dev_priv->display.cdclk.skl_preferred_vco_freq;
+ vco = display->cdclk.skl_preferred_vco_freq;
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
if (!crtc_state->hw.enable)
@@ -3091,7 +3123,7 @@ static int skl_modeset_calc_cdclk(struct intel_atomic_state *state)
static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_cdclk_state *cdclk_state =
intel_atomic_get_new_cdclk_state(state);
int min_cdclk, min_voltage_level, cdclk, vco;
@@ -3104,23 +3136,23 @@ static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state)
if (min_voltage_level < 0)
return min_voltage_level;
- cdclk = bxt_calc_cdclk(dev_priv, min_cdclk);
- vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
+ cdclk = bxt_calc_cdclk(display, min_cdclk);
+ vco = bxt_calc_cdclk_pll_vco(display, cdclk);
cdclk_state->logical.vco = vco;
cdclk_state->logical.cdclk = cdclk;
cdclk_state->logical.voltage_level =
max_t(int, min_voltage_level,
- intel_cdclk_calc_voltage_level(dev_priv, cdclk));
+ intel_cdclk_calc_voltage_level(display, cdclk));
if (!cdclk_state->active_pipes) {
- cdclk = bxt_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk);
- vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
+ cdclk = bxt_calc_cdclk(display, cdclk_state->force_min_cdclk);
+ vco = bxt_calc_cdclk_pll_vco(display, cdclk);
cdclk_state->actual.vco = vco;
cdclk_state->actual.cdclk = cdclk;
cdclk_state->actual.voltage_level =
- intel_cdclk_calc_voltage_level(dev_priv, cdclk);
+ intel_cdclk_calc_voltage_level(display, cdclk);
} else {
cdclk_state->actual = cdclk_state->logical;
}
@@ -3172,10 +3204,10 @@ static const struct intel_global_state_funcs intel_cdclk_funcs = {
struct intel_cdclk_state *
intel_atomic_get_cdclk_state(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_global_state *cdclk_state;
- cdclk_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.cdclk.obj);
+ cdclk_state = intel_atomic_get_global_obj_state(state, &display->cdclk.obj);
if (IS_ERR(cdclk_state))
return ERR_CAST(cdclk_state);
@@ -3231,24 +3263,26 @@ int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joi
return intel_atomic_lock_global_state(&cdclk_state->base);
}
-int intel_cdclk_init(struct drm_i915_private *dev_priv)
+int intel_cdclk_init(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_cdclk_state *cdclk_state;
cdclk_state = kzalloc(sizeof(*cdclk_state), GFP_KERNEL);
if (!cdclk_state)
return -ENOMEM;
- intel_atomic_global_obj_init(dev_priv, &dev_priv->display.cdclk.obj,
+ intel_atomic_global_obj_init(dev_priv, &display->cdclk.obj,
&cdclk_state->base, &intel_cdclk_funcs);
return 0;
}
-static bool intel_cdclk_need_serialize(struct drm_i915_private *i915,
+static bool intel_cdclk_need_serialize(struct intel_display *display,
const struct intel_cdclk_state *old_cdclk_state,
const struct intel_cdclk_state *new_cdclk_state)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
bool power_well_cnt_changed = hweight8(old_cdclk_state->active_pipes) !=
hweight8(new_cdclk_state->active_pipes);
bool cdclk_changed = intel_cdclk_changed(&old_cdclk_state->actual,
@@ -3262,7 +3296,7 @@ static bool intel_cdclk_need_serialize(struct drm_i915_private *i915,
int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
const struct intel_cdclk_state *old_cdclk_state;
struct intel_cdclk_state *new_cdclk_state;
enum pipe pipe = INVALID_PIPE;
@@ -3281,7 +3315,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
if (ret)
return ret;
- if (intel_cdclk_need_serialize(dev_priv, old_cdclk_state, new_cdclk_state)) {
+ if (intel_cdclk_need_serialize(display, old_cdclk_state, new_cdclk_state)) {
/*
* Also serialize commits across all crtcs
* if the actual hw needs to be poked.
@@ -3301,14 +3335,14 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
}
if (is_power_of_2(new_cdclk_state->active_pipes) &&
- intel_cdclk_can_cd2x_update(dev_priv,
+ intel_cdclk_can_cd2x_update(display,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
pipe = ilog2(new_cdclk_state->active_pipes);
- crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
if (IS_ERR(crtc_state))
@@ -3318,25 +3352,25 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
pipe = INVALID_PIPE;
}
- if (intel_cdclk_can_crawl_and_squash(dev_priv,
+ if (intel_cdclk_can_crawl_and_squash(display,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"Can change cdclk via crawling and squashing\n");
- } else if (intel_cdclk_can_squash(dev_priv,
+ } else if (intel_cdclk_can_squash(display,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"Can change cdclk via squashing\n");
- } else if (intel_cdclk_can_crawl(dev_priv,
+ } else if (intel_cdclk_can_crawl(display,
&old_cdclk_state->actual,
&new_cdclk_state->actual)) {
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"Can change cdclk via crawling\n");
} else if (pipe != INVALID_PIPE) {
new_cdclk_state->pipe = pipe;
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"Can change cdclk cd2x divider with pipe %c active\n",
pipe_name(pipe));
} else if (intel_cdclk_clock_changed(&old_cdclk_state->actual,
@@ -3348,24 +3382,24 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
new_cdclk_state->disable_pipes = true;
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"Modeset required for cdclk change\n");
}
- if (intel_mdclk_cdclk_ratio(dev_priv, &old_cdclk_state->actual) !=
- intel_mdclk_cdclk_ratio(dev_priv, &new_cdclk_state->actual)) {
- int ratio = intel_mdclk_cdclk_ratio(dev_priv, &new_cdclk_state->actual);
+ if (intel_mdclk_cdclk_ratio(display, &old_cdclk_state->actual) !=
+ intel_mdclk_cdclk_ratio(display, &new_cdclk_state->actual)) {
+ int ratio = intel_mdclk_cdclk_ratio(display, &new_cdclk_state->actual);
ret = intel_dbuf_state_set_mdclk_cdclk_ratio(state, ratio);
if (ret)
return ret;
}
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"New cdclk calculated to be logical %u kHz, actual %u kHz\n",
new_cdclk_state->logical.cdclk,
new_cdclk_state->actual.cdclk);
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"New voltage level calculated to be logical %u, actual %u\n",
new_cdclk_state->logical.voltage_level,
new_cdclk_state->actual.voltage_level);
@@ -3373,18 +3407,19 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
return 0;
}
-static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
+static int intel_compute_max_dotclk(struct intel_display *display)
{
- int max_cdclk_freq = dev_priv->display.cdclk.max_cdclk_freq;
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+ int max_cdclk_freq = display->cdclk.max_cdclk_freq;
- if (DISPLAY_VER(dev_priv) >= 10)
+ if (DISPLAY_VER(display) >= 10)
return 2 * max_cdclk_freq;
- else if (DISPLAY_VER(dev_priv) == 9 ||
+ else if (DISPLAY_VER(display) == 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
return max_cdclk_freq;
else if (IS_CHERRYVIEW(dev_priv))
return max_cdclk_freq*95/100;
- else if (DISPLAY_VER(dev_priv) < 4)
+ else if (DISPLAY_VER(display) < 4)
return 2*max_cdclk_freq*90/100;
else
return max_cdclk_freq*90/100;
@@ -3392,34 +3427,36 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
/**
* intel_update_max_cdclk - Determine the maximum support CDCLK frequency
- * @dev_priv: i915 device
+ * @display: display instance
*
* Determine the maximum CDCLK frequency the platform supports, and also
* derive the maximum dot clock frequency the maximum CDCLK frequency
* allows.
*/
-void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
+void intel_update_max_cdclk(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
- if (dev_priv->display.cdclk.hw.ref == 24000)
- dev_priv->display.cdclk.max_cdclk_freq = 552000;
+ if (display->cdclk.hw.ref == 24000)
+ display->cdclk.max_cdclk_freq = 552000;
else
- dev_priv->display.cdclk.max_cdclk_freq = 556800;
- } else if (DISPLAY_VER(dev_priv) >= 11) {
- if (dev_priv->display.cdclk.hw.ref == 24000)
- dev_priv->display.cdclk.max_cdclk_freq = 648000;
+ display->cdclk.max_cdclk_freq = 556800;
+ } else if (DISPLAY_VER(display) >= 11) {
+ if (display->cdclk.hw.ref == 24000)
+ display->cdclk.max_cdclk_freq = 648000;
else
- dev_priv->display.cdclk.max_cdclk_freq = 652800;
+ display->cdclk.max_cdclk_freq = 652800;
} else if (IS_GEMINILAKE(dev_priv)) {
- dev_priv->display.cdclk.max_cdclk_freq = 316800;
+ display->cdclk.max_cdclk_freq = 316800;
} else if (IS_BROXTON(dev_priv)) {
- dev_priv->display.cdclk.max_cdclk_freq = 624000;
- } else if (DISPLAY_VER(dev_priv) == 9) {
- u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
+ display->cdclk.max_cdclk_freq = 624000;
+ } else if (DISPLAY_VER(display) == 9) {
+ u32 limit = intel_de_read(display, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
int max_cdclk, vco;
- vco = dev_priv->display.cdclk.skl_preferred_vco_freq;
- drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
+ vco = display->cdclk.skl_preferred_vco_freq;
+ drm_WARN_ON(display->drm, vco != 8100000 && vco != 8640000);
/*
* Use the lower (vco 8640) cdclk values as a
@@ -3435,7 +3472,7 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
else
max_cdclk = 308571;
- dev_priv->display.cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
+ display->cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
} else if (IS_BROADWELL(dev_priv)) {
/*
* FIXME with extra cooling we can allow
@@ -3443,41 +3480,43 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
* How can we know if extra cooling is
* available? PCI ID, VTB, something else?
*/
- if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
- dev_priv->display.cdclk.max_cdclk_freq = 450000;
+ if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT)
+ display->cdclk.max_cdclk_freq = 450000;
else if (IS_BROADWELL_ULX(dev_priv))
- dev_priv->display.cdclk.max_cdclk_freq = 450000;
+ display->cdclk.max_cdclk_freq = 450000;
else if (IS_BROADWELL_ULT(dev_priv))
- dev_priv->display.cdclk.max_cdclk_freq = 540000;
+ display->cdclk.max_cdclk_freq = 540000;
else
- dev_priv->display.cdclk.max_cdclk_freq = 675000;
+ display->cdclk.max_cdclk_freq = 675000;
} else if (IS_CHERRYVIEW(dev_priv)) {
- dev_priv->display.cdclk.max_cdclk_freq = 320000;
+ display->cdclk.max_cdclk_freq = 320000;
} else if (IS_VALLEYVIEW(dev_priv)) {
- dev_priv->display.cdclk.max_cdclk_freq = 400000;
+ display->cdclk.max_cdclk_freq = 400000;
} else {
/* otherwise assume cdclk is fixed */
- dev_priv->display.cdclk.max_cdclk_freq = dev_priv->display.cdclk.hw.cdclk;
+ display->cdclk.max_cdclk_freq = display->cdclk.hw.cdclk;
}
- dev_priv->display.cdclk.max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
+ display->cdclk.max_dotclk_freq = intel_compute_max_dotclk(display);
- drm_dbg(&dev_priv->drm, "Max CD clock rate: %d kHz\n",
- dev_priv->display.cdclk.max_cdclk_freq);
+ drm_dbg(display->drm, "Max CD clock rate: %d kHz\n",
+ display->cdclk.max_cdclk_freq);
- drm_dbg(&dev_priv->drm, "Max dotclock rate: %d kHz\n",
- dev_priv->display.cdclk.max_dotclk_freq);
+ drm_dbg(display->drm, "Max dotclock rate: %d kHz\n",
+ display->cdclk.max_dotclk_freq);
}
/**
* intel_update_cdclk - Determine the current CDCLK frequency
- * @dev_priv: i915 device
+ * @display: display instance
*
* Determine the current CDCLK frequency.
*/
-void intel_update_cdclk(struct drm_i915_private *dev_priv)
+void intel_update_cdclk(struct intel_display *display)
{
- intel_cdclk_get_cdclk(dev_priv, &dev_priv->display.cdclk.hw);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
+ intel_cdclk_get_cdclk(display, &display->cdclk.hw);
/*
* 9:0 CMBUS [sic] CDCLK frequency (cdfreq):
@@ -3486,28 +3525,29 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv)
* generate GMBus clock. This will vary with the cdclk freq.
*/
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- intel_de_write(dev_priv, GMBUSFREQ_VLV,
- DIV_ROUND_UP(dev_priv->display.cdclk.hw.cdclk, 1000));
+ intel_de_write(display, GMBUSFREQ_VLV,
+ DIV_ROUND_UP(display->cdclk.hw.cdclk, 1000));
}
-static int dg1_rawclk(struct drm_i915_private *dev_priv)
+static int dg1_rawclk(struct intel_display *display)
{
/*
* DG1 always uses a 38.4 MHz rawclk. The bspec tells us
* "Program Numerator=2, Denominator=4, Divider=37 decimal."
*/
- intel_de_write(dev_priv, PCH_RAWCLK_FREQ,
+ intel_de_write(display, PCH_RAWCLK_FREQ,
CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2));
return 38400;
}
-static int cnp_rawclk(struct drm_i915_private *dev_priv)
+static int cnp_rawclk(struct intel_display *display)
{
- u32 rawclk;
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
int divider, fraction;
+ u32 rawclk;
- if (intel_de_read(dev_priv, SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) {
+ if (intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) {
/* 24 MHz */
divider = 24000;
fraction = 0;
@@ -3527,37 +3567,42 @@ static int cnp_rawclk(struct drm_i915_private *dev_priv)
rawclk |= ICP_RAWCLK_NUM(numerator);
}
- intel_de_write(dev_priv, PCH_RAWCLK_FREQ, rawclk);
+ intel_de_write(display, PCH_RAWCLK_FREQ, rawclk);
return divider + fraction;
}
-static int pch_rawclk(struct drm_i915_private *dev_priv)
+static int pch_rawclk(struct intel_display *display)
{
- return (intel_de_read(dev_priv, PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
+ return (intel_de_read(display, PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
}
-static int vlv_hrawclk(struct drm_i915_private *dev_priv)
+static int vlv_hrawclk(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
/* RAWCLK_FREQ_VLV register updated from power well code */
return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
CCK_DISPLAY_REF_CLOCK_CONTROL);
}
-static int i9xx_hrawclk(struct drm_i915_private *i915)
+static int i9xx_hrawclk(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
/* hrawclock is 1/4 the FSB frequency */
return DIV_ROUND_CLOSEST(i9xx_fsb_freq(i915), 4);
}
/**
* intel_read_rawclk - Determine the current RAWCLK frequency
- * @dev_priv: i915 device
+ * @display: display instance
*
* Determine the current RAWCLK frequency. RAWCLK is a fixed
* frequency clock so this needs to done only once.
*/
-u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
+u32 intel_read_rawclk(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 freq;
if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL)
@@ -3568,15 +3613,15 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
*/
freq = 38400;
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
- freq = dg1_rawclk(dev_priv);
+ freq = dg1_rawclk(display);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
- freq = cnp_rawclk(dev_priv);
+ freq = cnp_rawclk(display);
else if (HAS_PCH_SPLIT(dev_priv))
- freq = pch_rawclk(dev_priv);
+ freq = pch_rawclk(display);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- freq = vlv_hrawclk(dev_priv);
- else if (DISPLAY_VER(dev_priv) >= 3)
- freq = i9xx_hrawclk(dev_priv);
+ freq = vlv_hrawclk(display);
+ else if (DISPLAY_VER(display) >= 3)
+ freq = i9xx_hrawclk(display);
else
/* no rawclk on other platforms, or no need to know it */
return 0;
@@ -3586,23 +3631,23 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
static int i915_cdclk_info_show(struct seq_file *m, void *unused)
{
- struct drm_i915_private *i915 = m->private;
+ struct intel_display *display = m->private;
- seq_printf(m, "Current CD clock frequency: %d kHz\n", i915->display.cdclk.hw.cdclk);
- seq_printf(m, "Max CD clock frequency: %d kHz\n", i915->display.cdclk.max_cdclk_freq);
- seq_printf(m, "Max pixel clock frequency: %d kHz\n", i915->display.cdclk.max_dotclk_freq);
+ seq_printf(m, "Current CD clock frequency: %d kHz\n", display->cdclk.hw.cdclk);
+ seq_printf(m, "Max CD clock frequency: %d kHz\n", display->cdclk.max_cdclk_freq);
+ seq_printf(m, "Max pixel clock frequency: %d kHz\n", display->cdclk.max_dotclk_freq);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(i915_cdclk_info);
-void intel_cdclk_debugfs_register(struct drm_i915_private *i915)
+void intel_cdclk_debugfs_register(struct intel_display *display)
{
- struct drm_minor *minor = i915->drm.primary;
+ struct drm_minor *minor = display->drm->primary;
debugfs_create_file("i915_cdclk_info", 0444, minor->debugfs_root,
- i915, &i915_cdclk_info_fops);
+ display, &i915_cdclk_info_fops);
}
static const struct intel_cdclk_funcs rplu_cdclk_funcs = {
@@ -3743,97 +3788,99 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = {
/**
* intel_init_cdclk_hooks - Initialize CDCLK related modesetting hooks
- * @dev_priv: i915 device
+ * @display: display instance
*/
-void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
-{
- if (DISPLAY_VER(dev_priv) >= 20) {
- dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
- dev_priv->display.cdclk.table = xe2lpd_cdclk_table;
- } else if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1)) {
- dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
- dev_priv->display.cdclk.table = xe2hpd_cdclk_table;
- } else if (DISPLAY_VER(dev_priv) >= 14) {
- dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
- dev_priv->display.cdclk.table = mtl_cdclk_table;
+void intel_init_cdclk_hooks(struct intel_display *display)
+{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
+ if (DISPLAY_VER(display) >= 20) {
+ display->funcs.cdclk = &rplu_cdclk_funcs;
+ display->cdclk.table = xe2lpd_cdclk_table;
+ } else if (DISPLAY_VER_FULL(display) >= IP_VER(14, 1)) {
+ display->funcs.cdclk = &rplu_cdclk_funcs;
+ display->cdclk.table = xe2hpd_cdclk_table;
+ } else if (DISPLAY_VER(display) >= 14) {
+ display->funcs.cdclk = &rplu_cdclk_funcs;
+ display->cdclk.table = mtl_cdclk_table;
} else if (IS_DG2(dev_priv)) {
- dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
- dev_priv->display.cdclk.table = dg2_cdclk_table;
+ display->funcs.cdclk = &tgl_cdclk_funcs;
+ display->cdclk.table = dg2_cdclk_table;
} else if (IS_ALDERLAKE_P(dev_priv)) {
/* Wa_22011320316:adl-p[a0] */
if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) {
- dev_priv->display.cdclk.table = adlp_a_step_cdclk_table;
- dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
+ display->cdclk.table = adlp_a_step_cdclk_table;
+ display->funcs.cdclk = &tgl_cdclk_funcs;
} else if (IS_RAPTORLAKE_U(dev_priv)) {
- dev_priv->display.cdclk.table = rplu_cdclk_table;
- dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
+ display->cdclk.table = rplu_cdclk_table;
+ display->funcs.cdclk = &rplu_cdclk_funcs;
} else {
- dev_priv->display.cdclk.table = adlp_cdclk_table;
- dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
+ display->cdclk.table = adlp_cdclk_table;
+ display->funcs.cdclk = &tgl_cdclk_funcs;
}
} else if (IS_ROCKETLAKE(dev_priv)) {
- dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
- dev_priv->display.cdclk.table = rkl_cdclk_table;
- } else if (DISPLAY_VER(dev_priv) >= 12) {
- dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
- dev_priv->display.cdclk.table = icl_cdclk_table;
+ display->funcs.cdclk = &tgl_cdclk_funcs;
+ display->cdclk.table = rkl_cdclk_table;
+ } else if (DISPLAY_VER(display) >= 12) {
+ display->funcs.cdclk = &tgl_cdclk_funcs;
+ display->cdclk.table = icl_cdclk_table;
} else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
- dev_priv->display.funcs.cdclk = &ehl_cdclk_funcs;
- dev_priv->display.cdclk.table = icl_cdclk_table;
- } else if (DISPLAY_VER(dev_priv) >= 11) {
- dev_priv->display.funcs.cdclk = &icl_cdclk_funcs;
- dev_priv->display.cdclk.table = icl_cdclk_table;
+ display->funcs.cdclk = &ehl_cdclk_funcs;
+ display->cdclk.table = icl_cdclk_table;
+ } else if (DISPLAY_VER(display) >= 11) {
+ display->funcs.cdclk = &icl_cdclk_funcs;
+ display->cdclk.table = icl_cdclk_table;
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
- dev_priv->display.funcs.cdclk = &bxt_cdclk_funcs;
+ display->funcs.cdclk = &bxt_cdclk_funcs;
if (IS_GEMINILAKE(dev_priv))
- dev_priv->display.cdclk.table = glk_cdclk_table;
+ display->cdclk.table = glk_cdclk_table;
else
- dev_priv->display.cdclk.table = bxt_cdclk_table;
- } else if (DISPLAY_VER(dev_priv) == 9) {
- dev_priv->display.funcs.cdclk = &skl_cdclk_funcs;
+ display->cdclk.table = bxt_cdclk_table;
+ } else if (DISPLAY_VER(display) == 9) {
+ display->funcs.cdclk = &skl_cdclk_funcs;
} else if (IS_BROADWELL(dev_priv)) {
- dev_priv->display.funcs.cdclk = &bdw_cdclk_funcs;
+ display->funcs.cdclk = &bdw_cdclk_funcs;
} else if (IS_HASWELL(dev_priv)) {
- dev_priv->display.funcs.cdclk = &hsw_cdclk_funcs;
+ display->funcs.cdclk = &hsw_cdclk_funcs;
} else if (IS_CHERRYVIEW(dev_priv)) {
- dev_priv->display.funcs.cdclk = &chv_cdclk_funcs;
+ display->funcs.cdclk = &chv_cdclk_funcs;
} else if (IS_VALLEYVIEW(dev_priv)) {
- dev_priv->display.funcs.cdclk = &vlv_cdclk_funcs;
+ display->funcs.cdclk = &vlv_cdclk_funcs;
} else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
- dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs;
+ display->funcs.cdclk = &fixed_400mhz_cdclk_funcs;
} else if (IS_IRONLAKE(dev_priv)) {
- dev_priv->display.funcs.cdclk = &ilk_cdclk_funcs;
+ display->funcs.cdclk = &ilk_cdclk_funcs;
} else if (IS_GM45(dev_priv)) {
- dev_priv->display.funcs.cdclk = &gm45_cdclk_funcs;
+ display->funcs.cdclk = &gm45_cdclk_funcs;
} else if (IS_G45(dev_priv)) {
- dev_priv->display.funcs.cdclk = &g33_cdclk_funcs;
+ display->funcs.cdclk = &g33_cdclk_funcs;
} else if (IS_I965GM(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i965gm_cdclk_funcs;
+ display->funcs.cdclk = &i965gm_cdclk_funcs;
} else if (IS_I965G(dev_priv)) {
- dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs;
+ display->funcs.cdclk = &fixed_400mhz_cdclk_funcs;
} else if (IS_PINEVIEW(dev_priv)) {
- dev_priv->display.funcs.cdclk = &pnv_cdclk_funcs;
+ display->funcs.cdclk = &pnv_cdclk_funcs;
} else if (IS_G33(dev_priv)) {
- dev_priv->display.funcs.cdclk = &g33_cdclk_funcs;
+ display->funcs.cdclk = &g33_cdclk_funcs;
} else if (IS_I945GM(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i945gm_cdclk_funcs;
+ display->funcs.cdclk = &i945gm_cdclk_funcs;
} else if (IS_I945G(dev_priv)) {
- dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs;
+ display->funcs.cdclk = &fixed_400mhz_cdclk_funcs;
} else if (IS_I915GM(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i915gm_cdclk_funcs;
+ display->funcs.cdclk = &i915gm_cdclk_funcs;
} else if (IS_I915G(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i915g_cdclk_funcs;
+ display->funcs.cdclk = &i915g_cdclk_funcs;
} else if (IS_I865G(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i865g_cdclk_funcs;
+ display->funcs.cdclk = &i865g_cdclk_funcs;
} else if (IS_I85X(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i85x_cdclk_funcs;
+ display->funcs.cdclk = &i85x_cdclk_funcs;
} else if (IS_I845G(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i845g_cdclk_funcs;
+ display->funcs.cdclk = &i845g_cdclk_funcs;
} else if (IS_I830(dev_priv)) {
- dev_priv->display.funcs.cdclk = &i830_cdclk_funcs;
+ display->funcs.cdclk = &i830_cdclk_funcs;
}
- if (drm_WARN(&dev_priv->drm, !dev_priv->display.funcs.cdclk,
+ if (drm_WARN(display->drm, !display->funcs.cdclk,
"Unknown platform. Assuming i830\n"))
- dev_priv->display.funcs.cdclk = &i830_cdclk_funcs;
+ display->funcs.cdclk = &i830_cdclk_funcs;
}
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h
index cfdcdec07a4d..6b0e7a41eba3 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -11,9 +11,9 @@
#include "intel_display_limits.h"
#include "intel_global_state.h"
-struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc_state;
+struct intel_display;
struct intel_cdclk_config {
unsigned int cdclk, vco, ref, bypass;
@@ -59,24 +59,24 @@ struct intel_cdclk_state {
};
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state);
-void intel_cdclk_init_hw(struct drm_i915_private *i915);
-void intel_cdclk_uninit_hw(struct drm_i915_private *i915);
-void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
-void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
-void intel_update_cdclk(struct drm_i915_private *dev_priv);
-u32 intel_read_rawclk(struct drm_i915_private *dev_priv);
+void intel_cdclk_init_hw(struct intel_display *display);
+void intel_cdclk_uninit_hw(struct intel_display *display);
+void intel_init_cdclk_hooks(struct intel_display *display);
+void intel_update_max_cdclk(struct intel_display *display);
+void intel_update_cdclk(struct intel_display *display);
+u32 intel_read_rawclk(struct intel_display *display);
bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b);
-int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
+int intel_mdclk_cdclk_ratio(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config);
bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state);
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_cdclk_dump_config(struct drm_i915_private *i915,
+void intel_cdclk_dump_config(struct intel_display *display,
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,
+void intel_cdclk_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config);
int intel_cdclk_atomic_check(struct intel_atomic_state *state,
bool *need_cdclk_calc);
@@ -88,11 +88,11 @@ intel_atomic_get_cdclk_state(struct intel_atomic_state *state);
container_of_const((global_state), struct intel_cdclk_state, base)
#define intel_atomic_get_old_cdclk_state(state) \
- to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj))
+ to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->cdclk.obj))
#define intel_atomic_get_new_cdclk_state(state) \
- to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj))
+ to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->cdclk.obj))
-int intel_cdclk_init(struct drm_i915_private *dev_priv);
-void intel_cdclk_debugfs_register(struct drm_i915_private *i915);
+int intel_cdclk_init(struct intel_display *display);
+void intel_cdclk_debugfs_register(struct intel_display *display);
#endif /* __INTEL_CDCLK_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 5d701f48351b..caf1af039960 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -39,7 +39,8 @@ struct intel_color_funcs {
* the next vblank start, alongside any other double buffered
* registers involved with the same commit. This hook is optional.
*/
- void (*color_commit_noarm)(const struct intel_crtc_state *crtc_state);
+ void (*color_commit_noarm)(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state);
/*
* Program arming double buffered color management registers
* during vblank evasion. The registers (and whatever other registers
@@ -47,7 +48,8 @@ struct intel_color_funcs {
* during the next vblank start, alongside any other double buffered
* registers involved with the same commit.
*/
- void (*color_commit_arm)(const struct intel_crtc_state *crtc_state);
+ void (*color_commit_arm)(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state);
/*
* Perform any extra tasks needed after all the
* double buffered registers have been latched.
@@ -205,37 +207,44 @@ static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
return result;
}
-static void ilk_update_pipe_csc(struct intel_crtc *crtc,
+static void ilk_update_pipe_csc(struct intel_dsb *dsb,
+ struct intel_crtc *crtc,
const struct intel_csc_matrix *csc)
{
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- intel_de_write_fw(i915, PIPE_CSC_PREOFF_HI(pipe), csc->preoff[0]);
- intel_de_write_fw(i915, PIPE_CSC_PREOFF_ME(pipe), csc->preoff[1]);
- intel_de_write_fw(i915, PIPE_CSC_PREOFF_LO(pipe), csc->preoff[2]);
-
- intel_de_write_fw(i915, PIPE_CSC_COEFF_RY_GY(pipe),
- csc->coeff[0] << 16 | csc->coeff[1]);
- intel_de_write_fw(i915, PIPE_CSC_COEFF_BY(pipe),
- csc->coeff[2] << 16);
-
- intel_de_write_fw(i915, PIPE_CSC_COEFF_RU_GU(pipe),
- csc->coeff[3] << 16 | csc->coeff[4]);
- intel_de_write_fw(i915, PIPE_CSC_COEFF_BU(pipe),
- csc->coeff[5] << 16);
-
- intel_de_write_fw(i915, PIPE_CSC_COEFF_RV_GV(pipe),
- csc->coeff[6] << 16 | csc->coeff[7]);
- intel_de_write_fw(i915, PIPE_CSC_COEFF_BV(pipe),
- csc->coeff[8] << 16);
-
- if (DISPLAY_VER(i915) < 7)
+ intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_HI(pipe),
+ csc->preoff[0]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_ME(pipe),
+ csc->preoff[1]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_LO(pipe),
+ csc->preoff[2]);
+
+ intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RY_GY(pipe),
+ csc->coeff[0] << 16 | csc->coeff[1]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BY(pipe),
+ csc->coeff[2] << 16);
+
+ intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RU_GU(pipe),
+ csc->coeff[3] << 16 | csc->coeff[4]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BU(pipe),
+ csc->coeff[5] << 16);
+
+ intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RV_GV(pipe),
+ csc->coeff[6] << 16 | csc->coeff[7]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BV(pipe),
+ csc->coeff[8] << 16);
+
+ if (DISPLAY_VER(display) < 7)
return;
- intel_de_write_fw(i915, PIPE_CSC_POSTOFF_HI(pipe), csc->postoff[0]);
- intel_de_write_fw(i915, PIPE_CSC_POSTOFF_ME(pipe), csc->postoff[1]);
- intel_de_write_fw(i915, PIPE_CSC_POSTOFF_LO(pipe), csc->postoff[2]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_HI(pipe),
+ csc->postoff[0]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_ME(pipe),
+ csc->postoff[1]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_LO(pipe),
+ csc->postoff[2]);
}
static void ilk_read_pipe_csc(struct intel_crtc *crtc,
@@ -304,34 +313,41 @@ static void skl_read_csc(struct intel_crtc_state *crtc_state)
ilk_read_pipe_csc(crtc, &crtc_state->csc);
}
-static void icl_update_output_csc(struct intel_crtc *crtc,
+static void icl_update_output_csc(struct intel_dsb *dsb,
+ struct intel_crtc *crtc,
const struct intel_csc_matrix *csc)
{
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), csc->preoff[0]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), csc->preoff[1]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), csc->preoff[2]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_HI(pipe),
+ csc->preoff[0]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_ME(pipe),
+ csc->preoff[1]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_LO(pipe),
+ csc->preoff[2]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
- csc->coeff[0] << 16 | csc->coeff[1]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
- csc->coeff[2] << 16);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
+ csc->coeff[0] << 16 | csc->coeff[1]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
+ csc->coeff[2] << 16);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
- csc->coeff[3] << 16 | csc->coeff[4]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
- csc->coeff[5] << 16);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
+ csc->coeff[3] << 16 | csc->coeff[4]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
+ csc->coeff[5] << 16);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
- csc->coeff[6] << 16 | csc->coeff[7]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
- csc->coeff[8] << 16);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
+ csc->coeff[6] << 16 | csc->coeff[7]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
+ csc->coeff[8] << 16);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), csc->postoff[0]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), csc->postoff[1]);
- intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), csc->postoff[2]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe),
+ csc->postoff[0]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe),
+ csc->postoff[1]);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe),
+ csc->postoff[2]);
}
static void icl_read_output_csc(struct intel_crtc *crtc,
@@ -526,12 +542,13 @@ static void ilk_assign_csc(struct intel_crtc_state *crtc_state)
}
}
-static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
+static void ilk_load_csc_matrix(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
if (crtc_state->csc_enable)
- ilk_update_pipe_csc(crtc, &crtc_state->csc);
+ ilk_update_pipe_csc(dsb, crtc, &crtc_state->csc);
}
static void icl_assign_csc(struct intel_crtc_state *crtc_state)
@@ -563,15 +580,16 @@ static void icl_assign_csc(struct intel_crtc_state *crtc_state)
}
}
-static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
+static void icl_load_csc_matrix(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
if (crtc_state->csc_mode & ICL_CSC_ENABLE)
- ilk_update_pipe_csc(crtc, &crtc_state->csc);
+ ilk_update_pipe_csc(dsb, crtc, &crtc_state->csc);
if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE)
- icl_update_output_csc(crtc, &crtc_state->output_csc);
+ icl_update_output_csc(dsb, crtc, &crtc_state->output_csc);
}
static u16 ctm_to_twos_complement(u64 coeff, int int_bits, int frac_bits)
@@ -953,7 +971,8 @@ static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
REG_FIELD_GET(PREC_PALETTE_12P4_BLUE_LDW_MASK, ldw);
}
-static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
+static void icl_color_commit_noarm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
/*
* Despite Wa_1406463849, ICL no longer suffers from the SKL
@@ -963,10 +982,11 @@ static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
*
* On TGL+ all CSC arming issues have been properly fixed.
*/
- icl_load_csc_matrix(crtc_state);
+ icl_load_csc_matrix(dsb, crtc_state);
}
-static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
+static void skl_color_commit_noarm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
/*
* Possibly related to display WA #1184, SKL CSC loses the latched
@@ -979,21 +999,24 @@ static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
* which is called after PSR exit.
*/
if (!crtc_state->has_psr)
- ilk_load_csc_matrix(crtc_state);
+ ilk_load_csc_matrix(dsb, crtc_state);
}
-static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
+static void ilk_color_commit_noarm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
- ilk_load_csc_matrix(crtc_state);
+ ilk_load_csc_matrix(dsb, crtc_state);
}
-static void i9xx_color_commit_arm(const struct intel_crtc_state *crtc_state)
+static void i9xx_color_commit_arm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
/* update TRANSCONF GAMMA_MODE */
i9xx_set_pipeconf(crtc_state);
}
-static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state)
+static void ilk_color_commit_arm(struct intel_dsb *dsb,
+ 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);
@@ -1005,7 +1028,8 @@ static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state)
crtc_state->csc_mode);
}
-static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state)
+static void hsw_color_commit_arm(struct intel_dsb *dsb,
+ 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);
@@ -1076,15 +1100,16 @@ static void skl_get_config(struct intel_crtc_state *crtc_state)
crtc_state->csc_enable = true;
}
-static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
+static void skl_color_commit_arm(struct intel_dsb *dsb,
+ 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_display *display = to_intel_display(crtc->base.dev);
enum pipe pipe = crtc->pipe;
u32 val = 0;
if (crtc_state->has_psr)
- ilk_load_csc_matrix(crtc_state);
+ ilk_load_csc_matrix(dsb, crtc_state);
/*
* We don't (yet) allow userspace to control the pipe background color,
@@ -1095,32 +1120,29 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
if (crtc_state->csc_enable)
val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
- intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), val);
+ intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), val);
- intel_de_write(i915, GAMMA_MODE(crtc->pipe),
- crtc_state->gamma_mode);
+ intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
- intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
- crtc_state->csc_mode);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
}
-static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state)
+static void icl_color_commit_arm(struct intel_dsb *dsb,
+ 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_display *display = to_intel_display(crtc->base.dev);
enum pipe pipe = crtc->pipe;
/*
* We don't (yet) allow userspace to control the pipe background color,
* so force it to black.
*/
- intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0);
+ intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), 0);
- intel_de_write(i915, GAMMA_MODE(crtc->pipe),
- crtc_state->gamma_mode);
+ intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
- intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
- crtc_state->csc_mode);
+ intel_de_write_dsb(display, dsb, PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
}
static void icl_color_post_update(const struct intel_crtc_state *crtc_state)
@@ -1876,22 +1898,21 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
i915->display.funcs.color->load_luts(crtc_state);
}
-void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state)
+void intel_color_commit_noarm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
if (i915->display.funcs.color->color_commit_noarm)
- i915->display.funcs.color->color_commit_noarm(crtc_state);
+ i915->display.funcs.color->color_commit_noarm(dsb, crtc_state);
}
-void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
+void intel_color_commit_arm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
- i915->display.funcs.color->color_commit_arm(crtc_state);
-
- if (crtc_state->dsb_color_commit)
- intel_dsb_commit(crtc_state->dsb_color_commit, false);
+ i915->display.funcs.color->color_commit_arm(dsb, crtc_state);
}
void intel_color_post_update(const struct intel_crtc_state *crtc_state)
@@ -1902,6 +1923,23 @@ void intel_color_post_update(const struct intel_crtc_state *crtc_state)
i915->display.funcs.color->color_post_update(crtc_state);
}
+void intel_color_modeset(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+
+ intel_color_load_luts(crtc_state);
+ intel_color_commit_noarm(NULL, crtc_state);
+ intel_color_commit_arm(NULL, crtc_state);
+
+ if (DISPLAY_VER(display) < 9) {
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_plane *plane = to_intel_plane(crtc->base.primary);
+
+ /* update DSPCNTR to configure gamma/csc for pipe bottom color */
+ plane->disable_arm(NULL, plane, crtc_state);
+ }
+}
+
void intel_color_prepare_commit(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -1925,28 +1963,14 @@ void intel_color_prepare_commit(struct intel_atomic_state *state,
i915->display.funcs.color->load_luts(crtc_state);
- intel_dsb_finish(crtc_state->dsb_color_vblank);
-
- crtc_state->dsb_color_commit = intel_dsb_prepare(state, crtc, INTEL_DSB_0, 16);
- if (!crtc_state->dsb_color_commit) {
- intel_dsb_cleanup(crtc_state->dsb_color_vblank);
- crtc_state->dsb_color_vblank = NULL;
- return;
- }
+ intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank);
+ intel_dsb_interrupt(crtc_state->dsb_color_vblank);
- intel_dsb_chain(state, crtc_state->dsb_color_commit,
- crtc_state->dsb_color_vblank, true);
-
- intel_dsb_finish(crtc_state->dsb_color_commit);
+ intel_dsb_finish(crtc_state->dsb_color_vblank);
}
void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
{
- if (crtc_state->dsb_color_commit) {
- intel_dsb_cleanup(crtc_state->dsb_color_commit);
- crtc_state->dsb_color_commit = NULL;
- }
-
if (crtc_state->dsb_color_vblank) {
intel_dsb_cleanup(crtc_state->dsb_color_vblank);
crtc_state->dsb_color_vblank = NULL;
@@ -1955,8 +1979,6 @@ void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
void intel_color_wait_commit(const struct intel_crtc_state *crtc_state)
{
- if (crtc_state->dsb_color_commit)
- intel_dsb_wait(crtc_state->dsb_color_commit);
if (crtc_state->dsb_color_vblank)
intel_dsb_wait(crtc_state->dsb_color_vblank);
}
diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h
index 79f230a1709a..ba493f381031 100644
--- a/drivers/gpu/drm/i915/display/intel_color.h
+++ b/drivers/gpu/drm/i915/display/intel_color.h
@@ -11,6 +11,7 @@
struct intel_atomic_state;
struct intel_crtc_state;
struct intel_crtc;
+struct intel_dsb;
struct drm_i915_private;
struct drm_property_blob;
@@ -24,10 +25,13 @@ void intel_color_prepare_commit(struct intel_atomic_state *state,
void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);
bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state);
void intel_color_wait_commit(const struct intel_crtc_state *crtc_state);
-void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);
-void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);
+void intel_color_commit_noarm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state);
+void intel_color_commit_arm(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state);
void intel_color_post_update(const struct intel_crtc_state *crtc_state);
void intel_color_load_luts(const struct intel_crtc_state *crtc_state);
+void intel_color_modeset(const struct intel_crtc_state *crtc_state);
void intel_color_get_config(struct intel_crtc_state *crtc_state);
bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state,
const struct drm_property_blob *blob1,
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 835c8b844494..fd78adbaadbe 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -694,6 +694,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
static enum drm_connector_status
intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
{
+ struct intel_display *display = to_intel_display(&crt->base);
struct drm_device *dev = crt->base.base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
enum transcoder cpu_transcoder = (enum transcoder)pipe;
@@ -734,7 +735,7 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
TRANSCONF(dev_priv, cpu_transcoder));
/* Wait for next Vblank to substitue
* border color for Color info */
- intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe));
+ intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe));
st00 = intel_de_read8(dev_priv, _VGA_MSR_WRITE);
status = ((st00 & (1 << 4)) != 0) ?
connector_status_connected :
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 1b578cad2813..3c9168a57f38 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -9,6 +9,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_plane.h>
+#include <drm/drm_vblank.h>
#include <drm/drm_vblank_work.h>
#include "i915_vgpu.h"
@@ -48,12 +49,12 @@ struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915)
return to_intel_crtc(drm_crtc_from_index(&i915->drm, 0));
}
-struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
+struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display,
enum pipe pipe)
{
struct intel_crtc *crtc;
- for_each_intel_crtc(&i915->drm, crtc) {
+ for_each_intel_crtc(display->drm, crtc) {
if (crtc->pipe == pipe)
return crtc;
}
@@ -69,7 +70,8 @@ void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc)
void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
enum pipe pipe)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(i915, pipe);
+ struct intel_display *display = &i915->display;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
if (crtc->active)
intel_crtc_wait_for_next_vblank(crtc);
@@ -122,6 +124,8 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ crtc->block_dc_for_vblank = intel_psr_needs_block_dc_vblank(crtc_state);
+
assert_vblank_disabled(&crtc->base);
drm_crtc_set_max_vblank_count(&crtc->base,
intel_crtc_max_vblank_count(crtc_state));
@@ -138,6 +142,7 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_display *display = to_intel_display(crtc);
/*
* Should really happen exactly when we disable the pipe
@@ -148,6 +153,10 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
drm_crtc_vblank_off(&crtc->base);
assert_vblank_disabled(&crtc->base);
+
+ crtc->block_dc_for_vblank = false;
+
+ flush_work(&display->irq.vblank_dc_work);
}
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
@@ -387,13 +396,31 @@ fail:
return ret;
}
+int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
+ struct drm_crtc *drm_crtc;
+ struct intel_crtc *crtc;
+
+ drm_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
+ if (!drm_crtc)
+ return -ENOENT;
+
+ crtc = to_intel_crtc(drm_crtc);
+ pipe_from_crtc_id->pipe = crtc->pipe;
+
+ return 0;
+}
+
static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state)
{
return crtc_state->hw.active &&
- !intel_crtc_needs_modeset(crtc_state) &&
!crtc_state->preload_luts &&
+ !intel_crtc_needs_modeset(crtc_state) &&
intel_crtc_needs_color_update(crtc_state) &&
- !intel_color_uses_dsb(crtc_state);
+ !intel_color_uses_dsb(crtc_state) &&
+ !crtc_state->use_dsb;
}
static void intel_crtc_vblank_work(struct kthread_work *base)
@@ -457,6 +484,17 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
1000 * adjusted_mode->crtc_htotal);
}
+int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode,
+ int scanlines)
+{
+ /* paranoia */
+ if (!adjusted_mode->crtc_clock)
+ return 1;
+
+ return DIV_ROUND_UP_ULL(mul_u32_u32(scanlines, adjusted_mode->crtc_htotal * 1000),
+ adjusted_mode->crtc_clock);
+}
+
/**
* intel_pipe_update_start() - start update of a set of display registers
* @state: the atomic state
@@ -484,12 +522,8 @@ void intel_pipe_update_start(struct intel_atomic_state *state,
intel_psr_lock(new_crtc_state);
if (new_crtc_state->do_async_flip) {
- spin_lock_irq(&crtc->base.dev->event_lock);
- /* arm the event for the flip done irq handler */
- crtc->flip_done_event = new_crtc_state->uapi.event;
- spin_unlock_irq(&crtc->base.dev->event_lock);
-
- new_crtc_state->uapi.event = NULL;
+ intel_crtc_prepare_vblank_event(new_crtc_state,
+ &crtc->flip_done_event);
return;
}
@@ -589,6 +623,19 @@ void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state)
crtc_state->uapi.event = NULL;
}
+void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state,
+ struct drm_pending_vblank_event **event)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&crtc->base.dev->event_lock, irqflags);
+ *event = crtc_state->uapi.event;
+ spin_unlock_irqrestore(&crtc->base.dev->event_lock, irqflags);
+
+ crtc_state->uapi.event = NULL;
+}
+
/**
* intel_pipe_update_end() - end update of a set of display registers
* @state: the atomic state
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
index b615b7ab5ccd..de54ae1deedf 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.h
+++ b/drivers/gpu/drm/i915/display/intel_crtc.h
@@ -10,11 +10,15 @@
enum i9xx_plane_id;
enum pipe;
+struct drm_device;
struct drm_display_mode;
+struct drm_file;
struct drm_i915_private;
+struct drm_pending_vblank_event;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
+struct intel_display;
/*
* FIXME: We should instead only take spinlocks once for the entire update
@@ -28,9 +32,15 @@ struct intel_crtc_state;
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
int usecs);
+int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode,
+ int scanlines);
void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state);
+void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state,
+ struct drm_pending_vblank_event **event);
u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state);
int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe);
+int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
struct intel_crtc *crtc);
@@ -43,7 +53,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_wait_for_vblank_workers(struct intel_atomic_state *state);
struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915);
-struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
+struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display,
enum pipe pipe);
void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
enum pipe pipe);
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 9ad53e1cbbd0..9ba77970dab7 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -9,6 +9,7 @@
#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_vblank.h>
#include "i915_reg.h"
#include "intel_atomic.h"
@@ -26,8 +27,6 @@
#include "intel_vblank.h"
#include "skl_watermark.h"
-#include "gem/i915_gem_object.h"
-
/* Cursor formats */
static const u32 intel_cursor_formats[] = {
DRM_FORMAT_ARGB8888,
@@ -275,7 +274,8 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state,
}
/* TODO: split into noarm+arm pair */
-static void i845_cursor_update_arm(struct intel_plane *plane,
+static void i845_cursor_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -315,10 +315,11 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
}
}
-static void i845_cursor_disable_arm(struct intel_plane *plane,
+static void i845_cursor_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- i845_cursor_update_arm(plane, crtc_state, NULL);
+ i845_cursor_update_arm(dsb, plane, crtc_state, NULL);
}
static bool i845_cursor_get_hw_state(struct intel_plane *plane,
@@ -527,22 +528,25 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
return 0;
}
-static void i9xx_cursor_disable_sel_fetch_arm(struct intel_plane *plane,
+static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), 0);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0);
}
-static void wa_16021440873(struct intel_plane *plane,
+static void wa_16021440873(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
u32 ctl = plane_state->ctl;
int et_y_position = drm_rect_height(&crtc_state->pipe_src) + 1;
@@ -551,16 +555,18 @@ static void wa_16021440873(struct intel_plane *plane,
ctl &= ~MCURSOR_MODE_MASK;
ctl |= MCURSOR_MODE_64_2B;
- intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), ctl);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), ctl);
- intel_de_write(dev_priv, CURPOS_ERLY_TPT(dev_priv, pipe),
- CURSOR_POS_Y(et_y_position));
+ intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe),
+ CURSOR_POS_Y(et_y_position));
}
-static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
+static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
@@ -571,19 +577,17 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
if (crtc_state->enable_psr2_su_region_et) {
u32 val = intel_cursor_position(crtc_state, plane_state,
true);
- intel_de_write_fw(dev_priv,
- CURPOS_ERLY_TPT(dev_priv, pipe),
- val);
+
+ intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), val);
}
- intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe),
- plane_state->ctl);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), plane_state->ctl);
} else {
/* Wa_16021440873 */
if (crtc_state->enable_psr2_su_region_et)
- wa_16021440873(plane, crtc_state, plane_state);
+ wa_16021440873(dsb, plane, crtc_state, plane_state);
else
- i9xx_cursor_disable_sel_fetch_arm(plane, crtc_state);
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
}
}
@@ -610,9 +614,11 @@ static u32 skl_cursor_wm_reg_val(const struct skl_wm_level *level)
return val;
}
-static void skl_write_cursor_wm(struct intel_plane *plane,
+static void skl_write_cursor_wm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
@@ -622,30 +628,32 @@ static void skl_write_cursor_wm(struct intel_plane *plane,
int level;
for (level = 0; level < i915->display.wm.num_levels; level++)
- intel_de_write_fw(i915, CUR_WM(pipe, level),
- skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
+ intel_de_write_dsb(display, dsb, CUR_WM(pipe, level),
+ skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
- intel_de_write_fw(i915, CUR_WM_TRANS(pipe),
- skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
+ intel_de_write_dsb(display, dsb, CUR_WM_TRANS(pipe),
+ skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
if (HAS_HW_SAGV_WM(i915)) {
const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
- intel_de_write_fw(i915, CUR_WM_SAGV(pipe),
- skl_cursor_wm_reg_val(&wm->sagv.wm0));
- intel_de_write_fw(i915, CUR_WM_SAGV_TRANS(pipe),
- skl_cursor_wm_reg_val(&wm->sagv.trans_wm));
+ intel_de_write_dsb(display, dsb, CUR_WM_SAGV(pipe),
+ skl_cursor_wm_reg_val(&wm->sagv.wm0));
+ intel_de_write_dsb(display, dsb, CUR_WM_SAGV_TRANS(pipe),
+ skl_cursor_wm_reg_val(&wm->sagv.trans_wm));
}
- intel_de_write_fw(i915, CUR_BUF_CFG(pipe),
- skl_cursor_ddb_reg_val(ddb));
+ intel_de_write_dsb(display, dsb, CUR_BUF_CFG(pipe),
+ skl_cursor_ddb_reg_val(ddb));
}
/* TODO: split into noarm+arm pair */
-static void i9xx_cursor_update_arm(struct intel_plane *plane,
+static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0;
@@ -685,38 +693,36 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
*/
if (DISPLAY_VER(dev_priv) >= 9)
- skl_write_cursor_wm(plane, crtc_state);
+ skl_write_cursor_wm(dsb, plane, crtc_state);
if (plane_state)
- i9xx_cursor_update_sel_fetch_arm(plane, crtc_state,
- plane_state);
+ i9xx_cursor_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
else
- i9xx_cursor_disable_sel_fetch_arm(plane, crtc_state);
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
if (plane->cursor.base != base ||
plane->cursor.size != fbc_ctl ||
plane->cursor.cntl != cntl) {
if (HAS_CUR_FBC(dev_priv))
- intel_de_write_fw(dev_priv,
- CUR_FBC_CTL(dev_priv, pipe),
- fbc_ctl);
- intel_de_write_fw(dev_priv, CURCNTR(dev_priv, pipe), cntl);
- intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos);
- intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base);
+ intel_de_write_dsb(display, dsb, CUR_FBC_CTL(dev_priv, pipe), fbc_ctl);
+ intel_de_write_dsb(display, dsb, CURCNTR(dev_priv, pipe), cntl);
+ intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos);
+ intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base);
plane->cursor.base = base;
plane->cursor.size = fbc_ctl;
plane->cursor.cntl = cntl;
} else {
- intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos);
- intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base);
+ intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos);
+ intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base);
}
}
-static void i9xx_cursor_disable_arm(struct intel_plane *plane,
+static void i9xx_cursor_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- i9xx_cursor_update_arm(plane, crtc_state, NULL);
+ i9xx_cursor_update_arm(dsb, plane, crtc_state, NULL);
}
static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
@@ -905,10 +911,10 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
}
if (new_plane_state->uapi.visible) {
- intel_plane_update_noarm(plane, crtc_state, new_plane_state);
- intel_plane_update_arm(plane, crtc_state, new_plane_state);
+ intel_plane_update_noarm(NULL, plane, crtc_state, new_plane_state);
+ intel_plane_update_arm(NULL, plane, crtc_state, new_plane_state);
} else {
- intel_plane_disable_arm(plane, crtc_state);
+ intel_plane_disable_arm(NULL, plane, crtc_state);
}
local_irq_enable();
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index 4a6c3040ca15..f73d576fd99e 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -923,10 +923,10 @@ static const struct intel_c20pll_state mtl_c20_dp_uhbr20 = {
},
.mplla = { 0x3104, /* mplla cfg0 */
0xd105, /* mplla cfg1 */
- 0xc025, /* mplla cfg2 */
- 0xc025, /* mplla cfg3 */
- 0xa6ab, /* mplla cfg4 */
- 0x8c00, /* mplla cfg5 */
+ 0x9217, /* mplla cfg2 */
+ 0x9217, /* mplla cfg3 */
+ 0x8c00, /* mplla cfg4 */
+ 0x759a, /* mplla cfg5 */
0x4000, /* mplla cfg6 */
0x0003, /* mplla cfg7 */
0x3555, /* mplla cfg8 */
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index b1c294236cc8..fe1ded6707f9 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -54,6 +54,7 @@
#include "intel_dp_aux.h"
#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
+#include "intel_dp_test.h"
#include "intel_dp_tunnel.h"
#include "intel_dpio_phy.h"
#include "intel_dsi.h"
@@ -3115,11 +3116,12 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
+ struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *pipe_crtc;
+ int i;
- for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(old_crtc_state)) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -3130,8 +3132,7 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state,
intel_ddi_disable_transcoder_func(old_crtc_state);
- for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(old_crtc_state)) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -3382,8 +3383,9 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_display *display = to_intel_display(encoder);
struct intel_crtc *pipe_crtc;
+ int i;
intel_ddi_enable_transcoder_func(encoder, crtc_state);
@@ -3394,8 +3396,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
- for_each_intel_crtc_in_pipe_mask_reverse(&i915->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(crtc_state)) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state, i) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -4550,12 +4551,8 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
enum intel_hotplug_state state;
int ret;
- if (intel_dp->compliance.test_active &&
- intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
- intel_dp_phy_test(encoder);
- /* just do the PHY test and nothing else */
+ if (intel_dp_test_phy(intel_dp))
return INTEL_HOTPLUG_UNCHANGED;
- }
state = intel_encoder_hotplug(encoder, connector);
diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h
index e881bfeafb47..e017cd4a8168 100644
--- a/drivers/gpu/drm/i915/display/intel_de.h
+++ b/drivers/gpu/drm/i915/display/intel_de.h
@@ -8,6 +8,7 @@
#include "i915_drv.h"
#include "i915_trace.h"
+#include "intel_dsb.h"
#include "intel_uncore.h"
static inline struct intel_uncore *__to_uncore(struct intel_display *display)
@@ -233,4 +234,14 @@ __intel_de_write_notrace(struct intel_display *display, i915_reg_t reg,
}
#define intel_de_write_notrace(p,...) __intel_de_write_notrace(__to_intel_display(p), __VA_ARGS__)
+static __always_inline void
+intel_de_write_dsb(struct intel_display *display, struct intel_dsb *dsb,
+ i915_reg_t reg, u32 val)
+{
+ if (dsb)
+ intel_dsb_reg_write(dsb, reg, val);
+ else
+ intel_de_write_fw(display, reg, val);
+}
+
#endif /* __INTEL_DE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b4ef4d59da1a..e1f6255e918b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -43,9 +43,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_rect.h>
-
-#include "gem/i915_gem_lmem.h"
-#include "gem/i915_gem_object.h"
+#include <drm/drm_vblank.h>
#include "g4x_dp.h"
#include "g4x_hdmi.h"
@@ -60,6 +58,7 @@
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_audio.h"
+#include "intel_bo.h"
#include "intel_bw.h"
#include "intel_cdclk.h"
#include "intel_clock_gating.h"
@@ -135,7 +134,8 @@
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 hsw_set_transconf(const struct intel_crtc_state *crtc_state);
-static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state);
+static void bdw_set_pipe_misc(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state);
/* returns HPLL frequency in kHz */
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
@@ -253,6 +253,108 @@ static enum pipe joiner_primary_pipe(const struct intel_crtc_state *crtc_state)
return ffs(crtc_state->joiner_pipes) - 1;
}
+/*
+ * The following helper functions, despite being named for bigjoiner,
+ * are applicable to both bigjoiner and uncompressed joiner configurations.
+ */
+static bool is_bigjoiner(const struct intel_crtc_state *crtc_state)
+{
+ return hweight8(crtc_state->joiner_pipes) >= 2;
+}
+
+static u8 bigjoiner_primary_pipes(const struct intel_crtc_state *crtc_state)
+{
+ if (!is_bigjoiner(crtc_state))
+ return 0;
+
+ return crtc_state->joiner_pipes & (0b01010101 << joiner_primary_pipe(crtc_state));
+}
+
+static unsigned int bigjoiner_secondary_pipes(const struct intel_crtc_state *crtc_state)
+{
+ if (!is_bigjoiner(crtc_state))
+ return 0;
+
+ return crtc_state->joiner_pipes & (0b10101010 << joiner_primary_pipe(crtc_state));
+}
+
+bool intel_crtc_is_bigjoiner_primary(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ if (!is_bigjoiner(crtc_state))
+ return false;
+
+ return BIT(crtc->pipe) & bigjoiner_primary_pipes(crtc_state);
+}
+
+bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ if (!is_bigjoiner(crtc_state))
+ return false;
+
+ return BIT(crtc->pipe) & bigjoiner_secondary_pipes(crtc_state);
+}
+
+u8 _intel_modeset_primary_pipes(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ if (!is_bigjoiner(crtc_state))
+ return BIT(crtc->pipe);
+
+ return bigjoiner_primary_pipes(crtc_state);
+}
+
+u8 _intel_modeset_secondary_pipes(const struct intel_crtc_state *crtc_state)
+{
+ return bigjoiner_secondary_pipes(crtc_state);
+}
+
+bool intel_crtc_is_ultrajoiner(const struct intel_crtc_state *crtc_state)
+{
+ return intel_crtc_num_joined_pipes(crtc_state) >= 4;
+}
+
+static u8 ultrajoiner_primary_pipes(const struct intel_crtc_state *crtc_state)
+{
+ if (!intel_crtc_is_ultrajoiner(crtc_state))
+ return 0;
+
+ return crtc_state->joiner_pipes & (0b00010001 << joiner_primary_pipe(crtc_state));
+}
+
+bool intel_crtc_is_ultrajoiner_primary(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ return intel_crtc_is_ultrajoiner(crtc_state) &&
+ BIT(crtc->pipe) & ultrajoiner_primary_pipes(crtc_state);
+}
+
+/*
+ * The ultrajoiner enable bit doesn't seem to follow primary/secondary logic or
+ * any other logic, so lets just add helper function to
+ * at least hide this hassle..
+ */
+static u8 ultrajoiner_enable_pipes(const struct intel_crtc_state *crtc_state)
+{
+ if (!intel_crtc_is_ultrajoiner(crtc_state))
+ return 0;
+
+ return crtc_state->joiner_pipes & (0b01110111 << joiner_primary_pipe(crtc_state));
+}
+
+bool intel_crtc_ultrajoiner_enable_needed(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+ return intel_crtc_is_ultrajoiner(crtc_state) &&
+ BIT(crtc->pipe) & ultrajoiner_enable_pipes(crtc_state);
+}
+
u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state)
{
if (crtc_state->joiner_pipes)
@@ -277,9 +379,9 @@ bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state)
crtc->pipe == joiner_primary_pipe(crtc_state);
}
-static int intel_joiner_num_pipes(const struct intel_crtc_state *crtc_state)
+int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state)
{
- return hweight8(crtc_state->joiner_pipes);
+ return hweight8(intel_crtc_joined_pipe_mask(crtc_state));
}
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state)
@@ -291,10 +393,10 @@ u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state)
struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
if (intel_crtc_is_joiner_secondary(crtc_state))
- return intel_crtc_for_pipe(i915, joiner_primary_pipe(crtc_state));
+ return intel_crtc_for_pipe(display, joiner_primary_pipe(crtc_state));
else
return to_intel_crtc(crtc_state->uapi.crtc);
}
@@ -715,7 +817,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) == 2 && !crtc_state->active_planes)
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
- intel_plane_disable_arm(plane, crtc_state);
+ intel_plane_disable_arm(NULL, plane, crtc_state);
intel_crtc_wait_for_next_vblank(crtc);
}
@@ -1116,6 +1218,22 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
intel_encoders_audio_enable(state, crtc);
}
+static void intel_post_plane_update_after_readout(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);
+
+ /* Must be done after gamma readout due to HSW split gamma vs. IPS w/a */
+ hsw_ips_post_update(state, crtc);
+
+ /*
+ * Activate DRRS after state readout to avoid
+ * dp_m_n vs. dp_m2_n2 confusion on BDW+.
+ */
+ intel_drrs_activate(new_crtc_state);
+}
+
static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -1172,8 +1290,8 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,
* Apart from the async flip bit we want to
* preserve the old state for the plane.
*/
- intel_plane_async_flip(plane, old_crtc_state,
- old_plane_state, false);
+ intel_plane_async_flip(NULL, plane,
+ old_crtc_state, old_plane_state, false);
need_vbl_wait = true;
}
}
@@ -1249,8 +1367,8 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
*
* WaCxSRDisabledForSpriteScaling:ivb
*/
- if (old_crtc_state->hw.active &&
- new_crtc_state->disable_lp_wm && ilk_disable_lp_wm(dev_priv))
+ if (!HAS_GMCH(dev_priv) && old_crtc_state->hw.active &&
+ new_crtc_state->disable_cxsr && ilk_disable_cxsr(dev_priv))
intel_crtc_wait_for_next_vblank(crtc);
/*
@@ -1315,7 +1433,7 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state,
!(update_mask & BIT(plane->id)))
continue;
- intel_plane_disable_arm(plane, new_crtc_state);
+ intel_plane_disable_arm(NULL, plane, new_crtc_state);
if (old_plane_state->uapi.visible)
fb_bits |= plane->frontbuffer_bit;
@@ -1502,14 +1620,6 @@ static void intel_encoders_update_pipe(struct intel_atomic_state *state,
}
}
-static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct intel_plane *plane = to_intel_plane(crtc->base.primary);
-
- 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);
@@ -1575,11 +1685,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
* On ILK+ LUT must be loaded before the pipe is running but with
* clocks enabled
*/
- intel_color_load_luts(new_crtc_state);
- intel_color_commit_noarm(new_crtc_state);
- intel_color_commit_arm(new_crtc_state);
- /* update DSPCNTR to configure gamma for pipe bottom color */
- intel_disable_primary_plane(new_crtc_state);
+ intel_color_modeset(new_crtc_state);
intel_initial_watermarks(state, crtc);
intel_enable_transcoder(new_crtc_state);
@@ -1677,23 +1783,22 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
static void hsw_crtc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
+ struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
struct intel_crtc *pipe_crtc;
+ int i;
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
return;
-
- for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(new_crtc_state))
- intel_dmc_enable_pipe(dev_priv, pipe_crtc->pipe);
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i)
+ intel_dmc_enable_pipe(display, pipe_crtc->pipe);
intel_encoders_pre_pll_enable(state, crtc);
- for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(new_crtc_state)) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -1703,27 +1808,25 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
intel_encoders_pre_enable(state, crtc);
- for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(new_crtc_state)) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
intel_dsc_enable(pipe_crtc_state);
- if (DISPLAY_VER(dev_priv) >= 13)
+ if (HAS_UNCOMPRESSED_JOINER(dev_priv))
intel_uncompressed_joiner_enable(pipe_crtc_state);
intel_set_pipe_src_size(pipe_crtc_state);
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
- bdw_set_pipe_misc(pipe_crtc_state);
+ bdw_set_pipe_misc(NULL, pipe_crtc_state);
}
if (!transcoder_is_dsi(cpu_transcoder))
hsw_configure_cpu_transcoder(new_crtc_state);
- for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(new_crtc_state)) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -1741,12 +1844,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
* On ILK+ LUT must be loaded before the pipe is running but with
* clocks enabled
*/
- intel_color_load_luts(pipe_crtc_state);
- intel_color_commit_noarm(pipe_crtc_state);
- intel_color_commit_arm(pipe_crtc_state);
- /* update DSPCNTR to configure gamma/csc for pipe bottom color */
- if (DISPLAY_VER(dev_priv) < 9)
- intel_disable_primary_plane(pipe_crtc_state);
+ intel_color_modeset(pipe_crtc_state);
hsw_set_linetime_wm(pipe_crtc_state);
@@ -1758,8 +1856,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
intel_encoders_enable(state, crtc);
- for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(new_crtc_state)) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
enum pipe hsw_workaround_pipe;
@@ -1776,7 +1873,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
hsw_workaround_pipe = pipe_crtc_state->hsw_workaround_pipe;
if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) {
struct intel_crtc *wa_crtc =
- intel_crtc_for_pipe(dev_priv, hsw_workaround_pipe);
+ intel_crtc_for_pipe(display, hsw_workaround_pipe);
intel_crtc_wait_for_next_vblank(wa_crtc);
intel_crtc_wait_for_next_vblank(wa_crtc);
@@ -1841,10 +1938,11 @@ static void ilk_crtc_disable(struct intel_atomic_state *state,
static void hsw_crtc_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
+ struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_crtc *pipe_crtc;
+ int i;
/*
* FIXME collapse everything to one hook.
@@ -1853,8 +1951,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
intel_encoders_disable(state, crtc);
intel_encoders_post_disable(state, crtc);
- for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(old_crtc_state)) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -1863,9 +1960,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
intel_encoders_post_pll_disable(state, crtc);
- for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(old_crtc_state))
- intel_dmc_disable_pipe(i915, pipe_crtc->pipe);
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i)
+ intel_dmc_disable_pipe(display, pipe_crtc->pipe);
}
static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -2147,11 +2243,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
i9xx_pfit_enable(new_crtc_state);
- intel_color_load_luts(new_crtc_state);
- intel_color_commit_noarm(new_crtc_state);
- intel_color_commit_arm(new_crtc_state);
- /* update DSPCNTR to configure gamma for pipe bottom color */
- intel_disable_primary_plane(new_crtc_state);
+ intel_color_modeset(new_crtc_state);
intel_initial_watermarks(state, crtc);
intel_enable_transcoder(new_crtc_state);
@@ -2187,11 +2279,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
i9xx_pfit_enable(new_crtc_state);
- intel_color_load_luts(new_crtc_state);
- intel_color_commit_noarm(new_crtc_state);
- intel_color_commit_arm(new_crtc_state);
- /* update DSPCNTR to configure gamma for pipe bottom color */
- intel_disable_primary_plane(new_crtc_state);
+ intel_color_modeset(new_crtc_state);
if (!intel_initial_watermarks(state, crtc))
intel_update_watermarks(dev_priv);
@@ -2224,9 +2312,10 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
static void i9xx_crtc_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
+ struct intel_display *display = to_intel_display(state);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
/*
@@ -2265,7 +2354,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state,
/* clock the pipe down to 640x480@60 to potentially save power */
if (IS_I830(dev_priv))
- i830_enable_pipe(dev_priv, pipe);
+ i830_enable_pipe(display, pipe);
}
void intel_encoder_destroy(struct drm_encoder *encoder)
@@ -2343,9 +2432,9 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
static void intel_joiner_adjust_timings(const struct intel_crtc_state *crtc_state,
struct drm_display_mode *mode)
{
- int num_pipes = intel_joiner_num_pipes(crtc_state);
+ int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
- if (num_pipes < 2)
+ if (num_pipes == 1)
return;
mode->crtc_clock /= num_pipes;
@@ -2407,7 +2496,7 @@ static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state
drm_mode_copy(mode, pipe_mode);
intel_mode_from_crtc_timings(mode, mode);
mode->hdisplay = drm_rect_width(&crtc_state->pipe_src) *
- (intel_joiner_num_pipes(crtc_state) ?: 1);
+ intel_crtc_num_joined_pipes(crtc_state);
mode->vdisplay = drm_rect_height(&crtc_state->pipe_src);
/* Derive per-pipe timings in case joiner is used */
@@ -2427,10 +2516,10 @@ void intel_encoder_get_config(struct intel_encoder *encoder,
static void intel_joiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
{
- int num_pipes = intel_joiner_num_pipes(crtc_state);
+ int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
int width, height;
- if (num_pipes < 2)
+ if (num_pipes == 1)
return;
width = drm_rect_width(&crtc_state->pipe_src);
@@ -2887,11 +2976,11 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- int num_pipes = intel_joiner_num_pipes(crtc_state);
+ int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
enum pipe primary_pipe, pipe = crtc->pipe;
int width;
- if (num_pipes < 2)
+ if (num_pipes == 1)
return;
primary_pipe = joiner_primary_pipe(crtc_state);
@@ -3246,9 +3335,11 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
-static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state)
+static void bdw_set_pipe_misc(struct intel_dsb *dsb,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 val = 0;
@@ -3293,7 +3384,7 @@ static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state)
if (IS_BROADWELL(dev_priv))
val |= PIPE_MISC_PSR_MASK_SPRITE_ENABLE;
- intel_de_write(dev_priv, PIPE_MISC(crtc->pipe), val);
+ intel_de_write_dsb(display, dsb, PIPE_MISC(crtc->pipe), val);
}
int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc)
@@ -3534,23 +3625,57 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
return tmp & TRANS_DDI_FUNC_ENABLE;
}
-static void enabled_joiner_pipes(struct drm_i915_private *dev_priv,
- u8 *primary_pipes, u8 *secondary_pipes)
+static void enabled_uncompressed_joiner_pipes(struct intel_display *display,
+ u8 *primary_pipes, u8 *secondary_pipes)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_crtc *crtc;
*primary_pipes = 0;
*secondary_pipes = 0;
- for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc,
- joiner_pipes(dev_priv)) {
+ if (!HAS_UNCOMPRESSED_JOINER(display))
+ return;
+
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
+ joiner_pipes(i915)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
intel_wakeref_t wakeref;
- 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));
+ power_domain = POWER_DOMAIN_PIPE(pipe);
+ with_intel_display_power_if_enabled(i915, power_domain, wakeref) {
+ u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe));
+
+ if (tmp & UNCOMPRESSED_JOINER_PRIMARY)
+ *primary_pipes |= BIT(pipe);
+ if (tmp & UNCOMPRESSED_JOINER_SECONDARY)
+ *secondary_pipes |= BIT(pipe);
+ }
+ }
+}
+
+static void enabled_bigjoiner_pipes(struct intel_display *display,
+ u8 *primary_pipes, u8 *secondary_pipes)
+{
+ struct drm_i915_private *i915 = to_i915(display->drm);
+ struct intel_crtc *crtc;
+
+ *primary_pipes = 0;
+ *secondary_pipes = 0;
+
+ if (!HAS_BIGJOINER(display))
+ return;
+
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
+ joiner_pipes(i915)) {
+ enum intel_display_power_domain power_domain;
+ enum pipe pipe = crtc->pipe;
+ intel_wakeref_t wakeref;
+
+ power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe);
+ with_intel_display_power_if_enabled(i915, power_domain, wakeref) {
+ u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe));
if (!(tmp & BIG_JOINER_ENABLE))
continue;
@@ -3560,56 +3685,197 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv,
else
*secondary_pipes |= BIT(pipe);
}
+ }
+}
- if (DISPLAY_VER(dev_priv) < 13)
- continue;
+static u8 expected_secondary_pipes(u8 primary_pipes, int num_pipes)
+{
+ u8 secondary_pipes = 0;
- power_domain = POWER_DOMAIN_PIPE(pipe);
- with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
- u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
+ for (int i = 1; i < num_pipes; i++)
+ secondary_pipes |= primary_pipes << i;
- if (tmp & UNCOMPRESSED_JOINER_PRIMARY)
- *primary_pipes |= BIT(pipe);
- if (tmp & UNCOMPRESSED_JOINER_SECONDARY)
- *secondary_pipes |= BIT(pipe);
- }
- }
+ return secondary_pipes;
+}
+
+static u8 expected_uncompressed_joiner_secondary_pipes(u8 uncompjoiner_primary_pipes)
+{
+ return expected_secondary_pipes(uncompjoiner_primary_pipes, 2);
+}
- /* Joiner pipes should always be consecutive primary and secondary */
- drm_WARN(&dev_priv->drm, *secondary_pipes != *primary_pipes << 1,
- "Joiner misconfigured (primary pipes 0x%x, secondary pipes 0x%x)\n",
- *primary_pipes, *secondary_pipes);
+static u8 expected_bigjoiner_secondary_pipes(u8 bigjoiner_primary_pipes)
+{
+ return expected_secondary_pipes(bigjoiner_primary_pipes, 2);
}
-static enum pipe get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes)
+static u8 get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes)
{
- if ((secondary_pipes & BIT(pipe)) == 0)
- return pipe;
+ primary_pipes &= GENMASK(pipe, 0);
+
+ return primary_pipes ? BIT(fls(primary_pipes) - 1) : 0;
+}
- /* ignore everything above our pipe */
- primary_pipes &= ~GENMASK(7, pipe);
+static u8 expected_ultrajoiner_secondary_pipes(u8 ultrajoiner_primary_pipes)
+{
+ return expected_secondary_pipes(ultrajoiner_primary_pipes, 4);
+}
- /* highest remaining bit should be our primary pipe */
- return fls(primary_pipes) - 1;
+static u8 fixup_ultrajoiner_secondary_pipes(u8 ultrajoiner_primary_pipes,
+ u8 ultrajoiner_secondary_pipes)
+{
+ return ultrajoiner_secondary_pipes | ultrajoiner_primary_pipes << 3;
}
-static u8 get_joiner_secondary_pipes(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes)
+static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915,
+ u8 *primary_pipes, u8 *secondary_pipes)
{
- enum pipe primary_pipe, next_primary_pipe;
+ struct intel_crtc *crtc;
- primary_pipe = get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes);
+ *primary_pipes = 0;
+ *secondary_pipes = 0;
- if ((primary_pipes & BIT(primary_pipe)) == 0)
- return 0;
+ if (!HAS_ULTRAJOINER(i915))
+ return;
- /* ignore our primary pipe and everything below it */
- primary_pipes &= ~GENMASK(primary_pipe, 0);
- /* make sure a high bit is set for the ffs() */
- primary_pipes |= BIT(7);
- /* lowest remaining bit should be the next primary pipe */
- next_primary_pipe = ffs(primary_pipes) - 1;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
+ joiner_pipes(i915)) {
+ enum intel_display_power_domain power_domain;
+ enum pipe pipe = crtc->pipe;
+ intel_wakeref_t wakeref;
- return secondary_pipes & GENMASK(next_primary_pipe - 1, primary_pipe);
+ power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe);
+ with_intel_display_power_if_enabled(i915, power_domain, wakeref) {
+ u32 tmp = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe));
+
+ if (!(tmp & ULTRA_JOINER_ENABLE))
+ continue;
+
+ if (tmp & PRIMARY_ULTRA_JOINER_ENABLE)
+ *primary_pipes |= BIT(pipe);
+ else
+ *secondary_pipes |= BIT(pipe);
+ }
+ }
+}
+
+static void enabled_joiner_pipes(struct drm_i915_private *dev_priv,
+ enum pipe pipe,
+ u8 *primary_pipe, u8 *secondary_pipes)
+{
+ struct intel_display *display = to_intel_display(&dev_priv->drm);
+ u8 primary_ultrajoiner_pipes;
+ u8 primary_uncompressed_joiner_pipes, primary_bigjoiner_pipes;
+ u8 secondary_ultrajoiner_pipes;
+ u8 secondary_uncompressed_joiner_pipes, secondary_bigjoiner_pipes;
+ u8 ultrajoiner_pipes;
+ u8 uncompressed_joiner_pipes, bigjoiner_pipes;
+
+ enabled_ultrajoiner_pipes(dev_priv, &primary_ultrajoiner_pipes,
+ &secondary_ultrajoiner_pipes);
+ /*
+ * For some strange reason the last pipe in the set of four
+ * shouldn't have ultrajoiner enable bit set in hardware.
+ * Set the bit anyway to make life easier.
+ */
+ drm_WARN_ON(&dev_priv->drm,
+ expected_secondary_pipes(primary_ultrajoiner_pipes, 3) !=
+ secondary_ultrajoiner_pipes);
+ secondary_ultrajoiner_pipes =
+ fixup_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes,
+ secondary_ultrajoiner_pipes);
+
+ drm_WARN_ON(&dev_priv->drm, (primary_ultrajoiner_pipes & secondary_ultrajoiner_pipes) != 0);
+
+ enabled_uncompressed_joiner_pipes(display, &primary_uncompressed_joiner_pipes,
+ &secondary_uncompressed_joiner_pipes);
+
+ drm_WARN_ON(display->drm,
+ (primary_uncompressed_joiner_pipes & secondary_uncompressed_joiner_pipes) != 0);
+
+ enabled_bigjoiner_pipes(display, &primary_bigjoiner_pipes,
+ &secondary_bigjoiner_pipes);
+
+ drm_WARN_ON(display->drm,
+ (primary_bigjoiner_pipes & secondary_bigjoiner_pipes) != 0);
+
+ ultrajoiner_pipes = primary_ultrajoiner_pipes | secondary_ultrajoiner_pipes;
+ uncompressed_joiner_pipes = primary_uncompressed_joiner_pipes |
+ secondary_uncompressed_joiner_pipes;
+ bigjoiner_pipes = primary_bigjoiner_pipes | secondary_bigjoiner_pipes;
+
+ drm_WARN(display->drm, (ultrajoiner_pipes & bigjoiner_pipes) != ultrajoiner_pipes,
+ "Ultrajoiner pipes(%#x) should be bigjoiner pipes(%#x)\n",
+ ultrajoiner_pipes, bigjoiner_pipes);
+
+ drm_WARN(display->drm, secondary_ultrajoiner_pipes !=
+ expected_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes),
+ "Wrong secondary ultrajoiner pipes(expected %#x, current %#x)\n",
+ expected_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes),
+ secondary_ultrajoiner_pipes);
+
+ drm_WARN(display->drm, (uncompressed_joiner_pipes & bigjoiner_pipes) != 0,
+ "Uncompressed joiner pipes(%#x) and bigjoiner pipes(%#x) can't intersect\n",
+ uncompressed_joiner_pipes, bigjoiner_pipes);
+
+ drm_WARN(display->drm, secondary_bigjoiner_pipes !=
+ expected_bigjoiner_secondary_pipes(primary_bigjoiner_pipes),
+ "Wrong secondary bigjoiner pipes(expected %#x, current %#x)\n",
+ expected_bigjoiner_secondary_pipes(primary_bigjoiner_pipes),
+ secondary_bigjoiner_pipes);
+
+ drm_WARN(display->drm, secondary_uncompressed_joiner_pipes !=
+ expected_uncompressed_joiner_secondary_pipes(primary_uncompressed_joiner_pipes),
+ "Wrong secondary uncompressed joiner pipes(expected %#x, current %#x)\n",
+ expected_uncompressed_joiner_secondary_pipes(primary_uncompressed_joiner_pipes),
+ secondary_uncompressed_joiner_pipes);
+
+ *primary_pipe = 0;
+ *secondary_pipes = 0;
+
+ if (ultrajoiner_pipes & BIT(pipe)) {
+ *primary_pipe = get_joiner_primary_pipe(pipe, primary_ultrajoiner_pipes);
+ *secondary_pipes = secondary_ultrajoiner_pipes &
+ expected_ultrajoiner_secondary_pipes(*primary_pipe);
+
+ drm_WARN(display->drm,
+ expected_ultrajoiner_secondary_pipes(*primary_pipe) !=
+ *secondary_pipes,
+ "Wrong ultrajoiner secondary pipes for primary_pipe %#x (expected %#x, current %#x)\n",
+ *primary_pipe,
+ expected_ultrajoiner_secondary_pipes(*primary_pipe),
+ *secondary_pipes);
+ return;
+ }
+
+ if (uncompressed_joiner_pipes & BIT(pipe)) {
+ *primary_pipe = get_joiner_primary_pipe(pipe, primary_uncompressed_joiner_pipes);
+ *secondary_pipes = secondary_uncompressed_joiner_pipes &
+ expected_uncompressed_joiner_secondary_pipes(*primary_pipe);
+
+ drm_WARN(display->drm,
+ expected_uncompressed_joiner_secondary_pipes(*primary_pipe) !=
+ *secondary_pipes,
+ "Wrong uncompressed joiner secondary pipes for primary_pipe %#x (expected %#x, current %#x)\n",
+ *primary_pipe,
+ expected_uncompressed_joiner_secondary_pipes(*primary_pipe),
+ *secondary_pipes);
+ return;
+ }
+
+ if (bigjoiner_pipes & BIT(pipe)) {
+ *primary_pipe = get_joiner_primary_pipe(pipe, primary_bigjoiner_pipes);
+ *secondary_pipes = secondary_bigjoiner_pipes &
+ expected_bigjoiner_secondary_pipes(*primary_pipe);
+
+ drm_WARN(display->drm,
+ expected_bigjoiner_secondary_pipes(*primary_pipe) !=
+ *secondary_pipes,
+ "Wrong bigjoiner secondary pipes for primary_pipe %#x (expected %#x, current %#x)\n",
+ *primary_pipe,
+ expected_bigjoiner_secondary_pipes(*primary_pipe),
+ *secondary_pipes);
+ return;
+ }
}
static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
@@ -3628,7 +3894,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 primary_pipes, secondary_pipes;
+ u8 primary_pipe, secondary_pipes;
u8 enabled_transcoders = 0;
/*
@@ -3681,10 +3947,9 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
enabled_transcoders |= BIT(cpu_transcoder);
/* joiner secondary -> consider the primary pipe's transcoder as well */
- enabled_joiner_pipes(dev_priv, &primary_pipes, &secondary_pipes);
+ enabled_joiner_pipes(dev_priv, crtc->pipe, &primary_pipe, &secondary_pipes);
if (secondary_pipes & BIT(crtc->pipe)) {
- cpu_transcoder = (enum transcoder)
- get_joiner_primary_pipe(crtc->pipe, primary_pipes, secondary_pipes);
+ cpu_transcoder = (enum transcoder)ffs(primary_pipe) - 1;
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
enabled_transcoders |= BIT(cpu_transcoder);
}
@@ -3815,17 +4080,15 @@ static void intel_joiner_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 primary_pipes, secondary_pipes;
+ u8 primary_pipe, secondary_pipes;
enum pipe pipe = crtc->pipe;
- enabled_joiner_pipes(i915, &primary_pipes, &secondary_pipes);
+ enabled_joiner_pipes(i915, pipe, &primary_pipe, &secondary_pipes);
- if (((primary_pipes | secondary_pipes) & BIT(pipe)) == 0)
+ if (((primary_pipe | secondary_pipes) & BIT(pipe)) == 0)
return;
- crtc_state->joiner_pipes =
- BIT(get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes)) |
- get_joiner_secondary_pipes(pipe, primary_pipes, secondary_pipes);
+ crtc_state->joiner_pipes = primary_pipe | secondary_pipes;
}
static bool hsw_get_pipe_config(struct intel_crtc *crtc,
@@ -3986,7 +4249,7 @@ int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config)
struct drm_display_mode *
intel_encoder_current_mode(struct intel_encoder *encoder)
{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_display *display = to_intel_display(encoder);
struct intel_crtc_state *crtc_state;
struct drm_display_mode *mode;
struct intel_crtc *crtc;
@@ -3995,7 +4258,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
if (!encoder->get_hw_state(encoder, &pipe))
return NULL;
- crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
mode = kzalloc(sizeof(*mode), GFP_KERNEL);
if (!mode)
@@ -4285,22 +4548,11 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
if (ret)
return ret;
- ret = intel_compute_pipe_wm(state, crtc);
+ ret = intel_wm_compute(state, crtc);
if (ret) {
drm_dbg_kms(&dev_priv->drm,
- "Target pipe watermarks are invalid\n");
- return ret;
- }
-
- /*
- * Calculate 'intermediate' watermarks that satisfy both the
- * old state and the new state. We can program these
- * immediately.
- */
- ret = intel_compute_intermediate_wm(state, crtc);
- if (ret) {
- drm_dbg_kms(&dev_priv->drm,
- "No valid intermediate pipe watermarks are possible\n");
+ "[CRTC:%d:%s] watermarks are invalid\n",
+ crtc->base.base.id, crtc->base.name);
return ret;
}
@@ -6732,17 +6984,12 @@ int intel_atomic_check(struct drm_device *dev,
static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
{
- struct intel_crtc_state __maybe_unused *crtc_state;
- struct intel_crtc *crtc;
- int i, ret;
+ int ret;
ret = drm_atomic_helper_prepare_planes(state->base.dev, &state->base);
if (ret < 0)
return ret;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
- intel_color_prepare_commit(state, crtc);
-
return 0;
}
@@ -6823,12 +7070,12 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state,
* During modesets pipe configuration was programmed as the
* CRTC was enabled.
*/
- if (!modeset) {
+ if (!modeset && !new_crtc_state->use_dsb) {
if (intel_crtc_needs_color_update(new_crtc_state))
- intel_color_commit_arm(new_crtc_state);
+ intel_color_commit_arm(NULL, new_crtc_state);
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
- bdw_set_pipe_misc(new_crtc_state);
+ bdw_set_pipe_misc(NULL, new_crtc_state);
if (intel_crtc_needs_fastset(new_crtc_state))
intel_pipe_fastset(old_crtc_state, new_crtc_state);
@@ -6925,10 +7172,12 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF));
if (!modeset &&
- intel_crtc_needs_color_update(new_crtc_state))
- intel_color_commit_noarm(new_crtc_state);
+ intel_crtc_needs_color_update(new_crtc_state) &&
+ !new_crtc_state->use_dsb)
+ intel_color_commit_noarm(NULL, new_crtc_state);
- intel_crtc_planes_update_noarm(state, crtc);
+ if (!new_crtc_state->use_dsb)
+ intel_crtc_planes_update_noarm(NULL, state, crtc);
}
static void intel_update_crtc(struct intel_atomic_state *state,
@@ -6939,16 +7188,25 @@ static void intel_update_crtc(struct intel_atomic_state *state,
struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- /* Perform vblank evasion around commit operation */
- intel_pipe_update_start(state, crtc);
+ if (new_crtc_state->use_dsb) {
+ intel_crtc_prepare_vblank_event(new_crtc_state, &crtc->dsb_event);
- commit_pipe_pre_planes(state, crtc);
+ intel_dsb_commit(new_crtc_state->dsb_commit, false);
+ } else {
+ /* Perform vblank evasion around commit operation */
+ intel_pipe_update_start(state, crtc);
+
+ if (new_crtc_state->dsb_commit)
+ intel_dsb_commit(new_crtc_state->dsb_commit, false);
- intel_crtc_planes_update_arm(state, crtc);
+ commit_pipe_pre_planes(state, crtc);
- commit_pipe_post_planes(state, crtc);
+ intel_crtc_planes_update_arm(NULL, state, crtc);
- intel_pipe_update_end(state, crtc);
+ commit_pipe_post_planes(state, crtc);
+
+ intel_pipe_update_end(state, crtc);
+ }
/*
* VRR/Seamless M/N update may need to update frame timings.
@@ -7273,6 +7531,24 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat
}
}
+static void intel_atomic_dsb_wait_commit(struct intel_crtc_state *crtc_state)
+{
+ if (crtc_state->dsb_commit)
+ intel_dsb_wait(crtc_state->dsb_commit);
+
+ intel_color_wait_commit(crtc_state);
+}
+
+static void intel_atomic_dsb_cleanup(struct intel_crtc_state *crtc_state)
+{
+ if (crtc_state->dsb_commit) {
+ intel_dsb_cleanup(crtc_state->dsb_commit);
+ crtc_state->dsb_commit = NULL;
+ }
+
+ intel_color_cleanup_commit(crtc_state);
+}
+
static void intel_atomic_cleanup_work(struct work_struct *work)
{
struct intel_atomic_state *state =
@@ -7283,7 +7559,7 @@ static void intel_atomic_cleanup_work(struct work_struct *work)
int i;
for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i)
- intel_color_cleanup_commit(old_crtc_state);
+ intel_atomic_dsb_cleanup(old_crtc_state);
drm_atomic_helper_cleanup_planes(&i915->drm, &state->base);
drm_atomic_helper_commit_cleanup_done(&state->base);
@@ -7324,15 +7600,93 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s
* caller made sure that the object is synced wrt. the related color clear value
* GPU write on it.
*/
- ret = i915_gem_object_read_from_page(intel_fb_obj(fb),
- fb->offsets[cc_plane] + 16,
- &plane_state->ccval,
- sizeof(plane_state->ccval));
+ ret = intel_bo_read_from_page(intel_fb_bo(fb),
+ fb->offsets[cc_plane] + 16,
+ &plane_state->ccval,
+ sizeof(plane_state->ccval));
/* The above could only fail if the FB obj has an unexpected backing store type. */
drm_WARN_ON(&i915->drm, ret);
}
}
+static void intel_atomic_dsb_prepare(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ intel_color_prepare_commit(state, crtc);
+}
+
+static void intel_atomic_dsb_finish(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);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ if (!new_crtc_state->hw.active)
+ return;
+
+ if (state->base.legacy_cursor_update)
+ return;
+
+ /* FIXME deal with everything */
+ new_crtc_state->use_dsb =
+ new_crtc_state->update_planes &&
+ !new_crtc_state->vrr.enable &&
+ !new_crtc_state->do_async_flip &&
+ !new_crtc_state->has_psr &&
+ !new_crtc_state->scaler_state.scaler_users &&
+ !old_crtc_state->scaler_state.scaler_users &&
+ !intel_crtc_needs_modeset(new_crtc_state) &&
+ !intel_crtc_needs_fastset(new_crtc_state);
+
+ if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color_vblank)
+ return;
+
+ /*
+ * Rough estimate:
+ * ~64 registers per each plane * 8 planes = 512
+ * Double that for pipe stuff and other overhead.
+ */
+ new_crtc_state->dsb_commit = intel_dsb_prepare(state, crtc, INTEL_DSB_0,
+ new_crtc_state->use_dsb ? 1024 : 16);
+ if (!new_crtc_state->dsb_commit) {
+ new_crtc_state->use_dsb = false;
+ intel_color_cleanup_commit(new_crtc_state);
+ return;
+ }
+
+ if (new_crtc_state->use_dsb) {
+ if (intel_crtc_needs_color_update(new_crtc_state))
+ intel_color_commit_noarm(new_crtc_state->dsb_commit,
+ new_crtc_state);
+ intel_crtc_planes_update_noarm(new_crtc_state->dsb_commit,
+ state, crtc);
+
+ intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit);
+
+ if (intel_crtc_needs_color_update(new_crtc_state))
+ intel_color_commit_arm(new_crtc_state->dsb_commit,
+ new_crtc_state);
+ bdw_set_pipe_misc(new_crtc_state->dsb_commit,
+ new_crtc_state);
+ intel_crtc_planes_update_arm(new_crtc_state->dsb_commit,
+ state, crtc);
+
+ if (!new_crtc_state->dsb_color_vblank) {
+ intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1);
+ intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit);
+ intel_dsb_interrupt(new_crtc_state->dsb_commit);
+ }
+ }
+
+ if (new_crtc_state->dsb_color_vblank)
+ intel_dsb_chain(state, new_crtc_state->dsb_commit,
+ new_crtc_state->dsb_color_vblank, true);
+
+ intel_dsb_finish(new_crtc_state->dsb_commit);
+}
+
static void intel_atomic_commit_tail(struct intel_atomic_state *state)
{
struct drm_device *dev = state->base.dev;
@@ -7340,13 +7694,21 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
struct intel_crtc_state *new_crtc_state, *old_crtc_state;
struct intel_crtc *crtc;
struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
int i;
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ intel_atomic_dsb_prepare(state, crtc);
+
intel_atomic_commit_fence_wait(state);
intel_td_flush(dev_priv);
+ intel_atomic_prepare_plane_clear_colors(state);
+
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ intel_atomic_dsb_finish(state, crtc);
+
drm_atomic_helper_wait_for_dependencies(&state->base);
drm_dp_mst_atomic_wait_for_dependencies(&state->base);
intel_atomic_global_state_wait_for_dependencies(state);
@@ -7380,8 +7742,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
*/
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF);
- intel_atomic_prepare_plane_clear_colors(state);
-
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
if (intel_crtc_needs_modeset(new_crtc_state) ||
@@ -7462,7 +7822,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
if (new_crtc_state->do_async_flip)
intel_crtc_disable_flip_done(state, crtc);
- intel_color_wait_commit(new_crtc_state);
+ intel_atomic_dsb_wait_commit(new_crtc_state);
}
/*
@@ -7497,14 +7857,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_modeset_verify_crtc(state, crtc);
- /* Must be done after gamma readout due to HSW split gamma vs. IPS w/a */
- hsw_ips_post_update(state, crtc);
-
- /*
- * Activate DRRS after state readout to avoid
- * dp_m_n vs. dp_m2_n2 confusion on BDW+.
- */
- intel_drrs_activate(new_crtc_state);
+ intel_post_plane_update_after_readout(state, crtc);
/*
* DSB cleanup is done in cleanup_work aligning with framebuffer
@@ -7514,7 +7867,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
* FIXME get rid of this funny new->old swapping
*/
old_crtc_state->dsb_color_vblank = fetch_and_zero(&new_crtc_state->dsb_color_vblank);
- old_crtc_state->dsb_color_commit = fetch_and_zero(&new_crtc_state->dsb_color_commit);
+ old_crtc_state->dsb_commit = fetch_and_zero(&new_crtc_state->dsb_commit);
}
/* Underruns don't always raise interrupts, so check manually */
@@ -7661,13 +8014,6 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state,
ret = intel_atomic_swap_state(state);
if (ret) {
- struct intel_crtc_state *new_crtc_state;
- struct intel_crtc *crtc;
- int i;
-
- for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
- intel_color_cleanup_commit(new_crtc_state);
-
drm_atomic_helper_unprepare_planes(dev, &state->base);
intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
return ret;
@@ -7702,23 +8048,6 @@ void intel_plane_destroy(struct drm_plane *plane)
kfree(to_intel_plane(plane));
}
-int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
- struct drm_crtc *drmmode_crtc;
- struct intel_crtc *crtc;
-
- drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
- if (!drmmode_crtc)
- return -ENOENT;
-
- crtc = to_intel_crtc(drmmode_crtc);
- pipe_from_crtc_id->pipe = crtc->pipe;
-
- return 0;
-}
-
static u32 intel_encoder_possible_clones(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
@@ -7961,8 +8290,9 @@ static int max_dotclock(struct drm_i915_private *i915)
{
int max_dotclock = i915->display.cdclk.max_dotclk_freq;
- /* icl+ might use joiner */
- if (DISPLAY_VER(i915) >= 11)
+ if (HAS_ULTRAJOINER(i915))
+ max_dotclock *= 4;
+ else if (HAS_UNCOMPRESSED_JOINER(i915) || HAS_BIGJOINER(i915))
max_dotclock *= 2;
return max_dotclock;
@@ -8086,7 +8416,7 @@ enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *de
enum drm_mode_status
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
const struct drm_display_mode *mode,
- bool joiner)
+ int num_joined_pipes)
{
int plane_width_max, plane_height_max;
@@ -8103,7 +8433,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
* too big for that.
*/
if (DISPLAY_VER(dev_priv) >= 11) {
- plane_width_max = 5120 << joiner;
+ plane_width_max = 5120 * num_joined_pipes;
plane_height_max = 4320;
} else {
plane_width_max = 5120;
@@ -8255,9 +8585,9 @@ out:
return ret;
}
-void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
+void i830_enable_pipe(struct intel_display *display, enum pipe pipe)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
enum transcoder cpu_transcoder = (enum transcoder)pipe;
/* 640x480@60Hz, ~25175 kHz */
struct dpll clock = {
@@ -8270,10 +8600,10 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
u32 dpll, fp;
int i;
- drm_WARN_ON(&dev_priv->drm,
+ drm_WARN_ON(display->drm,
i9xx_calc_dpll_params(48000, &clock) != 25154);
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"enabling pipe %c due to force quirk (vco=%d dot=%d)\n",
pipe_name(pipe), clock.vco, clock.dot);
@@ -8285,35 +8615,35 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
PLL_REF_INPUT_DREFCLK |
DPLL_VCO_ENABLE;
- intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder),
+ intel_de_write(display, TRANS_HTOTAL(display, cpu_transcoder),
HACTIVE(640 - 1) | HTOTAL(800 - 1));
- intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder),
+ intel_de_write(display, TRANS_HBLANK(display, cpu_transcoder),
HBLANK_START(640 - 1) | HBLANK_END(800 - 1));
- intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder),
+ intel_de_write(display, TRANS_HSYNC(display, cpu_transcoder),
HSYNC_START(656 - 1) | HSYNC_END(752 - 1));
- intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
+ intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder),
VACTIVE(480 - 1) | VTOTAL(525 - 1));
- intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
+ intel_de_write(display, TRANS_VBLANK(display, cpu_transcoder),
VBLANK_START(480 - 1) | VBLANK_END(525 - 1));
- intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder),
+ intel_de_write(display, TRANS_VSYNC(display, cpu_transcoder),
VSYNC_START(490 - 1) | VSYNC_END(492 - 1));
- intel_de_write(dev_priv, PIPESRC(dev_priv, pipe),
+ intel_de_write(display, PIPESRC(display, pipe),
PIPESRC_WIDTH(640 - 1) | PIPESRC_HEIGHT(480 - 1));
- intel_de_write(dev_priv, FP0(pipe), fp);
- intel_de_write(dev_priv, FP1(pipe), fp);
+ intel_de_write(display, FP0(pipe), fp);
+ intel_de_write(display, FP1(pipe), fp);
/*
* Apparently we need to have VGA mode enabled prior to changing
* the P1/P2 dividers. Otherwise the DPLL will keep using the old
* dividers, even though the register value does change.
*/
- intel_de_write(dev_priv, DPLL(dev_priv, pipe),
+ intel_de_write(display, DPLL(display, pipe),
dpll & ~DPLL_VGA_MODE_DIS);
- intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
+ intel_de_write(display, DPLL(display, pipe), dpll);
/* Wait for the clocks to stabilize. */
- intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
+ intel_de_posting_read(display, DPLL(display, pipe));
udelay(150);
/* The pixel multiplier can only be updated once the
@@ -8321,46 +8651,46 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
*
* So write it again.
*/
- intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
+ intel_de_write(display, DPLL(display, pipe), dpll);
/* We do this three times for luck */
for (i = 0; i < 3 ; i++) {
- intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
- intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
+ intel_de_write(display, DPLL(display, pipe), dpll);
+ intel_de_posting_read(display, DPLL(display, pipe));
udelay(150); /* wait for warmup */
}
- intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), TRANSCONF_ENABLE);
- intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe));
+ intel_de_write(display, TRANSCONF(display, pipe), TRANSCONF_ENABLE);
+ intel_de_posting_read(display, TRANSCONF(display, pipe));
intel_wait_for_pipe_scanline_moving(crtc);
}
-void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
+void i830_disable_pipe(struct intel_display *display, enum pipe pipe)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
- drm_dbg_kms(&dev_priv->drm, "disabling pipe %c due to force quirk\n",
+ drm_dbg_kms(display->drm, "disabling pipe %c due to force quirk\n",
pipe_name(pipe));
- drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_A)) & DISP_ENABLE);
- drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_B)) & DISP_ENABLE);
- drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_C)) & DISP_ENABLE);
- drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & MCURSOR_MODE_MASK);
- drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_B)) & MCURSOR_MODE_MASK);
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, DSPCNTR(display, PLANE_A)) & DISP_ENABLE);
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, DSPCNTR(display, PLANE_B)) & DISP_ENABLE);
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, DSPCNTR(display, PLANE_C)) & DISP_ENABLE);
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, CURCNTR(display, PIPE_A)) & MCURSOR_MODE_MASK);
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, CURCNTR(display, PIPE_B)) & MCURSOR_MODE_MASK);
- intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), 0);
- intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe));
+ intel_de_write(display, TRANSCONF(display, pipe), 0);
+ intel_de_posting_read(display, TRANSCONF(display, pipe));
intel_wait_for_pipe_scanline_stopped(crtc);
- intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS);
- intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
+ intel_de_write(display, DPLL(display, pipe), DPLL_VGA_MODE_DIS);
+ intel_de_posting_read(display, DPLL(display, pipe));
}
void intel_hpd_poll_fini(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index b21d9578d5db..61e1df878de9 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -40,7 +40,6 @@ struct drm_encoder;
struct drm_file;
struct drm_format_info;
struct drm_framebuffer;
-struct drm_i915_gem_object;
struct drm_i915_private;
struct drm_mode_fb_cmd2;
struct drm_modeset_acquire_ctx;
@@ -52,6 +51,7 @@ struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_digital_port;
+struct intel_display;
struct intel_dp;
struct intel_encoder;
struct intel_initial_plane_config;
@@ -94,16 +94,6 @@ static inline bool transcoder_is_dsi(enum transcoder transcoder)
return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C;
}
-/*
- * Global legacy plane identifier. Valid only for primary/sprite
- * planes on pre-g4x, and only for primary planes on g4x-bdw.
- */
-enum i9xx_plane_id {
- PLANE_A,
- PLANE_B,
- PLANE_C,
-};
-
#define plane_name(p) ((p) + 'A')
#define for_each_plane_id_on_crtc(__crtc, __p) \
@@ -401,6 +391,30 @@ enum phy_fia {
((connector) = to_intel_connector((__state)->base.connectors[__i].ptr), \
(new_connector_state) = to_intel_digital_connector_state((__state)->base.connectors[__i].new_state), 1))
+#define for_each_crtc_in_masks(display, crtc, first_pipes, second_pipes, i) \
+ for ((i) = 0; \
+ (i) < (I915_MAX_PIPES * 2) && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \
+ (i)++) \
+ for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i))
+
+#define for_each_crtc_in_masks_reverse(display, crtc, first_pipes, second_pipes, i) \
+ for ((i) = (I915_MAX_PIPES * 2 - 1); \
+ (i) >= 0 && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \
+ (i)--) \
+ for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i))
+
+#define for_each_pipe_crtc_modeset_disable(display, crtc, crtc_state, i) \
+ for_each_crtc_in_masks(display, crtc, \
+ _intel_modeset_primary_pipes(crtc_state), \
+ _intel_modeset_secondary_pipes(crtc_state), \
+ i)
+
+#define for_each_pipe_crtc_modeset_enable(display, crtc, crtc_state, i) \
+ for_each_crtc_in_masks_reverse(display, crtc, \
+ _intel_modeset_primary_pipes(crtc_state), \
+ _intel_modeset_secondary_pipes(crtc_state), \
+ i)
+
int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
struct intel_crtc *crtc);
@@ -415,7 +429,7 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
enum drm_mode_status
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
const struct drm_display_mode *mode,
- bool joiner);
+ int num_joined_pipes);
enum drm_mode_status
intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915,
const struct drm_display_mode *mode);
@@ -425,7 +439,14 @@ bool is_trans_port_sync_master(const struct intel_crtc_state *state);
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state);
bool intel_crtc_is_joiner_secondary(const struct intel_crtc_state *crtc_state);
bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_bigjoiner_primary(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_ultrajoiner(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_ultrajoiner_primary(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_ultrajoiner_enable_needed(const struct intel_crtc_state *crtc_state);
u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state);
+u8 _intel_modeset_primary_pipes(const struct intel_crtc_state *crtc_state);
+u8 _intel_modeset_secondary_pipes(const struct intel_crtc_state *crtc_state);
struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state);
bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state);
bool intel_pipe_config_compare(const struct intel_crtc_state *current_config,
@@ -437,8 +458,8 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state);
void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state);
void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state);
void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state);
-void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe);
-void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe);
+void i830_enable_pipe(struct intel_display *display, enum pipe pipe);
+void i830_disable_pipe(struct intel_display *display, enum pipe pipe);
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv);
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
const char *name, u32 reg, int ref_freq);
@@ -470,16 +491,10 @@ bool intel_encoder_is_snps(struct intel_encoder *encoder);
bool intel_encoder_is_tc(struct intel_encoder *encoder);
enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder);
-int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-
int ilk_get_lanes_required(int target_clock, int link_bw, int bpp);
void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
struct intel_digital_port *dig_port,
unsigned int expected_mask);
-struct drm_framebuffer *
-intel_framebuffer_create(struct drm_i915_gem_object *obj,
- struct drm_mode_fb_cmd2 *mode_cmd);
bool intel_fuzzy_clock_check(int clock1, int clock2);
@@ -586,5 +601,6 @@ bool assert_port_valid(struct drm_i915_private *i915, enum port port);
})
bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915);
+int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state);
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
index 0a711114ff2b..45697af25fa9 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -81,10 +81,8 @@ struct intel_display_funcs {
struct intel_wm_funcs {
/* update_wm is for legacy wm management */
void (*update_wm)(struct drm_i915_private *dev_priv);
- int (*compute_pipe_wm)(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
- int (*compute_intermediate_wm)(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
+ int (*compute_watermarks)(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
void (*initial_watermarks)(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void (*atomic_update_watermarks)(struct intel_atomic_state *state,
@@ -457,6 +455,10 @@ struct intel_display {
/* For i915gm/i945gm vblank irq workaround */
u8 vblank_enabled;
+ int vblank_wa_num_pipes;
+
+ struct work_struct vblank_dc_work;
+
u32 de_irq_mask[I915_MAX_PIPES];
u32 pipestat_irq_mask[I915_MAX_PIPES];
} irq;
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index f5f618199d39..11aff485d8fa 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -3,6 +3,7 @@
* Copyright © 2020 Intel Corporation
*/
+#include <linux/debugfs.h>
#include <linux/string_helpers.h>
#include <drm/drm_debugfs.h>
@@ -10,13 +11,13 @@
#include <drm/drm_fourcc.h>
#include "hsw_ips.h"
-#include "i915_debugfs.h"
#include "i915_irq.h"
#include "i915_reg.h"
#include "intel_alpm.h"
+#include "intel_bo.h"
#include "intel_crtc.h"
-#include "intel_de.h"
#include "intel_crtc_state_dump.h"
+#include "intel_de.h"
#include "intel_display_debugfs.h"
#include "intel_display_debugfs_params.h"
#include "intel_display_power.h"
@@ -26,7 +27,9 @@
#include "intel_dp.h"
#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
+#include "intel_dp_test.h"
#include "intel_drrs.h"
+#include "intel_fb.h"
#include "intel_fbc.h"
#include "intel_fbdev.h"
#include "intel_hdcp.h"
@@ -39,11 +42,28 @@
#include "intel_vdsc.h"
#include "intel_wm.h"
+static struct intel_display *node_to_intel_display(struct drm_info_node *node)
+{
+ return to_intel_display(node->minor->dev);
+}
+
static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
{
return to_i915(node->minor->dev);
}
+static int intel_display_caps(struct seq_file *m, void *data)
+{
+ struct intel_display *display = node_to_intel_display(m->private);
+ struct drm_printer p = drm_seq_file_printer(m);
+
+ intel_display_device_info_print(DISPLAY_INFO(display),
+ DISPLAY_RUNTIME_INFO(display), &p);
+ intel_display_params_dump(&display->params, display->drm->driver->name, &p);
+
+ return 0;
+}
+
static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -106,7 +126,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
fbdev_fb->base.format->cpp[0] * 8,
fbdev_fb->base.modifier,
drm_framebuffer_read_refcount(&fbdev_fb->base));
- i915_debugfs_describe_obj(m, intel_fb_obj(&fbdev_fb->base));
+ intel_bo_describe(m, intel_fb_bo(&fbdev_fb->base));
seq_putc(m, '\n');
}
#endif
@@ -124,7 +144,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
fb->base.format->cpp[0] * 8,
fb->base.modifier,
drm_framebuffer_read_refcount(&fb->base));
- i915_debugfs_describe_obj(m, intel_fb_obj(&fb->base));
+ intel_bo_describe(m, intel_fb_bo(&fb->base));
seq_putc(m, '\n');
}
mutex_unlock(&dev_priv->drm.mode_config.fb_lock);
@@ -424,7 +444,7 @@ static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc)
int num_scalers = crtc->num_scalers;
int i;
- /* Not all platformas have a scaler */
+ /* Not all platforms have a scaler */
if (num_scalers) {
seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d scaling_filter=%d",
num_scalers,
@@ -773,198 +793,6 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused)
return 0;
}
-static ssize_t i915_displayport_test_active_write(struct file *file,
- const char __user *ubuf,
- size_t len, loff_t *offp)
-{
- char *input_buffer;
- int status = 0;
- struct drm_device *dev;
- struct drm_connector *connector;
- struct drm_connector_list_iter conn_iter;
- struct intel_dp *intel_dp;
- int val = 0;
-
- dev = ((struct seq_file *)file->private_data)->private;
-
- if (len == 0)
- return 0;
-
- input_buffer = memdup_user_nul(ubuf, len);
- if (IS_ERR(input_buffer))
- return PTR_ERR(input_buffer);
-
- drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len);
-
- drm_connector_list_iter_begin(dev, &conn_iter);
- drm_for_each_connector_iter(connector, &conn_iter) {
- struct intel_encoder *encoder;
-
- if (connector->connector_type !=
- DRM_MODE_CONNECTOR_DisplayPort)
- continue;
-
- encoder = to_intel_encoder(connector->encoder);
- if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
- continue;
-
- if (encoder && connector->status == connector_status_connected) {
- intel_dp = enc_to_intel_dp(encoder);
- status = kstrtoint(input_buffer, 10, &val);
- if (status < 0)
- break;
- drm_dbg(dev, "Got %d for test active\n", val);
- /* To prevent erroneous activation of the compliance
- * testing code, only accept an actual value of 1 here
- */
- if (val == 1)
- intel_dp->compliance.test_active = true;
- else
- intel_dp->compliance.test_active = false;
- }
- }
- drm_connector_list_iter_end(&conn_iter);
- kfree(input_buffer);
- if (status < 0)
- return status;
-
- *offp += len;
- return len;
-}
-
-static int i915_displayport_test_active_show(struct seq_file *m, void *data)
-{
- struct drm_i915_private *dev_priv = m->private;
- struct drm_connector *connector;
- struct drm_connector_list_iter conn_iter;
- struct intel_dp *intel_dp;
-
- drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
- drm_for_each_connector_iter(connector, &conn_iter) {
- struct intel_encoder *encoder;
-
- if (connector->connector_type !=
- DRM_MODE_CONNECTOR_DisplayPort)
- continue;
-
- encoder = to_intel_encoder(connector->encoder);
- if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
- continue;
-
- if (encoder && connector->status == connector_status_connected) {
- intel_dp = enc_to_intel_dp(encoder);
- if (intel_dp->compliance.test_active)
- seq_puts(m, "1");
- else
- seq_puts(m, "0");
- } else
- seq_puts(m, "0");
- }
- drm_connector_list_iter_end(&conn_iter);
-
- return 0;
-}
-
-static int i915_displayport_test_active_open(struct inode *inode,
- struct file *file)
-{
- return single_open(file, i915_displayport_test_active_show,
- inode->i_private);
-}
-
-static const struct file_operations i915_displayport_test_active_fops = {
- .owner = THIS_MODULE,
- .open = i915_displayport_test_active_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = i915_displayport_test_active_write
-};
-
-static int i915_displayport_test_data_show(struct seq_file *m, void *data)
-{
- struct drm_i915_private *dev_priv = m->private;
- struct drm_connector *connector;
- struct drm_connector_list_iter conn_iter;
- struct intel_dp *intel_dp;
-
- drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
- drm_for_each_connector_iter(connector, &conn_iter) {
- struct intel_encoder *encoder;
-
- if (connector->connector_type !=
- DRM_MODE_CONNECTOR_DisplayPort)
- continue;
-
- encoder = to_intel_encoder(connector->encoder);
- if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
- continue;
-
- if (encoder && connector->status == connector_status_connected) {
- intel_dp = enc_to_intel_dp(encoder);
- if (intel_dp->compliance.test_type ==
- DP_TEST_LINK_EDID_READ)
- seq_printf(m, "%lx",
- intel_dp->compliance.test_data.edid);
- else if (intel_dp->compliance.test_type ==
- DP_TEST_LINK_VIDEO_PATTERN) {
- seq_printf(m, "hdisplay: %d\n",
- intel_dp->compliance.test_data.hdisplay);
- seq_printf(m, "vdisplay: %d\n",
- intel_dp->compliance.test_data.vdisplay);
- seq_printf(m, "bpc: %u\n",
- intel_dp->compliance.test_data.bpc);
- } else if (intel_dp->compliance.test_type ==
- DP_TEST_LINK_PHY_TEST_PATTERN) {
- seq_printf(m, "pattern: %d\n",
- intel_dp->compliance.test_data.phytest.phy_pattern);
- seq_printf(m, "Number of lanes: %d\n",
- intel_dp->compliance.test_data.phytest.num_lanes);
- seq_printf(m, "Link Rate: %d\n",
- intel_dp->compliance.test_data.phytest.link_rate);
- seq_printf(m, "level: %02x\n",
- intel_dp->train_set[0]);
- }
- } else
- seq_puts(m, "0");
- }
- drm_connector_list_iter_end(&conn_iter);
-
- return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
-
-static int i915_displayport_test_type_show(struct seq_file *m, void *data)
-{
- struct drm_i915_private *dev_priv = m->private;
- struct drm_connector *connector;
- struct drm_connector_list_iter conn_iter;
- struct intel_dp *intel_dp;
-
- drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
- drm_for_each_connector_iter(connector, &conn_iter) {
- struct intel_encoder *encoder;
-
- if (connector->connector_type !=
- DRM_MODE_CONNECTOR_DisplayPort)
- continue;
-
- encoder = to_intel_encoder(connector->encoder);
- if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
- continue;
-
- if (encoder && connector->status == connector_status_connected) {
- intel_dp = enc_to_intel_dp(encoder);
- seq_printf(m, "%02lx\n", intel_dp->compliance.test_type);
- } else
- seq_puts(m, "0");
- }
- drm_connector_list_iter_end(&conn_iter);
-
- return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
-
static ssize_t
i915_fifo_underrun_reset_write(struct file *filp,
const char __user *ubuf,
@@ -1025,6 +853,7 @@ static const struct file_operations i915_fifo_underrun_reset_ops = {
};
static const struct drm_info_list intel_display_debugfs_list[] = {
+ {"intel_display_caps", intel_display_caps, 0},
{"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0},
{"i915_sr_status", i915_sr_status, 0},
{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
@@ -1037,37 +866,22 @@ static const struct drm_info_list intel_display_debugfs_list[] = {
{"i915_lpsp_status", i915_lpsp_status, 0},
};
-static const struct {
- const char *name;
- const struct file_operations *fops;
-} intel_display_debugfs_files[] = {
- {"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops},
- {"i915_dp_test_data", &i915_displayport_test_data_fops},
- {"i915_dp_test_type", &i915_displayport_test_type_fops},
- {"i915_dp_test_active", &i915_displayport_test_active_fops},
-};
-
void intel_display_debugfs_register(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
struct drm_minor *minor = i915->drm.primary;
- int i;
- for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) {
- debugfs_create_file(intel_display_debugfs_files[i].name,
- 0644,
- minor->debugfs_root,
- to_i915(minor->dev),
- intel_display_debugfs_files[i].fops);
- }
+ debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root,
+ to_i915(minor->dev), &i915_fifo_underrun_reset_ops);
drm_debugfs_create_files(intel_display_debugfs_list,
ARRAY_SIZE(intel_display_debugfs_list),
minor->debugfs_root, minor);
intel_bios_debugfs_register(display);
- intel_cdclk_debugfs_register(i915);
- intel_dmc_debugfs_register(i915);
+ intel_cdclk_debugfs_register(display);
+ intel_dmc_debugfs_register(display);
+ intel_dp_test_debugfs_register(display);
intel_fbc_debugfs_register(display);
intel_hpd_debugfs_register(i915);
intel_opregion_debugfs_register(display);
@@ -1502,6 +1316,68 @@ static int intel_crtc_pipe_show(struct seq_file *m, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(intel_crtc_pipe);
+static int i915_joiner_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = m->private;
+
+ seq_printf(m, "%d\n", connector->force_joined_pipes);
+
+ return 0;
+}
+
+static ssize_t i915_joiner_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct intel_connector *connector = m->private;
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ int force_joined_pipes = 0;
+ int ret;
+
+ if (len == 0)
+ return 0;
+
+ ret = kstrtoint_from_user(ubuf, len, 0, &force_joined_pipes);
+ if (ret < 0)
+ return ret;
+
+ switch (force_joined_pipes) {
+ case 0:
+ case 1:
+ case 2:
+ connector->force_joined_pipes = force_joined_pipes;
+ break;
+ case 4:
+ if (HAS_ULTRAJOINER(i915)) {
+ connector->force_joined_pipes = force_joined_pipes;
+ break;
+ }
+
+ fallthrough;
+ default:
+ return -EINVAL;
+ }
+
+ *offp += len;
+
+ return len;
+}
+
+static int i915_joiner_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, i915_joiner_show, inode->i_private);
+}
+
+static const struct file_operations i915_joiner_fops = {
+ .owner = THIS_MODULE,
+ .open = i915_joiner_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = i915_joiner_write
+};
+
/**
* intel_connector_debugfs_add - add i915 specific connector debugfs files
* @connector: pointer to a registered intel_connector
@@ -1548,11 +1424,11 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
connector, &i915_dsc_fractional_bpp_fops);
}
- if (DISPLAY_VER(i915) >= 11 &&
- (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
- connector_type == DRM_MODE_CONNECTOR_eDP)) {
- debugfs_create_bool("i915_bigjoiner_force_enable", 0644, root,
- &connector->force_bigjoiner_enable);
+ if ((connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+ connector_type == DRM_MODE_CONNECTOR_eDP) &&
+ intel_dp_has_joiner(intel_attached_dp(connector))) {
+ debugfs_create_file("i915_joiner_force_enable", 0644, root,
+ connector, &i915_joiner_fops);
}
if (connector_type == DRM_MODE_CONNECTOR_DSI ||
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index 1b46ba985580..aa22189e3853 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -1252,6 +1252,10 @@ static const struct platform_desc bmg_desc = {
PLATFORM(BATTLEMAGE),
};
+static const struct platform_desc ptl_desc = {
+ PLATFORM(PANTHERLAKE),
+};
+
__diag_pop();
/*
@@ -1318,9 +1322,11 @@ static const struct {
INTEL_RPLU_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
INTEL_RPLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
INTEL_DG2_IDS(INTEL_DISPLAY_DEVICE, &dg2_desc),
+ INTEL_ARL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
INTEL_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc),
INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
+ INTEL_PTL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
};
static const struct {
@@ -1331,6 +1337,7 @@ static const struct {
{ 14, 0, &xe_lpdp_display },
{ 14, 1, &xe2_hpd_display },
{ 20, 0, &xe2_lpd_display },
+ { 30, 0, &xe2_lpd_display },
};
static const struct intel_display_device_info *
@@ -1531,6 +1538,7 @@ void intel_display_device_remove(struct drm_i915_private *i915)
static void __intel_display_device_info_runtime_init(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
enum pipe pipe;
@@ -1677,7 +1685,7 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
}
}
- display_runtime->rawclk_freq = intel_read_rawclk(i915);
+ display_runtime->rawclk_freq = intel_read_rawclk(display);
drm_dbg_kms(&i915->drm, "rawclk rate: %d kHz\n", display_runtime->rawclk_freq);
return;
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index dfb0c8bf5ca2..071a36b51f79 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -70,6 +70,8 @@ enum intel_display_platform {
INTEL_DISPLAY_LUNARLAKE,
/* Display ver 14.1 (based on GMD ID) */
INTEL_DISPLAY_BATTLEMAGE,
+ /* Display ver 30 (based on GMD ID) */
+ INTEL_DISPLAY_PANTHERLAKE,
};
enum intel_display_subplatform {
@@ -118,6 +120,7 @@ enum intel_display_subplatform {
#define HAS_4TILE(i915) (IS_DG2(i915) || DISPLAY_VER(i915) >= 14)
#define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5)
+#define HAS_BIGJOINER(i915) (DISPLAY_VER(i915) >= 11 && HAS_DSC(i915))
#define HAS_CDCLK_CRAWL(i915) (DISPLAY_INFO(i915)->has_cdclk_crawl)
#define HAS_CDCLK_SQUASH(i915) (DISPLAY_INFO(i915)->has_cdclk_squash)
#define HAS_CUR_FBC(i915) (!HAS_GMCH(i915) && IS_DISPLAY_VER(i915, 7, 13))
@@ -149,9 +152,13 @@ enum intel_display_subplatform {
#define HAS_PSR(i915) (DISPLAY_INFO(i915)->has_psr)
#define HAS_PSR_HW_TRACKING(i915) (DISPLAY_INFO(i915)->has_psr_hw_tracking)
#define HAS_PSR2_SEL_FETCH(i915) (DISPLAY_VER(i915) >= 12)
-#define HAS_SAGV(i915) (DISPLAY_VER(i915) >= 9 && !IS_LP(i915))
+#define HAS_SAGV(i915) (DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915) && !IS_GEMINILAKE(i915))
#define HAS_TRANSCODER(i915, trans) ((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
BIT(trans)) != 0)
+#define HAS_UNCOMPRESSED_JOINER(i915) (DISPLAY_VER(i915) >= 13)
+#define HAS_ULTRAJOINER(i915) ((DISPLAY_VER(i915) >= 20 || \
+ (IS_DGFX(i915) && DISPLAY_VER(i915) == 14)) && \
+ HAS_DSC(i915))
#define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
#define HAS_AS_SDP(i915) (DISPLAY_VER(i915) >= 13)
#define HAS_CMRR(i915) (DISPLAY_VER(i915) >= 20)
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c
index 069426d9260b..c106fb2dd20b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -82,16 +82,17 @@ bool intel_display_driver_probe_defer(struct pci_dev *pdev)
void intel_display_driver_init_hw(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
struct intel_cdclk_state *cdclk_state;
if (!HAS_DISPLAY(i915))
return;
- cdclk_state = to_intel_cdclk_state(i915->display.cdclk.obj.state);
+ cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state);
- intel_update_cdclk(i915);
- intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK");
- cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw;
+ intel_update_cdclk(display);
+ intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK");
+ cdclk_state->logical = cdclk_state->actual = display->cdclk.hw;
intel_display_wa_apply(i915);
}
@@ -168,10 +169,11 @@ static void intel_mode_config_cleanup(struct drm_i915_private *i915)
static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
{
+ struct intel_display *display = &dev_priv->display;
struct intel_plane *plane;
for_each_intel_plane(&dev_priv->drm, plane) {
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv,
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display,
plane->pipe);
plane->base.possible_crtcs = drm_crtc_mask(&crtc->base);
@@ -193,7 +195,7 @@ void intel_display_driver_early_probe(struct drm_i915_private *i915)
intel_display_irq_init(i915);
intel_dkl_phy_init(i915);
intel_color_init_hooks(i915);
- intel_init_cdclk_hooks(i915);
+ intel_init_cdclk_hooks(&i915->display);
intel_audio_hooks_init(i915);
intel_dpll_init_clock_hook(i915);
intel_init_display_hooks(i915);
@@ -219,7 +221,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
intel_bios_init(display);
- ret = intel_vga_register(i915);
+ ret = intel_vga_register(display);
if (ret)
goto cleanup_bios;
@@ -235,7 +237,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
if (!HAS_DISPLAY(i915))
return 0;
- intel_dmc_init(i915);
+ intel_dmc_init(display);
i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
@@ -243,7 +245,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
intel_mode_config_init(i915);
- ret = intel_cdclk_init(i915);
+ ret = intel_cdclk_init(display);
if (ret)
goto cleanup_vga_client_pw_domain_dmc;
@@ -270,10 +272,10 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
return 0;
cleanup_vga_client_pw_domain_dmc:
- intel_dmc_fini(i915);
+ intel_dmc_fini(display);
intel_power_domains_driver_remove(i915);
cleanup_vga:
- intel_vga_unregister(i915);
+ intel_vga_unregister(display);
cleanup_bios:
intel_bios_driver_remove(display);
@@ -450,13 +452,13 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
intel_display_driver_init_hw(i915);
intel_dpll_update_ref_clks(i915);
- if (i915->display.cdclk.max_cdclk_freq == 0)
- intel_update_max_cdclk(i915);
+ if (display->cdclk.max_cdclk_freq == 0)
+ intel_update_max_cdclk(display);
intel_hti_init(display);
/* Just disable it once at startup */
- intel_vga_disable(i915);
+ intel_vga_disable(display);
intel_setup_outputs(i915);
ret = intel_dp_tunnel_mgr_init(display);
@@ -619,11 +621,11 @@ void intel_display_driver_remove_nogem(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
- intel_dmc_fini(i915);
+ intel_dmc_fini(display);
intel_power_domains_driver_remove(i915);
- intel_vga_unregister(i915);
+ intel_vga_unregister(display);
intel_bios_driver_remove(display);
}
@@ -681,12 +683,13 @@ __intel_display_driver_resume(struct drm_i915_private *i915,
struct drm_atomic_state *state,
struct drm_modeset_acquire_ctx *ctx)
{
+ struct intel_display *display = &i915->display;
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
int ret, i;
intel_modeset_setup_hw_state(i915, ctx);
- intel_vga_redisable(i915);
+ intel_vga_redisable(display);
if (!state)
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index 73369847ed66..6197a4bcac4a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -3,6 +3,8 @@
* Copyright © 2023 Intel Corporation
*/
+#include <drm/drm_vblank.h>
+
#include "gt/intel_rps.h"
#include "i915_drv.h"
#include "i915_irq.h"
@@ -27,7 +29,8 @@
static void
intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_display *display = &dev_priv->display;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
drm_crtc_handle_vblank(&crtc->base);
}
@@ -269,14 +272,17 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv,
intel_uncore_posting_read(&dev_priv->uncore, reg);
}
-static bool i915_has_asle(struct drm_i915_private *i915)
+static bool i915_has_legacy_blc_interrupt(struct intel_display *display)
{
- struct intel_display *display = &i915->display;
+ struct drm_i915_private *i915 = to_i915(display->drm);
- if (!IS_PINEVIEW(i915) && !IS_MOBILE(i915))
- return false;
+ if (IS_I85X(i915))
+ return true;
+
+ if (IS_PINEVIEW(i915))
+ return true;
- return intel_opregion_asle_present(display);
+ return IS_DISPLAY_VER(display, 3, 4) && IS_MOBILE(i915);
}
/**
@@ -285,7 +291,12 @@ static bool i915_has_asle(struct drm_i915_private *i915)
*/
void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv)
{
- if (!i915_has_asle(dev_priv))
+ struct intel_display *display = &dev_priv->display;
+
+ if (!intel_opregion_asle_present(display))
+ return;
+
+ if (!i915_has_legacy_blc_interrupt(display))
return;
spin_lock_irq(&dev_priv->irq_lock);
@@ -298,14 +309,15 @@ void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv)
spin_unlock_irq(&dev_priv->irq_lock);
}
-#if defined(CONFIG_DEBUG_FS)
+#if IS_ENABLED(CONFIG_DEBUG_FS)
static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe,
u32 crc0, u32 crc1,
u32 crc2, u32 crc3,
u32 crc4)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_display *display = &dev_priv->display;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
u32 crcs[5] = { crc0, crc1, crc2, crc3, crc4 };
@@ -344,7 +356,8 @@ display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
static void flip_done_handler(struct drm_i915_private *i915,
enum pipe pipe)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(i915, pipe);
+ struct intel_display *display = &i915->display;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
spin_lock(&i915->drm.event_lock);
@@ -400,7 +413,7 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
res1, res2);
}
-void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv)
+static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv)
{
enum pipe pipe;
@@ -480,28 +493,10 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
spin_unlock(&dev_priv->irq_lock);
}
-void i8xx_pipestat_irq_handler(struct drm_i915_private *dev_priv,
- u16 iir, u32 pipe_stats[I915_MAX_PIPES])
-{
- enum pipe pipe;
-
- for_each_pipe(dev_priv, pipe) {
- if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
- intel_handle_vblank(dev_priv, pipe);
-
- if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
- i9xx_pipe_crc_irq_handler(dev_priv, pipe);
-
- if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
- intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
- }
-}
-
void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv,
u32 iir, u32 pipe_stats[I915_MAX_PIPES])
{
struct intel_display *display = &dev_priv->display;
-
bool blc_event = false;
enum pipe pipe;
@@ -1226,15 +1221,14 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl)
{
- void __iomem * const regs = intel_uncore_regs(&i915->uncore);
u32 iir;
if (!(master_ctl & GEN11_GU_MISC_IRQ))
return 0;
- iir = raw_reg_read(regs, GEN11_GU_MISC_IIR);
+ iir = intel_de_read(i915, GEN11_GU_MISC_IIR);
if (likely(iir))
- raw_reg_write(regs, GEN11_GU_MISC_IIR, iir);
+ intel_de_write(i915, GEN11_GU_MISC_IIR, iir);
return iir;
}
@@ -1249,25 +1243,56 @@ void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir)
void gen11_display_irq_handler(struct drm_i915_private *i915)
{
- void __iomem * const regs = intel_uncore_regs(&i915->uncore);
- const u32 disp_ctl = raw_reg_read(regs, GEN11_DISPLAY_INT_CTL);
+ u32 disp_ctl;
disable_rpm_wakeref_asserts(&i915->runtime_pm);
/*
* GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ
* for the display related bits.
*/
- raw_reg_write(regs, GEN11_DISPLAY_INT_CTL, 0x0);
+ disp_ctl = intel_de_read(i915, GEN11_DISPLAY_INT_CTL);
+
+ intel_de_write(i915, GEN11_DISPLAY_INT_CTL, 0);
gen8_de_irq_handler(i915, disp_ctl);
- raw_reg_write(regs, GEN11_DISPLAY_INT_CTL,
- GEN11_DISPLAY_IRQ_ENABLE);
+ intel_de_write(i915, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
enable_rpm_wakeref_asserts(&i915->runtime_pm);
}
-/* Called from drm generic code, passed 'crtc' which
- * we use as a pipe index
- */
+static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915)
+{
+ lockdep_assert_held(&i915->drm.vblank_time_lock);
+
+ /*
+ * Vblank/CRC interrupts fail to wake the device up from C2+.
+ * Disabling render clock gating during C-states avoids
+ * the problem. There is a small power cost so we do this
+ * only when vblank/CRC interrupts are actually enabled.
+ */
+ if (i915->display.irq.vblank_enabled++ == 0)
+ intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE));
+}
+
+static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915)
+{
+ lockdep_assert_held(&i915->drm.vblank_time_lock);
+
+ if (--i915->display.irq.vblank_enabled == 0)
+ intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE));
+}
+
+void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable)
+{
+ spin_lock_irq(&i915->drm.vblank_time_lock);
+
+ if (enable)
+ i915gm_irq_cstate_wa_enable(i915);
+ else
+ i915gm_irq_cstate_wa_disable(i915);
+
+ spin_unlock_irq(&i915->drm.vblank_time_lock);
+}
+
int i8xx_enable_vblank(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
@@ -1281,22 +1306,35 @@ int i8xx_enable_vblank(struct drm_crtc *crtc)
return 0;
}
+void i8xx_disable_vblank(struct drm_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS);
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
int i915gm_enable_vblank(struct drm_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(crtc->dev);
- /*
- * Vblank interrupts fail to wake the device up from C2+.
- * Disabling render clock gating during C-states avoids
- * the problem. There is a small power cost so we do this
- * only when vblank interrupts are actually enabled.
- */
- if (i915->display.irq.vblank_enabled++ == 0)
- intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE));
+ i915gm_irq_cstate_wa_enable(i915);
return i8xx_enable_vblank(crtc);
}
+void i915gm_disable_vblank(struct drm_crtc *crtc)
+{
+ struct drm_i915_private *i915 = to_i915(crtc->dev);
+
+ i8xx_disable_vblank(crtc);
+
+ i915gm_irq_cstate_wa_disable(i915);
+}
+
int i965_enable_vblank(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
@@ -1311,6 +1349,18 @@ int i965_enable_vblank(struct drm_crtc *crtc)
return 0;
}
+void i965_disable_vblank(struct drm_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ i915_disable_pipestat(dev_priv, pipe,
+ PIPE_START_VBLANK_INTERRUPT_STATUS);
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
int ilk_enable_vblank(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
@@ -1332,6 +1382,19 @@ int ilk_enable_vblank(struct drm_crtc *crtc)
return 0;
}
+void ilk_disable_vblank(struct drm_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ unsigned long irqflags;
+ u32 bit = DISPLAY_VER(dev_priv) >= 7 ?
+ DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe);
+
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ ilk_disable_display_irq(dev_priv, bit);
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
bool enable)
{
@@ -1356,9 +1419,27 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
return true;
}
+static void intel_display_vblank_dc_work(struct work_struct *work)
+{
+ struct intel_display *display =
+ container_of(work, typeof(*display), irq.vblank_dc_work);
+ struct drm_i915_private *i915 = to_i915(display->drm);
+ int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes);
+
+ /*
+ * NOTE: intel_display_power_set_target_dc_state is used only by PSR
+ * code for DC3CO handling. DC3CO target state is currently disabled in
+ * PSR code. If DC3CO is taken into use we need take that into account
+ * here as well.
+ */
+ intel_display_power_set_target_dc_state(i915, vblank_wa_num_pipes ? DC_STATE_DISABLE :
+ DC_STATE_EN_UPTO_DC6);
+}
+
int bdw_enable_vblank(struct drm_crtc *_crtc)
{
struct intel_crtc *crtc = to_intel_crtc(_crtc);
+ struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
unsigned long irqflags;
@@ -1366,6 +1447,9 @@ int bdw_enable_vblank(struct drm_crtc *_crtc)
if (gen11_dsi_configure_te(crtc, true))
return 0;
+ if (crtc->block_dc_for_vblank && display->irq.vblank_wa_num_pipes++ == 0)
+ schedule_work(&display->irq.vblank_dc_work);
+
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
@@ -1379,58 +1463,10 @@ int bdw_enable_vblank(struct drm_crtc *_crtc)
return 0;
}
-/* Called from drm generic code, passed 'crtc' which
- * we use as a pipe index
- */
-void i8xx_disable_vblank(struct drm_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = to_i915(crtc->dev);
- enum pipe pipe = to_intel_crtc(crtc)->pipe;
- unsigned long irqflags;
-
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS);
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-}
-
-void i915gm_disable_vblank(struct drm_crtc *crtc)
-{
- struct drm_i915_private *i915 = to_i915(crtc->dev);
-
- i8xx_disable_vblank(crtc);
-
- if (--i915->display.irq.vblank_enabled == 0)
- intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE));
-}
-
-void i965_disable_vblank(struct drm_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = to_i915(crtc->dev);
- enum pipe pipe = to_intel_crtc(crtc)->pipe;
- unsigned long irqflags;
-
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_disable_pipestat(dev_priv, pipe,
- PIPE_START_VBLANK_INTERRUPT_STATUS);
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-}
-
-void ilk_disable_vblank(struct drm_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = to_i915(crtc->dev);
- enum pipe pipe = to_intel_crtc(crtc)->pipe;
- unsigned long irqflags;
- u32 bit = DISPLAY_VER(dev_priv) >= 7 ?
- DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe);
-
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- ilk_disable_display_irq(dev_priv, bit);
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-}
-
void bdw_disable_vblank(struct drm_crtc *_crtc)
{
struct intel_crtc *crtc = to_intel_crtc(_crtc);
+ struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
unsigned long irqflags;
@@ -1441,6 +1477,9 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+ if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes == 0)
+ schedule_work(&display->irq.vblank_dc_work);
}
void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
@@ -1457,10 +1496,21 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
i9xx_pipestat_irq_reset(dev_priv);
- GEN3_IRQ_RESET(uncore, VLV_);
+ gen2_irq_reset(uncore, VLV_IRQ_REGS);
dev_priv->irq_mask = ~0u;
}
+void i9xx_display_irq_reset(struct drm_i915_private *i915)
+{
+ if (I915_HAS_HOTPLUG(i915)) {
+ i915_hotplug_interrupt_update(i915, 0xffffffff, 0);
+ intel_uncore_rmw(&i915->uncore,
+ PORT_HOTPLUG_STAT(i915), 0, 0);
+ }
+
+ i9xx_pipestat_irq_reset(i915);
+}
+
void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
@@ -1489,7 +1539,7 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
dev_priv->irq_mask = ~enable_mask;
- GEN3_IRQ_INIT(uncore, VLV_, dev_priv->irq_mask, enable_mask);
+ gen2_irq_init(uncore, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask);
}
void gen8_display_irq_reset(struct drm_i915_private *dev_priv)
@@ -1506,10 +1556,10 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv)
for_each_pipe(dev_priv, pipe)
if (intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe)))
- GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe);
+ gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
- GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_);
- GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_);
+ gen2_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS);
+ gen2_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS);
}
void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
@@ -1549,18 +1599,18 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
for_each_pipe(dev_priv, pipe)
if (intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe)))
- GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe);
+ gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
- GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_);
- GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_);
+ gen2_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS);
+ gen2_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS);
if (DISPLAY_VER(dev_priv) >= 14)
- GEN3_IRQ_RESET(uncore, PICAINTERRUPT_);
+ gen2_irq_reset(uncore, PICAINTERRUPT_IRQ_REGS);
else
- GEN3_IRQ_RESET(uncore, GEN11_DE_HPD_);
+ gen2_irq_reset(uncore, GEN11_DE_HPD_IRQ_REGS);
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
- GEN3_IRQ_RESET(uncore, SDE);
+ gen2_irq_reset(uncore, SDE_IRQ_REGS);
}
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
@@ -1580,9 +1630,9 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
}
for_each_pipe_masked(dev_priv, pipe, pipe_mask)
- GEN8_IRQ_INIT_NDX(uncore, DE_PIPE, pipe,
- dev_priv->display.irq.de_irq_mask[pipe],
- ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier);
+ gen2_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe),
+ dev_priv->display.irq.de_irq_mask[pipe],
+ ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier);
spin_unlock_irq(&dev_priv->irq_lock);
}
@@ -1601,7 +1651,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
}
for_each_pipe_masked(dev_priv, pipe, pipe_mask)
- GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe);
+ gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
spin_unlock_irq(&dev_priv->irq_lock);
@@ -1635,7 +1685,7 @@ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv)
else
mask = SDE_GMBUS_CPT;
- GEN3_IRQ_INIT(uncore, SDE, ~mask, 0xffffffff);
+ gen2_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff);
}
void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
@@ -1692,7 +1742,7 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915)
}
if (IS_HASWELL(i915)) {
- gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR);
+ gen2_assert_iir_is_zero(uncore, EDP_PSR_IIR);
display_mask |= DE_EDP_PSR_INT_HSW;
}
@@ -1703,7 +1753,7 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915)
ibx_irq_postinstall(i915);
- GEN3_IRQ_INIT(uncore, DE, i915->irq_mask,
+ gen2_irq_init(uncore, DE_IRQ_REGS, i915->irq_mask,
display_mask | extra_mask);
}
@@ -1777,11 +1827,11 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
if (!intel_display_power_is_enabled(dev_priv, domain))
continue;
- gen3_assert_iir_is_zero(uncore,
+ gen2_assert_iir_is_zero(uncore,
TRANS_PSR_IIR(dev_priv, trans));
}
} else {
- gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR);
+ gen2_assert_iir_is_zero(uncore, EDP_PSR_IIR);
}
for_each_pipe(dev_priv, pipe) {
@@ -1789,20 +1839,20 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
if (intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe)))
- GEN8_IRQ_INIT_NDX(uncore, DE_PIPE, pipe,
- dev_priv->display.irq.de_irq_mask[pipe],
- de_pipe_enables);
+ gen2_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe),
+ dev_priv->display.irq.de_irq_mask[pipe],
+ de_pipe_enables);
}
- GEN3_IRQ_INIT(uncore, GEN8_DE_PORT_, ~de_port_masked, de_port_enables);
- GEN3_IRQ_INIT(uncore, GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked);
+ gen2_irq_init(uncore, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, de_port_enables);
+ gen2_irq_init(uncore, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked);
if (IS_DISPLAY_VER(dev_priv, 11, 13)) {
u32 de_hpd_masked = 0;
u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK |
GEN11_DE_TBT_HOTPLUG_MASK;
- GEN3_IRQ_INIT(uncore, GEN11_DE_HPD_, ~de_hpd_masked,
+ gen2_irq_init(uncore, GEN11_DE_HPD_IRQ_REGS, ~de_hpd_masked,
de_hpd_enables);
}
}
@@ -1815,10 +1865,10 @@ static void mtp_irq_postinstall(struct drm_i915_private *i915)
u32 de_hpd_enables = de_hpd_mask | XELPDP_DP_ALT_HOTPLUG_MASK |
XELPDP_TBT_HOTPLUG_MASK;
- GEN3_IRQ_INIT(uncore, PICAINTERRUPT_, ~de_hpd_mask,
+ gen2_irq_init(uncore, PICAINTERRUPT_IRQ_REGS, ~de_hpd_mask,
de_hpd_enables);
- GEN3_IRQ_INIT(uncore, SDE, ~sde_mask, 0xffffffff);
+ gen2_irq_init(uncore, SDE_IRQ_REGS, ~sde_mask, 0xffffffff);
}
static void icp_irq_postinstall(struct drm_i915_private *dev_priv)
@@ -1826,7 +1876,7 @@ static void icp_irq_postinstall(struct drm_i915_private *dev_priv)
struct intel_uncore *uncore = &dev_priv->uncore;
u32 mask = SDE_GMBUS_ICP;
- GEN3_IRQ_INIT(uncore, SDE, ~mask, 0xffffffff);
+ gen2_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff);
}
void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv)
@@ -1866,4 +1916,7 @@ void intel_display_irq_init(struct drm_i915_private *i915)
i915->display.irq.display_irqs_enabled = false;
intel_hotplug_irq_init(i915);
+
+ INIT_WORK(&i915->display.irq.vblank_dc_work,
+ intel_display_vblank_dc_work);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h
index 2a090dd6abd7..4b493cff7b8e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.h
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
@@ -54,6 +54,7 @@ void gen11_display_irq_handler(struct drm_i915_private *i915);
u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl);
void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir);
+void i9xx_display_irq_reset(struct drm_i915_private *i915);
void vlv_display_irq_reset(struct drm_i915_private *i915);
void gen8_display_irq_reset(struct drm_i915_private *i915);
void gen11_display_irq_reset(struct drm_i915_private *i915);
@@ -68,15 +69,15 @@ u32 i915_pipestat_enable_mask(struct drm_i915_private *i915, enum pipe pipe);
void i915_enable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask);
void i915_disable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask);
void i915_enable_asle_pipestat(struct drm_i915_private *i915);
-void i9xx_pipestat_irq_reset(struct drm_i915_private *i915);
void i9xx_pipestat_irq_ack(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
void i915_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]);
-void i8xx_pipestat_irq_handler(struct drm_i915_private *i915, u16 iir, u32 pipe_stats[I915_MAX_PIPES]);
void intel_display_irq_init(struct drm_i915_private *i915);
+void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable);
+
#endif /* __INTEL_DISPLAY_IRQ_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.h b/drivers/gpu/drm/i915/display/intel_display_limits.h
index c4775c99dc83..f0fa27e365ab 100644
--- a/drivers/gpu/drm/i915/display/intel_display_limits.h
+++ b/drivers/gpu/drm/i915/display/intel_display_limits.h
@@ -50,6 +50,16 @@ enum transcoder {
};
/*
+ * Global legacy plane identifier. Valid only for primary/sprite
+ * planes on pre-g4x, and only for primary planes on g4x-bdw.
+ */
+enum i9xx_plane_id {
+ PLANE_A,
+ PLANE_B,
+ PLANE_C,
+};
+
+/*
* Per-pipe plane identifier.
* I915_MAX_PLANES in the enum below is the maximum (across all platforms)
* number of planes per CRTC. Not all platforms really have this many planes,
diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c
index 1a45d300b6f0..024de8abcb1a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_params.c
+++ b/drivers/gpu/drm/i915/display/intel_display_params.c
@@ -173,14 +173,16 @@ static void _param_print_charp(struct drm_printer *p, const char *driver_name,
/**
* intel_display_params_dump - dump intel display modparams
- * @display: display device
+ * @params: display params
+ * @driver_name: driver name to use for printing
* @p: the &drm_printer
*
* Pretty printer for i915 modparams.
*/
-void intel_display_params_dump(struct intel_display *display, struct drm_printer *p)
+void intel_display_params_dump(const struct intel_display_params *params,
+ const char *driver_name, struct drm_printer *p)
{
-#define PRINT(T, x, ...) _param_print(p, display->drm->driver->name, #x, display->params.x);
+#define PRINT(T, x, ...) _param_print(p, driver_name, #x, params->x);
INTEL_DISPLAY_PARAMS_FOR_EACH(PRINT);
#undef PRINT
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_params.h b/drivers/gpu/drm/i915/display/intel_display_params.h
index da8dc943234b..dcb6face936a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_params.h
+++ b/drivers/gpu/drm/i915/display/intel_display_params.h
@@ -9,7 +9,6 @@
#include <linux/types.h>
struct drm_printer;
-struct intel_display;
/*
* Invoke param, a function-like macro, for each intel display param, with
@@ -56,8 +55,8 @@ struct intel_display_params {
};
#undef MEMBER
-void intel_display_params_dump(struct intel_display *display,
- struct drm_printer *p);
+void intel_display_params_dump(const struct intel_display_params *params,
+ const char *driver_name, struct drm_printer *p);
void intel_display_params_copy(struct intel_display_params *dest);
void intel_display_params_free(struct intel_display_params *params);
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index ef2fdbf97346..c2bc80f5bf6b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -545,7 +545,7 @@ intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
wakeref = intel_runtime_pm_get_if_in_use(&dev_priv->runtime_pm);
if (!wakeref)
- return false;
+ return NULL;
mutex_lock(&power_domains->lock);
@@ -560,7 +560,7 @@ intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
if (!is_enabled) {
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
- wakeref = 0;
+ wakeref = NULL;
}
return wakeref;
@@ -648,7 +648,7 @@ intel_display_power_put_async_work(struct work_struct *work)
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm);
- intel_wakeref_t old_work_wakeref = 0;
+ intel_wakeref_t old_work_wakeref = NULL;
mutex_lock(&power_domains->lock);
@@ -895,7 +895,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
!bitmap_subset(mask->bits, power_domain_set->mask.bits, POWER_DOMAIN_NUM));
for_each_power_domain(domain, mask) {
- intel_wakeref_t __maybe_unused wf = -1;
+ intel_wakeref_t __maybe_unused wf = INTEL_WAKEREF_DEF;
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
wf = fetch_and_zero(&power_domain_set->wakerefs[domain]);
@@ -1300,6 +1300,7 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
*/
static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
{
+ struct intel_display *display = &dev_priv->display;
u32 val;
val = intel_de_read(dev_priv, LCPLL_CTL);
@@ -1343,8 +1344,8 @@ 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_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");
+ intel_update_cdclk(display);
+ intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK");
}
/*
@@ -1416,10 +1417,11 @@ static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv,
static void skl_display_core_init(struct drm_i915_private *dev_priv,
bool resume)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
/* enable PCH reset handshake */
intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
@@ -1438,28 +1440,29 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
mutex_unlock(&power_domains->lock);
- intel_cdclk_init_hw(dev_priv);
+ intel_cdclk_init_hw(display);
gen9_dbuf_enable(dev_priv);
if (resume)
- intel_dmc_load_program(dev_priv);
+ intel_dmc_load_program(display);
}
static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
- gen9_disable_dc_states(dev_priv);
+ gen9_disable_dc_states(display);
/* TODO: disable DMC program */
gen9_dbuf_disable(dev_priv);
- intel_cdclk_uninit_hw(dev_priv);
+ intel_cdclk_uninit_hw(display);
/* The spec doesn't call for removing the reset handshake flag */
/* disable PG1 and Misc I/O */
@@ -1482,10 +1485,11 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
/*
* NDE_RSTWRN_OPT RST PCH Handshake En must always be 0b on BXT
@@ -1506,28 +1510,29 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume
mutex_unlock(&power_domains->lock);
- intel_cdclk_init_hw(dev_priv);
+ intel_cdclk_init_hw(display);
gen9_dbuf_enable(dev_priv);
if (resume)
- intel_dmc_load_program(dev_priv);
+ intel_dmc_load_program(display);
}
static void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
- gen9_disable_dc_states(dev_priv);
+ gen9_disable_dc_states(display);
/* TODO: disable DMC program */
gen9_dbuf_disable(dev_priv);
- intel_cdclk_uninit_hw(dev_priv);
+ intel_cdclk_uninit_hw(display);
/* The spec doesn't call for removing the reset handshake flag */
@@ -1623,10 +1628,11 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
static void icl_display_core_init(struct drm_i915_private *dev_priv,
bool resume)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
/* Wa_14011294188:ehl,jsl,tgl,rkl,adl-s */
if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP &&
@@ -1657,7 +1663,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
HOLD_PHY_PG1_LATCH | HOLD_PHY_CLKREQ_PG1_LATCH, 0);
/* 4. Enable CDCLK. */
- intel_cdclk_init_hw(dev_priv);
+ intel_cdclk_init_hw(display);
if (DISPLAY_VER(dev_priv) >= 12)
gen12_dbuf_slices_config(dev_priv);
@@ -1681,7 +1687,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
intel_de_rmw(dev_priv, CHICKEN_MISC_2, BMG_DARB_HALF_BLK_END_BURST, 1);
if (resume)
- intel_dmc_load_program(dev_priv);
+ intel_dmc_load_program(display);
/* Wa_14011508470:tgl,dg1,rkl,adl-s,adl-p,dg2 */
if (IS_DISPLAY_VER_FULL(dev_priv, IP_VER(12, 0), IP_VER(13, 0)))
@@ -1704,14 +1710,15 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
- gen9_disable_dc_states(dev_priv);
- intel_dmc_disable_program(dev_priv);
+ gen9_disable_dc_states(display);
+ intel_dmc_disable_program(display);
/* 1. Disable all display engine functions -> aready done */
@@ -1719,7 +1726,7 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
gen9_dbuf_disable(dev_priv);
/* 3. Disable CD clock */
- intel_cdclk_uninit_hw(dev_priv);
+ intel_cdclk_uninit_hw(display);
if (DISPLAY_VER(dev_priv) == 14)
intel_de_rmw(dev_priv, DC_STATE_EN, 0,
@@ -2066,7 +2073,8 @@ void intel_power_domains_disable(struct drm_i915_private *i915)
*/
void intel_power_domains_suspend(struct drm_i915_private *i915, bool s2idle)
{
- struct i915_power_domains *power_domains = &i915->display.power.domains;
+ struct intel_display *display = &i915->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
intel_wakeref_t wakeref __maybe_unused =
fetch_and_zero(&power_domains->init_wakeref);
@@ -2080,7 +2088,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915, bool s2idle)
* that would be blocked if the firmware was inactive.
*/
if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC9) && s2idle &&
- intel_dmc_has_payload(i915)) {
+ intel_dmc_has_payload(display)) {
intel_display_power_flush_work(i915);
intel_power_domains_verify_state(i915);
return;
@@ -2225,9 +2233,11 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915)
void intel_display_power_suspend_late(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
+
if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) ||
IS_BROXTON(i915)) {
- bxt_enable_dc9(i915);
+ bxt_enable_dc9(display);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_enable_pc8(i915);
}
@@ -2239,10 +2249,12 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915)
void intel_display_power_resume_early(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
+
if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) ||
IS_BROXTON(i915)) {
- gen9_sanitize_dc_state(i915);
- bxt_disable_dc9(i915);
+ gen9_sanitize_dc_state(display);
+ bxt_disable_dc9(display);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_disable_pc8(i915);
}
@@ -2254,12 +2266,14 @@ void intel_display_power_resume_early(struct drm_i915_private *i915)
void intel_display_power_suspend(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
+
if (DISPLAY_VER(i915) >= 11) {
icl_display_core_uninit(i915);
- bxt_enable_dc9(i915);
+ bxt_enable_dc9(display);
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
bxt_display_core_uninit(i915);
- bxt_enable_dc9(i915);
+ bxt_enable_dc9(display);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_enable_pc8(i915);
}
@@ -2267,23 +2281,24 @@ void intel_display_power_suspend(struct drm_i915_private *i915)
void intel_display_power_resume(struct drm_i915_private *i915)
{
- struct i915_power_domains *power_domains = &i915->display.power.domains;
+ struct intel_display *display = &i915->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
if (DISPLAY_VER(i915) >= 11) {
- bxt_disable_dc9(i915);
+ bxt_disable_dc9(display);
icl_display_core_init(i915, true);
- if (intel_dmc_has_payload(i915)) {
+ if (intel_dmc_has_payload(display)) {
if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
- skl_enable_dc6(i915);
+ skl_enable_dc6(display);
else if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
- gen9_enable_dc5(i915);
+ gen9_enable_dc5(display);
}
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
- bxt_disable_dc9(i915);
+ bxt_disable_dc9(display);
bxt_display_core_init(i915, true);
- if (intel_dmc_has_payload(i915) &&
+ if (intel_dmc_has_payload(display) &&
(power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5))
- gen9_enable_dc5(i915);
+ gen9_enable_dc5(display);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_disable_pc8(i915);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 425452c5a469..3f8f84df4733 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -232,7 +232,7 @@ intel_display_power_put_async(struct drm_i915_private *i915,
enum intel_display_power_domain domain,
intel_wakeref_t wakeref)
{
- __intel_display_power_put_async(i915, domain, -1, -1);
+ __intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, -1);
}
static inline void
@@ -241,7 +241,7 @@ intel_display_power_put_async_delay(struct drm_i915_private *i915,
intel_wakeref_t wakeref,
int delay_ms)
{
- __intel_display_power_put_async(i915, domain, -1, delay_ms);
+ __intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, delay_ms);
}
#endif
@@ -297,10 +297,10 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
#define with_intel_display_power(i915, domain, wf) \
for ((wf) = intel_display_power_get((i915), (domain)); (wf); \
- intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0)
+ intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL)
#define with_intel_display_power_if_enabled(i915, domain, wf) \
for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \
- intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0)
+ intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL)
#endif /* __INTEL_DISPLAY_POWER_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c
index 10948b3964ee..5575aa0d6689 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_map.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c
@@ -1586,6 +1586,136 @@ static const struct i915_power_well_desc_list xe2lpd_power_wells[] = {
I915_PW_DESCRIPTORS(xe2lpd_power_wells_pica),
};
+/*
+ * Xe3 changes the power well hierarchy slightly from Xe_LPD+; PGB now
+ * depends on PG1 instead of PG2:
+ *
+ * PG0
+ * |
+ * --PG1--
+ * / | \
+ * PGA PGB PG2
+ * / \
+ * PGC PGD
+ */
+
+#define XE3LPD_PW_C_POWER_DOMAINS \
+ POWER_DOMAIN_PIPE_C, \
+ POWER_DOMAIN_PIPE_PANEL_FITTER_C
+
+#define XE3LPD_PW_D_POWER_DOMAINS \
+ POWER_DOMAIN_PIPE_D, \
+ POWER_DOMAIN_PIPE_PANEL_FITTER_D
+
+#define XE3LPD_PW_2_POWER_DOMAINS \
+ XE3LPD_PW_C_POWER_DOMAINS, \
+ XE3LPD_PW_D_POWER_DOMAINS, \
+ POWER_DOMAIN_TRANSCODER_C, \
+ POWER_DOMAIN_TRANSCODER_D, \
+ POWER_DOMAIN_VGA, \
+ POWER_DOMAIN_PORT_DDI_LANES_TC1, \
+ POWER_DOMAIN_PORT_DDI_LANES_TC2, \
+ POWER_DOMAIN_PORT_DDI_LANES_TC3, \
+ POWER_DOMAIN_PORT_DDI_LANES_TC4
+
+I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_2,
+ XE3LPD_PW_2_POWER_DOMAINS,
+ POWER_DOMAIN_INIT);
+
+I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_b,
+ POWER_DOMAIN_PIPE_B,
+ POWER_DOMAIN_PIPE_PANEL_FITTER_B,
+ POWER_DOMAIN_INIT);
+
+I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_c,
+ XE3LPD_PW_C_POWER_DOMAINS,
+ POWER_DOMAIN_INIT);
+
+I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_d,
+ XE3LPD_PW_D_POWER_DOMAINS,
+ POWER_DOMAIN_INIT);
+
+static const struct i915_power_well_desc xe3lpd_power_wells_main[] = {
+ {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("PW_2", &xe3lpd_pwdoms_pw_2,
+ .hsw.idx = ICL_PW_CTL_IDX_PW_2,
+ .id = SKL_DISP_PW_2),
+ ),
+ .ops = &hsw_power_well_ops,
+ .has_vga = true,
+ .has_fuses = true,
+ }, {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("PW_A", &xelpd_pwdoms_pw_a,
+ .hsw.idx = XELPD_PW_CTL_IDX_PW_A),
+ ),
+ .ops = &hsw_power_well_ops,
+ .irq_pipe_mask = BIT(PIPE_A),
+ .has_fuses = true,
+ }, {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("PW_B", &xe3lpd_pwdoms_pw_b,
+ .hsw.idx = XELPD_PW_CTL_IDX_PW_B),
+ ),
+ .ops = &hsw_power_well_ops,
+ .irq_pipe_mask = BIT(PIPE_B),
+ .has_fuses = true,
+ }, {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("PW_C", &xe3lpd_pwdoms_pw_c,
+ .hsw.idx = XELPD_PW_CTL_IDX_PW_C),
+ ),
+ .ops = &hsw_power_well_ops,
+ .irq_pipe_mask = BIT(PIPE_C),
+ .has_fuses = true,
+ }, {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("PW_D", &xe3lpd_pwdoms_pw_d,
+ .hsw.idx = XELPD_PW_CTL_IDX_PW_D),
+ ),
+ .ops = &hsw_power_well_ops,
+ .irq_pipe_mask = BIT(PIPE_D),
+ .has_fuses = true,
+ }, {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("AUX_A", &icl_pwdoms_aux_a, .xelpdp.aux_ch = AUX_CH_A),
+ I915_PW("AUX_B", &icl_pwdoms_aux_b, .xelpdp.aux_ch = AUX_CH_B),
+ I915_PW("AUX_TC1", &xelpdp_pwdoms_aux_tc1, .xelpdp.aux_ch = AUX_CH_USBC1),
+ I915_PW("AUX_TC2", &xelpdp_pwdoms_aux_tc2, .xelpdp.aux_ch = AUX_CH_USBC2),
+ I915_PW("AUX_TC3", &xelpdp_pwdoms_aux_tc3, .xelpdp.aux_ch = AUX_CH_USBC3),
+ I915_PW("AUX_TC4", &xelpdp_pwdoms_aux_tc4, .xelpdp.aux_ch = AUX_CH_USBC4),
+ ),
+ .ops = &xelpdp_aux_power_well_ops,
+ },
+};
+
+I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_dc_off,
+ POWER_DOMAIN_DC_OFF,
+ XE3LPD_PW_2_POWER_DOMAINS,
+ XE3LPD_PW_C_POWER_DOMAINS,
+ XE3LPD_PW_D_POWER_DOMAINS,
+ POWER_DOMAIN_AUDIO_MMIO,
+ POWER_DOMAIN_INIT);
+
+static const struct i915_power_well_desc xe3lpd_power_wells_dcoff[] = {
+ {
+ .instances = &I915_PW_INSTANCES(
+ I915_PW("DC_off", &xe3lpd_pwdoms_dc_off,
+ .id = SKL_DISP_DC_OFF),
+ ),
+ .ops = &gen9_dc_off_power_well_ops,
+ },
+};
+
+static const struct i915_power_well_desc_list xe3lpd_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(xe3lpd_power_wells_dcoff),
+ I915_PW_DESCRIPTORS(xe3lpd_power_wells_main),
+ I915_PW_DESCRIPTORS(xe2lpd_power_wells_pica),
+};
+
static void init_power_well_domains(const struct i915_power_well_instance *inst,
struct i915_power_well *power_well)
{
@@ -1693,7 +1823,9 @@ int intel_display_power_map_init(struct i915_power_domains *power_domains)
return 0;
}
- if (DISPLAY_VER(i915) >= 20)
+ if (DISPLAY_VER(i915) >= 30)
+ return set_power_wells(power_domains, xe3lpd_power_wells);
+ else if (DISPLAY_VER(i915) >= 20)
return set_power_wells(power_domains, xe2lpd_power_wells);
else if (DISPLAY_VER(i915) >= 14)
return set_power_wells(power_domains, xelpdp_power_wells);
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
index 46e9eff12c23..adaf7cf3a33b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -187,8 +187,10 @@ int intel_power_well_refcount(struct i915_power_well *power_well)
static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv,
u8 irq_pipe_mask, bool has_vga)
{
+ struct intel_display *display = &dev_priv->display;
+
if (has_vga)
- intel_vga_reset_io_mem(dev_priv);
+ intel_vga_reset_io_mem(display);
if (irq_pipe_mask)
gen8_irq_power_well_post_enable(dev_priv, irq_pipe_mask);
@@ -601,20 +603,22 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
return (val & mask) == mask;
}
-static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
+static void assert_can_enable_dc9(struct intel_display *display)
{
- drm_WARN_ONCE(&dev_priv->drm,
- (intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_DC9),
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
+ drm_WARN_ONCE(display->drm,
+ (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_DC9),
"DC9 already programmed to be enabled.\n");
- drm_WARN_ONCE(&dev_priv->drm,
- intel_de_read(dev_priv, DC_STATE_EN) &
+ drm_WARN_ONCE(display->drm,
+ intel_de_read(display, DC_STATE_EN) &
DC_STATE_EN_UPTO_DC5,
"DC5 still not disabled to enable DC9.\n");
- drm_WARN_ONCE(&dev_priv->drm,
- intel_de_read(dev_priv, HSW_PWR_WELL_CTL2) &
+ drm_WARN_ONCE(display->drm,
+ intel_de_read(display, HSW_PWR_WELL_CTL2) &
HSW_PWR_WELL_CTL_REQ(SKL_PW_CTL_IDX_PW_2),
"Power well 2 on.\n");
- drm_WARN_ONCE(&dev_priv->drm, intel_irqs_enabled(dev_priv),
+ drm_WARN_ONCE(display->drm, intel_irqs_enabled(dev_priv),
"Interrupts not disabled yet.\n");
/*
@@ -626,12 +630,14 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
*/
}
-static void assert_can_disable_dc9(struct drm_i915_private *dev_priv)
+static void assert_can_disable_dc9(struct intel_display *display)
{
- drm_WARN_ONCE(&dev_priv->drm, intel_irqs_enabled(dev_priv),
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
+ drm_WARN_ONCE(display->drm, intel_irqs_enabled(dev_priv),
"Interrupts not disabled yet.\n");
- drm_WARN_ONCE(&dev_priv->drm,
- intel_de_read(dev_priv, DC_STATE_EN) &
+ drm_WARN_ONCE(display->drm,
+ intel_de_read(display, DC_STATE_EN) &
DC_STATE_EN_UPTO_DC5,
"DC5 still not disabled.\n");
@@ -644,14 +650,14 @@ static void assert_can_disable_dc9(struct drm_i915_private *dev_priv)
*/
}
-static void gen9_write_dc_state(struct drm_i915_private *dev_priv,
+static void gen9_write_dc_state(struct intel_display *display,
u32 state)
{
int rewrites = 0;
int rereads = 0;
u32 v;
- intel_de_write(dev_priv, DC_STATE_EN, state);
+ intel_de_write(display, DC_STATE_EN, state);
/* It has been observed that disabling the dc6 state sometimes
* doesn't stick and dmc keeps returning old value. Make sure
@@ -659,10 +665,10 @@ static void gen9_write_dc_state(struct drm_i915_private *dev_priv,
* we are confident that state is exactly what we want.
*/
do {
- v = intel_de_read(dev_priv, DC_STATE_EN);
+ v = intel_de_read(display, DC_STATE_EN);
if (v != state) {
- intel_de_write(dev_priv, DC_STATE_EN, state);
+ intel_de_write(display, DC_STATE_EN, state);
rewrites++;
rereads = 0;
} else if (rereads++ > 5) {
@@ -672,27 +678,28 @@ static void gen9_write_dc_state(struct drm_i915_private *dev_priv,
} while (rewrites < 100);
if (v != state)
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"Writing dc state to 0x%x failed, now 0x%x\n",
state, v);
/* Most of the times we need one retry, avoid spam */
if (rewrites > 1)
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"Rewrote dc state to 0x%x %d times\n",
state, rewrites);
}
-static u32 gen9_dc_mask(struct drm_i915_private *dev_priv)
+static u32 gen9_dc_mask(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 mask;
mask = DC_STATE_EN_UPTO_DC5;
- if (DISPLAY_VER(dev_priv) >= 12)
+ if (DISPLAY_VER(display) >= 12)
mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6
| DC_STATE_EN_DC9;
- else if (DISPLAY_VER(dev_priv) == 11)
+ else if (DISPLAY_VER(display) == 11)
mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
mask |= DC_STATE_EN_DC9;
@@ -702,17 +709,17 @@ static u32 gen9_dc_mask(struct drm_i915_private *dev_priv)
return mask;
}
-void gen9_sanitize_dc_state(struct drm_i915_private *i915)
+void gen9_sanitize_dc_state(struct intel_display *display)
{
- struct i915_power_domains *power_domains = &i915->display.power.domains;
+ struct i915_power_domains *power_domains = &display->power.domains;
u32 val;
- if (!HAS_DISPLAY(i915))
+ if (!HAS_DISPLAY(display))
return;
- val = intel_de_read(i915, DC_STATE_EN) & gen9_dc_mask(i915);
+ val = intel_de_read(display, DC_STATE_EN) & gen9_dc_mask(display);
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Resetting DC state tracking from %02x to %02x\n",
power_domains->dc_state, val);
power_domains->dc_state = val;
@@ -720,7 +727,7 @@ void gen9_sanitize_dc_state(struct drm_i915_private *i915)
/**
* gen9_set_dc_state - set target display C power state
- * @dev_priv: i915 device instance
+ * @display: display instance
* @state: target DC power state
* - DC_STATE_DISABLE
* - DC_STATE_EN_UPTO_DC5
@@ -741,150 +748,152 @@ void gen9_sanitize_dc_state(struct drm_i915_private *i915)
* back on and register state is restored. This is guaranteed by the MMIO write
* to DC_STATE_EN blocking until the state is restored.
*/
-void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
+void gen9_set_dc_state(struct intel_display *display, u32 state)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct i915_power_domains *power_domains = &display->power.domains;
u32 val;
u32 mask;
- if (!HAS_DISPLAY(dev_priv))
+ if (!HAS_DISPLAY(display))
return;
- if (drm_WARN_ON_ONCE(&dev_priv->drm,
+ if (drm_WARN_ON_ONCE(display->drm,
state & ~power_domains->allowed_dc_mask))
state &= power_domains->allowed_dc_mask;
- val = intel_de_read(dev_priv, DC_STATE_EN);
- mask = gen9_dc_mask(dev_priv);
- drm_dbg_kms(&dev_priv->drm, "Setting DC state from %02x to %02x\n",
+ val = intel_de_read(display, DC_STATE_EN);
+ mask = gen9_dc_mask(display);
+ drm_dbg_kms(display->drm, "Setting DC state from %02x to %02x\n",
val & mask, state);
/* Check if DMC is ignoring our DC state requests */
if ((val & mask) != power_domains->dc_state)
- drm_err(&dev_priv->drm, "DC state mismatch (0x%x -> 0x%x)\n",
+ drm_err(display->drm, "DC state mismatch (0x%x -> 0x%x)\n",
power_domains->dc_state, val & mask);
val &= ~mask;
val |= state;
- gen9_write_dc_state(dev_priv, val);
+ gen9_write_dc_state(display, val);
power_domains->dc_state = val & mask;
}
-static void tgl_enable_dc3co(struct drm_i915_private *dev_priv)
+static void tgl_enable_dc3co(struct intel_display *display)
{
- drm_dbg_kms(&dev_priv->drm, "Enabling DC3CO\n");
- gen9_set_dc_state(dev_priv, DC_STATE_EN_DC3CO);
+ drm_dbg_kms(display->drm, "Enabling DC3CO\n");
+ gen9_set_dc_state(display, DC_STATE_EN_DC3CO);
}
-static void tgl_disable_dc3co(struct drm_i915_private *dev_priv)
+static void tgl_disable_dc3co(struct intel_display *display)
{
- drm_dbg_kms(&dev_priv->drm, "Disabling DC3CO\n");
- intel_de_rmw(dev_priv, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0);
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ drm_dbg_kms(display->drm, "Disabling DC3CO\n");
+ intel_de_rmw(display, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0);
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
/*
* Delay of 200us DC3CO Exit time B.Spec 49196
*/
usleep_range(200, 210);
}
-static void assert_can_enable_dc5(struct drm_i915_private *dev_priv)
+static void assert_can_enable_dc5(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
enum i915_power_well_id high_pg;
/* Power wells at this level and above must be disabled for DC5 entry */
- if (DISPLAY_VER(dev_priv) == 12)
+ if (DISPLAY_VER(display) == 12)
high_pg = ICL_DISP_PW_3;
else
high_pg = SKL_DISP_PW_2;
- drm_WARN_ONCE(&dev_priv->drm,
+ drm_WARN_ONCE(display->drm,
intel_display_power_well_is_enabled(dev_priv, high_pg),
"Power wells above platform's DC5 limit still enabled.\n");
- drm_WARN_ONCE(&dev_priv->drm,
- (intel_de_read(dev_priv, DC_STATE_EN) &
+ drm_WARN_ONCE(display->drm,
+ (intel_de_read(display, DC_STATE_EN) &
DC_STATE_EN_UPTO_DC5),
"DC5 already programmed to be enabled.\n");
assert_rpm_wakelock_held(&dev_priv->runtime_pm);
- assert_dmc_loaded(dev_priv);
+ assert_dmc_loaded(display);
}
-void gen9_enable_dc5(struct drm_i915_private *dev_priv)
+void gen9_enable_dc5(struct intel_display *display)
{
- assert_can_enable_dc5(dev_priv);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+
+ assert_can_enable_dc5(display);
- drm_dbg_kms(&dev_priv->drm, "Enabling DC5\n");
+ drm_dbg_kms(display->drm, "Enabling DC5\n");
/* Wa Display #1183: skl,kbl,cfl */
- if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
- intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1,
+ if (DISPLAY_VER(display) == 9 && !IS_BROXTON(dev_priv))
+ intel_de_rmw(display, GEN8_CHICKEN_DCPR_1,
0, SKL_SELECT_ALTERNATE_DC_EXIT);
- intel_dmc_wl_enable(&dev_priv->display);
+ intel_dmc_wl_enable(display);
- gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5);
+ gen9_set_dc_state(display, DC_STATE_EN_UPTO_DC5);
}
-static void assert_can_enable_dc6(struct drm_i915_private *dev_priv)
+static void assert_can_enable_dc6(struct intel_display *display)
{
- drm_WARN_ONCE(&dev_priv->drm,
- (intel_de_read(dev_priv, UTIL_PIN_CTL) &
+ drm_WARN_ONCE(display->drm,
+ (intel_de_read(display, UTIL_PIN_CTL) &
(UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) ==
(UTIL_PIN_ENABLE | UTIL_PIN_MODE_PWM),
"Utility pin enabled in PWM mode\n");
- drm_WARN_ONCE(&dev_priv->drm,
- (intel_de_read(dev_priv, DC_STATE_EN) &
+ drm_WARN_ONCE(display->drm,
+ (intel_de_read(display, DC_STATE_EN) &
DC_STATE_EN_UPTO_DC6),
"DC6 already programmed to be enabled.\n");
- assert_dmc_loaded(dev_priv);
+ assert_dmc_loaded(display);
}
-void skl_enable_dc6(struct drm_i915_private *dev_priv)
+void skl_enable_dc6(struct intel_display *display)
{
- assert_can_enable_dc6(dev_priv);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
- drm_dbg_kms(&dev_priv->drm, "Enabling DC6\n");
+ assert_can_enable_dc6(display);
+
+ drm_dbg_kms(display->drm, "Enabling DC6\n");
/* Wa Display #1183: skl,kbl,cfl */
- if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
- intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1,
+ if (DISPLAY_VER(display) == 9 && !IS_BROXTON(dev_priv))
+ intel_de_rmw(display, GEN8_CHICKEN_DCPR_1,
0, SKL_SELECT_ALTERNATE_DC_EXIT);
- intel_dmc_wl_enable(&dev_priv->display);
+ intel_dmc_wl_enable(display);
- gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
+ gen9_set_dc_state(display, DC_STATE_EN_UPTO_DC6);
}
-void bxt_enable_dc9(struct drm_i915_private *dev_priv)
+void bxt_enable_dc9(struct intel_display *display)
{
- struct intel_display *display = &dev_priv->display;
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
- assert_can_enable_dc9(dev_priv);
+ assert_can_enable_dc9(display);
- drm_dbg_kms(&dev_priv->drm, "Enabling DC9\n");
+ drm_dbg_kms(display->drm, "Enabling DC9\n");
/*
- * Power sequencer reset is not needed on
- * platforms with South Display Engine on PCH,
- * because PPS registers are always on.
+ * Power sequencer reset is needed on BXT/GLK, because the PPS registers
+ * aren't always on, unlike with South Display Engine on PCH.
*/
- if (!HAS_PCH_SPLIT(dev_priv))
- intel_pps_reset_all(display);
- gen9_set_dc_state(dev_priv, DC_STATE_EN_DC9);
+ if (IS_BROXTON(dev_priv) || IS_GEMINILAKE(dev_priv))
+ bxt_pps_reset_all(display);
+ gen9_set_dc_state(display, DC_STATE_EN_DC9);
}
-void bxt_disable_dc9(struct drm_i915_private *dev_priv)
+void bxt_disable_dc9(struct intel_display *display)
{
- struct intel_display *display = &dev_priv->display;
+ assert_can_disable_dc9(display);
- assert_can_disable_dc9(dev_priv);
+ drm_dbg_kms(display->drm, "Disabling DC9\n");
- drm_dbg_kms(&dev_priv->drm, "Disabling DC9\n");
-
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
intel_pps_unlock_regs_wa(display);
}
@@ -949,8 +958,10 @@ static void bxt_verify_dpio_phy_power_wells(struct drm_i915_private *dev_priv)
static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- return ((intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_DC3CO) == 0 &&
- (intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0);
+ struct intel_display *display = &dev_priv->display;
+
+ return ((intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_DC3CO) == 0 &&
+ (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0);
}
static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
@@ -965,27 +976,28 @@ static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
enabled_dbuf_slices);
}
-void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
+void gen9_disable_dc_states(struct intel_display *display)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+ struct i915_power_domains *power_domains = &display->power.domains;
struct intel_cdclk_config cdclk_config = {};
if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) {
- tgl_disable_dc3co(dev_priv);
+ tgl_disable_dc3co(display);
return;
}
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ gen9_set_dc_state(display, DC_STATE_DISABLE);
- if (!HAS_DISPLAY(dev_priv))
+ if (!HAS_DISPLAY(display))
return;
- intel_dmc_wl_disable(&dev_priv->display);
+ intel_dmc_wl_disable(display);
- intel_cdclk_get_cdclk(dev_priv, &cdclk_config);
+ intel_cdclk_get_cdclk(display, &cdclk_config);
/* Can't read out voltage_level so can't use intel_cdclk_changed() */
- drm_WARN_ON(&dev_priv->drm,
- intel_cdclk_clock_changed(&dev_priv->display.cdclk.hw,
+ drm_WARN_ON(display->drm,
+ intel_cdclk_clock_changed(&display->cdclk.hw,
&cdclk_config));
gen9_assert_dbuf_enabled(dev_priv);
@@ -993,7 +1005,7 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_verify_dpio_phy_power_wells(dev_priv);
- if (DISPLAY_VER(dev_priv) >= 11)
+ if (DISPLAY_VER(display) >= 11)
/*
* DMC retains HW context only for port A, the other combo
* PHY's HW context for port B is lost after DC transitions,
@@ -1005,26 +1017,29 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- gen9_disable_dc_states(dev_priv);
+ struct intel_display *display = &dev_priv->display;
+
+ gen9_disable_dc_states(display);
}
static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
+ struct intel_display *display = &dev_priv->display;
+ struct i915_power_domains *power_domains = &display->power.domains;
- if (!intel_dmc_has_payload(dev_priv))
+ if (!intel_dmc_has_payload(display))
return;
switch (power_domains->target_dc_state) {
case DC_STATE_EN_DC3CO:
- tgl_enable_dc3co(dev_priv);
+ tgl_enable_dc3co(display);
break;
case DC_STATE_EN_UPTO_DC6:
- skl_enable_dc6(dev_priv);
+ skl_enable_dc6(display);
break;
case DC_STATE_EN_UPTO_DC5:
- gen9_enable_dc5(dev_priv);
+ gen9_enable_dc5(display);
break;
}
}
@@ -1048,24 +1063,30 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
static void i830_pipes_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE) == 0)
- i830_enable_pipe(dev_priv, PIPE_A);
- if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE) == 0)
- i830_enable_pipe(dev_priv, PIPE_B);
+ struct intel_display *display = &dev_priv->display;
+
+ if ((intel_de_read(display, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE) == 0)
+ i830_enable_pipe(display, PIPE_A);
+ if ((intel_de_read(display, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE) == 0)
+ i830_enable_pipe(display, PIPE_B);
}
static void i830_pipes_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- i830_disable_pipe(dev_priv, PIPE_B);
- i830_disable_pipe(dev_priv, PIPE_A);
+ struct intel_display *display = &dev_priv->display;
+
+ i830_disable_pipe(display, PIPE_B);
+ i830_disable_pipe(display, PIPE_A);
}
static bool i830_pipes_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- return intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE &&
- intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE;
+ struct intel_display *display = &dev_priv->display;
+
+ return intel_de_read(display, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE &&
+ intel_de_read(display, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE;
}
static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv,
@@ -1232,7 +1253,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
intel_crt_reset(&encoder->base);
}
- intel_vga_redisable_power_on(dev_priv);
+ intel_vga_redisable_power_on(display);
intel_pps_unlock_regs_wa(display);
}
@@ -1248,7 +1269,7 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv)
/* make sure we're done processing display irqs */
intel_synchronize_irq(dev_priv);
- intel_pps_reset_all(display);
+ vlv_pps_reset_all(display);
/* Prevent us from re-enabling polling on accident in late suspend */
if (!dev_priv->drm.dev->power.is_suspended)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.h b/drivers/gpu/drm/i915/display/intel_display_power_well.h
index 9357a9a73c06..93559f7c6100 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.h
@@ -12,6 +12,7 @@
struct drm_i915_private;
struct i915_power_well_ops;
+struct intel_display;
struct intel_encoder;
#define for_each_power_well(__dev_priv, __power_well) \
@@ -154,13 +155,13 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder,
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
enum dpio_channel ch, bool override);
-void gen9_enable_dc5(struct drm_i915_private *dev_priv);
-void skl_enable_dc6(struct drm_i915_private *dev_priv);
-void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv);
-void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state);
-void gen9_disable_dc_states(struct drm_i915_private *dev_priv);
-void bxt_enable_dc9(struct drm_i915_private *dev_priv);
-void bxt_disable_dc9(struct drm_i915_private *dev_priv);
+void gen9_enable_dc5(struct intel_display *display);
+void skl_enable_dc6(struct intel_display *display);
+void gen9_sanitize_dc_state(struct intel_display *display);
+void gen9_set_dc_state(struct intel_display *display, u32 state);
+void gen9_disable_dc_states(struct intel_display *display);
+void bxt_enable_dc9(struct intel_display *display);
+void bxt_disable_dc9(struct intel_display *display);
extern const struct i915_power_well_ops i9xx_always_on_power_well_ops;
extern const struct i915_power_well_ops chv_pipe_power_well_ops;
diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.c b/drivers/gpu/drm/i915/display/intel_display_snapshot.c
new file mode 100644
index 000000000000..030c4f873da1
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: MIT
+/* Copyright © 2024 Intel Corporation */
+
+#include <linux/slab.h>
+
+#include "i915_drv.h"
+#include "intel_display_device.h"
+#include "intel_display_params.h"
+#include "intel_display_snapshot.h"
+#include "intel_dmc.h"
+#include "intel_overlay.h"
+
+struct intel_display_snapshot {
+ struct intel_display *display;
+
+ struct intel_display_device_info info;
+ struct intel_display_runtime_info runtime_info;
+ struct intel_display_params params;
+ struct intel_overlay_snapshot *overlay;
+ struct intel_dmc_snapshot *dmc;
+};
+
+struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display)
+{
+ struct intel_display_snapshot *snapshot;
+
+ snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC);
+ if (!snapshot)
+ return NULL;
+
+ snapshot->display = display;
+
+ memcpy(&snapshot->info, DISPLAY_INFO(display), sizeof(snapshot->info));
+ memcpy(&snapshot->runtime_info, DISPLAY_RUNTIME_INFO(display),
+ sizeof(snapshot->runtime_info));
+
+ intel_display_params_copy(&snapshot->params);
+
+ snapshot->overlay = intel_overlay_snapshot_capture(display);
+ snapshot->dmc = intel_dmc_snapshot_capture(display);
+
+ return snapshot;
+}
+
+void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot,
+ struct drm_printer *p)
+{
+ struct intel_display *display;
+
+ if (!snapshot)
+ return;
+
+ display = snapshot->display;
+
+ intel_display_device_info_print(&snapshot->info, &snapshot->runtime_info, p);
+ intel_display_params_dump(&snapshot->params, display->drm->driver->name, p);
+
+ intel_overlay_snapshot_print(snapshot->overlay, p);
+ intel_dmc_snapshot_print(snapshot->dmc, p);
+}
+
+void intel_display_snapshot_free(struct intel_display_snapshot *snapshot)
+{
+ if (!snapshot)
+ return;
+
+ intel_display_params_free(&snapshot->params);
+
+ kfree(snapshot->overlay);
+ kfree(snapshot->dmc);
+ kfree(snapshot);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.h b/drivers/gpu/drm/i915/display/intel_display_snapshot.h
new file mode 100644
index 000000000000..7ed27cdea644
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2024 Intel Corporation */
+
+#ifndef __INTEL_DISPLAY_SNAPSHOT_H__
+#define __INTEL_DISPLAY_SNAPSHOT_H__
+
+struct drm_printer;
+struct intel_display;
+struct intel_display_snapshot;
+
+struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display);
+void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot,
+ struct drm_printer *p);
+void intel_display_snapshot_free(struct intel_display_snapshot *snapshot);
+
+#endif /* __INTEL_DISPLAY_SNAPSHOT_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h
index c734ef1fba3c..fc28d34b5eef 100644
--- a/drivers/gpu/drm/i915/display/intel_display_trace.h
+++ b/drivers/gpu/drm/i915/display/intel_display_trace.h
@@ -18,7 +18,7 @@
#include "intel_display_types.h"
#include "intel_vblank.h"
-#define __dev_name_i915(i915) dev_name((i915)->drm.dev)
+#define __dev_name_display(display) dev_name((display)->drm->dev)
#define __dev_name_kms(obj) dev_name((obj)->base.dev->dev)
TRACE_EVENT(intel_pipe_enable,
@@ -32,10 +32,10 @@ TRACE_EVENT(intel_pipe_enable,
__field(enum pipe, pipe)
),
TP_fast_assign(
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc);
struct intel_crtc *it__;
__assign_str(dev);
- for_each_intel_crtc(&dev_priv->drm, it__) {
+ for_each_intel_crtc(display->drm, it__) {
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
}
@@ -61,10 +61,10 @@ TRACE_EVENT(intel_pipe_disable,
),
TP_fast_assign(
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc);
struct intel_crtc *it__;
__assign_str(dev);
- for_each_intel_crtc(&dev_priv->drm, it__) {
+ for_each_intel_crtc(display->drm, it__) {
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
}
@@ -130,18 +130,18 @@ TRACE_EVENT(intel_pipe_crc,
);
TRACE_EVENT(intel_cpu_fifo_underrun,
- TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pipe),
- TP_ARGS(dev_priv, pipe),
+ TP_PROTO(struct intel_display *display, enum pipe pipe),
+ TP_ARGS(display, pipe),
TP_STRUCT__entry(
- __string(dev, __dev_name_i915(dev_priv))
+ __string(dev, __dev_name_display(display))
__field(enum pipe, pipe)
__field(u32, frame)
__field(u32, scanline)
),
TP_fast_assign(
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
__assign_str(dev);
__entry->pipe = pipe;
__entry->frame = intel_crtc_get_vblank_counter(crtc);
@@ -154,11 +154,11 @@ TRACE_EVENT(intel_cpu_fifo_underrun,
);
TRACE_EVENT(intel_pch_fifo_underrun,
- TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pch_transcoder),
- TP_ARGS(dev_priv, pch_transcoder),
+ TP_PROTO(struct intel_display *display, enum pipe pch_transcoder),
+ TP_ARGS(display, pch_transcoder),
TP_STRUCT__entry(
- __string(dev, __dev_name_i915(dev_priv))
+ __string(dev, __dev_name_display(display))
__field(enum pipe, pipe)
__field(u32, frame)
__field(u32, scanline)
@@ -166,7 +166,7 @@ TRACE_EVENT(intel_pch_fifo_underrun,
TP_fast_assign(
enum pipe pipe = pch_transcoder;
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
__assign_str(dev);
__entry->pipe = pipe;
__entry->frame = intel_crtc_get_vblank_counter(crtc);
@@ -179,11 +179,11 @@ TRACE_EVENT(intel_pch_fifo_underrun,
);
TRACE_EVENT(intel_memory_cxsr,
- TP_PROTO(struct drm_i915_private *dev_priv, bool old, bool new),
- TP_ARGS(dev_priv, old, new),
+ TP_PROTO(struct intel_display *display, bool old, bool new),
+ TP_ARGS(display, old, new),
TP_STRUCT__entry(
- __string(dev, __dev_name_i915(dev_priv))
+ __string(dev, __dev_name_display(display))
__array(u32, frame, 3)
__array(u32, scanline, 3)
__field(bool, old)
@@ -193,7 +193,7 @@ TRACE_EVENT(intel_memory_cxsr,
TP_fast_assign(
struct intel_crtc *crtc;
__assign_str(dev);
- for_each_intel_crtc(&dev_priv->drm, crtc) {
+ for_each_intel_crtc(display->drm, crtc) {
__entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc);
__entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc);
}
@@ -458,7 +458,8 @@ TRACE_EVENT(intel_fbc_activate,
),
TP_fast_assign(
- struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev),
+ struct intel_display *display = to_intel_display(plane->base.dev);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display,
plane->pipe);
__assign_str(dev);
__assign_str(name);
@@ -485,7 +486,8 @@ TRACE_EVENT(intel_fbc_deactivate,
),
TP_fast_assign(
- struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev),
+ struct intel_display *display = to_intel_display(plane->base.dev);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display,
plane->pipe);
__assign_str(dev);
__assign_str(name);
@@ -512,7 +514,8 @@ TRACE_EVENT(intel_fbc_nuke,
),
TP_fast_assign(
- struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev),
+ struct intel_display *display = to_intel_display(plane->base.dev);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display,
plane->pipe);
__assign_str(dev);
__assign_str(name);
@@ -652,12 +655,12 @@ TRACE_EVENT(intel_pipe_update_end,
);
TRACE_EVENT(intel_frontbuffer_invalidate,
- TP_PROTO(struct drm_i915_private *i915,
+ TP_PROTO(struct intel_display *display,
unsigned int frontbuffer_bits, unsigned int origin),
- TP_ARGS(i915, frontbuffer_bits, origin),
+ TP_ARGS(display, frontbuffer_bits, origin),
TP_STRUCT__entry(
- __string(dev, __dev_name_i915(i915))
+ __string(dev, __dev_name_display(display))
__field(unsigned int, frontbuffer_bits)
__field(unsigned int, origin)
),
@@ -673,12 +676,12 @@ TRACE_EVENT(intel_frontbuffer_invalidate,
);
TRACE_EVENT(intel_frontbuffer_flush,
- TP_PROTO(struct drm_i915_private *i915,
+ TP_PROTO(struct intel_display *display,
unsigned int frontbuffer_bits, unsigned int origin),
- TP_ARGS(i915, frontbuffer_bits, origin),
+ TP_ARGS(display, frontbuffer_bits, origin),
TP_STRUCT__entry(
- __string(dev, __dev_name_i915(i915))
+ __string(dev, __dev_name_display(display))
__field(unsigned int, frontbuffer_bits)
__field(unsigned int, origin)
),
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index f29e5dc3db91..2bb1fa64da2f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -26,10 +26,8 @@
#ifndef __INTEL_DISPLAY_TYPES_H__
#define __INTEL_DISPLAY_TYPES_H__
-#include <linux/i2c.h>
#include <linux/pm_qos.h>
#include <linux/pwm.h>
-#include <linux/sched/clock.h>
#include <drm/display/drm_dp_dual_mode_helper.h>
#include <drm/display/drm_dp_mst_helper.h>
@@ -38,16 +36,11 @@
#include <drm/drm_atomic.h>
#include <drm/drm_crtc.h>
#include <drm/drm_encoder.h>
-#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
-#include <drm/drm_probe_helper.h>
#include <drm/drm_rect.h>
-#include <drm/drm_vblank.h>
#include <drm/drm_vblank_work.h>
#include <drm/intel/i915_hdcp_interface.h>
-#include <media/cec-notifier.h>
-#include "gem/i915_gem_object_types.h" /* for to_intel_bo() */
#include "i915_vma.h"
#include "i915_vma_types.h"
#include "intel_bios.h"
@@ -57,11 +50,13 @@
#include "intel_dpll_mgr.h"
#include "intel_wm_types.h"
+struct cec_notifier;
struct drm_printer;
struct __intel_global_objs_state;
+struct intel_connector;
struct intel_ddi_buf_trans;
struct intel_fbc;
-struct intel_connector;
+struct intel_hdcp_shim;
struct intel_tc_port;
/*
@@ -430,128 +425,6 @@ struct intel_panel {
struct intel_digital_port;
-enum check_link_response {
- HDCP_LINK_PROTECTED = 0,
- HDCP_TOPOLOGY_CHANGE,
- HDCP_LINK_INTEGRITY_FAILURE,
- HDCP_REAUTH_REQUEST
-};
-
-/*
- * This structure serves as a translation layer between the generic HDCP code
- * and the bus-specific code. What that means is that HDCP over HDMI differs
- * from HDCP over DP, so to account for these differences, we need to
- * communicate with the receiver through this shim.
- *
- * For completeness, the 2 buses differ in the following ways:
- * - DP AUX vs. DDC
- * HDCP registers on the receiver are set via DP AUX for DP, and
- * they are set via DDC for HDMI.
- * - Receiver register offsets
- * The offsets of the registers are different for DP vs. HDMI
- * - Receiver register masks/offsets
- * For instance, the ready bit for the KSV fifo is in a different
- * place on DP vs HDMI
- * - Receiver register names
- * Seriously. In the DP spec, the 16-bit register containing
- * downstream information is called BINFO, on HDMI it's called
- * BSTATUS. To confuse matters further, DP has a BSTATUS register
- * with a completely different definition.
- * - KSV FIFO
- * On HDMI, the ksv fifo is read all at once, whereas on DP it must
- * be read 3 keys at a time
- * - Aksv output
- * Since Aksv is hidden in hardware, there's different procedures
- * to send it over DP AUX vs DDC
- */
-struct intel_hdcp_shim {
- /* Outputs the transmitter's An and Aksv values to the receiver. */
- int (*write_an_aksv)(struct intel_digital_port *dig_port, u8 *an);
-
- /* Reads the receiver's key selection vector */
- int (*read_bksv)(struct intel_digital_port *dig_port, u8 *bksv);
-
- /*
- * Reads BINFO from DP receivers and BSTATUS from HDMI receivers. The
- * definitions are the same in the respective specs, but the names are
- * different. Call it BSTATUS since that's the name the HDMI spec
- * uses and it was there first.
- */
- int (*read_bstatus)(struct intel_digital_port *dig_port,
- u8 *bstatus);
-
- /* Determines whether a repeater is present downstream */
- int (*repeater_present)(struct intel_digital_port *dig_port,
- bool *repeater_present);
-
- /* Reads the receiver's Ri' value */
- int (*read_ri_prime)(struct intel_digital_port *dig_port, u8 *ri);
-
- /* Determines if the receiver's KSV FIFO is ready for consumption */
- int (*read_ksv_ready)(struct intel_digital_port *dig_port,
- bool *ksv_ready);
-
- /* Reads the ksv fifo for num_downstream devices */
- int (*read_ksv_fifo)(struct intel_digital_port *dig_port,
- int num_downstream, u8 *ksv_fifo);
-
- /* Reads a 32-bit part of V' from the receiver */
- int (*read_v_prime_part)(struct intel_digital_port *dig_port,
- int i, u32 *part);
-
- /* Enables HDCP signalling on the port */
- int (*toggle_signalling)(struct intel_digital_port *dig_port,
- enum transcoder cpu_transcoder,
- bool enable);
-
- /* Enable/Disable stream encryption on DP MST Transport Link */
- int (*stream_encryption)(struct intel_connector *connector,
- bool enable);
-
- /* Ensures the link is still protected */
- bool (*check_link)(struct intel_digital_port *dig_port,
- struct intel_connector *connector);
-
- /* Detects panel's hdcp capability. This is optional for HDMI. */
- int (*hdcp_get_capability)(struct intel_digital_port *dig_port,
- bool *hdcp_capable);
-
- /* HDCP adaptation(DP/HDMI) required on the port */
- enum hdcp_wired_protocol protocol;
-
- /* Detects whether sink is HDCP2.2 capable */
- int (*hdcp_2_2_get_capability)(struct intel_connector *connector,
- bool *capable);
-
- /* Write HDCP2.2 messages */
- int (*write_2_2_msg)(struct intel_connector *connector,
- void *buf, size_t size);
-
- /* Read HDCP2.2 messages */
- int (*read_2_2_msg)(struct intel_connector *connector,
- u8 msg_id, void *buf, size_t size);
-
- /*
- * Implementation of DP HDCP2.2 Errata for the communication of stream
- * type to Receivers. In DP HDCP2.2 Stream type is one of the input to
- * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI.
- */
- int (*config_stream_type)(struct intel_connector *connector,
- bool is_repeater, u8 type);
-
- /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */
- int (*stream_2_2_encryption)(struct intel_connector *connector,
- bool enable);
-
- /* HDCP2.2 Link Integrity Check */
- int (*check_2_2_link)(struct intel_digital_port *dig_port,
- struct intel_connector *connector);
-
- /* HDCP remote sink cap */
- int (*get_remote_hdcp_capability)(struct intel_connector *connector,
- bool *hdcp_capable, bool *hdcp2_capable);
-};
-
struct intel_hdcp {
const struct intel_hdcp_shim *shim;
/* Mutex for hdcp state of the connector */
@@ -651,7 +524,7 @@ struct intel_connector {
struct intel_dp *mst_port;
- bool force_bigjoiner_enable;
+ int force_joined_pipes;
struct {
struct drm_dp_aux *dsc_decompression_aux;
@@ -1036,6 +909,10 @@ struct intel_csc_matrix {
u16 postoff[3];
};
+void intel_io_mmio_fw_write(void *ctx, i915_reg_t reg, u32 val);
+
+typedef void (*intel_io_reg_write)(void *ctx, i915_reg_t reg, u32 val);
+
struct intel_crtc_state {
/*
* uapi (drm) state. This is the software state shown to userspace.
@@ -1270,9 +1147,6 @@ struct intel_crtc_state {
/* w/a for waiting 2 vblanks during crtc enable */
enum pipe hsw_workaround_pipe;
- /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
- bool disable_lp_wm;
-
struct intel_crtc_wm_state wm;
int min_cdclk[I915_MAX_PLANES];
@@ -1396,8 +1270,9 @@ struct intel_crtc_state {
/* Only valid on TGL+ */
enum transcoder mst_master_transcoder;
- /* For DSB based color LUT updates */
- struct intel_dsb *dsb_color_vblank, *dsb_color_commit;
+ /* For DSB based pipe updates */
+ struct intel_dsb *dsb_color_vblank, *dsb_commit;
+ bool use_dsb;
u32 psr2_man_track_ctl;
@@ -1488,6 +1363,8 @@ struct intel_crtc {
/* armed event for async flip */
struct drm_pending_vblank_event *flip_done_event;
+ /* armed event for DSB based updates */
+ struct drm_pending_vblank_event *dsb_event;
/* Access to these should be protected by dev_priv->irq_lock. */
bool cpu_fifo_underrun_disabled;
@@ -1540,6 +1417,8 @@ struct intel_crtc {
#ifdef CONFIG_DEBUG_FS
struct intel_pipe_crc pipe_crc;
#endif
+
+ bool block_dc_for_vblank;
};
struct intel_plane {
@@ -1578,22 +1457,26 @@ struct intel_plane {
u32 pixel_format, u64 modifier,
unsigned int rotation);
/* Write all non-self arming plane registers */
- void (*update_noarm)(struct intel_plane *plane,
+ void (*update_noarm)(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
/* Write all self-arming plane registers */
- void (*update_arm)(struct intel_plane *plane,
+ void (*update_arm)(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
/* Disable the plane, must arm */
- void (*disable_arm)(struct intel_plane *plane,
+ void (*disable_arm)(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state);
bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
int (*check_plane)(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
int (*min_cdclk)(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
- void (*async_flip)(struct intel_plane *plane,
+ void (*async_flip)(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip);
@@ -1601,14 +1484,6 @@ struct intel_plane {
void (*disable_flip_done)(struct intel_plane *plane);
};
-struct intel_watermark_params {
- u16 fifo_size;
- u16 max_wm;
- u8 default_wm;
- u8 guard_size;
- u8 cacheline_size;
-};
-
#define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
#define to_intel_connector(x) container_of(x, struct intel_connector, base)
@@ -1622,8 +1497,6 @@ struct intel_watermark_params {
#define to_intel_framebuffer(fb) \
container_of_const((fb), struct intel_framebuffer, base)
-#define intel_fb_obj(x) ((x) ? to_intel_bo((x)->obj[0]) : NULL)
-
struct intel_hdmi {
i915_reg_t hdmi_reg;
struct {
@@ -1676,7 +1549,7 @@ struct intel_pps {
* Pipe whose power sequencer is currently locked into
* this port. Only relevant on VLV/CHV.
*/
- enum pipe pps_pipe;
+ enum pipe vlv_pps_pipe;
/*
* Power sequencer index. Only relevant on BXT+.
@@ -1689,12 +1562,12 @@ struct intel_pps {
* the use of the PPS for any pipe currentrly driving
* external DP as that will mess things up on VLV.
*/
- enum pipe active_pipe;
+ enum pipe vlv_active_pipe;
/*
* Set if the sequencer may be reset due to a power transition,
* requiring a reinitialization. Only relevant on BXT+.
*/
- bool pps_reset;
+ bool bxt_pps_reset;
struct edp_power_seq pps_delays;
struct edp_power_seq bios_pps_delays;
};
@@ -2050,7 +1923,10 @@ static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder)
static inline struct intel_dp *intel_attached_dp(struct intel_connector *connector)
{
- return enc_to_intel_dp(intel_attached_encoder(connector));
+ if (connector->mst_port)
+ return connector->mst_port;
+ else
+ return enc_to_intel_dp(intel_attached_encoder(connector));
}
static inline bool intel_encoder_is_dp(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 7c756d5ba2a2..48bbbf8f312c 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -52,7 +52,7 @@ enum intel_dmc_id {
};
struct intel_dmc {
- struct drm_i915_private *i915;
+ struct intel_display *display;
struct work_struct work;
const char *fw_path;
u32 max_fw_size; /* bytes */
@@ -70,21 +70,21 @@ struct intel_dmc {
};
/* Note: This may be NULL. */
-static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915)
+static struct intel_dmc *display_to_dmc(struct intel_display *display)
{
- return i915->display.dmc.dmc;
+ return display->dmc.dmc;
}
-static const char *dmc_firmware_param(struct drm_i915_private *i915)
+static const char *dmc_firmware_param(struct intel_display *display)
{
- const char *p = i915->display.params.dmc_firmware_path;
+ const char *p = display->params.dmc_firmware_path;
return p && *p ? p : NULL;
}
-static bool dmc_firmware_param_disabled(struct drm_i915_private *i915)
+static bool dmc_firmware_param_disabled(struct intel_display *display)
{
- const char *p = dmc_firmware_param(i915);
+ const char *p = dmc_firmware_param(display);
/* Magic path to indicate disabled */
return p && !strcmp(p, "/dev/null");
@@ -162,18 +162,19 @@ MODULE_FIRMWARE(SKL_DMC_PATH);
#define BXT_DMC_MAX_FW_SIZE 0x3000
MODULE_FIRMWARE(BXT_DMC_PATH);
-static const char *dmc_firmware_default(struct drm_i915_private *i915, u32 *size)
+static const char *dmc_firmware_default(struct intel_display *display, u32 *size)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
const char *fw_path = NULL;
u32 max_fw_size = 0;
- if (DISPLAY_VER_FULL(i915) == IP_VER(20, 0)) {
+ if (DISPLAY_VER_FULL(display) == IP_VER(20, 0)) {
fw_path = XE2LPD_DMC_PATH;
max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
- } else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 1)) {
+ } else if (DISPLAY_VER_FULL(display) == IP_VER(14, 1)) {
fw_path = BMG_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
- } else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
+ } else if (DISPLAY_VER_FULL(display) == IP_VER(14, 0)) {
fw_path = MTL_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
} else if (IS_DG2(i915)) {
@@ -194,7 +195,7 @@ static const char *dmc_firmware_default(struct drm_i915_private *i915, u32 *size
} else if (IS_TIGERLAKE(i915)) {
fw_path = TGL_DMC_PATH;
max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
- } else if (DISPLAY_VER(i915) == 11) {
+ } else if (DISPLAY_VER(display) == 11) {
fw_path = ICL_DMC_PATH;
max_fw_size = ICL_DMC_MAX_FW_SIZE;
} else if (IS_GEMINILAKE(i915)) {
@@ -375,70 +376,70 @@ static bool is_valid_dmc_id(enum intel_dmc_id dmc_id)
return dmc_id >= DMC_FW_MAIN && dmc_id < DMC_FW_MAX;
}
-static bool has_dmc_id_fw(struct drm_i915_private *i915, enum intel_dmc_id dmc_id)
+static bool has_dmc_id_fw(struct intel_display *display, enum intel_dmc_id dmc_id)
{
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct intel_dmc *dmc = display_to_dmc(display);
return dmc && dmc->dmc_info[dmc_id].payload;
}
-bool intel_dmc_has_payload(struct drm_i915_private *i915)
+bool intel_dmc_has_payload(struct intel_display *display)
{
- return has_dmc_id_fw(i915, DMC_FW_MAIN);
+ return has_dmc_id_fw(display, DMC_FW_MAIN);
}
static const struct stepping_info *
-intel_get_stepping_info(struct drm_i915_private *i915,
+intel_get_stepping_info(struct intel_display *display,
struct stepping_info *si)
{
- const char *step_name = intel_step_name(INTEL_DISPLAY_STEP(i915));
+ const char *step_name = intel_step_name(INTEL_DISPLAY_STEP(display));
si->stepping = step_name[0];
si->substepping = step_name[1];
return si;
}
-static void gen9_set_dc_state_debugmask(struct drm_i915_private *i915)
+static void gen9_set_dc_state_debugmask(struct intel_display *display)
{
/* The below bit doesn't need to be cleared ever afterwards */
- intel_de_rmw(i915, DC_STATE_DEBUG, 0,
+ intel_de_rmw(display, DC_STATE_DEBUG, 0,
DC_STATE_DEBUG_MASK_CORES | DC_STATE_DEBUG_MASK_MEMORY_UP);
- intel_de_posting_read(i915, DC_STATE_DEBUG);
+ intel_de_posting_read(display, DC_STATE_DEBUG);
}
-static void disable_event_handler(struct drm_i915_private *i915,
+static void disable_event_handler(struct intel_display *display,
i915_reg_t ctl_reg, i915_reg_t htp_reg)
{
- intel_de_write(i915, ctl_reg,
+ intel_de_write(display, ctl_reg,
REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
DMC_EVT_CTL_TYPE_EDGE_0_1) |
REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
DMC_EVT_CTL_EVENT_ID_FALSE));
- intel_de_write(i915, htp_reg, 0);
+ intel_de_write(display, htp_reg, 0);
}
-static void disable_all_event_handlers(struct drm_i915_private *i915)
+static void disable_all_event_handlers(struct intel_display *display)
{
enum intel_dmc_id dmc_id;
/* TODO: disable the event handlers on pre-GEN12 platforms as well */
- if (DISPLAY_VER(i915) < 12)
+ if (DISPLAY_VER(display) < 12)
return;
for_each_dmc_id(dmc_id) {
int handler;
- if (!has_dmc_id_fw(i915, dmc_id))
+ if (!has_dmc_id_fw(display, dmc_id))
continue;
for (handler = 0; handler < DMC_EVENT_HANDLER_COUNT_GEN12; handler++)
- disable_event_handler(i915,
- DMC_EVT_CTL(i915, dmc_id, handler),
- DMC_EVT_HTP(i915, dmc_id, handler));
+ disable_event_handler(display,
+ DMC_EVT_CTL(display, dmc_id, handler),
+ DMC_EVT_HTP(display, dmc_id, handler));
}
}
-static void adlp_pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
+static void adlp_pipedmc_clock_gating_wa(struct intel_display *display, bool enable)
{
enum pipe pipe;
@@ -451,84 +452,86 @@ static void adlp_pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool ena
*/
if (enable)
for (pipe = PIPE_A; pipe <= PIPE_D; pipe++)
- intel_de_rmw(i915, CLKGATE_DIS_PSL_EXT(pipe),
+ intel_de_rmw(display, CLKGATE_DIS_PSL_EXT(pipe),
0, PIPEDMC_GATING_DIS);
else
for (pipe = PIPE_C; pipe <= PIPE_D; pipe++)
- intel_de_rmw(i915, CLKGATE_DIS_PSL_EXT(pipe),
+ intel_de_rmw(display, CLKGATE_DIS_PSL_EXT(pipe),
PIPEDMC_GATING_DIS, 0);
}
-static void mtl_pipedmc_clock_gating_wa(struct drm_i915_private *i915)
+static void mtl_pipedmc_clock_gating_wa(struct intel_display *display)
{
/*
* Wa_16015201720
* The WA requires clock gating to be disabled all the time
* for pipe A and B.
*/
- intel_de_rmw(i915, GEN9_CLKGATE_DIS_0, 0,
+ intel_de_rmw(display, GEN9_CLKGATE_DIS_0, 0,
MTL_PIPEDMC_GATING_DIS_A | MTL_PIPEDMC_GATING_DIS_B);
}
-static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable)
+static void pipedmc_clock_gating_wa(struct intel_display *display, bool enable)
{
- if (DISPLAY_VER(i915) >= 14 && enable)
- mtl_pipedmc_clock_gating_wa(i915);
- else if (DISPLAY_VER(i915) == 13)
- adlp_pipedmc_clock_gating_wa(i915, enable);
+ if (DISPLAY_VER(display) >= 14 && enable)
+ mtl_pipedmc_clock_gating_wa(display);
+ else if (DISPLAY_VER(display) == 13)
+ adlp_pipedmc_clock_gating_wa(display, enable);
}
-void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe)
+void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe)
{
enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe);
- if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(i915, dmc_id))
+ if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id))
return;
- if (DISPLAY_VER(i915) >= 14)
- intel_de_rmw(i915, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe));
+ if (DISPLAY_VER(display) >= 14)
+ intel_de_rmw(display, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe));
else
- intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE);
+ intel_de_rmw(display, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE);
}
-void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe)
+void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe)
{
enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe);
- if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(i915, dmc_id))
+ if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id))
return;
- if (DISPLAY_VER(i915) >= 14)
- intel_de_rmw(i915, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0);
+ if (DISPLAY_VER(display) >= 14)
+ intel_de_rmw(display, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0);
else
- intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0);
+ intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0);
}
-static bool is_dmc_evt_ctl_reg(struct drm_i915_private *i915,
+static bool is_dmc_evt_ctl_reg(struct intel_display *display,
enum intel_dmc_id dmc_id, i915_reg_t reg)
{
u32 offset = i915_mmio_reg_offset(reg);
- u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(i915, dmc_id, 0));
- u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(i915, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
+ u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0));
+ u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
return offset >= start && offset < end;
}
-static bool is_dmc_evt_htp_reg(struct drm_i915_private *i915,
+static bool is_dmc_evt_htp_reg(struct intel_display *display,
enum intel_dmc_id dmc_id, i915_reg_t reg)
{
u32 offset = i915_mmio_reg_offset(reg);
- u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(i915, dmc_id, 0));
- u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(i915, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
+ u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0));
+ u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
return offset >= start && offset < end;
}
-static bool disable_dmc_evt(struct drm_i915_private *i915,
+static bool disable_dmc_evt(struct intel_display *display,
enum intel_dmc_id dmc_id,
i915_reg_t reg, u32 data)
{
- if (!is_dmc_evt_ctl_reg(i915, dmc_id, reg))
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
+ if (!is_dmc_evt_ctl_reg(display, dmc_id, reg))
return false;
/* keep all pipe DMC events disabled by default */
@@ -548,11 +551,11 @@ static bool disable_dmc_evt(struct drm_i915_private *i915,
return false;
}
-static u32 dmc_mmiodata(struct drm_i915_private *i915,
+static u32 dmc_mmiodata(struct intel_display *display,
struct intel_dmc *dmc,
enum intel_dmc_id dmc_id, int i)
{
- if (disable_dmc_evt(i915, dmc_id,
+ if (disable_dmc_evt(display, dmc_id,
dmc->dmc_info[dmc_id].mmioaddr[i],
dmc->dmc_info[dmc_id].mmiodata[i]))
return REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
@@ -565,25 +568,26 @@ static u32 dmc_mmiodata(struct drm_i915_private *i915,
/**
* intel_dmc_load_program() - write the firmware from memory to register.
- * @i915: i915 drm device.
+ * @display: display instance
*
* DMC firmware is read from a .bin file and kept in internal memory one time.
* Everytime display comes back from low power state this function is called to
* copy the firmware from internal memory to registers.
*/
-void intel_dmc_load_program(struct drm_i915_private *i915)
+void intel_dmc_load_program(struct intel_display *display)
{
- struct i915_power_domains *power_domains = &i915->display.power.domains;
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct drm_i915_private *i915 __maybe_unused = to_i915(display->drm);
+ struct i915_power_domains *power_domains = &display->power.domains;
+ struct intel_dmc *dmc = display_to_dmc(display);
enum intel_dmc_id dmc_id;
u32 i;
- if (!intel_dmc_has_payload(i915))
+ if (!intel_dmc_has_payload(display))
return;
- pipedmc_clock_gating_wa(i915, true);
+ pipedmc_clock_gating_wa(display, true);
- disable_all_event_handlers(i915);
+ disable_all_event_handlers(display);
assert_rpm_wakelock_held(&i915->runtime_pm);
@@ -591,7 +595,7 @@ void intel_dmc_load_program(struct drm_i915_private *i915)
for_each_dmc_id(dmc_id) {
for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) {
- intel_de_write_fw(i915,
+ intel_de_write_fw(display,
DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i),
dmc->dmc_info[dmc_id].payload[i]);
}
@@ -601,48 +605,48 @@ void intel_dmc_load_program(struct drm_i915_private *i915)
for_each_dmc_id(dmc_id) {
for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) {
- intel_de_write(i915, dmc->dmc_info[dmc_id].mmioaddr[i],
- dmc_mmiodata(i915, dmc, dmc_id, i));
+ intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i],
+ dmc_mmiodata(display, dmc, dmc_id, i));
}
}
power_domains->dc_state = 0;
- gen9_set_dc_state_debugmask(i915);
+ gen9_set_dc_state_debugmask(display);
- pipedmc_clock_gating_wa(i915, false);
+ pipedmc_clock_gating_wa(display, false);
}
/**
* intel_dmc_disable_program() - disable the firmware
- * @i915: i915 drm device
+ * @display: display instance
*
* Disable all event handlers in the firmware, making sure the firmware is
* inactive after the display is uninitialized.
*/
-void intel_dmc_disable_program(struct drm_i915_private *i915)
+void intel_dmc_disable_program(struct intel_display *display)
{
- if (!intel_dmc_has_payload(i915))
+ if (!intel_dmc_has_payload(display))
return;
- pipedmc_clock_gating_wa(i915, true);
- disable_all_event_handlers(i915);
- pipedmc_clock_gating_wa(i915, false);
+ pipedmc_clock_gating_wa(display, true);
+ disable_all_event_handlers(display);
+ pipedmc_clock_gating_wa(display, false);
- intel_dmc_wl_disable(&i915->display);
+ intel_dmc_wl_disable(display);
}
-void assert_dmc_loaded(struct drm_i915_private *i915)
+void assert_dmc_loaded(struct intel_display *display)
{
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct intel_dmc *dmc = display_to_dmc(display);
- drm_WARN_ONCE(&i915->drm, !dmc, "DMC not initialized\n");
- drm_WARN_ONCE(&i915->drm, dmc &&
- !intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)),
+ drm_WARN_ONCE(display->drm, !dmc, "DMC not initialized\n");
+ drm_WARN_ONCE(display->drm, dmc &&
+ !intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)),
"DMC program storage start is NULL\n");
- drm_WARN_ONCE(&i915->drm, !intel_de_read(i915, DMC_SSP_BASE),
+ drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_SSP_BASE),
"DMC SSP Base Not fine\n");
- drm_WARN_ONCE(&i915->drm, !intel_de_read(i915, DMC_HTP_SKL),
+ drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_HTP_SKL),
"DMC HTP Not fine\n");
}
@@ -673,7 +677,7 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc,
const struct stepping_info *si,
u8 package_ver)
{
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
enum intel_dmc_id dmc_id;
unsigned int i;
@@ -681,7 +685,7 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc,
dmc_id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id;
if (!is_valid_dmc_id(dmc_id)) {
- drm_dbg(&i915->drm, "Unsupported firmware id: %u\n", dmc_id);
+ drm_dbg(display->drm, "Unsupported firmware id: %u\n", dmc_id);
continue;
}
@@ -703,7 +707,7 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc,
const u32 *mmioaddr, u32 mmio_count,
int header_ver, enum intel_dmc_id dmc_id)
{
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
u32 start_range, end_range;
int i;
@@ -713,14 +717,14 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc,
} else if (dmc_id == DMC_FW_MAIN) {
start_range = TGL_MAIN_MMIO_START;
end_range = TGL_MAIN_MMIO_END;
- } else if (DISPLAY_VER(i915) >= 13) {
+ } else if (DISPLAY_VER(display) >= 13) {
start_range = ADLP_PIPE_MMIO_START;
end_range = ADLP_PIPE_MMIO_END;
- } else if (DISPLAY_VER(i915) >= 12) {
+ } else if (DISPLAY_VER(display) >= 12) {
start_range = TGL_PIPE_MMIO_START(dmc_id);
end_range = TGL_PIPE_MMIO_END(dmc_id);
} else {
- drm_warn(&i915->drm, "Unknown mmio range for sanity check");
+ drm_warn(display->drm, "Unknown mmio range for sanity check");
return false;
}
@@ -736,7 +740,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
const struct intel_dmc_header_base *dmc_header,
size_t rem_size, enum intel_dmc_id dmc_id)
{
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id];
unsigned int header_len_bytes, dmc_header_size, payload_size, i;
const u32 *mmioaddr, *mmiodata;
@@ -784,39 +788,39 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
start_mmioaddr = DMC_V1_MMIO_START_RANGE;
dmc_header_size = sizeof(*v1);
} else {
- drm_err(&i915->drm, "Unknown DMC fw header version: %u\n",
+ drm_err(display->drm, "Unknown DMC fw header version: %u\n",
dmc_header->header_ver);
return 0;
}
if (header_len_bytes != dmc_header_size) {
- drm_err(&i915->drm, "DMC firmware has wrong dmc header length "
+ drm_err(display->drm, "DMC firmware has wrong dmc header length "
"(%u bytes)\n", header_len_bytes);
return 0;
}
/* Cache the dmc header info. */
if (mmio_count > mmio_count_max) {
- drm_err(&i915->drm, "DMC firmware has wrong mmio count %u\n", mmio_count);
+ drm_err(display->drm, "DMC firmware has wrong mmio count %u\n", mmio_count);
return 0;
}
if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count,
dmc_header->header_ver, dmc_id)) {
- drm_err(&i915->drm, "DMC firmware has Wrong MMIO Addresses\n");
+ drm_err(display->drm, "DMC firmware has Wrong MMIO Addresses\n");
return 0;
}
- drm_dbg_kms(&i915->drm, "DMC %d:\n", dmc_id);
+ drm_dbg_kms(display->drm, "DMC %d:\n", dmc_id);
for (i = 0; i < mmio_count; i++) {
dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]);
dmc_info->mmiodata[i] = mmiodata[i];
- drm_dbg_kms(&i915->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n",
+ drm_dbg_kms(display->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n",
i, mmioaddr[i], mmiodata[i],
- is_dmc_evt_ctl_reg(i915, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" :
- is_dmc_evt_htp_reg(i915, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "",
- disable_dmc_evt(i915, dmc_id, dmc_info->mmioaddr[i],
+ is_dmc_evt_ctl_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" :
+ is_dmc_evt_htp_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "",
+ disable_dmc_evt(display, dmc_id, dmc_info->mmioaddr[i],
dmc_info->mmiodata[i]) ? " (disabling)" : "");
}
dmc_info->mmio_count = mmio_count;
@@ -830,7 +834,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
goto error_truncated;
if (payload_size > dmc->max_fw_size) {
- drm_err(&i915->drm, "DMC FW too big (%u bytes)\n", payload_size);
+ drm_err(display->drm, "DMC FW too big (%u bytes)\n", payload_size);
return 0;
}
dmc_info->dmc_fw_size = dmc_header->fw_size;
@@ -845,7 +849,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
return header_len_bytes + payload_size;
error_truncated:
- drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
+ drm_err(display->drm, "Truncated DMC firmware, refusing.\n");
return 0;
}
@@ -855,7 +859,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc,
const struct stepping_info *si,
size_t rem_size)
{
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
u32 package_size = sizeof(struct intel_package_header);
u32 num_entries, max_entries;
const struct intel_fw_info *fw_info;
@@ -868,7 +872,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc,
} else if (package_header->header_ver == 2) {
max_entries = PACKAGE_V2_MAX_FW_INFO_ENTRIES;
} else {
- drm_err(&i915->drm, "DMC firmware has unknown header version %u\n",
+ drm_err(display->drm, "DMC firmware has unknown header version %u\n",
package_header->header_ver);
return 0;
}
@@ -882,7 +886,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc,
goto error_truncated;
if (package_header->header_len * 4 != package_size) {
- drm_err(&i915->drm, "DMC firmware has wrong package header length "
+ drm_err(display->drm, "DMC firmware has wrong package header length "
"(%u bytes)\n", package_size);
return 0;
}
@@ -900,7 +904,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc,
return package_size;
error_truncated:
- drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
+ drm_err(display->drm, "Truncated DMC firmware, refusing.\n");
return 0;
}
@@ -909,16 +913,16 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc,
struct intel_css_header *css_header,
size_t rem_size)
{
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
if (rem_size < sizeof(struct intel_css_header)) {
- drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
+ drm_err(display->drm, "Truncated DMC firmware, refusing.\n");
return 0;
}
if (sizeof(struct intel_css_header) !=
(css_header->header_len * 4)) {
- drm_err(&i915->drm, "DMC firmware has wrong CSS header length "
+ drm_err(display->drm, "DMC firmware has wrong CSS header length "
"(%u bytes)\n",
(css_header->header_len * 4));
return 0;
@@ -931,12 +935,12 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc,
static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
{
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
struct intel_css_header *css_header;
struct intel_package_header *package_header;
struct intel_dmc_header_base *dmc_header;
struct stepping_info display_info = { '*', '*'};
- const struct stepping_info *si = intel_get_stepping_info(i915, &display_info);
+ const struct stepping_info *si = intel_get_stepping_info(display, &display_info);
enum intel_dmc_id dmc_id;
u32 readcount = 0;
u32 r, offset;
@@ -966,7 +970,7 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4;
if (offset > fw->size) {
- drm_err(&i915->drm, "Reading beyond the fw_size\n");
+ drm_err(display->drm, "Reading beyond the fw_size\n");
continue;
}
@@ -974,30 +978,35 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, dmc_id);
}
- if (!intel_dmc_has_payload(i915)) {
- drm_err(&i915->drm, "DMC firmware main program not found\n");
+ if (!intel_dmc_has_payload(display)) {
+ drm_err(display->drm, "DMC firmware main program not found\n");
return -ENOENT;
}
return 0;
}
-static void intel_dmc_runtime_pm_get(struct drm_i915_private *i915)
+static void intel_dmc_runtime_pm_get(struct intel_display *display)
{
- drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref);
- i915->display.dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT);
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
+ drm_WARN_ON(display->drm, display->dmc.wakeref);
+ display->dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT);
}
-static void intel_dmc_runtime_pm_put(struct drm_i915_private *i915)
+static void intel_dmc_runtime_pm_put(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref __maybe_unused =
- fetch_and_zero(&i915->display.dmc.wakeref);
+ fetch_and_zero(&display->dmc.wakeref);
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
}
-static const char *dmc_fallback_path(struct drm_i915_private *i915)
+static const char *dmc_fallback_path(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
if (IS_ALDERLAKE_P(i915))
return ADLP_DMC_FALLBACK_PATH;
@@ -1007,45 +1016,45 @@ static const char *dmc_fallback_path(struct drm_i915_private *i915)
static void dmc_load_work_fn(struct work_struct *work)
{
struct intel_dmc *dmc = container_of(work, typeof(*dmc), work);
- struct drm_i915_private *i915 = dmc->i915;
+ struct intel_display *display = dmc->display;
const struct firmware *fw = NULL;
const char *fallback_path;
int err;
- err = request_firmware(&fw, dmc->fw_path, i915->drm.dev);
+ err = request_firmware(&fw, dmc->fw_path, display->drm->dev);
- if (err == -ENOENT && !dmc_firmware_param(i915)) {
- fallback_path = dmc_fallback_path(i915);
+ if (err == -ENOENT && !dmc_firmware_param(display)) {
+ fallback_path = dmc_fallback_path(display);
if (fallback_path) {
- drm_dbg_kms(&i915->drm, "%s not found, falling back to %s\n",
+ drm_dbg_kms(display->drm, "%s not found, falling back to %s\n",
dmc->fw_path, fallback_path);
- err = request_firmware(&fw, fallback_path, i915->drm.dev);
+ err = request_firmware(&fw, fallback_path, display->drm->dev);
if (err == 0)
dmc->fw_path = fallback_path;
}
}
if (err) {
- drm_notice(&i915->drm,
+ drm_notice(display->drm,
"Failed to load DMC firmware %s (%pe). Disabling runtime power management.\n",
dmc->fw_path, ERR_PTR(err));
- drm_notice(&i915->drm, "DMC firmware homepage: %s",
+ drm_notice(display->drm, "DMC firmware homepage: %s",
INTEL_DMC_FIRMWARE_URL);
return;
}
err = parse_dmc_fw(dmc, fw);
if (err) {
- drm_notice(&i915->drm,
+ drm_notice(display->drm,
"Failed to parse DMC firmware %s (%pe). Disabling runtime power management.\n",
dmc->fw_path, ERR_PTR(err));
goto out;
}
- intel_dmc_load_program(i915);
- intel_dmc_runtime_pm_put(i915);
+ intel_dmc_load_program(display);
+ intel_dmc_runtime_pm_put(display);
- drm_info(&i915->drm, "Finished loading DMC firmware %s (v%u.%u)\n",
+ drm_info(display->drm, "Finished loading DMC firmware %s (v%u.%u)\n",
dmc->fw_path, DMC_VERSION_MAJOR(dmc->version),
DMC_VERSION_MINOR(dmc->version));
@@ -1055,16 +1064,17 @@ out:
/**
* intel_dmc_init() - initialize the firmware loading.
- * @i915: i915 drm device.
+ * @display: display instance
*
* This function is called at the time of loading the display driver to read
* firmware from a .bin file and copied into a internal memory.
*/
-void intel_dmc_init(struct drm_i915_private *i915)
+void intel_dmc_init(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_dmc *dmc;
- if (!HAS_DMC(i915))
+ if (!HAS_DMC(display))
return;
/*
@@ -1075,35 +1085,35 @@ void intel_dmc_init(struct drm_i915_private *i915)
* suspend as runtime suspend *requires* a working DMC for whatever
* reason.
*/
- intel_dmc_runtime_pm_get(i915);
+ intel_dmc_runtime_pm_get(display);
dmc = kzalloc(sizeof(*dmc), GFP_KERNEL);
if (!dmc)
return;
- dmc->i915 = i915;
+ dmc->display = display;
INIT_WORK(&dmc->work, dmc_load_work_fn);
- dmc->fw_path = dmc_firmware_default(i915, &dmc->max_fw_size);
+ dmc->fw_path = dmc_firmware_default(display, &dmc->max_fw_size);
- if (dmc_firmware_param_disabled(i915)) {
- drm_info(&i915->drm, "Disabling DMC firmware and runtime PM\n");
+ if (dmc_firmware_param_disabled(display)) {
+ drm_info(display->drm, "Disabling DMC firmware and runtime PM\n");
goto out;
}
- if (dmc_firmware_param(i915))
- dmc->fw_path = dmc_firmware_param(i915);
+ if (dmc_firmware_param(display))
+ dmc->fw_path = dmc_firmware_param(display);
if (!dmc->fw_path) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"No known DMC firmware for platform, disabling runtime PM\n");
goto out;
}
- i915->display.dmc.dmc = dmc;
+ display->dmc.dmc = dmc;
- drm_dbg_kms(&i915->drm, "Loading %s\n", dmc->fw_path);
+ drm_dbg_kms(display->drm, "Loading %s\n", dmc->fw_path);
queue_work(i915->unordered_wq, &dmc->work);
return;
@@ -1114,129 +1124,152 @@ out:
/**
* intel_dmc_suspend() - prepare DMC firmware before system suspend
- * @i915: i915 drm device
+ * @display: display instance
*
* Prepare the DMC firmware before entering system suspend. This includes
* flushing pending work items and releasing any resources acquired during
* init.
*/
-void intel_dmc_suspend(struct drm_i915_private *i915)
+void intel_dmc_suspend(struct intel_display *display)
{
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct intel_dmc *dmc = display_to_dmc(display);
- if (!HAS_DMC(i915))
+ if (!HAS_DMC(display))
return;
if (dmc)
flush_work(&dmc->work);
- intel_dmc_wl_disable(&i915->display);
+ intel_dmc_wl_disable(display);
/* Drop the reference held in case DMC isn't loaded. */
- if (!intel_dmc_has_payload(i915))
- intel_dmc_runtime_pm_put(i915);
+ if (!intel_dmc_has_payload(display))
+ intel_dmc_runtime_pm_put(display);
}
/**
* intel_dmc_resume() - init DMC firmware during system resume
- * @i915: i915 drm device
+ * @display: display instance
*
* Reinitialize the DMC firmware during system resume, reacquiring any
* resources released in intel_dmc_suspend().
*/
-void intel_dmc_resume(struct drm_i915_private *i915)
+void intel_dmc_resume(struct intel_display *display)
{
- if (!HAS_DMC(i915))
+ if (!HAS_DMC(display))
return;
/*
* Reacquire the reference to keep RPM disabled in case DMC isn't
* loaded.
*/
- if (!intel_dmc_has_payload(i915))
- intel_dmc_runtime_pm_get(i915);
+ if (!intel_dmc_has_payload(display))
+ intel_dmc_runtime_pm_get(display);
}
/**
* intel_dmc_fini() - unload the DMC firmware.
- * @i915: i915 drm device.
+ * @display: display instance
*
* Firmmware unloading includes freeing the internal memory and reset the
* firmware loading status.
*/
-void intel_dmc_fini(struct drm_i915_private *i915)
+void intel_dmc_fini(struct intel_display *display)
{
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct intel_dmc *dmc = display_to_dmc(display);
enum intel_dmc_id dmc_id;
- if (!HAS_DMC(i915))
+ if (!HAS_DMC(display))
return;
- intel_dmc_suspend(i915);
- drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref);
+ intel_dmc_suspend(display);
+ drm_WARN_ON(display->drm, display->dmc.wakeref);
if (dmc) {
for_each_dmc_id(dmc_id)
kfree(dmc->dmc_info[dmc_id].payload);
kfree(dmc);
- i915->display.dmc.dmc = NULL;
+ display->dmc.dmc = NULL;
}
}
-void intel_dmc_print_error_state(struct drm_printer *p,
- struct drm_i915_private *i915)
+struct intel_dmc_snapshot {
+ bool initialized;
+ bool loaded;
+ u32 version;
+};
+
+struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display)
{
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct intel_dmc *dmc = display_to_dmc(display);
+ struct intel_dmc_snapshot *snapshot;
- if (!HAS_DMC(i915))
- return;
+ if (!HAS_DMC(display))
+ return NULL;
- drm_printf(p, "DMC initialized: %s\n", str_yes_no(dmc));
- drm_printf(p, "DMC loaded: %s\n",
- str_yes_no(intel_dmc_has_payload(i915)));
+ snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC);
+ if (!snapshot)
+ return NULL;
+
+ snapshot->initialized = dmc;
+ snapshot->loaded = intel_dmc_has_payload(display);
if (dmc)
+ snapshot->version = dmc->version;
+
+ return snapshot;
+}
+
+void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p)
+{
+ if (!snapshot)
+ return;
+
+ drm_printf(p, "DMC initialized: %s\n", str_yes_no(snapshot->initialized));
+ drm_printf(p, "DMC loaded: %s\n", str_yes_no(snapshot->loaded));
+ if (snapshot->initialized)
drm_printf(p, "DMC fw version: %d.%d\n",
- DMC_VERSION_MAJOR(dmc->version),
- DMC_VERSION_MINOR(dmc->version));
+ DMC_VERSION_MAJOR(snapshot->version),
+ DMC_VERSION_MINOR(snapshot->version));
}
static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
{
- struct drm_i915_private *i915 = m->private;
- struct intel_dmc *dmc = i915_to_dmc(i915);
+ struct intel_display *display = m->private;
+ struct drm_i915_private *i915 = to_i915(display->drm);
+ struct intel_dmc *dmc = display_to_dmc(display);
intel_wakeref_t wakeref;
i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG;
- if (!HAS_DMC(i915))
+ if (!HAS_DMC(display))
return -ENODEV;
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc));
seq_printf(m, "fw loaded: %s\n",
- str_yes_no(intel_dmc_has_payload(i915)));
+ str_yes_no(intel_dmc_has_payload(display)));
seq_printf(m, "path: %s\n", dmc ? dmc->fw_path : "N/A");
seq_printf(m, "Pipe A fw needed: %s\n",
- str_yes_no(DISPLAY_VER(i915) >= 12));
+ str_yes_no(DISPLAY_VER(display) >= 12));
seq_printf(m, "Pipe A fw loaded: %s\n",
- str_yes_no(has_dmc_id_fw(i915, DMC_FW_PIPEA)));
+ str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEA)));
seq_printf(m, "Pipe B fw needed: %s\n",
str_yes_no(IS_ALDERLAKE_P(i915) ||
- DISPLAY_VER(i915) >= 14));
+ DISPLAY_VER(display) >= 14));
seq_printf(m, "Pipe B fw loaded: %s\n",
- str_yes_no(has_dmc_id_fw(i915, DMC_FW_PIPEB)));
+ str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEB)));
- if (!intel_dmc_has_payload(i915))
+ if (!intel_dmc_has_payload(display))
goto out;
seq_printf(m, "version: %d.%d\n", DMC_VERSION_MAJOR(dmc->version),
DMC_VERSION_MINOR(dmc->version));
- if (DISPLAY_VER(i915) >= 12) {
+ if (DISPLAY_VER(display) >= 12) {
i915_reg_t dc3co_reg;
- if (IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) {
+ if (IS_DGFX(i915) || DISPLAY_VER(display) >= 14) {
dc3co_reg = DG1_DMC_DEBUG3;
dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
} else {
@@ -1246,7 +1279,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
}
seq_printf(m, "DC3CO count: %d\n",
- intel_de_read(i915, dc3co_reg));
+ intel_de_read(display, dc3co_reg));
} else {
dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT :
SKL_DMC_DC3_DC5_COUNT;
@@ -1254,18 +1287,18 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
dc6_reg = SKL_DMC_DC5_DC6_COUNT;
}
- seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(i915, dc5_reg));
+ seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(display, dc5_reg));
if (i915_mmio_reg_valid(dc6_reg))
seq_printf(m, "DC5 -> DC6 count: %d\n",
- intel_de_read(i915, dc6_reg));
+ intel_de_read(display, dc6_reg));
seq_printf(m, "program base: 0x%08x\n",
- intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)));
+ intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)));
out:
seq_printf(m, "ssp base: 0x%08x\n",
- intel_de_read(i915, DMC_SSP_BASE));
- seq_printf(m, "htp: 0x%08x\n", intel_de_read(i915, DMC_HTP_SKL));
+ intel_de_read(display, DMC_SSP_BASE));
+ seq_printf(m, "htp: 0x%08x\n", intel_de_read(display, DMC_HTP_SKL));
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
@@ -1274,10 +1307,10 @@ out:
DEFINE_SHOW_ATTRIBUTE(intel_dmc_debugfs_status);
-void intel_dmc_debugfs_register(struct drm_i915_private *i915)
+void intel_dmc_debugfs_register(struct intel_display *display)
{
- struct drm_minor *minor = i915->drm.primary;
+ struct drm_minor *minor = display->drm->primary;
debugfs_create_file("i915_dmc_info", 0444, minor->debugfs_root,
- i915, &intel_dmc_debugfs_status_fops);
+ display, &intel_dmc_debugfs_status_fops);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
index 54cff6002e31..44cecef98e73 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc.h
@@ -9,22 +9,24 @@
#include <linux/types.h>
enum pipe;
-struct drm_i915_private;
struct drm_printer;
+struct intel_display;
+struct intel_dmc_snapshot;
-void intel_dmc_init(struct drm_i915_private *i915);
-void intel_dmc_load_program(struct drm_i915_private *i915);
-void intel_dmc_disable_program(struct drm_i915_private *i915);
-void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe);
-void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe);
-void intel_dmc_fini(struct drm_i915_private *i915);
-void intel_dmc_suspend(struct drm_i915_private *i915);
-void intel_dmc_resume(struct drm_i915_private *i915);
-bool intel_dmc_has_payload(struct drm_i915_private *i915);
-void intel_dmc_debugfs_register(struct drm_i915_private *i915);
-void intel_dmc_print_error_state(struct drm_printer *p,
- struct drm_i915_private *i915);
+void intel_dmc_init(struct intel_display *display);
+void intel_dmc_load_program(struct intel_display *display);
+void intel_dmc_disable_program(struct intel_display *display);
+void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe);
+void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe);
+void intel_dmc_fini(struct intel_display *display);
+void intel_dmc_suspend(struct intel_display *display);
+void intel_dmc_resume(struct intel_display *display);
+bool intel_dmc_has_payload(struct intel_display *display);
+void intel_dmc_debugfs_register(struct intel_display *display);
-void assert_dmc_loaded(struct drm_i915_private *i915);
+struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display);
+void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p);
+
+void assert_dmc_loaded(struct intel_display *display);
#endif /* __INTEL_DMC_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
index d9864b9cc429..5634ff07269d 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c
@@ -109,10 +109,8 @@ static bool intel_dmc_wl_check_range(u32 address)
static bool __intel_dmc_wl_supported(struct intel_display *display)
{
- struct drm_i915_private *i915 = to_i915(display->drm);
-
if (DISPLAY_VER(display) < 20 ||
- !intel_dmc_has_payload(i915) ||
+ !intel_dmc_has_payload(display) ||
!display->params.enable_dmc_wl)
return false;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 90fa73575feb..6b27fabd61c3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -67,6 +67,7 @@
#include "intel_dp_hdcp.h"
#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
+#include "intel_dp_test.h"
#include "intel_dp_tunnel.h"
#include "intel_dpio_phy.h"
#include "intel_dpll.h"
@@ -84,6 +85,7 @@
#include "intel_pch_display.h"
#include "intel_pps.h"
#include "intel_psr.h"
+#include "intel_runtime_pm.h"
#include "intel_quirks.h"
#include "intel_tc.h"
#include "intel_vdsc.h"
@@ -103,13 +105,6 @@
/* DP DSC FEC Overhead factor in ppm = 1/(0.972261) = 1.028530 */
#define DP_DSC_FEC_OVERHEAD_FACTOR 1028530
-/* Compliance test status bits */
-#define INTEL_DP_RESOLUTION_SHIFT_MASK 0
-#define INTEL_DP_RESOLUTION_PREFERRED (1 << INTEL_DP_RESOLUTION_SHIFT_MASK)
-#define INTEL_DP_RESOLUTION_STANDARD (2 << INTEL_DP_RESOLUTION_SHIFT_MASK)
-#define INTEL_DP_RESOLUTION_FAILSAFE (3 << INTEL_DP_RESOLUTION_SHIFT_MASK)
-
-
/* Constants for DP DSC configurations */
static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15};
@@ -770,8 +765,8 @@ static void intel_dp_set_common_rates(struct intel_dp *intel_dp)
intel_dp_link_config_init(intel_dp);
}
-static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
- u8 lane_count)
+bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
+ u8 lane_count)
{
/*
* FIXME: we need to synchronize the current link parameters with
@@ -865,36 +860,74 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p
return bits_per_pixel;
}
-static
-u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
- u32 mode_clock, u32 mode_hdisplay,
- bool bigjoiner)
+static int bigjoiner_interface_bits(struct intel_display *display)
{
- u32 max_bpp_small_joiner_ram;
+ return DISPLAY_VER(display) >= 14 ? 36 : 24;
+}
+
+static u32 bigjoiner_bw_max_bpp(struct intel_display *display, u32 mode_clock,
+ int num_joined_pipes)
+{
+ u32 max_bpp;
+ /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */
+ int ppc = 2;
+ int num_big_joiners = num_joined_pipes / 2;
+
+ max_bpp = display->cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits(display) /
+ intel_dp_mode_to_fec_clock(mode_clock);
+
+ max_bpp *= num_big_joiners;
+
+ return max_bpp;
+
+}
+
+static u32 small_joiner_ram_max_bpp(struct intel_display *display,
+ u32 mode_hdisplay,
+ int num_joined_pipes)
+{
+ struct drm_i915_private *i915 = to_i915(display->drm);
+ u32 max_bpp;
/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
- max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / mode_hdisplay;
+ max_bpp = small_joiner_ram_size_bits(i915) / mode_hdisplay;
+
+ max_bpp *= num_joined_pipes;
- if (bigjoiner) {
- int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24;
- /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */
- int ppc = 2;
- u32 max_bpp_bigjoiner =
- i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits /
- intel_dp_mode_to_fec_clock(mode_clock);
+ return max_bpp;
+}
- max_bpp_small_joiner_ram *= 2;
+static int ultrajoiner_ram_bits(void)
+{
+ return 4 * 72 * 512;
+}
- return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
- }
+static u32 ultrajoiner_ram_max_bpp(u32 mode_hdisplay)
+{
+ return ultrajoiner_ram_bits() / mode_hdisplay;
+}
+
+static
+u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
+ u32 mode_clock, u32 mode_hdisplay,
+ int num_joined_pipes)
+{
+ struct intel_display *display = to_intel_display(&i915->drm);
+ u32 max_bpp = small_joiner_ram_max_bpp(display, mode_hdisplay, num_joined_pipes);
- return max_bpp_small_joiner_ram;
+ if (num_joined_pipes > 1)
+ max_bpp = min(max_bpp, bigjoiner_bw_max_bpp(display, mode_clock,
+ num_joined_pipes));
+ if (num_joined_pipes == 4)
+ max_bpp = min(max_bpp, ultrajoiner_ram_max_bpp(mode_hdisplay));
+
+ return max_bpp;
}
u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
- bool bigjoiner,
+ int num_joined_pipes,
enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots)
@@ -940,7 +973,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
intel_dp_mode_to_fec_clock(mode_clock));
joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
- mode_hdisplay, bigjoiner);
+ mode_hdisplay, num_joined_pipes);
bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp);
@@ -950,7 +983,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
- bool bigjoiner)
+ int num_joined_pipes)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
u8 min_slice_count, i;
@@ -984,14 +1017,18 @@ u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
/* Find the closest match to the valid slice count values */
for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
- u8 test_slice_count = valid_dsc_slicecount[i] << bigjoiner;
+ u8 test_slice_count = valid_dsc_slicecount[i] * num_joined_pipes;
if (test_slice_count >
drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, false))
break;
- /* big joiner needs small joiner to be enabled */
- if (bigjoiner && test_slice_count < 4)
+ /*
+ * Bigjoiner needs small joiner to be enabled.
+ * So there should be at least 2 dsc slices per pipe,
+ * whenever bigjoiner is enabled.
+ */
+ if (num_joined_pipes > 1 && valid_dsc_slicecount[i] < 2)
continue;
if (min_slice_count <= test_slice_count)
@@ -1270,17 +1307,42 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
return MODE_OK;
}
-bool intel_dp_need_joiner(struct intel_dp *intel_dp,
- struct intel_connector *connector,
- int hdisplay, int clock)
+static
+bool intel_dp_needs_joiner(struct intel_dp *intel_dp,
+ struct intel_connector *connector,
+ int hdisplay, int clock,
+ int num_joined_pipes)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
if (!intel_dp_has_joiner(intel_dp))
return false;
- return clock > i915->display.cdclk.max_dotclk_freq || hdisplay > 5120 ||
- connector->force_bigjoiner_enable;
+ num_joined_pipes /= 2;
+
+ return clock > num_joined_pipes * i915->display.cdclk.max_dotclk_freq ||
+ hdisplay > num_joined_pipes * 5120;
+}
+
+int intel_dp_num_joined_pipes(struct intel_dp *intel_dp,
+ struct intel_connector *connector,
+ int hdisplay, int clock)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
+ if (connector->force_joined_pipes)
+ return connector->force_joined_pipes;
+
+ if (HAS_ULTRAJOINER(i915) &&
+ intel_dp_needs_joiner(intel_dp, connector, hdisplay, clock, 4))
+ return 4;
+
+ if ((HAS_BIGJOINER(i915) || HAS_UNCOMPRESSED_JOINER(i915)) &&
+ intel_dp_needs_joiner(intel_dp, connector, hdisplay, clock, 2))
+ return 2;
+
+ return 1;
}
bool intel_dp_has_dsc(const struct intel_connector *connector)
@@ -1317,7 +1379,8 @@ intel_dp_mode_valid(struct drm_connector *_connector,
u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
- bool dsc = false, joiner = false;
+ bool dsc = false;
+ int num_joined_pipes;
status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
if (status != MODE_OK)
@@ -1338,11 +1401,10 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock = fixed_mode->clock;
}
- if (intel_dp_need_joiner(intel_dp, connector,
- mode->hdisplay, target_clock)) {
- joiner = true;
- max_dotclk *= 2;
- }
+ num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector,
+ mode->hdisplay, target_clock);
+ max_dotclk *= num_joined_pipes;
+
if (target_clock > max_dotclk)
return MODE_CLOCK_HIGH;
@@ -1386,20 +1448,20 @@ intel_dp_mode_valid(struct drm_connector *_connector,
max_lanes,
target_clock,
mode->hdisplay,
- joiner,
+ num_joined_pipes,
output_format,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(connector,
target_clock,
mode->hdisplay,
- joiner);
+ num_joined_pipes);
}
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
- if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc)
+ if (intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes) && !dsc)
return MODE_CLOCK_HIGH;
if (mode_rate > max_rate && !dsc)
@@ -1409,7 +1471,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
if (status != MODE_OK)
return status;
- return intel_mode_valid_max_plane_size(dev_priv, mode, joiner);
+ return intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes);
}
bool intel_dp_source_supports_tps3(struct drm_i915_private *i915)
@@ -1632,45 +1694,6 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp,
return bpp;
}
-/* Adjust link config limits based on compliance test requests. */
-void
-intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
- struct intel_crtc_state *pipe_config,
- struct link_config_limits *limits)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-
- /* For DP Compliance we override the computed bpp for the pipe */
- if (intel_dp->compliance.test_data.bpc != 0) {
- int bpp = 3 * intel_dp->compliance.test_data.bpc;
-
- limits->pipe.min_bpp = limits->pipe.max_bpp = bpp;
- pipe_config->dither_force_disable = bpp == 6 * 3;
-
- drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp);
- }
-
- /* Use values requested by Compliance Test Request */
- if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
- int index;
-
- /* Validate the compliance test data since max values
- * might have changed due to link train fallback.
- */
- if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
- intel_dp->compliance.test_lane_count)) {
- index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- intel_dp->compliance.test_link_rate);
- if (index >= 0)
- limits->min_rate = limits->max_rate =
- intel_dp->compliance.test_link_rate;
- limits->min_lane_count = limits->max_lane_count =
- intel_dp->compliance.test_lane_count;
- }
- }
-}
-
static bool has_seamless_m_n(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
@@ -2109,6 +2132,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
int dsc_joiner_max_bpp;
+ int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config);
dsc_src_min_bpp = dsc_src_min_compressed_bpp();
dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config);
@@ -2123,7 +2147,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, adjusted_mode->clock,
adjusted_mode->hdisplay,
- pipe_config->joiner_pipes);
+ num_joined_pipes);
dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp);
dsc_max_bpp = min(dsc_max_bpp, fxp_q4_to_int(limits->link.max_bpp_x16));
@@ -2308,11 +2332,18 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
+ int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config);
int ret;
+ /*
+ * Though eDP v1.5 supports FEC with DSC, unlike DP, it is optional.
+ * Since, FEC is a bandwidth overhead, continue to not enable it for
+ * eDP. Until, there is a good reason to do so.
+ */
pipe_config->fec_enable = pipe_config->fec_enable ||
(!intel_dp_is_edp(intel_dp) &&
- intel_dp_supports_fec(intel_dp, connector, pipe_config));
+ intel_dp_supports_fec(intel_dp, connector, pipe_config) &&
+ !intel_dp_is_uhbr(pipe_config));
if (!intel_dp_supports_dsc(connector, pipe_config))
return -EINVAL;
@@ -2357,7 +2388,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
intel_dp_dsc_get_slice_count(connector,
adjusted_mode->crtc_clock,
adjusted_mode->crtc_hdisplay,
- pipe_config->joiner_pipes);
+ num_joined_pipes);
if (!dsc_dp_slice_count) {
drm_dbg_kms(&dev_priv->drm,
"Compressed Slice Count not supported\n");
@@ -2488,7 +2519,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
limits->min_rate = limits->max_rate;
}
- intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
+ intel_dp_test_compute_config(intel_dp, crtc_state, limits);
return intel_dp_compute_config_link_bpp_limits(intel_dp,
crtc_state,
@@ -2507,14 +2538,17 @@ int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state)
return intel_dp_link_required(adjusted_mode->crtc_clock, bpp);
}
-bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner)
+bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915,
+ int num_joined_pipes)
{
/*
* Pipe joiner needs compression up to display 12 due to bandwidth
* limitation. DG2 onwards pipe joiner can be enabled without
* compression.
+ * Ultrajoiner always needs compression.
*/
- return DISPLAY_VER(i915) < 13 && use_joiner;
+ return (!HAS_UNCOMPRESSED_JOINER(i915) && num_joined_pipes == 2) ||
+ num_joined_pipes == 4;
}
static int
@@ -2532,18 +2566,20 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct link_config_limits limits;
bool dsc_needed, joiner_needs_dsc;
+ int num_joined_pipes;
int ret = 0;
if (pipe_config->fec_enable &&
!intel_dp_supports_fec(intel_dp, connector, pipe_config))
return -EINVAL;
- if (intel_dp_need_joiner(intel_dp, connector,
- adjusted_mode->crtc_hdisplay,
- adjusted_mode->crtc_clock))
- pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
+ num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector,
+ adjusted_mode->crtc_hdisplay,
+ adjusted_mode->crtc_clock);
+ if (num_joined_pipes > 1)
+ pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe);
- joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, pipe_config->joiner_pipes);
+ joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, num_joined_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_compute_config_limits(intel_dp, pipe_config,
@@ -2742,7 +2778,6 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
as_sdp->duration_incr_ms = 0;
- as_sdp->duration_incr_ms = 0;
if (crtc_state->cmrr.enable) {
as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED;
@@ -3900,7 +3935,7 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
str_enable_disable(tmp));
}
-bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
+static bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
{
u8 dprx = 0;
@@ -4051,6 +4086,45 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
intel_dp->mso_pixel_overlap = mso ? info->mso_pixel_overlap : 0;
}
+static void
+intel_edp_set_sink_rates(struct intel_dp *intel_dp)
+{
+ intel_dp->num_sink_rates = 0;
+
+ if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
+ __le16 sink_rates[DP_MAX_SUPPORTED_RATES];
+ int i;
+
+ drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
+ sink_rates, sizeof(sink_rates));
+
+ for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
+ int val = le16_to_cpu(sink_rates[i]);
+
+ if (val == 0)
+ break;
+
+ /* Value read multiplied by 200kHz gives the per-lane
+ * link rate in kHz. The source rates are, however,
+ * stored in terms of LS_Clk kHz. The full conversion
+ * back to symbols is
+ * (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte)
+ */
+ intel_dp->sink_rates[i] = (val * 200) / 10;
+ }
+ intel_dp->num_sink_rates = i;
+ }
+
+ /*
+ * Use DP_LINK_RATE_SET if DP_SUPPORTED_LINK_RATES are available,
+ * default to DP_MAX_LINK_RATE and DP_LINK_BW_SET otherwise.
+ */
+ if (intel_dp->num_sink_rates)
+ intel_dp->use_rate_select = true;
+ else
+ intel_dp_set_sink_rates(intel_dp);
+}
+
static bool
intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
{
@@ -4095,42 +4169,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
*/
intel_psr_init_dpcd(intel_dp);
- /* Clear the default sink rates */
- intel_dp->num_sink_rates = 0;
-
- /* Read the eDP 1.4+ supported link rates. */
- if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
- __le16 sink_rates[DP_MAX_SUPPORTED_RATES];
- int i;
-
- drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
- sink_rates, sizeof(sink_rates));
-
- for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
- int val = le16_to_cpu(sink_rates[i]);
-
- if (val == 0)
- break;
-
- /* Value read multiplied by 200kHz gives the per-lane
- * link rate in kHz. The source rates are, however,
- * stored in terms of LS_Clk kHz. The full conversion
- * back to symbols is
- * (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte)
- */
- intel_dp->sink_rates[i] = (val * 200) / 10;
- }
- intel_dp->num_sink_rates = i;
- }
-
- /*
- * Use DP_LINK_RATE_SET if DP_SUPPORTED_LINK_RATES are available,
- * default to DP_MAX_LINK_RATE and DP_LINK_BW_SET otherwise.
- */
- if (intel_dp->num_sink_rates)
- intel_dp->use_rate_select = true;
- else
- intel_dp_set_sink_rates(intel_dp);
+ intel_edp_set_sink_rates(intel_dp);
intel_dp_set_max_sink_lane_count(intel_dp);
/* Read the eDP DSC DPCD registers */
@@ -4771,328 +4810,6 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
}
}
-static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int status = 0;
- int test_link_rate;
- u8 test_lane_count, test_link_bw;
- /* (DP CTS 1.2)
- * 4.3.1.11
- */
- /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */
- status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT,
- &test_lane_count);
-
- if (status <= 0) {
- drm_dbg_kms(&i915->drm, "Lane count read failed\n");
- return DP_TEST_NAK;
- }
- test_lane_count &= DP_MAX_LANE_COUNT_MASK;
-
- status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
- &test_link_bw);
- if (status <= 0) {
- drm_dbg_kms(&i915->drm, "Link Rate read failed\n");
- return DP_TEST_NAK;
- }
- test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
-
- /* Validate the requested link rate and lane count */
- if (!intel_dp_link_params_valid(intel_dp, test_link_rate,
- test_lane_count))
- return DP_TEST_NAK;
-
- intel_dp->compliance.test_lane_count = test_lane_count;
- intel_dp->compliance.test_link_rate = test_link_rate;
-
- return DP_TEST_ACK;
-}
-
-static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 test_pattern;
- u8 test_misc;
- __be16 h_width, v_height;
- int status = 0;
-
- /* Read the TEST_PATTERN (DP CTS 3.1.5) */
- status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN,
- &test_pattern);
- if (status <= 0) {
- drm_dbg_kms(&i915->drm, "Test pattern read failed\n");
- return DP_TEST_NAK;
- }
- if (test_pattern != DP_COLOR_RAMP)
- return DP_TEST_NAK;
-
- status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI,
- &h_width, 2);
- if (status <= 0) {
- drm_dbg_kms(&i915->drm, "H Width read failed\n");
- return DP_TEST_NAK;
- }
-
- status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
- &v_height, 2);
- if (status <= 0) {
- drm_dbg_kms(&i915->drm, "V Height read failed\n");
- return DP_TEST_NAK;
- }
-
- status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0,
- &test_misc);
- if (status <= 0) {
- drm_dbg_kms(&i915->drm, "TEST MISC read failed\n");
- return DP_TEST_NAK;
- }
- if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB)
- return DP_TEST_NAK;
- if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA)
- return DP_TEST_NAK;
- switch (test_misc & DP_TEST_BIT_DEPTH_MASK) {
- case DP_TEST_BIT_DEPTH_6:
- intel_dp->compliance.test_data.bpc = 6;
- break;
- case DP_TEST_BIT_DEPTH_8:
- intel_dp->compliance.test_data.bpc = 8;
- break;
- default:
- return DP_TEST_NAK;
- }
-
- intel_dp->compliance.test_data.video_pattern = test_pattern;
- intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width);
- intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height);
- /* Set test active flag here so userspace doesn't interrupt things */
- intel_dp->compliance.test_active = true;
-
- return DP_TEST_ACK;
-}
-
-static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 test_result = DP_TEST_ACK;
- struct intel_connector *intel_connector = intel_dp->attached_connector;
- struct drm_connector *connector = &intel_connector->base;
-
- if (intel_connector->detect_edid == NULL ||
- connector->edid_corrupt ||
- intel_dp->aux.i2c_defer_count > 6) {
- /* Check EDID read for NACKs, DEFERs and corruption
- * (DP CTS 1.2 Core r1.1)
- * 4.2.2.4 : Failed EDID read, I2C_NAK
- * 4.2.2.5 : Failed EDID read, I2C_DEFER
- * 4.2.2.6 : EDID corruption detected
- * Use failsafe mode for all cases
- */
- if (intel_dp->aux.i2c_nack_count > 0 ||
- intel_dp->aux.i2c_defer_count > 0)
- drm_dbg_kms(&i915->drm,
- "EDID read had %d NACKs, %d DEFERs\n",
- intel_dp->aux.i2c_nack_count,
- intel_dp->aux.i2c_defer_count);
- intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
- } else {
- /* FIXME: Get rid of drm_edid_raw() */
- const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
-
- /* We have to write the checksum of the last block read */
- block += block->extensions;
-
- if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
- block->checksum) <= 0)
- drm_dbg_kms(&i915->drm,
- "Failed to write EDID checksum\n");
-
- test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE;
- intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED;
- }
-
- /* Set test active flag here so userspace doesn't interrupt things */
- intel_dp->compliance.test_active = true;
-
- return test_result;
-}
-
-static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *dev_priv =
- to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
- struct drm_dp_phy_test_params *data =
- &intel_dp->compliance.test_data.phytest;
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
- enum pipe pipe = crtc->pipe;
- u32 pattern_val;
-
- switch (data->phy_pattern) {
- case DP_LINK_QUAL_PATTERN_DISABLE:
- drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n");
- intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0);
- if (DISPLAY_VER(dev_priv) >= 10)
- intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state),
- DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK,
- DP_TP_CTL_LINK_TRAIN_NORMAL);
- break;
- case DP_LINK_QUAL_PATTERN_D10_2:
- 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_LINK_QUAL_PATTERN_ERROR_RATE:
- 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_LINK_QUAL_PATTERN_PRBS7:
- 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;
- case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM:
- /*
- * FIXME: Ideally pattern should come from DPCD 0x250. As
- * current firmware of DPR-100 could not set it, so hardcoding
- * now for complaince test.
- */
- 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;
- intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 1), pattern_val);
- pattern_val = 0x0000f83e;
- intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 2), pattern_val);
- intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
- DDI_DP_COMP_CTL_ENABLE |
- DDI_DP_COMP_CTL_CUSTOM80);
- break;
- case DP_LINK_QUAL_PATTERN_CP2520_PAT_1:
- /*
- * FIXME: Ideally pattern should come from DPCD 0x24A. As
- * current firmware of DPR-100 could not set it, so hardcoding
- * now for complaince test.
- */
- 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 |
- pattern_val);
- break;
- case DP_LINK_QUAL_PATTERN_CP2520_PAT_3:
- if (DISPLAY_VER(dev_priv) < 10) {
- drm_warn(&dev_priv->drm, "Platform does not support TPS4\n");
- break;
- }
- drm_dbg_kms(&dev_priv->drm, "Set TPS4 compliance Phy Test Pattern\n");
- intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0);
- intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state),
- DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK,
- DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4);
- break;
- default:
- drm_warn(&dev_priv->drm, "Invalid Phy Test Pattern\n");
- }
-}
-
-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_dbg_kms(&i915->drm, "failed to get link status\n");
- return;
- }
-
- /* retrieve vswing & pre-emphasis setting */
- intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
- link_status);
-
- intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX);
-
- intel_dp_phy_pattern_update(intel_dp, crtc_state);
-
- drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
- intel_dp->train_set, crtc_state->lane_count);
-
- drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
- intel_dp->dpcd[DP_DPCD_REV]);
-}
-
-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_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n");
- return DP_TEST_NAK;
- }
-
- /* Set test active flag here so userspace doesn't interrupt things */
- intel_dp->compliance.test_active = true;
-
- return DP_TEST_ACK;
-}
-
-static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 response = DP_TEST_NAK;
- u8 request = 0;
- int status;
-
- status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request);
- if (status <= 0) {
- drm_dbg_kms(&i915->drm,
- "Could not read test request from sink\n");
- goto update_status;
- }
-
- switch (request) {
- case DP_TEST_LINK_TRAINING:
- drm_dbg_kms(&i915->drm, "LINK_TRAINING test requested\n");
- response = intel_dp_autotest_link_training(intel_dp);
- break;
- case DP_TEST_LINK_VIDEO_PATTERN:
- drm_dbg_kms(&i915->drm, "TEST_PATTERN test requested\n");
- response = intel_dp_autotest_video_pattern(intel_dp);
- break;
- case DP_TEST_LINK_EDID_READ:
- drm_dbg_kms(&i915->drm, "EDID test requested\n");
- response = intel_dp_autotest_edid(intel_dp);
- break;
- case DP_TEST_LINK_PHY_TEST_PATTERN:
- drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n");
- response = intel_dp_autotest_phy_pattern(intel_dp);
- break;
- default:
- drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n",
- request);
- break;
- }
-
- if (response & DP_TEST_ACK)
- intel_dp->compliance.test_type = request;
-
-update_status:
- status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response);
- if (status <= 0)
- drm_dbg_kms(&i915->drm,
- "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])
{
@@ -5293,8 +5010,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
return !intel_dp_link_ok(intel_dp, link_status);
}
-static bool intel_dp_has_connector(struct intel_dp *intel_dp,
- const struct drm_connector_state *conn_state)
+bool intel_dp_has_connector(struct intel_dp *intel_dp,
+ const struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_encoder *encoder;
@@ -5445,118 +5162,6 @@ void intel_dp_check_link_state(struct intel_dp *intel_dp)
intel_encoder_link_check_queue_work(encoder, 0);
}
-static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
- struct drm_modeset_acquire_ctx *ctx,
- 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;
-
- *pipe_mask = 0;
-
- drm_connector_list_iter_begin(&i915->drm, &conn_iter);
- for_each_intel_connector_iter(connector, &conn_iter) {
- struct drm_connector_state *conn_state =
- connector->base.state;
- struct intel_crtc_state *crtc_state;
- struct intel_crtc *crtc;
-
- if (!intel_dp_has_connector(intel_dp, conn_state))
- continue;
-
- crtc = to_intel_crtc(conn_state->crtc);
- if (!crtc)
- continue;
-
- ret = drm_modeset_lock(&crtc->base.mutex, ctx);
- if (ret)
- break;
-
- crtc_state = to_intel_crtc_state(crtc->base.state);
-
- drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state));
-
- if (!crtc_state->hw.active)
- continue;
-
- if (conn_state->commit &&
- !try_wait_for_completion(&conn_state->commit->hw_done))
- continue;
-
- *pipe_mask |= BIT(crtc->pipe);
- }
- drm_connector_list_iter_end(&conn_iter);
-
- return ret;
-}
-
-static int intel_dp_do_phy_test(struct intel_encoder *encoder,
- struct drm_modeset_acquire_ctx *ctx)
-{
- 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;
- u8 pipe_mask;
- int ret;
-
- ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
- ctx);
- if (ret)
- return ret;
-
- ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask);
- if (ret)
- return ret;
-
- 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_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
- const struct intel_crtc_state *crtc_state =
- to_intel_crtc_state(crtc->base.state);
-
- /* test on the MST master transcoder */
- if (DISPLAY_VER(dev_priv) >= 12 &&
- intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
- !intel_dp_mst_is_master_trans(crtc_state))
- continue;
-
- intel_dp_process_phy_request(intel_dp, crtc_state);
- break;
- }
-
- return 0;
-}
-
-void intel_dp_phy_test(struct intel_encoder *encoder)
-{
- struct drm_modeset_acquire_ctx ctx;
- int ret;
-
- drm_modeset_acquire_init(&ctx, 0);
-
- for (;;) {
- ret = intel_dp_do_phy_test(encoder, &ctx);
-
- if (ret == -EDEADLK) {
- drm_modeset_backoff(&ctx);
- continue;
- }
-
- break;
- }
-
- drm_modeset_drop_locks(&ctx);
- drm_modeset_acquire_fini(&ctx);
- drm_WARN(encoder->base.dev, ret,
- "Acquiring modeset locks failed with %i\n", ret);
-}
-
static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -5572,7 +5177,7 @@ static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
drm_dp_dpcd_writeb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val);
if (val & DP_AUTOMATED_TEST_REQUEST)
- intel_dp_handle_test_request(intel_dp);
+ intel_dp_test_request(intel_dp);
if (val & DP_CP_IRQ)
intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
@@ -5625,16 +5230,11 @@ static bool intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
static bool
intel_dp_short_pulse(struct intel_dp *intel_dp)
{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u8 old_sink_count = intel_dp->sink_count;
bool reprobe_needed = false;
bool ret;
- /*
- * Clearing compliance test variables to allow capturing
- * of values for next automated test request.
- */
- memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
+ intel_dp_test_reset(intel_dp);
/*
* Now read the DPCD to see if it's actually running
@@ -5659,24 +5259,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
intel_psr_short_pulse(intel_dp);
- switch (intel_dp->compliance.test_type) {
- case DP_TEST_LINK_TRAINING:
- drm_dbg_kms(&dev_priv->drm,
- "Link Training Compliance Test requested\n");
- /* Send a Hotplug Uevent to userspace to start modeset */
- drm_kms_helper_hotplug_event(&dev_priv->drm);
- break;
- case DP_TEST_LINK_PHY_TEST_PATTERN:
- drm_dbg_kms(&dev_priv->drm,
- "PHY test pattern Compliance Test requested\n");
- /*
- * Schedule long hpd to do the test
- *
- * FIXME get rid of the ad-hoc phy test modeset code
- * and properly incorporate it into the normal modeset.
- */
+ if (intel_dp_test_short_pulse(intel_dp))
reprobe_needed = true;
- }
return !reprobe_needed;
}
@@ -6033,7 +5617,7 @@ intel_dp_detect(struct drm_connector *connector,
status = connector_status_disconnected;
if (status == connector_status_disconnected) {
- memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
+ intel_dp_test_reset(intel_dp);
memset(intel_connector->dp.dsc_dpcd, 0, sizeof(intel_connector->dp.dsc_dpcd));
intel_dp->psr.sink_panel_replay_support = false;
intel_dp->psr.sink_panel_replay_su_support = false;
@@ -6471,7 +6055,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
u8 dpcd[DP_RECEIVER_CAP_SIZE];
if (dig_port->base.type == INTEL_OUTPUT_EDP &&
- (long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) {
+ (long_hpd ||
+ intel_runtime_pm_suspended(&i915->runtime_pm) ||
+ !intel_pps_have_panel_power_or_vdd(intel_dp))) {
/*
* vdd off can generate a long/short pulse on eDP which
* would require vdd on to handle it, and thus we
@@ -6620,20 +6206,8 @@ static void intel_edp_backlight_setup(struct intel_dp *intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
enum pipe pipe = INVALID_PIPE;
- if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
- /*
- * Figure out the current pipe for the initial backlight setup.
- * If the current pipe isn't valid, try the PPS pipe, and if that
- * fails just assume pipe A.
- */
- pipe = vlv_active_pipe(intel_dp);
-
- if (pipe != PIPE_A && pipe != PIPE_B)
- pipe = intel_dp->pps.pps_pipe;
-
- if (pipe != PIPE_A && pipe != PIPE_B)
- pipe = PIPE_A;
- }
+ if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
+ pipe = vlv_pps_backlight_initial_pipe(intel_dp);
intel_backlight_setup(connector, pipe);
}
@@ -6858,8 +6432,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
return false;
intel_dp->reset_link_params = true;
- intel_dp->pps.pps_pipe = INVALID_PIPE;
- intel_dp->pps.active_pipe = INVALID_PIPE;
/* Preserve the current hw state. */
intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg);
@@ -6887,7 +6459,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_dp_set_default_max_sink_lane_count(intel_dp);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
+ vlv_pps_pipe_init(intel_dp);
intel_dp_aux_init(intel_dp);
intel_connector->dp.dsc_decompression_aux = &intel_dp->aux;
@@ -6904,7 +6476,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
if (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) < 12)
connector->interlace_allowed = true;
- intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
+ if (type != DRM_MODE_CONNECTOR_eDP)
+ intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
intel_connector->base.polled = intel_connector->polled;
intel_connector_attach_encoder(intel_connector, intel_encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 1b9aaddd8c35..60baf4072dc9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -37,9 +37,6 @@ struct link_config_limits {
};
void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
-void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
- struct intel_crtc_state *pipe_config,
- struct link_config_limits *limits);
bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
int intel_dp_min_bpp(enum intel_output_format output_format);
@@ -117,13 +114,13 @@ void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
bool intel_dp_source_supports_tps3(struct drm_i915_private *i915);
bool intel_dp_source_supports_tps4(struct drm_i915_private *i915);
-bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
int intel_dp_link_required(int pixel_clock, int bpp);
int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
int bw_overhead);
int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
int max_dprx_rate, int max_dprx_lanes);
-bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner);
+bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915,
+ int num_joined_pipes);
bool intel_dp_has_joiner(struct intel_dp *intel_dp);
bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
@@ -142,7 +139,7 @@ int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector,
u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
- bool bigjoiner,
+ int num_joined_pipes,
enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots);
@@ -152,10 +149,10 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector
int bpc);
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
- bool bigjoiner);
-bool intel_dp_need_joiner(struct intel_dp *intel_dp,
- struct intel_connector *connector,
- int hdisplay, int clock);
+ int num_joined_pipes);
+int intel_dp_num_joined_pipes(struct intel_dp *intel_dp,
+ struct intel_connector *connector,
+ int hdisplay, int clock);
static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
{
@@ -190,7 +187,6 @@ void intel_dp_sync_state(struct intel_encoder *encoder,
void intel_dp_check_frl_training(struct intel_dp *intel_dp);
void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
-void intel_dp_phy_test(struct intel_encoder *encoder);
void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
@@ -204,4 +200,9 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector);
bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder);
+bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
+ u8 lane_count);
+bool intel_dp_has_connector(struct intel_dp *intel_dp,
+ const struct drm_connector_state *conn_state);
+
#endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 3425b3643143..dce645a07cdb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -19,6 +19,7 @@
#include "intel_dp_hdcp.h"
#include "intel_hdcp.h"
#include "intel_hdcp_regs.h"
+#include "intel_hdcp_shim.h"
static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
{
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 40bedc31d6bf..397cc4ebae52 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -21,6 +21,8 @@
* IN THE SOFTWARE.
*/
+#include <linux/debugfs.h>
+
#include <drm/display/drm_dp_helper.h>
#include "i915_drv.h"
@@ -208,8 +210,10 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd);
- for (i = 0; i < lttpr_count; i++)
+ for (i = 0; i < lttpr_count; i++) {
intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i));
+ drm_dp_dump_lttpr_desc(&intel_dp->aux, DP_PHY_LTTPR(i));
+ }
return lttpr_count;
}
@@ -1677,19 +1681,11 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
lt_dbg(intel_dp, DP_PHY_DPRX, "DP2.0 SDP CRC16 for 128b/132b enabled\n");
}
-static struct intel_dp *intel_connector_to_intel_dp(struct intel_connector *connector)
-{
- if (connector->mst_port)
- return connector->mst_port;
- else
- return enc_to_intel_dp(intel_attached_encoder(connector));
-}
-
static int i915_dp_force_link_rate_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = to_intel_connector(m->private);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int current_rate = -1;
int force_rate;
int err;
@@ -1760,7 +1756,7 @@ static ssize_t i915_dp_force_link_rate_write(struct file *file,
struct seq_file *m = file->private_data;
struct intel_connector *connector = to_intel_connector(m->private);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int rate;
int err;
@@ -1787,7 +1783,7 @@ static int i915_dp_force_lane_count_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = to_intel_connector(m->private);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int current_lane_count = -1;
int force_lane_count;
int err;
@@ -1862,7 +1858,7 @@ static ssize_t i915_dp_force_lane_count_write(struct file *file,
struct seq_file *m = file->private_data;
struct intel_connector *connector = to_intel_connector(m->private);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int lane_count;
int err;
@@ -1889,7 +1885,7 @@ static int i915_dp_max_link_rate_show(void *data, u64 *val)
{
struct intel_connector *connector = to_intel_connector(data);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
@@ -1908,7 +1904,7 @@ static int i915_dp_max_lane_count_show(void *data, u64 *val)
{
struct intel_connector *connector = to_intel_connector(data);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
@@ -1927,7 +1923,7 @@ static int i915_dp_force_link_training_failure_show(void *data, u64 *val)
{
struct intel_connector *connector = to_intel_connector(data);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
@@ -1945,7 +1941,7 @@ static int i915_dp_force_link_training_failure_write(void *data, u64 val)
{
struct intel_connector *connector = to_intel_connector(data);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
if (val > 2)
@@ -1969,7 +1965,7 @@ static int i915_dp_force_link_retrain_show(void *data, u64 *val)
{
struct intel_connector *connector = to_intel_connector(data);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
@@ -1987,7 +1983,7 @@ static int i915_dp_force_link_retrain_write(void *data, u64 val)
{
struct intel_connector *connector = to_intel_connector(data);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
@@ -2010,7 +2006,7 @@ static int i915_dp_link_retrain_disabled_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = to_intel_connector(m->private);
struct intel_display *display = to_intel_display(connector);
- struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
int err;
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 15541932b809..1a2ff3e1cb68 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -41,9 +41,10 @@
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_hdcp.h"
+#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
+#include "intel_dp_test.h"
#include "intel_dp_tunnel.h"
-#include "intel_dp_link_training.h"
#include "intel_dpio_phy.h"
#include "intel_hdcp.h"
#include "intel_hotplug.h"
@@ -89,25 +90,19 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state,
static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state,
const struct intel_connector *connector,
- bool ssc, bool dsc, int bpp_x16)
+ bool ssc, int dsc_slice_count, int bpp_x16)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
unsigned long flags = DRM_DP_BW_OVERHEAD_MST;
- int dsc_slice_count = 0;
int overhead;
flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0;
flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0;
flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0;
- if (dsc) {
+ if (dsc_slice_count)
flags |= DRM_DP_BW_OVERHEAD_DSC;
- dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
- adjusted_mode->clock,
- adjusted_mode->hdisplay,
- crtc_state->joiner_pipes);
- }
overhead = drm_dp_bw_overhead(crtc_state->lane_count,
adjusted_mode->hdisplay,
@@ -153,6 +148,19 @@ static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead)
return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000);
}
+static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state)
+{
+ const struct drm_display_mode *adjusted_mode =
+ &crtc_state->hw.adjusted_mode;
+ int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state);
+
+ return intel_dp_dsc_get_slice_count(connector,
+ adjusted_mode->clock,
+ adjusted_mode->hdisplay,
+ num_joined_pipes);
+}
+
static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
int max_bpp,
@@ -172,6 +180,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int bpp, slots = -EINVAL;
+ int dsc_slice_count = 0;
int max_dpt_bpp;
int ret = 0;
@@ -203,6 +212,15 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n",
min_bpp, max_bpp);
+ if (dsc) {
+ dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state);
+ if (!dsc_slice_count) {
+ drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n");
+
+ return -ENOSPC;
+ }
+ }
+
for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
int local_bw_overhead;
int remote_bw_overhead;
@@ -216,9 +234,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
intel_dp_output_bpp(crtc_state->output_format, bpp));
local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector,
- false, dsc, link_bpp_x16);
+ false, dsc_slice_count, link_bpp_x16);
remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector,
- true, dsc, link_bpp_x16);
+ true, dsc_slice_count, link_bpp_x16);
intel_dp_mst_compute_m_n(crtc_state, connector,
local_bw_overhead,
@@ -449,6 +467,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
if (mode_hblank_period_ns(adjusted_mode) > hblank_limit)
return false;
+ if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state))
+ return false;
+
return true;
}
@@ -539,7 +560,7 @@ intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
*/
limits->pipe.max_bpp = min(crtc_state->pipe_bpp, 24);
- intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
+ intel_dp_test_compute_config(intel_dp, crtc_state, limits);
if (!intel_dp_compute_config_link_bpp_limits(intel_dp,
crtc_state,
@@ -568,6 +589,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
&pipe_config->hw.adjusted_mode;
struct link_config_limits limits;
bool dsc_needed, joiner_needs_dsc;
+ int num_joined_pipes;
int ret = 0;
if (pipe_config->fec_enable &&
@@ -577,16 +599,17 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
- if (intel_dp_need_joiner(intel_dp, connector,
- adjusted_mode->crtc_hdisplay,
- adjusted_mode->crtc_clock))
- pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
+ num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector,
+ adjusted_mode->crtc_hdisplay,
+ adjusted_mode->crtc_clock);
+ if (num_joined_pipes > 1)
+ pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe);
pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->has_pch_encoder = false;
- joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, pipe_config->joiner_pipes);
+ joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_mst_compute_config_limits(intel_dp,
@@ -985,6 +1008,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
+ struct intel_display *display = to_intel_display(encoder);
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
struct intel_digital_port *dig_port = intel_mst->primary;
struct intel_dp *intel_dp = &dig_port->dp;
@@ -1001,6 +1025,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_crtc *pipe_crtc;
bool last_mst_stream;
+ int i;
intel_dp->active_mst_links--;
last_mst_stream = intel_dp->active_mst_links == 0;
@@ -1008,8 +1033,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
DISPLAY_VER(dev_priv) >= 12 && last_mst_stream &&
!intel_dp_mst_is_master_trans(old_crtc_state));
- for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(old_crtc_state)) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -1033,8 +1057,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
intel_ddi_disable_transcoder_func(old_crtc_state);
- for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(old_crtc_state)) {
+ for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) {
const struct intel_crtc_state *old_pipe_crtc_state =
intel_atomic_get_old_crtc_state(state, pipe_crtc);
@@ -1243,6 +1266,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
const struct intel_crtc_state *pipe_config,
const struct drm_connector_state *conn_state)
{
+ struct intel_display *display = to_intel_display(encoder);
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
struct intel_digital_port *dig_port = intel_mst->primary;
struct intel_dp *intel_dp = &dig_port->dp;
@@ -1253,7 +1277,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
enum transcoder trans = pipe_config->cpu_transcoder;
bool first_mst_stream = intel_dp->active_mst_links == 1;
struct intel_crtc *pipe_crtc;
- int ret;
+ int ret, i;
drm_WARN_ON(&dev_priv->drm, pipe_config->has_pch_encoder);
@@ -1300,8 +1324,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
intel_enable_transcoder(pipe_config);
- for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc,
- intel_crtc_joined_pipe_mask(pipe_config)) {
+ for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config, i) {
const struct intel_crtc_state *pipe_crtc_state =
intel_atomic_get_new_crtc_state(state, pipe_crtc);
@@ -1422,10 +1445,11 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq;
int max_rate, mode_rate, max_lanes, max_link_clock;
int ret;
- bool dsc = false, joiner = false;
+ bool dsc = false;
u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
int target_clock = mode->clock;
+ int num_joined_pipes;
if (drm_connector_is_unregistered(connector)) {
*status = MODE_ERROR;
@@ -1465,11 +1489,9 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
* corresponding link capabilities of the sink) in case the
* stream is uncompressed for it by the last branch device.
*/
- if (intel_dp_need_joiner(intel_dp, intel_connector,
- mode->hdisplay, target_clock)) {
- joiner = true;
- max_dotclk *= 2;
- }
+ num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, intel_connector,
+ mode->hdisplay, target_clock);
+ max_dotclk *= num_joined_pipes;
ret = drm_modeset_lock(&mgr->base.lock, ctx);
if (ret)
@@ -1495,20 +1517,20 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
max_lanes,
target_clock,
mode->hdisplay,
- joiner,
+ num_joined_pipes,
INTEL_OUTPUT_FORMAT_RGB,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_connector,
target_clock,
mode->hdisplay,
- joiner);
+ num_joined_pipes);
}
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
- if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc) {
+ if (intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes) && !dsc) {
*status = MODE_CLOCK_HIGH;
return 0;
}
@@ -1518,7 +1540,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
return 0;
}
- *status = intel_mode_valid_max_plane_size(dev_priv, mode, joiner);
+ *status = intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes);
return 0;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c
new file mode 100644
index 000000000000..e05819300d77
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_test.c
@@ -0,0 +1,765 @@
+// SPDX-License-Identifier: MIT
+/* Copyright © 2024 Intel Corporation */
+
+#include <linux/debugfs.h>
+
+#include <drm/display/drm_dp.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_probe_helper.h>
+
+#include "i915_drv.h"
+#include "i915_reg.h"
+#include "intel_ddi.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_dp_link_training.h"
+#include "intel_dp_mst.h"
+#include "intel_dp_test.h"
+
+void intel_dp_test_reset(struct intel_dp *intel_dp)
+{
+ /*
+ * Clearing compliance test variables to allow capturing
+ * of values for next automated test request.
+ */
+ memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
+}
+
+/* Adjust link config limits based on compliance test requests. */
+void intel_dp_test_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+
+ /* For DP Compliance we override the computed bpp for the pipe */
+ if (intel_dp->compliance.test_data.bpc != 0) {
+ int bpp = 3 * intel_dp->compliance.test_data.bpc;
+
+ limits->pipe.min_bpp = bpp;
+ limits->pipe.max_bpp = bpp;
+ pipe_config->dither_force_disable = bpp == 6 * 3;
+
+ drm_dbg_kms(display->drm, "Setting pipe_bpp to %d\n", bpp);
+ }
+
+ /* Use values requested by Compliance Test Request */
+ if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
+ int index;
+
+ /* Validate the compliance test data since max values
+ * might have changed due to link train fallback.
+ */
+ if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
+ intel_dp->compliance.test_lane_count)) {
+ index = intel_dp_rate_index(intel_dp->common_rates,
+ intel_dp->num_common_rates,
+ intel_dp->compliance.test_link_rate);
+ if (index >= 0) {
+ limits->min_rate = intel_dp->compliance.test_link_rate;
+ limits->max_rate = intel_dp->compliance.test_link_rate;
+ }
+ limits->min_lane_count = intel_dp->compliance.test_lane_count;
+ limits->max_lane_count = intel_dp->compliance.test_lane_count;
+ }
+ }
+}
+
+/* Compliance test status bits */
+#define INTEL_DP_RESOLUTION_PREFERRED 1
+#define INTEL_DP_RESOLUTION_STANDARD 2
+#define INTEL_DP_RESOLUTION_FAILSAFE 3
+
+static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ int status = 0;
+ int test_link_rate;
+ u8 test_lane_count, test_link_bw;
+ /* (DP CTS 1.2)
+ * 4.3.1.11
+ */
+ /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */
+ status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT,
+ &test_lane_count);
+
+ if (status <= 0) {
+ drm_dbg_kms(display->drm, "Lane count read failed\n");
+ return DP_TEST_NAK;
+ }
+ test_lane_count &= DP_MAX_LANE_COUNT_MASK;
+
+ status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
+ &test_link_bw);
+ if (status <= 0) {
+ drm_dbg_kms(display->drm, "Link Rate read failed\n");
+ return DP_TEST_NAK;
+ }
+ test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
+
+ /* Validate the requested link rate and lane count */
+ if (!intel_dp_link_params_valid(intel_dp, test_link_rate,
+ test_lane_count))
+ return DP_TEST_NAK;
+
+ intel_dp->compliance.test_lane_count = test_lane_count;
+ intel_dp->compliance.test_link_rate = test_link_rate;
+
+ return DP_TEST_ACK;
+}
+
+static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u8 test_pattern;
+ u8 test_misc;
+ __be16 h_width, v_height;
+ int status = 0;
+
+ /* Read the TEST_PATTERN (DP CTS 3.1.5) */
+ status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN,
+ &test_pattern);
+ if (status <= 0) {
+ drm_dbg_kms(display->drm, "Test pattern read failed\n");
+ return DP_TEST_NAK;
+ }
+ if (test_pattern != DP_COLOR_RAMP)
+ return DP_TEST_NAK;
+
+ status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI,
+ &h_width, 2);
+ if (status <= 0) {
+ drm_dbg_kms(display->drm, "H Width read failed\n");
+ return DP_TEST_NAK;
+ }
+
+ status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
+ &v_height, 2);
+ if (status <= 0) {
+ drm_dbg_kms(display->drm, "V Height read failed\n");
+ return DP_TEST_NAK;
+ }
+
+ status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0,
+ &test_misc);
+ if (status <= 0) {
+ drm_dbg_kms(display->drm, "TEST MISC read failed\n");
+ return DP_TEST_NAK;
+ }
+ if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB)
+ return DP_TEST_NAK;
+ if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA)
+ return DP_TEST_NAK;
+ switch (test_misc & DP_TEST_BIT_DEPTH_MASK) {
+ case DP_TEST_BIT_DEPTH_6:
+ intel_dp->compliance.test_data.bpc = 6;
+ break;
+ case DP_TEST_BIT_DEPTH_8:
+ intel_dp->compliance.test_data.bpc = 8;
+ break;
+ default:
+ return DP_TEST_NAK;
+ }
+
+ intel_dp->compliance.test_data.video_pattern = test_pattern;
+ intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width);
+ intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height);
+ /* Set test active flag here so userspace doesn't interrupt things */
+ intel_dp->compliance.test_active = true;
+
+ return DP_TEST_ACK;
+}
+
+static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u8 test_result = DP_TEST_ACK;
+ struct intel_connector *intel_connector = intel_dp->attached_connector;
+ struct drm_connector *connector = &intel_connector->base;
+
+ if (!intel_connector->detect_edid || connector->edid_corrupt ||
+ intel_dp->aux.i2c_defer_count > 6) {
+ /* Check EDID read for NACKs, DEFERs and corruption
+ * (DP CTS 1.2 Core r1.1)
+ * 4.2.2.4 : Failed EDID read, I2C_NAK
+ * 4.2.2.5 : Failed EDID read, I2C_DEFER
+ * 4.2.2.6 : EDID corruption detected
+ * Use failsafe mode for all cases
+ */
+ if (intel_dp->aux.i2c_nack_count > 0 ||
+ intel_dp->aux.i2c_defer_count > 0)
+ drm_dbg_kms(display->drm,
+ "EDID read had %d NACKs, %d DEFERs\n",
+ intel_dp->aux.i2c_nack_count,
+ intel_dp->aux.i2c_defer_count);
+ intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE;
+ } else {
+ /* FIXME: Get rid of drm_edid_raw() */
+ const struct edid *block = drm_edid_raw(intel_connector->detect_edid);
+
+ /* We have to write the checksum of the last block read */
+ block += block->extensions;
+
+ if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM,
+ block->checksum) <= 0)
+ drm_dbg_kms(display->drm,
+ "Failed to write EDID checksum\n");
+
+ test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE;
+ intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED;
+ }
+
+ /* Set test active flag here so userspace doesn't interrupt things */
+ intel_dp->compliance.test_active = true;
+
+ return test_result;
+}
+
+static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ struct drm_dp_phy_test_params *data =
+ &intel_dp->compliance.test_data.phytest;
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ enum pipe pipe = crtc->pipe;
+ u32 pattern_val;
+
+ switch (data->phy_pattern) {
+ case DP_LINK_QUAL_PATTERN_DISABLE:
+ drm_dbg_kms(display->drm, "Disable Phy Test Pattern\n");
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0);
+ if (DISPLAY_VER(display) >= 10)
+ intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
+ DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK,
+ DP_TP_CTL_LINK_TRAIN_NORMAL);
+ break;
+ case DP_LINK_QUAL_PATTERN_D10_2:
+ drm_dbg_kms(display->drm, "Set D10.2 Phy Test Pattern\n");
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe),
+ DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2);
+ break;
+ case DP_LINK_QUAL_PATTERN_ERROR_RATE:
+ drm_dbg_kms(display->drm,
+ "Set Error Count Phy Test Pattern\n");
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe),
+ DDI_DP_COMP_CTL_ENABLE |
+ DDI_DP_COMP_CTL_SCRAMBLED_0);
+ break;
+ case DP_LINK_QUAL_PATTERN_PRBS7:
+ drm_dbg_kms(display->drm, "Set PRBS7 Phy Test Pattern\n");
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe),
+ DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7);
+ break;
+ case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM:
+ /*
+ * FIXME: Ideally pattern should come from DPCD 0x250. As
+ * current firmware of DPR-100 could not set it, so hardcoding
+ * now for complaince test.
+ */
+ drm_dbg_kms(display->drm,
+ "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
+ pattern_val = 0x3e0f83e0;
+ intel_de_write(display, DDI_DP_COMP_PAT(pipe, 0), pattern_val);
+ pattern_val = 0x0f83e0f8;
+ intel_de_write(display, DDI_DP_COMP_PAT(pipe, 1), pattern_val);
+ pattern_val = 0x0000f83e;
+ intel_de_write(display, DDI_DP_COMP_PAT(pipe, 2), pattern_val);
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe),
+ DDI_DP_COMP_CTL_ENABLE |
+ DDI_DP_COMP_CTL_CUSTOM80);
+ break;
+ case DP_LINK_QUAL_PATTERN_CP2520_PAT_1:
+ /*
+ * FIXME: Ideally pattern should come from DPCD 0x24A. As
+ * current firmware of DPR-100 could not set it, so hardcoding
+ * now for complaince test.
+ */
+ drm_dbg_kms(display->drm,
+ "Set HBR2 compliance Phy Test Pattern\n");
+ pattern_val = 0xFB;
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe),
+ DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 |
+ pattern_val);
+ break;
+ case DP_LINK_QUAL_PATTERN_CP2520_PAT_3:
+ if (DISPLAY_VER(display) < 10) {
+ drm_warn(display->drm,
+ "Platform does not support TPS4\n");
+ break;
+ }
+ drm_dbg_kms(display->drm,
+ "Set TPS4 compliance Phy Test Pattern\n");
+ intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0);
+ intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
+ DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK,
+ DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4);
+ break;
+ default:
+ drm_warn(display->drm, "Invalid Phy Test Pattern\n");
+ }
+}
+
+static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(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_dbg_kms(display->drm, "failed to get link status\n");
+ return;
+ }
+
+ /* retrieve vswing & pre-emphasis setting */
+ intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
+ link_status);
+
+ intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX);
+
+ intel_dp_phy_pattern_update(intel_dp, crtc_state);
+
+ drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
+ intel_dp->train_set, crtc_state->lane_count);
+
+ drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
+ intel_dp->dpcd[DP_DPCD_REV]);
+}
+
+static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(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_dbg_kms(display->drm,
+ "DP Phy Test pattern AUX read failure\n");
+ return DP_TEST_NAK;
+ }
+
+ /* Set test active flag here so userspace doesn't interrupt things */
+ intel_dp->compliance.test_active = true;
+
+ return DP_TEST_ACK;
+}
+
+void intel_dp_test_request(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ u8 response = DP_TEST_NAK;
+ u8 request = 0;
+ int status;
+
+ status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request);
+ if (status <= 0) {
+ drm_dbg_kms(display->drm,
+ "Could not read test request from sink\n");
+ goto update_status;
+ }
+
+ switch (request) {
+ case DP_TEST_LINK_TRAINING:
+ drm_dbg_kms(display->drm, "LINK_TRAINING test requested\n");
+ response = intel_dp_autotest_link_training(intel_dp);
+ break;
+ case DP_TEST_LINK_VIDEO_PATTERN:
+ drm_dbg_kms(display->drm, "TEST_PATTERN test requested\n");
+ response = intel_dp_autotest_video_pattern(intel_dp);
+ break;
+ case DP_TEST_LINK_EDID_READ:
+ drm_dbg_kms(display->drm, "EDID test requested\n");
+ response = intel_dp_autotest_edid(intel_dp);
+ break;
+ case DP_TEST_LINK_PHY_TEST_PATTERN:
+ drm_dbg_kms(display->drm, "PHY_PATTERN test requested\n");
+ response = intel_dp_autotest_phy_pattern(intel_dp);
+ break;
+ default:
+ drm_dbg_kms(display->drm, "Invalid test request '%02x'\n",
+ request);
+ break;
+ }
+
+ if (response & DP_TEST_ACK)
+ intel_dp->compliance.test_type = request;
+
+update_status:
+ status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response);
+ if (status <= 0)
+ drm_dbg_kms(display->drm,
+ "Could not write test response to sink\n");
+}
+
+/* phy test */
+
+static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
+ struct drm_modeset_acquire_ctx *ctx,
+ u8 *pipe_mask)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ struct drm_connector_list_iter conn_iter;
+ struct intel_connector *connector;
+ int ret = 0;
+
+ *pipe_mask = 0;
+
+ drm_connector_list_iter_begin(display->drm, &conn_iter);
+ for_each_intel_connector_iter(connector, &conn_iter) {
+ struct drm_connector_state *conn_state =
+ connector->base.state;
+ struct intel_crtc_state *crtc_state;
+ struct intel_crtc *crtc;
+
+ if (!intel_dp_has_connector(intel_dp, conn_state))
+ continue;
+
+ crtc = to_intel_crtc(conn_state->crtc);
+ if (!crtc)
+ continue;
+
+ ret = drm_modeset_lock(&crtc->base.mutex, ctx);
+ if (ret)
+ break;
+
+ crtc_state = to_intel_crtc_state(crtc->base.state);
+
+ drm_WARN_ON(display->drm,
+ !intel_crtc_has_dp_encoder(crtc_state));
+
+ if (!crtc_state->hw.active)
+ continue;
+
+ if (conn_state->commit &&
+ !try_wait_for_completion(&conn_state->commit->hw_done))
+ continue;
+
+ *pipe_mask |= BIT(crtc->pipe);
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return ret;
+}
+
+static int intel_dp_do_phy_test(struct intel_encoder *encoder,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ struct intel_display *display = to_intel_display(encoder);
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_crtc *crtc;
+ u8 pipe_mask;
+ int ret;
+
+ ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex,
+ ctx);
+ if (ret)
+ return ret;
+
+ ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask);
+ if (ret)
+ return ret;
+
+ if (pipe_mask == 0)
+ return 0;
+
+ drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n",
+ encoder->base.base.id, encoder->base.name);
+
+ for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) {
+ const struct intel_crtc_state *crtc_state =
+ to_intel_crtc_state(crtc->base.state);
+
+ /* test on the MST master transcoder */
+ if (DISPLAY_VER(display) >= 12 &&
+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+ !intel_dp_mst_is_master_trans(crtc_state))
+ continue;
+
+ intel_dp_process_phy_request(intel_dp, crtc_state);
+ break;
+ }
+
+ return 0;
+}
+
+bool intel_dp_test_phy(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ if (!intel_dp->compliance.test_active ||
+ intel_dp->compliance.test_type != DP_TEST_LINK_PHY_TEST_PATTERN)
+ return false;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ for (;;) {
+ ret = intel_dp_do_phy_test(encoder, &ctx);
+
+ if (ret == -EDEADLK) {
+ drm_modeset_backoff(&ctx);
+ continue;
+ }
+
+ break;
+ }
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+ drm_WARN(encoder->base.dev, ret,
+ "Acquiring modeset locks failed with %i\n", ret);
+
+ return true;
+}
+
+bool intel_dp_test_short_pulse(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ bool reprobe_needed = false;
+
+ switch (intel_dp->compliance.test_type) {
+ case DP_TEST_LINK_TRAINING:
+ drm_dbg_kms(display->drm,
+ "Link Training Compliance Test requested\n");
+ /* Send a Hotplug Uevent to userspace to start modeset */
+ drm_kms_helper_hotplug_event(display->drm);
+ break;
+ case DP_TEST_LINK_PHY_TEST_PATTERN:
+ drm_dbg_kms(display->drm,
+ "PHY test pattern Compliance Test requested\n");
+ /*
+ * Schedule long hpd to do the test
+ *
+ * FIXME get rid of the ad-hoc phy test modeset code
+ * and properly incorporate it into the normal modeset.
+ */
+ reprobe_needed = true;
+ }
+
+ return reprobe_needed;
+}
+
+static ssize_t i915_displayport_test_active_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct intel_display *display = m->private;
+ char *input_buffer;
+ int status = 0;
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+ struct intel_dp *intel_dp;
+ int val = 0;
+
+ if (len == 0)
+ return 0;
+
+ input_buffer = memdup_user_nul(ubuf, len);
+ if (IS_ERR(input_buffer))
+ return PTR_ERR(input_buffer);
+
+ drm_dbg_kms(display->drm, "Copied %d bytes from user\n", (unsigned int)len);
+
+ drm_connector_list_iter_begin(display->drm, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
+ if (connector->connector_type !=
+ DRM_MODE_CONNECTOR_DisplayPort)
+ continue;
+
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(encoder);
+ status = kstrtoint(input_buffer, 10, &val);
+ if (status < 0)
+ break;
+ drm_dbg_kms(display->drm, "Got %d for test active\n", val);
+ /* To prevent erroneous activation of the compliance
+ * testing code, only accept an actual value of 1 here
+ */
+ if (val == 1)
+ intel_dp->compliance.test_active = true;
+ else
+ intel_dp->compliance.test_active = false;
+ }
+ }
+ drm_connector_list_iter_end(&conn_iter);
+ kfree(input_buffer);
+ if (status < 0)
+ return status;
+
+ *offp += len;
+ return len;
+}
+
+static int i915_displayport_test_active_show(struct seq_file *m, void *data)
+{
+ struct intel_display *display = m->private;
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+ struct intel_dp *intel_dp;
+
+ drm_connector_list_iter_begin(display->drm, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
+ if (connector->connector_type !=
+ DRM_MODE_CONNECTOR_DisplayPort)
+ continue;
+
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(encoder);
+ if (intel_dp->compliance.test_active)
+ seq_puts(m, "1");
+ else
+ seq_puts(m, "0");
+ } else {
+ seq_puts(m, "0");
+ }
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return 0;
+}
+
+static int i915_displayport_test_active_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, i915_displayport_test_active_show,
+ inode->i_private);
+}
+
+static const struct file_operations i915_displayport_test_active_fops = {
+ .owner = THIS_MODULE,
+ .open = i915_displayport_test_active_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = i915_displayport_test_active_write
+};
+
+static int i915_displayport_test_data_show(struct seq_file *m, void *data)
+{
+ struct intel_display *display = m->private;
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+ struct intel_dp *intel_dp;
+
+ drm_connector_list_iter_begin(display->drm, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
+ if (connector->connector_type !=
+ DRM_MODE_CONNECTOR_DisplayPort)
+ continue;
+
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(encoder);
+ if (intel_dp->compliance.test_type ==
+ DP_TEST_LINK_EDID_READ)
+ seq_printf(m, "%lx",
+ intel_dp->compliance.test_data.edid);
+ else if (intel_dp->compliance.test_type ==
+ DP_TEST_LINK_VIDEO_PATTERN) {
+ seq_printf(m, "hdisplay: %d\n",
+ intel_dp->compliance.test_data.hdisplay);
+ seq_printf(m, "vdisplay: %d\n",
+ intel_dp->compliance.test_data.vdisplay);
+ seq_printf(m, "bpc: %u\n",
+ intel_dp->compliance.test_data.bpc);
+ } else if (intel_dp->compliance.test_type ==
+ DP_TEST_LINK_PHY_TEST_PATTERN) {
+ seq_printf(m, "pattern: %d\n",
+ intel_dp->compliance.test_data.phytest.phy_pattern);
+ seq_printf(m, "Number of lanes: %d\n",
+ intel_dp->compliance.test_data.phytest.num_lanes);
+ seq_printf(m, "Link Rate: %d\n",
+ intel_dp->compliance.test_data.phytest.link_rate);
+ seq_printf(m, "level: %02x\n",
+ intel_dp->train_set[0]);
+ }
+ } else {
+ seq_puts(m, "0");
+ }
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
+
+static int i915_displayport_test_type_show(struct seq_file *m, void *data)
+{
+ struct intel_display *display = m->private;
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+ struct intel_dp *intel_dp;
+
+ drm_connector_list_iter_begin(display->drm, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
+ if (connector->connector_type !=
+ DRM_MODE_CONNECTOR_DisplayPort)
+ continue;
+
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(encoder);
+ seq_printf(m, "%02lx\n", intel_dp->compliance.test_type);
+ } else {
+ seq_puts(m, "0");
+ }
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
+
+static const struct {
+ const char *name;
+ const struct file_operations *fops;
+} intel_display_debugfs_files[] = {
+ {"i915_dp_test_data", &i915_displayport_test_data_fops},
+ {"i915_dp_test_type", &i915_displayport_test_type_fops},
+ {"i915_dp_test_active", &i915_displayport_test_active_fops},
+};
+
+void intel_dp_test_debugfs_register(struct intel_display *display)
+{
+ struct drm_minor *minor = display->drm->primary;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) {
+ debugfs_create_file(intel_display_debugfs_files[i].name,
+ 0644,
+ minor->debugfs_root,
+ display,
+ intel_display_debugfs_files[i].fops);
+ }
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.h b/drivers/gpu/drm/i915/display/intel_dp_test.h
new file mode 100644
index 000000000000..dcc167e4c7f6
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_test.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2024 Intel Corporation */
+
+#ifndef __INTEL_DP_TEST_H__
+#define __INTEL_DP_TEST_H__
+
+#include <linux/types.h>
+
+struct intel_crtc_state;
+struct intel_display;
+struct intel_dp;
+struct link_config_limits;
+
+void intel_dp_test_reset(struct intel_dp *intel_dp);
+void intel_dp_test_request(struct intel_dp *intel_dp);
+void intel_dp_test_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits);
+bool intel_dp_test_phy(struct intel_dp *intel_dp);
+bool intel_dp_test_short_pulse(struct intel_dp *intel_dp);
+void intel_dp_test_debugfs_register(struct intel_display *display);
+
+#endif /* __INTEL_DP_TEST_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
index a0c00b7d3303..e9314cf25a19 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h
@@ -20,7 +20,7 @@ struct intel_dp;
struct intel_encoder;
struct intel_link_bw_limits;
-#if defined(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
+#if IS_ENABLED(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx);
void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index 340dfce480b8..b679c5391fe6 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -589,11 +589,14 @@ static bool intel_pll_is_valid(struct drm_i915_private *dev_priv,
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
return false;
- if (!IS_PINEVIEW(dev_priv) && !IS_LP(dev_priv))
+ if (!IS_PINEVIEW(dev_priv) &&
+ !IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
+ !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv))
if (clock->m1 <= clock->m2)
return false;
- if (!IS_LP(dev_priv)) {
+ if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
+ !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) {
if (clock->p < limit->p.min || limit->p.max < clock->p)
return false;
if (clock->m < limit->m.min || limit->m.max < clock->m)
@@ -780,7 +783,7 @@ g4x_find_best_dpll(const struct intel_limit *limit,
max_n = limit->n.max;
/* based on hardware requirement, prefer smaller n to precision */
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
- /* based on hardware requirement, prefere larger m1,m2 */
+ /* based on hardware requirement, prefer larger m1,m2 */
for (clock.m1 = limit->m1.max;
clock.m1 >= limit->m1.min; clock.m1--) {
for (clock.m2 = limit->m2.max;
@@ -2212,7 +2215,8 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
const struct dpll *dpll)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_display *display = &dev_priv->display;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
struct intel_crtc_state *crtc_state;
crtc_state = intel_crtc_state_alloc(crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index 3a6d99044828..ce8c76e44e6a 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -242,7 +242,7 @@ void intel_dpt_suspend(struct drm_i915_private *i915)
struct i915_address_space *
intel_dpt_create(struct intel_framebuffer *fb)
{
- struct drm_gem_object *obj = &intel_fb_obj(&fb->base)->base;
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
struct drm_i915_private *i915 = to_i915(obj->dev);
struct drm_i915_gem_object *dpt_obj;
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 3ca29afa5422..bb39eb96e812 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -3,6 +3,8 @@
* Copyright © 2021 Intel Corporation
*/
+#include <linux/debugfs.h>
+
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index e0c628d1fe7d..b7b44399adaa 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -4,6 +4,8 @@
*
*/
+#include <drm/drm_vblank.h>
+
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
@@ -37,9 +39,16 @@ struct intel_dsb {
unsigned int free_pos;
/*
- * ins_start_offset will help to store start dword of the dsb
- * instuction and help in identifying the batch of auto-increment
- * register.
+ * Previously emitted DSB instruction. Used to
+ * identify/adjust the instruction for indexed
+ * register writes.
+ */
+ u32 ins[2];
+
+ /*
+ * Start of the previously emitted DSB instruction.
+ * Used to adjust the instruction for indexed
+ * register writes.
*/
unsigned int ins_start_offset;
@@ -119,6 +128,12 @@ pre_commit_crtc_state(struct intel_atomic_state *state,
return old_crtc_state;
}
+static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state)
+{
+ return intel_mode_vblank_start(&crtc_state->hw.adjusted_mode) -
+ intel_mode_vdisplay(&crtc_state->hw.adjusted_mode);
+}
+
static int dsb_vtotal(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -215,9 +230,11 @@ static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)
dsb->free_pos = ALIGN(dsb->free_pos, 2);
dsb->ins_start_offset = dsb->free_pos;
+ dsb->ins[0] = ldw;
+ dsb->ins[1] = udw;
- intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, ldw);
- intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, udw);
+ intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, dsb->ins[0]);
+ intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, dsb->ins[1]);
}
static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb,
@@ -233,10 +250,8 @@ static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb,
if (dsb->free_pos == 0)
return false;
- prev_opcode = intel_dsb_buffer_read(&dsb->dsb_buf,
- dsb->ins_start_offset + 1) & ~DSB_REG_VALUE_MASK;
- prev_reg = intel_dsb_buffer_read(&dsb->dsb_buf,
- dsb->ins_start_offset + 1) & DSB_REG_VALUE_MASK;
+ prev_opcode = dsb->ins[1] & ~DSB_REG_VALUE_MASK;
+ prev_reg = dsb->ins[1] & DSB_REG_VALUE_MASK;
return prev_opcode == opcode && prev_reg == i915_mmio_reg_offset(reg);
}
@@ -269,8 +284,6 @@ static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_
void intel_dsb_reg_write(struct intel_dsb *dsb,
i915_reg_t reg, u32 val)
{
- u32 old_val;
-
/*
* For example the buffer will look like below for 3 dwords for auto
* increment register:
@@ -299,23 +312,27 @@ void intel_dsb_reg_write(struct intel_dsb *dsb,
/* convert to indexed write? */
if (intel_dsb_prev_ins_is_mmio_write(dsb, reg)) {
- u32 prev_val = intel_dsb_buffer_read(&dsb->dsb_buf,
- dsb->ins_start_offset + 0);
+ u32 prev_val = dsb->ins[0];
- intel_dsb_buffer_write(&dsb->dsb_buf,
- dsb->ins_start_offset + 0, 1); /* count */
+ dsb->ins[0] = 1; /* count */
+ dsb->ins[1] = (DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT) |
+ i915_mmio_reg_offset(reg);
+
+ intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0,
+ dsb->ins[0]);
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 1,
- (DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT) |
- i915_mmio_reg_offset(reg));
- intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 2, prev_val);
+ dsb->ins[1]);
+ intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 2,
+ prev_val);
dsb->free_pos++;
}
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, val);
/* Update the count */
- old_val = intel_dsb_buffer_read(&dsb->dsb_buf, dsb->ins_start_offset);
- intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset, old_val + 1);
+ dsb->ins[0]++;
+ intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0,
+ dsb->ins[0]);
/* if number of data words is odd, then the last dword should be 0.*/
if (dsb->free_pos & 0x1)
@@ -370,6 +387,24 @@ void intel_dsb_nonpost_end(struct intel_dsb *dsb)
intel_dsb_noop(dsb, 4);
}
+void intel_dsb_interrupt(struct intel_dsb *dsb)
+{
+ intel_dsb_emit(dsb, 0,
+ DSB_OPCODE_INTERRUPT << DSB_OPCODE_SHIFT);
+}
+
+void intel_dsb_wait_usec(struct intel_dsb *dsb, int count)
+{
+ intel_dsb_emit(dsb, count,
+ DSB_OPCODE_WAIT_USEC << DSB_OPCODE_SHIFT);
+}
+
+void intel_dsb_wait_vblanks(struct intel_dsb *dsb, int count)
+{
+ intel_dsb_emit(dsb, count,
+ DSB_OPCODE_WAIT_VBLANKS << DSB_OPCODE_SHIFT);
+}
+
static void intel_dsb_emit_wait_dsl(struct intel_dsb *dsb,
u32 opcode, int lower, int upper)
{
@@ -510,6 +545,31 @@ static u32 dsb_error_int_en(struct intel_display *display)
return errors;
}
+void intel_dsb_vblank_evade(struct intel_atomic_state *state,
+ struct intel_dsb *dsb)
+{
+ struct intel_crtc *crtc = dsb->crtc;
+ const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
+ /* FIXME calibrate sensibly */
+ int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20);
+ int vblank_delay = dsb_vblank_delay(crtc_state);
+ int start, end;
+
+ if (pre_commit_is_vrr_active(state, crtc)) {
+ end = intel_vrr_vmin_vblank_start(crtc_state);
+ start = end - vblank_delay - latency;
+ intel_dsb_wait_scanline_out(state, dsb, start, end);
+
+ end = intel_vrr_vmax_vblank_start(crtc_state);
+ start = end - vblank_delay - latency;
+ intel_dsb_wait_scanline_out(state, dsb, start, end);
+ } else {
+ end = intel_mode_vblank_start(&crtc_state->hw.adjusted_mode);
+ start = end - vblank_delay - latency;
+ intel_dsb_wait_scanline_out(state, dsb, start, end);
+ }
+}
+
static void _intel_dsb_chain(struct intel_atomic_state *state,
struct intel_dsb *dsb,
struct intel_dsb *chained_dsb,
@@ -535,7 +595,7 @@ static void _intel_dsb_chain(struct intel_atomic_state *state,
intel_dsb_reg_write(dsb, DSB_INTERRUPT(pipe, chained_dsb->id),
dsb_error_int_status(display) | DSB_PROG_INT_STATUS |
- dsb_error_int_en(display));
+ dsb_error_int_en(display) | DSB_PROG_INT_EN);
if (ctrl & DSB_WAIT_FOR_VBLANK) {
int dewake_scanline = dsb_dewake_scanline_start(state, crtc);
@@ -577,6 +637,17 @@ void intel_dsb_chain(struct intel_atomic_state *state,
wait_for_vblank ? DSB_WAIT_FOR_VBLANK : 0);
}
+void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state,
+ struct intel_dsb *dsb)
+{
+ struct intel_crtc *crtc = dsb->crtc;
+ const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
+ int usecs = intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode,
+ dsb_vblank_delay(crtc_state)) + 1;
+
+ intel_dsb_wait_usec(dsb, usecs);
+}
+
static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
int hw_dewake_scanline)
{
@@ -603,7 +674,7 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
intel_de_write_fw(display, DSB_INTERRUPT(pipe, dsb->id),
dsb_error_int_status(display) | DSB_PROG_INT_STATUS |
- dsb_error_int_en(display));
+ dsb_error_int_en(display) | DSB_PROG_INT_EN);
intel_de_write_fw(display, DSB_HEAD(pipe, dsb->id),
intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));
@@ -671,6 +742,9 @@ void intel_dsb_wait(struct intel_dsb *dsb)
/* Attempt to reset it */
dsb->free_pos = 0;
dsb->ins_start_offset = 0;
+ dsb->ins[0] = 0;
+ dsb->ins[1] = 0;
+
intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id), 0);
intel_de_write_fw(display, DSB_INTERRUPT(pipe, dsb->id),
@@ -723,8 +797,6 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
dsb->id = dsb_id;
dsb->crtc = crtc;
dsb->size = size / 4; /* in dwords */
- dsb->free_pos = 0;
- dsb->ins_start_offset = 0;
dsb->chicken = dsb_chicken(state, crtc);
dsb->hw_dewake_scanline =
@@ -759,12 +831,29 @@ void intel_dsb_cleanup(struct intel_dsb *dsb)
void intel_dsb_irq_handler(struct intel_display *display,
enum pipe pipe, enum intel_dsb_id dsb_id)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(display->drm), pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
u32 tmp, errors;
tmp = intel_de_read_fw(display, DSB_INTERRUPT(pipe, dsb_id));
intel_de_write_fw(display, DSB_INTERRUPT(pipe, dsb_id), tmp);
+ if (tmp & DSB_PROG_INT_STATUS) {
+ spin_lock(&display->drm->event_lock);
+
+ if (crtc->dsb_event) {
+ /*
+ * Update vblank counter/timestmap in case it
+ * hasn't been done yet for this frame.
+ */
+ drm_crtc_accurate_vblank_count(&crtc->base);
+
+ drm_crtc_send_vblank_event(&crtc->base, crtc->dsb_event);
+ crtc->dsb_event = NULL;
+ }
+
+ spin_unlock(&display->drm->event_lock);
+ }
+
errors = tmp & dsb_error_int_status(display);
if (errors)
drm_err(display->drm, "[CRTC:%d:%s] DSB %d error interrupt: 0x%x\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h
index c352c12aa59f..33e0fc2ab380 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.h
+++ b/drivers/gpu/drm/i915/display/intel_dsb.h
@@ -39,12 +39,19 @@ void intel_dsb_reg_write_masked(struct intel_dsb *dsb,
void intel_dsb_noop(struct intel_dsb *dsb, int count);
void intel_dsb_nonpost_start(struct intel_dsb *dsb);
void intel_dsb_nonpost_end(struct intel_dsb *dsb);
+void intel_dsb_interrupt(struct intel_dsb *dsb);
+void intel_dsb_wait_usec(struct intel_dsb *dsb, int count);
+void intel_dsb_wait_vblanks(struct intel_dsb *dsb, int count);
+void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state,
+ struct intel_dsb *dsb);
void intel_dsb_wait_scanline_in(struct intel_atomic_state *state,
struct intel_dsb *dsb,
int lower, int upper);
void intel_dsb_wait_scanline_out(struct intel_atomic_state *state,
struct intel_dsb *dsb,
int lower, int upper);
+void intel_dsb_vblank_evade(struct intel_atomic_state *state,
+ struct intel_dsb *dsb);
void intel_dsb_chain(struct intel_atomic_state *state,
struct intel_dsb *dsb,
struct intel_dsb *chained_dsb,
diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c
index bd5888ce4852..0be46c6c9611 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi.c
@@ -76,7 +76,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
if (fixed_mode->clock > max_dotclk)
return MODE_CLOCK_HIGH;
- return intel_mode_valid_max_plane_size(dev_priv, mode, false);
+ return intel_mode_valid_max_plane_size(dev_priv, mode, 1);
}
struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 12e7628cbecf..9508ceae0d84 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -31,6 +31,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 5be7bb43e2e0..70ced57ab102 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -3,15 +3,16 @@
* Copyright © 2021 Intel Corporation
*/
-#include <drm/drm_blend.h>
-#include <drm/drm_modeset_helper.h>
-
#include <linux/dma-fence.h>
#include <linux/dma-resv.h>
-#include "gem/i915_gem_object.h"
+#include <drm/drm_blend.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_modeset_helper.h>
+
#include "i915_drv.h"
#include "intel_atomic_plane.h"
+#include "intel_bo.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_dpt.h"
@@ -44,6 +45,14 @@ static const struct drm_format_info skl_ccs_formats[] = {
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
};
/*
@@ -66,6 +75,30 @@ static const struct drm_format_info gen12_ccs_formats[] = {
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
.char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
.hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
{ .format = DRM_FORMAT_YUYV, .num_planes = 2,
.char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
.hsub = 2, .vsub = 1, .is_yuv = true },
@@ -101,31 +134,79 @@ static const struct drm_format_info gen12_ccs_formats[] = {
*/
static const struct drm_format_info gen12_ccs_cc_formats[] = {
{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3,
- .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 },
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3,
+ .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 3,
+ .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
};
static const struct drm_format_info gen12_flat_ccs_cc_formats[] = {
{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, },
{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
- .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 },
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+ .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, },
+ { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
+ .hsub = 1, .vsub = 1, .has_alpha = true },
+ { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 2,
+ .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 },
.hsub = 1, .vsub = 1, .has_alpha = true },
};
@@ -1224,7 +1305,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int color_plane,
int plane_width, int *x, int *y)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base);
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
int ret;
ret = intel_fb_offset_to_xy(x, y, &fb->base, color_plane);
@@ -1248,7 +1329,7 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co
* fb layout agrees with the fence layout. We already check that the
* fb stride matches the fence stride elsewhere.
*/
- if (color_plane == 0 && i915_gem_object_is_tiled(obj) &&
+ if (color_plane == 0 && intel_bo_is_tiled(obj) &&
(*x + plane_width) * fb->base.format->cpp[color_plane] > fb->base.pitches[color_plane]) {
drm_dbg_kms(fb->base.dev,
"bad fb plane %d offset: 0x%x\n",
@@ -1568,7 +1649,7 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base);
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
u32 gtt_offset_rotated = 0;
u32 gtt_offset_remapped = 0;
unsigned int max_size = 0;
@@ -1641,10 +1722,10 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
max_size = max(max_size, offset + size);
}
- if (mul_u32_u32(max_size, tile_size) > intel_bo_to_drm_bo(obj)->size) {
+ if (mul_u32_u32(max_size, tile_size) > obj->size) {
drm_dbg_kms(&i915->drm,
"fb too big for bo (need %llu bytes, have %zu bytes)\n",
- mul_u32_u32(max_size, tile_size), intel_bo_to_drm_bo(obj)->size);
+ mul_u32_u32(max_size, tile_size), obj->size);
return -EINVAL;
}
@@ -1868,7 +1949,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
intel_frontbuffer_put(intel_fb->frontbuffer);
- intel_fb_bo_framebuffer_fini(intel_fb_obj(fb));
+ intel_fb_bo_framebuffer_fini(intel_fb_bo(fb));
kfree(intel_fb);
}
@@ -1877,16 +1958,16 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file,
unsigned int *handle)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct drm_i915_private *i915 = to_i915(intel_bo_to_drm_bo(obj)->dev);
+ struct drm_gem_object *obj = intel_fb_bo(fb);
+ struct intel_display *display = to_intel_display(obj->dev);
- if (i915_gem_object_is_userptr(obj)) {
- drm_dbg(&i915->drm,
+ if (intel_bo_is_userptr(obj)) {
+ drm_dbg(display->drm,
"attempting to use a userptr for a framebuffer, denied\n");
return -EINVAL;
}
- return drm_gem_handle_create(file, intel_bo_to_drm_bo(obj), handle);
+ return drm_gem_handle_create(file, obj, handle);
}
struct frontbuffer_fence_cb {
@@ -1910,7 +1991,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
struct drm_clip_rect *clips,
unsigned int num_clips)
{
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_gem_object *obj = intel_fb_bo(fb);
struct intel_frontbuffer *front = to_intel_frontbuffer(fb);
struct dma_fence *fence;
struct frontbuffer_fence_cb *cb;
@@ -1919,10 +2000,10 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
if (!atomic_read(&front->bits))
return 0;
- if (dma_resv_test_signaled(intel_bo_to_drm_bo(obj)->resv, dma_resv_usage_rw(false)))
+ if (dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(false)))
goto flush;
- ret = dma_resv_get_singleton(intel_bo_to_drm_bo(obj)->resv, dma_resv_usage_rw(false),
+ ret = dma_resv_get_singleton(obj->resv, dma_resv_usage_rw(false),
&fence);
if (ret || !fence)
goto flush;
@@ -1949,7 +2030,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
return ret;
flush:
- i915_gem_object_flush_if_display(obj);
+ intel_bo_flush_if_display(obj);
intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
return ret;
}
@@ -1961,10 +2042,10 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
};
int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd)
{
- struct drm_i915_private *dev_priv = to_i915(intel_bo_to_drm_bo(obj)->dev);
+ struct drm_i915_private *dev_priv = to_i915(obj->dev);
struct drm_framebuffer *fb = &intel_fb->base;
u32 max_stride;
int ret = -EINVAL;
@@ -2040,7 +2121,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
}
}
- fb->obj[i] = intel_bo_to_drm_bo(obj);
+ fb->obj[i] = obj;
}
ret = intel_fill_fb_info(dev_priv, intel_fb);
@@ -2084,7 +2165,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
const struct drm_mode_fb_cmd2 *user_mode_cmd)
{
struct drm_framebuffer *fb;
- struct drm_i915_gem_object *obj;
+ struct drm_gem_object *obj;
struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
struct drm_i915_private *i915 = to_i915(dev);
@@ -2093,13 +2174,13 @@ intel_user_framebuffer_create(struct drm_device *dev,
return ERR_CAST(obj);
fb = intel_framebuffer_create(obj, &mode_cmd);
- drm_gem_object_put(intel_bo_to_drm_bo(obj));
+ drm_gem_object_put(obj);
return fb;
}
struct drm_framebuffer *
-intel_framebuffer_create(struct drm_i915_gem_object *obj,
+intel_framebuffer_create(struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct intel_framebuffer *intel_fb;
@@ -2119,3 +2200,8 @@ err:
kfree(intel_fb);
return ERR_PTR(ret);
}
+
+struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb)
+{
+ return fb ? fb->obj[0] : NULL;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h
index 10de437e8ef8..8240febff84c 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fb.h
@@ -12,6 +12,7 @@
struct drm_device;
struct drm_file;
struct drm_framebuffer;
+struct drm_gem_object;
struct drm_i915_gem_object;
struct drm_i915_private;
struct drm_mode_fb_cmd2;
@@ -84,9 +85,12 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio
int intel_plane_compute_gtt(struct intel_plane_state *plane_state);
int intel_framebuffer_init(struct intel_framebuffer *ifb,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd);
struct drm_framebuffer *
+intel_framebuffer_create(struct drm_gem_object *obj,
+ struct drm_mode_fb_cmd2 *mode_cmd);
+struct drm_framebuffer *
intel_user_framebuffer_create(struct drm_device *dev,
struct drm_file *filp,
const struct drm_mode_fb_cmd2 *user_mode_cmd);
@@ -96,4 +100,6 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb);
unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier);
+struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb);
+
#endif /* __INTEL_FB_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c
index 4be09541e509..810ca6ff8640 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_bo.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_bo.c
@@ -11,15 +11,16 @@
#include "intel_fb.h"
#include "intel_fb_bo.h"
-void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj)
+void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj)
{
/* Nothing to do for i915 */
}
int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *_obj,
struct drm_mode_fb_cmd2 *mode_cmd)
{
+ struct drm_i915_gem_object *obj = to_intel_bo(_obj);
struct drm_i915_private *i915 = to_i915(obj->base.dev);
unsigned int tiling, stride;
@@ -74,7 +75,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
return 0;
}
-struct drm_i915_gem_object *
+struct drm_gem_object *
intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
struct drm_file *filp,
const struct drm_mode_fb_cmd2 *mode_cmd)
@@ -93,5 +94,5 @@ intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
return ERR_PTR(-EREMOTE);
}
- return obj;
+ return intel_bo_to_drm_bo(obj);
}
diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.h b/drivers/gpu/drm/i915/display/intel_fb_bo.h
index 232bf898b013..e71acd1bcb24 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_bo.h
+++ b/drivers/gpu/drm/i915/display/intel_fb_bo.h
@@ -7,18 +7,18 @@
#define __INTEL_FB_BO_H__
struct drm_file;
-struct drm_mode_fb_cmd2;
-struct drm_i915_gem_object;
+struct drm_gem_object;
struct drm_i915_private;
+struct drm_mode_fb_cmd2;
struct intel_framebuffer;
-void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj);
+void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj);
int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd);
-struct drm_i915_gem_object *
+struct drm_gem_object *
intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
struct drm_file *filp,
const struct drm_mode_fb_cmd2 *user_mode_cmd);
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index 575b271e012b..d3a86f9c6bc8 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -26,7 +26,8 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_gem_object *_obj = intel_fb_bo(fb);
+ struct drm_i915_gem_object *obj = to_intel_bo(_obj);
struct i915_gem_ww_ctx ww;
struct i915_vma *vma;
int ret;
@@ -111,7 +112,8 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_gem_object *_obj = intel_fb_bo(fb);
+ struct drm_i915_gem_object *obj = to_intel_bo(_obj);
intel_wakeref_t wakeref;
struct i915_gem_ww_ctx ww;
struct i915_vma *vma;
@@ -274,9 +276,11 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
* will trigger might_sleep() even if it won't actually sleep,
* which is the case when the fb has already been pinned.
*/
- if (intel_plane_needs_physical(plane))
- plane_state->phys_dma_addr =
- i915_gem_object_get_dma_address(intel_fb_obj(&fb->base), 0);
+ if (intel_plane_needs_physical(plane)) {
+ struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base));
+
+ plane_state->phys_dma_addr = i915_gem_object_get_dma_address(obj, 0);
+ }
} else {
unsigned int alignment = intel_plane_fb_min_alignment(plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 52b79bacef4d..2e0863093cff 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -38,6 +38,7 @@
* forcibly disable it to allow proper screen updates.
*/
+#include <linux/debugfs.h>
#include <linux/string_helpers.h>
#include <drm/drm_blend.h>
@@ -1792,7 +1793,6 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
{
struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work);
struct intel_display *display = fbc->display;
- struct drm_i915_private *i915 = to_i915(display->drm);
mutex_lock(&fbc->lock);
@@ -1805,7 +1805,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
intel_fbc_deactivate(fbc, "FIFO underrun");
if (!fbc->flip_pending)
- intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(i915, fbc->state.plane->pipe));
+ intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, fbc->state.plane->pipe));
__intel_fbc_disable(fbc);
out:
mutex_unlock(&fbc->lock);
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 49a1ac4f5491..00852ff5b247 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -41,12 +41,11 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_gem.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include "gem/i915_gem_mman.h"
-#include "gem/i915_gem_object.h"
-
#include "i915_drv.h"
+#include "intel_bo.h"
#include "intel_display_types.h"
#include "intel_fb.h"
#include "intel_fb_pin.h"
@@ -129,10 +128,9 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct intel_fbdev *fbdev = to_intel_fbdev(info->par);
- struct drm_gem_object *bo = drm_gem_fb_get_obj(&fbdev->fb->base, 0);
- struct drm_i915_gem_object *obj = to_intel_bo(bo);
+ struct drm_gem_object *obj = drm_gem_fb_get_obj(&fbdev->fb->base, 0);
- return i915_gem_fb_mmap(obj, vma);
+ return intel_bo_fb_mmap(obj, vma);
}
static void intel_fbdev_fb_destroy(struct fb_info *info)
@@ -187,7 +185,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct i915_vma *vma;
unsigned long flags = 0;
bool prealloc = false;
- struct drm_i915_gem_object *obj;
+ struct drm_gem_object *obj;
int ret;
mutex_lock(&ifbdev->hpd_lock);
@@ -209,7 +207,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
drm_framebuffer_put(&fb->base);
fb = NULL;
}
- if (!fb || drm_WARN_ON(dev, !intel_fb_obj(&fb->base))) {
+ if (!fb || drm_WARN_ON(dev, !intel_fb_bo(&fb->base))) {
drm_dbg_kms(&dev_priv->drm,
"no BIOS fb, allocating a new one\n");
fb = intel_fbdev_fb_alloc(helper, sizes);
@@ -247,7 +245,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
info->fbops = &intelfb_ops;
- obj = intel_fb_obj(&fb->base);
+ obj = intel_fb_bo(&fb->base);
ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma);
if (ret)
@@ -259,7 +257,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
* If the object is stolen however, it will be full of whatever
* garbage was left in there.
*/
- if (!i915_gem_object_is_shmem(obj) && !prealloc)
+ if (!intel_bo_is_shmem(obj) && !prealloc)
memset_io(info->screen_base, 0, info->screen_size);
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
@@ -323,8 +321,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
to_intel_plane(crtc->base.primary);
struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
- struct drm_i915_gem_object *obj =
- intel_fb_obj(plane_state->uapi.fb);
+ struct drm_gem_object *obj = intel_fb_bo(plane_state->uapi.fb);
if (!crtc_state->uapi.active) {
drm_dbg_kms(&i915->drm,
@@ -340,12 +337,12 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
continue;
}
- if (intel_bo_to_drm_bo(obj)->size > max_size) {
+ if (obj->size > max_size) {
drm_dbg_kms(&i915->drm,
"found possible fb from [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name);
fb = to_intel_framebuffer(plane_state->uapi.fb);
- max_size = intel_bo_to_drm_bo(obj)->size;
+ max_size = obj->size;
}
}
@@ -533,7 +530,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
* full of whatever garbage was left in there.
*/
if (state == FBINFO_STATE_RUNNING &&
- !i915_gem_object_is_shmem(intel_fb_obj(&ifbdev->fb->base)))
+ !intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base)))
memset_io(info->screen_base, 0, info->screen_size);
drm_fb_helper_set_suspend(&ifbdev->helper, state);
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
index 497525ef9668..4991c35a2632 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
@@ -9,6 +9,7 @@
#include "i915_drv.h"
#include "intel_display_types.h"
+#include "intel_fb.h"
#include "intel_fbdev_fb.h"
struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
@@ -60,15 +61,16 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
return ERR_PTR(-ENOMEM);
}
- fb = intel_framebuffer_create(obj, &mode_cmd);
+ fb = intel_framebuffer_create(intel_bo_to_drm_bo(obj), &mode_cmd);
i915_gem_object_put(obj);
return to_intel_framebuffer(fb);
}
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
- struct drm_i915_gem_object *obj, struct i915_vma *vma)
+ struct drm_gem_object *_obj, struct i915_vma *vma)
{
+ struct drm_i915_gem_object *obj = to_intel_bo(_obj);
struct i915_gem_ww_ctx ww;
void __iomem *vaddr;
int ret;
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
index 4832fe688fbf..e502ae375fc0 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
@@ -8,7 +8,7 @@
struct drm_fb_helper;
struct drm_fb_helper_surface_size;
-struct drm_i915_gem_object;
+struct drm_gem_object;
struct drm_i915_private;
struct fb_info;
struct i915_vma;
@@ -16,6 +16,6 @@ struct i915_vma;
struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
- struct drm_i915_gem_object *obj, struct i915_vma *vma);
+ struct drm_gem_object *obj, struct i915_vma *vma);
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c
index 222cd0e1a2bc..0168894e9cd1 100644
--- a/drivers/gpu/drm/i915/display/intel_fdi.c
+++ b/drivers/gpu/drm/i915/display/intel_fdi.c
@@ -137,6 +137,7 @@ void intel_fdi_link_train(struct intel_crtc *crtc,
*/
int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state)
{
+ struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state;
const struct intel_crtc_state *new_crtc_state;
@@ -145,7 +146,7 @@ int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state)
if (!IS_IVYBRIDGE(i915) || INTEL_NUM_PIPES(i915) != 3)
return 0;
- crtc = intel_crtc_for_pipe(i915, PIPE_C);
+ crtc = intel_crtc_for_pipe(display, PIPE_C);
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
if (!new_crtc_state)
return 0;
@@ -157,7 +158,7 @@ int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state)
if (!old_crtc_state->fdi_lanes)
return 0;
- crtc = intel_crtc_for_pipe(i915, PIPE_B);
+ crtc = intel_crtc_for_pipe(display, PIPE_B);
new_crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
if (IS_ERR(new_crtc_state))
return PTR_ERR(new_crtc_state);
@@ -184,6 +185,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
struct intel_crtc_state *pipe_config,
enum pipe *pipe_to_reduce)
{
+ struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_atomic_state *state = pipe_config->uapi.state;
struct intel_crtc *other_crtc;
@@ -223,7 +225,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
if (pipe_config->fdi_lanes <= 2)
return 0;
- other_crtc = intel_crtc_for_pipe(dev_priv, PIPE_C);
+ other_crtc = intel_crtc_for_pipe(display, PIPE_C);
other_crtc_state =
intel_atomic_get_crtc_state(state, other_crtc);
if (IS_ERR(other_crtc_state))
@@ -244,7 +246,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
return -EINVAL;
}
- other_crtc = intel_crtc_for_pipe(dev_priv, PIPE_B);
+ other_crtc = intel_crtc_for_pipe(display, PIPE_B);
other_crtc_state =
intel_atomic_get_crtc_state(state, other_crtc);
if (IS_ERR(other_crtc_state))
diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
index 8949fbb1cc60..745ce22afb89 100644
--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
@@ -57,6 +57,7 @@
static bool ivb_can_enable_err_int(struct drm_device *dev)
{
+ struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crtc *crtc;
enum pipe pipe;
@@ -64,7 +65,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev)
lockdep_assert_held(&dev_priv->irq_lock);
for_each_pipe(dev_priv, pipe) {
- crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
if (crtc->cpu_fifo_underrun_disabled)
return false;
@@ -75,6 +76,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev)
static bool cpt_can_enable_serr_int(struct drm_device *dev)
{
+ struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
enum pipe pipe;
struct intel_crtc *crtc;
@@ -82,7 +84,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev)
lockdep_assert_held(&dev_priv->irq_lock);
for_each_pipe(dev_priv, pipe) {
- crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
if (crtc->pch_fifo_underrun_disabled)
return false;
@@ -93,6 +95,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev)
static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
{
+ struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
i915_reg_t reg = PIPESTAT(dev_priv, crtc->pipe);
u32 enable_mask;
@@ -106,7 +109,7 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
intel_de_write(dev_priv, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
intel_de_posting_read(dev_priv, reg);
- trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe);
+ trace_intel_cpu_fifo_underrun(display, crtc->pipe);
drm_err(&dev_priv->drm, "pipe %c underrun\n", pipe_name(crtc->pipe));
}
@@ -147,6 +150,7 @@ static void ilk_set_fifo_underrun_reporting(struct drm_device *dev,
static void ivb_check_fifo_underruns(struct intel_crtc *crtc)
{
+ struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
u32 err_int = intel_de_read(dev_priv, GEN7_ERR_INT);
@@ -159,7 +163,7 @@ static void ivb_check_fifo_underruns(struct intel_crtc *crtc)
intel_de_write(dev_priv, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
intel_de_posting_read(dev_priv, GEN7_ERR_INT);
- trace_intel_cpu_fifo_underrun(dev_priv, pipe);
+ trace_intel_cpu_fifo_underrun(display, pipe);
drm_err(&dev_priv->drm, "fifo underrun on pipe %c\n", pipe_name(pipe));
}
@@ -235,6 +239,7 @@ static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
{
+ struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pch_transcoder = crtc->pipe;
u32 serr_int = intel_de_read(dev_priv, SERR_INT);
@@ -248,7 +253,7 @@ static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
intel_de_posting_read(dev_priv, SERR_INT);
- trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
+ trace_intel_pch_fifo_underrun(display, pch_transcoder);
drm_err(&dev_priv->drm, "pch fifo underrun on pch transcoder %c\n",
pipe_name(pch_transcoder));
}
@@ -282,8 +287,9 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable)
{
+ struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
bool old;
lockdep_assert_held(&dev_priv->irq_lock);
@@ -351,8 +357,9 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
enum pipe pch_transcoder,
bool enable)
{
+ struct intel_display *display = &dev_priv->display;
struct intel_crtc *crtc =
- intel_crtc_for_pipe(dev_priv, pch_transcoder);
+ intel_crtc_for_pipe(display, pch_transcoder);
unsigned long flags;
bool old;
@@ -395,7 +402,8 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
- struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
+ struct intel_display *display = &dev_priv->display;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
u32 underruns = 0;
/* We may be called too early in init, thanks BIOS! */
@@ -427,7 +435,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
}
if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
- trace_intel_cpu_fifo_underrun(dev_priv, pipe);
+ trace_intel_cpu_fifo_underrun(display, pipe);
if (DISPLAY_VER(dev_priv) >= 11)
drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun: %s%s%s%s\n",
@@ -455,9 +463,11 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pch_transcoder)
{
+ struct intel_display *display = &dev_priv->display;
+
if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
false)) {
- trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
+ trace_intel_pch_fifo_underrun(display, pch_transcoder);
drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n",
pipe_name(pch_transcoder));
}
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index af4576dee92a..6ed5f726ee60 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -55,9 +55,11 @@
* cancelled as soon as busyness is detected.
*/
-#include "gem/i915_gem_object_frontbuffer.h"
+#include <drm/drm_gem.h>
+
#include "i915_active.h"
#include "i915_drv.h"
+#include "intel_bo.h"
#include "intel_display_trace.h"
#include "intel_display_types.h"
#include "intel_dp.h"
@@ -93,7 +95,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
if (!frontbuffer_bits)
return;
- trace_intel_frontbuffer_flush(i915, frontbuffer_bits, origin);
+ trace_intel_frontbuffer_flush(display, frontbuffer_bits, origin);
might_sleep();
intel_td_flush(i915);
@@ -173,17 +175,17 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
enum fb_op_origin origin,
unsigned int frontbuffer_bits)
{
- struct drm_i915_private *i915 = intel_bo_to_i915(front->obj);
- struct intel_display *display = &i915->display;
+ struct intel_display *display = to_intel_display(front->obj->dev);
+ struct drm_i915_private *i915 = to_i915(display->drm);
if (origin == ORIGIN_CS) {
- spin_lock(&i915->display.fb_tracking.lock);
- i915->display.fb_tracking.busy_bits |= frontbuffer_bits;
- i915->display.fb_tracking.flip_bits &= ~frontbuffer_bits;
- spin_unlock(&i915->display.fb_tracking.lock);
+ spin_lock(&display->fb_tracking.lock);
+ display->fb_tracking.busy_bits |= frontbuffer_bits;
+ display->fb_tracking.flip_bits &= ~frontbuffer_bits;
+ spin_unlock(&display->fb_tracking.lock);
}
- trace_intel_frontbuffer_invalidate(i915, frontbuffer_bits, origin);
+ trace_intel_frontbuffer_invalidate(display, frontbuffer_bits, origin);
might_sleep();
intel_psr_invalidate(display, frontbuffer_bits, origin);
@@ -195,14 +197,15 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
enum fb_op_origin origin,
unsigned int frontbuffer_bits)
{
- struct drm_i915_private *i915 = intel_bo_to_i915(front->obj);
+ struct intel_display *display = to_intel_display(front->obj->dev);
+ struct drm_i915_private *i915 = to_i915(display->drm);
if (origin == ORIGIN_CS) {
- spin_lock(&i915->display.fb_tracking.lock);
+ spin_lock(&display->fb_tracking.lock);
/* Filter out new bits since rendering started. */
- frontbuffer_bits &= i915->display.fb_tracking.busy_bits;
- i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits;
- spin_unlock(&i915->display.fb_tracking.lock);
+ frontbuffer_bits &= display->fb_tracking.busy_bits;
+ display->fb_tracking.busy_bits &= ~frontbuffer_bits;
+ spin_unlock(&display->fb_tracking.lock);
}
if (frontbuffer_bits)
@@ -214,7 +217,7 @@ static void intel_frontbuffer_flush_work(struct work_struct *work)
struct intel_frontbuffer *front =
container_of(work, struct intel_frontbuffer, flush_work);
- i915_gem_object_flush_if_display(front->obj);
+ intel_bo_flush_if_display(front->obj);
intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
intel_frontbuffer_put(front);
}
@@ -255,31 +258,32 @@ static void frontbuffer_retire(struct i915_active *ref)
}
static void frontbuffer_release(struct kref *ref)
- __releases(&intel_bo_to_i915(front->obj)->display.fb_tracking.lock)
+ __releases(&to_intel_display(front->obj->dev)->fb_tracking.lock)
{
struct intel_frontbuffer *ret, *front =
container_of(ref, typeof(*front), ref);
- struct drm_i915_gem_object *obj = front->obj;
+ struct drm_gem_object *obj = front->obj;
+ struct intel_display *display = to_intel_display(obj->dev);
- drm_WARN_ON(&intel_bo_to_i915(obj)->drm, atomic_read(&front->bits));
+ drm_WARN_ON(display->drm, atomic_read(&front->bits));
- i915_ggtt_clear_scanout(obj);
+ i915_ggtt_clear_scanout(to_intel_bo(obj));
- ret = i915_gem_object_set_frontbuffer(obj, NULL);
- drm_WARN_ON(&intel_bo_to_i915(obj)->drm, ret);
- spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock);
+ ret = intel_bo_set_frontbuffer(obj, NULL);
+ drm_WARN_ON(display->drm, ret);
+ spin_unlock(&display->fb_tracking.lock);
i915_active_fini(&front->write);
kfree_rcu(front, rcu);
}
struct intel_frontbuffer *
-intel_frontbuffer_get(struct drm_i915_gem_object *obj)
+intel_frontbuffer_get(struct drm_gem_object *obj)
{
- struct drm_i915_private *i915 = intel_bo_to_i915(obj);
+ struct drm_i915_private *i915 = to_i915(obj->dev);
struct intel_frontbuffer *front, *cur;
- front = i915_gem_object_get_frontbuffer(obj);
+ front = intel_bo_get_frontbuffer(obj);
if (front)
return front;
@@ -297,7 +301,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj)
INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
spin_lock(&i915->display.fb_tracking.lock);
- cur = i915_gem_object_set_frontbuffer(obj, front);
+ cur = intel_bo_set_frontbuffer(obj, front);
spin_unlock(&i915->display.fb_tracking.lock);
if (cur != front)
kfree(front);
@@ -308,7 +312,7 @@ void intel_frontbuffer_put(struct intel_frontbuffer *front)
{
kref_put_lock(&front->ref,
frontbuffer_release,
- &intel_bo_to_i915(front->obj)->display.fb_tracking.lock);
+ &to_intel_display(front->obj->dev)->fb_tracking.lock);
}
/**
@@ -337,13 +341,17 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old,
BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE);
if (old) {
- drm_WARN_ON(&intel_bo_to_i915(old->obj)->drm,
+ struct intel_display *display = to_intel_display(old->obj->dev);
+
+ drm_WARN_ON(display->drm,
!(atomic_read(&old->bits) & frontbuffer_bits));
atomic_andnot(frontbuffer_bits, &old->bits);
}
if (new) {
- drm_WARN_ON(&intel_bo_to_i915(new->obj)->drm,
+ struct intel_display *display = to_intel_display(new->obj->dev);
+
+ drm_WARN_ON(display->drm,
atomic_read(&new->bits) & frontbuffer_bits);
atomic_or(frontbuffer_bits, &new->bits);
}
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h
index abb51e8bb920..6237780a9f68 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h
@@ -30,6 +30,7 @@
#include "i915_active_types.h"
+struct drm_gem_object;
struct drm_i915_private;
enum fb_op_origin {
@@ -44,7 +45,7 @@ struct intel_frontbuffer {
struct kref ref;
atomic_t bits;
struct i915_active write;
- struct drm_i915_gem_object *obj;
+ struct drm_gem_object *obj;
struct rcu_head rcu;
struct work_struct flush_work;
@@ -77,7 +78,7 @@ void intel_frontbuffer_flip(struct drm_i915_private *i915,
void intel_frontbuffer_put(struct intel_frontbuffer *front);
struct intel_frontbuffer *
-intel_frontbuffer_get(struct drm_i915_gem_object *obj);
+intel_frontbuffer_get(struct drm_gem_object *obj);
void __intel_fb_invalidate(struct intel_frontbuffer *front,
enum fb_op_origin origin,
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 377939de0ff4..ed6aa87403e2 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -25,6 +25,7 @@
#include "intel_hdcp.h"
#include "intel_hdcp_gsc.h"
#include "intel_hdcp_regs.h"
+#include "intel_hdcp_shim.h"
#include "intel_pcode.h"
#define KEY_LOAD_TRIES 5
@@ -35,20 +36,20 @@ static void
intel_hdcp_disable_hdcp_line_rekeying(struct intel_encoder *encoder,
struct intel_hdcp *hdcp)
{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_display *display = to_intel_display(encoder);
/* Here we assume HDMI is in TMDS mode of operation */
if (encoder->type != INTEL_OUTPUT_HDMI)
return;
- if (DISPLAY_VER(dev_priv) >= 14) {
- if (IS_DISPLAY_VER_STEP(dev_priv, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
- intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
+ if (DISPLAY_VER(display) >= 14) {
+ if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
+ intel_de_rmw(display, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
0, HDCP_LINE_REKEY_DISABLE);
- else if (IS_DISPLAY_VER_STEP(dev_priv, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
- IS_DISPLAY_VER_STEP(dev_priv, IP_VER(20, 0), STEP_B0, STEP_FOREVER))
- intel_de_rmw(dev_priv,
- TRANS_DDI_FUNC_CTL(dev_priv, hdcp->cpu_transcoder),
+ else if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
+ IS_DISPLAY_VER_STEP(display, IP_VER(20, 0), STEP_B0, STEP_FOREVER))
+ intel_de_rmw(display,
+ TRANS_DDI_FUNC_CTL(display, hdcp->cpu_transcoder),
0, TRANS_DDI_HDCP_LINE_REKEY_DISABLE);
}
}
@@ -95,10 +96,10 @@ static int
intel_hdcp_required_content_stream(struct intel_atomic_state *state,
struct intel_digital_port *dig_port)
{
+ struct intel_display *display = to_intel_display(state);
struct drm_connector_list_iter conn_iter;
struct intel_digital_port *conn_dig_port;
struct intel_connector *connector;
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
bool enforce_type0 = false;
int k;
@@ -111,7 +112,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
if (!dig_port->hdcp_mst_type1_capable)
enforce_type0 = true;
- drm_connector_list_iter_begin(&i915->drm, &conn_iter);
+ drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
if (connector->base.status == connector_status_disconnected)
continue;
@@ -133,7 +134,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
}
drm_connector_list_iter_end(&conn_iter);
- if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0))
+ if (drm_WARN_ON(display->drm, data->k > INTEL_NUM_PIPES(display) || data->k == 0))
return -EINVAL;
/*
@@ -181,7 +182,7 @@ static
int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port,
const struct intel_hdcp_shim *shim, u8 *bksv)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
int ret, i, tries = 2;
/* HDCP spec states that we must retry the bksv if it is invalid */
@@ -193,7 +194,7 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port,
break;
}
if (i == tries) {
- drm_dbg_kms(&i915->drm, "Bksv is invalid\n");
+ drm_dbg_kms(display->drm, "Bksv is invalid\n");
return -ENODEV;
}
@@ -232,7 +233,7 @@ bool intel_hdcp_get_capability(struct intel_connector *connector)
*/
static bool intel_hdcp2_prerequisite(struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
/* I915 support for HDCP2.2 */
@@ -240,18 +241,18 @@ static bool intel_hdcp2_prerequisite(struct intel_connector *connector)
return false;
/* If MTL+ make sure gsc is loaded and proxy is setup */
- if (intel_hdcp_gsc_cs_required(i915)) {
- if (!intel_hdcp_gsc_check_status(i915))
+ if (intel_hdcp_gsc_cs_required(display)) {
+ if (!intel_hdcp_gsc_check_status(display))
return false;
}
/* MEI/GSC interface is solid depending on which is used */
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- if (!i915->display.hdcp.comp_added || !i915->display.hdcp.arbiter) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ if (!display->hdcp.comp_added || !display->hdcp.arbiter) {
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return false;
}
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return true;
}
@@ -287,19 +288,19 @@ void intel_hdcp_get_remote_capability(struct intel_connector *connector,
*hdcp2_capable = false;
}
-static bool intel_hdcp_in_use(struct drm_i915_private *i915,
+static bool intel_hdcp_in_use(struct intel_display *display,
enum transcoder cpu_transcoder, enum port port)
{
- return intel_de_read(i915,
- HDCP_STATUS(i915, cpu_transcoder, port)) &
+ return intel_de_read(display,
+ HDCP_STATUS(display, cpu_transcoder, port)) &
HDCP_STATUS_ENC;
}
-static bool intel_hdcp2_in_use(struct drm_i915_private *i915,
+static bool intel_hdcp2_in_use(struct intel_display *display,
enum transcoder cpu_transcoder, enum port port)
{
- return intel_de_read(i915,
- HDCP2_STATUS(i915, cpu_transcoder, port)) &
+ return intel_de_read(display,
+ HDCP2_STATUS(display, cpu_transcoder, port)) &
LINK_ENCRYPTION_STATUS;
}
@@ -324,8 +325,9 @@ static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *dig_port,
return 0;
}
-static bool hdcp_key_loadable(struct drm_i915_private *i915)
+static bool hdcp_key_loadable(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
enum i915_power_well_id id;
intel_wakeref_t wakeref;
bool enabled = false;
@@ -352,19 +354,20 @@ static bool hdcp_key_loadable(struct drm_i915_private *i915)
return enabled;
}
-static void intel_hdcp_clear_keys(struct drm_i915_private *i915)
+static void intel_hdcp_clear_keys(struct intel_display *display)
{
- intel_de_write(i915, HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER);
- intel_de_write(i915, HDCP_KEY_STATUS,
+ intel_de_write(display, HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER);
+ intel_de_write(display, HDCP_KEY_STATUS,
HDCP_KEY_LOAD_DONE | HDCP_KEY_LOAD_STATUS | HDCP_FUSE_IN_PROGRESS | HDCP_FUSE_ERROR | HDCP_FUSE_DONE);
}
-static int intel_hdcp_load_keys(struct drm_i915_private *i915)
+static int intel_hdcp_load_keys(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
int ret;
u32 val;
- val = intel_de_read(i915, HDCP_KEY_STATUS);
+ val = intel_de_read(display, HDCP_KEY_STATUS);
if ((val & HDCP_KEY_LOAD_DONE) && (val & HDCP_KEY_LOAD_STATUS))
return 0;
@@ -373,7 +376,7 @@ static int intel_hdcp_load_keys(struct drm_i915_private *i915)
* out of reset. So if Key is not already loaded, its an error state.
*/
if (IS_HASWELL(i915) || IS_BROADWELL(i915))
- if (!(intel_de_read(i915, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE))
+ if (!(intel_de_read(display, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE))
return -ENXIO;
/*
@@ -384,20 +387,20 @@ static int intel_hdcp_load_keys(struct drm_i915_private *i915)
* process from other platforms. These platforms use the GT Driver
* Mailbox interface.
*/
- if (DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915)) {
+ if (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)) {
ret = snb_pcode_write(&i915->uncore, SKL_PCODE_LOAD_HDCP_KEYS, 1);
if (ret) {
- drm_err(&i915->drm,
+ drm_err(display->drm,
"Failed to initiate HDCP key load (%d)\n",
ret);
return ret;
}
} else {
- intel_de_write(i915, HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER);
+ intel_de_write(display, HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER);
}
/* Wait for the keys to load (500us) */
- ret = intel_de_wait_custom(i915, HDCP_KEY_STATUS,
+ ret = intel_de_wait_custom(display, HDCP_KEY_STATUS,
HDCP_KEY_LOAD_DONE, HDCP_KEY_LOAD_DONE,
10, 1, &val);
if (ret)
@@ -406,27 +409,27 @@ static int intel_hdcp_load_keys(struct drm_i915_private *i915)
return -ENXIO;
/* Send Aksv over to PCH display for use in authentication */
- intel_de_write(i915, HDCP_KEY_CONF, HDCP_AKSV_SEND_TRIGGER);
+ intel_de_write(display, HDCP_KEY_CONF, HDCP_AKSV_SEND_TRIGGER);
return 0;
}
/* Returns updated SHA-1 index */
-static int intel_write_sha_text(struct drm_i915_private *i915, u32 sha_text)
+static int intel_write_sha_text(struct intel_display *display, u32 sha_text)
{
- intel_de_write(i915, HDCP_SHA_TEXT, sha_text);
- if (intel_de_wait_for_set(i915, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) {
- drm_err(&i915->drm, "Timed out waiting for SHA1 ready\n");
+ intel_de_write(display, HDCP_SHA_TEXT, sha_text);
+ if (intel_de_wait_for_set(display, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) {
+ drm_err(display->drm, "Timed out waiting for SHA1 ready\n");
return -ETIMEDOUT;
}
return 0;
}
static
-u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915,
+u32 intel_hdcp_get_repeater_ctl(struct intel_display *display,
enum transcoder cpu_transcoder, enum port port)
{
- if (DISPLAY_VER(i915) >= 12) {
+ if (DISPLAY_VER(display) >= 12) {
switch (cpu_transcoder) {
case TRANSCODER_A:
return HDCP_TRANSA_REP_PRESENT |
@@ -441,7 +444,7 @@ u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915,
return HDCP_TRANSD_REP_PRESENT |
HDCP_TRANSD_SHA1_M0;
default:
- drm_err(&i915->drm, "Unknown transcoder %d\n",
+ drm_err(display->drm, "Unknown transcoder %d\n",
cpu_transcoder);
return 0;
}
@@ -459,7 +462,7 @@ u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915,
case PORT_E:
return HDCP_DDIE_REP_PRESENT | HDCP_DDIE_SHA1_M0;
default:
- drm_err(&i915->drm, "Unknown port %d\n", port);
+ drm_err(display->drm, "Unknown port %d\n", port);
return 0;
}
}
@@ -469,8 +472,8 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
const struct intel_hdcp_shim *shim,
u8 *ksv_fifo, u8 num_downstream, u8 *bstatus)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
enum port port = dig_port->base.port;
u32 vprime, sha_text, sha_leftovers, rep_ctl;
@@ -481,7 +484,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
ret = shim->read_v_prime_part(dig_port, i, &vprime);
if (ret)
return ret;
- intel_de_write(i915, HDCP_SHA_V_PRIME(i), vprime);
+ intel_de_write(display, HDCP_SHA_V_PRIME(i), vprime);
}
/*
@@ -497,8 +500,8 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
sha_idx = 0;
sha_text = 0;
sha_leftovers = 0;
- rep_ctl = intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, port);
- intel_de_write(i915, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
+ rep_ctl = intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port);
+ intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
for (i = 0; i < num_downstream; i++) {
unsigned int sha_empty;
u8 *ksv = &ksv_fifo[i * DRM_HDCP_KSV_LEN];
@@ -510,14 +513,14 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
sha_text |= ksv[j] << off;
}
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
/* Programming guide writes this every 64 bytes */
sha_idx += sizeof(sha_text);
if (!(sha_idx % 64))
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
/* Store the leftover bytes from the ksv in sha_text */
@@ -534,7 +537,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
if (sizeof(sha_text) > sha_leftovers)
continue;
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
sha_leftovers = 0;
@@ -550,73 +553,73 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
*/
if (sha_leftovers == 0) {
/* Write 16 bits of text, 16 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_16);
- ret = intel_write_sha_text(i915,
+ ret = intel_write_sha_text(display,
bstatus[0] << 8 | bstatus[1]);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 32 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_0);
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 16 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_16);
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
} else if (sha_leftovers == 1) {
/* Write 24 bits of text, 8 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_24);
sha_text |= bstatus[0] << 16 | bstatus[1] << 8;
/* Only 24-bits of data, must be in the LSB */
sha_text = (sha_text & 0xffffff00) >> 8;
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 32 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_0);
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 24 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_8);
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
} else if (sha_leftovers == 2) {
/* Write 32 bits of text */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
sha_text |= bstatus[0] << 8 | bstatus[1];
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 64 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_0);
for (i = 0; i < 2; i++) {
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
@@ -626,56 +629,56 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
* Terminate the SHA-1 stream by hand. For the other leftover
* cases this is appended by the hardware.
*/
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
sha_text = DRM_HDCP_SHA1_TERMINATOR << 24;
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
} else if (sha_leftovers == 3) {
/* Write 32 bits of text (filled from LSB) */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
sha_text |= bstatus[0];
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 8 bits of text (filled from LSB), 24 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_8);
- ret = intel_write_sha_text(i915, bstatus[1]);
+ ret = intel_write_sha_text(display, bstatus[1]);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 32 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_0);
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
/* Write 8 bits of M0 */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_24);
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
} else {
- drm_dbg_kms(&i915->drm, "Invalid number of leftovers %d\n",
+ drm_dbg_kms(display->drm, "Invalid number of leftovers %d\n",
sha_leftovers);
return -EINVAL;
}
- intel_de_write(i915, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
+ intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
/* Fill up to 64-4 bytes with zeros (leave the last write for length) */
while ((sha_idx % 64) < (64 - sizeof(sha_text))) {
- ret = intel_write_sha_text(i915, 0);
+ ret = intel_write_sha_text(display, 0);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
@@ -687,20 +690,20 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
* - 10 bytes for BINFO/BSTATUS(2), M0(8)
*/
sha_text = (num_downstream * 5 + 10) * 8;
- ret = intel_write_sha_text(i915, sha_text);
+ ret = intel_write_sha_text(display, sha_text);
if (ret < 0)
return ret;
/* Tell the HW we're done with the hash and wait for it to ACK */
- intel_de_write(i915, HDCP_REP_CTL,
+ intel_de_write(display, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_COMPLETE_HASH);
- if (intel_de_wait_for_set(i915, HDCP_REP_CTL,
+ if (intel_de_wait_for_set(display, HDCP_REP_CTL,
HDCP_SHA1_COMPLETE, 1)) {
- drm_err(&i915->drm, "Timed out waiting for SHA1 complete\n");
+ drm_err(display->drm, "Timed out waiting for SHA1 complete\n");
return -ETIMEDOUT;
}
- if (!(intel_de_read(i915, HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) {
- drm_dbg_kms(&i915->drm, "SHA-1 mismatch, HDCP failed\n");
+ if (!(intel_de_read(display, HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) {
+ drm_dbg_kms(display->drm, "SHA-1 mismatch, HDCP failed\n");
return -ENXIO;
}
@@ -711,15 +714,15 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
static
int intel_hdcp_auth_downstream(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
u8 bstatus[2], num_downstream, *ksv_fifo;
int ret, i, tries = 3;
ret = intel_hdcp_poll_ksv_fifo(dig_port, shim);
if (ret) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"KSV list failed to become ready (%d)\n", ret);
return ret;
}
@@ -730,7 +733,7 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) ||
DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) {
- drm_dbg_kms(&i915->drm, "Max Topology Limit Exceeded\n");
+ drm_dbg_kms(display->drm, "Max Topology Limit Exceeded\n");
return -EPERM;
}
@@ -743,14 +746,14 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
*/
num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]);
if (num_downstream == 0) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Repeater with zero downstream devices\n");
return -EINVAL;
}
ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
if (!ksv_fifo) {
- drm_dbg_kms(&i915->drm, "Out of mem: ksv_fifo\n");
+ drm_dbg_kms(display->drm, "Out of mem: ksv_fifo\n");
return -ENOMEM;
}
@@ -758,9 +761,9 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
if (ret)
goto err;
- if (drm_hdcp_check_ksvs_revoked(&i915->drm, ksv_fifo,
+ if (drm_hdcp_check_ksvs_revoked(display->drm, ksv_fifo,
num_downstream) > 0) {
- drm_err(&i915->drm, "Revoked Ksv(s) in ksv_fifo\n");
+ drm_err(display->drm, "Revoked Ksv(s) in ksv_fifo\n");
ret = -EPERM;
goto err;
}
@@ -778,12 +781,12 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
}
if (i == tries) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"V Prime validation failed.(%d)\n", ret);
goto err;
}
- drm_dbg_kms(&i915->drm, "HDCP is enabled (%d downstream devices)\n",
+ drm_dbg_kms(display->drm, "HDCP is enabled (%d downstream devices)\n",
num_downstream);
ret = 0;
err:
@@ -794,8 +797,8 @@ err:
/* Implements Part 1 of the HDCP authorization procedure */
static int intel_hdcp_auth(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
const struct intel_hdcp_shim *shim = hdcp->shim;
enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
@@ -827,7 +830,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
if (ret)
return ret;
if (!hdcp_capable) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Panel is not HDCP capable\n");
return -EINVAL;
}
@@ -835,24 +838,24 @@ static int intel_hdcp_auth(struct intel_connector *connector)
/* Initialize An with 2 random values and acquire it */
for (i = 0; i < 2; i++)
- intel_de_write(i915,
- HDCP_ANINIT(i915, cpu_transcoder, port),
+ intel_de_write(display,
+ HDCP_ANINIT(display, cpu_transcoder, port),
get_random_u32());
- intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port),
+ intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port),
HDCP_CONF_CAPTURE_AN);
/* Wait for An to be acquired */
- if (intel_de_wait_for_set(i915,
- HDCP_STATUS(i915, cpu_transcoder, port),
+ if (intel_de_wait_for_set(display,
+ HDCP_STATUS(display, cpu_transcoder, port),
HDCP_STATUS_AN_READY, 1)) {
- drm_err(&i915->drm, "Timed out waiting for An\n");
+ drm_err(display->drm, "Timed out waiting for An\n");
return -ETIMEDOUT;
}
- an.reg[0] = intel_de_read(i915,
- HDCP_ANLO(i915, cpu_transcoder, port));
- an.reg[1] = intel_de_read(i915,
- HDCP_ANHI(i915, cpu_transcoder, port));
+ an.reg[0] = intel_de_read(display,
+ HDCP_ANLO(display, cpu_transcoder, port));
+ an.reg[1] = intel_de_read(display,
+ HDCP_ANHI(display, cpu_transcoder, port));
ret = shim->write_an_aksv(dig_port, an.shim);
if (ret)
return ret;
@@ -865,34 +868,34 @@ static int intel_hdcp_auth(struct intel_connector *connector)
if (ret < 0)
return ret;
- if (drm_hdcp_check_ksvs_revoked(&i915->drm, bksv.shim, 1) > 0) {
- drm_err(&i915->drm, "BKSV is revoked\n");
+ if (drm_hdcp_check_ksvs_revoked(display->drm, bksv.shim, 1) > 0) {
+ drm_err(display->drm, "BKSV is revoked\n");
return -EPERM;
}
- intel_de_write(i915, HDCP_BKSVLO(i915, cpu_transcoder, port),
+ intel_de_write(display, HDCP_BKSVLO(display, cpu_transcoder, port),
bksv.reg[0]);
- intel_de_write(i915, HDCP_BKSVHI(i915, cpu_transcoder, port),
+ intel_de_write(display, HDCP_BKSVHI(display, cpu_transcoder, port),
bksv.reg[1]);
ret = shim->repeater_present(dig_port, &repeater_present);
if (ret)
return ret;
if (repeater_present)
- intel_de_write(i915, HDCP_REP_CTL,
- intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, port));
+ intel_de_write(display, HDCP_REP_CTL,
+ intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port));
ret = shim->toggle_signalling(dig_port, cpu_transcoder, true);
if (ret)
return ret;
- intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port),
+ intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port),
HDCP_CONF_AUTH_AND_ENC);
/* Wait for R0 ready */
- if (wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
+ if (wait_for(intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) &
(HDCP_STATUS_R0_READY | HDCP_STATUS_ENC), 1)) {
- drm_err(&i915->drm, "Timed out waiting for R0 ready\n");
+ drm_err(display->drm, "Timed out waiting for R0 ready\n");
return -ETIMEDOUT;
}
@@ -918,30 +921,30 @@ static int intel_hdcp_auth(struct intel_connector *connector)
ret = shim->read_ri_prime(dig_port, ri.shim);
if (ret)
return ret;
- intel_de_write(i915,
- HDCP_RPRIME(i915, cpu_transcoder, port),
+ intel_de_write(display,
+ HDCP_RPRIME(display, cpu_transcoder, port),
ri.reg);
/* Wait for Ri prime match */
- if (!wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
+ if (!wait_for(intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) &
(HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1))
break;
}
if (i == tries) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Timed out waiting for Ri prime match (%x)\n",
- intel_de_read(i915,
- HDCP_STATUS(i915, cpu_transcoder, port)));
+ intel_de_read(display,
+ HDCP_STATUS(display, cpu_transcoder, port)));
return -ETIMEDOUT;
}
/* Wait for encryption confirmation */
- if (intel_de_wait_for_set(i915,
- HDCP_STATUS(i915, cpu_transcoder, port),
+ if (intel_de_wait_for_set(display,
+ HDCP_STATUS(display, cpu_transcoder, port),
HDCP_STATUS_ENC,
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
- drm_err(&i915->drm, "Timed out waiting for encryption\n");
+ drm_err(display->drm, "Timed out waiting for encryption\n");
return -ETIMEDOUT;
}
@@ -949,42 +952,42 @@ static int intel_hdcp_auth(struct intel_connector *connector)
if (shim->stream_encryption) {
ret = shim->stream_encryption(connector, true);
if (ret) {
- drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n",
+ drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n",
connector->base.base.id, connector->base.name);
return ret;
}
- drm_dbg_kms(&i915->drm, "HDCP 1.4 transcoder: %s stream encrypted\n",
+ drm_dbg_kms(display->drm, "HDCP 1.4 transcoder: %s stream encrypted\n",
transcoder_name(hdcp->stream_transcoder));
}
if (repeater_present)
return intel_hdcp_auth_downstream(connector);
- drm_dbg_kms(&i915->drm, "HDCP is enabled (no repeater present)\n");
+ drm_dbg_kms(display->drm, "HDCP is enabled (no repeater present)\n");
return 0;
}
static int _intel_hdcp_disable(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
u32 repeater_ctl;
int ret;
- drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP is being disabled...\n",
+ drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP is being disabled...\n",
connector->base.base.id, connector->base.name);
if (hdcp->shim->stream_encryption) {
ret = hdcp->shim->stream_encryption(connector, false);
if (ret) {
- drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n",
+ drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n",
connector->base.base.id, connector->base.name);
return ret;
}
- drm_dbg_kms(&i915->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n",
+ drm_dbg_kms(display->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n",
transcoder_name(hdcp->stream_transcoder));
/*
* If there are other connectors on this port using HDCP,
@@ -996,51 +999,51 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
}
hdcp->hdcp_encrypted = false;
- intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port), 0);
- if (intel_de_wait_for_clear(i915,
- HDCP_STATUS(i915, cpu_transcoder, port),
+ intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port), 0);
+ if (intel_de_wait_for_clear(display,
+ HDCP_STATUS(display, cpu_transcoder, port),
~0, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
- drm_err(&i915->drm,
+ drm_err(display->drm,
"Failed to disable HDCP, timeout clearing status\n");
return -ETIMEDOUT;
}
- repeater_ctl = intel_hdcp_get_repeater_ctl(i915, cpu_transcoder,
+ repeater_ctl = intel_hdcp_get_repeater_ctl(display, cpu_transcoder,
port);
- intel_de_rmw(i915, HDCP_REP_CTL, repeater_ctl, 0);
+ intel_de_rmw(display, HDCP_REP_CTL, repeater_ctl, 0);
ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder, false);
if (ret) {
- drm_err(&i915->drm, "Failed to disable HDCP signalling\n");
+ drm_err(display->drm, "Failed to disable HDCP signalling\n");
return ret;
}
- drm_dbg_kms(&i915->drm, "HDCP is disabled\n");
+ drm_dbg_kms(display->drm, "HDCP is disabled\n");
return 0;
}
static int intel_hdcp1_enable(struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
int i, ret, tries = 3;
- drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP is being enabled...\n",
+ drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP is being enabled...\n",
connector->base.base.id, connector->base.name);
- if (!hdcp_key_loadable(i915)) {
- drm_err(&i915->drm, "HDCP key Load is not possible\n");
+ if (!hdcp_key_loadable(display)) {
+ drm_err(display->drm, "HDCP key Load is not possible\n");
return -ENXIO;
}
for (i = 0; i < KEY_LOAD_TRIES; i++) {
- ret = intel_hdcp_load_keys(i915);
+ ret = intel_hdcp_load_keys(display);
if (!ret)
break;
- intel_hdcp_clear_keys(i915);
+ intel_hdcp_clear_keys(display);
}
if (ret) {
- drm_err(&i915->drm, "Could not load HDCP keys, (%d)\n",
+ drm_err(display->drm, "Could not load HDCP keys, (%d)\n",
ret);
return ret;
}
@@ -1053,13 +1056,13 @@ static int intel_hdcp1_enable(struct intel_connector *connector)
return 0;
}
- drm_dbg_kms(&i915->drm, "HDCP Auth failure (%d)\n", ret);
+ drm_dbg_kms(display->drm, "HDCP Auth failure (%d)\n", ret);
/* Ensuring HDCP encryption and signalling are stopped. */
_intel_hdcp_disable(connector);
}
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"HDCP authentication failed (%d tries/%d)\n", tries, ret);
return ret;
}
@@ -1072,20 +1075,20 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
static void intel_hdcp_update_value(struct intel_connector *connector,
u64 value, bool update_property)
{
- struct drm_device *dev = connector->base.dev;
+ struct intel_display *display = to_intel_display(connector);
+ struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
- drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
+ drm_WARN_ON(display->drm, !mutex_is_locked(&hdcp->mutex));
if (hdcp->value == value)
return;
- drm_WARN_ON(dev, !mutex_is_locked(&dig_port->hdcp_mutex));
+ drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp_mutex));
if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
- if (!drm_WARN_ON(dev, dig_port->num_hdcp_streams == 0))
+ if (!drm_WARN_ON(display->drm, dig_port->num_hdcp_streams == 0))
dig_port->num_hdcp_streams--;
} else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
dig_port->num_hdcp_streams++;
@@ -1102,8 +1105,8 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
/* Implements Part 3 of the HDCP authorization procedure */
static int intel_hdcp_check_link(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder;
@@ -1121,12 +1124,12 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
goto out;
}
- if (drm_WARN_ON(&i915->drm,
- !intel_hdcp_in_use(i915, cpu_transcoder, port))) {
- drm_err(&i915->drm,
+ if (drm_WARN_ON(display->drm,
+ !intel_hdcp_in_use(display, cpu_transcoder, port))) {
+ drm_err(display->drm,
"[CONNECTOR:%d:%s] HDCP link stopped encryption,%x\n",
connector->base.base.id, connector->base.name,
- intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)));
+ intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)));
ret = -ENXIO;
intel_hdcp_update_value(connector,
DRM_MODE_CONTENT_PROTECTION_DESIRED,
@@ -1142,13 +1145,13 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
goto out;
}
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] HDCP link failed, retrying authentication\n",
connector->base.base.id, connector->base.name);
ret = _intel_hdcp_disable(connector);
if (ret) {
- drm_err(&i915->drm, "Failed to disable hdcp (%d)\n", ret);
+ drm_err(display->drm, "Failed to disable hdcp (%d)\n", ret);
intel_hdcp_update_value(connector,
DRM_MODE_CONTENT_PROTECTION_DESIRED,
true);
@@ -1169,9 +1172,9 @@ static void intel_hdcp_prop_work(struct work_struct *work)
struct intel_hdcp *hdcp = container_of(work, struct intel_hdcp,
prop_work);
struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
- drm_modeset_lock(&i915->drm.mode_config.connection_mutex, NULL);
+ drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL);
mutex_lock(&hdcp->mutex);
/*
@@ -1184,7 +1187,7 @@ static void intel_hdcp_prop_work(struct work_struct *work)
hdcp->value);
mutex_unlock(&hdcp->mutex);
- drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+ drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
drm_connector_put(&connector->base);
}
@@ -1199,25 +1202,25 @@ static int
hdcp2_prepare_ake_init(struct intel_connector *connector,
struct hdcp2_ake_init *ake_data)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->initiate_hdcp2_session(arbiter->hdcp_dev, data, ake_data);
if (ret)
- drm_dbg_kms(&i915->drm, "Prepare_ake_init failed. %d\n",
+ drm_dbg_kms(display->drm, "Prepare_ake_init failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1229,17 +1232,17 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
struct hdcp2_ake_no_stored_km *ek_pub_km,
size_t *msg_sz)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
@@ -1247,9 +1250,9 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
rx_cert, paired,
ek_pub_km, msg_sz);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Verify rx_cert failed. %d\n",
+ drm_dbg_kms(display->drm, "Verify rx_cert failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1257,24 +1260,24 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
static int hdcp2_verify_hprime(struct intel_connector *connector,
struct hdcp2_ake_send_hprime *rx_hprime)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->verify_hprime(arbiter->hdcp_dev, data, rx_hprime);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Verify hprime failed. %d\n", ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ drm_dbg_kms(display->drm, "Verify hprime failed. %d\n", ret);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1283,25 +1286,25 @@ static int
hdcp2_store_pairing_info(struct intel_connector *connector,
struct hdcp2_ake_send_pairing_info *pairing_info)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->store_pairing_info(arbiter->hdcp_dev, data, pairing_info);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Store pairing info failed. %d\n",
+ drm_dbg_kms(display->drm, "Store pairing info failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1310,25 +1313,25 @@ static int
hdcp2_prepare_lc_init(struct intel_connector *connector,
struct hdcp2_lc_init *lc_init)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->initiate_locality_check(arbiter->hdcp_dev, data, lc_init);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Prepare lc_init failed. %d\n",
+ drm_dbg_kms(display->drm, "Prepare lc_init failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1337,25 +1340,25 @@ static int
hdcp2_verify_lprime(struct intel_connector *connector,
struct hdcp2_lc_send_lprime *rx_lprime)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->verify_lprime(arbiter->hdcp_dev, data, rx_lprime);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Verify L_Prime failed. %d\n",
+ drm_dbg_kms(display->drm, "Verify L_Prime failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1363,25 +1366,25 @@ hdcp2_verify_lprime(struct intel_connector *connector,
static int hdcp2_prepare_skey(struct intel_connector *connector,
struct hdcp2_ske_send_eks *ske_data)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->get_session_key(arbiter->hdcp_dev, data, ske_data);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Get session key failed. %d\n",
+ drm_dbg_kms(display->drm, "Get session key failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1392,17 +1395,17 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
*rep_topology,
struct hdcp2_rep_send_ack *rep_send_ack)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
@@ -1411,9 +1414,9 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
rep_topology,
rep_send_ack);
if (ret < 0)
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Verify rep topology failed. %d\n", ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1422,71 +1425,71 @@ static int
hdcp2_verify_mprime(struct intel_connector *connector,
struct hdcp2_rep_stream_ready *stream_ready)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->verify_mprime(arbiter->hdcp_dev, data, stream_ready);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Verify mprime failed. %d\n", ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ drm_dbg_kms(display->drm, "Verify mprime failed. %d\n", ret);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
static int hdcp2_authenticate_port(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->enable_hdcp_authentication(arbiter->hdcp_dev, data);
if (ret < 0)
- drm_dbg_kms(&i915->drm, "Enable hdcp auth failed. %d\n",
+ drm_dbg_kms(display->drm, "Enable hdcp auth failed. %d\n",
ret);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
static int hdcp2_close_session(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct i915_hdcp_arbiter *arbiter;
int ret;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- arbiter = i915->display.hdcp.arbiter;
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ arbiter = display->hdcp.arbiter;
if (!arbiter || !arbiter->ops) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return -EINVAL;
}
ret = arbiter->ops->close_hdcp_session(arbiter->hdcp_dev,
&dig_port->hdcp_port_data);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
@@ -1499,7 +1502,7 @@ static int hdcp2_deauthenticate_port(struct intel_connector *connector)
/* Authentication flow starts from here */
static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
union {
struct hdcp2_ake_init ake_init;
@@ -1510,7 +1513,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
} msgs;
const struct intel_hdcp_shim *shim = hdcp->shim;
size_t size;
- int ret;
+ int ret, i;
/* Init for seq_num */
hdcp->seq_num_v = 0;
@@ -1520,27 +1523,50 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
if (ret < 0)
return ret;
- ret = shim->write_2_2_msg(connector, &msgs.ake_init,
- sizeof(msgs.ake_init));
- if (ret < 0)
- return ret;
+ /*
+ * Retry the first read and write to downstream at least 10 times
+ * with a 50ms delay if not hdcp2 capable(dock decides to stop advertising
+ * hdcp2 capability for some reason). The reason being that
+ * during suspend resume dock usually keeps the HDCP2 registers inaccesible
+ * causing AUX error. This wouldn't be a big problem if the userspace
+ * just kept retrying with some delay while it continues to play low
+ * value content but most userpace applications end up throwing an error
+ * when it receives one from KMD. This makes sure we give the dock
+ * and the sink devices to complete its power cycle and then try HDCP
+ * authentication. The values of 10 and delay of 50ms was decided based
+ * on multiple trial and errors.
+ */
+ for (i = 0; i < 10; i++) {
+ if (!intel_hdcp2_get_capability(connector)) {
+ msleep(50);
+ continue;
+ }
+
+ ret = shim->write_2_2_msg(connector, &msgs.ake_init,
+ sizeof(msgs.ake_init));
+ if (ret < 0)
+ continue;
+
+ ret = shim->read_2_2_msg(connector, HDCP_2_2_AKE_SEND_CERT,
+ &msgs.send_cert, sizeof(msgs.send_cert));
+ if (ret > 0)
+ break;
+ }
- ret = shim->read_2_2_msg(connector, HDCP_2_2_AKE_SEND_CERT,
- &msgs.send_cert, sizeof(msgs.send_cert));
if (ret < 0)
return ret;
if (msgs.send_cert.rx_caps[0] != HDCP_2_2_RX_CAPS_VERSION_VAL) {
- drm_dbg_kms(&i915->drm, "cert.rx_caps dont claim HDCP2.2\n");
+ drm_dbg_kms(display->drm, "cert.rx_caps dont claim HDCP2.2\n");
return -EINVAL;
}
hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]);
- if (drm_hdcp_check_ksvs_revoked(&i915->drm,
+ if (drm_hdcp_check_ksvs_revoked(display->drm,
msgs.send_cert.cert_rx.receiver_id,
1) > 0) {
- drm_err(&i915->drm, "Receiver ID is revoked\n");
+ drm_err(display->drm, "Receiver ID is revoked\n");
return -EPERM;
}
@@ -1691,8 +1717,8 @@ out:
static
int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
union {
struct hdcp2_rep_send_receiverid_list recvid_list;
@@ -1712,7 +1738,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
if (HDCP_2_2_MAX_CASCADE_EXCEEDED(rx_info[1]) ||
HDCP_2_2_MAX_DEVS_EXCEEDED(rx_info[1])) {
- drm_dbg_kms(&i915->drm, "Topology Max Size Exceeded\n");
+ drm_dbg_kms(display->drm, "Topology Max Size Exceeded\n");
return -EINVAL;
}
@@ -1725,7 +1751,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
!HDCP_2_2_HDCP_2_0_REP_CONNECTED(rx_info[1]);
if (!dig_port->hdcp_mst_type1_capable && hdcp->content_type) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"HDCP1.x or 2.0 Legacy Device Downstream\n");
return -EINVAL;
}
@@ -1735,23 +1761,23 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v);
if (!hdcp->hdcp2_encrypted && seq_num_v) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Non zero Seq_num_v at first RecvId_List msg\n");
return -EINVAL;
}
if (seq_num_v < hdcp->seq_num_v) {
/* Roll over of the seq_num_v from repeater. Reauthenticate. */
- drm_dbg_kms(&i915->drm, "Seq_num_v roll over.\n");
+ drm_dbg_kms(display->drm, "Seq_num_v roll over.\n");
return -EINVAL;
}
device_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
- if (drm_hdcp_check_ksvs_revoked(&i915->drm,
+ if (drm_hdcp_check_ksvs_revoked(display->drm,
msgs.recvid_list.receiver_ids,
device_cnt) > 0) {
- drm_err(&i915->drm, "Revoked receiver ID(s) is in list\n");
+ drm_err(display->drm, "Revoked receiver ID(s) is in list\n");
return -EPERM;
}
@@ -1772,27 +1798,27 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
static int hdcp2_authenticate_sink(struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
const struct intel_hdcp_shim *shim = hdcp->shim;
int ret;
ret = hdcp2_authentication_key_exchange(connector);
if (ret < 0) {
- drm_dbg_kms(&i915->drm, "AKE Failed. Err : %d\n", ret);
+ drm_dbg_kms(display->drm, "AKE Failed. Err : %d\n", ret);
return ret;
}
ret = hdcp2_locality_check(connector);
if (ret < 0) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Locality Check failed. Err : %d\n", ret);
return ret;
}
ret = hdcp2_session_key_exchange(connector);
if (ret < 0) {
- drm_dbg_kms(&i915->drm, "SKE Failed. Err : %d\n", ret);
+ drm_dbg_kms(display->drm, "SKE Failed. Err : %d\n", ret);
return ret;
}
@@ -1807,7 +1833,7 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector)
if (hdcp->is_repeater) {
ret = hdcp2_authenticate_repeater_topology(connector);
if (ret < 0) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Repeater Auth Failed. Err: %d\n", ret);
return ret;
}
@@ -1818,17 +1844,17 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector)
static int hdcp2_enable_stream_encryption(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
enum port port = dig_port->base.port;
int ret = 0;
- if (!(intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
+ if (!(intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
LINK_ENCRYPTION_STATUS)) {
- drm_err(&i915->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n",
+ drm_err(display->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n",
connector->base.base.id, connector->base.name);
ret = -EPERM;
goto link_recover;
@@ -1837,11 +1863,11 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector)
if (hdcp->shim->stream_2_2_encryption) {
ret = hdcp->shim->stream_2_2_encryption(connector, true);
if (ret) {
- drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n",
+ drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n",
connector->base.base.id, connector->base.name);
return ret;
}
- drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encrypted\n",
+ drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encrypted\n",
transcoder_name(hdcp->stream_transcoder));
}
@@ -1849,7 +1875,7 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector)
link_recover:
if (hdcp2_deauthenticate_port(connector) < 0)
- drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
+ drm_dbg_kms(display->drm, "Port deauth failed.\n");
dig_port->hdcp_auth_status = false;
data->k = 0;
@@ -1859,35 +1885,35 @@ link_recover:
static int hdcp2_enable_encryption(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
int ret;
- drm_WARN_ON(&i915->drm,
- intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
+ drm_WARN_ON(display->drm,
+ intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
LINK_ENCRYPTION_STATUS);
if (hdcp->shim->toggle_signalling) {
ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder,
true);
if (ret) {
- drm_err(&i915->drm,
+ drm_err(display->drm,
"Failed to enable HDCP signalling. %d\n",
ret);
return ret;
}
}
- if (intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
+ if (intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
LINK_AUTH_STATUS)
/* Link is Authenticated. Now set for Encryption */
- intel_de_rmw(i915, HDCP2_CTL(i915, cpu_transcoder, port),
+ intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port),
0, CTL_LINK_ENCRYPTION_REQ);
- ret = intel_de_wait_for_set(i915,
- HDCP2_STATUS(i915, cpu_transcoder,
+ ret = intel_de_wait_for_set(display,
+ HDCP2_STATUS(display, cpu_transcoder,
port),
LINK_ENCRYPTION_STATUS,
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
@@ -1898,32 +1924,33 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
static int hdcp2_disable_encryption(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
int ret;
- drm_WARN_ON(&i915->drm, !(intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) &
- LINK_ENCRYPTION_STATUS));
+ drm_WARN_ON(display->drm,
+ !(intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) &
+ LINK_ENCRYPTION_STATUS));
- intel_de_rmw(i915, HDCP2_CTL(i915, cpu_transcoder, port),
+ intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port),
CTL_LINK_ENCRYPTION_REQ, 0);
- ret = intel_de_wait_for_clear(i915,
- HDCP2_STATUS(i915, cpu_transcoder,
+ ret = intel_de_wait_for_clear(display,
+ HDCP2_STATUS(display, cpu_transcoder,
port),
LINK_ENCRYPTION_STATUS,
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
if (ret == -ETIMEDOUT)
- drm_dbg_kms(&i915->drm, "Disable Encryption Timedout");
+ drm_dbg_kms(display->drm, "Disable Encryption Timedout");
if (hdcp->shim->toggle_signalling) {
ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder,
false);
if (ret) {
- drm_err(&i915->drm,
+ drm_err(display->drm,
"Failed to disable HDCP signalling. %d\n",
ret);
return ret;
@@ -1936,7 +1963,7 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
static int
hdcp2_propagate_stream_management_info(struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
int i, tries = 3, ret;
if (!connector->hdcp.is_repeater)
@@ -1949,12 +1976,12 @@ hdcp2_propagate_stream_management_info(struct intel_connector *connector)
/* Lets restart the auth incase of seq_num_m roll over */
if (connector->hdcp.seq_num_m > HDCP_2_2_SEQ_NUM_MAX) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"seq_num_m roll over.(%d)\n", ret);
break;
}
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"HDCP2 stream management %d of %d Failed.(%d)\n",
i + 1, tries, ret);
}
@@ -1965,8 +1992,8 @@ hdcp2_propagate_stream_management_info(struct intel_connector *connector)
static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
int ret = 0, i, tries = 3;
for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) {
@@ -1974,7 +2001,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
if (!ret) {
ret = intel_hdcp_prepare_streams(state, connector);
if (ret) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Prepare stream failed.(%d)\n",
ret);
break;
@@ -1982,7 +2009,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
ret = hdcp2_propagate_stream_management_info(connector);
if (ret) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Stream management failed.(%d)\n",
ret);
break;
@@ -1991,15 +2018,15 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
ret = hdcp2_authenticate_port(connector);
if (!ret)
break;
- drm_dbg_kms(&i915->drm, "HDCP2 port auth failed.(%d)\n",
+ drm_dbg_kms(display->drm, "HDCP2 port auth failed.(%d)\n",
ret);
}
/* Clearing the mei hdcp session */
- drm_dbg_kms(&i915->drm, "HDCP2.2 Auth %d of %d Failed.(%d)\n",
+ drm_dbg_kms(display->drm, "HDCP2.2 Auth %d of %d Failed.(%d)\n",
i + 1, tries, ret);
if (hdcp2_deauthenticate_port(connector) < 0)
- drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
+ drm_dbg_kms(display->drm, "Port deauth failed.\n");
}
if (!ret && !dig_port->hdcp_auth_status) {
@@ -2010,10 +2037,10 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
msleep(HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN);
ret = hdcp2_enable_encryption(connector);
if (ret < 0) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Encryption Enable Failed.(%d)\n", ret);
if (hdcp2_deauthenticate_port(connector) < 0)
- drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
+ drm_dbg_kms(display->drm, "Port deauth failed.\n");
}
}
@@ -2026,11 +2053,11 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state,
static int _intel_hdcp2_enable(struct intel_atomic_state *state,
struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
- drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being enabled. Type: %d\n",
+ drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being enabled. Type: %d\n",
connector->base.base.id, connector->base.name,
hdcp->content_type);
@@ -2038,12 +2065,12 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state,
ret = hdcp2_authenticate_and_encrypt(state, connector);
if (ret) {
- drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n",
+ drm_dbg_kms(display->drm, "HDCP2 Type%d Enabling Failed. (%d)\n",
hdcp->content_type, ret);
return ret;
}
- drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is enabled. Type %d\n",
+ drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is enabled. Type %d\n",
connector->base.base.id, connector->base.name,
hdcp->content_type);
@@ -2054,23 +2081,23 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state,
static int
_intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
- drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being Disabled\n",
+ drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being Disabled\n",
connector->base.base.id, connector->base.name);
if (hdcp->shim->stream_2_2_encryption) {
ret = hdcp->shim->stream_2_2_encryption(connector, false);
if (ret) {
- drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n",
+ drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n",
connector->base.base.id, connector->base.name);
return ret;
}
- drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n",
+ drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n",
transcoder_name(hdcp->stream_transcoder));
if (dig_port->num_hdcp_streams > 0 && !hdcp2_link_recovery)
@@ -2080,7 +2107,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery
ret = hdcp2_disable_encryption(connector);
if (hdcp2_deauthenticate_port(connector) < 0)
- drm_dbg_kms(&i915->drm, "Port deauth failed.\n");
+ drm_dbg_kms(display->drm, "Port deauth failed.\n");
connector->hdcp.hdcp2_encrypted = false;
dig_port->hdcp_auth_status = false;
@@ -2092,8 +2119,8 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery
/* Implements the Link Integrity Check for HDCP2.2 */
static int intel_hdcp2_check_link(struct intel_connector *connector)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder;
@@ -2110,11 +2137,11 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
goto out;
}
- if (drm_WARN_ON(&i915->drm,
- !intel_hdcp2_in_use(i915, cpu_transcoder, port))) {
- drm_err(&i915->drm,
+ if (drm_WARN_ON(display->drm,
+ !intel_hdcp2_in_use(display, cpu_transcoder, port))) {
+ drm_err(display->drm,
"HDCP2.2 link stopped the encryption, %x\n",
- intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)));
+ intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)));
ret = -ENXIO;
_intel_hdcp2_disable(connector, true);
intel_hdcp_update_value(connector,
@@ -2137,17 +2164,17 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
goto out;
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"HDCP2.2 Downstream topology change\n");
} else {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] HDCP2.2 link failed, retrying auth\n",
connector->base.base.id, connector->base.name);
}
ret = _intel_hdcp2_disable(connector, true);
if (ret) {
- drm_err(&i915->drm,
+ drm_err(display->drm,
"[CONNECTOR:%d:%s] Failed to disable hdcp2.2 (%d)\n",
connector->base.base.id, connector->base.name, ret);
intel_hdcp_update_value(connector,
@@ -2169,7 +2196,8 @@ static void intel_hdcp_check_work(struct work_struct *work)
struct intel_hdcp,
check_work);
struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
+ struct drm_i915_private *i915 = to_i915(display->drm);
if (drm_connector_is_unregistered(&connector->base))
return;
@@ -2186,13 +2214,12 @@ static int i915_hdcp_component_bind(struct device *drv_kdev,
struct device *mei_kdev, void *data)
{
struct intel_display *display = to_intel_display(drv_kdev);
- struct drm_i915_private *i915 = to_i915(display->drm);
- drm_dbg(&i915->drm, "I915 HDCP comp bind\n");
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- i915->display.hdcp.arbiter = (struct i915_hdcp_arbiter *)data;
- i915->display.hdcp.arbiter->hdcp_dev = mei_kdev;
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ drm_dbg(display->drm, "I915 HDCP comp bind\n");
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ display->hdcp.arbiter = (struct i915_hdcp_arbiter *)data;
+ display->hdcp.arbiter->hdcp_dev = mei_kdev;
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return 0;
}
@@ -2201,12 +2228,11 @@ static void i915_hdcp_component_unbind(struct device *drv_kdev,
struct device *mei_kdev, void *data)
{
struct intel_display *display = to_intel_display(drv_kdev);
- struct drm_i915_private *i915 = to_i915(display->drm);
- drm_dbg(&i915->drm, "I915 HDCP comp unbind\n");
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- i915->display.hdcp.arbiter = NULL;
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ drm_dbg(display->drm, "I915 HDCP comp unbind\n");
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ display->hdcp.arbiter = NULL;
+ mutex_unlock(&display->hdcp.hdcp_mutex);
}
static const struct component_ops i915_hdcp_ops = {
@@ -2240,11 +2266,11 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
struct intel_digital_port *dig_port,
const struct intel_hdcp_shim *shim)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
enum port port = dig_port->base.port;
- if (DISPLAY_VER(i915) < 12)
+ if (DISPLAY_VER(display) < 12)
data->hdcp_ddi = intel_get_hdcp_ddi_index(port);
else
/*
@@ -2264,11 +2290,11 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
data->protocol = (u8)shim->protocol;
if (!data->streams)
- data->streams = kcalloc(INTEL_NUM_PIPES(i915),
+ data->streams = kcalloc(INTEL_NUM_PIPES(display),
sizeof(struct hdcp2_streamid_type),
GFP_KERNEL);
if (!data->streams) {
- drm_err(&i915->drm, "Out of Memory\n");
+ drm_err(display->drm, "Out of Memory\n");
return -ENOMEM;
}
@@ -2277,13 +2303,15 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
static bool is_hdcp2_supported(struct drm_i915_private *i915)
{
- if (intel_hdcp_gsc_cs_required(i915))
+ struct intel_display *display = to_intel_display(&i915->drm);
+
+ if (intel_hdcp_gsc_cs_required(display))
return true;
if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
return false;
- return (DISPLAY_VER(i915) >= 10 ||
+ return (DISPLAY_VER(display) >= 10 ||
IS_KABYLAKE(i915) ||
IS_COFFEELAKE(i915) ||
IS_COMETLAKE(i915));
@@ -2291,28 +2319,29 @@ static bool is_hdcp2_supported(struct drm_i915_private *i915)
void intel_hdcp_component_init(struct drm_i915_private *i915)
{
+ struct intel_display *display = to_intel_display(&i915->drm);
int ret;
if (!is_hdcp2_supported(i915))
return;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- drm_WARN_ON(&i915->drm, i915->display.hdcp.comp_added);
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ drm_WARN_ON(display->drm, display->hdcp.comp_added);
- i915->display.hdcp.comp_added = true;
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
- if (intel_hdcp_gsc_cs_required(i915))
- ret = intel_hdcp_gsc_init(i915);
+ display->hdcp.comp_added = true;
+ mutex_unlock(&display->hdcp.hdcp_mutex);
+ if (intel_hdcp_gsc_cs_required(display))
+ ret = intel_hdcp_gsc_init(display);
else
- ret = component_add_typed(i915->drm.dev, &i915_hdcp_ops,
+ ret = component_add_typed(display->drm->dev, &i915_hdcp_ops,
I915_COMPONENT_HDCP);
if (ret < 0) {
- drm_dbg_kms(&i915->drm, "Failed at fw component add(%d)\n",
+ drm_dbg_kms(display->drm, "Failed at fw component add(%d)\n",
ret);
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- i915->display.hdcp.comp_added = false;
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ display->hdcp.comp_added = false;
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return;
}
}
@@ -2321,13 +2350,13 @@ static void intel_hdcp2_init(struct intel_connector *connector,
struct intel_digital_port *dig_port,
const struct intel_hdcp_shim *shim)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
ret = initialize_hdcp_port_data(connector, dig_port, shim);
if (ret) {
- drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
+ drm_dbg_kms(display->drm, "Mei hdcp data init failed\n");
return;
}
@@ -2371,7 +2400,8 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
const struct intel_crtc_state *pipe_config,
const struct drm_connector_state *conn_state)
{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_display *display = to_intel_display(encoder);
+ struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
@@ -2383,14 +2413,14 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
return -ENOENT;
if (!connector->encoder) {
- drm_err(&i915->drm, "[CONNECTOR:%d:%s] encoder is not initialized\n",
+ drm_err(display->drm, "[CONNECTOR:%d:%s] encoder is not initialized\n",
connector->base.base.id, connector->base.name);
return -ENODEV;
}
mutex_lock(&hdcp->mutex);
mutex_lock(&dig_port->hdcp_mutex);
- drm_WARN_ON(&i915->drm,
+ drm_WARN_ON(display->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
hdcp->content_type = (u8)conn_state->hdcp_content_type;
@@ -2555,19 +2585,21 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
void intel_hdcp_component_fini(struct drm_i915_private *i915)
{
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- if (!i915->display.hdcp.comp_added) {
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ struct intel_display *display = to_intel_display(&i915->drm);
+
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ if (!display->hdcp.comp_added) {
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return;
}
- i915->display.hdcp.comp_added = false;
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ display->hdcp.comp_added = false;
+ mutex_unlock(&display->hdcp.hdcp_mutex);
- if (intel_hdcp_gsc_cs_required(i915))
- intel_hdcp_gsc_fini(i915);
+ if (intel_hdcp_gsc_cs_required(display))
+ intel_hdcp_gsc_fini(display);
else
- component_del(i915->drm.dev, &i915_hdcp_ops);
+ component_del(display->drm->dev, &i915_hdcp_ops);
}
void intel_hdcp_cleanup(struct intel_connector *connector)
@@ -2657,7 +2689,8 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
{
struct intel_hdcp *hdcp = &connector->hdcp;
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
+ struct drm_i915_private *i915 = to_i915(display->drm);
if (!hdcp->shim)
return;
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index 16afeb8a3a8d..55965844d829 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -19,18 +19,19 @@ struct intel_hdcp_gsc_message {
void *hdcp_cmd_out;
};
-bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)
+bool intel_hdcp_gsc_cs_required(struct intel_display *display)
{
- return DISPLAY_VER(i915) >= 14;
+ return DISPLAY_VER(display) >= 14;
}
-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)
+bool intel_hdcp_gsc_check_status(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_gt *gt = i915->media_gt;
struct intel_gsc_uc *gsc = gt ? &gt->uc.gsc : NULL;
if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"GSC components required for HDCP2.2 are not ready\n");
return false;
}
@@ -106,8 +107,9 @@ static const struct i915_hdcp_ops gsc_hdcp_ops = {
.close_hdcp_session = intel_hdcp_gsc_close_session,
};
-static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915)
+static int intel_hdcp_gsc_hdcp2_init(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hdcp_gsc_message *hdcp_message;
int ret;
@@ -120,19 +122,19 @@ static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915)
* NOTE: No need to lock the comp mutex here as it is already
* going to be taken before this function called
*/
- i915->display.hdcp.hdcp_message = hdcp_message;
+ display->hdcp.hdcp_message = hdcp_message;
ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message);
if (ret)
- drm_err(&i915->drm, "Could not initialize hdcp_message\n");
+ drm_err(display->drm, "Could not initialize hdcp_message\n");
return ret;
}
-static void intel_hdcp_gsc_free_message(struct drm_i915_private *i915)
+static void intel_hdcp_gsc_free_message(struct intel_display *display)
{
struct intel_hdcp_gsc_message *hdcp_message =
- i915->display.hdcp.hdcp_message;
+ display->hdcp.hdcp_message;
hdcp_message->hdcp_cmd_in = NULL;
hdcp_message->hdcp_cmd_out = NULL;
@@ -140,7 +142,7 @@ static void intel_hdcp_gsc_free_message(struct drm_i915_private *i915)
kfree(hdcp_message);
}
-int intel_hdcp_gsc_init(struct drm_i915_private *i915)
+int intel_hdcp_gsc_init(struct intel_display *display)
{
struct i915_hdcp_arbiter *data;
int ret;
@@ -149,20 +151,20 @@ int intel_hdcp_gsc_init(struct drm_i915_private *i915)
if (!data)
return -ENOMEM;
- mutex_lock(&i915->display.hdcp.hdcp_mutex);
- i915->display.hdcp.arbiter = data;
- i915->display.hdcp.arbiter->hdcp_dev = i915->drm.dev;
- i915->display.hdcp.arbiter->ops = &gsc_hdcp_ops;
- ret = intel_hdcp_gsc_hdcp2_init(i915);
- mutex_unlock(&i915->display.hdcp.hdcp_mutex);
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ display->hdcp.arbiter = data;
+ display->hdcp.arbiter->hdcp_dev = display->drm->dev;
+ display->hdcp.arbiter->ops = &gsc_hdcp_ops;
+ ret = intel_hdcp_gsc_hdcp2_init(display);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
-void intel_hdcp_gsc_fini(struct drm_i915_private *i915)
+void intel_hdcp_gsc_fini(struct intel_display *display)
{
- intel_hdcp_gsc_free_message(i915);
- kfree(i915->display.hdcp.arbiter);
+ intel_hdcp_gsc_free_message(display);
+ kfree(display->hdcp.arbiter);
}
static int intel_gsc_send_sync(struct drm_i915_private *i915,
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
index 5f610df61cc9..5695a5e4f609 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h
@@ -10,14 +10,15 @@
#include <linux/types.h>
struct drm_i915_private;
+struct intel_display;
struct intel_hdcp_gsc_message;
-bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915);
+bool intel_hdcp_gsc_cs_required(struct intel_display *display);
ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
size_t msg_in_len, u8 *msg_out,
size_t msg_out_len);
-int intel_hdcp_gsc_init(struct drm_i915_private *i915);
-void intel_hdcp_gsc_fini(struct drm_i915_private *i915);
-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915);
+int intel_hdcp_gsc_init(struct intel_display *display);
+void intel_hdcp_gsc_fini(struct intel_display *display);
+bool intel_hdcp_gsc_check_status(struct intel_display *display);
#endif /* __INTEL_HDCP_GCS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
index 35bdb532bbb3..129104fa9b16 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
@@ -46,12 +46,12 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
(u8 *)&session_init_out,
sizeof(session_init_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
WIRED_INITIATE_HDCP2_SESSION,
session_init_out.header.status);
return -EIO;
@@ -108,12 +108,12 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
(u8 *)&verify_rxcert_out,
sizeof(verify_rxcert_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte);
return byte;
}
if (verify_rxcert_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
WIRED_VERIFY_RECEIVER_CERT,
verify_rxcert_out.header.status);
return -EIO;
@@ -171,12 +171,12 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,
(u8 *)&send_hprime_out,
sizeof(send_hprime_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (send_hprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status);
return -EIO;
}
@@ -222,12 +222,12 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat
(u8 *)&pairing_info_out,
sizeof(pairing_info_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (pairing_info_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. Status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. Status: 0x%X\n",
WIRED_AKE_SEND_PAIRING_INFO,
pairing_info_out.header.status);
return -EIO;
@@ -269,12 +269,12 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev,
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&lc_init_in, sizeof(lc_init_in),
(u8 *)&lc_init_out, sizeof(lc_init_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (lc_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. status: 0x%X\n",
WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status);
return -EIO;
}
@@ -323,12 +323,12 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,
(u8 *)&verify_lprime_out,
sizeof(verify_lprime_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (verify_lprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
WIRED_VALIDATE_LOCALITY,
verify_lprime_out.header.status);
return -EIO;
@@ -369,12 +369,12 @@ int intel_hdcp_gsc_get_session_key(struct device *dev,
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&get_skey_in, sizeof(get_skey_in),
(u8 *)&get_skey_out, sizeof(get_skey_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (get_skey_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
WIRED_GET_SESSION_KEY, get_skey_out.header.status);
return -EIO;
}
@@ -435,12 +435,12 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
(u8 *)&verify_repeater_out,
sizeof(verify_repeater_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (verify_repeater_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
WIRED_VERIFY_REPEATER,
verify_repeater_out.header.status);
return -EIO;
@@ -504,12 +504,12 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev,
sizeof(verify_mprime_out));
kfree(verify_mprime_in);
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (verify_mprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
WIRED_REPEATER_AUTH_STREAM_REQ,
verify_mprime_out.header.status);
return -EIO;
@@ -552,12 +552,12 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev,
(u8 *)&enable_auth_out,
sizeof(enable_auth_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (enable_auth_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
WIRED_ENABLE_AUTH, enable_auth_out.header.status);
return -EIO;
}
@@ -599,12 +599,12 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)
(u8 *)&session_close_out,
sizeof(session_close_out));
if (byte < 0) {
- drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
+ drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
}
if (session_close_out.header.status != FW_HDCP_STATUS_SUCCESS) {
- drm_dbg_kms(&i915->drm, "Session Close Failed. status: 0x%X\n",
+ drm_dbg_kms(display->drm, "Session Close Failed. status: 0x%X\n",
session_close_out.header.status);
return -EIO;
}
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
index ce199d6f6232..2d597f27e931 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
@@ -22,11 +22,12 @@ struct hdcp2_ske_send_eks;
struct hdcp2_rep_send_receiverid_list;
struct hdcp2_rep_send_ack;
struct hdcp2_rep_stream_ready;
+struct intel_display;
ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
size_t msg_in_len, u8 *msg_out,
size_t msg_out_len);
-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915);
+bool intel_hdcp_gsc_check_status(struct intel_display *display);
int
intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
struct hdcp2_ake_init *ake_data);
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_shim.h b/drivers/gpu/drm/i915/display/intel_hdcp_shim.h
new file mode 100644
index 000000000000..abf9ae2f4ada
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_shim.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2024 Intel Corporation */
+
+#ifndef __INTEL_HDCP_SHIM_H__
+#define __INTEL_HDCP_SHIM_H__
+
+#include <linux/types.h>
+
+#include <drm/intel/i915_hdcp_interface.h>
+
+enum transcoder;
+struct intel_connector;
+struct intel_digital_port;
+
+enum check_link_response {
+ HDCP_LINK_PROTECTED = 0,
+ HDCP_TOPOLOGY_CHANGE,
+ HDCP_LINK_INTEGRITY_FAILURE,
+ HDCP_REAUTH_REQUEST
+};
+
+/*
+ * This structure serves as a translation layer between the generic HDCP code
+ * and the bus-specific code. What that means is that HDCP over HDMI differs
+ * from HDCP over DP, so to account for these differences, we need to
+ * communicate with the receiver through this shim.
+ *
+ * For completeness, the 2 buses differ in the following ways:
+ * - DP AUX vs. DDC
+ * HDCP registers on the receiver are set via DP AUX for DP, and
+ * they are set via DDC for HDMI.
+ * - Receiver register offsets
+ * The offsets of the registers are different for DP vs. HDMI
+ * - Receiver register masks/offsets
+ * For instance, the ready bit for the KSV fifo is in a different
+ * place on DP vs HDMI
+ * - Receiver register names
+ * Seriously. In the DP spec, the 16-bit register containing
+ * downstream information is called BINFO, on HDMI it's called
+ * BSTATUS. To confuse matters further, DP has a BSTATUS register
+ * with a completely different definition.
+ * - KSV FIFO
+ * On HDMI, the ksv fifo is read all at once, whereas on DP it must
+ * be read 3 keys at a time
+ * - Aksv output
+ * Since Aksv is hidden in hardware, there's different procedures
+ * to send it over DP AUX vs DDC
+ */
+struct intel_hdcp_shim {
+ /* Outputs the transmitter's An and Aksv values to the receiver. */
+ int (*write_an_aksv)(struct intel_digital_port *dig_port, u8 *an);
+
+ /* Reads the receiver's key selection vector */
+ int (*read_bksv)(struct intel_digital_port *dig_port, u8 *bksv);
+
+ /*
+ * Reads BINFO from DP receivers and BSTATUS from HDMI receivers. The
+ * definitions are the same in the respective specs, but the names are
+ * different. Call it BSTATUS since that's the name the HDMI spec
+ * uses and it was there first.
+ */
+ int (*read_bstatus)(struct intel_digital_port *dig_port,
+ u8 *bstatus);
+
+ /* Determines whether a repeater is present downstream */
+ int (*repeater_present)(struct intel_digital_port *dig_port,
+ bool *repeater_present);
+
+ /* Reads the receiver's Ri' value */
+ int (*read_ri_prime)(struct intel_digital_port *dig_port, u8 *ri);
+
+ /* Determines if the receiver's KSV FIFO is ready for consumption */
+ int (*read_ksv_ready)(struct intel_digital_port *dig_port,
+ bool *ksv_ready);
+
+ /* Reads the ksv fifo for num_downstream devices */
+ int (*read_ksv_fifo)(struct intel_digital_port *dig_port,
+ int num_downstream, u8 *ksv_fifo);
+
+ /* Reads a 32-bit part of V' from the receiver */
+ int (*read_v_prime_part)(struct intel_digital_port *dig_port,
+ int i, u32 *part);
+
+ /* Enables HDCP signalling on the port */
+ int (*toggle_signalling)(struct intel_digital_port *dig_port,
+ enum transcoder cpu_transcoder,
+ bool enable);
+
+ /* Enable/Disable stream encryption on DP MST Transport Link */
+ int (*stream_encryption)(struct intel_connector *connector,
+ bool enable);
+
+ /* Ensures the link is still protected */
+ bool (*check_link)(struct intel_digital_port *dig_port,
+ struct intel_connector *connector);
+
+ /* Detects panel's hdcp capability. This is optional for HDMI. */
+ int (*hdcp_get_capability)(struct intel_digital_port *dig_port,
+ bool *hdcp_capable);
+
+ /* HDCP adaptation(DP/HDMI) required on the port */
+ enum hdcp_wired_protocol protocol;
+
+ /* Detects whether sink is HDCP2.2 capable */
+ int (*hdcp_2_2_get_capability)(struct intel_connector *connector,
+ bool *capable);
+
+ /* Write HDCP2.2 messages */
+ int (*write_2_2_msg)(struct intel_connector *connector,
+ void *buf, size_t size);
+
+ /* Read HDCP2.2 messages */
+ int (*read_2_2_msg)(struct intel_connector *connector,
+ u8 msg_id, void *buf, size_t size);
+
+ /*
+ * Implementation of DP HDCP2.2 Errata for the communication of stream
+ * type to Receivers. In DP HDCP2.2 Stream type is one of the input to
+ * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI.
+ */
+ int (*config_stream_type)(struct intel_connector *connector,
+ bool is_repeater, u8 type);
+
+ /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */
+ int (*stream_2_2_encryption)(struct intel_connector *connector,
+ bool enable);
+
+ /* HDCP2.2 Link Integrity Check */
+ int (*check_2_2_link)(struct intel_digital_port *dig_port,
+ struct intel_connector *connector);
+
+ /* HDCP remote sink cap */
+ int (*get_remote_hdcp_capability)(struct intel_connector *connector,
+ bool *hdcp_capable, bool *hdcp2_capable);
+};
+
+#endif /* __INTEL_HDCP_SHIM_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index cd9ee171e0df..72ac910bf6ec 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -38,8 +38,11 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_probe_helper.h>
#include <drm/intel/intel_lpe_audio.h>
+#include <media/cec-notifier.h>
+
#include "g4x_hdmi.h"
#include "i915_drv.h"
#include "i915_reg.h"
@@ -55,6 +58,7 @@
#include "intel_gmbus.h"
#include "intel_hdcp.h"
#include "intel_hdcp_regs.h"
+#include "intel_hdcp_shim.h"
#include "intel_hdmi.h"
#include "intel_lspcon.h"
#include "intel_panel.h"
@@ -1310,8 +1314,8 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port,
memcpy(&write_buf[1], buffer, size);
msg.addr = DRM_HDCP_DDC_ADDR;
- msg.flags = 0,
- msg.len = size + 1,
+ msg.flags = 0;
+ msg.len = size + 1;
msg.buf = write_buf;
ret = i2c_transfer(ddc, &msg, 1);
@@ -2053,7 +2057,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
return status;
}
- return intel_mode_valid_max_plane_size(dev_priv, mode, false);
+ return intel_mode_valid_max_plane_size(dev_priv, mode, 1);
}
bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c
index d9ec349f3c8c..a013b0e0ef54 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.c
@@ -21,8 +21,11 @@
* IN THE SOFTWARE.
*/
+#include <linux/debugfs.h>
#include <linux/kernel.h>
+#include <drm/drm_probe_helper.h>
+
#include "i915_drv.h"
#include "i915_irq.h"
#include "intel_display_power.h"
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
index 2c4e946d5575..5d055dc9366f 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
@@ -849,10 +849,11 @@ static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv)
enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
- if (INTEL_PCH_TYPE(dev_priv) <= PCH_TGP)
- intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ);
- else
- intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
+ /*
+ * We reduce the value to 250us to be able to detect SHPD when an external display
+ * is connected. This is also expected of us as stated in DP1.4a Table 3-4.
+ */
+ intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
@@ -1060,6 +1061,10 @@ static void mtp_hpd_irq_setup(struct drm_i915_private *i915)
enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd);
hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd);
+ /*
+ * Use 250us here to align with the DP1.4a(Table 3-4) spec as to what the
+ * SHPD_FILTER_CNT value should be.
+ */
intel_de_write(i915, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
mtp_hpd_invert(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c
index e7a9b860fac6..c87cd1d16d0a 100644
--- a/drivers/gpu/drm/i915/display/intel_link_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
@@ -26,7 +26,6 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
struct intel_link_bw_limits *limits)
{
struct intel_display *display = to_intel_display(state);
- struct drm_i915_private *i915 = to_i915(state->base.dev);
enum pipe pipe;
limits->force_fec_pipes = 0;
@@ -34,7 +33,7 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
for_each_pipe(display, pipe) {
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state,
- intel_crtc_for_pipe(i915, pipe));
+ intel_crtc_for_pipe(display, pipe));
if (state->base.duplicated && crtc_state) {
limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index fb4ed9f7855b..5f753ee743c6 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -37,6 +37,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -263,7 +264,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
temp |= LVDS_PIPE_SEL(pipe);
}
- /* set the corresponsding LVDS_BORDER bit */
+ /* set the corresponding LVDS_BORDER bit */
temp &= ~LVDS_BORDER_ENABLE;
temp |= crtc_state->gmch_pfit.lvds_border_bits;
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
index 72694dde3c22..2c8668b1ebae 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
@@ -8,6 +8,7 @@
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -221,6 +222,7 @@ static u8 get_transcoder_pipes(struct drm_i915_private *i915,
static void get_portsync_pipes(struct intel_crtc *crtc,
u8 *master_pipe_mask, u8 *slave_pipes_mask)
{
+ struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -243,7 +245,7 @@ static void get_portsync_pipes(struct intel_crtc *crtc,
*master_pipe_mask = get_transcoder_pipes(i915, BIT(master_transcoder));
drm_WARN_ON(&i915->drm, !is_power_of_2(*master_pipe_mask));
- master_crtc = intel_crtc_for_pipe(i915, ffs(*master_pipe_mask) - 1);
+ master_crtc = intel_crtc_for_pipe(display, ffs(*master_pipe_mask) - 1);
master_crtc_state = to_intel_crtc_state(master_crtc->base.state);
*slave_pipes_mask = get_transcoder_pipes(i915, master_crtc_state->sync_mode_slaves_mask);
}
@@ -375,6 +377,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
static void
intel_sanitize_plane_mapping(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
struct intel_crtc *crtc;
if (DISPLAY_VER(i915) >= 4)
@@ -396,7 +399,7 @@ intel_sanitize_plane_mapping(struct drm_i915_private *i915)
"[PLANE:%d:%s] attached to the wrong pipe, disabling plane\n",
plane->base.base.id, plane->base.name);
- plane_crtc = intel_crtc_for_pipe(i915, pipe);
+ plane_crtc = intel_crtc_for_pipe(display, pipe);
intel_plane_disable_noatomic(plane_crtc, plane);
}
}
@@ -490,8 +493,8 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc,
}
/* Disable any background color/etc. set by the BIOS */
- intel_color_commit_noarm(crtc_state);
- intel_color_commit_arm(crtc_state);
+ intel_color_commit_noarm(NULL, crtc_state);
+ intel_color_commit_arm(NULL, crtc_state);
}
if (!crtc_state->hw.active ||
@@ -662,6 +665,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
/* FIXME read out full plane state for all planes */
static void readout_plane_state(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
struct intel_plane *plane;
struct intel_crtc *crtc;
@@ -674,7 +678,7 @@ static void readout_plane_state(struct drm_i915_private *i915)
visible = plane->get_hw_state(plane, &pipe);
- crtc = intel_crtc_for_pipe(i915, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
crtc_state = to_intel_crtc_state(crtc->base.state);
intel_set_plane_visible(crtc_state, plane_state, visible);
@@ -695,6 +699,7 @@ static void readout_plane_state(struct drm_i915_private *i915)
static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(i915->display.cdclk.obj.state);
struct intel_dbuf_state *dbuf_state =
@@ -743,7 +748,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
pipe = 0;
if (encoder->get_hw_state(encoder, &pipe)) {
- crtc = intel_crtc_for_pipe(i915, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
crtc_state = to_intel_crtc_state(crtc->base.state);
encoder->base.crtc = &crtc->base;
@@ -955,6 +960,7 @@ static void intel_early_display_was(struct drm_i915_private *i915)
void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
struct drm_modeset_acquire_ctx *ctx)
{
+ struct intel_display *display = &i915->display;
struct intel_encoder *encoder;
struct intel_crtc *crtc;
intel_wakeref_t wakeref;
@@ -982,7 +988,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
drm_crtc_vblank_reset(&crtc->base);
if (crtc_state->hw.active) {
- intel_dmc_enable_pipe(i915, crtc->pipe);
+ intel_dmc_enable_pipe(display, crtc->pipe);
intel_crtc_vblank_on(crtc_state);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c
index ff11836459de..0eaa6cd6fe80 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.c
+++ b/drivers/gpu/drm/i915/display/intel_opregion.c
@@ -26,6 +26,7 @@
*/
#include <linux/acpi.h>
+#include <linux/debugfs.h>
#include <linux/dmi.h>
#include <acpi/video.h>
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c
index 06b1122ec13e..2ec14096ba9c 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.c
+++ b/drivers/gpu/drm/i915/display/intel_overlay.c
@@ -294,7 +294,7 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
drm_WARN_ON(&overlay->i915->drm, overlay->old_vma);
if (vma)
- frontbuffer = intel_frontbuffer_get(vma->obj);
+ frontbuffer = intel_frontbuffer_get(intel_bo_to_drm_bo(vma->obj));
intel_frontbuffer_track(overlay->frontbuffer, frontbuffer,
INTEL_FRONTBUFFER_OVERLAY(pipe));
@@ -1457,18 +1457,19 @@ void intel_overlay_cleanup(struct drm_i915_private *dev_priv)
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
-struct intel_overlay_error_state {
+struct intel_overlay_snapshot {
struct overlay_registers regs;
unsigned long base;
u32 dovsta;
u32 isr;
};
-struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
+struct intel_overlay_snapshot *
+intel_overlay_snapshot_capture(struct intel_display *display)
{
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_overlay *overlay = dev_priv->display.overlay;
- struct intel_overlay_error_state *error;
+ struct intel_overlay_snapshot *error;
if (!overlay || !overlay->active)
return NULL;
@@ -1487,9 +1488,12 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
}
void
-intel_overlay_print_error_state(struct drm_printer *p,
- struct intel_overlay_error_state *error)
+intel_overlay_snapshot_print(const struct intel_overlay_snapshot *error,
+ struct drm_printer *p)
{
+ if (!error)
+ return;
+
drm_printf(p, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
error->dovsta, error->isr);
drm_printf(p, " Register file at 0x%08lx:\n", error->base);
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.h b/drivers/gpu/drm/i915/display/intel_overlay.h
index f28a09c062d0..eafac24d1de8 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.h
+++ b/drivers/gpu/drm/i915/display/intel_overlay.h
@@ -6,12 +6,15 @@
#ifndef __INTEL_OVERLAY_H__
#define __INTEL_OVERLAY_H__
+#include <linux/types.h>
+
struct drm_device;
struct drm_file;
struct drm_i915_private;
struct drm_printer;
+struct intel_display;
struct intel_overlay;
-struct intel_overlay_error_state;
+struct intel_overlay_snapshot;
#ifdef I915
void intel_overlay_setup(struct drm_i915_private *dev_priv);
@@ -22,10 +25,6 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void intel_overlay_reset(struct drm_i915_private *dev_priv);
-struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_i915_private *dev_priv);
-void intel_overlay_print_error_state(struct drm_printer *p,
- struct intel_overlay_error_state *error);
#else
static inline void intel_overlay_setup(struct drm_i915_private *dev_priv)
{
@@ -50,13 +49,21 @@ static inline int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
static inline void intel_overlay_reset(struct drm_i915_private *dev_priv)
{
}
-static inline struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
+#endif
+
+#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) && defined(I915)
+struct intel_overlay_snapshot *
+intel_overlay_snapshot_capture(struct intel_display *display);
+void intel_overlay_snapshot_print(const struct intel_overlay_snapshot *error,
+ struct drm_printer *p);
+#else
+static inline struct intel_overlay_snapshot *
+intel_overlay_snapshot_capture(struct intel_display *display)
{
return NULL;
}
-static inline void intel_overlay_print_error_state(struct drm_printer *p,
- struct intel_overlay_error_state *error)
+static inline void intel_overlay_snapshot_print(const struct intel_overlay_snapshot *error,
+ struct drm_printer *p)
{
}
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
index 82ceede0b2b1..304da826dee1 100644
--- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
@@ -32,6 +32,7 @@
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_de.h"
+#include "intel_display_irq.h"
#include "intel_display_types.h"
#include "intel_pipe_crc.h"
#include "intel_pipe_crc_regs.h"
@@ -285,6 +286,9 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
struct drm_modeset_acquire_ctx ctx;
int ret;
+ if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv))
+ i915gm_irq_cstate_wa(dev_priv, enable);
+
drm_modeset_acquire_init(&ctx, 0);
state = drm_atomic_state_alloc(&dev_priv->drm);
diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
index ada1792df5b3..62401f6a04e4 100644
--- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
+++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
@@ -302,7 +302,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
if (intel_framebuffer_init(to_intel_framebuffer(fb),
- vma->obj, &mode_cmd)) {
+ intel_bo_to_drm_bo(vma->obj), &mode_cmd)) {
drm_dbg_kms(&dev_priv->drm, "intel fb init failed\n");
goto err_vma;
}
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index feddc30e3375..ffeee9daa568 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -3,6 +3,8 @@
* Copyright © 2020 Intel Corporation
*/
+#include <linux/debugfs.h>
+
#include "g4x_dp.h"
#include "i915_drv.h"
#include "i915_reg.h"
@@ -31,7 +33,7 @@ static const char *pps_name(struct intel_dp *intel_dp)
struct intel_pps *pps = &intel_dp->pps;
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
- switch (pps->pps_pipe) {
+ switch (pps->vlv_pps_pipe) {
case INVALID_PIPE:
/*
* FIXME would be nice if we can guarantee
@@ -43,7 +45,7 @@ static const char *pps_name(struct intel_dp *intel_dp)
case PIPE_B:
return "PPS B";
default:
- MISSING_CASE(pps->pps_pipe);
+ MISSING_CASE(pps->vlv_pps_pipe);
break;
}
} else {
@@ -68,7 +70,7 @@ intel_wakeref_t intel_pps_lock(struct intel_dp *intel_dp)
intel_wakeref_t wakeref;
/*
- * See intel_pps_reset_all() why we need a power domain reference here.
+ * See vlv_pps_reset_all() why we need a power domain reference here.
*/
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);
mutex_lock(&display->pps.mutex);
@@ -85,7 +87,7 @@ intel_wakeref_t intel_pps_unlock(struct intel_dp *intel_dp,
mutex_unlock(&display->pps.mutex);
intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
- return 0;
+ return NULL;
}
static void
@@ -94,7 +96,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
- enum pipe pipe = intel_dp->pps.pps_pipe;
+ enum pipe pipe = intel_dp->pps.vlv_pps_pipe;
bool pll_enabled, release_cl_override = false;
enum dpio_phy phy = vlv_pipe_to_phy(pipe);
enum dpio_channel ch = vlv_pipe_to_channel(pipe);
@@ -180,18 +182,18 @@ static enum pipe vlv_find_free_pps(struct intel_display *display)
if (encoder->type == INTEL_OUTPUT_EDP) {
drm_WARN_ON(display->drm,
- intel_dp->pps.active_pipe != INVALID_PIPE &&
- intel_dp->pps.active_pipe !=
- intel_dp->pps.pps_pipe);
+ intel_dp->pps.vlv_active_pipe != INVALID_PIPE &&
+ intel_dp->pps.vlv_active_pipe !=
+ intel_dp->pps.vlv_pps_pipe);
- if (intel_dp->pps.pps_pipe != INVALID_PIPE)
- pipes &= ~(1 << intel_dp->pps.pps_pipe);
+ if (intel_dp->pps.vlv_pps_pipe != INVALID_PIPE)
+ pipes &= ~(1 << intel_dp->pps.vlv_pps_pipe);
} else {
drm_WARN_ON(display->drm,
- intel_dp->pps.pps_pipe != INVALID_PIPE);
+ intel_dp->pps.vlv_pps_pipe != INVALID_PIPE);
- if (intel_dp->pps.active_pipe != INVALID_PIPE)
- pipes &= ~(1 << intel_dp->pps.active_pipe);
+ if (intel_dp->pps.vlv_active_pipe != INVALID_PIPE)
+ pipes &= ~(1 << intel_dp->pps.vlv_active_pipe);
}
}
@@ -213,11 +215,11 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
/* We should never land here with regular DP ports */
drm_WARN_ON(display->drm, !intel_dp_is_edp(intel_dp));
- drm_WARN_ON(display->drm, intel_dp->pps.active_pipe != INVALID_PIPE &&
- intel_dp->pps.active_pipe != intel_dp->pps.pps_pipe);
+ drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE &&
+ intel_dp->pps.vlv_active_pipe != intel_dp->pps.vlv_pps_pipe);
- if (intel_dp->pps.pps_pipe != INVALID_PIPE)
- return intel_dp->pps.pps_pipe;
+ if (intel_dp->pps.vlv_pps_pipe != INVALID_PIPE)
+ return intel_dp->pps.vlv_pps_pipe;
pipe = vlv_find_free_pps(display);
@@ -229,7 +231,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
pipe = PIPE_A;
vlv_steal_power_sequencer(display, pipe);
- intel_dp->pps.pps_pipe = pipe;
+ intel_dp->pps.vlv_pps_pipe = pipe;
drm_dbg_kms(display->drm,
"picked %s for [ENCODER:%d:%s]\n",
@@ -246,7 +248,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
*/
vlv_power_sequencer_kick(intel_dp);
- return intel_dp->pps.pps_pipe;
+ return intel_dp->pps.vlv_pps_pipe;
}
static int
@@ -260,10 +262,10 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp)
/* We should never land here with regular DP ports */
drm_WARN_ON(display->drm, !intel_dp_is_edp(intel_dp));
- if (!intel_dp->pps.pps_reset)
+ if (!intel_dp->pps.bxt_pps_reset)
return pps_idx;
- intel_dp->pps.pps_reset = false;
+ intel_dp->pps.bxt_pps_reset = false;
/*
* Only the HW needs to be reprogrammed, the SW state is fixed and
@@ -325,19 +327,19 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
/* try to find a pipe with this port selected */
/* first pick one where the panel is on */
- intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(display, port,
- pps_has_pp_on);
+ intel_dp->pps.vlv_pps_pipe = vlv_initial_pps_pipe(display, port,
+ pps_has_pp_on);
/* didn't find one? pick one where vdd is on */
- if (intel_dp->pps.pps_pipe == INVALID_PIPE)
- intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(display, port,
- pps_has_vdd_on);
+ if (intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
+ intel_dp->pps.vlv_pps_pipe = vlv_initial_pps_pipe(display, port,
+ pps_has_vdd_on);
/* didn't find one? pick one with just the correct port */
- if (intel_dp->pps.pps_pipe == INVALID_PIPE)
- intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(display, port,
- pps_any);
+ if (intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
+ intel_dp->pps.vlv_pps_pipe = vlv_initial_pps_pipe(display, port,
+ pps_any);
/* didn't find one? just let vlv_power_sequencer_pipe() pick one when needed */
- if (intel_dp->pps.pps_pipe == INVALID_PIPE) {
+ if (intel_dp->pps.vlv_pps_pipe == INVALID_PIPE) {
drm_dbg_kms(display->drm,
"[ENCODER:%d:%s] no initial power sequencer\n",
dig_port->base.base.base.id, dig_port->base.base.name);
@@ -446,21 +448,17 @@ pps_initial_setup(struct intel_dp *intel_dp)
return intel_pps_is_valid(intel_dp);
}
-void intel_pps_reset_all(struct intel_display *display)
+void vlv_pps_reset_all(struct intel_display *display)
{
- struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder;
- if (drm_WARN_ON(display->drm, !IS_LP(dev_priv)))
- return;
-
if (!HAS_DISPLAY(display))
return;
/*
* We can't grab pps_mutex here due to deadlock with power_domain
* mutex when power_domain functions are called while holding pps_mutex.
- * That also means that in order to use pps_pipe the code needs to
+ * That also means that in order to use vlv_pps_pipe the code needs to
* hold both a power domain reference and pps_mutex, and the power domain
* reference get/put must be done while _not_ holding pps_mutex.
* pps_{lock,unlock}() do these steps in the correct order, so one
@@ -470,16 +468,27 @@ void intel_pps_reset_all(struct intel_display *display)
for_each_intel_dp(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- drm_WARN_ON(display->drm,
- intel_dp->pps.active_pipe != INVALID_PIPE);
+ drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE);
- if (encoder->type != INTEL_OUTPUT_EDP)
- continue;
+ if (encoder->type == INTEL_OUTPUT_EDP)
+ intel_dp->pps.vlv_pps_pipe = INVALID_PIPE;
+ }
+}
+
+void bxt_pps_reset_all(struct intel_display *display)
+{
+ struct intel_encoder *encoder;
+
+ if (!HAS_DISPLAY(display))
+ return;
- if (DISPLAY_VER(display) >= 9)
- intel_dp->pps.pps_reset = true;
- else
- intel_dp->pps.pps_pipe = INVALID_PIPE;
+ /* See vlv_pps_reset_all() for why we can't grab pps_mutex here. */
+
+ for_each_intel_dp(display->drm, encoder) {
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ if (encoder->type == INTEL_OUTPUT_EDP)
+ intel_dp->pps.bxt_pps_reset = true;
}
}
@@ -548,7 +557,7 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp)
lockdep_assert_held(&display->pps.mutex);
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
- intel_dp->pps.pps_pipe == INVALID_PIPE)
+ intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
return false;
return (intel_de_read(display, _pp_stat_reg(intel_dp)) & PP_ON) != 0;
@@ -562,7 +571,7 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
lockdep_assert_held(&display->pps.mutex);
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
- intel_dp->pps.pps_pipe == INVALID_PIPE)
+ intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
return false;
return intel_de_read(display, _pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD;
@@ -1151,10 +1160,10 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
- enum pipe pipe = intel_dp->pps.pps_pipe;
+ enum pipe pipe = intel_dp->pps.vlv_pps_pipe;
i915_reg_t pp_on_reg = PP_ON_DELAYS(display, pipe);
- drm_WARN_ON(display->drm, intel_dp->pps.active_pipe != INVALID_PIPE);
+ drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE);
if (drm_WARN_ON(display->drm, pipe != PIPE_A && pipe != PIPE_B))
return;
@@ -1177,7 +1186,7 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
intel_de_write(display, pp_on_reg, 0);
intel_de_posting_read(display, pp_on_reg);
- intel_dp->pps.pps_pipe = INVALID_PIPE;
+ intel_dp->pps.vlv_pps_pipe = INVALID_PIPE;
}
static void vlv_steal_power_sequencer(struct intel_display *display,
@@ -1190,12 +1199,12 @@ static void vlv_steal_power_sequencer(struct intel_display *display,
for_each_intel_dp(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- drm_WARN(display->drm, intel_dp->pps.active_pipe == pipe,
+ drm_WARN(display->drm, intel_dp->pps.vlv_active_pipe == pipe,
"stealing PPS %c from active [ENCODER:%d:%s]\n",
pipe_name(pipe), encoder->base.base.id,
encoder->base.name);
- if (intel_dp->pps.pps_pipe != pipe)
+ if (intel_dp->pps.vlv_pps_pipe != pipe)
continue;
drm_dbg_kms(display->drm,
@@ -1208,8 +1217,59 @@ static void vlv_steal_power_sequencer(struct intel_display *display,
}
}
-void vlv_pps_init(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+static enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+ struct drm_i915_private *dev_priv = to_i915(display->drm);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ enum pipe pipe;
+
+ if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
+ encoder->port, &pipe))
+ return pipe;
+
+ return INVALID_PIPE;
+}
+
+/* Call on all DP, not just eDP */
+void vlv_pps_pipe_init(struct intel_dp *intel_dp)
+{
+ intel_dp->pps.vlv_pps_pipe = INVALID_PIPE;
+ intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp);
+}
+
+/* Call on all DP, not just eDP */
+void vlv_pps_pipe_reset(struct intel_dp *intel_dp)
+{
+ intel_wakeref_t wakeref;
+
+ with_intel_pps_lock(intel_dp, wakeref)
+ intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp);
+}
+
+enum pipe vlv_pps_backlight_initial_pipe(struct intel_dp *intel_dp)
+{
+ enum pipe pipe;
+
+ /*
+ * Figure out the current pipe for the initial backlight setup. If the
+ * current pipe isn't valid, try the PPS pipe, and if that fails just
+ * assume pipe A.
+ */
+ pipe = vlv_active_pipe(intel_dp);
+
+ if (pipe != PIPE_A && pipe != PIPE_B)
+ pipe = intel_dp->pps.vlv_pps_pipe;
+
+ if (pipe != PIPE_A && pipe != PIPE_B)
+ pipe = PIPE_A;
+
+ return pipe;
+}
+
+/* Call on all DP, not just eDP */
+void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(encoder);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -1217,10 +1277,10 @@ void vlv_pps_init(struct intel_encoder *encoder,
lockdep_assert_held(&display->pps.mutex);
- drm_WARN_ON(display->drm, intel_dp->pps.active_pipe != INVALID_PIPE);
+ drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE);
- if (intel_dp->pps.pps_pipe != INVALID_PIPE &&
- intel_dp->pps.pps_pipe != crtc->pipe) {
+ if (intel_dp->pps.vlv_pps_pipe != INVALID_PIPE &&
+ intel_dp->pps.vlv_pps_pipe != crtc->pipe) {
/*
* If another power sequencer was being used on this
* port previously make sure to turn off vdd there while
@@ -1235,13 +1295,13 @@ void vlv_pps_init(struct intel_encoder *encoder,
*/
vlv_steal_power_sequencer(display, crtc->pipe);
- intel_dp->pps.active_pipe = crtc->pipe;
+ intel_dp->pps.vlv_active_pipe = crtc->pipe;
if (!intel_dp_is_edp(intel_dp))
return;
/* now it's all ours */
- intel_dp->pps.pps_pipe = crtc->pipe;
+ intel_dp->pps.vlv_pps_pipe = crtc->pipe;
drm_dbg_kms(display->drm,
"initializing %s for [ENCODER:%d:%s]\n",
@@ -1253,6 +1313,18 @@ void vlv_pps_init(struct intel_encoder *encoder,
pps_init_registers(intel_dp, true);
}
+/* Call on all DP, not just eDP */
+void vlv_pps_port_disable(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ intel_wakeref_t wakeref;
+
+ with_intel_pps_lock(intel_dp, wakeref)
+ intel_dp->pps.vlv_active_pipe = INVALID_PIPE;
+}
+
static void pps_vdd_init(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h
index 0c5da83a559e..bc5046d53626 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.h
+++ b/drivers/gpu/drm/i915/display/intel_pps.h
@@ -43,10 +43,16 @@ void intel_pps_wait_power_cycle(struct intel_dp *intel_dp);
bool intel_pps_init(struct intel_dp *intel_dp);
void intel_pps_init_late(struct intel_dp *intel_dp);
void intel_pps_encoder_reset(struct intel_dp *intel_dp);
-void intel_pps_reset_all(struct intel_display *display);
-void vlv_pps_init(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state);
+void vlv_pps_pipe_init(struct intel_dp *intel_dp);
+void vlv_pps_pipe_reset(struct intel_dp *intel_dp);
+enum pipe vlv_pps_backlight_initial_pipe(struct intel_dp *intel_dp);
+void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state);
+void vlv_pps_port_disable(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state);
+void vlv_pps_reset_all(struct intel_display *display);
+void bxt_pps_reset_all(struct intel_display *display);
void intel_pps_unlock_regs_wa(struct intel_display *display);
void intel_pps_setup(struct intel_display *display);
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 136a0d6ca970..3b20325b3f6a 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -21,6 +21,8 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/debugfs.h>
+
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_debugfs.h>
@@ -33,6 +35,7 @@
#include "intel_cursor_regs.h"
#include "intel_ddi.h"
#include "intel_de.h"
+#include "intel_display_irq.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_aux.h"
@@ -762,7 +765,7 @@ static void _psr_enable_sink(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(intel_dp);
- u8 val = DP_PSR_ENABLE;
+ u8 val = 0;
if (crtc_state->has_sel_update) {
val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
@@ -782,7 +785,9 @@ static void _psr_enable_sink(struct intel_dp *intel_dp,
if (intel_dp->psr.entry_setup_frames > 0)
val |= DP_PSR_FRAME_CAPTURE;
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
+ val |= DP_PSR_ENABLE;
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
}
@@ -1599,6 +1604,10 @@ _panel_replay_compute_config(struct intel_dp *intel_dp,
/* Remaining checks are for eDP only */
+ if (to_intel_crtc(crtc_state->uapi.crtc)->pipe != PIPE_A &&
+ to_intel_crtc(crtc_state->uapi.crtc)->pipe != PIPE_B)
+ return false;
+
/* 128b/132b Panel Replay is not supported on eDP */
if (intel_dp_is_uhbr(crtc_state)) {
drm_dbg_kms(display->drm,
@@ -2114,7 +2123,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
intel_de_rmw(display,
- PORT_ALPM_CTL(display, cpu_transcoder),
+ PORT_ALPM_CTL(cpu_transcoder),
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
}
@@ -2221,6 +2230,36 @@ unlock:
mutex_unlock(&psr->lock);
}
+/**
+ * intel_psr_needs_block_dc_vblank - Check if block dc entry is needed
+ * @crtc_state: CRTC status
+ *
+ * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
+ * prevent it in case of Panel Replay. Panel Replay switches main link off on
+ * DC entry. This means vblank interrupts are not fired and is a problem if
+ * user-space is polling for vblank events.
+ */
+bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_encoder *encoder;
+
+ for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) {
+ struct intel_dp *intel_dp;
+
+ if (!intel_encoder_is_dp(encoder))
+ continue;
+
+ intel_dp = enc_to_intel_dp(encoder);
+
+ if (intel_dp_is_edp(intel_dp) &&
+ CAN_PANEL_REPLAY(intel_dp))
+ return true;
+ }
+
+ return false;
+}
+
static u32 man_trk_ctl_enable_bit_get(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
@@ -2480,11 +2519,60 @@ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *c
return true;
}
+/* Wa 14019834836 */
+static void intel_psr_apply_pr_link_on_su_wa(struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct intel_encoder *encoder;
+ int hactive_limit;
+
+ if (crtc_state->psr2_su_area.y1 != 0 ||
+ crtc_state->psr2_su_area.y2 != 0)
+ return;
+
+ if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ hactive_limit = intel_dp_is_uhbr(crtc_state) ? 1230 : 546;
+ else
+ hactive_limit = intel_dp_is_uhbr(crtc_state) ? 615 : 273;
+
+ if (crtc_state->hw.adjusted_mode.hdisplay < hactive_limit)
+ return;
+
+ for_each_intel_encoder_mask_with_psr(display->drm, encoder,
+ crtc_state->uapi.encoder_mask) {
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ if (!intel_dp_is_edp(intel_dp) &&
+ intel_dp->psr.panel_replay_enabled &&
+ intel_dp->psr.sel_update_enabled) {
+ crtc_state->psr2_su_area.y2++;
+ return;
+ }
+ }
+}
+
+static void
+intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ /* Wa_14014971492 */
+ if (!crtc_state->has_panel_replay &&
+ ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
+ IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) &&
+ crtc_state->splitter.enable)
+ crtc_state->psr2_su_area.y1 = 0;
+
+ /* Wa 14019834836 */
+ if (DISPLAY_VER(display) == 30)
+ intel_psr_apply_pr_link_on_su_wa(crtc_state);
+}
+
int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *new_plane_state, *old_plane_state;
struct intel_plane *plane;
@@ -2589,12 +2677,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
if (full_update)
goto skip_sel_fetch_set_loop;
- /* Wa_14014971492 */
- if (!crtc_state->has_panel_replay &&
- ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
- IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv))) &&
- crtc_state->splitter.enable)
- crtc_state->psr2_su_area.y1 = 0;
+ intel_psr_apply_su_area_workarounds(crtc_state);
ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
if (ret)
@@ -3848,10 +3931,8 @@ void intel_psr_connector_debugfs_add(struct intel_connector *connector)
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct dentry *root = connector->base.debugfs_entry;
- /* TODO: Add support for MST connectors as well. */
- if ((connector->base.connector_type != DRM_MODE_CONNECTOR_eDP &&
- connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) ||
- connector->mst_port)
+ if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP &&
+ connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort)
return;
debugfs_create_file("i915_psr_sink_status", 0444, root,
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index 6eb5f15f674f..5f26f61f82aa 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -58,6 +58,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
void intel_psr_pause(struct intel_dp *intel_dp);
void intel_psr_resume(struct intel_dp *intel_dp);
+bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
void intel_psr_lock(const struct intel_crtc_state *crtc_state);
void intel_psr_unlock(const struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h
index 642bb15fb547..0841242543ca 100644
--- a/drivers/gpu/drm/i915/display/intel_psr_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h
@@ -9,6 +9,7 @@
#include "intel_display_reg_defs.h"
#include "intel_dp_aux_regs.h"
+#define _TRANS_EXITLINE_A 0x60018
#define TRANS_EXITLINE(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_EXITLINE_A)
#define EXITLINE_ENABLE REG_BIT(31)
#define EXITLINE_MASK REG_GENMASK(12, 0)
@@ -295,7 +296,7 @@
#define _PORT_ALPM_CTL_A 0x16fa2c
#define _PORT_ALPM_CTL_B 0x16fc2c
-#define PORT_ALPM_CTL(dev_priv, port) _MMIO_PORT(port, _PORT_ALPM_CTL_A, _PORT_ALPM_CTL_B)
+#define PORT_ALPM_CTL(port) _MMIO_PORT(port, _PORT_ALPM_CTL_A, _PORT_ALPM_CTL_B)
#define PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(31)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK REG_GENMASK(23, 20)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK, val)
@@ -306,7 +307,7 @@
#define _PORT_ALPM_LFPS_CTL_A 0x16fa30
#define _PORT_ALPM_LFPS_CTL_B 0x16fc30
-#define PORT_ALPM_LFPS_CTL(dev_priv, port) _MMIO_PORT(port, _PORT_ALPM_LFPS_CTL_A, _PORT_ALPM_LFPS_CTL_B)
+#define PORT_ALPM_LFPS_CTL(port) _MMIO_PORT(port, _PORT_ALPM_LFPS_CTL_A, _PORT_ALPM_LFPS_CTL_B)
#define PORT_ALPM_LFPS_CTL_LFPS_START_POLARITY REG_BIT(31)
#define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MASK REG_GENMASK(27, 24)
#define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MIN 7
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index 29b56d53a340..28f497ae785b 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -231,7 +231,7 @@ static struct intel_quirk intel_quirks[] = {
{ 0x0f31, 0x103c, 0x220f, quirk_invert_brightness },
};
-static struct intel_dpcd_quirk intel_dpcd_quirks[] = {
+static const struct intel_dpcd_quirk intel_dpcd_quirks[] = {
/* Dell Precision 5490 */
{
.device = 0x7d55,
@@ -272,7 +272,7 @@ void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
int i;
for (i = 0; i < ARRAY_SIZE(intel_dpcd_quirks); i++) {
- struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i];
+ const struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i];
if (d->device == q->device &&
(d->subsystem_vendor == q->subsystem_vendor ||
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index 7cc519b402e9..b83bf813677d 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -36,6 +36,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
+#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index e657b09ede99..e6fadcef58e0 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -378,7 +378,8 @@ static void vlv_sprite_update_gamma(const struct intel_plane_state *plane_state)
}
static void
-vlv_sprite_update_noarm(struct intel_plane *plane,
+vlv_sprite_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -399,7 +400,8 @@ vlv_sprite_update_noarm(struct intel_plane *plane,
}
static void
-vlv_sprite_update_arm(struct intel_plane *plane,
+vlv_sprite_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -449,7 +451,8 @@ vlv_sprite_update_arm(struct intel_plane *plane,
}
static void
-vlv_sprite_disable_arm(struct intel_plane *plane,
+vlv_sprite_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(plane->base.dev);
@@ -795,7 +798,8 @@ static void ivb_sprite_update_gamma(const struct intel_plane_state *plane_state)
}
static void
-ivb_sprite_update_noarm(struct intel_plane *plane,
+ivb_sprite_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -826,7 +830,8 @@ ivb_sprite_update_noarm(struct intel_plane *plane,
}
static void
-ivb_sprite_update_arm(struct intel_plane *plane,
+ivb_sprite_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -874,7 +879,8 @@ ivb_sprite_update_arm(struct intel_plane *plane,
}
static void
-ivb_sprite_disable_arm(struct intel_plane *plane,
+ivb_sprite_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(plane->base.dev);
@@ -1133,7 +1139,8 @@ static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state)
}
static void
-g4x_sprite_update_noarm(struct intel_plane *plane,
+g4x_sprite_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -1162,7 +1169,8 @@ g4x_sprite_update_noarm(struct intel_plane *plane,
}
static void
-g4x_sprite_update_arm(struct intel_plane *plane,
+g4x_sprite_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
@@ -1206,7 +1214,8 @@ g4x_sprite_update_arm(struct intel_plane *plane,
}
static void
-g4x_sprite_disable_arm(struct intel_plane *plane,
+g4x_sprite_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(plane->base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h
index 044a032e41b9..531079979c05 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.h
+++ b/drivers/gpu/drm/i915/display/intel_sprite.h
@@ -8,9 +8,6 @@
#include <linux/types.h>
-struct drm_device;
-struct drm_display_mode;
-struct drm_file;
struct drm_i915_private;
struct intel_crtc_state;
struct intel_plane_state;
@@ -19,8 +16,6 @@ enum pipe;
#ifdef I915
struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
enum pipe pipe, int plane);
-int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
index 4853c4806004..1d0b84b464c1 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
@@ -42,6 +42,7 @@ static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_intel_sprite_colorkey *set = data;
struct drm_plane *plane;
@@ -100,7 +101,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
*/
if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
struct intel_crtc *crtc =
- intel_crtc_for_pipe(dev_priv,
+ intel_crtc_for_pipe(display,
to_intel_plane(plane)->pipe);
plane_state = drm_atomic_get_plane_state(state,
diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
index 581844d1db9a..e40aff490486 100644
--- a/drivers/gpu/drm/i915/display/intel_tv.c
+++ b/drivers/gpu/drm/i915/display/intel_tv.c
@@ -33,6 +33,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c
index 0b7f2134e441..d18b8292be49 100644
--- a/drivers/gpu/drm/i915/display/intel_vblank.c
+++ b/drivers/gpu/drm/i915/display/intel_vblank.c
@@ -3,6 +3,8 @@
* Copyright © 2022-2023 Intel Corporation
*/
+#include <drm/drm_vblank.h>
+
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_color.h"
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 2e849b015e74..40525f5c4c42 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -306,6 +306,12 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3;
+ if (vdsc_cfg->bits_per_component < 8) {
+ drm_dbg_kms(&dev_priv->drm, "DSC bpc requirements not met bpc: %d\n",
+ vdsc_cfg->bits_per_component);
+ return -EINVAL;
+ }
+
drm_dsc_set_rc_buf_thresh(vdsc_cfg);
/*
@@ -379,9 +385,9 @@ static int intel_dsc_get_vdsc_per_pipe(const struct intel_crtc_state *crtc_state
int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state)
{
int num_vdsc_instances = intel_dsc_get_vdsc_per_pipe(crtc_state);
+ int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state);
- if (crtc_state->joiner_pipes)
- num_vdsc_instances *= 2;
+ num_vdsc_instances *= num_joined_pipes;
return num_vdsc_instances;
}
@@ -742,7 +748,7 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
u32 dss_ctl1_val = 0;
if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) {
- if (intel_crtc_is_joiner_secondary(crtc_state))
+ if (intel_crtc_is_bigjoiner_secondary(crtc_state))
dss_ctl1_val |= UNCOMPRESSED_JOINER_SECONDARY;
else
dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY;
@@ -770,8 +776,15 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
dss_ctl1_val |= JOINER_ENABLE;
}
if (crtc_state->joiner_pipes) {
+ if (intel_crtc_ultrajoiner_enable_needed(crtc_state))
+ dss_ctl1_val |= ULTRA_JOINER_ENABLE;
+
+ if (intel_crtc_is_ultrajoiner_primary(crtc_state))
+ dss_ctl1_val |= PRIMARY_ULTRA_JOINER_ENABLE;
+
dss_ctl1_val |= BIG_JOINER_ENABLE;
- if (!intel_crtc_is_joiner_secondary(crtc_state))
+
+ if (intel_crtc_is_bigjoiner_primary(crtc_state))
dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE;
}
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
index f921ad67b587..bf32a3b46fb1 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
@@ -37,6 +37,8 @@
#define SPLITTER_CONFIGURATION_MASK REG_GENMASK(26, 25)
#define SPLITTER_CONFIGURATION_2_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 0)
#define SPLITTER_CONFIGURATION_4_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 1)
+#define ULTRA_JOINER_ENABLE REG_BIT(23)
+#define PRIMARY_ULTRA_JOINER_ENABLE REG_BIT(22)
#define UNCOMPRESSED_JOINER_PRIMARY (1 << 21)
#define UNCOMPRESSED_JOINER_SECONDARY (1 << 20)
diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
index 0b5916c15307..2c76a0176a35 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -14,24 +14,26 @@
#include "intel_de.h"
#include "intel_vga.h"
-static i915_reg_t intel_vga_cntrl_reg(struct drm_i915_private *i915)
+static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
+
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
return VLV_VGACNTRL;
- else if (DISPLAY_VER(i915) >= 5)
+ else if (DISPLAY_VER(display) >= 5)
return CPU_VGACNTRL;
else
return VGACNTRL;
}
/* Disable the VGA plane that we never use */
-void intel_vga_disable(struct drm_i915_private *dev_priv)
+void intel_vga_disable(struct intel_display *display)
{
- struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
- i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
+ i915_reg_t vga_reg = intel_vga_cntrl_reg(display);
u8 sr1;
- if (intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)
+ if (intel_de_read(display, vga_reg) & VGA_DISP_DISABLE)
return;
/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
@@ -42,23 +44,24 @@ void intel_vga_disable(struct drm_i915_private *dev_priv)
vga_put(pdev, VGA_RSRC_LEGACY_IO);
udelay(300);
- intel_de_write(dev_priv, vga_reg, VGA_DISP_DISABLE);
- intel_de_posting_read(dev_priv, vga_reg);
+ intel_de_write(display, vga_reg, VGA_DISP_DISABLE);
+ intel_de_posting_read(display, vga_reg);
}
-void intel_vga_redisable_power_on(struct drm_i915_private *dev_priv)
+void intel_vga_redisable_power_on(struct intel_display *display)
{
- i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
+ i915_reg_t vga_reg = intel_vga_cntrl_reg(display);
- if (!(intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)) {
- drm_dbg_kms(&dev_priv->drm,
+ if (!(intel_de_read(display, vga_reg) & VGA_DISP_DISABLE)) {
+ drm_dbg_kms(display->drm,
"Something enabled VGA plane, disabling it\n");
- intel_vga_disable(dev_priv);
+ intel_vga_disable(display);
}
}
-void intel_vga_redisable(struct drm_i915_private *i915)
+void intel_vga_redisable(struct intel_display *display)
{
+ struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref;
/*
@@ -74,14 +77,14 @@ void intel_vga_redisable(struct drm_i915_private *i915)
if (!wakeref)
return;
- intel_vga_redisable_power_on(i915);
+ intel_vga_redisable_power_on(display);
intel_display_power_put(i915, POWER_DOMAIN_VGA, wakeref);
}
-void intel_vga_reset_io_mem(struct drm_i915_private *i915)
+void intel_vga_reset_io_mem(struct intel_display *display)
{
- struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
/*
* After we re-enable the power well, if we touch VGA register 0x3d5
@@ -98,10 +101,10 @@ void intel_vga_reset_io_mem(struct drm_i915_private *i915)
vga_put(pdev, VGA_RSRC_LEGACY_IO);
}
-int intel_vga_register(struct drm_i915_private *i915)
+int intel_vga_register(struct intel_display *display)
{
- struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
int ret;
/*
@@ -119,9 +122,9 @@ int intel_vga_register(struct drm_i915_private *i915)
return 0;
}
-void intel_vga_unregister(struct drm_i915_private *i915)
+void intel_vga_unregister(struct intel_display *display)
{
- struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ struct pci_dev *pdev = to_pci_dev(display->drm->dev);
vga_client_unregister(pdev);
}
diff --git a/drivers/gpu/drm/i915/display/intel_vga.h b/drivers/gpu/drm/i915/display/intel_vga.h
index ba5b55b917f0..824dfc32a199 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.h
+++ b/drivers/gpu/drm/i915/display/intel_vga.h
@@ -6,13 +6,13 @@
#ifndef __INTEL_VGA_H__
#define __INTEL_VGA_H__
-struct drm_i915_private;
+struct intel_display;
-void intel_vga_reset_io_mem(struct drm_i915_private *i915);
-void intel_vga_disable(struct drm_i915_private *i915);
-void intel_vga_redisable(struct drm_i915_private *i915);
-void intel_vga_redisable_power_on(struct drm_i915_private *i915);
-int intel_vga_register(struct drm_i915_private *i915);
-void intel_vga_unregister(struct drm_i915_private *i915);
+void intel_vga_reset_io_mem(struct intel_display *display);
+void intel_vga_disable(struct intel_display *display);
+void intel_vga_redisable(struct intel_display *display);
+void intel_vga_redisable_power_on(struct intel_display *display);
+int intel_vga_register(struct intel_display *display);
+void intel_vga_unregister(struct intel_display *display);
#endif /* __INTEL_VGA_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c
index 82c4933ad507..d7dc49aecd27 100644
--- a/drivers/gpu/drm/i915/display/intel_wm.c
+++ b/drivers/gpu/drm/i915/display/intel_wm.c
@@ -3,6 +3,8 @@
* Copyright © 2023 Intel Corporation
*/
+#include <linux/debugfs.h>
+
#include "i915_drv.h"
#include "i9xx_wm.h"
#include "intel_display_types.h"
@@ -48,29 +50,15 @@ void intel_update_watermarks(struct drm_i915_private *i915)
i915->display.funcs.wm->update_wm(i915);
}
-int intel_compute_pipe_wm(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
+int intel_wm_compute(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
-
- if (i915->display.funcs.wm->compute_pipe_wm)
- return i915->display.funcs.wm->compute_pipe_wm(state, crtc);
-
- return 0;
-}
-
-int intel_compute_intermediate_wm(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
-{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
-
- if (!i915->display.funcs.wm->compute_intermediate_wm)
- return 0;
+ struct intel_display *display = to_intel_display(state);
- if (drm_WARN_ON(&i915->drm, !i915->display.funcs.wm->compute_pipe_wm))
+ if (!display->funcs.wm->compute_watermarks)
return 0;
- return i915->display.funcs.wm->compute_intermediate_wm(state, crtc);
+ return display->funcs.wm->compute_watermarks(state, crtc);
}
bool intel_initial_watermarks(struct intel_atomic_state *state,
diff --git a/drivers/gpu/drm/i915/display/intel_wm.h b/drivers/gpu/drm/i915/display/intel_wm.h
index 48429ac140d2..e97cdca89a5c 100644
--- a/drivers/gpu/drm/i915/display/intel_wm.h
+++ b/drivers/gpu/drm/i915/display/intel_wm.h
@@ -15,10 +15,8 @@ struct intel_crtc_state;
struct intel_plane_state;
void intel_update_watermarks(struct drm_i915_private *i915);
-int intel_compute_pipe_wm(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
-int intel_compute_intermediate_wm(struct intel_atomic_state *state,
- struct intel_crtc *crtc);
+int intel_wm_compute(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
bool intel_initial_watermarks(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_atomic_update_watermarks(struct intel_atomic_state *state,
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 17d4c880ecc4..9557b08ca2e2 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -11,6 +11,7 @@
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic_plane.h"
+#include "intel_bo.h"
#include "intel_de.h"
#include "intel_display_irq.h"
#include "intel_display_types.h"
@@ -349,7 +350,6 @@ static int skl_plane_max_width(const struct drm_framebuffer *fb,
return 5120;
case I915_FORMAT_MOD_Y_TILED_CCS:
case I915_FORMAT_MOD_Yf_TILED_CCS:
- case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
/* FIXME AUX plane? */
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
@@ -593,11 +593,11 @@ static u32 skl_plane_min_alignment(struct intel_plane *plane,
* in full-range YCbCr.
*/
static void
-icl_program_input_csc(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state,
+icl_program_input_csc(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
enum plane_id plane_id = plane->id;
@@ -641,31 +641,31 @@ icl_program_input_csc(struct intel_plane *plane,
};
const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
- ROFF(csc[0]) | GOFF(csc[1]));
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
- BOFF(csc[2]));
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
- ROFF(csc[3]) | GOFF(csc[4]));
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
- BOFF(csc[5]));
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
- ROFF(csc[6]) | GOFF(csc[7]));
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
- BOFF(csc[8]));
-
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
- PREOFF_YUV_TO_RGB_HI);
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
- PREOFF_YUV_TO_RGB_ME);
- intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
- PREOFF_YUV_TO_RGB_LO);
- intel_de_write_fw(dev_priv,
- PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
- intel_de_write_fw(dev_priv,
- PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
- intel_de_write_fw(dev_priv,
- PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
+ ROFF(csc[0]) | GOFF(csc[1]));
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
+ BOFF(csc[2]));
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
+ ROFF(csc[3]) | GOFF(csc[4]));
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
+ BOFF(csc[5]));
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
+ ROFF(csc[6]) | GOFF(csc[7]));
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
+ BOFF(csc[8]));
+
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
+ PREOFF_YUV_TO_RGB_HI);
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
+ PREOFF_YUV_TO_RGB_ME);
+ intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
+ PREOFF_YUV_TO_RGB_LO);
+ intel_de_write_dsb(display, dsb,
+ PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
+ intel_de_write_dsb(display, dsb,
+ PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
+ intel_de_write_dsb(display, dsb,
+ PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
}
static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
@@ -719,9 +719,11 @@ static u32 skl_plane_wm_reg_val(const struct skl_wm_level *level)
return val;
}
-static void skl_write_plane_wm(struct intel_plane *plane,
+static void skl_write_plane_wm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
@@ -733,71 +735,75 @@ static void skl_write_plane_wm(struct intel_plane *plane,
int level;
for (level = 0; level < i915->display.wm.num_levels; level++)
- intel_de_write_fw(i915, PLANE_WM(pipe, plane_id, level),
- skl_plane_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
+ intel_de_write_dsb(display, dsb, PLANE_WM(pipe, plane_id, level),
+ skl_plane_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
- intel_de_write_fw(i915, PLANE_WM_TRANS(pipe, plane_id),
- skl_plane_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
+ intel_de_write_dsb(display, dsb, PLANE_WM_TRANS(pipe, plane_id),
+ skl_plane_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
if (HAS_HW_SAGV_WM(i915)) {
const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
- intel_de_write_fw(i915, PLANE_WM_SAGV(pipe, plane_id),
- skl_plane_wm_reg_val(&wm->sagv.wm0));
- intel_de_write_fw(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id),
- skl_plane_wm_reg_val(&wm->sagv.trans_wm));
+ intel_de_write_dsb(display, dsb, PLANE_WM_SAGV(pipe, plane_id),
+ skl_plane_wm_reg_val(&wm->sagv.wm0));
+ intel_de_write_dsb(display, dsb, PLANE_WM_SAGV_TRANS(pipe, plane_id),
+ skl_plane_wm_reg_val(&wm->sagv.trans_wm));
}
- intel_de_write_fw(i915, PLANE_BUF_CFG(pipe, plane_id),
- skl_plane_ddb_reg_val(ddb));
+ intel_de_write_dsb(display, dsb, PLANE_BUF_CFG(pipe, plane_id),
+ skl_plane_ddb_reg_val(ddb));
if (DISPLAY_VER(i915) < 11)
- intel_de_write_fw(i915, PLANE_NV12_BUF_CFG(pipe, plane_id),
- skl_plane_ddb_reg_val(ddb_y));
+ intel_de_write_dsb(display, dsb, PLANE_NV12_BUF_CFG(pipe, plane_id),
+ skl_plane_ddb_reg_val(ddb_y));
}
static void
-skl_plane_disable_arm(struct intel_plane *plane,
+skl_plane_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
- skl_write_plane_wm(plane, crtc_state);
+ skl_write_plane_wm(dsb, plane, crtc_state);
- intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
- intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), 0);
+ intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), 0);
}
-static void icl_plane_disable_sel_fetch_arm(struct intel_plane *plane,
+static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
}
static void
-icl_plane_disable_arm(struct intel_plane *plane,
+icl_plane_disable_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
if (icl_is_hdr_plane(dev_priv, plane_id))
- intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CUS_CTL(pipe, plane_id), 0);
- skl_write_plane_wm(plane, crtc_state);
+ skl_write_plane_wm(dsb, plane, crtc_state);
- icl_plane_disable_sel_fetch_arm(plane, crtc_state);
- intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
- intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+ icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
+ intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), 0);
+ intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), 0);
}
static bool
@@ -1234,28 +1240,30 @@ static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state)
return keymsk;
}
-static void icl_plane_csc_load_black(struct intel_plane *plane)
+static void icl_plane_csc_load_black(struct intel_dsb *dsb,
+ struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
- intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 0), 0);
- intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 1), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 0), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 1), 0);
- intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 2), 0);
- intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 3), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 2), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 3), 0);
- intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 4), 0);
- intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 5), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 4), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 5), 0);
- intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0);
- intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0);
- intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0);
- intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0);
- intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0);
- intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0);
+ intel_de_write_dsb(display, dsb, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
}
static int icl_plane_color_plane(const struct intel_plane_state *plane_state)
@@ -1268,11 +1276,12 @@ static int icl_plane_color_plane(const struct intel_plane_state *plane_state)
}
static void
-skl_plane_update_noarm(struct intel_plane *plane,
+skl_plane_update_noarm(struct intel_dsb *dsb,
+ 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);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
u32 stride = skl_plane_stride(plane_state, 0);
@@ -1287,21 +1296,23 @@ skl_plane_update_noarm(struct intel_plane *plane,
crtc_y = 0;
}
- 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),
- PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
- PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
+ intel_de_write_dsb(display, dsb, PLANE_STRIDE(pipe, plane_id),
+ PLANE_STRIDE_(stride));
+ intel_de_write_dsb(display, dsb, PLANE_POS(pipe, plane_id),
+ PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
+ intel_de_write_dsb(display, dsb, PLANE_SIZE(pipe, plane_id),
+ PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
- skl_write_plane_wm(plane, crtc_state);
+ skl_write_plane_wm(dsb, plane, crtc_state);
}
static void
-skl_plane_update_arm(struct intel_plane *plane,
+skl_plane_update_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
@@ -1321,22 +1332,26 @@ skl_plane_update_arm(struct intel_plane *plane,
plane_color_ctl = plane_state->color_ctl |
glk_plane_color_ctl_crtc(crtc_state);
- 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_dsb(display, dsb, PLANE_KEYVAL(pipe, plane_id),
+ skl_plane_keyval(plane_state));
+ intel_de_write_dsb(display, dsb, PLANE_KEYMSK(pipe, plane_id),
+ skl_plane_keymsk(plane_state));
+ intel_de_write_dsb(display, dsb, PLANE_KEYMAX(pipe, plane_id),
+ skl_plane_keymax(plane_state));
- intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
- PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
+ intel_de_write_dsb(display, dsb, PLANE_OFFSET(pipe, plane_id),
+ PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
- intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
- skl_plane_aux_dist(plane_state, 0));
+ intel_de_write_dsb(display, dsb, PLANE_AUX_DIST(pipe, plane_id),
+ skl_plane_aux_dist(plane_state, 0));
- intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
- PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
- PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
+ intel_de_write_dsb(display, dsb, PLANE_AUX_OFFSET(pipe, plane_id),
+ 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);
+ intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id),
+ plane_color_ctl);
/*
* Enable the scaler before the plane so that we don't
@@ -1353,17 +1368,19 @@ skl_plane_update_arm(struct intel_plane *plane,
* disabled. Try to make the plane enable atomic by writing
* the control register just before the surface register.
*/
- intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
- intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
- skl_plane_surf(plane_state, 0));
+ intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id),
+ plane_ctl);
+ intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id),
+ skl_plane_surf(plane_state, 0));
}
-static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
+static void icl_plane_update_sel_fetch_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
int color_plane)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
const struct drm_rect *clip;
u32 val;
@@ -1380,7 +1397,7 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
y = (clip->y1 + plane_state->uapi.dst.y1);
val = y << 16;
val |= plane_state->uapi.dst.x1;
- intel_de_write_fw(i915, SEL_FETCH_PLANE_POS(pipe, plane->id), val);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_POS(pipe, plane->id), val);
x = plane_state->view.color_plane[color_plane].x;
@@ -1395,20 +1412,21 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
val = y << 16 | x;
- intel_de_write_fw(i915, SEL_FETCH_PLANE_OFFSET(pipe, plane->id),
- val);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_OFFSET(pipe, plane->id), val);
/* Sizes are 0 based */
val = (drm_rect_height(clip) - 1) << 16;
val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
- intel_de_write_fw(i915, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val);
}
static void
-icl_plane_update_noarm(struct intel_plane *plane,
+icl_plane_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
+ struct intel_display *display = to_intel_display(plane->base.dev);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
@@ -1432,76 +1450,82 @@ icl_plane_update_noarm(struct intel_plane *plane,
crtc_y = 0;
}
- 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),
- PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
- PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
+ intel_de_write_dsb(display, dsb, PLANE_STRIDE(pipe, plane_id),
+ PLANE_STRIDE_(stride));
+ intel_de_write_dsb(display, dsb, PLANE_POS(pipe, plane_id),
+ PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
+ intel_de_write_dsb(display, dsb, PLANE_SIZE(pipe, plane_id),
+ PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
- 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_dsb(display, dsb, PLANE_KEYVAL(pipe, plane_id),
+ skl_plane_keyval(plane_state));
+ intel_de_write_dsb(display, dsb, PLANE_KEYMSK(pipe, plane_id),
+ skl_plane_keymsk(plane_state));
+ intel_de_write_dsb(display, dsb, PLANE_KEYMAX(pipe, plane_id),
+ skl_plane_keymax(plane_state));
- intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
- PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
+ intel_de_write_dsb(display, dsb, PLANE_OFFSET(pipe, plane_id),
+ PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
- intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
- lower_32_bits(plane_state->ccval));
- intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 1),
- upper_32_bits(plane_state->ccval));
+ intel_de_write_dsb(display, dsb, PLANE_CC_VAL(pipe, plane_id, 0),
+ lower_32_bits(plane_state->ccval));
+ intel_de_write_dsb(display, dsb, PLANE_CC_VAL(pipe, plane_id, 1),
+ upper_32_bits(plane_state->ccval));
}
/* FLAT CCS doesn't need to program AUX_DIST */
if (!HAS_FLAT_CCS(dev_priv) && DISPLAY_VER(dev_priv) < 20)
- intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
- skl_plane_aux_dist(plane_state, color_plane));
+ intel_de_write_dsb(display, dsb, PLANE_AUX_DIST(pipe, plane_id),
+ skl_plane_aux_dist(plane_state, color_plane));
if (icl_is_hdr_plane(dev_priv, plane_id))
- intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
- plane_state->cus_ctl);
+ intel_de_write_dsb(display, dsb, PLANE_CUS_CTL(pipe, plane_id),
+ plane_state->cus_ctl);
- intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
+ intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id),
+ plane_color_ctl);
if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
- icl_program_input_csc(plane, crtc_state, plane_state);
+ icl_program_input_csc(dsb, plane, plane_state);
- skl_write_plane_wm(plane, crtc_state);
+ skl_write_plane_wm(dsb, plane, crtc_state);
/*
* FIXME: pxp session invalidation can hit any time even at time of commit
* or after the commit, display content will be garbage.
*/
if (plane_state->force_black)
- icl_plane_csc_load_black(plane);
+ icl_plane_csc_load_black(dsb, plane, crtc_state);
- icl_plane_update_sel_fetch_noarm(plane, crtc_state, plane_state, color_plane);
+ icl_plane_update_sel_fetch_noarm(dsb, plane, crtc_state, plane_state, color_plane);
}
-static void icl_plane_update_sel_fetch_arm(struct intel_plane *plane,
+static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
if (!crtc_state->enable_psr2_sel_fetch)
return;
if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
- intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id),
- SEL_FETCH_PLANE_CTL_ENABLE);
+ intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id),
+ SEL_FETCH_PLANE_CTL_ENABLE);
else
- icl_plane_disable_sel_fetch_arm(plane, crtc_state);
+ icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
}
static void
-icl_plane_update_arm(struct intel_plane *plane,
+icl_plane_update_arm(struct intel_dsb *dsb,
+ 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);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
int color_plane = icl_plane_color_plane(plane_state);
@@ -1520,25 +1544,27 @@ icl_plane_update_arm(struct intel_plane *plane,
if (plane_state->scaler_id >= 0)
skl_program_plane_scaler(plane, crtc_state, plane_state);
- icl_plane_update_sel_fetch_arm(plane, crtc_state, plane_state);
+ icl_plane_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
/*
* The control register self-arms if the plane was previously
* disabled. Try to make the plane enable atomic by writing
* the control register just before the surface register.
*/
- intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
- intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
- skl_plane_surf(plane_state, color_plane));
+ intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id),
+ plane_ctl);
+ intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id),
+ skl_plane_surf(plane_state, color_plane));
}
static void
-skl_plane_async_flip(struct intel_plane *plane,
+skl_plane_async_flip(struct intel_dsb *dsb,
+ struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ struct intel_display *display = to_intel_display(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
u32 plane_ctl = plane_state->ctl;
@@ -1548,9 +1574,10 @@ skl_plane_async_flip(struct intel_plane *plane,
if (async_flip)
plane_ctl |= PLANE_CTL_ASYNC_FLIP;
- intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
- intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
- skl_plane_surf(plane_state, 0));
+ intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id),
+ plane_ctl);
+ intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id),
+ skl_plane_surf(plane_state, 0));
}
static bool intel_format_is_p01x(u32 format)
@@ -2084,13 +2111,13 @@ static void check_protection(struct intel_plane_state *plane_state)
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_gem_object *obj = intel_fb_bo(fb);
if (DISPLAY_VER(i915) < 11)
return;
plane_state->decrypt = intel_pxp_key_check(i915->pxp, obj, false) == 0;
- plane_state->force_black = i915_gem_object_is_protected(obj) &&
+ plane_state->force_black = intel_bo_is_protected(obj) &&
!plane_state->decrypt;
}
@@ -2302,8 +2329,8 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
}
}
-static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
- u32 format, u64 modifier)
+static bool icl_plane_format_mod_supported(struct drm_plane *_plane,
+ u32 format, u64 modifier)
{
struct intel_plane *plane = to_intel_plane(_plane);
@@ -2315,9 +2342,14 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_ABGR2101010:
if (intel_fb_is_ccs_modifier(modifier))
return true;
fallthrough;
+ case DRM_FORMAT_RGB565:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
@@ -2327,20 +2359,69 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_P010:
case DRM_FORMAT_P012:
case DRM_FORMAT_P016:
- if (intel_fb_is_mc_ccs_modifier(modifier))
+ case DRM_FORMAT_XVYU2101010:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED)
return true;
fallthrough;
- case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_C8:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_Y210:
+ case DRM_FORMAT_Y212:
+ case DRM_FORMAT_Y216:
+ case DRM_FORMAT_XVYU12_16161616:
+ case DRM_FORMAT_XVYU16161616:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED ||
+ modifier == I915_FORMAT_MOD_Y_TILED)
+ return true;
+ fallthrough;
+ default:
+ return false;
+ }
+}
+
+static bool tgl_plane_format_mod_supported(struct drm_plane *_plane,
+ u32 format, u64 modifier)
+{
+ struct intel_plane *plane = to_intel_plane(_plane);
+
+ if (!intel_fb_plane_supports_modifier(plane, modifier))
+ return false;
+
+ switch (format) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_ABGR2101010:
- case DRM_FORMAT_XVYU2101010:
- case DRM_FORMAT_C8:
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_ABGR16161616F:
case DRM_FORMAT_XRGB16161616F:
case DRM_FORMAT_ARGB16161616F:
+ if (intel_fb_is_ccs_modifier(modifier))
+ return true;
+ fallthrough;
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_XYUV8888:
+ case DRM_FORMAT_P010:
+ case DRM_FORMAT_P012:
+ case DRM_FORMAT_P016:
+ if (intel_fb_is_mc_ccs_modifier(modifier))
+ return true;
+ fallthrough;
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XVYU2101010:
+ case DRM_FORMAT_C8:
case DRM_FORMAT_Y210:
case DRM_FORMAT_Y212:
case DRM_FORMAT_Y216:
@@ -2363,13 +2444,22 @@ static const struct drm_plane_funcs skl_plane_funcs = {
.format_mod_supported = skl_plane_format_mod_supported,
};
-static const struct drm_plane_funcs gen12_plane_funcs = {
+static const struct drm_plane_funcs icl_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = intel_plane_destroy,
+ .atomic_duplicate_state = intel_plane_duplicate_state,
+ .atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = icl_plane_format_mod_supported,
+};
+
+static const struct drm_plane_funcs tgl_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = intel_plane_destroy,
.atomic_duplicate_state = intel_plane_duplicate_state,
.atomic_destroy_state = intel_plane_destroy_state,
- .format_mod_supported = gen12_plane_format_mod_supported,
+ .format_mod_supported = tgl_plane_format_mod_supported,
};
static void
@@ -2411,8 +2501,8 @@ static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
(plane_id == PLANE_1 || plane_id == PLANE_2);
}
-static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
- enum plane_id plane_id)
+static bool tgl_plane_has_mc_ccs(struct drm_i915_private *i915,
+ enum plane_id plane_id)
{
if (DISPLAY_VER(i915) < 12)
return false;
@@ -2450,7 +2540,7 @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915,
caps |= INTEL_PLANE_CAP_CCS_RC_CC;
}
- if (gen12_plane_has_mc_ccs(i915, plane_id))
+ if (tgl_plane_has_mc_ccs(i915, plane_id))
caps |= INTEL_PLANE_CAP_CCS_MC;
if (DISPLAY_VER(i915) >= 14 && IS_DGFX(i915))
@@ -2541,7 +2631,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane_id, &num_formats);
if (DISPLAY_VER(dev_priv) >= 12)
- plane_funcs = &gen12_plane_funcs;
+ plane_funcs = &tgl_plane_funcs;
+ else if (DISPLAY_VER(dev_priv) == 11)
+ plane_funcs = &icl_plane_funcs;
else
plane_funcs = &skl_plane_funcs;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 045c7cac166b..31de33e868df 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3,6 +3,8 @@
* Copyright © 2022 Intel Corporation
*/
+#include <linux/debugfs.h>
+
#include <drm/drm_blend.h>
#include "i915_drv.h"
@@ -716,7 +718,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
int width, const struct drm_format_info *format,
u64 modifier, unsigned int rotation,
u32 plane_pixel_rate, struct skl_wm_params *wp,
- int color_plane);
+ int color_plane, unsigned int pan_x);
static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
struct intel_plane *plane,
@@ -763,7 +765,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
drm_format_info(DRM_FORMAT_ARGB8888),
DRM_FORMAT_MOD_LINEAR,
DRM_MODE_ROTATE_0,
- crtc_state->pixel_rate, &wp, 0);
+ crtc_state->pixel_rate, &wp, 0, 0);
drm_WARN_ON(&i915->drm, ret);
for (level = 0; level < i915->display.wm.num_levels; level++) {
@@ -1740,7 +1742,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
int width, const struct drm_format_info *format,
u64 modifier, unsigned int rotation,
u32 plane_pixel_rate, struct skl_wm_params *wp,
- int color_plane)
+ int color_plane, unsigned int pan_x)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
@@ -1801,7 +1803,9 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
wp->y_min_scanlines,
wp->dbuf_block_size);
- if (DISPLAY_VER(i915) >= 10)
+ if (DISPLAY_VER(i915) >= 30)
+ interm_pbpl += (pan_x != 0);
+ else if (DISPLAY_VER(i915) >= 10)
interm_pbpl++;
wp->plane_blocks_per_line = div_fixed16(interm_pbpl,
@@ -1843,7 +1847,8 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
fb->format, fb->modifier,
plane_state->hw.rotation,
intel_plane_pixel_rate(crtc_state, plane_state),
- wp, color_plane);
+ wp, color_plane,
+ plane_state->uapi.src.x1);
}
static bool skl_wm_has_lines(struct drm_i915_private *i915, int level)
@@ -1907,7 +1912,10 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
}
}
- blocks = fixed16_to_u32_round_up(selected_result) + 1;
+ blocks = fixed16_to_u32_round_up(selected_result);
+ if (DISPLAY_VER(i915) < 30)
+ blocks++;
+
/*
* Lets have blocks at minimum equivalent to plane_blocks_per_line
* as there will be at minimum one line for lines configuration. This
@@ -2971,6 +2979,7 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
static void skl_wm_get_hw_state(struct drm_i915_private *i915)
{
+ struct intel_display *display = &i915->display;
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(i915->display.dbuf.obj.state);
struct intel_crtc *crtc;
@@ -2978,7 +2987,7 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915)
if (HAS_MBUS_JOINING(i915))
dbuf_state->joined_mbus = intel_de_read(i915, MBUS_CTL) & MBUS_JOIN;
- dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(i915, &i915->display.cdclk.hw);
+ dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw);
for_each_intel_crtc(&i915->drm, crtc) {
struct intel_crtc_state *crtc_state =
@@ -3598,6 +3607,7 @@ static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state
static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state,
const struct intel_dbuf_state *dbuf_state)
{
+ struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
enum pipe pipe = ffs(dbuf_state->active_pipes) - 1;
const struct intel_crtc_state *new_crtc_state;
@@ -3606,7 +3616,7 @@ static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state,
drm_WARN_ON(&i915->drm, !dbuf_state->joined_mbus);
drm_WARN_ON(&i915->drm, !is_power_of_2(dbuf_state->active_pipes));
- crtc = intel_crtc_for_pipe(i915, pipe);
+ crtc = intel_crtc_for_pipe(display, pipe);
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
if (new_crtc_state && !intel_crtc_needs_modeset(new_crtc_state))
@@ -3668,7 +3678,7 @@ void intel_dbuf_mbus_pre_ddb_update(struct intel_atomic_state *state)
void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
const struct intel_dbuf_state *new_dbuf_state =
intel_atomic_get_new_dbuf_state(state);
const struct intel_dbuf_state *old_dbuf_state =
@@ -3687,7 +3697,7 @@ void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state)
intel_dbuf_mbus_join_update(state, pipe);
if (pipe != INVALID_PIPE) {
- struct intel_crtc *crtc = intel_crtc_for_pipe(i915, pipe);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
intel_crtc_wait_for_next_vblank(crtc);
}
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h
index 78b121941237..e73baec94873 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark.h
@@ -73,9 +73,9 @@ intel_atomic_get_dbuf_state(struct intel_atomic_state *state);
container_of_const((global_state), struct intel_dbuf_state, base)
#define intel_atomic_get_old_dbuf_state(state) \
- to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.dbuf.obj))
+ to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->dbuf.obj))
#define intel_atomic_get_new_dbuf_state(state) \
- to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->display.dbuf.obj))
+ to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->dbuf.obj))
int intel_dbuf_init(struct drm_i915_private *i915);
int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state,
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index d21f3fb39706..32d15bd9a358 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -30,6 +30,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -1071,7 +1072,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
hsync = intel_de_read(display, MIPI_HSYNC_PADDING_COUNT(display, port));
hbp = intel_de_read(display, MIPI_HBP_COUNT(display, port));
- /* harizontal values are in terms of high speed byte clock */
+ /* horizontal values are in terms of high speed byte clock */
hfp = pixels_from_txbyteclkhs(hfp, bpp, lane_count,
intel_dsi->burst_mode_ratio);
hsync = pixels_from_txbyteclkhs(hsync, bpp, lane_count,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index a3b83cfe1726..f151640c1d13 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -915,7 +915,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
*/
if (i915_gem_context_uses_protected_content(eb->gem_context) &&
i915_gem_object_is_protected(obj)) {
- err = intel_pxp_key_check(eb->i915->pxp, obj, true);
+ err = intel_pxp_key_check(eb->i915->pxp, intel_bo_to_drm_bo(obj), true);
if (err) {
i915_gem_object_put(obj);
return ERR_PTR(err);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 3b27218aabe2..900c08337942 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -13,7 +13,7 @@
#include "i915_driver.h"
#include "i915_drv.h"
-#if defined(CONFIG_X86)
+#if IS_ENABLED(CONFIG_X86)
#include <asm/smp.h>
#else
#define wbinvd_on_all_cpus() \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index d166052eb2ce..9117e9422844 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -117,7 +117,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
},
{ NULL, 0 },
}, *phase;
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
unsigned long count = 0;
unsigned long scanned = 0;
int err = 0, i = 0;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index d29005980806..9d958a6f377e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -457,7 +457,7 @@ static int init_reserved_stolen(struct drm_i915_private *i915)
icl_get_stolen_reserved(i915, uncore,
&reserved_base, &reserved_size);
} else if (GRAPHICS_VER(i915) >= 8) {
- if (IS_LP(i915))
+ if (IS_CHERRYVIEW(i915) || IS_BROXTON(i915) || IS_GEMINILAKE(i915))
chv_get_stolen_reserved(i915, uncore,
&reserved_base, &reserved_size);
else
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 070a8b3fa0fa..10d8673641f7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -1038,7 +1038,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
struct ttm_buffer_object *bo = area->vm_private_data;
struct drm_device *dev = bo->base.dev;
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
vm_fault_t ret;
int idx;
@@ -1195,7 +1195,7 @@ static u64 i915_ttm_mmap_offset(struct drm_i915_gem_object *obj)
static void i915_ttm_unmap_virtual(struct drm_i915_gem_object *obj)
{
struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
assert_object_held_shared(obj);
diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index 20b9b04ec1e0..cc866773ba6f 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -70,7 +70,7 @@ static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b)
if (!--b->irq_enabled)
b->irq_disable(b);
- WRITE_ONCE(b->irq_armed, 0);
+ WRITE_ONCE(b->irq_armed, NULL);
intel_gt_pm_put_async(b->irq_engine->gt, wakeref);
}
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index ad4c51f18d3a..1240d44eeb85 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -452,10 +452,10 @@ void gen8_gt_irq_reset(struct intel_gt *gt)
{
struct intel_uncore *uncore = gt->uncore;
- GEN8_IRQ_RESET_NDX(uncore, GT, 0);
- GEN8_IRQ_RESET_NDX(uncore, GT, 1);
- GEN8_IRQ_RESET_NDX(uncore, GT, 2);
- GEN8_IRQ_RESET_NDX(uncore, GT, 3);
+ gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(0));
+ gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(1));
+ gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(2));
+ gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(3));
}
void gen8_gt_irq_postinstall(struct intel_gt *gt)
@@ -476,14 +476,14 @@ void gen8_gt_irq_postinstall(struct intel_gt *gt)
gt->pm_ier = 0x0;
gt->pm_imr = ~gt->pm_ier;
- GEN8_IRQ_INIT_NDX(uncore, GT, 0, ~gt_interrupts[0], gt_interrupts[0]);
- GEN8_IRQ_INIT_NDX(uncore, GT, 1, ~gt_interrupts[1], gt_interrupts[1]);
+ gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(0), ~gt_interrupts[0], gt_interrupts[0]);
+ gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(1), ~gt_interrupts[1], gt_interrupts[1]);
/*
* RPS interrupts will get enabled/disabled on demand when RPS itself
* is enabled/disabled. Same wil be the case for GuC interrupts.
*/
- GEN8_IRQ_INIT_NDX(uncore, GT, 2, gt->pm_imr, gt->pm_ier);
- GEN8_IRQ_INIT_NDX(uncore, GT, 3, ~gt_interrupts[3], gt_interrupts[3]);
+ gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(2), gt->pm_imr, gt->pm_ier);
+ gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(3), ~gt_interrupts[3], gt_interrupts[3]);
}
static void gen5_gt_update_irq(struct intel_gt *gt,
@@ -514,9 +514,9 @@ void gen5_gt_irq_reset(struct intel_gt *gt)
{
struct intel_uncore *uncore = gt->uncore;
- GEN3_IRQ_RESET(uncore, GT);
+ gen2_irq_reset(uncore, GT_IRQ_REGS);
if (GRAPHICS_VER(gt->i915) >= 6)
- GEN3_IRQ_RESET(uncore, GEN6_PM);
+ gen2_irq_reset(uncore, GEN6_PM_IRQ_REGS);
}
void gen5_gt_irq_postinstall(struct intel_gt *gt)
@@ -538,7 +538,7 @@ void gen5_gt_irq_postinstall(struct intel_gt *gt)
else
gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT;
- GEN3_IRQ_INIT(uncore, GT, gt->gt_imr, gt_irqs);
+ gen2_irq_init(uncore, GT_IRQ_REGS, gt->gt_imr, gt_irqs);
if (GRAPHICS_VER(gt->i915) >= 6) {
/*
@@ -551,6 +551,6 @@ void gen5_gt_irq_postinstall(struct intel_gt *gt)
}
gt->pm_imr = 0xffffffff;
- GEN3_IRQ_INIT(uncore, GEN6_PM, gt->pm_imr, pm_irqs);
+ gen2_irq_init(uncore, GEN6_PM_IRQ_REGS, gt->pm_imr, pm_irqs);
}
}
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index 911fd0160221..6f25c747bc29 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -35,7 +35,7 @@ static inline void __intel_gt_pm_get(struct intel_gt *gt)
static inline intel_wakeref_t intel_gt_pm_get_if_awake(struct intel_gt *gt)
{
if (!intel_wakeref_get_if_active(&gt->wakeref))
- return 0;
+ return NULL;
return intel_wakeref_track(&gt->wakeref);
}
@@ -73,7 +73,7 @@ static inline void intel_gt_pm_put_async(struct intel_gt *gt, intel_wakeref_t ha
}
#define with_intel_gt_pm(gt, wf) \
- for (wf = intel_gt_pm_get(gt); wf; intel_gt_pm_put(gt, wf), wf = 0)
+ for ((wf) = intel_gt_pm_get(gt); (wf); intel_gt_pm_put((gt), (wf)), (wf) = NULL)
/**
* with_intel_gt_pm_if_awake - if GT is PM awake, get a reference to prevent
@@ -84,7 +84,7 @@ static inline void intel_gt_pm_put_async(struct intel_gt *gt, intel_wakeref_t ha
* @wf: pointer to a temporary wakeref.
*/
#define with_intel_gt_pm_if_awake(gt, wf) \
- for (wf = intel_gt_pm_get_if_awake(gt); wf; intel_gt_pm_put_async(gt, wf), wf = 0)
+ for ((wf) = intel_gt_pm_get_if_awake(gt); (wf); intel_gt_pm_put_async((gt), (wf)), (wf) = NULL)
static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
{
@@ -105,9 +105,13 @@ int intel_gt_runtime_resume(struct intel_gt *gt);
ktime_t intel_gt_get_awake_time(const struct intel_gt *gt);
+#define INTEL_WAKEREF_MOCK_GT ERR_PTR(-ENODEV)
+
static inline bool is_mock_gt(const struct intel_gt *gt)
{
- return I915_SELFTEST_ONLY(gt->awake == -ENODEV);
+ BUILD_BUG_ON(INTEL_WAKEREF_DEF == INTEL_WAKEREF_MOCK_GT);
+
+ return I915_SELFTEST_ONLY(gt->awake == INTEL_WAKEREF_MOCK_GT);
}
#endif /* INTEL_GT_PM_H */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 57a3c83d3655..6dba65e54cdb 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -432,6 +432,7 @@
#define XEHPG_INSTDONE_GEOM_SVG MCR_REG(0x666c)
#define CACHE_MODE_0_GEN7 _MMIO(0x7000) /* IVB+ */
+#define DISABLE_REPACKING_FOR_COMPRESSION REG_BIT(15) /* jsl+ */
#define RC_OP_FLUSH_ENABLE (1 << 0)
#define HIZ_RAW_STALL_OPT_DISABLE (1 << 2)
#define CACHE_MODE_1 _MMIO(0x7004) /* IVB+ */
@@ -1472,6 +1473,10 @@
GEN6_PM_RP_DOWN_THRESHOLD | \
GEN6_PM_RP_DOWN_TIMEOUT)
+#define GEN6_PM_IRQ_REGS I915_IRQ_REGS(GEN6_PMIMR, \
+ GEN6_PMIER, \
+ GEN6_PMIIR)
+
#define GEN7_GT_SCRATCH(i) _MMIO(0x4f100 + (i) * 4)
#define GEN7_GT_SCRATCH_REG_NUM 8
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 8f1ea95471ef..f42f21632306 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1233,7 +1233,7 @@ void intel_gt_reset(struct intel_gt *gt,
}
if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
- intel_runtime_pm_disable_interrupts(gt->i915);
+ intel_irq_suspend(gt->i915);
if (do_reset(gt, stalled_mask)) {
gt_err(gt, "Failed to reset chip\n");
@@ -1241,7 +1241,7 @@ void intel_gt_reset(struct intel_gt *gt,
}
if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display)
- intel_runtime_pm_enable_interrupts(gt->i915);
+ intel_irq_resume(gt->i915);
intel_overlay_reset(gt->i915);
diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c b/drivers/gpu/drm/i915/gt/intel_tlb.c
index 756e9ebbc725..2487768bc230 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.c
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
@@ -122,7 +122,7 @@ void intel_gt_invalidate_tlb_full(struct intel_gt *gt, u32 seqno)
{
intel_wakeref_t wakeref;
- if (I915_SELFTEST_ONLY(gt->awake == -ENODEV))
+ if (is_mock_gt(gt))
return;
if (intel_gt_is_wedged(gt))
diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index e539a656cfc3..6972525fe6be 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -2299,6 +2299,15 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
GEN8_RC_SEMA_IDLE_MSG_DISABLE);
}
+ if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) {
+ /*
+ * "Disable Repacking for Compression (masked R/W access)
+ * before rendering compressed surfaces for display."
+ */
+ wa_masked_en(wal, CACHE_MODE_0_GEN7,
+ DISABLE_REPACKING_FOR_COMPRESSION);
+ }
+
if (GRAPHICS_VER(i915) == 11) {
/* This is not an Wa. Enable for better image quality */
wa_masked_en(wal,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 23f54c84cbab..fe53e8eccf4b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -145,7 +145,7 @@ static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, bool
* an end user should hit the timeout is in case of extreme thermal throttling.
* And a system that is that hot during boot is probably dead anyway!
*/
-#if defined(CONFIG_DRM_I915_DEBUG_GEM)
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
#define GUC_LOAD_RETRY_LIMIT 20
#else
#define GUC_LOAD_RETRY_LIMIT 3
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index bf16351c9349..222c95f62156 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -14,7 +14,7 @@
#include "intel_guc_log.h"
#include "intel_guc_print.h"
-#if defined(CONFIG_DRM_I915_DEBUG_GUC)
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M
#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_16M
#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ed979847187f..9ede6f240d79 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1339,7 +1339,7 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
* start_gt_clk is derived from GuC state. To get a consistent
* view of activity, we query the GuC state only if gt is awake.
*/
- wakeref = in_reset ? 0 : intel_gt_pm_get_if_awake(gt);
+ wakeref = in_reset ? NULL : intel_gt_pm_get_if_awake(gt);
if (wakeref) {
stats_saved = *stats;
gt_stamp_saved = guc->timestamp.gt_stamp;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 2d9152eb7282..d7ac31c3254c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -455,7 +455,7 @@ static const char *auth_mode_string(struct intel_huc *huc,
* an end user should hit the timeout is in case of extreme thermal throttling.
* And a system that is that hot during boot is probably dead anyway!
*/
-#if defined(CONFIG_DRM_I915_DEBUG_GEM)
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
#define HUC_LOAD_RETRY_LIMIT 20
#else
#define HUC_LOAD_RETRY_LIMIT 3
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 2f4c9c66b40b..81d67a46cd9e 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -50,7 +50,6 @@
#include "trace.h"
#include "display/i9xx_plane_regs.h"
-#include "display/intel_display.h"
#include "display/intel_sprite_regs.h"
#include "gem/i915_gem_context.h"
#include "gem/i915_gem_pm.h"
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 58cca4906f41..1bce1493b86f 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1190,7 +1190,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
ppgtt_set_shadow_entry(spt, se, index);
return 0;
err:
- /* Cancel the existing addess mappings of DMA addr. */
+ /* Cancel the existing address mappings of DMA addr. */
for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) {
gvt_vdbg_mm("invalidate 4K entry\n");
ppgtt_invalidate_pte(sub_spt, &sub_se);
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index 908f910420c2..509f9ccae3a9 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -439,7 +439,7 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
gvt_vgpu_err("requesting SMI service\n");
return 0;
}
- /* ignore non 0->1 trasitions */
+ /* ignore non 0->1 transitions */
if ((vgpu_cfg_space(vgpu)[INTEL_GVT_PCI_SWSCI]
& SWSCI_SCI_TRIGGER) ||
!(swsci & SWSCI_SCI_TRIGGER)) {
diff --git a/drivers/gpu/drm/i915/gvt/page_track.c b/drivers/gpu/drm/i915/gvt/page_track.c
index 60a65435556d..20c3cd807488 100644
--- a/drivers/gpu/drm/i915/gvt/page_track.c
+++ b/drivers/gpu/drm/i915/gvt/page_track.c
@@ -167,7 +167,7 @@ int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa,
return -ENXIO;
if (unlikely(vgpu->failsafe)) {
- /* Remove write protection to prevent furture traps. */
+ /* Remove write protection to prevent future traps. */
intel_gvt_page_track_remove(vgpu, gpa >> PAGE_SHIFT);
} else {
ret = page_track->handler(page_track, gpa, data, bytes);
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index a5c8005ec484..23f2cc397ec9 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -1052,7 +1052,7 @@ void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu,
struct intel_vgpu_workload *pos, *n;
intel_engine_mask_t tmp;
- /* free the unsubmited workloads in the queues. */
+ /* free the unsubmitted workloads in the queues. */
for_each_engine_masked(engine, vgpu->gvt->gt, engine_mask, tmp) {
list_for_each_entry_safe(pos, n,
&s->workload_q_head[engine->id], list) {
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index f969f585d07b..1c2a97f593c7 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -33,8 +33,6 @@
#include <linux/debugfs.h>
#include <drm/drm_debugfs.h>
-#include "display/intel_display_params.h"
-
#include "gem/i915_gem_context.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_buffer_pool.h"
@@ -66,7 +64,6 @@ static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
static int i915_capabilities(struct seq_file *m, void *data)
{
struct drm_i915_private *i915 = node_to_i915(m->private);
- struct intel_display *display = &i915->display;
struct drm_printer p = drm_seq_file_printer(m);
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915));
@@ -76,10 +73,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
intel_gt_info_print(&to_gt(i915)->info, &p);
intel_driver_caps_print(&i915->caps, &p);
- kernel_param_lock(THIS_MODULE);
i915_params_dump(&i915->params, &p);
- intel_display_params_dump(display, &p);
- kernel_param_unlock(THIS_MODULE);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index 74fa8f57f302..365329ff8a07 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -48,8 +48,8 @@
#include "display/intel_acpi.h"
#include "display/intel_bw.h"
#include "display/intel_cdclk.h"
+#include "display/intel_crtc.h"
#include "display/intel_display_driver.h"
-#include "display/intel_display.h"
#include "display/intel_dmc.h"
#include "display/intel_dp.h"
#include "display/intel_dpt.h"
@@ -59,7 +59,7 @@
#include "display/intel_overlay.h"
#include "display/intel_pch_refclk.h"
#include "display/intel_pps.h"
-#include "display/intel_sprite.h"
+#include "display/intel_sprite_uapi.h"
#include "display/skl_watermark.h"
#include "gem/i915_gem_context.h"
@@ -950,7 +950,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
intel_dp_mst_suspend(i915);
- intel_runtime_pm_disable_interrupts(i915);
+ intel_irq_suspend(i915);
intel_hpd_cancel_work(i915);
if (HAS_DISPLAY(i915))
@@ -959,7 +959,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
intel_encoder_suspend_all(&i915->display);
intel_encoder_shutdown_all(&i915->display);
- intel_dmc_suspend(i915);
+ intel_dmc_suspend(&i915->display);
i915_gem_suspend(i915);
@@ -1035,7 +1035,7 @@ static int i915_drm_suspend(struct drm_device *dev)
intel_dp_mst_suspend(dev_priv);
- intel_runtime_pm_disable_interrupts(dev_priv);
+ intel_irq_suspend(dev_priv);
intel_hpd_cancel_work(dev_priv);
if (HAS_DISPLAY(dev_priv))
@@ -1054,7 +1054,7 @@ static int i915_drm_suspend(struct drm_device *dev)
dev_priv->suspend_count++;
- intel_dmc_suspend(dev_priv);
+ intel_dmc_suspend(display);
enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
@@ -1164,7 +1164,7 @@ static int i915_drm_resume(struct drm_device *dev)
/* Must be called after GGTT is resumed. */
intel_dpt_resume(dev_priv);
- intel_dmc_resume(dev_priv);
+ intel_dmc_resume(display);
i915_restore_display(dev_priv);
intel_pps_unlock_regs_wa(display);
@@ -1181,7 +1181,7 @@ static int i915_drm_resume(struct drm_device *dev)
* Modeset enabling in intel_display_driver_init_hw() also needs working
* interrupts.
*/
- intel_runtime_pm_enable_interrupts(dev_priv);
+ intel_irq_resume(dev_priv);
if (HAS_DISPLAY(dev_priv))
drm_mode_config_reset(dev);
@@ -1481,7 +1481,7 @@ static int intel_runtime_suspend(struct device *kdev)
for_each_gt(gt, dev_priv, i)
intel_gt_runtime_suspend(gt);
- intel_runtime_pm_disable_interrupts(dev_priv);
+ intel_irq_suspend(dev_priv);
for_each_gt(gt, dev_priv, i)
intel_uncore_suspend(gt->uncore);
@@ -1494,7 +1494,7 @@ static int intel_runtime_suspend(struct device *kdev)
"Runtime suspend failed, disabling it (%d)\n", ret);
intel_uncore_runtime_resume(&dev_priv->uncore);
- intel_runtime_pm_enable_interrupts(dev_priv);
+ intel_irq_resume(dev_priv);
for_each_gt(gt, dev_priv, i)
intel_gt_runtime_resume(gt);
@@ -1587,7 +1587,7 @@ static int intel_runtime_resume(struct device *kdev)
for_each_gt(gt, dev_priv, i)
intel_uncore_runtime_resume(gt->uncore);
- intel_runtime_pm_enable_interrupts(dev_priv);
+ intel_irq_resume(dev_priv);
/*
* No point of rolling back things in case of an error, as the best
@@ -1725,7 +1725,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_crtc_get_pipe_from_crtc_id_ioctl, 0),
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 39f6614a0a99..3c4b106cc7a0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -234,6 +234,7 @@ struct drm_i915_private {
/* protects the irq masks */
spinlock_t irq_lock;
+ bool irqs_enabled;
/* Sideband mailbox protection */
struct mutex sb_lock;
@@ -343,8 +344,6 @@ struct drm_i915_private {
struct intel_pxp *pxp;
- bool irq_enabled;
-
struct i915_pmu pmu;
/* The TTM device structure. */
@@ -613,9 +612,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define IS_TIGERLAKE_UY(i915) \
IS_SUBPLATFORM(i915, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY)
-#define IS_LP(i915) (INTEL_INFO(i915)->is_lp)
-#define IS_GEN9_LP(i915) (GRAPHICS_VER(i915) == 9 && IS_LP(i915))
-#define IS_GEN9_BC(i915) (GRAPHICS_VER(i915) == 9 && !IS_LP(i915))
+#define IS_GEN9_LP(i915) (IS_BROXTON(i915) || IS_GEMINILAKE(i915))
+#define IS_GEN9_BC(i915) (GRAPHICS_VER(i915) == 9 && !IS_GEN9_LP(i915))
#define __HAS_ENGINE(engine_mask, id) ((engine_mask) & BIT(id))
#define HAS_ENGINE(gt, id) __HAS_ENGINE((gt)->info.engine_mask, id)
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 6469b9bcf2ec..135ded17334e 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -40,8 +40,7 @@
#include <drm/drm_cache.h>
#include <drm/drm_print.h>
-#include "display/intel_dmc.h"
-#include "display/intel_overlay.h"
+#include "display/intel_display_snapshot.h"
#include "gem/i915_gem_context.h"
#include "gem/i915_gem_lmem.h"
@@ -651,8 +650,6 @@ static void err_print_capabilities(struct drm_i915_error_state_buf *m,
struct drm_printer p = i915_error_printer(m);
intel_device_info_print(&error->device_info, &error->runtime_info, &p);
- intel_display_device_info_print(&error->display_device_info,
- &error->display_runtime_info, &p);
intel_driver_caps_print(&error->driver_caps, &p);
}
@@ -660,10 +657,8 @@ static void err_print_params(struct drm_i915_error_state_buf *m,
const struct i915_params *params)
{
struct drm_printer p = i915_error_printer(m);
- struct intel_display *display = &m->i915->display;
i915_params_dump(params, &p);
- intel_display_params_dump(display, &p);
}
static void err_print_pciid(struct drm_i915_error_state_buf *m,
@@ -875,8 +870,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
- intel_dmc_print_error_state(&p, m->i915);
-
err_printf(m, "RPM wakelock: %s\n", str_yes_no(error->wakelock));
err_printf(m, "PM suspended: %s\n", str_yes_no(error->suspended));
@@ -905,11 +898,10 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
err_print_gt_info(m, error->gt);
}
- if (error->overlay)
- intel_overlay_print_error_state(&p, error->overlay);
-
err_print_capabilities(m, error);
err_print_params(m, &error->params);
+
+ intel_display_snapshot_print(error->display_snapshot, &p);
}
static int err_print_to_sgl(struct i915_gpu_coredump *error)
@@ -1032,7 +1024,6 @@ static void i915_vma_coredump_free(struct i915_vma_coredump *vma)
static void cleanup_params(struct i915_gpu_coredump *error)
{
i915_params_free(&error->params);
- intel_display_params_free(&error->display_params);
}
static void cleanup_uc(struct intel_uc_coredump *uc)
@@ -1077,7 +1068,7 @@ void __i915_gpu_coredump_free(struct kref *error_ref)
cleanup_gt(gt);
}
- kfree(error->overlay);
+ intel_display_snapshot_free(error->display_snapshot);
cleanup_params(error);
@@ -1993,17 +1984,12 @@ static void capture_gen(struct i915_gpu_coredump *error)
error->suspend_count = i915->suspend_count;
i915_params_copy(&error->params, &i915->params);
- intel_display_params_copy(&error->display_params);
memcpy(&error->device_info,
INTEL_INFO(i915),
sizeof(error->device_info));
memcpy(&error->runtime_info,
RUNTIME_INFO(i915),
sizeof(error->runtime_info));
- memcpy(&error->display_device_info, DISPLAY_INFO(i915),
- sizeof(error->display_device_info));
- memcpy(&error->display_runtime_info, DISPLAY_RUNTIME_INFO(i915),
- sizeof(error->display_runtime_info));
error->driver_caps = i915->caps;
}
@@ -2097,6 +2083,7 @@ static struct i915_gpu_coredump *
__i915_gpu_coredump(struct intel_gt *gt, intel_engine_mask_t engine_mask, u32 dump_flags)
{
struct drm_i915_private *i915 = gt->i915;
+ struct intel_display *display = &i915->display;
struct i915_gpu_coredump *error;
/* Check if GPU capture has been disabled */
@@ -2138,7 +2125,7 @@ __i915_gpu_coredump(struct intel_gt *gt, intel_engine_mask_t engine_mask, u32 du
error->simulated |= error->gt->simulated;
}
- error->overlay = intel_overlay_capture_error_state(i915);
+ error->display_snapshot = intel_display_snapshot_capture(display);
return error;
}
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index 7c255bb1c319..78a8928562a9 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -14,8 +14,6 @@
#include <drm/drm_mm.h>
-#include "display/intel_display_device.h"
-#include "display/intel_display_params.h"
#include "gt/intel_engine.h"
#include "gt/intel_engine_types.h"
#include "gt/intel_gt_types.h"
@@ -31,7 +29,7 @@
struct drm_i915_private;
struct i915_vma_compress;
struct intel_engine_capture_vma;
-struct intel_overlay_error_state;
+struct intel_display_snapshot;
struct i915_vma_coredump {
struct i915_vma_coredump *next;
@@ -212,15 +210,12 @@ struct i915_gpu_coredump {
struct intel_device_info device_info;
struct intel_runtime_info runtime_info;
- struct intel_display_device_info display_device_info;
- struct intel_display_runtime_info display_runtime_info;
struct intel_driver_caps driver_caps;
struct i915_params params;
- struct intel_display_params display_params;
-
- struct intel_overlay_error_state *overlay;
struct scatterlist *sgl, *fit;
+
+ struct intel_display_snapshot *display_snapshot;
};
struct i915_gpu_error {
diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c
index 17d30f6b84b0..7dfe1784153f 100644
--- a/drivers/gpu/drm/i915/i915_hwmon.c
+++ b/drivers/gpu/drm/i915/i915_hwmon.c
@@ -7,6 +7,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/types.h>
+#include <linux/units.h>
#include "i915_drv.h"
#include "i915_hwmon.h"
@@ -32,6 +33,7 @@
struct hwm_reg {
i915_reg_t gt_perf_status;
+ i915_reg_t pkg_temp;
i915_reg_t pkg_power_sku_unit;
i915_reg_t pkg_power_sku;
i915_reg_t pkg_rapl_limit;
@@ -280,6 +282,7 @@ static const struct attribute_group *hwm_groups[] = {
};
static const struct hwmon_channel_info * const hwm_info[] = {
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_CRIT),
HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),
@@ -311,6 +314,37 @@ static int hwm_pcode_write_i1(struct drm_i915_private *i915, u32 uval)
}
static umode_t
+hwm_temp_is_visible(const struct hwm_drvdata *ddat, u32 attr)
+{
+ struct i915_hwmon *hwmon = ddat->hwmon;
+
+ if (attr == hwmon_temp_input && i915_mmio_reg_valid(hwmon->rg.pkg_temp))
+ return 0444;
+
+ return 0;
+}
+
+static int
+hwm_temp_read(struct hwm_drvdata *ddat, u32 attr, long *val)
+{
+ struct i915_hwmon *hwmon = ddat->hwmon;
+ intel_wakeref_t wakeref;
+ u32 reg_val;
+
+ switch (attr) {
+ case hwmon_temp_input:
+ with_intel_runtime_pm(ddat->uncore->rpm, wakeref)
+ reg_val = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_temp);
+
+ /* HW register value is in degrees Celsius, convert to millidegrees. */
+ *val = REG_FIELD_GET(TEMP_MASK, reg_val) * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static umode_t
hwm_in_is_visible(const struct hwm_drvdata *ddat, u32 attr)
{
struct drm_i915_private *i915 = ddat->uncore->i915;
@@ -692,6 +726,8 @@ hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type,
struct hwm_drvdata *ddat = (struct hwm_drvdata *)drvdata;
switch (type) {
+ case hwmon_temp:
+ return hwm_temp_is_visible(ddat, attr);
case hwmon_in:
return hwm_in_is_visible(ddat, attr);
case hwmon_power:
@@ -714,6 +750,8 @@ hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
struct hwm_drvdata *ddat = dev_get_drvdata(dev);
switch (type) {
+ case hwmon_temp:
+ return hwm_temp_read(ddat, attr, val);
case hwmon_in:
return hwm_in_read(ddat, attr, val);
case hwmon_power:
@@ -810,6 +848,7 @@ hwm_get_preregistration_info(struct drm_i915_private *i915)
hwmon->rg.gt_perf_status = GEN12_RPSTAT1;
if (IS_DG1(i915) || IS_DG2(i915)) {
+ hwmon->rg.pkg_temp = PCU_PACKAGE_TEMPERATURE;
hwmon->rg.pkg_power_sku_unit = PCU_PACKAGE_POWER_SKU_UNIT;
hwmon->rg.pkg_power_sku = PCU_PACKAGE_POWER_SKU;
hwmon->rg.pkg_rapl_limit = PCU_PACKAGE_RAPL_LIMIT;
@@ -817,6 +856,7 @@ hwm_get_preregistration_info(struct drm_i915_private *i915)
hwmon->rg.energy_status_tile = INVALID_MMIO_REG;
hwmon->rg.fan_speed = PCU_PWM_FAN_SPEED;
} else {
+ hwmon->rg.pkg_temp = INVALID_MMIO_REG;
hwmon->rg.pkg_power_sku_unit = INVALID_MMIO_REG;
hwmon->rg.pkg_power_sku = INVALID_MMIO_REG;
hwmon->rg.pkg_rapl_limit = INVALID_MMIO_REG;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2321de48d169..f75cbf5b8a1c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -77,39 +77,24 @@ static inline void pmu_irq_stats(struct drm_i915_private *i915,
WRITE_ONCE(i915->pmu.irq_count, i915->pmu.irq_count + 1);
}
-void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr,
- i915_reg_t iir, i915_reg_t ier)
+void gen2_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs)
{
- intel_uncore_write(uncore, imr, 0xffffffff);
- intel_uncore_posting_read(uncore, imr);
+ intel_uncore_write(uncore, regs.imr, 0xffffffff);
+ intel_uncore_posting_read(uncore, regs.imr);
- intel_uncore_write(uncore, ier, 0);
+ intel_uncore_write(uncore, regs.ier, 0);
/* IIR can theoretically queue up two events. Be paranoid. */
- intel_uncore_write(uncore, iir, 0xffffffff);
- intel_uncore_posting_read(uncore, iir);
- intel_uncore_write(uncore, iir, 0xffffffff);
- intel_uncore_posting_read(uncore, iir);
-}
-
-static void gen2_irq_reset(struct intel_uncore *uncore)
-{
- intel_uncore_write16(uncore, GEN2_IMR, 0xffff);
- intel_uncore_posting_read16(uncore, GEN2_IMR);
-
- intel_uncore_write16(uncore, GEN2_IER, 0);
-
- /* IIR can theoretically queue up two events. Be paranoid. */
- intel_uncore_write16(uncore, GEN2_IIR, 0xffff);
- intel_uncore_posting_read16(uncore, GEN2_IIR);
- intel_uncore_write16(uncore, GEN2_IIR, 0xffff);
- intel_uncore_posting_read16(uncore, GEN2_IIR);
+ intel_uncore_write(uncore, regs.iir, 0xffffffff);
+ intel_uncore_posting_read(uncore, regs.iir);
+ intel_uncore_write(uncore, regs.iir, 0xffffffff);
+ intel_uncore_posting_read(uncore, regs.iir);
}
/*
* We should clear IMR at preinstall/uninstall, and just check at postinstall.
*/
-void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg)
+void gen2_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg)
{
u32 val = intel_uncore_read(uncore, reg);
@@ -125,42 +110,14 @@ void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg)
intel_uncore_posting_read(uncore, reg);
}
-static void gen2_assert_iir_is_zero(struct intel_uncore *uncore)
-{
- u16 val = intel_uncore_read16(uncore, GEN2_IIR);
-
- if (val == 0)
- return;
-
- drm_WARN(&uncore->i915->drm, 1,
- "Interrupt register 0x%x is not zero: 0x%08x\n",
- i915_mmio_reg_offset(GEN2_IIR), val);
- intel_uncore_write16(uncore, GEN2_IIR, 0xffff);
- intel_uncore_posting_read16(uncore, GEN2_IIR);
- intel_uncore_write16(uncore, GEN2_IIR, 0xffff);
- intel_uncore_posting_read16(uncore, GEN2_IIR);
-}
-
-void gen3_irq_init(struct intel_uncore *uncore,
- i915_reg_t imr, u32 imr_val,
- i915_reg_t ier, u32 ier_val,
- i915_reg_t iir)
-{
- gen3_assert_iir_is_zero(uncore, iir);
-
- intel_uncore_write(uncore, ier, ier_val);
- intel_uncore_write(uncore, imr, imr_val);
- intel_uncore_posting_read(uncore, imr);
-}
-
-static void gen2_irq_init(struct intel_uncore *uncore,
- u32 imr_val, u32 ier_val)
+void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs,
+ u32 imr_val, u32 ier_val)
{
- gen2_assert_iir_is_zero(uncore);
+ gen2_assert_iir_is_zero(uncore, regs.iir);
- intel_uncore_write16(uncore, GEN2_IER, ier_val);
- intel_uncore_write16(uncore, GEN2_IMR, imr_val);
- intel_uncore_posting_read16(uncore, GEN2_IMR);
+ intel_uncore_write(uncore, regs.ier, ier_val);
+ intel_uncore_write(uncore, regs.imr, imr_val);
+ intel_uncore_posting_read(uncore, regs.imr);
}
/**
@@ -298,7 +255,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
hotplug_status = i9xx_hpd_irq_ack(dev_priv);
/* Call regardless, as some status bits might not be
- * signalled in iir */
+ * signalled in IIR */
i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
if (iir & (I915_LPE_PIPE_A_INTERRUPT |
@@ -380,7 +337,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
hotplug_status = i9xx_hpd_irq_ack(dev_priv);
/* Call regardless, as some status bits might not be
- * signalled in iir */
+ * signalled in IIR */
i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
if (iir & (I915_LPE_PIPE_A_INTERRUPT |
@@ -665,7 +622,7 @@ static void ibx_irq_reset(struct drm_i915_private *dev_priv)
if (HAS_PCH_NOP(dev_priv))
return;
- GEN3_IRQ_RESET(uncore, SDE);
+ gen2_irq_reset(uncore, SDE_IRQ_REGS);
if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv))
intel_uncore_write(&dev_priv->uncore, SERR_INT, 0xffffffff);
@@ -677,7 +634,7 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
- GEN3_IRQ_RESET(uncore, DE);
+ gen2_irq_reset(uncore, DE_IRQ_REGS);
dev_priv->irq_mask = ~0u;
if (GRAPHICS_VER(dev_priv) == 7)
@@ -714,7 +671,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
gen8_gt_irq_reset(to_gt(dev_priv));
gen8_display_irq_reset(dev_priv);
- GEN3_IRQ_RESET(uncore, GEN8_PCU_);
+ gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
if (HAS_PCH_SPLIT(dev_priv))
ibx_irq_reset(dev_priv);
@@ -731,8 +688,8 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv)
gen11_gt_irq_reset(gt);
gen11_display_irq_reset(dev_priv);
- GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_);
- GEN3_IRQ_RESET(uncore, GEN8_PCU_);
+ gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS);
+ gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
}
static void dg1_irq_reset(struct drm_i915_private *dev_priv)
@@ -748,8 +705,8 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv)
gen11_display_irq_reset(dev_priv);
- GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_);
- GEN3_IRQ_RESET(uncore, GEN8_PCU_);
+ gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS);
+ gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
intel_uncore_write(uncore, GEN11_GFX_MSTR_IRQ, ~0);
}
@@ -763,7 +720,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv)
gen8_gt_irq_reset(to_gt(dev_priv));
- GEN3_IRQ_RESET(uncore, GEN8_PCU_);
+ gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->display.irq.display_irqs_enabled)
@@ -808,7 +765,7 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
gen11_gt_irq_postinstall(gt);
gen11_de_irq_postinstall(dev_priv);
- GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked);
+ gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked);
gen11_master_intr_enable(intel_uncore_regs(uncore));
intel_uncore_posting_read(&dev_priv->uncore, GEN11_GFX_MSTR_IRQ);
@@ -824,7 +781,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv)
for_each_gt(gt, dev_priv, i)
gen11_gt_irq_postinstall(gt);
- GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked);
+ gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked);
dg1_de_irq_postinstall(dev_priv);
@@ -845,16 +802,6 @@ static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv)
intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ);
}
-static void i8xx_irq_reset(struct drm_i915_private *dev_priv)
-{
- struct intel_uncore *uncore = &dev_priv->uncore;
-
- i9xx_pipestat_irq_reset(dev_priv);
-
- gen2_irq_reset(uncore);
- dev_priv->irq_mask = ~0u;
-}
-
static u32 i9xx_error_mask(struct drm_i915_private *i915)
{
/*
@@ -876,76 +823,6 @@ static u32 i9xx_error_mask(struct drm_i915_private *i915)
I915_ERROR_MEMORY_REFRESH);
}
-static void i8xx_irq_postinstall(struct drm_i915_private *dev_priv)
-{
- struct intel_uncore *uncore = &dev_priv->uncore;
- u16 enable_mask;
-
- intel_uncore_write16(uncore, EMR, i9xx_error_mask(dev_priv));
-
- /* Unmask the interrupts that we always want on. */
- dev_priv->irq_mask =
- ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
- I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
- I915_MASTER_ERROR_INTERRUPT);
-
- enable_mask =
- I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
- I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
- I915_MASTER_ERROR_INTERRUPT |
- I915_USER_INTERRUPT;
-
- gen2_irq_init(uncore, dev_priv->irq_mask, enable_mask);
-
- /* Interrupt setup is already guaranteed to be single-threaded, this is
- * just to make the assert_spin_locked check happy. */
- spin_lock_irq(&dev_priv->irq_lock);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
- i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
- spin_unlock_irq(&dev_priv->irq_lock);
-}
-
-static void i8xx_error_irq_ack(struct drm_i915_private *i915,
- u16 *eir, u16 *eir_stuck)
-{
- struct intel_uncore *uncore = &i915->uncore;
- u16 emr;
-
- *eir = intel_uncore_read16(uncore, EIR);
- intel_uncore_write16(uncore, EIR, *eir);
-
- *eir_stuck = intel_uncore_read16(uncore, EIR);
- if (*eir_stuck == 0)
- return;
-
- /*
- * Toggle all EMR bits to make sure we get an edge
- * in the ISR master error bit if we don't clear
- * all the EIR bits. Otherwise the edge triggered
- * IIR on i965/g4x wouldn't notice that an interrupt
- * is still pending. Also some EIR bits can't be
- * cleared except by handling the underlying error
- * (or by a GPU reset) so we mask any bit that
- * remains set.
- */
- emr = intel_uncore_read16(uncore, EMR);
- intel_uncore_write16(uncore, EMR, 0xffff);
- intel_uncore_write16(uncore, EMR, emr | *eir_stuck);
-}
-
-static void i8xx_error_irq_handler(struct drm_i915_private *dev_priv,
- u16 eir, u16 eir_stuck)
-{
- drm_dbg(&dev_priv->drm, "Master Error: EIR 0x%04x\n", eir);
-
- if (eir_stuck)
- drm_dbg(&dev_priv->drm, "EIR stuck: 0x%04x, masked\n",
- eir_stuck);
-
- drm_dbg(&dev_priv->drm, "PGTBL_ER: 0x%08x\n",
- intel_uncore_read(&dev_priv->uncore, PGTBL_ER));
-}
-
static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv,
u32 *eir, u32 *eir_stuck)
{
@@ -986,66 +863,13 @@ static void i9xx_error_irq_handler(struct drm_i915_private *dev_priv,
intel_uncore_read(&dev_priv->uncore, PGTBL_ER));
}
-static irqreturn_t i8xx_irq_handler(int irq, void *arg)
-{
- struct drm_i915_private *dev_priv = arg;
- irqreturn_t ret = IRQ_NONE;
-
- if (!intel_irqs_enabled(dev_priv))
- return IRQ_NONE;
-
- /* IRQs are synced during runtime_suspend, we don't require a wakeref */
- disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
-
- do {
- u32 pipe_stats[I915_MAX_PIPES] = {};
- u16 eir = 0, eir_stuck = 0;
- u16 iir;
-
- iir = intel_uncore_read16(&dev_priv->uncore, GEN2_IIR);
- if (iir == 0)
- break;
-
- ret = IRQ_HANDLED;
-
- /* Call regardless, as some status bits might not be
- * signalled in iir */
- i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
- i8xx_error_irq_ack(dev_priv, &eir, &eir_stuck);
-
- intel_uncore_write16(&dev_priv->uncore, GEN2_IIR, iir);
-
- if (iir & I915_USER_INTERRUPT)
- intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], iir);
-
- if (iir & I915_MASTER_ERROR_INTERRUPT)
- i8xx_error_irq_handler(dev_priv, eir, eir_stuck);
-
- i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats);
- } while (0);
-
- pmu_irq_stats(dev_priv, ret);
-
- enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
-
- return ret;
-}
-
static void i915_irq_reset(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
- if (I915_HAS_HOTPLUG(dev_priv)) {
- i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
- intel_uncore_rmw(&dev_priv->uncore,
- PORT_HOTPLUG_STAT(dev_priv), 0, 0);
- }
-
- i9xx_pipestat_irq_reset(dev_priv);
+ i9xx_display_irq_reset(dev_priv);
- GEN3_IRQ_RESET(uncore, GEN2_);
+ gen2_irq_reset(uncore, GEN2_IRQ_REGS);
dev_priv->irq_mask = ~0u;
}
@@ -1056,28 +880,28 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv)
intel_uncore_write(uncore, EMR, i9xx_error_mask(dev_priv));
- /* Unmask the interrupts that we always want on. */
dev_priv->irq_mask =
- ~(I915_ASLE_INTERRUPT |
- I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+ ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
I915_MASTER_ERROR_INTERRUPT);
enable_mask =
- I915_ASLE_INTERRUPT |
I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
I915_MASTER_ERROR_INTERRUPT |
I915_USER_INTERRUPT;
+ if (DISPLAY_VER(dev_priv) >= 3) {
+ dev_priv->irq_mask &= ~I915_ASLE_INTERRUPT;
+ enable_mask |= I915_ASLE_INTERRUPT;
+ }
+
if (I915_HAS_HOTPLUG(dev_priv)) {
- /* Enable in IER... */
- enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
- /* and unmask in IMR */
dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT;
+ enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
}
- GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask);
+ gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->irq_mask, enable_mask);
/* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy. */
@@ -1117,7 +941,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
hotplug_status = i9xx_hpd_irq_ack(dev_priv);
/* Call regardless, as some status bits might not be
- * signalled in iir */
+ * signalled in IIR */
i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
if (iir & I915_MASTER_ERROR_INTERRUPT)
@@ -1148,12 +972,9 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
- i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
- intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT(dev_priv), 0, 0);
+ i9xx_display_irq_reset(dev_priv);
- i9xx_pipestat_irq_reset(dev_priv);
-
- GEN3_IRQ_RESET(uncore, GEN2_);
+ gen2_irq_reset(uncore, GEN2_IRQ_REGS);
dev_priv->irq_mask = ~0u;
}
@@ -1183,7 +1004,6 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv)
intel_uncore_write(uncore, EMR, i965_error_mask(dev_priv));
- /* Unmask the interrupts that we always want on. */
dev_priv->irq_mask =
~(I915_ASLE_INTERRUPT |
I915_DISPLAY_PORT_INTERRUPT |
@@ -1202,7 +1022,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv)
if (IS_G4X(dev_priv))
enable_mask |= I915_BSD_USER_INTERRUPT;
- GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask);
+ gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->irq_mask, enable_mask);
/* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy. */
@@ -1242,7 +1062,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
hotplug_status = i9xx_hpd_irq_ack(dev_priv);
/* Call regardless, as some status bits might not be
- * signalled in iir */
+ * signalled in IIR */
i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
if (iir & I915_MASTER_ERROR_INTERRUPT)
@@ -1317,10 +1137,8 @@ static irq_handler_t intel_irq_handler(struct drm_i915_private *dev_priv)
return valleyview_irq_handler;
else if (GRAPHICS_VER(dev_priv) == 4)
return i965_irq_handler;
- else if (GRAPHICS_VER(dev_priv) == 3)
- return i915_irq_handler;
else
- return i8xx_irq_handler;
+ return i915_irq_handler;
} else {
if (GRAPHICS_VER_FULL(dev_priv) >= IP_VER(12, 10))
return dg1_irq_handler;
@@ -1342,10 +1160,8 @@ static void intel_irq_reset(struct drm_i915_private *dev_priv)
valleyview_irq_reset(dev_priv);
else if (GRAPHICS_VER(dev_priv) == 4)
i965_irq_reset(dev_priv);
- else if (GRAPHICS_VER(dev_priv) == 3)
- i915_irq_reset(dev_priv);
else
- i8xx_irq_reset(dev_priv);
+ i915_irq_reset(dev_priv);
} else {
if (GRAPHICS_VER_FULL(dev_priv) >= IP_VER(12, 10))
dg1_irq_reset(dev_priv);
@@ -1367,10 +1183,8 @@ static void intel_irq_postinstall(struct drm_i915_private *dev_priv)
valleyview_irq_postinstall(dev_priv);
else if (GRAPHICS_VER(dev_priv) == 4)
i965_irq_postinstall(dev_priv);
- else if (GRAPHICS_VER(dev_priv) == 3)
- i915_irq_postinstall(dev_priv);
else
- i8xx_irq_postinstall(dev_priv);
+ i915_irq_postinstall(dev_priv);
} else {
if (GRAPHICS_VER_FULL(dev_priv) >= IP_VER(12, 10))
dg1_irq_postinstall(dev_priv);
@@ -1404,16 +1218,14 @@ int intel_irq_install(struct drm_i915_private *dev_priv)
* interrupts as enabled _before_ actually enabling them to avoid
* special cases in our ordering checks.
*/
- dev_priv->runtime_pm.irqs_enabled = true;
-
- dev_priv->irq_enabled = true;
+ dev_priv->irqs_enabled = true;
intel_irq_reset(dev_priv);
ret = request_irq(irq, intel_irq_handler(dev_priv),
IRQF_SHARED, DRIVER_NAME, dev_priv);
if (ret < 0) {
- dev_priv->irq_enabled = false;
+ dev_priv->irqs_enabled = false;
return ret;
}
@@ -1433,56 +1245,46 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
{
int irq = to_pci_dev(dev_priv->drm.dev)->irq;
- /*
- * FIXME we can get called twice during driver probe
- * error handling as well as during driver remove due to
- * intel_display_driver_remove() calling us out of sequence.
- * Would be nice if it didn't do that...
- */
- if (!dev_priv->irq_enabled)
+ if (drm_WARN_ON(&dev_priv->drm, !dev_priv->irqs_enabled))
return;
- dev_priv->irq_enabled = false;
-
intel_irq_reset(dev_priv);
free_irq(irq, dev_priv);
intel_hpd_cancel_work(dev_priv);
- dev_priv->runtime_pm.irqs_enabled = false;
+ dev_priv->irqs_enabled = false;
}
/**
- * intel_runtime_pm_disable_interrupts - runtime interrupt disabling
- * @dev_priv: i915 device instance
+ * intel_irq_suspend - Suspend interrupts
+ * @i915: i915 device instance
*
- * This function is used to disable interrupts at runtime, both in the runtime
- * pm and the system suspend/resume code.
+ * This function is used to disable interrupts at runtime.
*/
-void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
+void intel_irq_suspend(struct drm_i915_private *i915)
{
- intel_irq_reset(dev_priv);
- dev_priv->runtime_pm.irqs_enabled = false;
- intel_synchronize_irq(dev_priv);
+ intel_irq_reset(i915);
+ i915->irqs_enabled = false;
+ intel_synchronize_irq(i915);
}
/**
- * intel_runtime_pm_enable_interrupts - runtime interrupt enabling
- * @dev_priv: i915 device instance
+ * intel_irq_resume - Resume interrupts
+ * @i915: i915 device instance
*
- * This function is used to enable interrupts at runtime, both in the runtime
- * pm and the system suspend/resume code.
+ * This function is used to enable interrupts at runtime.
*/
-void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv)
+void intel_irq_resume(struct drm_i915_private *i915)
{
- dev_priv->runtime_pm.irqs_enabled = true;
- intel_irq_reset(dev_priv);
- intel_irq_postinstall(dev_priv);
+ i915->irqs_enabled = true;
+ intel_irq_reset(i915);
+ intel_irq_postinstall(i915);
}
bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
{
- return dev_priv->runtime_pm.irqs_enabled;
+ return dev_priv->irqs_enabled;
}
void intel_synchronize_irq(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h
index e665a1b007dc..0457f6402e05 100644
--- a/drivers/gpu/drm/i915/i915_irq.h
+++ b/drivers/gpu/drm/i915/i915_irq.h
@@ -34,45 +34,17 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv);
void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915, u32 mask);
-void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
-void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
+void intel_irq_suspend(struct drm_i915_private *i915);
+void intel_irq_resume(struct drm_i915_private *i915);
bool intel_irqs_enabled(struct drm_i915_private *dev_priv);
void intel_synchronize_irq(struct drm_i915_private *i915);
void intel_synchronize_hardirq(struct drm_i915_private *i915);
-void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg);
+void gen2_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg);
-void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr,
- i915_reg_t iir, i915_reg_t ier);
+void gen2_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs);
-void gen3_irq_init(struct intel_uncore *uncore,
- i915_reg_t imr, u32 imr_val,
- i915_reg_t ier, u32 ier_val,
- i915_reg_t iir);
-
-#define GEN8_IRQ_RESET_NDX(uncore, type, which) \
-({ \
- unsigned int which_ = which; \
- gen3_irq_reset((uncore), GEN8_##type##_IMR(which_), \
- GEN8_##type##_IIR(which_), GEN8_##type##_IER(which_)); \
-})
-
-#define GEN3_IRQ_RESET(uncore, type) \
- gen3_irq_reset((uncore), type##IMR, type##IIR, type##IER)
-
-#define GEN8_IRQ_INIT_NDX(uncore, type, which, imr_val, ier_val) \
-({ \
- unsigned int which_ = which; \
- gen3_irq_init((uncore), \
- GEN8_##type##_IMR(which_), imr_val, \
- GEN8_##type##_IER(which_), ier_val, \
- GEN8_##type##_IIR(which_)); \
-})
-
-#define GEN3_IRQ_INIT(uncore, type, imr_val, ier_val) \
- gen3_irq_init((uncore), \
- type##IMR, imr_val, \
- type##IER, ier_val, \
- type##IIR)
+void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs,
+ u32 imr_val, u32 ier_val);
#endif /* __I915_IRQ_H__ */
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index d37bb3a704d0..eaf8a098e1c5 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -367,7 +367,6 @@ static const struct intel_device_info ivb_q_info = {
static const struct intel_device_info vlv_info = {
PLATFORM(INTEL_VALLEYVIEW),
GEN(7),
- .is_lp = 1,
.has_runtime_pm = 1,
.has_rc6 = 1,
.has_reset_engine = true,
@@ -451,7 +450,6 @@ static const struct intel_device_info bdw_gt3_info = {
static const struct intel_device_info chv_info = {
PLATFORM(INTEL_CHERRYVIEW),
GEN(8),
- .is_lp = 1,
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
.has_64bit_reloc = 1,
.has_runtime_pm = 1,
@@ -512,7 +510,6 @@ static const struct intel_device_info skl_gt4_info = {
#define GEN9_LP_FEATURES \
GEN(9), \
- .is_lp = 1, \
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
.has_3d_pipeline = 1, \
.has_64bit_reloc = 1, \
@@ -870,6 +867,7 @@ static const struct pci_device_id pciidlist[] = {
INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &adl_p_info),
INTEL_DG2_IDS(INTEL_VGA_DEVICE, &dg2_info),
INTEL_ATS_M_IDS(INTEL_VGA_DEVICE, &ats_m_info),
+ INTEL_ARL_IDS(INTEL_VGA_DEVICE, &mtl_info),
INTEL_MTL_IDS(INTEL_VGA_DEVICE, &mtl_info),
{}
};
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 41f4350a7c6c..818142f5a10c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -422,6 +422,11 @@
#define GEN2_IIR _MMIO(0x20a4)
#define GEN2_IMR _MMIO(0x20a8)
#define GEN2_ISR _MMIO(0x20ac)
+
+#define GEN2_IRQ_REGS I915_IRQ_REGS(GEN2_IMR, \
+ GEN2_IER, \
+ GEN2_IIR)
+
#define VLV_GUNIT_CLOCK_GATE _MMIO(VLV_DISPLAY_BASE + 0x2060)
#define GINT_DIS (1 << 22)
#define GCFG_DIS (1 << 8)
@@ -434,6 +439,10 @@
#define VLV_PCBR _MMIO(VLV_DISPLAY_BASE + 0x2120)
#define VLV_PCBR_ADDR_SHIFT 12
+#define VLV_IRQ_REGS I915_IRQ_REGS(VLV_IMR, \
+ VLV_IER, \
+ VLV_IIR)
+
#define DISPLAY_PLANE_FLIP_PENDING(plane) (1 << (11 - (plane))) /* A and B only */
#define EIR _MMIO(0x20b0)
#define EMR _MMIO(0x20b4)
@@ -1071,87 +1080,77 @@
/* Pipe/transcoder A timing regs */
#define _TRANS_HTOTAL_A 0x60000
+#define _TRANS_HTOTAL_B 0x61000
+#define TRANS_HTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HTOTAL_A)
#define HTOTAL_MASK REG_GENMASK(31, 16)
#define HTOTAL(htotal) REG_FIELD_PREP(HTOTAL_MASK, (htotal))
#define HACTIVE_MASK REG_GENMASK(15, 0)
#define HACTIVE(hdisplay) REG_FIELD_PREP(HACTIVE_MASK, (hdisplay))
+
#define _TRANS_HBLANK_A 0x60004
+#define _TRANS_HBLANK_B 0x61004
+#define TRANS_HBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HBLANK_A)
#define HBLANK_END_MASK REG_GENMASK(31, 16)
#define HBLANK_END(hblank_end) REG_FIELD_PREP(HBLANK_END_MASK, (hblank_end))
#define HBLANK_START_MASK REG_GENMASK(15, 0)
#define HBLANK_START(hblank_start) REG_FIELD_PREP(HBLANK_START_MASK, (hblank_start))
+
#define _TRANS_HSYNC_A 0x60008
+#define _TRANS_HSYNC_B 0x61008
+#define TRANS_HSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HSYNC_A)
#define HSYNC_END_MASK REG_GENMASK(31, 16)
#define HSYNC_END(hsync_end) REG_FIELD_PREP(HSYNC_END_MASK, (hsync_end))
#define HSYNC_START_MASK REG_GENMASK(15, 0)
#define HSYNC_START(hsync_start) REG_FIELD_PREP(HSYNC_START_MASK, (hsync_start))
+
#define _TRANS_VTOTAL_A 0x6000c
+#define _TRANS_VTOTAL_B 0x6100c
+#define TRANS_VTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VTOTAL_A)
#define VTOTAL_MASK REG_GENMASK(31, 16)
#define VTOTAL(vtotal) REG_FIELD_PREP(VTOTAL_MASK, (vtotal))
#define VACTIVE_MASK REG_GENMASK(15, 0)
#define VACTIVE(vdisplay) REG_FIELD_PREP(VACTIVE_MASK, (vdisplay))
+
#define _TRANS_VBLANK_A 0x60010
+#define _TRANS_VBLANK_B 0x61010
+#define TRANS_VBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VBLANK_A)
#define VBLANK_END_MASK REG_GENMASK(31, 16)
#define VBLANK_END(vblank_end) REG_FIELD_PREP(VBLANK_END_MASK, (vblank_end))
#define VBLANK_START_MASK REG_GENMASK(15, 0)
#define VBLANK_START(vblank_start) REG_FIELD_PREP(VBLANK_START_MASK, (vblank_start))
+
#define _TRANS_VSYNC_A 0x60014
+#define _TRANS_VSYNC_B 0x61014
+#define TRANS_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNC_A)
#define VSYNC_END_MASK REG_GENMASK(31, 16)
#define VSYNC_END(vsync_end) REG_FIELD_PREP(VSYNC_END_MASK, (vsync_end))
#define VSYNC_START_MASK REG_GENMASK(15, 0)
#define VSYNC_START(vsync_start) REG_FIELD_PREP(VSYNC_START_MASK, (vsync_start))
-#define _TRANS_EXITLINE_A 0x60018
+
#define _PIPEASRC 0x6001c
+#define _PIPEBSRC 0x6101c
+#define PIPESRC(dev_priv, pipe) _MMIO_TRANS2(dev_priv, (pipe), _PIPEASRC)
#define PIPESRC_WIDTH_MASK REG_GENMASK(31, 16)
#define PIPESRC_WIDTH(w) REG_FIELD_PREP(PIPESRC_WIDTH_MASK, (w))
#define PIPESRC_HEIGHT_MASK REG_GENMASK(15, 0)
#define PIPESRC_HEIGHT(h) REG_FIELD_PREP(PIPESRC_HEIGHT_MASK, (h))
-#define _BCLRPAT_A 0x60020
-#define _TRANS_VSYNCSHIFT_A 0x60028
-#define _TRANS_MULT_A 0x6002c
-/* Pipe/transcoder B timing regs */
-#define _TRANS_HTOTAL_B 0x61000
-#define _TRANS_HBLANK_B 0x61004
-#define _TRANS_HSYNC_B 0x61008
-#define _TRANS_VTOTAL_B 0x6100c
-#define _TRANS_VBLANK_B 0x61010
-#define _TRANS_VSYNC_B 0x61014
-#define _PIPEBSRC 0x6101c
+#define _BCLRPAT_A 0x60020
#define _BCLRPAT_B 0x61020
-#define _TRANS_VSYNCSHIFT_B 0x61028
-#define _TRANS_MULT_B 0x6102c
-
-/* DSI 0 timing regs */
-#define _TRANS_HTOTAL_DSI0 0x6b000
-#define _TRANS_HSYNC_DSI0 0x6b008
-#define _TRANS_VTOTAL_DSI0 0x6b00c
-#define _TRANS_VSYNC_DSI0 0x6b014
-#define _TRANS_VSYNCSHIFT_DSI0 0x6b028
-
-/* DSI 1 timing regs */
-#define _TRANS_HTOTAL_DSI1 0x6b800
-#define _TRANS_HSYNC_DSI1 0x6b808
-#define _TRANS_VTOTAL_DSI1 0x6b80c
-#define _TRANS_VSYNC_DSI1 0x6b814
-#define _TRANS_VSYNCSHIFT_DSI1 0x6b828
-
-#define TRANS_HTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HTOTAL_A)
-#define TRANS_HBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HBLANK_A)
-#define TRANS_HSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HSYNC_A)
-#define TRANS_VTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VTOTAL_A)
-#define TRANS_VBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VBLANK_A)
-#define TRANS_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNC_A)
#define BCLRPAT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _BCLRPAT_A)
+
+#define _TRANS_VSYNCSHIFT_A 0x60028
+#define _TRANS_VSYNCSHIFT_B 0x61028
#define TRANS_VSYNCSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNCSHIFT_A)
-#define PIPESRC(dev_priv, pipe) _MMIO_TRANS2(dev_priv, (pipe), _PIPEASRC)
+
+#define _TRANS_MULT_A 0x6002c
+#define _TRANS_MULT_B 0x6102c
#define TRANS_MULT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A)
/* VGA port control */
#define ADPA _MMIO(0x61100)
#define PCH_ADPA _MMIO(0xe1100)
#define VLV_ADPA _MMIO(VLV_DISPLAY_BASE + 0x61100)
-
#define ADPA_DAC_ENABLE (1 << 31)
#define ADPA_DAC_DISABLE 0
#define ADPA_PIPE_SEL_SHIFT 30
@@ -1195,7 +1194,6 @@
#define ADPA_DPMS_STANDBY (2 << 10)
#define ADPA_DPMS_OFF (3 << 10)
-
/* Hotplug control (945+ only) */
#define PORT_HOTPLUG_EN(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61110)
#define PORTB_HOTPLUG_INT_EN (1 << 29)
@@ -1446,11 +1444,9 @@
#define DP_B _MMIO(0x64100)
#define DP_C _MMIO(0x64200)
#define DP_D _MMIO(0x64300)
-
#define VLV_DP_B _MMIO(VLV_DISPLAY_BASE + 0x64100)
#define VLV_DP_C _MMIO(VLV_DISPLAY_BASE + 0x64200)
#define CHV_DP_D _MMIO(VLV_DISPLAY_BASE + 0x64300)
-
#define DP_PORT_EN (1 << 31)
#define DP_PIPE_SEL_SHIFT 30
#define DP_PIPE_SEL_MASK (1 << 30)
@@ -1549,16 +1545,16 @@
*/
#define _PIPEA_DATA_M_G4X 0x70050
#define _PIPEB_DATA_M_G4X 0x71050
-
+#define PIPE_DATA_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X)
/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
#define TU_SIZE_MASK REG_GENMASK(30, 25)
#define TU_SIZE(x) REG_FIELD_PREP(TU_SIZE_MASK, (x) - 1) /* default size 64 */
-
#define DATA_LINK_M_N_MASK REG_GENMASK(23, 0)
#define DATA_LINK_N_MAX (0x800000)
#define _PIPEA_DATA_N_G4X 0x70054
#define _PIPEB_DATA_N_G4X 0x71054
+#define PIPE_DATA_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X)
/*
* Computing Link M and N values for the Display Port link
@@ -1570,22 +1566,22 @@
* The Link value is transmitted in the Main Stream
* Attributes and VB-ID.
*/
-
#define _PIPEA_LINK_M_G4X 0x70060
#define _PIPEB_LINK_M_G4X 0x71060
+#define PIPE_LINK_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X)
+
#define _PIPEA_LINK_N_G4X 0x70064
#define _PIPEB_LINK_N_G4X 0x71064
-
-#define PIPE_DATA_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X)
-#define PIPE_DATA_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X)
-#define PIPE_LINK_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X)
#define PIPE_LINK_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X)
/* Pipe A */
#define _PIPEADSL 0x70000
+#define PIPEDSL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEADSL)
#define PIPEDSL_CURR_FIELD REG_BIT(31) /* ctg+ */
#define PIPEDSL_LINE_MASK REG_GENMASK(19, 0)
+
#define _TRANSACONF 0x70008
+#define TRANSCONF(dev_priv, trans) _MMIO_PIPE2(dev_priv, (trans), _TRANSACONF)
#define TRANSCONF_ENABLE REG_BIT(31)
#define TRANSCONF_DOUBLE_WIDE REG_BIT(30) /* pre-i965 */
#define TRANSCONF_STATE_ENABLE REG_BIT(30) /* i965+ */
@@ -1645,6 +1641,7 @@
#define TRANSCONF_PIXEL_COUNT_SCALING_X4 1
#define _PIPEASTAT 0x70024
+#define PIPESTAT(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEASTAT)
#define PIPE_FIFO_UNDERRUN_STATUS (1UL << 31)
#define SPRITE1_FLIP_DONE_INT_EN_VLV (1UL << 30)
#define PIPE_CRC_ERROR_ENABLE (1UL << 29)
@@ -1691,15 +1688,8 @@
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1)
#define PIPE_HBLANK_INT_STATUS (1UL << 0)
#define PIPE_OVERLAY_UPDATED_STATUS (1UL << 0)
-
-#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000
-#define PIPESTAT_INT_STATUS_MASK 0x0000ffff
-
-#define TRANSCONF(dev_priv, trans) _MMIO_PIPE2(dev_priv, (trans), _TRANSACONF)
-#define PIPEDSL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEADSL)
-#define PIPEFRAME(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEHIGH)
-#define PIPEFRAMEPIXEL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEPIXEL)
-#define PIPESTAT(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEASTAT)
+#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000
+#define PIPESTAT_INT_STATUS_MASK 0x0000ffff
#define _PIPE_ARB_CTL_A 0x70028 /* icl+ */
#define PIPE_ARB_CTL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPE_ARB_CTL_A)
@@ -1707,6 +1697,7 @@
#define _PIPE_MISC_A 0x70030
#define _PIPE_MISC_B 0x71030
+#define PIPE_MISC(pipe) _MMIO_PIPE(pipe, _PIPE_MISC_A, _PIPE_MISC_B)
#define PIPE_MISC_YUV420_ENABLE REG_BIT(27) /* glk+ */
#define PIPE_MISC_YUV420_MODE_FULL_BLEND REG_BIT(26) /* glk+ */
#define PIPE_MISC_HDR_MODE_PRECISION REG_BIT(23) /* icl+ */
@@ -1734,16 +1725,15 @@
#define PIPE_MISC_DITHER_TYPE_ST1 REG_FIELD_PREP(PIPE_MISC_DITHER_TYPE_MASK, 1)
#define PIPE_MISC_DITHER_TYPE_ST2 REG_FIELD_PREP(PIPE_MISC_DITHER_TYPE_MASK, 2)
#define PIPE_MISC_DITHER_TYPE_TEMP REG_FIELD_PREP(PIPE_MISC_DITHER_TYPE_MASK, 3)
-#define PIPE_MISC(pipe) _MMIO_PIPE(pipe, _PIPE_MISC_A, _PIPE_MISC_B)
#define _PIPE_MISC2_A 0x7002C
#define _PIPE_MISC2_B 0x7102C
+#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B)
#define PIPE_MISC2_BUBBLE_COUNTER_MASK REG_GENMASK(31, 24)
#define PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN REG_FIELD_PREP(PIPE_MISC2_BUBBLE_COUNTER_MASK, 80)
#define PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS REG_FIELD_PREP(PIPE_MISC2_BUBBLE_COUNTER_MASK, 20)
#define PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK REG_GENMASK(2, 0) /* tgl+ */
#define PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id) REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
-#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B)
#define _ICL_PIPE_A_STATUS 0x70058
#define ICL_PIPESTATUS(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _ICL_PIPE_A_STATUS)
@@ -2066,33 +2056,38 @@
* frame = (high1 << 8) | low1;
*/
#define _PIPEAFRAMEHIGH 0x70040
+#define PIPEFRAME(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEHIGH)
#define PIPE_FRAME_HIGH_MASK 0x0000ffff
#define PIPE_FRAME_HIGH_SHIFT 0
+
#define _PIPEAFRAMEPIXEL 0x70044
+#define PIPEFRAMEPIXEL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEPIXEL)
#define PIPE_FRAME_LOW_MASK 0xff000000
#define PIPE_FRAME_LOW_SHIFT 24
#define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0
+
/* GM45+ just has to be different */
#define _PIPEA_FRMCOUNT_G4X 0x70040
-#define _PIPEA_FLIPCOUNT_G4X 0x70044
#define PIPE_FRMCOUNT_G4X(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FRMCOUNT_G4X)
+
+#define _PIPEA_FLIPCOUNT_G4X 0x70044
#define PIPE_FLIPCOUNT_G4X(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FLIPCOUNT_G4X)
/* CHV pipe B blender */
#define _CHV_BLEND_A 0x60a00
+#define CHV_BLEND(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_BLEND_A)
#define CHV_BLEND_MASK REG_GENMASK(31, 30)
#define CHV_BLEND_LEGACY REG_FIELD_PREP(CHV_BLEND_MASK, 0)
#define CHV_BLEND_ANDROID REG_FIELD_PREP(CHV_BLEND_MASK, 1)
#define CHV_BLEND_MPO REG_FIELD_PREP(CHV_BLEND_MASK, 2)
+
#define _CHV_CANVAS_A 0x60a04
+#define CHV_CANVAS(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_CANVAS_A)
#define CHV_CANVAS_RED_MASK REG_GENMASK(29, 20)
#define CHV_CANVAS_GREEN_MASK REG_GENMASK(19, 10)
#define CHV_CANVAS_BLUE_MASK REG_GENMASK(9, 0)
-#define CHV_BLEND(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_BLEND_A)
-#define CHV_CANVAS(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_CANVAS_A)
-
/* Display/Sprite base address macros */
#define DISP_BASEADDR_MASK (0xfffff000)
#define I915_LO_DISPBASE(val) ((val) & ~DISP_BASEADDR_MASK)
@@ -2114,11 +2109,6 @@
#define SWF3(dev_priv, i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x72414 + (i) * 4)
#define SWF_ILK(i) _MMIO(0x4F000 + (i) * 4)
-/* ICL DSI 0 and 1 */
-#define _PIPEDSI0CONF 0x7b008
-#define _PIPEDSI1CONF 0x7b808
-
-
/* VBIOS regs */
#define VGACNTRL _MMIO(0x71400)
# define VGA_DISP_DISABLE (1 << 31)
@@ -2156,38 +2146,42 @@
# define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11)
#define _PIPEA_DATA_M1 0x60030
-#define _PIPEA_DATA_N1 0x60034
-#define _PIPEA_DATA_M2 0x60038
-#define _PIPEA_DATA_N2 0x6003c
-#define _PIPEA_LINK_M1 0x60040
-#define _PIPEA_LINK_N1 0x60044
-#define _PIPEA_LINK_M2 0x60048
-#define _PIPEA_LINK_N2 0x6004c
-
-/* PIPEB timing regs are same start from 0x61000 */
-
#define _PIPEB_DATA_M1 0x61030
-#define _PIPEB_DATA_N1 0x61034
-#define _PIPEB_DATA_M2 0x61038
-#define _PIPEB_DATA_N2 0x6103c
-#define _PIPEB_LINK_M1 0x61040
-#define _PIPEB_LINK_N1 0x61044
-#define _PIPEB_LINK_M2 0x61048
-#define _PIPEB_LINK_N2 0x6104c
-
#define PIPE_DATA_M1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M1)
+
+#define _PIPEA_DATA_N1 0x60034
+#define _PIPEB_DATA_N1 0x61034
#define PIPE_DATA_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N1)
+
+#define _PIPEA_DATA_M2 0x60038
+#define _PIPEB_DATA_M2 0x61038
#define PIPE_DATA_M2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M2)
+
+#define _PIPEA_DATA_N2 0x6003c
+#define _PIPEB_DATA_N2 0x6103c
#define PIPE_DATA_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N2)
+
+#define _PIPEA_LINK_M1 0x60040
+#define _PIPEB_LINK_M1 0x61040
#define PIPE_LINK_M1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M1)
+
+#define _PIPEA_LINK_N1 0x60044
+#define _PIPEB_LINK_N1 0x61044
#define PIPE_LINK_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N1)
+
+#define _PIPEA_LINK_M2 0x60048
+#define _PIPEB_LINK_M2 0x61048
#define PIPE_LINK_M2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M2)
+
+#define _PIPEA_LINK_N2 0x6004c
+#define _PIPEB_LINK_N2 0x6104c
#define PIPE_LINK_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N2)
/* CPU panel fitter */
/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */
#define _PFA_CTL_1 0x68080
#define _PFB_CTL_1 0x68880
+#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1)
#define PF_ENABLE REG_BIT(31)
#define PF_PIPE_SEL_MASK_IVB REG_GENMASK(30, 29) /* ivb/hsw */
#define PF_PIPE_SEL_IVB(pipe) REG_FIELD_PREP(PF_PIPE_SEL_MASK_IVB, (pipe))
@@ -2196,37 +2190,43 @@
#define PF_FILTER_MED_3x3 REG_FIELD_PREP(PF_FILTER_MASK, 1)
#define PF_FILTER_EDGE_ENHANCE REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 2)
#define PF_FILTER_EDGE_SOFTEN REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 3)
+
#define _PFA_WIN_SZ 0x68074
#define _PFB_WIN_SZ 0x68874
+#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ)
#define PF_WIN_XSIZE_MASK REG_GENMASK(31, 16)
#define PF_WIN_XSIZE(w) REG_FIELD_PREP(PF_WIN_XSIZE_MASK, (w))
#define PF_WIN_YSIZE_MASK REG_GENMASK(15, 0)
#define PF_WIN_YSIZE(h) REG_FIELD_PREP(PF_WIN_YSIZE_MASK, (h))
+
#define _PFA_WIN_POS 0x68070
#define _PFB_WIN_POS 0x68870
+#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS)
#define PF_WIN_XPOS_MASK REG_GENMASK(31, 16)
#define PF_WIN_XPOS(x) REG_FIELD_PREP(PF_WIN_XPOS_MASK, (x))
#define PF_WIN_YPOS_MASK REG_GENMASK(15, 0)
#define PF_WIN_YPOS(y) REG_FIELD_PREP(PF_WIN_YPOS_MASK, (y))
+
#define _PFA_VSCALE 0x68084
#define _PFB_VSCALE 0x68884
+#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
+
#define _PFA_HSCALE 0x68090
#define _PFB_HSCALE 0x68890
-
-#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1)
-#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ)
-#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS)
-#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
#define PF_HSCALE(pipe) _MMIO_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
/*
* Skylake scalers
*/
+#define _ID(id, a, b) _PICK_EVEN(id, a, b)
#define _PS_1A_CTRL 0x68180
#define _PS_2A_CTRL 0x68280
#define _PS_1B_CTRL 0x68980
#define _PS_2B_CTRL 0x68A80
#define _PS_1C_CTRL 0x69180
+#define SKL_PS_CTRL(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_1A_CTRL, _PS_2A_CTRL), \
+ _ID(id, _PS_1B_CTRL, _PS_2B_CTRL))
#define PS_SCALER_EN REG_BIT(31)
#define PS_SCALER_TYPE_MASK REG_BIT(30) /* icl+ */
#define PS_SCALER_TYPE_NON_LINEAR REG_FIELD_PREP(PS_SCALER_TYPE_MASK, 0)
@@ -2279,6 +2279,9 @@
#define _PS_PWR_GATE_1B 0x68960
#define _PS_PWR_GATE_2B 0x68A60
#define _PS_PWR_GATE_1C 0x69160
+#define SKL_PS_PWR_GATE(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_PWR_GATE_1A, _PS_PWR_GATE_2A), \
+ _ID(id, _PS_PWR_GATE_1B, _PS_PWR_GATE_2B))
#define PS_PWR_GATE_DIS_OVERRIDE REG_BIT(31)
#define PS_PWR_GATE_SETTLING_TIME_MASK REG_GENMASK(4, 3)
#define PS_PWR_GATE_SETTLING_TIME_32 REG_FIELD_PREP(PS_PWR_GATE_SETTLING_TIME_MASK, 0)
@@ -2296,6 +2299,9 @@
#define _PS_WIN_POS_1B 0x68970
#define _PS_WIN_POS_2B 0x68A70
#define _PS_WIN_POS_1C 0x69170
+#define SKL_PS_WIN_POS(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_WIN_POS_1A, _PS_WIN_POS_2A), \
+ _ID(id, _PS_WIN_POS_1B, _PS_WIN_POS_2B))
#define PS_WIN_XPOS_MASK REG_GENMASK(31, 16)
#define PS_WIN_XPOS(x) REG_FIELD_PREP(PS_WIN_XPOS_MASK, (x))
#define PS_WIN_YPOS_MASK REG_GENMASK(15, 0)
@@ -2306,6 +2312,9 @@
#define _PS_WIN_SZ_1B 0x68974
#define _PS_WIN_SZ_2B 0x68A74
#define _PS_WIN_SZ_1C 0x69174
+#define SKL_PS_WIN_SZ(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_WIN_SZ_1A, _PS_WIN_SZ_2A), \
+ _ID(id, _PS_WIN_SZ_1B, _PS_WIN_SZ_2B))
#define PS_WIN_XSIZE_MASK REG_GENMASK(31, 16)
#define PS_WIN_XSIZE(w) REG_FIELD_PREP(PS_WIN_XSIZE_MASK, (w))
#define PS_WIN_YSIZE_MASK REG_GENMASK(15, 0)
@@ -2316,18 +2325,27 @@
#define _PS_VSCALE_1B 0x68984
#define _PS_VSCALE_2B 0x68A84
#define _PS_VSCALE_1C 0x69184
+#define SKL_PS_VSCALE(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_VSCALE_1A, _PS_VSCALE_2A), \
+ _ID(id, _PS_VSCALE_1B, _PS_VSCALE_2B))
#define _PS_HSCALE_1A 0x68190
#define _PS_HSCALE_2A 0x68290
#define _PS_HSCALE_1B 0x68990
#define _PS_HSCALE_2B 0x68A90
#define _PS_HSCALE_1C 0x69190
+#define SKL_PS_HSCALE(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_HSCALE_1A, _PS_HSCALE_2A), \
+ _ID(id, _PS_HSCALE_1B, _PS_HSCALE_2B))
#define _PS_VPHASE_1A 0x68188
#define _PS_VPHASE_2A 0x68288
#define _PS_VPHASE_1B 0x68988
#define _PS_VPHASE_2B 0x68A88
#define _PS_VPHASE_1C 0x69188
+#define SKL_PS_VPHASE(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_VPHASE_1A, _PS_VPHASE_2A), \
+ _ID(id, _PS_VPHASE_1B, _PS_VPHASE_2B))
#define PS_Y_PHASE_MASK REG_GENMASK(31, 16)
#define PS_Y_PHASE(x) REG_FIELD_PREP(PS_Y_PHASE_MASK, (x))
#define PS_UV_RGB_PHASE_MASK REG_GENMASK(15, 0)
@@ -2340,56 +2358,32 @@
#define _PS_HPHASE_1B 0x68994
#define _PS_HPHASE_2B 0x68A94
#define _PS_HPHASE_1C 0x69194
+#define SKL_PS_HPHASE(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_HPHASE_1A, _PS_HPHASE_2A), \
+ _ID(id, _PS_HPHASE_1B, _PS_HPHASE_2B))
#define _PS_ECC_STAT_1A 0x681D0
#define _PS_ECC_STAT_2A 0x682D0
#define _PS_ECC_STAT_1B 0x689D0
#define _PS_ECC_STAT_2B 0x68AD0
#define _PS_ECC_STAT_1C 0x691D0
+#define SKL_PS_ECC_STAT(pipe, id) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \
+ _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B))
#define _PS_COEF_SET0_INDEX_1A 0x68198
#define _PS_COEF_SET0_INDEX_2A 0x68298
#define _PS_COEF_SET0_INDEX_1B 0x68998
#define _PS_COEF_SET0_INDEX_2B 0x68A98
+#define GLK_PS_COEF_INDEX_SET(pipe, id, set) _MMIO_PIPE(pipe, \
+ _ID(id, _PS_COEF_SET0_INDEX_1A, _PS_COEF_SET0_INDEX_2A) + (set) * 8, \
+ _ID(id, _PS_COEF_SET0_INDEX_1B, _PS_COEF_SET0_INDEX_2B) + (set) * 8)
#define PS_COEF_INDEX_AUTO_INC REG_BIT(10)
#define _PS_COEF_SET0_DATA_1A 0x6819C
#define _PS_COEF_SET0_DATA_2A 0x6829C
#define _PS_COEF_SET0_DATA_1B 0x6899C
#define _PS_COEF_SET0_DATA_2B 0x68A9C
-
-#define _ID(id, a, b) _PICK_EVEN(id, a, b)
-#define SKL_PS_CTRL(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_1A_CTRL, _PS_2A_CTRL), \
- _ID(id, _PS_1B_CTRL, _PS_2B_CTRL))
-#define SKL_PS_PWR_GATE(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_PWR_GATE_1A, _PS_PWR_GATE_2A), \
- _ID(id, _PS_PWR_GATE_1B, _PS_PWR_GATE_2B))
-#define SKL_PS_WIN_POS(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_WIN_POS_1A, _PS_WIN_POS_2A), \
- _ID(id, _PS_WIN_POS_1B, _PS_WIN_POS_2B))
-#define SKL_PS_WIN_SZ(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_WIN_SZ_1A, _PS_WIN_SZ_2A), \
- _ID(id, _PS_WIN_SZ_1B, _PS_WIN_SZ_2B))
-#define SKL_PS_VSCALE(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_VSCALE_1A, _PS_VSCALE_2A), \
- _ID(id, _PS_VSCALE_1B, _PS_VSCALE_2B))
-#define SKL_PS_HSCALE(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_HSCALE_1A, _PS_HSCALE_2A), \
- _ID(id, _PS_HSCALE_1B, _PS_HSCALE_2B))
-#define SKL_PS_VPHASE(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_VPHASE_1A, _PS_VPHASE_2A), \
- _ID(id, _PS_VPHASE_1B, _PS_VPHASE_2B))
-#define SKL_PS_HPHASE(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_HPHASE_1A, _PS_HPHASE_2A), \
- _ID(id, _PS_HPHASE_1B, _PS_HPHASE_2B))
-#define SKL_PS_ECC_STAT(pipe, id) _MMIO_PIPE(pipe, \
- _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \
- _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B))
-#define GLK_PS_COEF_INDEX_SET(pipe, id, set) _MMIO_PIPE(pipe, \
- _ID(id, _PS_COEF_SET0_INDEX_1A, _PS_COEF_SET0_INDEX_2A) + (set) * 8, \
- _ID(id, _PS_COEF_SET0_INDEX_1B, _PS_COEF_SET0_INDEX_2B) + (set) * 8)
-
#define GLK_PS_COEF_DATA_SET(pipe, id, set) _MMIO_PIPE(pipe, \
_ID(id, _PS_COEF_SET0_DATA_1A, _PS_COEF_SET0_DATA_2A) + (set) * 8, \
_ID(id, _PS_COEF_SET0_DATA_1B, _PS_COEF_SET0_DATA_2B) + (set) * 8)
@@ -2459,11 +2453,19 @@
#define DEIIR _MMIO(0x44008)
#define DEIER _MMIO(0x4400c)
+#define DE_IRQ_REGS I915_IRQ_REGS(DEIMR, \
+ DEIER, \
+ DEIIR)
+
#define GTISR _MMIO(0x44010)
#define GTIMR _MMIO(0x44014)
#define GTIIR _MMIO(0x44018)
#define GTIER _MMIO(0x4401c)
+#define GT_IRQ_REGS I915_IRQ_REGS(GTIMR, \
+ GTIER, \
+ GTIIR)
+
#define GEN8_MASTER_IRQ _MMIO(0x44200)
#define GEN8_MASTER_IRQ_CONTROL (1 << 31)
#define GEN8_PCU_IRQ (1 << 30)
@@ -2489,6 +2491,10 @@
#define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which)))
#define GEN8_GT_IER(which) _MMIO(0x4430c + (0x10 * (which)))
+#define GEN8_GT_IRQ_REGS(which) I915_IRQ_REGS(GEN8_GT_IMR(which), \
+ GEN8_GT_IER(which), \
+ GEN8_GT_IIR(which))
+
#define GEN8_RCS_IRQ_SHIFT 0
#define GEN8_BCS_IRQ_SHIFT 16
#define GEN8_VCS0_IRQ_SHIFT 0 /* NB: VCS1 in bspec! */
@@ -2540,6 +2546,10 @@
#define GEN8_PIPE_VSYNC REG_BIT(1)
#define GEN8_PIPE_VBLANK REG_BIT(0)
+#define GEN8_DE_PIPE_IRQ_REGS(pipe) I915_IRQ_REGS(GEN8_DE_PIPE_IMR(pipe), \
+ GEN8_DE_PIPE_IER(pipe), \
+ GEN8_DE_PIPE_IIR(pipe))
+
#define _HPD_PIN_DDI(hpd_pin) ((hpd_pin) - HPD_PORT_A)
#define _HPD_PIN_TC(hpd_pin) ((hpd_pin) - HPD_PORT_TC1)
@@ -2575,6 +2585,10 @@
#define TGL_DE_PORT_AUX_DDIB REG_BIT(1)
#define TGL_DE_PORT_AUX_DDIA REG_BIT(0)
+#define GEN8_DE_PORT_IRQ_REGS I915_IRQ_REGS(GEN8_DE_PORT_IMR, \
+ GEN8_DE_PORT_IER, \
+ GEN8_DE_PORT_IIR)
+
#define GEN8_DE_MISC_ISR _MMIO(0x44460)
#define GEN8_DE_MISC_IMR _MMIO(0x44464)
#define GEN8_DE_MISC_IIR _MMIO(0x44468)
@@ -2585,17 +2599,29 @@
#define GEN8_DE_EDP_PSR REG_BIT(19)
#define XELPDP_PMDEMAND_RSP REG_BIT(3)
+#define GEN8_DE_MISC_IRQ_REGS I915_IRQ_REGS(GEN8_DE_MISC_IMR, \
+ GEN8_DE_MISC_IER, \
+ GEN8_DE_MISC_IIR)
+
#define GEN8_PCU_ISR _MMIO(0x444e0)
#define GEN8_PCU_IMR _MMIO(0x444e4)
#define GEN8_PCU_IIR _MMIO(0x444e8)
#define GEN8_PCU_IER _MMIO(0x444ec)
+#define GEN8_PCU_IRQ_REGS I915_IRQ_REGS(GEN8_PCU_IMR, \
+ GEN8_PCU_IER, \
+ GEN8_PCU_IIR)
+
#define GEN11_GU_MISC_ISR _MMIO(0x444f0)
#define GEN11_GU_MISC_IMR _MMIO(0x444f4)
#define GEN11_GU_MISC_IIR _MMIO(0x444f8)
#define GEN11_GU_MISC_IER _MMIO(0x444fc)
#define GEN11_GU_MISC_GSE (1 << 27)
+#define GEN11_GU_MISC_IRQ_REGS I915_IRQ_REGS(GEN11_GU_MISC_IMR, \
+ GEN11_GU_MISC_IER, \
+ GEN11_GU_MISC_IIR)
+
#define GEN11_GFX_MSTR_IRQ _MMIO(0x190010)
#define GEN11_MASTER_IRQ (1 << 31)
#define GEN11_PCU_IRQ (1 << 30)
@@ -2639,6 +2665,10 @@
GEN11_TBT_HOTPLUG(HPD_PORT_TC2) | \
GEN11_TBT_HOTPLUG(HPD_PORT_TC1))
+#define GEN11_DE_HPD_IRQ_REGS I915_IRQ_REGS(GEN11_DE_HPD_IMR, \
+ GEN11_DE_HPD_IER, \
+ GEN11_DE_HPD_IIR)
+
#define GEN11_TBT_HOTPLUG_CTL _MMIO(0x44030)
#define GEN11_TC_HOTPLUG_CTL _MMIO(0x44038)
#define GEN11_HOTPLUG_CTL_ENABLE(hpd_pin) (8 << (_HPD_PIN_TC(hpd_pin) * 4))
@@ -2659,6 +2689,10 @@
#define XELPDP_TBT_HOTPLUG(hpd_pin) REG_BIT(_HPD_PIN_TC(hpd_pin))
#define XELPDP_TBT_HOTPLUG_MASK REG_GENMASK(3, 0)
+#define PICAINTERRUPT_IRQ_REGS I915_IRQ_REGS(PICAINTERRUPT_IMR, \
+ PICAINTERRUPT_IER, \
+ PICAINTERRUPT_IIR)
+
#define XELPDP_PORT_HOTPLUG_CTL(hpd_pin) _MMIO(0x16F270 + (_HPD_PIN_TC(hpd_pin) * 0x200))
#define XELPDP_TBT_HOTPLUG_ENABLE REG_BIT(6)
#define XELPDP_TBT_HPD_LONG_DETECT REG_BIT(5)
@@ -3015,6 +3049,10 @@
#define SDEIIR _MMIO(0xc4008)
#define SDEIER _MMIO(0xc400c)
+#define SDE_IRQ_REGS I915_IRQ_REGS(SDEIMR, \
+ SDEIER, \
+ SDEIIR)
+
#define SERR_INT _MMIO(0xc4040)
#define SERR_INT_POISON (1 << 31)
#define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1 << ((pipe) * 3))
@@ -3098,11 +3136,12 @@
#define PCH_DPLL(pll) _MMIO((pll) == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
#define _PCH_FPA0 0xc6040
+#define _PCH_FPB0 0xc6048
+#define PCH_FP0(pll) _MMIO((pll) == 0 ? _PCH_FPA0 : _PCH_FPB0)
#define FP_CB_TUNE (0x3 << 22)
+
#define _PCH_FPA1 0xc6044
-#define _PCH_FPB0 0xc6048
#define _PCH_FPB1 0xc604c
-#define PCH_FP0(pll) _MMIO((pll) == 0 ? _PCH_FPA0 : _PCH_FPB0)
#define PCH_FP1(pll) _MMIO((pll) == 0 ? _PCH_FPA1 : _PCH_FPB1)
#define PCH_DPLL_TEST _MMIO(0xc606c)
@@ -3155,50 +3194,93 @@
/* transcoder */
#define _PCH_TRANS_HTOTAL_A 0xe0000
+#define _PCH_TRANS_HTOTAL_B 0xe1000
+#define PCH_TRANS_HTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B)
#define TRANS_HTOTAL_SHIFT 16
#define TRANS_HACTIVE_SHIFT 0
+
#define _PCH_TRANS_HBLANK_A 0xe0004
+#define _PCH_TRANS_HBLANK_B 0xe1004
+#define PCH_TRANS_HBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B)
#define TRANS_HBLANK_END_SHIFT 16
#define TRANS_HBLANK_START_SHIFT 0
+
#define _PCH_TRANS_HSYNC_A 0xe0008
+#define _PCH_TRANS_HSYNC_B 0xe1008
+#define PCH_TRANS_HSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B)
#define TRANS_HSYNC_END_SHIFT 16
#define TRANS_HSYNC_START_SHIFT 0
+
#define _PCH_TRANS_VTOTAL_A 0xe000c
+#define _PCH_TRANS_VTOTAL_B 0xe100c
+#define PCH_TRANS_VTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B)
#define TRANS_VTOTAL_SHIFT 16
#define TRANS_VACTIVE_SHIFT 0
+
#define _PCH_TRANS_VBLANK_A 0xe0010
+#define _PCH_TRANS_VBLANK_B 0xe1010
+#define PCH_TRANS_VBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B)
#define TRANS_VBLANK_END_SHIFT 16
#define TRANS_VBLANK_START_SHIFT 0
+
#define _PCH_TRANS_VSYNC_A 0xe0014
+#define _PCH_TRANS_VSYNC_B 0xe1014
+#define PCH_TRANS_VSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B)
#define TRANS_VSYNC_END_SHIFT 16
#define TRANS_VSYNC_START_SHIFT 0
+
#define _PCH_TRANS_VSYNCSHIFT_A 0xe0028
+#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028
+#define PCH_TRANS_VSYNCSHIFT(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, _PCH_TRANS_VSYNCSHIFT_B)
#define _PCH_TRANSA_DATA_M1 0xe0030
+#define _PCH_TRANSB_DATA_M1 0xe1030
+#define PCH_TRANS_DATA_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1)
+
#define _PCH_TRANSA_DATA_N1 0xe0034
+#define _PCH_TRANSB_DATA_N1 0xe1034
+#define PCH_TRANS_DATA_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1)
+
#define _PCH_TRANSA_DATA_M2 0xe0038
+#define _PCH_TRANSB_DATA_M2 0xe1038
+#define PCH_TRANS_DATA_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2)
+
#define _PCH_TRANSA_DATA_N2 0xe003c
+#define _PCH_TRANSB_DATA_N2 0xe103c
+#define PCH_TRANS_DATA_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2)
+
#define _PCH_TRANSA_LINK_M1 0xe0040
+#define _PCH_TRANSB_LINK_M1 0xe1040
+#define PCH_TRANS_LINK_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1)
+
#define _PCH_TRANSA_LINK_N1 0xe0044
+#define _PCH_TRANSB_LINK_N1 0xe1044
+#define PCH_TRANS_LINK_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1)
+
#define _PCH_TRANSA_LINK_M2 0xe0048
+#define _PCH_TRANSB_LINK_M2 0xe1048
+#define PCH_TRANS_LINK_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2)
+
#define _PCH_TRANSA_LINK_N2 0xe004c
+#define _PCH_TRANSB_LINK_N2 0xe104c
+#define PCH_TRANS_LINK_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2)
/* Per-transcoder DIP controls (PCH) */
#define _VIDEO_DIP_CTL_A 0xe0200
+#define _VIDEO_DIP_CTL_B 0xe1200
+#define TVIDEO_DIP_CTL(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B)
+
#define _VIDEO_DIP_DATA_A 0xe0208
+#define _VIDEO_DIP_DATA_B 0xe1208
+#define TVIDEO_DIP_DATA(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B)
+
#define _VIDEO_DIP_GCP_A 0xe0210
+#define _VIDEO_DIP_GCP_B 0xe1210
+#define TVIDEO_DIP_GCP(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B)
#define GCP_COLOR_INDICATION (1 << 2)
#define GCP_DEFAULT_PHASE_ENABLE (1 << 1)
#define GCP_AV_MUTE (1 << 0)
-#define _VIDEO_DIP_CTL_B 0xe1200
-#define _VIDEO_DIP_DATA_B 0xe1208
-#define _VIDEO_DIP_GCP_B 0xe1210
-
-#define TVIDEO_DIP_CTL(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B)
-#define TVIDEO_DIP_DATA(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B)
-#define TVIDEO_DIP_GCP(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B)
-
/* Per-transcoder DIP controls (VLV) */
#define _VLV_VIDEO_DIP_CTL_A 0x60200
#define _VLV_VIDEO_DIP_CTL_B 0x61170
@@ -3225,36 +3307,54 @@
_CHV_VIDEO_DIP_GDCP_PAYLOAD_C)
/* Haswell DIP controls */
-
#define _HSW_VIDEO_DIP_CTL_A 0x60200
-#define _HSW_VIDEO_DIP_AVI_DATA_A 0x60220
-#define _HSW_VIDEO_DIP_VS_DATA_A 0x60260
-#define _HSW_VIDEO_DIP_SPD_DATA_A 0x602A0
-#define _HSW_VIDEO_DIP_GMP_DATA_A 0x602E0
-#define _HSW_VIDEO_DIP_VSC_DATA_A 0x60320
-#define _ADL_VIDEO_DIP_AS_DATA_A 0x60484
-#define _GLK_VIDEO_DIP_DRM_DATA_A 0x60440
-#define _HSW_VIDEO_DIP_AVI_ECC_A 0x60240
-#define _HSW_VIDEO_DIP_VS_ECC_A 0x60280
-#define _HSW_VIDEO_DIP_SPD_ECC_A 0x602C0
-#define _HSW_VIDEO_DIP_GMP_ECC_A 0x60300
-#define _HSW_VIDEO_DIP_VSC_ECC_A 0x60344
-#define _HSW_VIDEO_DIP_GCP_A 0x60210
-
#define _HSW_VIDEO_DIP_CTL_B 0x61200
+#define HSW_TVIDEO_DIP_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_CTL_A)
+
+#define _HSW_VIDEO_DIP_AVI_DATA_A 0x60220
#define _HSW_VIDEO_DIP_AVI_DATA_B 0x61220
+#define HSW_TVIDEO_DIP_AVI_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4)
+
+#define _HSW_VIDEO_DIP_VS_DATA_A 0x60260
#define _HSW_VIDEO_DIP_VS_DATA_B 0x61260
+#define HSW_TVIDEO_DIP_VS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4)
+
+#define _HSW_VIDEO_DIP_SPD_DATA_A 0x602A0
#define _HSW_VIDEO_DIP_SPD_DATA_B 0x612A0
+#define HSW_TVIDEO_DIP_SPD_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4)
+
+#define _HSW_VIDEO_DIP_GMP_DATA_A 0x602E0
#define _HSW_VIDEO_DIP_GMP_DATA_B 0x612E0
+#define HSW_TVIDEO_DIP_GMP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4)
+
+#define _HSW_VIDEO_DIP_VSC_DATA_A 0x60320
#define _HSW_VIDEO_DIP_VSC_DATA_B 0x61320
+#define HSW_TVIDEO_DIP_VSC_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4)
+
+/*ADLP and later: */
+#define _ADL_VIDEO_DIP_AS_DATA_A 0x60484
#define _ADL_VIDEO_DIP_AS_DATA_B 0x61484
+#define ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans,\
+ _ADL_VIDEO_DIP_AS_DATA_A + (i) * 4)
+
+#define _GLK_VIDEO_DIP_DRM_DATA_A 0x60440
#define _GLK_VIDEO_DIP_DRM_DATA_B 0x61440
+#define GLK_TVIDEO_DIP_DRM_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4)
+
+#define _HSW_VIDEO_DIP_AVI_ECC_A 0x60240
#define _HSW_VIDEO_DIP_BVI_ECC_B 0x61240
+#define _HSW_VIDEO_DIP_VS_ECC_A 0x60280
#define _HSW_VIDEO_DIP_VS_ECC_B 0x61280
+#define _HSW_VIDEO_DIP_SPD_ECC_A 0x602C0
#define _HSW_VIDEO_DIP_SPD_ECC_B 0x612C0
+#define _HSW_VIDEO_DIP_GMP_ECC_A 0x60300
#define _HSW_VIDEO_DIP_GMP_ECC_B 0x61300
+#define _HSW_VIDEO_DIP_VSC_ECC_A 0x60344
#define _HSW_VIDEO_DIP_VSC_ECC_B 0x61344
+
+#define _HSW_VIDEO_DIP_GCP_A 0x60210
#define _HSW_VIDEO_DIP_GCP_B 0x61210
+#define HSW_TVIDEO_DIP_GCP(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GCP_A)
/* Icelake PPS_DATA and _ECC DIP Registers.
* These are available for transcoders B,C and eDP.
@@ -3264,62 +3364,16 @@
#define _ICL_VIDEO_DIP_PPS_DATA_A 0x60350
#define _ICL_VIDEO_DIP_PPS_DATA_B 0x61350
+#define ICL_VIDEO_DIP_PPS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4)
+
#define _ICL_VIDEO_DIP_PPS_ECC_A 0x603D4
#define _ICL_VIDEO_DIP_PPS_ECC_B 0x613D4
-
-#define HSW_TVIDEO_DIP_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_CTL_A)
-#define HSW_TVIDEO_DIP_GCP(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GCP_A)
-#define HSW_TVIDEO_DIP_AVI_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_VS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_SPD_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_GMP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_VSC_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4)
-#define GLK_TVIDEO_DIP_DRM_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4)
-#define ICL_VIDEO_DIP_PPS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4)
#define ICL_VIDEO_DIP_PPS_ECC(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_ECC_A + (i) * 4)
-/*ADLP and later: */
-#define ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans,\
- _ADL_VIDEO_DIP_AS_DATA_A + (i) * 4)
#define _HSW_STEREO_3D_CTL_A 0x70020
-#define S3D_ENABLE (1 << 31)
#define _HSW_STEREO_3D_CTL_B 0x71020
-
#define HSW_STEREO_3D_CTL(dev_priv, trans) _MMIO_PIPE2(dev_priv, trans, _HSW_STEREO_3D_CTL_A)
-
-#define _PCH_TRANS_HTOTAL_B 0xe1000
-#define _PCH_TRANS_HBLANK_B 0xe1004
-#define _PCH_TRANS_HSYNC_B 0xe1008
-#define _PCH_TRANS_VTOTAL_B 0xe100c
-#define _PCH_TRANS_VBLANK_B 0xe1010
-#define _PCH_TRANS_VSYNC_B 0xe1014
-#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028
-
-#define PCH_TRANS_HTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B)
-#define PCH_TRANS_HBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B)
-#define PCH_TRANS_HSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B)
-#define PCH_TRANS_VTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B)
-#define PCH_TRANS_VBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B)
-#define PCH_TRANS_VSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B)
-#define PCH_TRANS_VSYNCSHIFT(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, _PCH_TRANS_VSYNCSHIFT_B)
-
-#define _PCH_TRANSB_DATA_M1 0xe1030
-#define _PCH_TRANSB_DATA_N1 0xe1034
-#define _PCH_TRANSB_DATA_M2 0xe1038
-#define _PCH_TRANSB_DATA_N2 0xe103c
-#define _PCH_TRANSB_LINK_M1 0xe1040
-#define _PCH_TRANSB_LINK_N1 0xe1044
-#define _PCH_TRANSB_LINK_M2 0xe1048
-#define _PCH_TRANSB_LINK_N2 0xe104c
-
-#define PCH_TRANS_DATA_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1)
-#define PCH_TRANS_DATA_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1)
-#define PCH_TRANS_DATA_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2)
-#define PCH_TRANS_DATA_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2)
-#define PCH_TRANS_LINK_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1)
-#define PCH_TRANS_LINK_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1)
-#define PCH_TRANS_LINK_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2)
-#define PCH_TRANS_LINK_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2)
+#define S3D_ENABLE (1 << 31)
#define _PCH_TRANSACONF 0xf0008
#define _PCH_TRANSBCONF 0xf1008
@@ -4125,6 +4179,7 @@ enum skl_power_gate {
#define _DPLL1_CFGCR1 0x6C040
#define _DPLL2_CFGCR1 0x6C048
#define _DPLL3_CFGCR1 0x6C050
+#define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1)
#define DPLL_CFGCR1_FREQ_ENABLE (1 << 31)
#define DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff << 9)
#define DPLL_CFGCR1_DCO_FRACTION(x) ((x) << 9)
@@ -4133,6 +4188,7 @@ enum skl_power_gate {
#define _DPLL1_CFGCR2 0x6C044
#define _DPLL2_CFGCR2 0x6C04C
#define _DPLL3_CFGCR2 0x6C054
+#define DPLL_CFGCR2(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2)
#define DPLL_CFGCR2_QDIV_RATIO_MASK (0xff << 8)
#define DPLL_CFGCR2_QDIV_RATIO(x) ((x) << 8)
#define DPLL_CFGCR2_QDIV_MODE(x) ((x) << 7)
@@ -4151,9 +4207,6 @@ enum skl_power_gate {
#define DPLL_CFGCR2_PDIV_7_INVALID (5 << 2)
#define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3)
-#define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1)
-#define DPLL_CFGCR2(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2)
-
/* ICL Clocks */
#define ICL_DPCLKA_CFGCR0 _MMIO(0x164280)
#define ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy) (1 << _PICK(phy, 10, 11, 24, 4, 5))
@@ -4246,7 +4299,6 @@ enum skl_power_gate {
/* ADL-P Type C PLL */
#define PORTTC1_PLL_ENABLE 0x46038
#define PORTTC2_PLL_ENABLE 0x46040
-
#define ADLP_PORTTC_PLL_ENABLE(tc_port) _MMIO_PORT((tc_port), \
PORTTC1_PLL_ENABLE, \
PORTTC2_PLL_ENABLE)
diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h
index a685db1e815d..e251bcc0c89f 100644
--- a/drivers/gpu/drm/i915/i915_reg_defs.h
+++ b/drivers/gpu/drm/i915/i915_reg_defs.h
@@ -284,4 +284,14 @@ typedef struct {
#define i915_mmio_reg_equal(a, b) (i915_mmio_reg_offset(a) == i915_mmio_reg_offset(b))
#define i915_mmio_reg_valid(r) (!i915_mmio_reg_equal(r, INVALID_MMIO_REG))
+/* A triplet for IMR/IER/IIR registers. */
+struct i915_irq_regs {
+ i915_reg_t imr;
+ i915_reg_t ier;
+ i915_reg_t iir;
+};
+
+#define I915_IRQ_REGS(_imr, _ier, _iir) \
+ ((const struct i915_irq_regs){ .imr = (_imr), .ier = (_ier), .iir = (_iir) })
+
#endif /* __I915_REG_DEFS__ */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index f8373a461f17..9d3d9b983032 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -118,6 +118,7 @@ void i915_save_display(struct drm_i915_private *dev_priv)
void i915_restore_display(struct drm_i915_private *dev_priv)
{
+ struct intel_display *display = &dev_priv->display;
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
if (!HAS_DISPLAY(dev_priv))
@@ -134,7 +135,7 @@ void i915_restore_display(struct drm_i915_private *dev_priv)
intel_de_write(dev_priv, DSPARB(dev_priv),
dev_priv->regfile.saveDSPARB);
- intel_vga_redisable(dev_priv);
+ intel_vga_redisable(display);
intel_gmbus_reset(dev_priv);
}
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index ce1cbee1b39d..09d89bdf82f4 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -322,7 +322,7 @@ DEFINE_EVENT(i915_request, i915_request_add,
TP_ARGS(rq)
);
-#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS)
+#if IS_ENABLED(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS)
DEFINE_EVENT(i915_request, i915_request_guc_submit,
TP_PROTO(struct i915_request *rq),
TP_ARGS(rq)
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 71bdc89bd621..609214231ffc 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -270,7 +270,7 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
#define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000)
/* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */
-#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT)
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG) && IS_ENABLED(CONFIG_PREEMPT_COUNT)
# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic())
#else
# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0)
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index d2f064d2525c..776f8cc51b2f 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -2157,7 +2157,7 @@ static struct dma_fence *__i915_vma_unbind_async(struct i915_vma *vma)
int i915_vma_unbind(struct i915_vma *vma)
{
struct i915_address_space *vm = vma->vm;
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
int err;
assert_object_held_shared(vma->obj);
@@ -2196,7 +2196,7 @@ int i915_vma_unbind_async(struct i915_vma *vma, bool trylock_vm)
{
struct drm_i915_gem_object *obj = vma->obj;
struct i915_address_space *vm = vma->vm;
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
struct dma_fence *fence;
int err;
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 643ff1bf74ee..4f4aa4ff9963 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -138,7 +138,6 @@ enum intel_ppgtt_type {
#define DEV_INFO_FOR_EACH_FLAG(func) \
func(is_mobile); \
- func(is_lp); \
func(require_force_probe); \
func(is_dgfx); \
/* Keep has_* in alphabetical order */ \
diff --git a/drivers/gpu/drm/i915/intel_mchbar_regs.h b/drivers/gpu/drm/i915/intel_mchbar_regs.h
index 73900c098d59..dc2477179c3e 100644
--- a/drivers/gpu/drm/i915/intel_mchbar_regs.h
+++ b/drivers/gpu/drm/i915/intel_mchbar_regs.h
@@ -207,6 +207,10 @@
#define PCU_PACKAGE_ENERGY_STATUS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x593c)
#define GEN6_GT_PERF_STATUS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5948)
+
+#define PCU_PACKAGE_TEMPERATURE _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5978)
+#define TEMP_MASK REG_GENMASK(7, 0)
+
#define GEN6_RP_STATE_LIMITS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5994)
#define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998)
#define RP0_CAP_MASK REG_GENMASK(7, 0)
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 2d0647aca964..1a47ecfd3fd8 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -66,7 +66,7 @@ static intel_wakeref_t
track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
{
if (!rpm->available || rpm->no_wakeref_tracking)
- return -1;
+ return INTEL_WAKEREF_DEF;
return intel_ref_tracker_alloc(&rpm->debug);
}
@@ -114,7 +114,7 @@ static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
static intel_wakeref_t
track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
{
- return -1;
+ return INTEL_WAKEREF_DEF;
}
static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm,
@@ -250,7 +250,7 @@ static intel_wakeref_t __intel_runtime_pm_get_if_active(struct intel_runtime_pm
pm_runtime_get_if_active(rpm->kdev) <= 0) ||
(!ignore_usecount &&
pm_runtime_get_if_in_use(rpm->kdev) <= 0))
- return 0;
+ return NULL;
}
intel_runtime_pm_acquire(rpm, true);
@@ -336,7 +336,7 @@ intel_runtime_pm_put_raw(struct intel_runtime_pm *rpm, intel_wakeref_t wref)
*/
void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm)
{
- __intel_runtime_pm_put(rpm, -1, true);
+ __intel_runtime_pm_put(rpm, INTEL_WAKEREF_DEF, true);
}
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h
index de3579d399e1..e22669d61e95 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.h
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.h
@@ -42,7 +42,6 @@ struct intel_runtime_pm {
atomic_t wakeref_count;
struct device *kdev; /* points to i915->drm.dev */
bool available;
- bool irqs_enabled;
bool no_wakeref_tracking;
/*
@@ -97,10 +96,16 @@ intel_rpm_wakelock_count(int wakeref_count)
return wakeref_count >> INTEL_RPM_WAKELOCK_SHIFT;
}
+static inline bool
+intel_runtime_pm_suspended(struct intel_runtime_pm *rpm)
+{
+ return pm_runtime_suspended(rpm->kdev);
+}
+
static inline void
assert_rpm_device_not_suspended(struct intel_runtime_pm *rpm)
{
- WARN_ONCE(pm_runtime_suspended(rpm->kdev),
+ WARN_ONCE(intel_runtime_pm_suspended(rpm),
"Device suspended during HW access\n");
}
@@ -189,15 +194,15 @@ intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm);
#define with_intel_runtime_pm(rpm, wf) \
for ((wf) = intel_runtime_pm_get(rpm); (wf); \
- intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
+ intel_runtime_pm_put((rpm), (wf)), (wf) = NULL)
#define with_intel_runtime_pm_if_in_use(rpm, wf) \
for ((wf) = intel_runtime_pm_get_if_in_use(rpm); (wf); \
- intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
+ intel_runtime_pm_put((rpm), (wf)), (wf) = NULL)
#define with_intel_runtime_pm_if_active(rpm, wf) \
for ((wf) = intel_runtime_pm_get_if_active(rpm); (wf); \
- intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
+ intel_runtime_pm_put((rpm), (wf)), (wf) = NULL)
void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm);
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index dea2f63184f8..87f246047312 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -27,11 +27,11 @@ int __intel_wakeref_get_first(struct intel_wakeref *wf)
if (!atomic_read(&wf->count)) {
INTEL_WAKEREF_BUG_ON(wf->wakeref);
wf->wakeref = wakeref;
- wakeref = 0;
+ wakeref = NULL;
ret = wf->ops->get(wf);
if (ret) {
- wakeref = xchg(&wf->wakeref, 0);
+ wakeref = xchg(&wf->wakeref, NULL);
wake_up_var(&wf->wakeref);
goto unlock;
}
@@ -52,7 +52,7 @@ unlock:
static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
{
- intel_wakeref_t wakeref = 0;
+ intel_wakeref_t wakeref = NULL;
INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
if (unlikely(!atomic_dec_and_test(&wf->count)))
@@ -61,7 +61,7 @@ static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
/* ops->put() must reschedule its own release on error/deferral */
if (likely(!wf->ops->put(wf))) {
INTEL_WAKEREF_BUG_ON(!wf->wakeref);
- wakeref = xchg(&wf->wakeref, 0);
+ wakeref = xchg(&wf->wakeref, NULL);
wake_up_var(&wf->wakeref);
}
@@ -107,7 +107,7 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
__mutex_init(&wf->mutex, "wakeref.mutex", &key->mutex);
atomic_set(&wf->count, 0);
- wf->wakeref = 0;
+ wf->wakeref = NULL;
INIT_DELAYED_WORK(&wf->work, __intel_wakeref_put_work);
lockdep_init_map(&wf->work.work.lockdep_map,
@@ -142,7 +142,7 @@ static void wakeref_auto_timeout(struct timer_list *t)
if (!refcount_dec_and_lock_irqsave(&wf->count, &wf->lock, &flags))
return;
- wakeref = fetch_and_zero(&wf->wakeref);
+ wakeref = xchg(&wf->wakeref, NULL);
spin_unlock_irqrestore(&wf->lock, flags);
intel_runtime_pm_put(&wf->i915->runtime_pm, wakeref);
@@ -154,7 +154,7 @@ void intel_wakeref_auto_init(struct intel_wakeref_auto *wf,
spin_lock_init(&wf->lock);
timer_setup(&wf->timer, wakeref_auto_timeout, 0);
refcount_set(&wf->count, 0);
- wf->wakeref = 0;
+ wf->wakeref = NULL;
wf->i915 = i915;
}
diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h
index 68aa3be48251..48836ef52d40 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.h
+++ b/drivers/gpu/drm/i915/intel_wakeref.h
@@ -21,7 +21,7 @@
#include <linux/timer.h>
#include <linux/workqueue.h>
-typedef unsigned long intel_wakeref_t;
+typedef struct ref_tracker *intel_wakeref_t;
#define INTEL_REFTRACK_DEAD_COUNT 16
#define INTEL_REFTRACK_PRINT_LIMIT 16
@@ -273,7 +273,7 @@ __intel_wakeref_defer_park(struct intel_wakeref *wf)
*/
int intel_wakeref_wait_for_idle(struct intel_wakeref *wf);
-#define INTEL_WAKEREF_DEF ((intel_wakeref_t)(-1))
+#define INTEL_WAKEREF_DEF ERR_PTR(-ENOENT)
static inline intel_wakeref_t intel_ref_tracker_alloc(struct ref_tracker_dir *dir)
{
@@ -281,17 +281,19 @@ static inline intel_wakeref_t intel_ref_tracker_alloc(struct ref_tracker_dir *di
ref_tracker_alloc(dir, &user, GFP_NOWAIT);
- return (intel_wakeref_t)user ?: INTEL_WAKEREF_DEF;
+ return user ?: INTEL_WAKEREF_DEF;
}
static inline void intel_ref_tracker_free(struct ref_tracker_dir *dir,
- intel_wakeref_t handle)
+ intel_wakeref_t wakeref)
{
- struct ref_tracker *user;
+ if (wakeref == INTEL_WAKEREF_DEF)
+ wakeref = NULL;
- user = (handle == INTEL_WAKEREF_DEF) ? NULL : (void *)handle;
+ if (WARN_ON(IS_ERR(wakeref)))
+ return;
- ref_tracker_free(dir, &user);
+ ref_tracker_free(dir, &wakeref);
}
void intel_ref_tracker_show(struct ref_tracker_dir *dir,
@@ -314,7 +316,7 @@ static inline void intel_wakeref_untrack(struct intel_wakeref *wf,
static inline intel_wakeref_t intel_wakeref_track(struct intel_wakeref *wf)
{
- return -1;
+ return INTEL_WAKEREF_DEF;
}
static inline void intel_wakeref_untrack(struct intel_wakeref *wf,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 75278e78ca90..da3577149769 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -461,9 +461,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
}
int intel_pxp_key_check(struct intel_pxp *pxp,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *_obj,
bool assign)
{
+ struct drm_i915_gem_object *obj = to_intel_bo(_obj);
+
if (!intel_pxp_is_active(pxp))
return -ENODEV;
@@ -529,7 +531,7 @@ void intel_pxp_invalidate(struct intel_pxp *pxp)
if (ctx->pxp_wakeref) {
intel_runtime_pm_put(&i915->runtime_pm,
ctx->pxp_wakeref);
- ctx->pxp_wakeref = 0;
+ ctx->pxp_wakeref = NULL;
}
spin_lock_irq(&i915->gem.contexts.lock);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index d9372f6f7797..4ed97db5e7c6 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -9,7 +9,7 @@
#include <linux/errno.h>
#include <linux/types.h>
-struct drm_i915_gem_object;
+struct drm_gem_object;
struct drm_i915_private;
struct intel_pxp;
@@ -32,7 +32,7 @@ int intel_pxp_start(struct intel_pxp *pxp);
void intel_pxp_end(struct intel_pxp *pxp);
int intel_pxp_key_check(struct intel_pxp *pxp,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *obj,
bool assign);
void intel_pxp_invalidate(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 91794ca17a58..ae57eb03dfca 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -137,7 +137,7 @@ static const struct intel_device_info mock_info = {
struct drm_i915_private *mock_gem_device(void)
{
-#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
+#if IS_ENABLED(CONFIG_IOMMU_API) && IS_ENABLED(CONFIG_INTEL_IOMMU)
static struct dev_iommu fake_iommu = { .priv = (void *)-1 };
#endif
struct drm_i915_private *i915;
@@ -153,7 +153,7 @@ struct drm_i915_private *mock_gem_device(void)
dev_set_name(&pdev->dev, "mock");
dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
-#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
+#if IS_ENABLED(CONFIG_IOMMU_API) && IS_ENABLED(CONFIG_INTEL_IOMMU)
/* HACK to disable iommu for the fake device; force identity mapping */
pdev->dev.iommu = &fake_iommu;
#endif
@@ -203,7 +203,7 @@ struct drm_i915_private *mock_gem_device(void)
intel_root_gt_init_early(i915);
mock_uncore_init(&i915->uncore, i915);
atomic_inc(&to_gt(i915)->wakeref.count); /* disable; no hw support */
- to_gt(i915)->awake = -ENODEV;
+ to_gt(i915)->awake = INTEL_WAKEREF_MOCK_GT;
mock_gt_probe(i915);
ret = intel_region_ttm_device_init(i915);
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
index 4aba47bccc63..9e310f4099f4 100644
--- a/drivers/gpu/drm/i915/soc/intel_dram.c
+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
@@ -714,7 +714,7 @@ void intel_dram_detect(struct drm_i915_private *i915)
* Assume level 0 watermark latency adjustment is needed until proven
* otherwise, this w/a is not needed by bxt/glk.
*/
- dram_info->wm_lv_0_adjust_needed = !IS_GEN9_LP(i915);
+ dram_info->wm_lv_0_adjust_needed = !IS_BROXTON(i915) && !IS_GEMINILAKE(i915);
if (DISPLAY_VER(i915) >= 14)
ret = xelpdp_get_dram_info(i915);
@@ -722,7 +722,7 @@ void intel_dram_detect(struct drm_i915_private *i915)
ret = gen12_get_dram_info(i915);
else if (GRAPHICS_VER(i915) >= 11)
ret = gen11_get_dram_info(i915);
- else if (IS_GEN9_LP(i915))
+ else if (IS_BROXTON(i915) || IS_GEMINILAKE(i915))
ret = bxt_get_dram_info(i915);
else
ret = skl_get_dram_info(i915);
diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c
index 542eea50093c..842db43e46c0 100644
--- a/drivers/gpu/drm/i915/soc/intel_pch.c
+++ b/drivers/gpu/drm/i915/soc/intel_pch.c
@@ -124,7 +124,10 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
drm_dbg_kms(&dev_priv->drm, "Found Tiger Lake LP PCH\n");
drm_WARN_ON(&dev_priv->drm, !IS_TIGERLAKE(dev_priv) &&
!IS_ROCKETLAKE(dev_priv) &&
- !IS_GEN9_BC(dev_priv));
+ !IS_SKYLAKE(dev_priv) &&
+ !IS_KABYLAKE(dev_priv) &&
+ !IS_COFFEELAKE(dev_priv) &&
+ !IS_COMETLAKE(dev_priv));
return PCH_TGP;
case INTEL_PCH_JSP_DEVICE_ID_TYPE:
drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n");
diff --git a/drivers/gpu/drm/i915/soc/intel_rom.c b/drivers/gpu/drm/i915/soc/intel_rom.c
new file mode 100644
index 000000000000..243d98cab8c3
--- /dev/null
+++ b/drivers/gpu/drm/i915/soc/intel_rom.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "i915_reg.h"
+
+#include "intel_rom.h"
+#include "intel_uncore.h"
+
+struct intel_rom {
+ /* for PCI ROM */
+ struct pci_dev *pdev;
+ void __iomem *oprom;
+
+ /* for SPI */
+ struct intel_uncore *uncore;
+ loff_t offset;
+
+ size_t size;
+
+ u32 (*read32)(struct intel_rom *rom, loff_t offset);
+ u16 (*read16)(struct intel_rom *rom, loff_t offset);
+ void (*read_block)(struct intel_rom *rom, void *data, loff_t offset, size_t size);
+ void (*free)(struct intel_rom *rom);
+};
+
+static u32 spi_read32(struct intel_rom *rom, loff_t offset)
+{
+ intel_uncore_write(rom->uncore, PRIMARY_SPI_ADDRESS,
+ rom->offset + offset);
+
+ return intel_uncore_read(rom->uncore, PRIMARY_SPI_TRIGGER);
+}
+
+static u16 spi_read16(struct intel_rom *rom, loff_t offset)
+{
+ return spi_read32(rom, offset) & 0xffff;
+}
+
+struct intel_rom *intel_rom_spi(struct drm_i915_private *i915)
+{
+ struct intel_rom *rom;
+ u32 static_region;
+
+ rom = kzalloc(sizeof(*rom), GFP_KERNEL);
+ if (!rom)
+ return NULL;
+
+ rom->uncore = &i915->uncore;
+
+ static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS);
+ static_region &= OPTIONROM_SPI_REGIONID_MASK;
+ intel_uncore_write(rom->uncore, PRIMARY_SPI_REGIONID, static_region);
+
+ rom->offset = intel_uncore_read(rom->uncore, OROM_OFFSET) & OROM_OFFSET_MASK;
+
+ rom->size = 0x200000;
+
+ rom->read32 = spi_read32;
+ rom->read16 = spi_read16;
+
+ return rom;
+}
+
+static u32 pci_read32(struct intel_rom *rom, loff_t offset)
+{
+ return ioread32(rom->oprom + offset);
+}
+
+static u16 pci_read16(struct intel_rom *rom, loff_t offset)
+{
+ return ioread16(rom->oprom + offset);
+}
+
+static void pci_read_block(struct intel_rom *rom, void *data,
+ loff_t offset, size_t size)
+{
+ memcpy_fromio(data, rom->oprom + offset, size);
+}
+
+static void pci_free(struct intel_rom *rom)
+{
+ pci_unmap_rom(rom->pdev, rom->oprom);
+}
+
+struct intel_rom *intel_rom_pci(struct drm_i915_private *i915)
+{
+ struct intel_rom *rom;
+
+ rom = kzalloc(sizeof(*rom), GFP_KERNEL);
+ if (!rom)
+ return NULL;
+
+ rom->pdev = to_pci_dev(i915->drm.dev);
+
+ rom->oprom = pci_map_rom(rom->pdev, &rom->size);
+ if (!rom->oprom) {
+ kfree(rom);
+ return NULL;
+ }
+
+ rom->read32 = pci_read32;
+ rom->read16 = pci_read16;
+ rom->read_block = pci_read_block;
+ rom->free = pci_free;
+
+ return rom;
+}
+
+u32 intel_rom_read32(struct intel_rom *rom, loff_t offset)
+{
+ return rom->read32(rom, offset);
+}
+
+u16 intel_rom_read16(struct intel_rom *rom, loff_t offset)
+{
+ return rom->read16(rom, offset);
+}
+
+void intel_rom_read_block(struct intel_rom *rom, void *data,
+ loff_t offset, size_t size)
+{
+ u32 *ptr = data;
+ loff_t index;
+
+ if (rom->read_block) {
+ rom->read_block(rom, data, offset, size);
+ return;
+ }
+
+ for (index = 0; index < size; index += 4)
+ *ptr++ = rom->read32(rom, offset + index);
+}
+
+loff_t intel_rom_find(struct intel_rom *rom, u32 needle)
+{
+ loff_t offset;
+
+ for (offset = 0; offset < rom->size; offset += 4) {
+ if (rom->read32(rom, offset) == needle)
+ return offset;
+ }
+
+ return -ENOENT;
+}
+
+size_t intel_rom_size(struct intel_rom *rom)
+{
+ return rom->size;
+}
+
+void intel_rom_free(struct intel_rom *rom)
+{
+ if (rom && rom->free)
+ rom->free(rom);
+
+ kfree(rom);
+}
diff --git a/drivers/gpu/drm/i915/soc/intel_rom.h b/drivers/gpu/drm/i915/soc/intel_rom.h
new file mode 100644
index 000000000000..fb2979c8ef7f
--- /dev/null
+++ b/drivers/gpu/drm/i915/soc/intel_rom.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_ROM_H__
+#define __INTEL_ROM_H__
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_rom;
+
+struct intel_rom *intel_rom_spi(struct drm_i915_private *i915);
+struct intel_rom *intel_rom_pci(struct drm_i915_private *i915);
+
+u32 intel_rom_read32(struct intel_rom *rom, loff_t offset);
+u16 intel_rom_read16(struct intel_rom *rom, loff_t offset);
+void intel_rom_read_block(struct intel_rom *rom, void *data,
+ loff_t offset, size_t size);
+loff_t intel_rom_find(struct intel_rom *rom, u32 needle);
+size_t intel_rom_size(struct intel_rom *rom);
+void intel_rom_free(struct intel_rom *rom);
+
+#endif /* __INTEL_ROM_H__ */
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index cb6c625bdef0..da80c29aa363 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -150,7 +150,6 @@ subdir-ccflags-$(CONFIG_DRM_XE_DISPLAY) += \
-I$(src)/display/ext \
-I$(src)/compat-i915-headers \
-I$(srctree)/drivers/gpu/drm/i915/display/ \
- -Ddrm_i915_gem_object=xe_bo \
-Ddrm_i915_private=xe_device
# Rule to build SOC code shared with i915
@@ -167,6 +166,7 @@ $(obj)/i915-display/%.o: $(srctree)/drivers/gpu/drm/i915/display/%.c FORCE
xe-$(CONFIG_DRM_XE_DISPLAY) += \
display/ext/i915_irq.o \
display/ext/i915_utils.o \
+ display/intel_bo.o \
display/intel_fb_bo.o \
display/intel_fbdev_fb.o \
display/xe_display.o \
@@ -182,7 +182,8 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
# SOC code shared with i915
xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-soc/intel_dram.o \
- i915-soc/intel_pch.o
+ i915-soc/intel_pch.o \
+ i915-soc/intel_rom.o
# Display code shared with i915
xe-$(CONFIG_DRM_XE_DISPLAY) += \
@@ -222,6 +223,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_dp_hdcp.o \
i915-display/intel_dp_link_training.o \
i915-display/intel_dp_mst.o \
+ i915-display/intel_dp_test.o \
i915-display/intel_dpll.o \
i915-display/intel_dpll_mgr.o \
i915-display/intel_dpt_common.o \
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h
deleted file mode 100644
index 710cecca972d..000000000000
--- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h
+++ /dev/null
@@ -1 +0,0 @@
-/* Empty */
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h
deleted file mode 100644
index 650ea2803a97..000000000000
--- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _I915_GEM_MMAN_H_
-#define _I915_GEM_MMAN_H_
-
-#include "xe_bo_types.h"
-#include <drm/drm_prime.h>
-
-static inline int i915_gem_fb_mmap(struct xe_bo *bo, struct vm_area_struct *vma)
-{
- return drm_gem_prime_mmap(&bo->ttm.base, vma);
-}
-
-#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h
deleted file mode 100644
index 777c20ceabab..000000000000
--- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2022 Intel Corporation
- */
-
-#ifndef _I915_GEM_OBJECT_H_
-#define _I915_GEM_OBJECT_H_
-
-#include <linux/types.h>
-
-#include "xe_bo.h"
-
-#define i915_gem_object_is_shmem(obj) (0) /* We don't use shmem */
-
-static inline dma_addr_t i915_gem_object_get_dma_address(const struct xe_bo *bo, pgoff_t n)
-{
- /* Should never be called */
- WARN_ON(1);
- return n;
-}
-
-static inline bool i915_gem_object_is_tiled(const struct xe_bo *bo)
-{
- /* legacy tiling is unused */
- return false;
-}
-
-static inline bool i915_gem_object_is_userptr(const struct xe_bo *bo)
-{
- /* legacy tiling is unused */
- return false;
-}
-
-static inline int i915_gem_object_read_from_page(struct xe_bo *bo,
- u32 ofs, u64 *ptr, u32 size)
-{
- struct ttm_bo_kmap_obj map;
- void *src;
- bool is_iomem;
- int ret;
-
- ret = xe_bo_lock(bo, true);
- if (ret)
- return ret;
-
- ret = ttm_bo_kmap(&bo->ttm, ofs >> PAGE_SHIFT, 1, &map);
- if (ret)
- goto out_unlock;
-
- ofs &= ~PAGE_MASK;
- src = ttm_kmap_obj_virtual(&map, &is_iomem);
- src += ofs;
- if (is_iomem)
- memcpy_fromio(ptr, (void __iomem *)src, size);
- else
- memcpy(ptr, src, size);
-
- ttm_bo_kunmap(&map);
-out_unlock:
- xe_bo_unlock(bo);
- return ret;
-}
-
-#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h
deleted file mode 100644
index 2a3f12d2978c..000000000000
--- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2022 Intel Corporation
- */
-
-#ifndef _I915_GEM_OBJECT_FRONTBUFFER_H_
-#define _I915_GEM_OBJECT_FRONTBUFFER_H_
-
-#define i915_gem_object_get_frontbuffer(obj) NULL
-#define i915_gem_object_set_frontbuffer(obj, front) (front)
-
-#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h
deleted file mode 100644
index 7d6bb1abab73..000000000000
--- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/* Copyright © 2024 Intel Corporation */
-
-#ifndef __I915_GEM_OBJECT_TYPES_H__
-#define __I915_GEM_OBJECT_TYPES_H__
-
-#include "xe_bo.h"
-
-#define to_intel_bo(x) gem_to_xe_bo((x))
-
-#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h
deleted file mode 100644
index b4c47617b64b..000000000000
--- a/drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef __I915_DEBUGFS_H__
-#define __I915_DEBUGFS_H__
-
-struct drm_i915_gem_object;
-struct seq_file;
-
-static inline void i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) {}
-
-#endif /* __I915_DEBUGFS_H__ */
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
index f27a2c75b56d..b7041b578e5e 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
@@ -14,6 +14,7 @@
#include "i915_utils.h"
#include "intel_runtime_pm.h"
+#include "xe_device.h" /* for xe_device_has_flat_ccs() */
#include "xe_device_types.h"
static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
@@ -75,10 +76,6 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
#define IS_MOBILE(xe) (xe && 0)
-#define IS_LP(xe) ((xe) && 0)
-#define IS_GEN9_LP(xe) ((xe) && 0)
-#define IS_GEN9_BC(xe) ((xe) && 0)
-
#define IS_TIGERLAKE_UY(xe) (xe && 0)
#define IS_COMETLAKE_ULX(xe) (xe && 0)
#define IS_COFFEELAKE_ULX(xe) (xe && 0)
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
index 8c7b315aa8ac..274042bff1be 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
@@ -20,18 +20,26 @@ static inline void enable_rpm_wakeref_asserts(void *rpm)
{
}
+static inline bool
+intel_runtime_pm_suspended(struct xe_runtime_pm *pm)
+{
+ struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
+
+ return pm_runtime_suspended(xe->drm.dev);
+}
+
static inline intel_wakeref_t intel_runtime_pm_get(struct xe_runtime_pm *pm)
{
struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
- return xe_pm_runtime_resume_and_get(xe);
+ return xe_pm_runtime_resume_and_get(xe) ? INTEL_WAKEREF_DEF : NULL;
}
static inline intel_wakeref_t intel_runtime_pm_get_if_in_use(struct xe_runtime_pm *pm)
{
struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
- return xe_pm_runtime_get_if_in_use(xe);
+ return xe_pm_runtime_get_if_in_use(xe) ? INTEL_WAKEREF_DEF : NULL;
}
static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm *pm)
@@ -39,7 +47,8 @@ static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm
struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
xe_pm_runtime_get_noresume(xe);
- return true;
+
+ return INTEL_WAKEREF_DEF;
}
static inline void intel_runtime_pm_put_unchecked(struct xe_runtime_pm *pm)
@@ -62,6 +71,6 @@ static inline void intel_runtime_pm_put(struct xe_runtime_pm *pm, intel_wakeref_
#define with_intel_runtime_pm(rpm, wf) \
for ((wf) = intel_runtime_pm_get(rpm); (wf); \
- intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
+ intel_runtime_pm_put((rpm), (wf)), (wf) = NULL)
#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
index ee3469d4ae73..0382beb4035b 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
@@ -155,30 +155,6 @@ static inline void intel_uncore_write_notrace(struct intel_uncore *uncore,
xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val);
}
-static inline void __iomem *intel_uncore_regs(struct intel_uncore *uncore)
-{
- struct xe_device *xe = container_of(uncore, struct xe_device, uncore);
-
- return xe_device_get_root_tile(xe)->mmio.regs;
-}
-
-/*
- * The raw_reg_{read,write} macros are intended as a micro-optimization for
- * interrupt handlers so that the pointer indirection on uncore->regs can
- * be computed once (and presumably cached in a register) instead of generating
- * extra load instructions for each MMIO access.
- *
- * Given that these macros are only intended for non-GSI interrupt registers
- * (and the goal is to avoid extra instructions generated by the compiler),
- * these macros do not account for uncore->gsi_offset. Any caller that needs
- * to use these macros on a GSI register is responsible for adding the
- * appropriate GSI offset to the 'base' parameter.
- */
-#define raw_reg_read(base, reg) \
- readl(base + i915_mmio_reg_offset(reg))
-#define raw_reg_write(base, reg, value) \
- writel(value, base + i915_mmio_reg_offset(reg))
-
#define intel_uncore_forcewake_get(x, y) do { } while (0)
#define intel_uncore_forcewake_put(x, y) do { } while (0)
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h
index ecb1c0707706..2a32faea9db5 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h
@@ -5,4 +5,6 @@
#include <linux/types.h>
-typedef unsigned long intel_wakeref_t;
+typedef struct ref_tracker *intel_wakeref_t;
+
+#define INTEL_WAKEREF_DEF ERR_PTR(-ENOENT)
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
index c2c30ece8f77..5dfc587c8237 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
@@ -9,20 +9,14 @@
#include <linux/errno.h>
#include <linux/types.h>
-struct drm_i915_gem_object;
+struct drm_gem_object;
struct intel_pxp;
static inline int intel_pxp_key_check(struct intel_pxp *pxp,
- struct drm_i915_gem_object *obj,
+ struct drm_gem_object *obj,
bool assign)
{
return -ENODEV;
}
-static inline bool
-i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
-{
- return false;
-}
-
#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h b/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h
new file mode 100644
index 000000000000..05cbfb697b2b
--- /dev/null
+++ b/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include "../../../i915/soc/intel_rom.h"
diff --git a/drivers/gpu/drm/xe/display/ext/i915_irq.c b/drivers/gpu/drm/xe/display/ext/i915_irq.c
index eb40f1cb44f6..a7dbc6554d69 100644
--- a/drivers/gpu/drm/xe/display/ext/i915_irq.c
+++ b/drivers/gpu/drm/xe/display/ext/i915_irq.c
@@ -7,25 +7,24 @@
#include "i915_reg.h"
#include "intel_uncore.h"
-void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr,
- i915_reg_t iir, i915_reg_t ier)
+void gen2_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs)
{
- intel_uncore_write(uncore, imr, 0xffffffff);
- intel_uncore_posting_read(uncore, imr);
+ intel_uncore_write(uncore, regs.imr, 0xffffffff);
+ intel_uncore_posting_read(uncore, regs.imr);
- intel_uncore_write(uncore, ier, 0);
+ intel_uncore_write(uncore, regs.ier, 0);
/* IIR can theoretically queue up two events. Be paranoid. */
- intel_uncore_write(uncore, iir, 0xffffffff);
- intel_uncore_posting_read(uncore, iir);
- intel_uncore_write(uncore, iir, 0xffffffff);
- intel_uncore_posting_read(uncore, iir);
+ intel_uncore_write(uncore, regs.iir, 0xffffffff);
+ intel_uncore_posting_read(uncore, regs.iir);
+ intel_uncore_write(uncore, regs.iir, 0xffffffff);
+ intel_uncore_posting_read(uncore, regs.iir);
}
/*
* We should clear IMR at preinstall/uninstall, and just check at postinstall.
*/
-void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg)
+void gen2_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg)
{
struct xe_device *xe = container_of(uncore, struct xe_device, uncore);
u32 val = intel_uncore_read(uncore, reg);
@@ -42,16 +41,14 @@ void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg)
intel_uncore_posting_read(uncore, reg);
}
-void gen3_irq_init(struct intel_uncore *uncore,
- i915_reg_t imr, u32 imr_val,
- i915_reg_t ier, u32 ier_val,
- i915_reg_t iir)
+void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs,
+ u32 imr_val, u32 ier_val)
{
- gen3_assert_iir_is_zero(uncore, iir);
+ gen2_assert_iir_is_zero(uncore, regs.iir);
- intel_uncore_write(uncore, ier, ier_val);
- intel_uncore_write(uncore, imr, imr_val);
- intel_uncore_posting_read(uncore, imr);
+ intel_uncore_write(uncore, regs.ier, ier_val);
+ intel_uncore_write(uncore, regs.imr, imr_val);
+ intel_uncore_posting_read(uncore, regs.imr);
}
bool intel_irqs_enabled(struct xe_device *xe)
diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c
new file mode 100644
index 000000000000..9f54fad0f1c0
--- /dev/null
+++ b/drivers/gpu/drm/xe/display/intel_bo.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: MIT
+/* Copyright © 2024 Intel Corporation */
+
+#include <drm/drm_gem.h>
+
+#include "xe_bo.h"
+#include "intel_bo.h"
+
+bool intel_bo_is_tiled(struct drm_gem_object *obj)
+{
+ /* legacy tiling is unused */
+ return false;
+}
+
+bool intel_bo_is_userptr(struct drm_gem_object *obj)
+{
+ /* xe does not have userptr bos */
+ return false;
+}
+
+bool intel_bo_is_shmem(struct drm_gem_object *obj)
+{
+ return false;
+}
+
+bool intel_bo_is_protected(struct drm_gem_object *obj)
+{
+ return false;
+}
+
+void intel_bo_flush_if_display(struct drm_gem_object *obj)
+{
+}
+
+int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+ return drm_gem_prime_mmap(obj, vma);
+}
+
+int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size)
+{
+ struct xe_bo *bo = gem_to_xe_bo(obj);
+ struct ttm_bo_kmap_obj map;
+ void *src;
+ bool is_iomem;
+ int ret;
+
+ ret = xe_bo_lock(bo, true);
+ if (ret)
+ return ret;
+
+ ret = ttm_bo_kmap(&bo->ttm, offset >> PAGE_SHIFT, 1, &map);
+ if (ret)
+ goto out_unlock;
+
+ offset &= ~PAGE_MASK;
+ src = ttm_kmap_obj_virtual(&map, &is_iomem);
+ src += offset;
+ if (is_iomem)
+ memcpy_fromio(dst, (void __iomem *)src, size);
+ else
+ memcpy(dst, src, size);
+
+ ttm_bo_kunmap(&map);
+out_unlock:
+ xe_bo_unlock(bo);
+ return ret;
+}
+
+struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj)
+{
+ return NULL;
+}
+
+struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
+ struct intel_frontbuffer *front)
+{
+ return front;
+}
+
+void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
+{
+ /* FIXME */
+}
diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c
index 63ce97cc4cfe..4d209ebc26c2 100644
--- a/drivers/gpu/drm/xe/display/intel_fb_bo.c
+++ b/drivers/gpu/drm/xe/display/intel_fb_bo.c
@@ -11,8 +11,10 @@
#include "intel_fb_bo.h"
#include "xe_bo.h"
-void intel_fb_bo_framebuffer_fini(struct xe_bo *bo)
+void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj)
{
+ struct xe_bo *bo = gem_to_xe_bo(obj);
+
if (bo->flags & XE_BO_FLAG_PINNED) {
/* Unpin our kernel fb first */
xe_bo_lock(bo, false);
@@ -23,9 +25,10 @@ void intel_fb_bo_framebuffer_fini(struct xe_bo *bo)
}
int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
- struct xe_bo *bo,
+ struct drm_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd)
{
+ struct xe_bo *bo = gem_to_xe_bo(obj);
struct xe_device *xe = to_xe_device(bo->ttm.base.dev);
int ret;
@@ -65,11 +68,11 @@ err:
return ret;
}
-struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
- struct drm_file *filp,
- const struct drm_mode_fb_cmd2 *mode_cmd)
+struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
+ struct drm_file *filp,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
{
- struct drm_i915_gem_object *bo;
+ struct xe_bo *bo;
struct drm_gem_object *gem = drm_gem_object_lookup(filp, mode_cmd->handles[0]);
if (!gem)
@@ -78,11 +81,11 @@ struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
bo = gem_to_xe_bo(gem);
/* Require vram placement or dma-buf import */
if (IS_DGFX(i915) &&
- !xe_bo_can_migrate(gem_to_xe_bo(gem), XE_PL_VRAM0) &&
+ !xe_bo_can_migrate(bo, XE_PL_VRAM0) &&
bo->ttm.type != ttm_bo_type_sg) {
drm_gem_object_put(gem);
return ERR_PTR(-EREMOTE);
}
- return bo;
+ return gem;
}
diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.h b/drivers/gpu/drm/xe/display/intel_fb_bo.h
deleted file mode 100644
index 5d365b925b7a..000000000000
--- a/drivers/gpu/drm/xe/display/intel_fb_bo.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2021 Intel Corporation
- */
-
-#ifndef __INTEL_FB_BO_H__
-#define __INTEL_FB_BO_H__
-
-struct drm_file;
-struct drm_mode_fb_cmd2;
-struct drm_i915_private;
-struct intel_framebuffer;
-struct xe_bo;
-
-void intel_fb_bo_framebuffer_fini(struct xe_bo *bo);
-int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
- struct xe_bo *bo,
- struct drm_mode_fb_cmd2 *mode_cmd);
-
-struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
- struct drm_file *filp,
- const struct drm_mode_fb_cmd2 *mode_cmd);
-
-#endif
diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
index 99499d6c0256..ca95fcd098ec 100644
--- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
+++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
@@ -6,6 +6,7 @@
#include <drm/drm_fb_helper.h>
#include "intel_display_types.h"
+#include "intel_fb.h"
#include "intel_fbdev_fb.h"
#include "xe_bo.h"
#include "xe_ttm_stolen_mgr.h"
@@ -20,7 +21,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
struct drm_device *dev = helper->dev;
struct xe_device *xe = to_xe_device(dev);
struct drm_mode_fb_cmd2 mode_cmd = {};
- struct drm_i915_gem_object *obj;
+ struct xe_bo *obj;
int size;
/* we don't do packed 24bpp */
@@ -64,13 +65,13 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
goto err;
}
- fb = intel_framebuffer_create(obj, &mode_cmd);
+ fb = intel_framebuffer_create(&obj->ttm.base, &mode_cmd);
if (IS_ERR(fb)) {
xe_bo_unpin_map_no_vm(obj);
goto err;
}
- drm_gem_object_put(intel_bo_to_drm_bo(obj));
+ drm_gem_object_put(&obj->ttm.base);
return to_intel_framebuffer(fb);
@@ -79,8 +80,9 @@ err:
}
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
- struct drm_i915_gem_object *obj, struct i915_vma *vma)
+ struct drm_gem_object *_obj, struct i915_vma *vma)
{
+ struct xe_bo *obj = gem_to_xe_bo(_obj);
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
if (!(obj->flags & XE_BO_FLAG_SYSTEM)) {
@@ -100,7 +102,7 @@ int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info
XE_WARN_ON(iosys_map_is_null(&obj->vmap));
info->screen_base = obj->vmap.vaddr_iomem;
- info->screen_size = intel_bo_to_drm_bo(obj)->size;
+ info->screen_size = obj->ttm.base.size;
return 0;
}
diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
index 26b2cae11d46..957ae763531d 100644
--- a/drivers/gpu/drm/xe/display/xe_display.c
+++ b/drivers/gpu/drm/xe/display/xe_display.c
@@ -10,6 +10,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_managed.h>
+#include <drm/drm_probe_helper.h>
#include <uapi/drm/xe_drm.h>
#include "soc/intel_dram.h"
@@ -320,7 +321,9 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
* properly.
*/
intel_power_domains_disable(xe);
- intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
+ if (!runtime)
+ intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true);
+
if (!runtime && has_display(xe)) {
drm_kms_helper_poll_disable(&xe->drm);
intel_display_driver_disable_user_access(xe);
@@ -329,7 +332,8 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
xe_display_flush_cleanup_work(xe);
- intel_dp_mst_suspend(xe);
+ if (!runtime)
+ intel_dp_mst_suspend(xe);
intel_hpd_cancel_work(xe);
@@ -340,7 +344,7 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
intel_opregion_suspend(display, s2idle ? PCI_D1 : PCI_D3cold);
- intel_dmc_suspend(xe);
+ intel_dmc_suspend(display);
}
void xe_display_pm_suspend(struct xe_device *xe)
@@ -430,7 +434,7 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
if (!xe->info.probe_display)
return;
- intel_dmc_resume(xe);
+ intel_dmc_resume(display);
if (has_display(xe))
drm_mode_config_reset(&xe->drm);
@@ -442,7 +446,9 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
intel_display_driver_resume_access(xe);
/* MST sideband requires HPD interrupts enabled */
- intel_dp_mst_resume(xe);
+ if (!runtime)
+ intel_dp_mst_resume(xe);
+
if (!runtime && has_display(xe)) {
intel_display_driver_resume(xe);
drm_kms_helper_poll_enable(&xe->drm);
@@ -452,7 +458,8 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
intel_opregion_resume(display);
- intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
+ if (!runtime)
+ intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
intel_power_domains_enable(xe);
}
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index b58fc4ba2aac..79dbbbe03c7f 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -84,7 +84,8 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb,
struct xe_device *xe = to_xe_device(fb->base.dev);
struct xe_tile *tile0 = xe_device_get_root_tile(xe);
struct xe_ggtt *ggtt = tile0->mem.ggtt;
- struct xe_bo *bo = intel_fb_obj(&fb->base), *dpt;
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
+ struct xe_bo *bo = gem_to_xe_bo(obj), *dpt;
u32 dpt_size, size = bo->ttm.base.size;
if (view->type == I915_GTT_VIEW_NORMAL)
@@ -185,7 +186,8 @@ static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb,
const struct i915_gtt_view *view,
struct i915_vma *vma)
{
- struct xe_bo *bo = intel_fb_obj(&fb->base);
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
+ struct xe_bo *bo = gem_to_xe_bo(obj);
struct xe_device *xe = to_xe_device(fb->base.dev);
struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt;
u32 align;
@@ -269,7 +271,8 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb,
struct drm_device *dev = fb->base.dev;
struct xe_device *xe = to_xe_device(dev);
struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL);
- struct xe_bo *bo = intel_fb_obj(&fb->base);
+ struct drm_gem_object *obj = intel_fb_bo(&fb->base);
+ struct xe_bo *bo = gem_to_xe_bo(obj);
int ret;
if (!vma)
@@ -366,7 +369,8 @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags)
int intel_plane_pin_fb(struct intel_plane_state *plane_state)
{
struct drm_framebuffer *fb = plane_state->hw.fb;
- struct xe_bo *bo = intel_fb_obj(fb);
+ struct drm_gem_object *obj = intel_fb_bo(fb);
+ struct xe_bo *bo = gem_to_xe_bo(obj);
struct i915_vma *vma;
/* We reject creating !SCANOUT fb's, so this is weird.. */
diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 6619a40aed15..231677129a35 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -30,13 +30,14 @@ struct intel_hdcp_gsc_message {
#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)
-bool intel_hdcp_gsc_cs_required(struct xe_device *xe)
+bool intel_hdcp_gsc_cs_required(struct intel_display *display)
{
- return DISPLAY_VER(xe) >= 14;
+ return DISPLAY_VER(display) >= 14;
}
-bool intel_hdcp_gsc_check_status(struct xe_device *xe)
+bool intel_hdcp_gsc_check_status(struct intel_display *display)
{
+ struct xe_device *xe = to_xe_device(display->drm);
struct xe_tile *tile = xe_device_get_root_tile(xe);
struct xe_gt *gt = tile->media_gt;
struct xe_gsc *gsc = &gt->uc.gsc;
@@ -66,9 +67,10 @@ out:
}
/*This function helps allocate memory for the command that we will send to gsc cs */
-static int intel_hdcp_gsc_initialize_message(struct xe_device *xe,
+static int intel_hdcp_gsc_initialize_message(struct intel_display *display,
struct intel_hdcp_gsc_message *hdcp_message)
{
+ struct xe_device *xe = to_xe_device(display->drm);
struct xe_bo *bo = NULL;
u64 cmd_in, cmd_out;
int ret = 0;
@@ -80,7 +82,7 @@ static int intel_hdcp_gsc_initialize_message(struct xe_device *xe,
XE_BO_FLAG_GGTT);
if (IS_ERR(bo)) {
- drm_err(&xe->drm, "Failed to allocate bo for HDCP streaming command!\n");
+ drm_err(display->drm, "Failed to allocate bo for HDCP streaming command!\n");
ret = PTR_ERR(bo);
goto out;
}
@@ -96,7 +98,7 @@ out:
return ret;
}
-static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe)
+static int intel_hdcp_gsc_hdcp2_init(struct intel_display *display)
{
struct intel_hdcp_gsc_message *hdcp_message;
int ret;
@@ -110,14 +112,14 @@ static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe)
* NOTE: No need to lock the comp mutex here as it is already
* going to be taken before this function called
*/
- ret = intel_hdcp_gsc_initialize_message(xe, hdcp_message);
+ ret = intel_hdcp_gsc_initialize_message(display, hdcp_message);
if (ret) {
- drm_err(&xe->drm, "Could not initialize hdcp_message\n");
+ drm_err(display->drm, "Could not initialize hdcp_message\n");
kfree(hdcp_message);
return ret;
}
- xe->display.hdcp.hdcp_message = hdcp_message;
+ display->hdcp.hdcp_message = hdcp_message;
return ret;
}
@@ -137,7 +139,7 @@ static const struct i915_hdcp_ops gsc_hdcp_ops = {
.close_hdcp_session = intel_hdcp_gsc_close_session,
};
-int intel_hdcp_gsc_init(struct xe_device *xe)
+int intel_hdcp_gsc_init(struct intel_display *display)
{
struct i915_hdcp_arbiter *data;
int ret;
@@ -146,33 +148,33 @@ int intel_hdcp_gsc_init(struct xe_device *xe)
if (!data)
return -ENOMEM;
- mutex_lock(&xe->display.hdcp.hdcp_mutex);
- xe->display.hdcp.arbiter = data;
- xe->display.hdcp.arbiter->hdcp_dev = xe->drm.dev;
- xe->display.hdcp.arbiter->ops = &gsc_hdcp_ops;
- ret = intel_hdcp_gsc_hdcp2_init(xe);
+ mutex_lock(&display->hdcp.hdcp_mutex);
+ display->hdcp.arbiter = data;
+ display->hdcp.arbiter->hdcp_dev = display->drm->dev;
+ display->hdcp.arbiter->ops = &gsc_hdcp_ops;
+ ret = intel_hdcp_gsc_hdcp2_init(display);
if (ret)
kfree(data);
- mutex_unlock(&xe->display.hdcp.hdcp_mutex);
+ mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
-void intel_hdcp_gsc_fini(struct xe_device *xe)
+void intel_hdcp_gsc_fini(struct intel_display *display)
{
struct intel_hdcp_gsc_message *hdcp_message =
- xe->display.hdcp.hdcp_message;
- struct i915_hdcp_arbiter *arb = xe->display.hdcp.arbiter;
+ display->hdcp.hdcp_message;
+ struct i915_hdcp_arbiter *arb = display->hdcp.arbiter;
if (hdcp_message) {
xe_bo_unpin_map_no_vm(hdcp_message->hdcp_bo);
kfree(hdcp_message);
- xe->display.hdcp.hdcp_message = NULL;
+ display->hdcp.hdcp_message = NULL;
}
kfree(arb);
- xe->display.hdcp.arbiter = NULL;
+ display->hdcp.arbiter = NULL;
}
static int xe_gsc_send_sync(struct xe_device *xe,
diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c
index a50ab9eae40a..8c113463a3d5 100644
--- a/drivers/gpu/drm/xe/display/xe_plane_initial.c
+++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c
@@ -170,7 +170,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
return false;
if (intel_framebuffer_init(to_intel_framebuffer(fb),
- bo, &mode_cmd)) {
+ &bo->ttm.base, &mode_cmd)) {
drm_dbg_kms(&xe->drm, "intel fb init failed\n");
goto err_bo;
}
@@ -248,7 +248,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
* the lookup of sysmem scratch pages.
*/
plane->check_plane(crtc_state, plane_state);
- plane->async_flip(plane, crtc_state, plane_state, true);
+ plane->async_flip(NULL, plane, crtc_state, plane_state, true);
return;
nofb:
diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
index 6e4be52306df..31f4ba3bd8c1 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -312,8 +312,6 @@ static inline unsigned int xe_sg_segment_size(struct device *dev)
return round_down(max / 2, PAGE_SIZE);
}
-#define i915_gem_object_flush_if_display(obj) ((void)(obj))
-
#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
/**
* xe_bo_is_mem_type - Whether the bo currently resides in the given
diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
index 2ed558ac2264..8b9201775081 100644
--- a/drivers/gpu/drm/xe/xe_bo_types.h
+++ b/drivers/gpu/drm/xe/xe_bo_types.h
@@ -78,7 +78,4 @@ struct xe_bo {
struct list_head vram_userfault_link;
};
-#define intel_bo_to_drm_bo(bo) (&(bo)->ttm.base)
-#define intel_bo_to_i915(bo) to_i915(intel_bo_to_drm_bo(bo)->dev)
-
#endif
diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h
index 2bf03ebfcf73..6b92f8c3731b 100644
--- a/include/drm/intel/i915_pciids.h
+++ b/include/drm/intel/i915_pciids.h
@@ -25,27 +25,20 @@
#ifndef _I915_PCIIDS_H
#define _I915_PCIIDS_H
-/*
- * A pci_device_id struct {
- * __u32 vendor, device;
- * __u32 subvendor, subdevice;
- * __u32 class, class_mask;
- * kernel_ulong_t driver_data;
- * };
- * Don't use C99 here because "class" is reserved and we want to
- * give userspace flexibility.
- */
-#define INTEL_VGA_DEVICE(id, info) { \
- 0x8086, id, \
- ~0, ~0, \
- 0x030000, 0xff0000, \
- (unsigned long) info }
-
-#define INTEL_QUANTA_VGA_DEVICE(info) { \
- 0x8086, 0x16a, \
- 0x152d, 0x8990, \
- 0x030000, 0xff0000, \
- (unsigned long) info }
+#ifdef __KERNEL__
+#define INTEL_VGA_DEVICE(_id, _info) { \
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, (_id)), \
+ .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, \
+ .driver_data = (kernel_ulong_t)(_info), \
+}
+
+#define INTEL_QUANTA_VGA_DEVICE(_info) { \
+ .vendor = PCI_VENDOR_ID_INTEL, .device = 0x16a, \
+ .subvendor = 0x152d, .subdevice = 0x8990, \
+ .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, \
+ .driver_data = (kernel_ulong_t)(_info), \
+}
+#endif
#define INTEL_I810_IDS(MACRO__, ...) \
MACRO__(0x7121, ## __VA_ARGS__), /* I810 */ \
@@ -771,15 +764,16 @@
INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \
INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__)
-/* MTL */
+/* ARL */
#define INTEL_ARL_IDS(MACRO__, ...) \
MACRO__(0x7D41, ## __VA_ARGS__), \
MACRO__(0x7D51, ## __VA_ARGS__), \
MACRO__(0x7D67, ## __VA_ARGS__), \
- MACRO__(0x7DD1, ## __VA_ARGS__)
+ MACRO__(0x7DD1, ## __VA_ARGS__), \
+ MACRO__(0xB640, ## __VA_ARGS__)
+/* MTL */
#define INTEL_MTL_IDS(MACRO__, ...) \
- INTEL_ARL_IDS(MACRO__, ## __VA_ARGS__), \
MACRO__(0x7D40, ## __VA_ARGS__), \
MACRO__(0x7D45, ## __VA_ARGS__), \
MACRO__(0x7D55, ## __VA_ARGS__), \
@@ -800,4 +794,16 @@
MACRO__(0xE20D, ## __VA_ARGS__), \
MACRO__(0xE212, ## __VA_ARGS__)
+/* PTL */
+#define INTEL_PTL_IDS(MACRO__, ...) \
+ MACRO__(0xB080, ## __VA_ARGS__), \
+ MACRO__(0xB081, ## __VA_ARGS__), \
+ MACRO__(0xB082, ## __VA_ARGS__), \
+ MACRO__(0xB090, ## __VA_ARGS__), \
+ MACRO__(0xB091, ## __VA_ARGS__), \
+ MACRO__(0xB092, ## __VA_ARGS__), \
+ MACRO__(0xB0A0, ## __VA_ARGS__), \
+ MACRO__(0xB0A1, ## __VA_ARGS__), \
+ MACRO__(0xB0A2, ## __VA_ARGS__)
+
#endif /* _I915_PCIIDS_H */