summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-07-18 19:34:02 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-07-18 19:34:02 +0300
commitb3ce7a30847a54a7f96a35e609303d8afecd460b (patch)
tree81fb53546e55b9c670da4476b4b0b27e57abb25d /drivers/gpu/drm/i915/display
parentb1bc554e009e3aeed7e4cfd2e717c7a34a98c683 (diff)
parent478a52707b0abe98aac7f8c53ccddb759be66b06 (diff)
downloadlinux-b3ce7a30847a54a7f96a35e609303d8afecd460b.tar.xz
Merge tag 'drm-next-2024-07-18' of https://gitlab.freedesktop.org/drm/kernel
Pull drm updates from Dave Airlie: "There's a lot of stuff in here, amd, i915 and xe have new platform work, lots of core rework around EDID handling, some new COMPILE_TEST options, maintainer changes and a lots of other stuff. Summary: core: - deprecate DRM data and return 0 date - connector: Create a set of helpers to help with HDMI support - Remove driver owner assignments - Allow more drivers to compile with COMPILE_TEST - Conversions to drm_edid - Sprinkle MODULE_DESCRIPTIONS everywhere they are missing - Remove drm_mm_replace_node - print: Add a drm prefix to warn level messages too, remove ___drm_dbg, consolidate prefix handling - New monochrome TV mode variant ttm: - improve number of page faults on some platforms - fix test builds under PREEMPT_RT - more test coverage ci: - Require a more recent version of mesa - improve farm setup and test generation dma-buf: - warn if reserving 0 fence slots - internal API heap enhancements fbdev: - Create memory manager optimized fbdev emulation panic: - Allow to select fonts - improve drm_fb_dma_get_scanout_buffer - Allow to dump kmsg to the screen bridge: - Remove redundant checks on bridge->encoder - Remove drm_bridge_chain_mode_fixup - bridge-connector: Plumb in the new HDMI helper - analogix_dp: Various improvements, handle AUX transfers timeout - samsung-dsim: Fix timings calculation - tc358767: Plenty of small fixes, fix no connector attach, fix clocks - sii902x: state validation improvements panels: - Switch panels from register table initialization to proper code - Now that the panel code tracks the panel state, remove every ad-hoc implementation in the panel drivers - More cleanup of prepare / enable state tracking in drivers - edp: Drop legacy panel compatibles - simple-bridge: Switch to devm_drm_bridge_add - New panels: Lincoln Tech Sol LCD185-101CT, Microtips Technology 13-101HIEBCAF0-C, Microtips Technology MF-103HIEB0GA0, BOE nv110wum-l60, IVO t109nw41, WL-355608-A8, PrimeView PM070WL4, Lincoln Technologies LCD197, Ortustech COM35H3P70ULC, AUO G104STN01, K&d kd101ne3-40ti amdgpu: - DCN 4.0.x support - GC 12.0 support - GMC 12.0 support - SDMA 7.0 support - MES12 support - MMHUB 4.1 support - GFX12 modifier and DCC support - lots of IP fixes/updates amdkfd: - Contiguous VRAM allocations - GC 12.0 support - SDMA 7.0 support - SR-IOV fixes - KFD GFX ALU exceptions i915: - Battlemage Xe2 HPD display enablement - Panel Replay enabling - DP AUX-less ALPM/LOBF - Enable link training failure fallback for DP MST links - CMRR (Content Match Refresh Rate) enabling - Increase ADL-S/ADL-P/DG2+ max TMDS bitrate to 6 Gbps - Enable eDP AUX based HDR backlight - Support replaying GPU hangs with captured context image - Automate CCS Mode setting during engine resets - lots of refactoring - Support replaying GPU hangs with captured context image - Increase FLR timeout from 3s to 9s - Enable w/a 16021333562 for DG2, MTL and ARL [guc] xe: - update MAINATINERS - New uapi adding OA functionality to Xe - expose l3 bank mask - fix display detect on ADL-N - runtime PM Fixes - Fix silent backmerge issues - More prep for SR-IOV - HWmon additions - per client usage info - Rework GPU page fault handling - Drop EXEC_QUEUE_FLAG_BANNED - Add BMG PCI IDs - Scheduler fixes and improvements - Rename xe_exec_queue::compute to xe_exec_queue::lr - Use ttm_uncached for BO with NEEDS_UC flag - Rename xe perf layer as xe observation layer - lots of refactoring radeon: - Backlight workaround for iMac - Silence UBSAN flex array warnings msm: - Validate registers XML description against schema in CI - core/dpu: SM7150 support - mdp5: Add support for MSM8937 - gpu: Add param for userspace to know if raytracing is supported - gpu: X185 support (aka gpu in X1 laptop chips) - gpu: a505 support ivpu: - hardware scheduler support - profiling support - improvements to the platform support layer - firmware handling improvements - clocks/power mgmt improvements - scheduler/logging improvements habanalabs: - Gradual sleep in polling memory macro - Reduce Gaudi2 MSI-X interrupt count to 128 - Add Gaudi2-D revision support - Add timestamp to CPLD info - Gaudi2: Assume hard-reset by firmware upon MC SEI severe error - Align Gaudi2 interrupt names - Check for errors after preboot is ready - Change habanalabs maintainer and git repo path mgag200: - refactoring and improvements - Add BMC output - enable polling nouveau: - add registry command line v3d: - perf counters improvements zynqmp: - irq and debugfs improvements atmel-hlcdc: - Support XLCDC in sam9x7 mipi-dbi: - Remove mipi_dbi_machine_little_endian - make SPI bits per word configurable - support RGB888 - allow pixel formats to be specified in the DT sun4i: - Rework the blender setup for DE2 panfrost: - Enable MT8188 support vc4: - Monochrome TV support exynos: - fix fallback mode regression - fix memory leak - Use drm_edid_duplicate() instead of kmemdup() etnaviv: - fix i.MX8MP NPU clock gating - workaround FE register cdc issues on some cores - fix DMA sync handling for cached buffers - fix job timeout handling - keep TS enabled on MMUv2 cores for improved performance mediatek: - Convert to platform remove callback returning void- - Drop chain_mode_fixup call in mode_valid() - Fixes the errors of MediaTek display driver found by IGT - Add display support for the MT8365-EVK board - Fix bit depth overwritten for mtk_ovl_set bit_depth() - Fix possible_crtcs calculation - Fix spurious kfree() ast: - refactor mode setting code stm: - Add LVDS support - DSI PHY updates" * tag 'drm-next-2024-07-18' of https://gitlab.freedesktop.org/drm/kernel: (2501 commits) drm/amdgpu/mes12: add missing opcode string drm/amdgpu/mes11: update opcode strings Revert "drm/amd/display: Reset freesync config before update new state" drm/omap: Restrict compile testing to PAGE_SIZE less than 64KB drm/xe: Drop trace_xe_hw_fence_free drm/xe/uapi: Rename xe perf layer as xe observation layer drm/amdgpu: remove exp hw support check for gfx12 drm/amdgpu: timely save bad pages to eeprom after gpu ras reset is completed drm/amdgpu: flush all cached ras bad pages to eeprom drm/amdgpu: select compute ME engines dynamically drm/amd/display: Allow display DCC for DCN401 drm/amdgpu: select compute ME engines dynamically drm/amdgpu/job: Replace DRM_INFO/ERROR logging drm/amdgpu: select compute ME engines dynamically drm/amd/pm: Ignore initial value in smu response register drm/amdgpu: Initialize VF partition mode drm/amd/amdgpu: fix SDMA IRQ client ID <-> req mapping MAINTAINERS: fix Xinhui's name MAINTAINERS: update powerplay and swsmu drm/qxl: Pin buffer objects for internal mappings ...
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r--drivers/gpu/drm/i915/display/dvo_ns2501.c1
-rw-r--r--drivers/gpu/drm/i915/display/g4x_dp.c37
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c175
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane_regs.h112
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_wm.c114
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_alpm.c415
-rw-r--r--drivers/gpu/drm/i915/display/intel_alpm.h27
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c97
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio.c17
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio_regs.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c243
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c65
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c130
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c154
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_color_regs.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.c50
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c74
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc_state_dump.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c166
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor_regs.h112
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.c379
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h48
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c137
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c838
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h13
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.c937
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.h89
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_irq.c96
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_limits.h21
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_params.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_params.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_well.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_trace.h50
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h95
-rw-r--r--drivers/gpu/drm/i915/display/intel_dkl_phy.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c410
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h24
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c149
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_regs.h18
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_hdcp.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c538
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c84
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c63
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt_common.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_drrs.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.c95
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.h13
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb_regs.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi_vbt.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dvo.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_encoder.c83
-rw-r--r--drivers/gpu/drm/i915/display/intel_encoder.h20
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c164
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.c104
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.h13
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c38
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c41
-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.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_fifo_underrun.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_frontbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c27
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c41
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug_irq.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_lpe_audio.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_setup.c60
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_verify.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_panel.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch_display.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_pipe_crc.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h152
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.c32
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps_regs.h16
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c1087
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr_regs.h93
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c27
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite_regs.h242
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite_uapi.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_tdf.h25
-rw-r--r--drivers/gpu/drm/i915/display/intel_vblank.c179
-rw-r--r--drivers/gpu/drm/i915/display/intel_vblank.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h729
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c19
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc_regs.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_vga.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_vrr.c182
-rw-r--r--drivers/gpu/drm/i915/display/intel_vrr_regs.h127
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c273
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.h2
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane_regs.h442
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.c134
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.h13
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark_regs.h83
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c3
117 files changed, 7710 insertions, 3246 deletions
diff --git a/drivers/gpu/drm/i915/display/dvo_ns2501.c b/drivers/gpu/drm/i915/display/dvo_ns2501.c
index 1df212fb000e..21486008dae9 100644
--- a/drivers/gpu/drm/i915/display/dvo_ns2501.c
+++ b/drivers/gpu/drm/i915/display/dvo_ns2501.c
@@ -27,7 +27,6 @@
*/
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_display_types.h"
#include "intel_dvo_dev.h"
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index 06ec04e667e3..a8e746a0f670 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -20,6 +20,7 @@
#include "intel_dp_aux.h"
#include "intel_dp_link_training.h"
#include "intel_dpio_phy.h"
+#include "intel_encoder.h"
#include "intel_fifo_underrun.h"
#include "intel_hdmi.h"
#include "intel_hotplug.h"
@@ -706,7 +707,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
intel_dp_configure_protocol_converter(intel_dp, pipe_config);
intel_dp_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, pipe_config);
- intel_dp_start_link_train(intel_dp, pipe_config);
+ intel_dp_start_link_train(state, intel_dp, pipe_config);
intel_dp_stop_link_train(intel_dp, pipe_config);
}
@@ -1159,9 +1160,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
struct intel_connector *connector)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_modeset_acquire_ctx ctx;
enum intel_hotplug_state state;
- int ret;
if (intel_dp->compliance.test_active &&
intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
@@ -1172,23 +1171,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
state = intel_encoder_hotplug(encoder, connector);
- drm_modeset_acquire_init(&ctx, 0);
-
- for (;;) {
- ret = intel_dp_retrain_link(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);
+ intel_dp_check_link_state(intel_dp);
/*
* Keeping it consistent with intel_ddi_hotplug() and
@@ -1228,7 +1211,7 @@ static bool g4x_digital_port_connected(struct intel_encoder *encoder)
return false;
}
- return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit;
+ return intel_de_read(dev_priv, PORT_HOTPLUG_STAT(dev_priv)) & bit;
}
static bool ilk_digital_port_connected(struct intel_encoder *encoder)
@@ -1239,6 +1222,15 @@ static bool ilk_digital_port_connected(struct intel_encoder *encoder)
return intel_de_read(dev_priv, DEISR) & bit;
}
+static void g4x_dp_suspend_complete(struct intel_encoder *encoder)
+{
+ /*
+ * TODO: Move this to intel_dp_encoder_suspend(),
+ * once modeset locking around that is removed.
+ */
+ intel_encoder_link_check_flush_work(encoder);
+}
+
static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
{
intel_dp_encoder_flush_work(encoder);
@@ -1325,6 +1317,8 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
"DP %c", port_name(port)))
goto err_encoder_init;
+ intel_encoder_link_check_init(intel_encoder, intel_dp_link_check);
+
intel_encoder->hotplug = intel_dp_hotplug;
intel_encoder->compute_config = intel_dp_compute_config;
intel_encoder->get_hw_state = intel_dp_get_hw_state;
@@ -1333,6 +1327,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check;
intel_encoder->update_pipe = intel_backlight_update;
intel_encoder->suspend = intel_dp_encoder_suspend;
+ intel_encoder->suspend_complete = g4x_dp_suspend_complete;
intel_encoder->shutdown = intel_dp_encoder_shutdown;
if (IS_CHERRYVIEW(dev_priv)) {
intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 0279c8aabdd1..9447f7229b60 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -10,6 +10,7 @@
#include "i915_reg.h"
#include "i9xx_plane.h"
+#include "i9xx_plane_regs.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_de.h"
@@ -224,8 +225,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv =
- to_i915(plane_state->uapi.plane->dev);
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
int src_x, src_y, src_w;
u32 offset;
@@ -266,7 +267,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
* despite them not using the linear offset anymore.
*/
if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
- u32 alignment = intel_surf_alignment(fb, 0);
+ unsigned int alignment = plane->min_alignment(plane, fb, 0);
int cpp = fb->format->cpp[0];
while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
@@ -422,7 +423,7 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane),
plane_state->view.color_plane[0].mapping_stride);
if (DISPLAY_VER(dev_priv) < 4) {
@@ -436,9 +437,9 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
* generator but let's assume we still need to
* program whatever is there.
*/
- intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPPOS(dev_priv, i9xx_plane),
DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSIZE(dev_priv, i9xx_plane),
DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
}
}
@@ -455,6 +456,11 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
+ /* see intel_plane_atomic_calc_changes() */
+ if (plane->need_async_flip_toggle_wa &&
+ crtc_state->async_flip_planes & BIT(plane->id))
+ dspcntr |= DISP_ASYNC_FLIP;
+
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
if (DISPLAY_VER(dev_priv) >= 4)
@@ -468,20 +474,21 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
int crtc_w = drm_rect_width(&plane_state->uapi.dst);
int crtc_h = drm_rect_height(&plane_state->uapi.dst);
- intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
+ intel_de_write_fw(dev_priv, PRIMPOS(dev_priv, i9xx_plane),
PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
+ intel_de_write_fw(dev_priv, PRIMSIZE(dev_priv, i9xx_plane),
PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
- intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
+ intel_de_write_fw(dev_priv,
+ PRIMCNSTALPHA(dev_priv, i9xx_plane), 0);
}
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPOFFSET(dev_priv, i9xx_plane),
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
} else if (DISPLAY_VER(dev_priv) >= 4) {
- intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPLINOFF(dev_priv, i9xx_plane),
linear_offset);
- intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPTILEOFF(dev_priv, i9xx_plane),
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
}
@@ -490,13 +497,13 @@ static void i9xx_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, DSPCNTR(i9xx_plane), dspcntr);
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
else
- intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -533,12 +540,12 @@ static void i9xx_plane_disable_arm(struct intel_plane *plane,
*/
dspcntr = i9xx_plane_ctl_crtc(crtc_state);
- intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0);
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), 0);
else
- intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), 0);
}
static void
@@ -555,9 +562,9 @@ g4x_primary_async_flip(struct intel_plane *plane,
if (async_flip)
dspcntr |= DISP_ASYNC_FLIP;
- intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -571,7 +578,7 @@ vlv_primary_async_flip(struct intel_plane *plane,
u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- intel_de_write_fw(dev_priv, DSPADDR_VLV(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPADDR_VLV(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -679,7 +686,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
+ val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
ret = val & DISP_ENABLE;
@@ -736,25 +743,87 @@ i965_plane_max_stride(struct intel_plane *plane,
}
static unsigned int
-i9xx_plane_max_stride(struct intel_plane *plane,
+i915_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ if (modifier == I915_FORMAT_MOD_X_TILED)
+ return 8 * 1024;
+ else
+ return 16 * 1024;
+}
- if (DISPLAY_VER(dev_priv) >= 3) {
- if (modifier == I915_FORMAT_MOD_X_TILED)
- return 8*1024;
- else
- return 16*1024;
- } else {
- if (plane->i9xx_plane == PLANE_C)
- return 4*1024;
- else
- return 8*1024;
+static unsigned int
+i8xx_plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation)
+{
+ if (plane->i9xx_plane == PLANE_C)
+ return 4 * 1024;
+ else
+ return 8 * 1024;
+}
+
+static unsigned int vlv_primary_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
+ switch (fb->modifier) {
+ case I915_FORMAT_MOD_X_TILED:
+ if (HAS_ASYNC_FLIPS(i915))
+ return 256 * 1024;
+ return 4 * 1024;
+ case DRM_FORMAT_MOD_LINEAR:
+ return 128 * 1024;
+ default:
+ MISSING_CASE(fb->modifier);
+ return 0;
+ }
+}
+
+static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
+ switch (fb->modifier) {
+ case I915_FORMAT_MOD_X_TILED:
+ if (HAS_ASYNC_FLIPS(i915))
+ return 256 * 1024;
+ return 4 * 1024;
+ case DRM_FORMAT_MOD_LINEAR:
+ return 4 * 1024;
+ default:
+ MISSING_CASE(fb->modifier);
+ return 0;
+ }
+}
+
+static unsigned int i965_plane_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ switch (fb->modifier) {
+ case I915_FORMAT_MOD_X_TILED:
+ return 4 * 1024;
+ case DRM_FORMAT_MOD_LINEAR:
+ return 128 * 1024;
+ default:
+ MISSING_CASE(fb->modifier);
+ return 0;
}
}
+static unsigned int i9xx_plane_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ return 0;
+}
+
static const struct drm_plane_funcs i965_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
@@ -849,8 +918,10 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
if (HAS_GMCH(dev_priv)) {
if (DISPLAY_VER(dev_priv) >= 4)
plane->max_stride = i965_plane_max_stride;
+ else if (DISPLAY_VER(dev_priv) == 3)
+ plane->max_stride = i915_plane_max_stride;
else
- plane->max_stride = i9xx_plane_max_stride;
+ plane->max_stride = i8xx_plane_max_stride;
} else {
if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
plane->max_stride = hsw_primary_max_stride;
@@ -858,6 +929,15 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
plane->max_stride = ilk_primary_max_stride;
}
+ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ plane->min_alignment = vlv_primary_min_alignment;
+ else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
+ plane->min_alignment = g4x_primary_min_alignment;
+ else if (DISPLAY_VER(dev_priv) == 4)
+ plane->min_alignment = i965_plane_min_alignment;
+ else
+ plane->min_alignment = i9xx_plane_min_alignment;
+
if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
plane->update_arm = i830_plane_update_arm;
} else {
@@ -873,7 +953,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
plane->enable_flip_done = vlv_primary_enable_flip_done;
plane->disable_flip_done = vlv_primary_disable_flip_done;
} else if (IS_BROADWELL(dev_priv)) {
- plane->need_async_flip_disable_wa = true;
+ plane->need_async_flip_toggle_wa = true;
plane->async_flip = g4x_primary_async_flip;
plane->enable_flip_done = bdw_primary_enable_flip_done;
plane->disable_flip_done = bdw_primary_disable_flip_done;
@@ -1002,7 +1082,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
fb->dev = dev;
- val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
+ val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
if (DISPLAY_VER(dev_priv) >= 4) {
if (val & DISP_TILED) {
@@ -1023,29 +1103,30 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
fb->format = drm_format_info(fourcc);
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
+ offset = intel_de_read(dev_priv,
+ DSPOFFSET(dev_priv, i9xx_plane));
+ base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
} else if (DISPLAY_VER(dev_priv) >= 4) {
if (plane_config->tiling)
offset = intel_de_read(dev_priv,
- DSPTILEOFF(i9xx_plane));
+ DSPTILEOFF(dev_priv, i9xx_plane));
else
offset = intel_de_read(dev_priv,
- DSPLINOFF(i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
+ DSPLINOFF(dev_priv, i9xx_plane));
+ base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
} else {
offset = 0;
- base = intel_de_read(dev_priv, DSPADDR(i9xx_plane));
+ base = intel_de_read(dev_priv, DSPADDR(dev_priv, i9xx_plane));
}
plane_config->base = base;
drm_WARN_ON(&dev_priv->drm, offset != 0);
- val = intel_de_read(dev_priv, PIPESRC(pipe));
+ val = intel_de_read(dev_priv, PIPESRC(dev_priv, pipe));
fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
- val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane));
+ val = intel_de_read(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane));
fb->pitches[0] = val & 0xffffffc0;
aligned_height = intel_fb_align_height(fb, 0, fb->height);
@@ -1084,9 +1165,9 @@ bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
return false;
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write(dev_priv, DSPSURF(i9xx_plane), base);
+ intel_de_write(dev_priv, DSPSURF(dev_priv, i9xx_plane), base);
else
- intel_de_write(dev_priv, DSPADDR(i9xx_plane), base);
+ intel_de_write(dev_priv, DSPADDR(dev_priv, i9xx_plane), base);
return true;
}
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane_regs.h b/drivers/gpu/drm/i915/display/i9xx_plane_regs.h
new file mode 100644
index 000000000000..5d7ba824f354
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/i9xx_plane_regs.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __I9XX_PLANE_REGS_H__
+#define __I9XX_PLANE_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _DSPAADDR_VLV 0x7017C /* vlv/chv */
+#define DSPADDR_VLV(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAADDR_VLV)
+
+#define _DSPACNTR 0x70180
+#define DSPCNTR(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPACNTR)
+#define DISP_ENABLE REG_BIT(31)
+#define DISP_PIPE_GAMMA_ENABLE REG_BIT(30)
+#define DISP_FORMAT_MASK REG_GENMASK(29, 26)
+#define DISP_FORMAT_8BPP REG_FIELD_PREP(DISP_FORMAT_MASK, 2)
+#define DISP_FORMAT_BGRA555 REG_FIELD_PREP(DISP_FORMAT_MASK, 3)
+#define DISP_FORMAT_BGRX555 REG_FIELD_PREP(DISP_FORMAT_MASK, 4)
+#define DISP_FORMAT_BGRX565 REG_FIELD_PREP(DISP_FORMAT_MASK, 5)
+#define DISP_FORMAT_BGRX888 REG_FIELD_PREP(DISP_FORMAT_MASK, 6)
+#define DISP_FORMAT_BGRA888 REG_FIELD_PREP(DISP_FORMAT_MASK, 7)
+#define DISP_FORMAT_RGBX101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 8)
+#define DISP_FORMAT_RGBA101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 9)
+#define DISP_FORMAT_BGRX101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 10)
+#define DISP_FORMAT_BGRA101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 11)
+#define DISP_FORMAT_RGBX161616 REG_FIELD_PREP(DISP_FORMAT_MASK, 12)
+#define DISP_FORMAT_RGBX888 REG_FIELD_PREP(DISP_FORMAT_MASK, 14)
+#define DISP_FORMAT_RGBA888 REG_FIELD_PREP(DISP_FORMAT_MASK, 15)
+#define DISP_STEREO_ENABLE REG_BIT(25)
+#define DISP_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
+#define DISP_PIPE_SEL_MASK REG_GENMASK(25, 24)
+#define DISP_PIPE_SEL(pipe) REG_FIELD_PREP(DISP_PIPE_SEL_MASK, (pipe))
+#define DISP_SRC_KEY_ENABLE REG_BIT(22)
+#define DISP_LINE_DOUBLE REG_BIT(20)
+#define DISP_STEREO_POLARITY_SECOND REG_BIT(18)
+#define DISP_ALPHA_PREMULTIPLY REG_BIT(16) /* CHV pipe B */
+#define DISP_ROTATE_180 REG_BIT(15) /* i965+ */
+#define DISP_ALPHA_TRANS_ENABLE REG_BIT(15) /* pre-g4x plane B */
+#define DISP_TRICKLE_FEED_DISABLE REG_BIT(14) /* g4x+ */
+#define DISP_TILED REG_BIT(10) /* i965+ */
+#define DISP_ASYNC_FLIP REG_BIT(9) /* g4x+ */
+#define DISP_MIRROR REG_BIT(8) /* CHV pipe B */
+#define DISP_SPRITE_ABOVE_OVERLAY REG_BIT(0) /* pre-g4x plane B/C */
+
+#define _DSPAADDR 0x70184 /* pre-i965 */
+#define DSPADDR(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAADDR)
+
+#define _DSPALINOFF 0x70184 /* i965+ */
+#define DSPLINOFF(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPALINOFF)
+
+#define _DSPASTRIDE 0x70188
+#define DSPSTRIDE(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASTRIDE)
+
+#define _DSPAPOS 0x7018C /* pre-g4x */
+#define DSPPOS(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAPOS)
+#define DISP_POS_Y_MASK REG_GENMASK(31, 16)
+#define DISP_POS_Y(y) REG_FIELD_PREP(DISP_POS_Y_MASK, (y))
+#define DISP_POS_X_MASK REG_GENMASK(15, 0)
+#define DISP_POS_X(x) REG_FIELD_PREP(DISP_POS_X_MASK, (x))
+
+#define _DSPASIZE 0x70190 /* pre-g4x */
+#define DSPSIZE(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASIZE)
+#define DISP_HEIGHT_MASK REG_GENMASK(31, 16)
+#define DISP_HEIGHT(h) REG_FIELD_PREP(DISP_HEIGHT_MASK, (h))
+#define DISP_WIDTH_MASK REG_GENMASK(15, 0)
+#define DISP_WIDTH(w) REG_FIELD_PREP(DISP_WIDTH_MASK, (w))
+
+#define _DSPASURF 0x7019C /* i965+ */
+#define DSPSURF(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASURF)
+#define DISP_ADDR_MASK REG_GENMASK(31, 12)
+
+#define _DSPATILEOFF 0x701A4 /* i965+ */
+#define DSPTILEOFF(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPATILEOFF)
+#define DISP_OFFSET_Y_MASK REG_GENMASK(31, 16)
+#define DISP_OFFSET_Y(y) REG_FIELD_PREP(DISP_OFFSET_Y_MASK, (y))
+#define DISP_OFFSET_X_MASK REG_GENMASK(15, 0)
+#define DISP_OFFSET_X(x) REG_FIELD_PREP(DISP_OFFSET_X_MASK, (x))
+
+#define _DSPAOFFSET 0x701A4 /* hsw+ */
+#define DSPOFFSET(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAOFFSET)
+
+#define _DSPASURFLIVE 0x701AC /* g4x+ */
+#define DSPSURFLIVE(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASURFLIVE)
+
+#define _DSPAGAMC 0x701E0 /* pre-g4x */
+#define DSPGAMC(dev_priv, plane, i) _MMIO_PIPE2(dev_priv, plane, _DSPAGAMC + (5 - (i)) * 4) /* plane C only, 6 x u0.8 */
+
+/* CHV pipe B primary plane */
+#define _PRIMPOS_A 0x60a08
+#define PRIMPOS(dev_priv, plane) _MMIO_TRANS2(dev_priv, plane, _PRIMPOS_A)
+#define PRIM_POS_Y_MASK REG_GENMASK(31, 16)
+#define PRIM_POS_Y(y) REG_FIELD_PREP(PRIM_POS_Y_MASK, (y))
+#define PRIM_POS_X_MASK REG_GENMASK(15, 0)
+#define PRIM_POS_X(x) REG_FIELD_PREP(PRIM_POS_X_MASK, (x))
+
+#define _PRIMSIZE_A 0x60a0c
+#define PRIMSIZE(dev_priv, plane) _MMIO_TRANS2(dev_priv, plane, _PRIMSIZE_A)
+#define PRIM_HEIGHT_MASK REG_GENMASK(31, 16)
+#define PRIM_HEIGHT(h) REG_FIELD_PREP(PRIM_HEIGHT_MASK, (h))
+#define PRIM_WIDTH_MASK REG_GENMASK(15, 0)
+#define PRIM_WIDTH(w) REG_FIELD_PREP(PRIM_WIDTH_MASK, (w))
+
+#define _PRIMCNSTALPHA_A 0x60a10
+#define PRIMCNSTALPHA(dev_priv, plane) _MMIO_TRANS2(dev_priv, plane, _PRIMCNSTALPHA_A)
+#define PRIM_CONST_ALPHA_ENABLE REG_BIT(31)
+#define PRIM_CONST_ALPHA_MASK REG_GENMASK(7, 0)
+#define PRIM_CONST_ALPHA(alpha) REG_FIELD_PREP(PRIM_CONST_ALPHA_MASK, (alpha))
+
+#endif /* __I9XX_PLANE_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c
index 628e7192ebc9..2b7c3d270b17 100644
--- a/drivers/gpu/drm/i915/display/i9xx_wm.c
+++ b/drivers/gpu/drm/i915/display/i9xx_wm.c
@@ -70,25 +70,24 @@ static const struct cxsr_latency cxsr_latency_table[] = {
{0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */
};
-static const struct cxsr_latency *intel_get_cxsr_latency(struct drm_i915_private *i915)
+static const struct cxsr_latency *pnv_get_cxsr_latency(struct drm_i915_private *i915)
{
int i;
- if (i915->fsb_freq == 0 || i915->mem_freq == 0)
- return NULL;
-
for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
const struct cxsr_latency *latency = &cxsr_latency_table[i];
bool is_desktop = !IS_MOBILE(i915);
if (is_desktop == latency->is_desktop &&
i915->is_ddr3 == latency->is_ddr3 &&
- i915->fsb_freq == latency->fsb_freq &&
- i915->mem_freq == latency->mem_freq)
+ DIV_ROUND_CLOSEST(i915->fsb_freq, 1000) == latency->fsb_freq &&
+ DIV_ROUND_CLOSEST(i915->mem_freq, 1000) == latency->mem_freq)
return latency;
}
- drm_dbg_kms(&i915->drm, "Unknown FSB/MEM found, disable CxSR\n");
+ drm_dbg_kms(&i915->drm,
+ "Could not find CxSR latency for DDR%s, FSB %u kHz, MEM %u kHz\n",
+ i915->is_ddr3 ? "3" : "2", i915->fsb_freq, i915->mem_freq);
return NULL;
}
@@ -149,14 +148,14 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl
intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0);
intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF);
} else if (IS_PINEVIEW(dev_priv)) {
- val = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ val = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
was_enabled = val & PINEVIEW_SELF_REFRESH_EN;
if (enable)
val |= PINEVIEW_SELF_REFRESH_EN;
else
val &= ~PINEVIEW_SELF_REFRESH_EN;
- intel_uncore_write(&dev_priv->uncore, DSPFW3, val);
- intel_uncore_posting_read(&dev_priv->uncore, DSPFW3);
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), val);
+ intel_uncore_posting_read(&dev_priv->uncore, DSPFW3(dev_priv));
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) {
was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN;
val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) :
@@ -269,13 +268,15 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
switch (pipe) {
case PIPE_A:
- dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ dsparb = intel_uncore_read(&dev_priv->uncore,
+ DSPARB(dev_priv));
dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2);
sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0);
sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4);
break;
case PIPE_B:
- dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ dsparb = intel_uncore_read(&dev_priv->uncore,
+ DSPARB(dev_priv));
dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2);
sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8);
sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12);
@@ -300,7 +301,7 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
- u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv));
int size;
size = dsparb & 0x7f;
@@ -316,7 +317,7 @@ static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv,
static int i830_get_fifo_size(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
- u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv));
int size;
size = dsparb & 0x1ff;
@@ -333,7 +334,7 @@ static int i830_get_fifo_size(struct drm_i915_private *dev_priv,
static int i845_get_fifo_size(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
- u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv));
int size;
size = dsparb & 0x7f;
@@ -635,10 +636,9 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
u32 reg;
unsigned int wm;
- latency = intel_get_cxsr_latency(dev_priv);
+ latency = pnv_get_cxsr_latency(dev_priv);
if (!latency) {
- drm_dbg_kms(&dev_priv->drm,
- "Unknown FSB/MEM found, disable CxSR\n");
+ drm_dbg_kms(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n");
intel_set_memory_cxsr(dev_priv, false);
return;
}
@@ -655,10 +655,10 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
&pnv_display_wm,
pnv_display_wm.fifo_size,
cpp, latency->display_sr);
- reg = intel_uncore_read(&dev_priv->uncore, DSPFW1);
+ reg = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv));
reg &= ~DSPFW_SR_MASK;
reg |= FW_WM(wm, SR);
- intel_uncore_write(&dev_priv->uncore, DSPFW1, reg);
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), reg);
drm_dbg_kms(&dev_priv->drm, "DSPFW1 register is %x\n", reg);
/* cursor SR */
@@ -666,7 +666,8 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
&pnv_cursor_wm,
pnv_display_wm.fifo_size,
4, latency->cursor_sr);
- intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_CURSOR_SR_MASK,
+ intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv),
+ DSPFW_CURSOR_SR_MASK,
FW_WM(wm, CURSOR_SR));
/* Display HPLL off SR */
@@ -674,17 +675,18 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
&pnv_display_hplloff_wm,
pnv_display_hplloff_wm.fifo_size,
cpp, latency->display_hpll_disable);
- intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR));
+ intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv),
+ DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR));
/* cursor HPLL off SR */
wm = intel_calculate_wm(dev_priv, pixel_rate,
&pnv_cursor_hplloff_wm,
pnv_display_hplloff_wm.fifo_size,
4, latency->cursor_hpll_disable);
- reg = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ reg = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
reg &= ~DSPFW_HPLL_CURSOR_MASK;
reg |= FW_WM(wm, HPLL_CURSOR);
- intel_uncore_write(&dev_priv->uncore, DSPFW3, reg);
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), reg);
drm_dbg_kms(&dev_priv->drm, "DSPFW3 register is %x\n", reg);
intel_set_memory_cxsr(dev_priv, true);
@@ -718,25 +720,25 @@ static void g4x_write_wm_values(struct drm_i915_private *dev_priv,
for_each_pipe(dev_priv, pipe)
trace_g4x_wm(intel_crtc_for_pipe(dev_priv, pipe), wm);
- intel_uncore_write(&dev_priv->uncore, DSPFW1,
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
FW_WM(wm->sr.plane, SR) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW2,
+ intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv),
(wm->fbc_en ? DSPFW_FBC_SR_EN : 0) |
FW_WM(wm->sr.fbc, FBC_SR) |
FW_WM(wm->hpll.fbc, FBC_HPLL_SR) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW3,
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv),
(wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) |
FW_WM(wm->sr.cursor, CURSOR_SR) |
FW_WM(wm->hpll.cursor, HPLL_CURSOR) |
FW_WM(wm->hpll.plane, HPLL_SR));
- intel_uncore_posting_read(&dev_priv->uncore, DSPFW1);
+ intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv));
}
#define FW_WM_VLV(value, plane) \
@@ -768,16 +770,16 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
intel_uncore_write(&dev_priv->uncore, DSPFW5, 0);
intel_uncore_write(&dev_priv->uncore, DSPFW6, 0);
- intel_uncore_write(&dev_priv->uncore, DSPFW1,
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
FW_WM(wm->sr.plane, SR) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) |
FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) |
FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW2,
+ intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv),
FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) |
FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW3,
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv),
FW_WM(wm->sr.cursor, CURSOR_SR));
if (IS_CHERRYVIEW(dev_priv)) {
@@ -815,7 +817,7 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI));
}
- intel_uncore_posting_read(&dev_priv->uncore, DSPFW1);
+ intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv));
}
#undef FW_WM_VLV
@@ -1787,7 +1789,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
switch (crtc->pipe) {
case PIPE_A:
- dsparb = intel_uncore_read_fw(uncore, DSPARB);
+ dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv));
dsparb2 = intel_uncore_read_fw(uncore, DSPARB2);
dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) |
@@ -1800,11 +1802,11 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) |
VLV_FIFO(SPRITEB_HI, sprite1_start >> 8));
- intel_uncore_write_fw(uncore, DSPARB, dsparb);
+ intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb);
intel_uncore_write_fw(uncore, DSPARB2, dsparb2);
break;
case PIPE_B:
- dsparb = intel_uncore_read_fw(uncore, DSPARB);
+ dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv));
dsparb2 = intel_uncore_read_fw(uncore, DSPARB2);
dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) |
@@ -1817,7 +1819,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) |
VLV_FIFO(SPRITED_HI, sprite1_start >> 8));
- intel_uncore_write_fw(uncore, DSPARB, dsparb);
+ intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb);
intel_uncore_write_fw(uncore, DSPARB2, dsparb2);
break;
case PIPE_C:
@@ -1841,7 +1843,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
break;
}
- intel_uncore_posting_read_fw(uncore, DSPARB);
+ intel_uncore_posting_read_fw(uncore, DSPARB(dev_priv));
spin_unlock(&uncore->lock);
}
@@ -2065,14 +2067,17 @@ static void i965_update_wm(struct drm_i915_private *dev_priv)
srwm);
/* 965 has limitations... */
- intel_uncore_write(&dev_priv->uncore, DSPFW1, FW_WM(srwm, SR) |
- FW_WM(8, CURSORB) |
- FW_WM(8, PLANEB) |
- FW_WM(8, PLANEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW2, FW_WM(8, CURSORA) |
- FW_WM(8, PLANEC_OLD));
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
+ FW_WM(srwm, SR) |
+ FW_WM(8, CURSORB) |
+ FW_WM(8, PLANEB) |
+ FW_WM(8, PLANEA));
+ intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv),
+ FW_WM(8, CURSORA) |
+ FW_WM(8, PLANEC_OLD));
/* update cursor SR watermark */
- intel_uncore_write(&dev_priv->uncore, DSPFW3, FW_WM(cursor_sr, CURSOR_SR));
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv),
+ FW_WM(cursor_sr, CURSOR_SR));
if (cxsr_enabled)
intel_set_memory_cxsr(dev_priv, true);
@@ -3519,13 +3524,13 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv,
{
u32 tmp;
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv));
wm->sr.plane = _FW_WM(tmp, SR);
wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB);
wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEB);
wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv));
wm->fbc_en = tmp & DSPFW_FBC_SR_EN;
wm->sr.fbc = _FW_WM(tmp, FBC_SR);
wm->hpll.fbc = _FW_WM(tmp, FBC_HPLL_SR);
@@ -3533,7 +3538,7 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv,
wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA);
wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM(tmp, SPRITEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
wm->hpll_en = tmp & DSPFW_HPLL_SR_EN;
wm->sr.cursor = _FW_WM(tmp, CURSOR_SR);
wm->hpll.cursor = _FW_WM(tmp, HPLL_CURSOR);
@@ -3559,18 +3564,18 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv,
(tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK);
}
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv));
wm->sr.plane = _FW_WM(tmp, SR);
wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB);
wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEB);
wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv));
wm->pipe[PIPE_A].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEB);
wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA);
wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
wm->sr.cursor = _FW_WM(tmp, CURSOR_SR);
if (IS_CHERRYVIEW(dev_priv)) {
@@ -4022,13 +4027,8 @@ void i9xx_wm_init(struct drm_i915_private *dev_priv)
g4x_setup_wm_latency(dev_priv);
dev_priv->display.funcs.wm = &g4x_wm_funcs;
} else if (IS_PINEVIEW(dev_priv)) {
- if (!intel_get_cxsr_latency(dev_priv)) {
- drm_info(&dev_priv->drm,
- "failed to find known CxSR latency "
- "(found ddr%s fsb freq %d, mem freq %d), "
- "disabling CxSR\n",
- (dev_priv->is_ddr3 == 1) ? "3" : "2",
- dev_priv->fsb_freq, dev_priv->mem_freq);
+ if (!pnv_get_cxsr_latency(dev_priv)) {
+ drm_info(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n");
/* Disable CxSR and never update its watermark again */
intel_set_memory_cxsr(dev_priv, false);
dev_priv->display.funcs.wm = &nop_funcs;
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 79ecfc339430..ae8f6617aa70 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -784,7 +784,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
if (intel_dsi->dual_link) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL2(dsi_trans),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL2(dev_priv, dsi_trans),
0, PORT_SYNC_MODE_ENABLE);
}
@@ -796,7 +797,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
dsi_trans = dsi_port_to_transcoder(port);
/* select data lane width */
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
tmp &= ~DDI_PORT_WIDTH_MASK;
tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count);
@@ -822,7 +824,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
/* enable DDI buffer */
tmp |= TRANS_DDI_FUNC_ENABLE;
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans), tmp);
+ intel_de_write(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans), tmp);
}
/* wait for link ready */
@@ -915,7 +918,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
/* program TRANS_HTOTAL register */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_HTOTAL(dsi_trans),
+ intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, dsi_trans),
HACTIVE(hactive - 1) | HTOTAL(htotal - 1));
}
@@ -938,7 +941,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_HSYNC(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_HSYNC(dev_priv, dsi_trans),
HSYNC_START(hsync_start - 1) | HSYNC_END(hsync_end - 1));
}
}
@@ -952,7 +956,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
* struct drm_display_mode.
* For interlace mode: program required pixel minus 2
*/
- intel_de_write(dev_priv, TRANS_VTOTAL(dsi_trans),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, dsi_trans),
VACTIVE(vactive - 1) | VTOTAL(vtotal - 1));
}
@@ -966,7 +970,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
if (is_vid_mode(intel_dsi)) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_VSYNC(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_VSYNC(dev_priv, dsi_trans),
VSYNC_START(vsync_start - 1) | VSYNC_END(vsync_end - 1));
}
}
@@ -980,7 +985,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
if (is_vid_mode(intel_dsi)) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_VSYNCSHIFT(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_VSYNCSHIFT(dev_priv, dsi_trans),
vsync_shift);
}
}
@@ -994,7 +1000,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
if (DISPLAY_VER(dev_priv) >= 12) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_VBLANK(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_VBLANK(dev_priv, dsi_trans),
VBLANK_START(vactive - 1) | VBLANK_END(vtotal - 1));
}
}
@@ -1009,10 +1016,11 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANSCONF(dsi_trans), 0, TRANSCONF_ENABLE);
+ intel_de_rmw(dev_priv, TRANSCONF(dev_priv, dsi_trans), 0,
+ TRANSCONF_ENABLE);
/* wait for transcoder to be enabled */
- if (intel_de_wait_for_set(dev_priv, TRANSCONF(dsi_trans),
+ if (intel_de_wait_for_set(dev_priv, TRANSCONF(dev_priv, dsi_trans),
TRANSCONF_STATE_ENABLE, 10))
drm_err(&dev_priv->drm,
"DSI transcoder not enabled\n");
@@ -1275,10 +1283,11 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
dsi_trans = dsi_port_to_transcoder(port);
/* disable transcoder */
- intel_de_rmw(dev_priv, TRANSCONF(dsi_trans), TRANSCONF_ENABLE, 0);
+ intel_de_rmw(dev_priv, TRANSCONF(dev_priv, dsi_trans),
+ TRANSCONF_ENABLE, 0);
/* wait for transcoder to be disabled */
- if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dsi_trans),
+ if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dev_priv, dsi_trans),
TRANSCONF_STATE_ENABLE, 50))
drm_err(&dev_priv->drm,
"DSI trancoder not disabled\n");
@@ -1327,7 +1336,8 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
/* disable ddi function */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans),
TRANS_DDI_FUNC_ENABLE, 0);
}
@@ -1335,7 +1345,8 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
if (intel_dsi->dual_link) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL2(dsi_trans),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL2(dev_priv, dsi_trans),
PORT_SYNC_MODE_ENABLE, 0);
}
}
@@ -1691,7 +1702,8 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
case TRANS_DDI_EDP_INPUT_A_ON:
*pipe = PIPE_A;
@@ -1710,7 +1722,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
goto out;
}
- tmp = intel_de_read(dev_priv, TRANSCONF(dsi_trans));
+ tmp = intel_de_read(dev_priv, TRANSCONF(dev_priv, dsi_trans));
ret = tmp & TRANSCONF_ENABLE;
}
out:
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
new file mode 100644
index 000000000000..866b3b409c4d
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2024, Intel Corporation.
+ */
+
+#include "intel_alpm.h"
+#include "intel_crtc.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_dp_aux.h"
+#include "intel_psr_regs.h"
+
+bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp)
+{
+ return intel_dp->alpm_dpcd & DP_ALPM_CAP;
+}
+
+bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp)
+{
+ return intel_dp->alpm_dpcd & DP_ALPM_AUX_LESS_CAP;
+}
+
+void intel_alpm_init_dpcd(struct intel_dp *intel_dp)
+{
+ u8 dpcd;
+
+ if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP, &dpcd) < 0)
+ return;
+
+ intel_dp->alpm_dpcd = dpcd;
+}
+
+/*
+ * See Bspec: 71632 for the table
+ *
+ * Silence_period = tSilence,Min + ((tSilence,Max - tSilence,Min) / 2)
+ *
+ * Half cycle duration:
+ *
+ * Link rates 1.62 - 4.32 and tLFPS_Cycle = 70 ns
+ * FLOOR( (Link Rate * tLFPS_Cycle) / (2 * 10) )
+ *
+ * Link rates 5.4 - 8.1
+ * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ] = 10
+ * LFPS Period chosen is the mid-point of the min:max values from the table
+ * FLOOR( LFPS Period in Symbol clocks /
+ * (2 * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ]) )
+ */
+static bool _lnl_get_silence_period_and_lfps_half_cycle(int link_rate,
+ int *silence_period,
+ int *lfps_half_cycle)
+{
+ switch (link_rate) {
+ case 162000:
+ *silence_period = 20;
+ *lfps_half_cycle = 5;
+ break;
+ case 216000:
+ *silence_period = 27;
+ *lfps_half_cycle = 7;
+ break;
+ case 243000:
+ *silence_period = 31;
+ *lfps_half_cycle = 8;
+ break;
+ case 270000:
+ *silence_period = 34;
+ *lfps_half_cycle = 9;
+ break;
+ case 324000:
+ *silence_period = 41;
+ *lfps_half_cycle = 11;
+ break;
+ case 432000:
+ *silence_period = 56;
+ *lfps_half_cycle = 15;
+ break;
+ case 540000:
+ *silence_period = 69;
+ *lfps_half_cycle = 12;
+ break;
+ case 648000:
+ *silence_period = 84;
+ *lfps_half_cycle = 15;
+ break;
+ case 675000:
+ *silence_period = 87;
+ *lfps_half_cycle = 15;
+ break;
+ case 810000:
+ *silence_period = 104;
+ *lfps_half_cycle = 19;
+ break;
+ default:
+ *silence_period = *lfps_half_cycle = -1;
+ return false;
+ }
+ return true;
+}
+
+/*
+ * AUX-Less Wake Time = CEILING( ((PHY P2 to P0) + tLFPS_Period, Max+
+ * tSilence, Max+ tPHY Establishment + tCDS) / tline)
+ * For the "PHY P2 to P0" latency see the PHY Power Control page
+ * (PHY P2 to P0) : https://gfxspecs.intel.com/Predator/Home/Index/68965
+ * : 12 us
+ * The tLFPS_Period, Max term is 800ns
+ * The tSilence, Max term is 180ns
+ * The tPHY Establishment (a.k.a. t1) term is 50us
+ * The tCDS term is 1 or 2 times t2
+ * t2 = Number ML_PHY_LOCK * tML_PHY_LOCK
+ * Number ML_PHY_LOCK = ( 7 + CEILING( 6.5us / tML_PHY_LOCK ) + 1)
+ * Rounding up the 6.5us padding to the next ML_PHY_LOCK boundary and
+ * adding the "+ 1" term ensures all ML_PHY_LOCK sequences that start
+ * within the CDS period complete within the CDS period regardless of
+ * entry into the period
+ * tML_PHY_LOCK = TPS4 Length * ( 10 / (Link Rate in MHz) )
+ * TPS4 Length = 252 Symbols
+ */
+static int _lnl_compute_aux_less_wake_time(int port_clock)
+{
+ int tphy2_p2_to_p0 = 12 * 1000;
+ int tlfps_period_max = 800;
+ int tsilence_max = 180;
+ int t1 = 50 * 1000;
+ int tps4 = 252;
+ /* port_clock is link rate in 10kbit/s units */
+ int tml_phy_lock = 1000 * 1000 * tps4 / port_clock;
+ int num_ml_phy_lock = 7 + DIV_ROUND_UP(6500, tml_phy_lock) + 1;
+ int t2 = num_ml_phy_lock * tml_phy_lock;
+ int tcds = 1 * t2;
+
+ return DIV_ROUND_UP(tphy2_p2_to_p0 + tlfps_period_max + tsilence_max +
+ t1 + tcds, 1000);
+}
+
+static int
+_lnl_compute_aux_less_alpm_params(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int aux_less_wake_time, aux_less_wake_lines, silence_period,
+ lfps_half_cycle;
+
+ aux_less_wake_time =
+ _lnl_compute_aux_less_wake_time(crtc_state->port_clock);
+ aux_less_wake_lines = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode,
+ aux_less_wake_time);
+
+ if (!_lnl_get_silence_period_and_lfps_half_cycle(crtc_state->port_clock,
+ &silence_period,
+ &lfps_half_cycle))
+ return false;
+
+ if (aux_less_wake_lines > ALPM_CTL_AUX_LESS_WAKE_TIME_MASK ||
+ silence_period > PORT_ALPM_CTL_SILENCE_PERIOD_MASK ||
+ lfps_half_cycle > PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK)
+ return false;
+
+ if (i915->display.params.psr_safest_params)
+ aux_less_wake_lines = ALPM_CTL_AUX_LESS_WAKE_TIME_MASK;
+
+ intel_dp->alpm_parameters.aux_less_wake_lines = aux_less_wake_lines;
+ intel_dp->alpm_parameters.silence_period_sym_clocks = silence_period;
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms = lfps_half_cycle;
+
+ return true;
+}
+
+static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int check_entry_lines;
+
+ if (DISPLAY_VER(i915) < 20)
+ return true;
+
+ /* ALPM Entry Check = 2 + CEILING( 5us /tline ) */
+ check_entry_lines = 2 +
+ intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5);
+
+ if (check_entry_lines > 15)
+ return false;
+
+ if (!_lnl_compute_aux_less_alpm_params(intel_dp, crtc_state))
+ return false;
+
+ if (i915->display.params.psr_safest_params)
+ check_entry_lines = 15;
+
+ intel_dp->alpm_parameters.check_entry_lines = check_entry_lines;
+
+ return true;
+}
+
+/*
+ * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There
+ * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are
+ * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us.
+ */
+static int skl_io_buffer_wake_time(void)
+{
+ return 18;
+}
+
+static int tgl_io_buffer_wake_time(void)
+{
+ return 10;
+}
+
+static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ if (DISPLAY_VER(i915) >= 12)
+ return tgl_io_buffer_wake_time();
+ else
+ return skl_io_buffer_wake_time();
+}
+
+bool intel_alpm_compute_params(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time;
+ int tfw_exit_latency = 20; /* eDP spec */
+ int phy_wake = 4; /* eDP spec */
+ int preamble = 8; /* eDP spec */
+ int precharge = intel_dp_aux_fw_sync_len() - preamble;
+ u8 max_wake_lines;
+
+ io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) +
+ preamble + phy_wake + tfw_exit_latency;
+ fast_wake_time = precharge + preamble + phy_wake +
+ tfw_exit_latency;
+
+ if (DISPLAY_VER(i915) >= 20)
+ max_wake_lines = 68;
+ else if (DISPLAY_VER(i915) >= 12)
+ max_wake_lines = 12;
+ else
+ max_wake_lines = 8;
+
+ io_wake_lines = intel_usecs_to_scanlines(
+ &crtc_state->hw.adjusted_mode, io_wake_time);
+ fast_wake_lines = intel_usecs_to_scanlines(
+ &crtc_state->hw.adjusted_mode, fast_wake_time);
+
+ if (io_wake_lines > max_wake_lines ||
+ fast_wake_lines > max_wake_lines)
+ return false;
+
+ if (!_lnl_compute_alpm_params(intel_dp, crtc_state))
+ return false;
+
+ if (i915->display.params.psr_safest_params)
+ io_wake_lines = fast_wake_lines = max_wake_lines;
+
+ /* According to Bspec lower limit should be set as 7 lines. */
+ intel_dp->alpm_parameters.io_wake_lines = max(io_wake_lines, 7);
+ intel_dp->alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7);
+
+ return true;
+}
+
+void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+ int waketime_in_lines, first_sdp_position;
+ int context_latency, guardband;
+
+ if (!intel_dp_is_edp(intel_dp))
+ return;
+
+ if (DISPLAY_VER(i915) < 20)
+ return;
+
+ if (!intel_dp_as_sdp_supported(intel_dp))
+ return;
+
+ if (crtc_state->has_psr)
+ return;
+
+ if (!(intel_alpm_aux_wake_supported(intel_dp) ||
+ intel_alpm_aux_less_wake_supported(intel_dp)))
+ return;
+
+ if (!intel_alpm_compute_params(intel_dp, crtc_state))
+ return;
+
+ context_latency = adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
+ guardband = adjusted_mode->crtc_vtotal -
+ adjusted_mode->crtc_vdisplay - context_latency;
+ first_sdp_position = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
+ if (intel_alpm_aux_less_wake_supported(intel_dp))
+ waketime_in_lines = intel_dp->alpm_parameters.io_wake_lines;
+ else
+ waketime_in_lines = intel_dp->alpm_parameters.aux_less_wake_lines;
+
+ crtc_state->has_lobf = (context_latency + guardband) >
+ (first_sdp_position + waketime_in_lines);
+}
+
+static void lnl_alpm_configure(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+ enum port port = dp_to_dig_port(intel_dp)->base.port;
+ u32 alpm_ctl;
+
+ if (DISPLAY_VER(dev_priv) < 20 || (!intel_dp->psr.sel_update_enabled &&
+ !intel_dp_is_edp(intel_dp)))
+ return;
+
+ /*
+ * Panel Replay on eDP is always using ALPM aux less. I.e. no need to
+ * check panel support at this point.
+ */
+ if ((intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) ||
+ (crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp))) {
+ alpm_ctl = ALPM_CTL_ALPM_ENABLE |
+ ALPM_CTL_ALPM_AUX_LESS_ENABLE |
+ ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS |
+ ALPM_CTL_AUX_LESS_WAKE_TIME(intel_dp->alpm_parameters.aux_less_wake_lines);
+
+ intel_de_write(dev_priv,
+ PORT_ALPM_CTL(dev_priv, port),
+ PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
+ PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
+ PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
+ PORT_ALPM_CTL_SILENCE_PERIOD(
+ intel_dp->alpm_parameters.silence_period_sym_clocks));
+
+ intel_de_write(dev_priv,
+ PORT_ALPM_LFPS_CTL(dev_priv, 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) |
+ PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
+ PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms));
+ } else {
+ alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
+ ALPM_CTL_EXTENDED_FAST_WAKE_TIME(intel_dp->alpm_parameters.fast_wake_lines);
+ }
+
+ if (crtc_state->has_lobf)
+ alpm_ctl |= ALPM_CTL_LOBF_ENABLE;
+
+ alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(intel_dp->alpm_parameters.check_entry_lines);
+
+ intel_de_write(dev_priv, ALPM_CTL(dev_priv, cpu_transcoder), alpm_ctl);
+}
+
+void intel_alpm_configure(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ lnl_alpm_configure(intel_dp, crtc_state);
+}
+
+static int i915_edp_lobf_info_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = m->private;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct drm_crtc *crtc;
+ struct intel_crtc_state *crtc_state;
+ enum transcoder cpu_transcoder;
+ u32 alpm_ctl;
+ int ret;
+
+ ret = drm_modeset_lock_single_interruptible(&dev_priv->drm.mode_config.connection_mutex);
+ if (ret)
+ return ret;
+
+ crtc = connector->base.state->crtc;
+ if (connector->base.status != connector_status_connected || !crtc) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ crtc_state = to_intel_crtc_state(crtc->state);
+ cpu_transcoder = crtc_state->cpu_transcoder;
+ alpm_ctl = intel_de_read(dev_priv, ALPM_CTL(dev_priv, cpu_transcoder));
+ seq_printf(m, "LOBF status: %s\n", str_enabled_disabled(alpm_ctl & ALPM_CTL_LOBF_ENABLE));
+ seq_printf(m, "Aux-wake alpm status: %s\n",
+ str_enabled_disabled(!(alpm_ctl & ALPM_CTL_ALPM_AUX_LESS_ENABLE)));
+ seq_printf(m, "Aux-less alpm status: %s\n",
+ str_enabled_disabled(alpm_ctl & ALPM_CTL_ALPM_AUX_LESS_ENABLE));
+out:
+ drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex);
+
+ return ret;
+}
+
+DEFINE_SHOW_ATTRIBUTE(i915_edp_lobf_info);
+
+void intel_alpm_lobf_debugfs_add(struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct dentry *root = connector->base.debugfs_entry;
+
+ if (DISPLAY_VER(i915) < 20 ||
+ connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
+ return;
+
+ debugfs_create_file("i915_edp_lobf_info", 0444, root,
+ connector, &i915_edp_lobf_info_fops);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.h b/drivers/gpu/drm/i915/display/intel_alpm.h
new file mode 100644
index 000000000000..8c409b10dce6
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_alpm.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef _INTEL_ALPM_H
+#define _INTEL_ALPM_H
+
+#include <linux/types.h>
+
+struct intel_dp;
+struct intel_crtc_state;
+struct drm_connector_state;
+struct intel_connector;
+
+void intel_alpm_init_dpcd(struct intel_dp *intel_dp);
+bool intel_alpm_compute_params(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state);
+void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state);
+void intel_alpm_configure(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state);
+void intel_alpm_lobf_debugfs_add(struct intel_connector *connector);
+bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp);
+bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp);
+#endif
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 7a77ae3dc394..76aa10b6f647 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -35,7 +35,6 @@
#include <drm/drm_fourcc.h>
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_cdclk.h"
#include "intel_display_types.h"
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 76d77d5a0409..e979786aa5cf 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -32,6 +32,7 @@
*/
#include <linux/dma-fence-chain.h>
+#include <linux/dma-resv.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -39,9 +40,10 @@
#include <drm/drm_fourcc.h>
#include "i915_config.h"
-#include "i915_reg.h"
+#include "i9xx_plane_regs.h"
#include "intel_atomic_plane.h"
#include "intel_cdclk.h"
+#include "intel_cursor.h"
#include "intel_display_rps.h"
#include "intel_display_trace.h"
#include "intel_display_types.h"
@@ -144,6 +146,14 @@ intel_plane_destroy_state(struct drm_plane *plane,
kfree(plane_state);
}
+bool intel_plane_needs_physical(struct intel_plane *plane)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
+ return plane->id == PLANE_CURSOR &&
+ DISPLAY_INFO(i915)->cursor_needs_physical;
+}
+
unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct drm_rect *dst,
unsigned int rate)
@@ -327,10 +337,10 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
intel_plane_clear_hw_state(plane_state);
/*
- * For the bigjoiner slave uapi.crtc will point at
- * the master crtc. So we explicitly assign the right
- * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
- * the plane is logically enabled on the uapi level.
+ * For the joiner secondary uapi.crtc will point at
+ * the primary crtc. So we explicitly assign the right
+ * secondary crtc to hw.crtc. uapi.crtc!=NULL simply
+ * indicates the plane is logically enabled on the uapi level.
*/
plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
@@ -429,10 +439,16 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
* In platforms after DISPLAY13, we might need to override
* first async flip in order to change watermark levels
* as part of optimization.
- * So for those, we are checking if this is a first async flip.
- * For platforms earlier than DISPLAY13 we always do async flip.
+ *
+ * And let's do this for all skl+ so that we can eg. change the
+ * modifier as well.
+ *
+ * TODO: For older platforms there is less reason to do this as
+ * only X-tile is supported with async flips, though we could
+ * extend this so other scanout parameters (stride/etc) could
+ * be changed as well...
*/
- return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
+ return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip;
}
static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
@@ -594,6 +610,17 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
new_crtc_state->do_async_flip = true;
new_crtc_state->async_flip_planes |= BIT(plane->id);
+ } else if (plane->need_async_flip_toggle_wa &&
+ new_crtc_state->uapi.async_flip) {
+ /*
+ * On platforms with double buffered async flip bit we
+ * set the bit already one frame early during the sync
+ * flip (see {i9xx,skl}_plane_update_arm()). The
+ * hardware will therefore be ready to perform a real
+ * async flip during the next commit, without having
+ * to wait yet another frame for the bit to latch.
+ */
+ new_crtc_state->async_flip_planes |= BIT(plane->id);
}
return 0;
@@ -688,27 +715,27 @@ int intel_plane_atomic_check(struct intel_atomic_state *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_master_plane_state;
+ const struct intel_plane_state *new_primary_crtc_plane_state;
struct intel_crtc *crtc = intel_crtc_for_pipe(i915, 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 =
intel_atomic_get_new_crtc_state(state, crtc);
- if (new_crtc_state && intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
- struct intel_crtc *master_crtc =
- intel_master_crtc(new_crtc_state);
- struct intel_plane *master_plane =
- intel_crtc_get_plane(master_crtc, plane->id);
+ if (new_crtc_state && intel_crtc_is_joiner_secondary(new_crtc_state)) {
+ struct intel_crtc *primary_crtc =
+ intel_primary_crtc(new_crtc_state);
+ struct intel_plane *primary_crtc_plane =
+ intel_crtc_get_plane(primary_crtc, plane->id);
- new_master_plane_state =
- intel_atomic_get_new_plane_state(state, master_plane);
+ new_primary_crtc_plane_state =
+ intel_atomic_get_new_plane_state(state, primary_crtc_plane);
} else {
- new_master_plane_state = new_plane_state;
+ new_primary_crtc_plane_state = new_plane_state;
}
intel_plane_copy_uapi_to_hw_state(new_plane_state,
- new_master_plane_state,
+ new_primary_crtc_plane_state,
crtc);
new_plane_state->uapi.visible = false;
@@ -775,18 +802,30 @@ void intel_plane_update_noarm(struct intel_plane *plane,
plane->update_noarm(plane, crtc_state, plane_state);
}
+void intel_plane_async_flip(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *plane_state,
+ bool async_flip)
+{
+ 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);
+}
+
void intel_plane_update_arm(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);
- trace_intel_plane_update_arm(plane, crtc);
+ if (crtc_state->do_async_flip && plane->async_flip) {
+ intel_plane_async_flip(plane, crtc_state, plane_state, true);
+ return;
+ }
- if (crtc_state->do_async_flip && plane->async_flip)
- plane->async_flip(plane, crtc_state, plane_state, true);
- else
- plane->update_arm(plane, crtc_state, plane_state);
+ trace_intel_plane_update_arm(plane, crtc);
+ plane->update_arm(plane, crtc_state, plane_state);
}
void intel_plane_disable_arm(struct intel_plane *plane,
@@ -1163,7 +1202,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
intel_display_rps_mark_interactive(dev_priv, state, false);
- /* Should only be called after a successful intel_prepare_plane_fb()! */
intel_plane_unpin_fb(old_plane_state);
}
@@ -1176,3 +1214,14 @@ void intel_plane_helper_add(struct intel_plane *plane)
{
drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
}
+
+void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
+ struct intel_plane_state *new_plane_state)
+{
+ if (!old_plane_state->ggtt_vma ||
+ old_plane_state->ggtt_vma == new_plane_state->ggtt_vma)
+ return;
+
+ drm_vblank_work_init(&old_plane_state->unpin_work, old_plane_state->uapi.crtc,
+ intel_cursor_unpin_work);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 191dad0efc8e..6c4fe3596465 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -32,6 +32,10 @@ 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,
+ 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,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
@@ -66,5 +70,8 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
void intel_plane_helper_add(struct intel_plane *plane);
+bool intel_plane_needs_physical(struct intel_plane *plane);
+void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
+ struct intel_plane_state *new_plane_state);
#endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 40e7d862675e..b9bafec06fb8 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -26,7 +26,7 @@
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
-#include <drm/i915_component.h>
+#include <drm/intel/i915_component.h>
#include "i915_drv.h"
#include "intel_atomic.h"
@@ -183,6 +183,15 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
{ 192000, TMDS_445_5M, 20480, 371250 },
};
+/*
+ * WA_14020863754: Implement Audio Workaround
+ * Corner case with Min Hblank Fix can cause audio hang
+ */
+static bool needs_wa_14020863754(struct drm_i915_private *i915)
+{
+ return (DISPLAY_VER(i915) == 20 || IS_BATTLEMAGE(i915));
+}
+
/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
{
@@ -415,6 +424,9 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder,
intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0);
+ if (needs_wa_14020863754(i915))
+ intel_de_rmw(i915, AUD_CHICKENBIT_REG3, DACBE_DISABLE_MIN_HBLANK_FIX, 0);
+
mutex_unlock(&i915->display.audio.mutex);
}
@@ -540,6 +552,9 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP))
enable_audio_dsc_wa(encoder, crtc_state);
+ if (needs_wa_14020863754(i915))
+ intel_de_rmw(i915, AUD_CHICKENBIT_REG3, 0, DACBE_DISABLE_MIN_HBLANK_FIX);
+
/* Enable audio presence detect */
intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
0, AUDIO_OUTPUT_ENABLE(cpu_transcoder));
diff --git a/drivers/gpu/drm/i915/display/intel_audio_regs.h b/drivers/gpu/drm/i915/display/intel_audio_regs.h
index 88ea2740365d..4c31844d21df 100644
--- a/drivers/gpu/drm/i915/display/intel_audio_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_audio_regs.h
@@ -164,4 +164,7 @@
_VLV_AUD_PORT_EN_D_DBG)
#define VLV_AMP_MUTE (1 << 1)
+#define AUD_CHICKENBIT_REG3 _MMIO(0x65F1C)
+#define DACBE_DISABLE_MIN_HBLANK_FIX REG_BIT(18)
+
#endif /* __INTEL_AUDIO_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 5fb48b6129b6..ec1e3a380360 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -36,6 +36,7 @@
#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"
@@ -170,22 +171,22 @@ static const struct {
.min_size = sizeof(struct bdb_driver_features), },
{ .section_id = BDB_SDVO_LVDS_OPTIONS,
.min_size = sizeof(struct bdb_sdvo_lvds_options), },
- { .section_id = BDB_SDVO_PANEL_DTDS,
- .min_size = sizeof(struct bdb_sdvo_panel_dtds), },
+ { .section_id = BDB_SDVO_LVDS_DTD,
+ .min_size = sizeof(struct bdb_sdvo_lvds_dtd), },
{ .section_id = BDB_EDP,
.min_size = sizeof(struct bdb_edp), },
- { .section_id = BDB_LVDS_OPTIONS,
- .min_size = sizeof(struct bdb_lvds_options), },
+ { .section_id = BDB_LFP_OPTIONS,
+ .min_size = sizeof(struct bdb_lfp_options), },
/*
- * BDB_LVDS_LFP_DATA depends on BDB_LVDS_LFP_DATA_PTRS,
+ * BDB_LFP_DATA depends on BDB_LFP_DATA_PTRS,
* so keep the two ordered.
*/
- { .section_id = BDB_LVDS_LFP_DATA_PTRS,
- .min_size = sizeof(struct bdb_lvds_lfp_data_ptrs), },
- { .section_id = BDB_LVDS_LFP_DATA,
+ { .section_id = BDB_LFP_DATA_PTRS,
+ .min_size = sizeof(struct bdb_lfp_data_ptrs), },
+ { .section_id = BDB_LFP_DATA,
.min_size = 0, /* special case */ },
- { .section_id = BDB_LVDS_BACKLIGHT,
- .min_size = sizeof(struct bdb_lfp_backlight_data), },
+ { .section_id = BDB_LFP_BACKLIGHT,
+ .min_size = sizeof(struct bdb_lfp_backlight), },
{ .section_id = BDB_LFP_POWER,
.min_size = sizeof(struct bdb_lfp_power), },
{ .section_id = BDB_MIPI_CONFIG,
@@ -200,30 +201,30 @@ static const struct {
static size_t lfp_data_min_size(struct drm_i915_private *i915)
{
- const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ const struct bdb_lfp_data_ptrs *ptrs;
size_t size;
- ptrs = bdb_find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ ptrs = bdb_find_section(i915, BDB_LFP_DATA_PTRS);
if (!ptrs)
return 0;
- size = sizeof(struct bdb_lvds_lfp_data);
+ size = sizeof(struct bdb_lfp_data);
if (ptrs->panel_name.table_size)
size = max(size, ptrs->panel_name.offset +
- sizeof(struct bdb_lvds_lfp_data_tail));
+ sizeof(struct bdb_lfp_data_tail));
return size;
}
static bool validate_lfp_data_ptrs(const void *bdb,
- const struct bdb_lvds_lfp_data_ptrs *ptrs)
+ const struct bdb_lfp_data_ptrs *ptrs)
{
int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
int data_block_size, lfp_data_size;
const void *data_block;
int i;
- data_block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
+ data_block = find_raw_section(bdb, BDB_LFP_DATA);
if (!data_block)
return false;
@@ -232,7 +233,7 @@ static bool validate_lfp_data_ptrs(const void *bdb,
return false;
/* always 3 indicating the presence of fp_timing+dvo_timing+panel_pnp_id */
- if (ptrs->lvds_entries != 3)
+ if (ptrs->num_entries != 3)
return false;
fp_timing_size = ptrs->ptr[0].fp_timing.table_size;
@@ -242,13 +243,13 @@ static bool validate_lfp_data_ptrs(const void *bdb,
/* fp_timing has variable size */
if (fp_timing_size < 32 ||
- dvo_timing_size != sizeof(struct lvds_dvo_timing) ||
- panel_pnp_id_size != sizeof(struct lvds_pnp_id))
+ dvo_timing_size != sizeof(struct bdb_edid_dtd) ||
+ panel_pnp_id_size != sizeof(struct bdb_edid_pnp_id))
return false;
/* panel_name is not present in old VBTs */
if (panel_name_size != 0 &&
- panel_name_size != sizeof(struct lvds_lfp_panel_name))
+ panel_name_size != sizeof(struct bdb_edid_product_name))
return false;
lfp_data_size = ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
@@ -311,11 +312,11 @@ static bool validate_lfp_data_ptrs(const void *bdb,
/* make the data table offsets relative to the data block */
static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
{
- struct bdb_lvds_lfp_data_ptrs *ptrs = ptrs_block;
+ struct bdb_lfp_data_ptrs *ptrs = ptrs_block;
u32 offset;
int i;
- offset = raw_block_offset(bdb, BDB_LVDS_LFP_DATA);
+ offset = raw_block_offset(bdb, BDB_LFP_DATA);
for (i = 0; i < 16; i++) {
if (ptrs->ptr[i].fp_timing.offset < offset ||
@@ -338,7 +339,7 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
return validate_lfp_data_ptrs(bdb, ptrs);
}
-static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
+static int make_lfp_data_ptr(struct lfp_data_ptr_table *table,
int table_size, int total_size)
{
if (total_size < table_size)
@@ -350,8 +351,8 @@ static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
return total_size - table_size;
}
-static void next_lfp_data_ptr(struct lvds_lfp_data_ptr_table *next,
- const struct lvds_lfp_data_ptr_table *prev,
+static void next_lfp_data_ptr(struct lfp_data_ptr_table *next,
+ const struct lfp_data_ptr_table *prev,
int size)
{
next->table_size = prev->table_size;
@@ -362,7 +363,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
const void *bdb)
{
int i, size, table_size, block_size, offset, fp_timing_size;
- struct bdb_lvds_lfp_data_ptrs *ptrs;
+ struct bdb_lfp_data_ptrs *ptrs;
const void *block;
void *ptrs_block;
@@ -377,7 +378,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
fp_timing_size = 38;
- block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
+ block = find_raw_section(bdb, BDB_LFP_DATA);
if (!block)
return NULL;
@@ -385,8 +386,8 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
block_size = get_blocksize(block);
- size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
- sizeof(struct lvds_pnp_id);
+ size = fp_timing_size + sizeof(struct bdb_edid_dtd) +
+ sizeof(struct bdb_edid_pnp_id);
if (size * 16 > block_size)
return NULL;
@@ -394,40 +395,40 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
if (!ptrs_block)
return NULL;
- *(u8 *)(ptrs_block + 0) = BDB_LVDS_LFP_DATA_PTRS;
+ *(u8 *)(ptrs_block + 0) = BDB_LFP_DATA_PTRS;
*(u16 *)(ptrs_block + 1) = sizeof(*ptrs);
ptrs = ptrs_block + 3;
- table_size = sizeof(struct lvds_pnp_id);
+ table_size = sizeof(struct bdb_edid_pnp_id);
size = make_lfp_data_ptr(&ptrs->ptr[0].panel_pnp_id, table_size, size);
- table_size = sizeof(struct lvds_dvo_timing);
+ table_size = sizeof(struct bdb_edid_dtd);
size = make_lfp_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
table_size = fp_timing_size;
size = make_lfp_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
if (ptrs->ptr[0].fp_timing.table_size)
- ptrs->lvds_entries++;
+ ptrs->num_entries++;
if (ptrs->ptr[0].dvo_timing.table_size)
- ptrs->lvds_entries++;
+ ptrs->num_entries++;
if (ptrs->ptr[0].panel_pnp_id.table_size)
- ptrs->lvds_entries++;
+ ptrs->num_entries++;
- if (size != 0 || ptrs->lvds_entries != 3) {
+ if (size != 0 || ptrs->num_entries != 3) {
kfree(ptrs_block);
return NULL;
}
- size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
- sizeof(struct lvds_pnp_id);
+ size = fp_timing_size + sizeof(struct bdb_edid_dtd) +
+ sizeof(struct bdb_edid_pnp_id);
for (i = 1; i < 16; i++) {
next_lfp_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
next_lfp_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
next_lfp_data_ptr(&ptrs->ptr[i].panel_pnp_id, &ptrs->ptr[i-1].panel_pnp_id, size);
}
- table_size = sizeof(struct lvds_lfp_panel_name);
+ table_size = sizeof(struct bdb_edid_product_name);
if (16 * (size + table_size) <= block_size) {
ptrs->panel_name.table_size = table_size;
@@ -461,7 +462,7 @@ init_bdb_block(struct drm_i915_private *i915,
block = find_raw_section(bdb, section_id);
/* Modern VBTs lack the LFP data table pointers block, make one up */
- if (!block && section_id == BDB_LVDS_LFP_DATA_PTRS) {
+ if (!block && section_id == BDB_LFP_DATA_PTRS) {
temp_block = generate_lfp_data_ptrs(i915, bdb);
if (temp_block)
block = temp_block + 3;
@@ -496,7 +497,7 @@ init_bdb_block(struct drm_i915_private *i915,
drm_dbg_kms(&i915->drm, "Found BDB block %d (size %zu, min size %zu)\n",
section_id, block_size, min_size);
- if (section_id == BDB_LVDS_LFP_DATA_PTRS &&
+ if (section_id == BDB_LFP_DATA_PTRS &&
!fixup_lfp_data_ptrs(bdb, entry->data + 3)) {
drm_err(&i915->drm, "VBT has malformed LFP data table pointers\n");
kfree(entry);
@@ -515,7 +516,7 @@ static void init_bdb_blocks(struct drm_i915_private *i915,
enum bdb_block_id section_id = bdb_blocks[i].section_id;
size_t min_size = bdb_blocks[i].min_size;
- if (section_id == BDB_LVDS_LFP_DATA)
+ if (section_id == BDB_LFP_DATA)
min_size = lfp_data_min_size(i915);
init_bdb_block(i915, bdb, section_id, min_size);
@@ -525,7 +526,7 @@ static void init_bdb_blocks(struct drm_i915_private *i915,
static void
fill_detail_timing_data(struct drm_i915_private *i915,
struct drm_display_mode *panel_fixed_mode,
- const struct lvds_dvo_timing *dvo_timing)
+ const struct bdb_edid_dtd *dvo_timing)
{
panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
dvo_timing->hactive_lo;
@@ -579,36 +580,36 @@ fill_detail_timing_data(struct drm_i915_private *i915,
drm_mode_set_name(panel_fixed_mode);
}
-static const struct lvds_dvo_timing *
-get_lvds_dvo_timing(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs,
- int index)
+static const struct bdb_edid_dtd *
+get_lfp_dvo_timing(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs,
+ int index)
{
return (const void *)data + ptrs->ptr[index].dvo_timing.offset;
}
-static const struct lvds_fp_timing *
-get_lvds_fp_timing(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs,
- int index)
+static const struct fp_timing *
+get_lfp_fp_timing(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs,
+ int index)
{
return (const void *)data + ptrs->ptr[index].fp_timing.offset;
}
static const struct drm_edid_product_id *
-get_lvds_pnp_id(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs,
- int index)
+get_lfp_pnp_id(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs,
+ int index)
{
/* These two are supposed to have the same layout in memory. */
- BUILD_BUG_ON(sizeof(struct lvds_pnp_id) != sizeof(struct drm_edid_product_id));
+ BUILD_BUG_ON(sizeof(struct bdb_edid_pnp_id) != sizeof(struct drm_edid_product_id));
return (const void *)data + ptrs->ptr[index].panel_pnp_id.offset;
}
-static const struct bdb_lvds_lfp_data_tail *
-get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs)
+static const struct bdb_lfp_data_tail *
+get_lfp_data_tail(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs)
{
if (ptrs->panel_name.table_size)
return (const void *)data + ptrs->panel_name.offset;
@@ -627,33 +628,33 @@ static int vbt_get_panel_type(struct drm_i915_private *i915,
const struct intel_bios_encoder_data *devdata,
const struct drm_edid *drm_edid, bool use_fallback)
{
- const struct bdb_lvds_options *lvds_options;
+ const struct bdb_lfp_options *lfp_options;
- lvds_options = bdb_find_section(i915, BDB_LVDS_OPTIONS);
- if (!lvds_options)
+ lfp_options = bdb_find_section(i915, BDB_LFP_OPTIONS);
+ if (!lfp_options)
return -1;
- if (lvds_options->panel_type > 0xf &&
- lvds_options->panel_type != 0xff) {
+ if (lfp_options->panel_type > 0xf &&
+ lfp_options->panel_type != 0xff) {
drm_dbg_kms(&i915->drm, "Invalid VBT panel type 0x%x\n",
- lvds_options->panel_type);
+ lfp_options->panel_type);
return -1;
}
if (devdata && devdata->child.handle == DEVICE_HANDLE_LFP2)
- return lvds_options->panel_type2;
+ return lfp_options->panel_type2;
drm_WARN_ON(&i915->drm, devdata && devdata->child.handle != DEVICE_HANDLE_LFP1);
- return lvds_options->panel_type;
+ return lfp_options->panel_type;
}
static int pnpid_get_panel_type(struct drm_i915_private *i915,
const struct intel_bios_encoder_data *devdata,
const struct drm_edid *drm_edid, bool use_fallback)
{
- const struct bdb_lvds_lfp_data *data;
- const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ const struct bdb_lfp_data *data;
+ const struct bdb_lfp_data_ptrs *ptrs;
struct drm_edid_product_id product_id, product_id_nodate;
struct drm_printer p;
int i, best = -1;
@@ -670,17 +671,17 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, "EDID");
drm_edid_print_product_id(&p, &product_id, true);
- ptrs = bdb_find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ ptrs = bdb_find_section(i915, BDB_LFP_DATA_PTRS);
if (!ptrs)
return -1;
- data = bdb_find_section(i915, BDB_LVDS_LFP_DATA);
+ data = bdb_find_section(i915, BDB_LFP_DATA);
if (!data)
return -1;
for (i = 0; i < 16; i++) {
const struct drm_edid_product_id *vbt_id =
- get_lvds_pnp_id(data, ptrs, i);
+ get_lfp_pnp_id(data, ptrs, i);
/* full match? */
if (!memcmp(vbt_id, &product_id, sizeof(*vbt_id)))
@@ -786,25 +787,25 @@ static void
parse_panel_options(struct drm_i915_private *i915,
struct intel_panel *panel)
{
- const struct bdb_lvds_options *lvds_options;
+ const struct bdb_lfp_options *lfp_options;
int panel_type = panel->vbt.panel_type;
int drrs_mode;
- lvds_options = bdb_find_section(i915, BDB_LVDS_OPTIONS);
- if (!lvds_options)
+ lfp_options = bdb_find_section(i915, BDB_LFP_OPTIONS);
+ if (!lfp_options)
return;
- panel->vbt.lvds_dither = lvds_options->pixel_dither;
+ panel->vbt.lvds_dither = lfp_options->pixel_dither;
/*
* Empirical evidence indicates the block size can be
* either 4,14,16,24+ bytes. For older VBTs no clear
* relationship between the block size vs. BDB version.
*/
- if (get_blocksize(lvds_options) < 16)
+ if (get_blocksize(lfp_options) < 16)
return;
- drrs_mode = panel_bits(lvds_options->dps_panel_type_bits,
+ drrs_mode = panel_bits(lfp_options->dps_panel_type_bits,
panel_type, 2);
/*
* VBT has static DRRS = 0 and seamless DRRS = 2.
@@ -832,17 +833,17 @@ parse_panel_options(struct drm_i915_private *i915,
static void
parse_lfp_panel_dtd(struct drm_i915_private *i915,
struct intel_panel *panel,
- const struct bdb_lvds_lfp_data *lvds_lfp_data,
- const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs)
+ const struct bdb_lfp_data *lfp_data,
+ const struct bdb_lfp_data_ptrs *lfp_data_ptrs)
{
- const struct lvds_dvo_timing *panel_dvo_timing;
- const struct lvds_fp_timing *fp_timing;
+ const struct bdb_edid_dtd *panel_dvo_timing;
+ const struct fp_timing *fp_timing;
struct drm_display_mode *panel_fixed_mode;
int panel_type = panel->vbt.panel_type;
- panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
- lvds_lfp_data_ptrs,
- panel_type);
+ panel_dvo_timing = get_lfp_dvo_timing(lfp_data,
+ lfp_data_ptrs,
+ panel_type);
panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
if (!panel_fixed_mode)
@@ -850,15 +851,15 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915,
fill_detail_timing_data(i915, panel_fixed_mode, panel_dvo_timing);
- panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+ panel->vbt.lfp_vbt_mode = panel_fixed_mode;
drm_dbg_kms(&i915->drm,
"Found panel mode in BIOS VBT legacy lfp table: " DRM_MODE_FMT "\n",
DRM_MODE_ARG(panel_fixed_mode));
- fp_timing = get_lvds_fp_timing(lvds_lfp_data,
- lvds_lfp_data_ptrs,
- panel_type);
+ fp_timing = get_lfp_fp_timing(lfp_data,
+ lfp_data_ptrs,
+ panel_type);
/* check the resolution, just to be sure */
if (fp_timing->x_res == panel_fixed_mode->hdisplay &&
@@ -874,25 +875,25 @@ static void
parse_lfp_data(struct drm_i915_private *i915,
struct intel_panel *panel)
{
- const struct bdb_lvds_lfp_data *data;
- const struct bdb_lvds_lfp_data_tail *tail;
- const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ const struct bdb_lfp_data *data;
+ const struct bdb_lfp_data_tail *tail;
+ const struct bdb_lfp_data_ptrs *ptrs;
const struct drm_edid_product_id *pnp_id;
struct drm_printer p;
int panel_type = panel->vbt.panel_type;
- ptrs = bdb_find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ ptrs = bdb_find_section(i915, BDB_LFP_DATA_PTRS);
if (!ptrs)
return;
- data = bdb_find_section(i915, BDB_LVDS_LFP_DATA);
+ data = bdb_find_section(i915, BDB_LFP_DATA);
if (!data)
return;
- if (!panel->vbt.lfp_lvds_vbt_mode)
+ if (!panel->vbt.lfp_vbt_mode)
parse_lfp_panel_dtd(i915, panel, data, ptrs);
- pnp_id = get_lvds_pnp_id(data, ptrs, panel_type);
+ pnp_id = get_lfp_pnp_id(data, ptrs, panel_type);
p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, "Panel");
drm_edid_print_product_id(&p, pnp_id, false);
@@ -1001,19 +1002,19 @@ parse_generic_dtd(struct drm_i915_private *i915,
"Found panel mode in BIOS VBT generic dtd table: " DRM_MODE_FMT "\n",
DRM_MODE_ARG(panel_fixed_mode));
- panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+ panel->vbt.lfp_vbt_mode = panel_fixed_mode;
}
static void
parse_lfp_backlight(struct drm_i915_private *i915,
struct intel_panel *panel)
{
- const struct bdb_lfp_backlight_data *backlight_data;
+ const struct bdb_lfp_backlight *backlight_data;
const struct lfp_backlight_data_entry *entry;
int panel_type = panel->vbt.panel_type;
u16 level;
- backlight_data = bdb_find_section(i915, BDB_LVDS_BACKLIGHT);
+ backlight_data = bdb_find_section(i915, BDB_LFP_BACKLIGHT);
if (!backlight_data)
return;
@@ -1091,19 +1092,18 @@ parse_lfp_backlight(struct drm_i915_private *i915,
panel->vbt.backlight.controller);
}
-/* Try to find sdvo panel data */
static void
-parse_sdvo_panel_data(struct drm_i915_private *i915,
- struct intel_panel *panel)
+parse_sdvo_lvds_data(struct drm_i915_private *i915,
+ struct intel_panel *panel)
{
- const struct bdb_sdvo_panel_dtds *dtds;
+ const struct bdb_sdvo_lvds_dtd *dtd;
struct drm_display_mode *panel_fixed_mode;
int index;
index = i915->display.params.vbt_sdvo_panel_type;
if (index == -2) {
drm_dbg_kms(&i915->drm,
- "Ignore SDVO panel mode from BIOS VBT tables.\n");
+ "Ignore SDVO LVDS mode from BIOS VBT tables.\n");
return;
}
@@ -1117,20 +1117,32 @@ parse_sdvo_panel_data(struct drm_i915_private *i915,
index = sdvo_lvds_options->panel_type;
}
- dtds = bdb_find_section(i915, BDB_SDVO_PANEL_DTDS);
- if (!dtds)
+ dtd = bdb_find_section(i915, BDB_SDVO_LVDS_DTD);
+ if (!dtd)
return;
+ /*
+ * This should not happen, as long as the panel_type
+ * enumeration doesn't grow over 4 items. But if it does, it
+ * could lead to hard-to-detect bugs, so better double-check
+ * it here to be sure.
+ */
+ if (index >= ARRAY_SIZE(dtd->dtd)) {
+ drm_err(&i915->drm, "index %d is larger than dtd->dtd[4] array\n",
+ index);
+ return;
+ }
+
panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
if (!panel_fixed_mode)
return;
- fill_detail_timing_data(i915, panel_fixed_mode, &dtds->dtds[index]);
+ fill_detail_timing_data(i915, panel_fixed_mode, &dtd->dtd[index]);
panel->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode;
drm_dbg_kms(&i915->drm,
- "Found SDVO panel mode in BIOS VBT tables: " DRM_MODE_FMT "\n",
+ "Found SDVO LVDS mode in BIOS VBT tables: " DRM_MODE_FMT "\n",
DRM_MODE_ARG(panel_fixed_mode));
}
@@ -1513,6 +1525,10 @@ parse_edp(struct drm_i915_private *i915,
if (i915->display.vbt.version >= 244)
panel->vbt.edp.max_link_rate =
edp->edp_max_port_link_rate[panel_type] * 20;
+
+ if (i915->display.vbt.version >= 251)
+ panel->vbt.edp.dsc_disable =
+ panel_bool(edp->edp_dsc_disable, panel_type);
}
static void
@@ -1677,7 +1693,7 @@ parse_mipi_config(struct drm_i915_private *i915,
panel->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
/* Block #40 is already parsed and panel_fixed_mode is
- * stored in i915->lfp_lvds_vbt_mode
+ * stored in i915->lfp_vbt_mode
* resuse this when needed
*/
@@ -2220,15 +2236,14 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
const u8 *ddc_pin_map;
int i, n_entries;
- if (IS_DGFX(i915))
- return vbt_pin;
-
if (INTEL_PCH_TYPE(i915) >= PCH_MTL || IS_ALDERLAKE_P(i915)) {
ddc_pin_map = adlp_ddc_pin_map;
n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
} else if (IS_ALDERLAKE_S(i915)) {
ddc_pin_map = adls_ddc_pin_map;
n_entries = ARRAY_SIZE(adls_ddc_pin_map);
+ } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
+ return vbt_pin;
} else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) {
ddc_pin_map = rkl_pch_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map);
@@ -3258,7 +3273,7 @@ static void intel_bios_init_panel(struct drm_i915_private *i915,
parse_generic_dtd(i915, panel);
parse_lfp_data(i915, panel);
parse_lfp_backlight(i915, panel);
- parse_sdvo_panel_data(i915, panel);
+ parse_sdvo_lvds_data(i915, panel);
parse_panel_driver_features(i915, panel);
parse_power_conservation_features(i915, panel);
parse_edp(i915, panel);
@@ -3307,8 +3322,8 @@ void intel_bios_fini_panel(struct intel_panel *panel)
{
kfree(panel->vbt.sdvo_lvds_vbt_mode);
panel->vbt.sdvo_lvds_vbt_mode = NULL;
- kfree(panel->vbt.lfp_lvds_vbt_mode);
- panel->vbt.lfp_lvds_vbt_mode = NULL;
+ kfree(panel->vbt.lfp_vbt_mode);
+ panel->vbt.lfp_vbt_mode = NULL;
kfree(panel->vbt.dsi.data);
panel->vbt.dsi.data = NULL;
kfree(panel->vbt.dsi.pps);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 972ea887e232..47036d4abb33 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -22,6 +22,8 @@ struct intel_qgv_point {
u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd;
};
+#define DEPROGBWPCLIMIT 60
+
struct intel_psf_gv_point {
u8 clk; /* clock in multiples of 16.6666 MHz */
};
@@ -241,6 +243,9 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
qi->channel_width = 16;
qi->deinterleave = 4;
break;
+ case INTEL_DRAM_GDDR:
+ qi->channel_width = 32;
+ break;
default:
MISSING_CASE(dram_info->type);
return -EINVAL;
@@ -387,6 +392,12 @@ static const struct intel_sa_info mtl_sa_info = {
.derating = 10,
};
+static const struct intel_sa_info xe2_hpd_sa_info = {
+ .derating = 30,
+ .deprogbwlimit = 53,
+ /* Other values not used by simplified algorithm */
+};
+
static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa)
{
struct intel_qgv_info qi = {};
@@ -493,7 +504,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
dclk_max = icl_sagv_max_dclk(&qi);
peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max;
- maxdebw = min(sa->deprogbwlimit * 1000, peakbw * 6 / 10); /* 60% */
+ maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100);
ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
/*
@@ -598,6 +609,54 @@ static void dg2_get_bw_info(struct drm_i915_private *i915)
i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
}
+static int xe2_hpd_get_bw_info(struct drm_i915_private *i915,
+ const struct intel_sa_info *sa)
+{
+ struct intel_qgv_info qi = {};
+ int num_channels = i915->dram_info.num_channels;
+ int peakbw, maxdebw;
+ int ret, i;
+
+ ret = icl_get_qgv_points(i915, &qi, true);
+ if (ret) {
+ drm_dbg_kms(&i915->drm,
+ "Failed to get memory subsystem information, ignoring bandwidth limits");
+ return ret;
+ }
+
+ peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi);
+ maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 10);
+
+ for (i = 0; i < qi.num_points; i++) {
+ const struct intel_qgv_point *point = &qi.points[i];
+ int bw = num_channels * (qi.channel_width / 8) * point->dclk;
+
+ i915->display.bw.max[0].deratedbw[i] =
+ min(maxdebw, (100 - sa->derating) * bw / 100);
+ i915->display.bw.max[0].peakbw[i] = bw;
+
+ drm_dbg_kms(&i915->drm, "QGV %d: deratedbw=%u peakbw: %u\n",
+ i, i915->display.bw.max[0].deratedbw[i],
+ i915->display.bw.max[0].peakbw[i]);
+ }
+
+ /* Bandwidth does not depend on # of planes; set all groups the same */
+ i915->display.bw.max[0].num_planes = 1;
+ i915->display.bw.max[0].num_qgv_points = qi.num_points;
+ for (i = 1; i < ARRAY_SIZE(i915->display.bw.max); i++)
+ memcpy(&i915->display.bw.max[i], &i915->display.bw.max[0],
+ sizeof(i915->display.bw.max[0]));
+
+ /*
+ * Xe2_HPD should always have exactly two QGV points representing
+ * battery and plugged-in operation.
+ */
+ drm_WARN_ON(&i915->drm, qi.num_points != 2);
+ i915->display.sagv.status = I915_SAGV_ENABLED;
+
+ return 0;
+}
+
static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv,
int num_planes, int qgv_point)
{
@@ -684,7 +743,9 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
- if (DISPLAY_VER(dev_priv) >= 14)
+ if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1) && IS_DGFX(dev_priv))
+ xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_sa_info);
+ else if (DISPLAY_VER(dev_priv) >= 14)
tgl_get_bw_info(dev_priv, &mtl_sa_info);
else if (IS_DG2(dev_priv))
dg2_get_bw_info(dev_priv);
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 7a833b5f2de2..16d5550f7e5e 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -23,6 +23,7 @@
#include <linux/time.h>
+#include "soc/intel_dram.h"
#include "hsw_ips.h"
#include "i915_reg.h"
#include "intel_atomic.h"
@@ -113,7 +114,7 @@ struct intel_cdclk_funcs {
void (*set_cdclk)(struct drm_i915_private *i915,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe);
- int (*modeset_calc_cdclk)(struct intel_cdclk_state *state);
+ int (*modeset_calc_cdclk)(struct intel_atomic_state *state);
u8 (*calc_voltage_level)(int cdclk);
};
@@ -130,10 +131,11 @@ static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv,
dev_priv->display.funcs.cdclk->set_cdclk(dev_priv, cdclk_config, pipe);
}
-static int intel_cdclk_modeset_calc_cdclk(struct drm_i915_private *dev_priv,
- struct intel_cdclk_state *cdclk_config)
+static int intel_cdclk_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(cdclk_config);
+ struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+
+ return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(state);
}
static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv,
@@ -1443,6 +1445,14 @@ static const struct intel_cdclk_vals xe2lpd_cdclk_table[] = {
{}
};
+/*
+ * Xe2_HPD always uses the minimal cdclk table from Wa_15015413771
+ */
+static const struct intel_cdclk_vals xe2hpd_cdclk_table[] = {
+ { .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },
+ {}
+};
+
static const int cdclk_squash_len = 16;
static int cdclk_squash_divider(u16 waveform)
@@ -2723,7 +2733,7 @@ static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
min_cdclk = max_t(int, min_cdclk,
DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances));
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock);
/*
@@ -2826,10 +2836,11 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
return min_cdclk;
}
-static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
+static int intel_compute_min_cdclk(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
const struct intel_bw_state *bw_state;
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
@@ -2908,10 +2919,11 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
* future platforms this code will need to be
* adjusted.
*/
-static int bxt_compute_min_voltage_level(struct intel_cdclk_state *cdclk_state)
+static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
u8 min_voltage_level;
@@ -2944,13 +2956,14 @@ static int bxt_compute_min_voltage_level(struct intel_cdclk_state *cdclk_state)
return min_voltage_level;
}
-static int vlv_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
@@ -2973,11 +2986,13 @@ static int vlv_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int bdw_modeset_calc_cdclk(struct intel_atomic_state *state)
{
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
@@ -3000,10 +3015,11 @@ static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int skl_dpll0_vco(struct intel_cdclk_state *cdclk_state)
+static int skl_dpll0_vco(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
int vco, i;
@@ -3037,15 +3053,17 @@ static int skl_dpll0_vco(struct intel_cdclk_state *cdclk_state)
return vco;
}
-static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int skl_modeset_calc_cdclk(struct intel_atomic_state *state)
{
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk, vco;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
- vco = skl_dpll0_vco(cdclk_state);
+ vco = skl_dpll0_vco(state);
cdclk = skl_calc_cdclk(min_cdclk, vco);
@@ -3068,17 +3086,18 @@ static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, min_voltage_level, cdclk, vco;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
- min_voltage_level = bxt_compute_min_voltage_level(cdclk_state);
+ min_voltage_level = bxt_compute_min_voltage_level(state);
if (min_voltage_level < 0)
return min_voltage_level;
@@ -3106,7 +3125,7 @@ static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)
{
int min_cdclk;
@@ -3115,7 +3134,7 @@ static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
* check that the required minimum frequency doesn't exceed
* the actual cdclk frequency.
*/
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
@@ -3255,7 +3274,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
new_cdclk_state->active_pipes =
intel_calc_active_pipes(state, old_cdclk_state->active_pipes);
- ret = intel_cdclk_modeset_calc_cdclk(dev_priv, new_cdclk_state);
+ ret = intel_cdclk_modeset_calc_cdclk(state);
if (ret)
return ret;
@@ -3521,60 +3540,10 @@ static int vlv_hrawclk(struct drm_i915_private *dev_priv)
CCK_DISPLAY_REF_CLOCK_CONTROL);
}
-static int i9xx_hrawclk(struct drm_i915_private *dev_priv)
+static int i9xx_hrawclk(struct drm_i915_private *i915)
{
- u32 clkcfg;
-
- /*
- * hrawclock is 1/4 the FSB frequency
- *
- * Note that this only reads the state of the FSB
- * straps, not the actual FSB frequency. Some BIOSen
- * let you configure each independently. Ideally we'd
- * read out the actual FSB frequency but sadly we
- * don't know which registers have that information,
- * and all the relevant docs have gone to bit heaven :(
- */
- clkcfg = intel_de_read(dev_priv, CLKCFG) & CLKCFG_FSB_MASK;
-
- if (IS_MOBILE(dev_priv)) {
- switch (clkcfg) {
- case CLKCFG_FSB_400:
- return 100000;
- case CLKCFG_FSB_533:
- return 133333;
- case CLKCFG_FSB_667:
- return 166667;
- case CLKCFG_FSB_800:
- return 200000;
- case CLKCFG_FSB_1067:
- return 266667;
- case CLKCFG_FSB_1333:
- return 333333;
- default:
- MISSING_CASE(clkcfg);
- return 133333;
- }
- } else {
- switch (clkcfg) {
- case CLKCFG_FSB_400_ALT:
- return 100000;
- case CLKCFG_FSB_533:
- return 133333;
- case CLKCFG_FSB_667:
- return 166667;
- case CLKCFG_FSB_800:
- return 200000;
- case CLKCFG_FSB_1067_ALT:
- return 266667;
- case CLKCFG_FSB_1333_ALT:
- return 333333;
- case CLKCFG_FSB_1600_ALT:
- return 400000;
- default:
- return 133333;
- }
- }
+ /* hrawclock is 1/4 the FSB frequency */
+ return DIV_ROUND_CLOSEST(i9xx_fsb_freq(i915), 4);
}
/**
@@ -3778,6 +3747,9 @@ 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;
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index d23163dc64d4..7ac50aacec73 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -22,7 +22,7 @@
*
*/
-#include "i915_reg.h"
+#include "i9xx_plane_regs.h"
#include "intel_color.h"
#include "intel_color_regs.h"
#include "intel_de.h"
@@ -30,7 +30,8 @@
#include "intel_dsb.h"
struct intel_color_funcs {
- int (*color_check)(struct intel_crtc_state *crtc_state);
+ int (*color_check)(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
/*
* Program non-arming double buffered color management registers
* before vblank evasion. The registers should then latch after
@@ -1038,7 +1039,7 @@ static void i9xx_get_config(struct intel_crtc_state *crtc_state)
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
u32 tmp;
- tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
+ tmp = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
if (tmp & DISP_PIPE_GAMMA_ENABLE)
crtc_state->gamma_enable = true;
@@ -1284,9 +1285,9 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
i965_lut_10p6_udw(&lut[i]));
}
- intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 0), lut[i].red);
- intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 1), lut[i].green);
- intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 2), lut[i].blue);
+ intel_de_write_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 0), lut[i].red);
+ intel_de_write_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 1), lut[i].green);
+ intel_de_write_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 2), lut[i].blue);
}
static void i965_load_luts(const struct intel_crtc_state *crtc_state)
@@ -1901,19 +1902,24 @@ void intel_color_post_update(const struct intel_crtc_state *crtc_state)
i915->display.funcs.color->color_post_update(crtc_state);
}
-void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
+void intel_color_prepare_commit(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
if (!crtc_state->hw.active ||
intel_crtc_needs_modeset(crtc_state))
return;
+ if (!intel_crtc_needs_color_update(crtc_state))
+ return;
+
if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
return;
- crtc_state->dsb = intel_dsb_prepare(crtc_state, 1024);
+ crtc_state->dsb = intel_dsb_prepare(state, crtc, INTEL_DSB_0, 1024);
if (!crtc_state->dsb)
return;
@@ -1942,11 +1948,9 @@ bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
return crtc_state->dsb;
}
-static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
+static bool intel_can_preload_luts(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@@ -1954,11 +1958,9 @@ static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state
!old_crtc_state->pre_csc_lut;
}
-static bool vlv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
+static bool vlv_can_preload_luts(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@@ -1966,13 +1968,13 @@ static bool vlv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
!old_crtc_state->post_csc_lut;
}
-static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
+static bool chv_can_preload_luts(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
/*
* CGM_PIPE_MODE is itself single buffered. We'd have to
@@ -1982,14 +1984,29 @@ static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
return false;
- return vlv_can_preload_luts(new_crtc_state);
+ return vlv_can_preload_luts(state, crtc);
}
-int intel_color_check(struct intel_crtc_state *crtc_state)
+int intel_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
- return i915->display.funcs.color->color_check(crtc_state);
+ /*
+ * May need to update pipe gamma enable bits
+ * when C8 planes are getting enabled/disabled.
+ */
+ if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes)
+ new_crtc_state->uapi.color_mgmt_changed = true;
+
+ if (!intel_crtc_needs_color_update(new_crtc_state))
+ return 0;
+
+ return i915->display.funcs.color->color_check(state, crtc);
}
void intel_color_get_config(struct intel_crtc_state *crtc_state)
@@ -2039,14 +2056,14 @@ static bool need_plane_update(struct intel_plane *plane,
}
static int
-intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
+intel_color_add_affected_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane *plane;
if (!new_crtc_state->hw.active ||
@@ -2240,9 +2257,12 @@ static void intel_assign_luts(struct intel_crtc_state *crtc_state)
crtc_state->hw.gamma_lut);
}
-static int i9xx_color_check(struct intel_crtc_state *crtc_state)
+static int i9xx_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2262,13 +2282,13 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
return ret;
}
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
intel_assign_luts(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2277,8 +2297,11 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
* VLV color pipeline:
* u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
*/
-static int vlv_color_check(struct intel_crtc_state *crtc_state)
+static int vlv_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2293,7 +2316,7 @@ static int vlv_color_check(struct intel_crtc_state *crtc_state)
crtc_state->wgc_enable = crtc_state->hw.ctm;
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2301,7 +2324,7 @@ static int vlv_color_check(struct intel_crtc_state *crtc_state)
vlv_assign_csc(crtc_state);
- crtc_state->preload_luts = vlv_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = vlv_can_preload_luts(state, crtc);
return 0;
}
@@ -2336,8 +2359,11 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
* We always bypass the WGC csc and use the CGM csc
* instead since it has degamma and better precision.
*/
-static int chv_color_check(struct intel_crtc_state *crtc_state)
+static int chv_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2362,7 +2388,7 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
*/
crtc_state->wgc_enable = false;
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2370,7 +2396,7 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
chv_assign_csc(crtc_state);
- crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = chv_can_preload_luts(state, crtc);
return 0;
}
@@ -2454,9 +2480,12 @@ static int ilk_assign_luts(struct intel_crtc_state *crtc_state)
return 0;
}
-static int ilk_color_check(struct intel_crtc_state *crtc_state)
+static int ilk_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2484,7 +2513,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
crtc_state->csc_mode = ilk_csc_mode(crtc_state);
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2494,7 +2523,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
ilk_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2555,9 +2584,12 @@ static int ivb_assign_luts(struct intel_crtc_state *crtc_state)
return 0;
}
-static int ivb_color_check(struct intel_crtc_state *crtc_state)
+static int ivb_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2592,7 +2624,7 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
crtc_state->csc_mode = ivb_csc_mode(crtc_state);
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2602,7 +2634,7 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
ilk_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2686,9 +2718,12 @@ static int glk_check_luts(const struct intel_crtc_state *crtc_state)
return _check_luts(crtc_state, degamma_tests, gamma_tests);
}
-static int glk_color_check(struct intel_crtc_state *crtc_state)
+static int glk_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = glk_check_luts(crtc_state);
@@ -2725,7 +2760,7 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
crtc_state->csc_mode = 0;
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2735,7 +2770,7 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
ilk_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2783,8 +2818,11 @@ static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
return csc_mode;
}
-static int icl_color_check(struct intel_crtc_state *crtc_state)
+static int icl_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2799,7 +2837,7 @@ static int icl_color_check(struct intel_crtc_state *crtc_state)
icl_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -3239,9 +3277,9 @@ static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
i965_lut_10p6_pack(&lut[i], ldw, udw);
}
- lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
- lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
- lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
+ lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 0)));
+ lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 1)));
+ lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 2)));
return blob;
}
diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h
index 8ecd36149def..79f230a1709a 100644
--- a/drivers/gpu/drm/i915/display/intel_color.h
+++ b/drivers/gpu/drm/i915/display/intel_color.h
@@ -8,6 +8,7 @@
#include <linux/types.h>
+struct intel_atomic_state;
struct intel_crtc_state;
struct intel_crtc;
struct drm_i915_private;
@@ -16,8 +17,10 @@ struct drm_property_blob;
void intel_color_init_hooks(struct drm_i915_private *i915);
int intel_color_init(struct drm_i915_private *i915);
void intel_color_crtc_init(struct intel_crtc *crtc);
-int intel_color_check(struct intel_crtc_state *crtc_state);
-void intel_color_prepare_commit(struct intel_crtc_state *crtc_state);
+int intel_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+void intel_color_prepare_commit(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
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);
diff --git a/drivers/gpu/drm/i915/display/intel_color_regs.h b/drivers/gpu/drm/i915/display/intel_color_regs.h
index bb99ea533842..8eb643cfead7 100644
--- a/drivers/gpu/drm/i915/display/intel_color_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_color_regs.h
@@ -36,6 +36,11 @@
_CHV_PALETTE_C, _CHV_PALETTE_C) + \
(i) * 4)
+/* i965/g4x/vlv/chv */
+#define _PIPEAGCMAX 0x70010
+#define _PIPEBGCMAX 0x71010
+#define PIPEGCMAX(dev_priv, pipe, i) _MMIO_PIPE2(dev_priv, pipe, _PIPEAGCMAX + (i) * 4) /* u1.16 */
+
/* ilk+ palette */
#define _LGC_PALETTE_A 0x4a000
#define _LGC_PALETTE_B 0x4a800
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 10e95dc425a6..835c8b844494 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -193,7 +193,7 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
adpa |= ADPA_PIPE_SEL(crtc->pipe);
if (!HAS_PCH_SPLIT(dev_priv))
- intel_de_write(dev_priv, BCLRPAT(crtc->pipe), 0);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, crtc->pipe), 0);
switch (mode) {
case DRM_MODE_DPMS_ON:
@@ -603,18 +603,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
CRT_HOTPLUG_FORCE_DETECT,
CRT_HOTPLUG_FORCE_DETECT);
/* wait for FORCE_DETECT to go off */
- if (intel_de_wait_for_clear(dev_priv, PORT_HOTPLUG_EN,
+ if (intel_de_wait_for_clear(dev_priv, PORT_HOTPLUG_EN(dev_priv),
CRT_HOTPLUG_FORCE_DETECT, 1000))
drm_dbg_kms(&dev_priv->drm,
"timed out waiting for FORCE_DETECT to go off");
}
- stat = intel_de_read(dev_priv, PORT_HOTPLUG_STAT);
+ stat = intel_de_read(dev_priv, PORT_HOTPLUG_STAT(dev_priv));
if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
ret = true;
/* clear the interrupt we just generated, if any */
- intel_de_write(dev_priv, PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
+ intel_de_write(dev_priv, PORT_HOTPLUG_STAT(dev_priv),
+ CRT_HOTPLUG_INT_STATUS);
i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0);
@@ -707,9 +708,12 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
drm_dbg_kms(&dev_priv->drm, "starting load-detect on CRT\n");
- save_bclrpat = intel_de_read(dev_priv, BCLRPAT(cpu_transcoder));
- save_vtotal = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder));
- vblank = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder));
+ save_bclrpat = intel_de_read(dev_priv,
+ BCLRPAT(dev_priv, cpu_transcoder));
+ save_vtotal = intel_de_read(dev_priv,
+ TRANS_VTOTAL(dev_priv, cpu_transcoder));
+ vblank = intel_de_read(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder));
vtotal = REG_FIELD_GET(VTOTAL_MASK, save_vtotal) + 1;
vactive = REG_FIELD_GET(VACTIVE_MASK, save_vtotal) + 1;
@@ -718,14 +722,16 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
vblank_end = REG_FIELD_GET(VBLANK_END_MASK, vblank) + 1;
/* Set the border color to purple. */
- intel_de_write(dev_priv, BCLRPAT(cpu_transcoder), 0x500050);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, cpu_transcoder), 0x500050);
if (DISPLAY_VER(dev_priv) != 2) {
- u32 transconf = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ u32 transconf = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder),
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
transconf | TRANSCONF_FORCE_BORDER);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_posting_read(dev_priv,
+ 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));
@@ -734,7 +740,8 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
connector_status_connected :
connector_status_disconnected;
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), transconf);
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
+ transconf);
} else {
bool restore_vblank = false;
int count, detect;
@@ -744,11 +751,13 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
* Yes, this will flicker
*/
if (vblank_start <= vactive && vblank_end >= vtotal) {
- u32 vsync = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder));
+ u32 vsync = intel_de_read(dev_priv,
+ TRANS_VSYNC(dev_priv, cpu_transcoder));
u32 vsync_start = REG_FIELD_GET(VSYNC_START_MASK, vsync) + 1;
vblank_start = vsync_start;
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(vblank_start - 1) |
VBLANK_END(vblank_end - 1));
restore_vblank = true;
@@ -762,9 +771,9 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
/*
* Wait for the border to be displayed
*/
- while (intel_de_read(dev_priv, PIPEDSL(pipe)) >= vactive)
+ while (intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe)) >= vactive)
;
- while ((dsl = intel_de_read(dev_priv, PIPEDSL(pipe))) <= vsample)
+ while ((dsl = intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe))) <= vsample)
;
/*
* Watch ST00 for an entire scanline
@@ -777,11 +786,13 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
st00 = intel_de_read8(dev_priv, _VGA_MSR_WRITE);
if (st00 & (1 << 4))
detect++;
- } while ((intel_de_read(dev_priv, PIPEDSL(pipe)) == dsl));
+ } while ((intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe)) == dsl));
/* restore vblank if necessary */
if (restore_vblank)
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), vblank);
+ intel_de_write(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder),
+ vblank);
/*
* If more than 3/4 of the scanline detected a monitor,
* then it is assumed to be present. This works even on i830,
@@ -794,7 +805,8 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
}
/* Restore previous settings */
- intel_de_write(dev_priv, BCLRPAT(cpu_transcoder), save_bclrpat);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, cpu_transcoder),
+ save_bclrpat);
return status;
}
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 25593f6aae7d..1b578cad2813 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -24,7 +24,6 @@
#include "intel_display_trace.h"
#include "intel_display_types.h"
#include "intel_drrs.h"
-#include "intel_dsb.h"
#include "intel_dsi.h"
#include "intel_fifo_underrun.h"
#include "intel_pipe_crc.h"
@@ -78,8 +77,7 @@ void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
{
- struct drm_device *dev = crtc->base.dev;
- struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(&crtc->base)];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
if (!crtc->active)
return 0;
@@ -311,8 +309,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
crtc->num_scalers = DISPLAY_RUNTIME_INFO(dev_priv)->num_scalers[pipe];
if (DISPLAY_VER(dev_priv) >= 9)
- primary = skl_universal_plane_create(dev_priv, pipe,
- PLANE_PRIMARY);
+ primary = skl_universal_plane_create(dev_priv, pipe, PLANE_1);
else
primary = intel_primary_plane_create(dev_priv, pipe);
if (IS_ERR(primary)) {
@@ -327,8 +324,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
struct intel_plane *plane;
if (DISPLAY_VER(dev_priv) >= 9)
- plane = skl_universal_plane_create(dev_priv, pipe,
- PLANE_SPRITE0 + sprite);
+ plane = skl_universal_plane_create(dev_priv, pipe, PLANE_2 + sprite);
else
plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
if (IS_ERR(plane)) {
@@ -414,8 +410,8 @@ static void intel_crtc_vblank_work(struct kthread_work *base)
if (crtc_state->uapi.event) {
spin_lock_irq(&crtc->base.dev->event_lock);
drm_crtc_send_vblank_event(&crtc->base, crtc_state->uapi.event);
- crtc_state->uapi.event = NULL;
spin_unlock_irq(&crtc->base.dev->event_lock);
+ crtc_state->uapi.event = NULL;
}
trace_intel_crtc_vblank_work_end(crtc);
@@ -457,8 +453,8 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
if (!adjusted_mode->crtc_htotal)
return 1;
- return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
- 1000 * adjusted_mode->crtc_htotal);
+ return DIV_ROUND_UP_ULL(mul_u32_u32(usecs, adjusted_mode->crtc_clock),
+ 1000 * adjusted_mode->crtc_htotal);
}
/**
@@ -500,6 +496,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state,
if (intel_crtc_needs_vblank_work(new_crtc_state))
intel_crtc_vblank_work_init(new_crtc_state);
+ if (state->base.legacy_cursor_update) {
+ struct intel_plane *plane;
+ struct intel_plane_state *old_plane_state, *new_plane_state;
+ int i;
+
+ for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
+ new_plane_state, i) {
+ if (old_plane_state->uapi.crtc == &crtc->base)
+ intel_plane_init_cursor_vblank_work(old_plane_state,
+ new_plane_state);
+ }
+ }
+
intel_vblank_evade_init(old_crtc_state, new_crtc_state, &evade);
if (drm_WARN_ON(&dev_priv->drm, drm_crtc_vblank_get(&crtc->base)))
@@ -563,6 +572,23 @@ static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end)
static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) {}
#endif
+void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ unsigned long irqflags;
+
+ if (!crtc_state->uapi.event)
+ return;
+
+ drm_WARN_ON(crtc->base.dev, drm_crtc_vblank_get(&crtc->base) != 0);
+
+ spin_lock_irqsave(&crtc->base.dev->event_lock, irqflags);
+ drm_crtc_arm_vblank_event(&crtc->base, 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
@@ -604,16 +630,26 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
drm_vblank_work_schedule(&new_crtc_state->vblank_work,
drm_crtc_accurate_vblank_count(&crtc->base) + 1,
false);
- } else if (new_crtc_state->uapi.event) {
- drm_WARN_ON(&dev_priv->drm,
- drm_crtc_vblank_get(&crtc->base) != 0);
-
- spin_lock(&crtc->base.dev->event_lock);
- drm_crtc_arm_vblank_event(&crtc->base,
- new_crtc_state->uapi.event);
- spin_unlock(&crtc->base.dev->event_lock);
+ } else {
+ intel_crtc_arm_vblank_event(new_crtc_state);
+ }
- new_crtc_state->uapi.event = NULL;
+ if (state->base.legacy_cursor_update) {
+ struct intel_plane *plane;
+ struct intel_plane_state *old_plane_state;
+ int i;
+
+ for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
+ if (old_plane_state->uapi.crtc == &crtc->base &&
+ old_plane_state->unpin_work.vblank) {
+ drm_vblank_work_schedule(&old_plane_state->unpin_work,
+ drm_crtc_accurate_vblank_count(&crtc->base) + 1,
+ false);
+
+ /* Remove plane from atomic state, cleanup/free is done from vblank worker. */
+ memset(&state->base.planes[i], 0, sizeof(state->base.planes[i]));
+ }
+ }
}
/*
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h
index 22d7993d1f0b..b615b7ab5ccd 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.h
+++ b/drivers/gpu/drm/i915/display/intel_crtc.h
@@ -28,6 +28,7 @@ struct intel_crtc_state;
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
int usecs);
+void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state);
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);
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
index ccaa4cb2809b..6df526e189b5 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
@@ -222,10 +222,10 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
transcoder_name(pipe_config->master_transcoder),
pipe_config->sync_mode_slaves_mask);
- drm_printf(&p, "bigjoiner: %s, pipes: 0x%x\n",
- intel_crtc_is_bigjoiner_slave(pipe_config) ? "slave" :
- intel_crtc_is_bigjoiner_master(pipe_config) ? "master" : "no",
- pipe_config->bigjoiner_pipes);
+ drm_printf(&p, "joiner: %s, pipes: 0x%x\n",
+ intel_crtc_is_joiner_secondary(pipe_config) ? "secondary" :
+ intel_crtc_is_joiner_primary(pipe_config) ? "primary" : "no",
+ pipe_config->joiner_pipes);
drm_printf(&p, "splitter: %s, link count %d, overlap %d\n",
str_enabled_disabled(pipe_config->splitter.enable),
@@ -251,9 +251,10 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
drm_printf(&p, "sdp split: %s\n",
str_enabled_disabled(pipe_config->sdp_split_enable));
- drm_printf(&p, "psr: %s, psr2: %s, panel replay: %s, selective fetch: %s\n",
- str_enabled_disabled(pipe_config->has_psr),
- str_enabled_disabled(pipe_config->has_psr2),
+ drm_printf(&p, "psr: %s, selective update: %s, panel replay: %s, selective fetch: %s\n",
+ str_enabled_disabled(pipe_config->has_psr &&
+ !pipe_config->has_panel_replay),
+ str_enabled_disabled(pipe_config->has_sel_update),
str_enabled_disabled(pipe_config->has_panel_replay),
str_enabled_disabled(pipe_config->enable_psr2_sel_fetch));
}
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 23a122ee20c9..9ad53e1cbbd0 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -14,6 +14,7 @@
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_cursor.h"
+#include "intel_cursor_regs.h"
#include "intel_de.h"
#include "intel_display.h"
#include "intel_display_types.h"
@@ -193,6 +194,13 @@ i845_cursor_max_stride(struct intel_plane *plane,
return 2048;
}
+static unsigned int i845_cursor_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ return 32;
+}
+
static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
{
u32 cntl = 0;
@@ -293,17 +301,17 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
if (plane->cursor.base != base ||
plane->cursor.size != size ||
plane->cursor.cntl != cntl) {
- intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0);
- intel_de_write_fw(dev_priv, CURBASE(PIPE_A), base);
- intel_de_write_fw(dev_priv, CURSIZE(PIPE_A), size);
- intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
- intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl);
+ intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), 0);
+ intel_de_write_fw(dev_priv, CURBASE(dev_priv, PIPE_A), base);
+ intel_de_write_fw(dev_priv, CURSIZE(dev_priv, PIPE_A), size);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
+ intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), cntl);
plane->cursor.base = base;
plane->cursor.size = size;
plane->cursor.cntl = cntl;
} else {
- intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
}
}
@@ -326,7 +334,7 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane,
if (!wakeref)
return false;
- ret = intel_de_read(dev_priv, CURCNTR(PIPE_A)) & CURSOR_ENABLE;
+ ret = intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & CURSOR_ENABLE;
*pipe = PIPE_A;
@@ -343,6 +351,28 @@ i9xx_cursor_max_stride(struct intel_plane *plane,
return plane->base.dev->mode_config.cursor_width * 4;
}
+static unsigned int i830_cursor_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ /* "AlmadorM Errata – Requires 32-bpp cursor data to be 16KB aligned." */
+ return 16 * 1024; /* physical */
+}
+
+static unsigned int i85x_cursor_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ return 256; /* physical */
+}
+
+static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ return 4 * 1024; /* physical for i915/i945 */
+}
+
static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -506,7 +536,7 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_plane *plane,
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0);
+ intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), 0);
}
static void wa_16021440873(struct intel_plane *plane,
@@ -521,10 +551,10 @@ static void wa_16021440873(struct intel_plane *plane,
ctl &= ~MCURSOR_MODE_MASK;
ctl |= MCURSOR_MODE_64_2B;
- intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), ctl);
+ intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), ctl);
- intel_de_write(dev_priv, PIPE_SRCSZ_ERLY_TPT(pipe),
- PIPESRC_HEIGHT(et_y_position));
+ intel_de_write(dev_priv, CURPOS_ERLY_TPT(dev_priv, pipe),
+ CURSOR_POS_Y(et_y_position));
}
static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
@@ -541,10 +571,12 @@ 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(pipe), val);
+ intel_de_write_fw(dev_priv,
+ CURPOS_ERLY_TPT(dev_priv, pipe),
+ val);
}
- intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
+ intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe),
plane_state->ctl);
} else {
/* Wa_16021440873 */
@@ -555,6 +587,60 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
}
}
+static u32 skl_cursor_ddb_reg_val(const struct skl_ddb_entry *entry)
+{
+ if (!entry->end)
+ return 0;
+
+ return CUR_BUF_END(entry->end - 1) |
+ CUR_BUF_START(entry->start);
+}
+
+static u32 skl_cursor_wm_reg_val(const struct skl_wm_level *level)
+{
+ u32 val = 0;
+
+ if (level->enable)
+ val |= CUR_WM_EN;
+ if (level->ignore_lines)
+ val |= CUR_WM_IGNORE_LINES;
+ val |= REG_FIELD_PREP(CUR_WM_BLOCKS_MASK, level->blocks);
+ val |= REG_FIELD_PREP(CUR_WM_LINES_MASK, level->lines);
+
+ return val;
+}
+
+static void skl_write_cursor_wm(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ enum plane_id plane_id = plane->id;
+ enum pipe pipe = plane->pipe;
+ const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+ const struct skl_ddb_entry *ddb =
+ &crtc_state->wm.skl.plane_ddb[plane_id];
+ 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_fw(i915, 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_fw(i915, 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,
const struct intel_crtc_state *crtc_state,
@@ -611,18 +697,19 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
plane->cursor.size != fbc_ctl ||
plane->cursor.cntl != cntl) {
if (HAS_CUR_FBC(dev_priv))
- intel_de_write_fw(dev_priv, CUR_FBC_CTL(pipe),
+ intel_de_write_fw(dev_priv,
+ CUR_FBC_CTL(dev_priv, pipe),
fbc_ctl);
- intel_de_write_fw(dev_priv, CURCNTR(pipe), cntl);
- intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
- intel_de_write_fw(dev_priv, CURBASE(pipe), base);
+ 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);
plane->cursor.base = base;
plane->cursor.size = fbc_ctl;
plane->cursor.cntl = cntl;
} else {
- intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
- intel_de_write_fw(dev_priv, CURBASE(pipe), base);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos);
+ intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base);
}
}
@@ -651,7 +738,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, CURCNTR(plane->pipe));
+ val = intel_de_read(dev_priv, CURCNTR(dev_priv, plane->pipe));
ret = val & MCURSOR_MODE_MASK;
@@ -674,6 +761,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane,
return format == DRM_FORMAT_ARGB8888;
}
+void intel_cursor_unpin_work(struct kthread_work *base)
+{
+ struct drm_vblank_work *work = to_drm_vblank_work(base);
+ struct intel_plane_state *plane_state =
+ container_of(work, typeof(*plane_state), unpin_work);
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+
+ intel_plane_unpin_fb(plane_state);
+ intel_plane_destroy_state(&plane->base, &plane_state->uapi);
+}
+
static int
intel_legacy_cursor_update(struct drm_plane *_plane,
struct drm_crtc *_crtc,
@@ -703,12 +801,12 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
* PSR2 plane and transcoder registers can only be updated during
* vblank.
*
- * FIXME bigjoiner fastpath would be good
+ * FIXME joiner fastpath would be good
*/
if (!crtc_state->hw.active ||
intel_crtc_needs_modeset(crtc_state) ||
intel_crtc_needs_fastset(crtc_state) ||
- crtc_state->bigjoiner_pipes)
+ crtc_state->joiner_pipes)
goto slow;
/*
@@ -817,14 +915,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
intel_psr_unlock(crtc_state);
- intel_plane_unpin_fb(old_plane_state);
+ if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) {
+ drm_vblank_work_init(&old_plane_state->unpin_work, &crtc->base,
+ intel_cursor_unpin_work);
+
+ drm_vblank_work_schedule(&old_plane_state->unpin_work,
+ drm_crtc_accurate_vblank_count(&crtc->base) + 1,
+ false);
+
+ old_plane_state = NULL;
+ } else {
+ intel_plane_unpin_fb(old_plane_state);
+ }
out_free:
if (new_crtc_state)
intel_crtc_destroy_state(&crtc->base, &new_crtc_state->uapi);
if (ret)
intel_plane_destroy_state(&plane->base, &new_plane_state->uapi);
- else
+ else if (old_plane_state)
intel_plane_destroy_state(&plane->base, &old_plane_state->uapi);
return ret;
@@ -884,12 +993,21 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
cursor->max_stride = i845_cursor_max_stride;
+ cursor->min_alignment = i845_cursor_min_alignment;
cursor->update_arm = i845_cursor_update_arm;
cursor->disable_arm = i845_cursor_disable_arm;
cursor->get_hw_state = i845_cursor_get_hw_state;
cursor->check_plane = i845_check_cursor;
} else {
cursor->max_stride = i9xx_cursor_max_stride;
+
+ if (IS_I830(dev_priv))
+ cursor->min_alignment = i830_cursor_min_alignment;
+ else if (IS_I85X(dev_priv))
+ cursor->min_alignment = i85x_cursor_min_alignment;
+ else
+ cursor->min_alignment = i9xx_cursor_min_alignment;
+
cursor->update_arm = i9xx_cursor_update_arm;
cursor->disable_arm = i9xx_cursor_disable_arm;
cursor->get_hw_state = i9xx_cursor_get_hw_state;
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.h b/drivers/gpu/drm/i915/display/intel_cursor.h
index ce333bf4c2d5..e2d9ec710a86 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.h
+++ b/drivers/gpu/drm/i915/display/intel_cursor.h
@@ -9,9 +9,12 @@
enum pipe;
struct drm_i915_private;
struct intel_plane;
+struct kthread_work;
struct intel_plane *
intel_cursor_plane_create(struct drm_i915_private *dev_priv,
enum pipe pipe);
+void intel_cursor_unpin_work(struct kthread_work *base);
+
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_cursor_regs.h b/drivers/gpu/drm/i915/display/intel_cursor_regs.h
new file mode 100644
index 000000000000..aaa66331063e
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_cursor_regs.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_CURSOR_REGS_H__
+#define __INTEL_CURSOR_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _CURACNTR 0x70080
+#define CURCNTR(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURACNTR)
+/* Old style CUR*CNTR flags (desktop 8xx) */
+#define CURSOR_ENABLE REG_BIT(31)
+#define CURSOR_PIPE_GAMMA_ENABLE REG_BIT(30)
+#define CURSOR_STRIDE_MASK REG_GENMASK(29, 28)
+#define CURSOR_STRIDE(stride) REG_FIELD_PREP(CURSOR_STRIDE_MASK, ffs(stride) - 9) /* 256,512,1k,2k */
+#define CURSOR_FORMAT_MASK REG_GENMASK(26, 24)
+#define CURSOR_FORMAT_2C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 0)
+#define CURSOR_FORMAT_3C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 1)
+#define CURSOR_FORMAT_4C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 2)
+#define CURSOR_FORMAT_ARGB REG_FIELD_PREP(CURSOR_FORMAT_MASK, 4)
+#define CURSOR_FORMAT_XRGB REG_FIELD_PREP(CURSOR_FORMAT_MASK, 5)
+/* New style CUR*CNTR flags */
+#define MCURSOR_ARB_SLOTS_MASK REG_GENMASK(30, 28) /* icl+ */
+#define MCURSOR_ARB_SLOTS(x) REG_FIELD_PREP(MCURSOR_ARB_SLOTS_MASK, (x)) /* icl+ */
+#define MCURSOR_PIPE_SEL_MASK REG_GENMASK(29, 28)
+#define MCURSOR_PIPE_SEL(pipe) REG_FIELD_PREP(MCURSOR_PIPE_SEL_MASK, (pipe))
+#define MCURSOR_PIPE_GAMMA_ENABLE REG_BIT(26)
+#define MCURSOR_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
+#define MCURSOR_ROTATE_180 REG_BIT(15)
+#define MCURSOR_TRICKLE_FEED_DISABLE REG_BIT(14)
+#define MCURSOR_MODE_MASK 0x27
+#define MCURSOR_MODE_DISABLE 0x00
+#define MCURSOR_MODE_128_32B_AX 0x02
+#define MCURSOR_MODE_256_32B_AX 0x03
+#define MCURSOR_MODE_64_2B 0x04
+#define MCURSOR_MODE_64_32B_AX 0x07
+#define MCURSOR_MODE_128_ARGB_AX (0x20 | MCURSOR_MODE_128_32B_AX)
+#define MCURSOR_MODE_256_ARGB_AX (0x20 | MCURSOR_MODE_256_32B_AX)
+#define MCURSOR_MODE_64_ARGB_AX (0x20 | MCURSOR_MODE_64_32B_AX)
+
+#define _CURABASE 0x70084
+#define CURBASE(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURABASE)
+
+#define _CURAPOS 0x70088
+#define CURPOS(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURAPOS)
+#define CURSOR_POS_Y_SIGN REG_BIT(31)
+#define CURSOR_POS_Y_MASK REG_GENMASK(30, 16)
+#define CURSOR_POS_Y(y) REG_FIELD_PREP(CURSOR_POS_Y_MASK, (y))
+#define CURSOR_POS_X_SIGN REG_BIT(15)
+#define CURSOR_POS_X_MASK REG_GENMASK(14, 0)
+#define CURSOR_POS_X(x) REG_FIELD_PREP(CURSOR_POS_X_MASK, (x))
+
+#define _CURAPOS_ERLY_TPT 0x7008c
+#define CURPOS_ERLY_TPT(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURAPOS_ERLY_TPT)
+
+#define _CURASIZE 0x700a0 /* 845/865 */
+#define CURSIZE(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURASIZE)
+#define CURSOR_HEIGHT_MASK REG_GENMASK(21, 12)
+#define CURSOR_HEIGHT(h) REG_FIELD_PREP(CURSOR_HEIGHT_MASK, (h))
+#define CURSOR_WIDTH_MASK REG_GENMASK(9, 0)
+#define CURSOR_WIDTH(w) REG_FIELD_PREP(CURSOR_WIDTH_MASK, (w))
+
+#define _CUR_FBC_CTL_A 0x700a0 /* ivb+ */
+#define CUR_FBC_CTL(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CUR_FBC_CTL_A)
+#define CUR_FBC_EN REG_BIT(31)
+#define CUR_FBC_HEIGHT_MASK REG_GENMASK(7, 0)
+#define CUR_FBC_HEIGHT(h) REG_FIELD_PREP(CUR_FBC_HEIGHT_MASK, (h))
+
+#define _CUR_CHICKEN_A 0x700a4 /* mtl+ */
+#define CUR_CHICKEN(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CUR_CHICKEN_A)
+
+#define _CURASURFLIVE 0x700ac /* g4x+ */
+#define CURSURFLIVE(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURASURFLIVE)
+
+/* skl+ */
+#define _CUR_WM_A_0 0x70140
+#define _CUR_WM_B_0 0x71140
+#define CUR_WM(pipe, level) _MMIO(_PIPE((pipe), _CUR_WM_A_0, _CUR_WM_B_0) + (level) * 4)
+#define CUR_WM_EN REG_BIT(31)
+#define CUR_WM_IGNORE_LINES REG_BIT(30)
+#define CUR_WM_LINES_MASK REG_GENMASK(26, 14)
+#define CUR_WM_BLOCKS_MASK REG_GENMASK(11, 0)
+
+#define _CUR_WM_SAGV_A 0x70158
+#define _CUR_WM_SAGV_B 0x71158
+#define CUR_WM_SAGV(pipe) _MMIO_PIPE((pipe), _CUR_WM_SAGV_A, _CUR_WM_SAGV_B)
+
+#define _CUR_WM_SAGV_TRANS_A 0x7015C
+#define _CUR_WM_SAGV_TRANS_B 0x7115C
+#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE((pipe), _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B)
+
+#define _CUR_WM_TRANS_A 0x70168
+#define _CUR_WM_TRANS_B 0x71168
+#define CUR_WM_TRANS(pipe) _MMIO_PIPE((pipe), _CUR_WM_TRANS_A, _CUR_WM_TRANS_B)
+
+#define _CUR_BUF_CFG_A 0x7017c
+#define _CUR_BUF_CFG_B 0x7117c
+#define CUR_BUF_CFG(pipe) _MMIO_PIPE((pipe), _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
+/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
+#define CUR_BUF_END_MASK REG_GENMASK(27, 16)
+#define CUR_BUF_END(end) REG_FIELD_PREP(CUR_BUF_END_MASK, (end))
+#define CUR_BUF_START_MASK REG_GENMASK(11, 0)
+#define CUR_BUF_START(start) REG_FIELD_PREP(CUR_BUF_START_MASK, (start))
+
+/* tgl+ */
+#define _SEL_FETCH_CUR_CTL_A 0x70880
+#define _SEL_FETCH_CUR_CTL_B 0x71880
+#define SEL_FETCH_CUR_CTL(pipe) _MMIO_PIPE((pipe), _SEL_FETCH_CUR_CTL_A, _SEL_FETCH_CUR_CTL_B)
+
+#endif /* __INTEL_CURSOR_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index 8e3b13884bb8..4a6c3040ca15 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -946,6 +946,183 @@ static const struct intel_c20pll_state * const mtl_c20_dp_tables[] = {
};
/*
+ * eDP link rates with 38.4 MHz reference clock.
+ */
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r216 = {
+ .clock = 216000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x50e1,
+ 0x2120,
+ 0x8e18,
+ 0xbfc1,
+ 0x9000,
+ 0x78f6,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r243 = {
+ .clock = 243000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x50fd,
+ 0x2120,
+ 0x8f18,
+ 0xbfc1,
+ 0xa200,
+ 0x8814,
+ 0x2000,
+ 0x0001,
+ 0x1000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r324 = {
+ .clock = 324000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x30a8,
+ 0x2110,
+ 0xcd9a,
+ 0xbfc1,
+ 0x6c00,
+ 0x5ab8,
+ 0x2000,
+ 0x0001,
+ 0x6000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r432 = {
+ .clock = 432000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x30e1,
+ 0x2110,
+ 0x8e18,
+ 0xbfc1,
+ 0x9000,
+ 0x78f6,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r675 = {
+ .clock = 675000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x10af,
+ 0x2108,
+ 0xce1a,
+ 0xbfc1,
+ 0x7080,
+ 0x5e80,
+ 0x2000,
+ 0x0001,
+ 0x6400,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state * const xe2hpd_c20_edp_tables[] = {
+ &mtl_c20_dp_rbr,
+ &xe2hpd_c20_edp_r216,
+ &xe2hpd_c20_edp_r243,
+ &mtl_c20_dp_hbr1,
+ &xe2hpd_c20_edp_r324,
+ &xe2hpd_c20_edp_r432,
+ &mtl_c20_dp_hbr2,
+ &xe2hpd_c20_edp_r675,
+ &mtl_c20_dp_hbr3,
+ NULL,
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_dp_uhbr13_5 = {
+ .clock = 1350000, /* 13.5 Gbps */
+ .tx = { 0xbea0, /* tx cfg0 */
+ 0x4800, /* tx cfg1 */
+ 0x0000, /* tx cfg2 */
+ },
+ .cmn = {0x0500, /* cmn cfg0*/
+ 0x0005, /* cmn cfg1 */
+ 0x0000, /* cmn cfg2 */
+ 0x0000, /* cmn cfg3 */
+ },
+ .mpllb = { 0x015f, /* mpllb cfg0 */
+ 0x2205, /* mpllb cfg1 */
+ 0x1b17, /* mpllb cfg2 */
+ 0xffc1, /* mpllb cfg3 */
+ 0xbd00, /* mpllb cfg4 */
+ 0x9ec3, /* mpllb cfg5 */
+ 0x2000, /* mpllb cfg6 */
+ 0x0001, /* mpllb cfg7 */
+ 0x4800, /* mpllb cfg8 */
+ 0x0000, /* mpllb cfg9 */
+ 0x0000, /* mpllb cfg10 */
+ },
+};
+
+static const struct intel_c20pll_state * const xe2hpd_c20_dp_tables[] = {
+ &mtl_c20_dp_rbr,
+ &mtl_c20_dp_hbr1,
+ &mtl_c20_dp_hbr2,
+ &mtl_c20_dp_hbr3,
+ &mtl_c20_dp_uhbr10,
+ &xe2hpd_c20_dp_uhbr13_5,
+ NULL,
+};
+
+/*
* HDMI link rates with 38.4 MHz reference clock.
*/
@@ -1861,6 +2038,7 @@ static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
if (crtc_state->port_clock == tables[i]->clock) {
crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
intel_c10pll_update_pll(crtc_state, encoder);
+ crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
return 0;
}
@@ -1928,8 +2106,8 @@ static void intel_c10_pll_program(struct drm_i915_private *i915,
MB_WRITE_COMMITTED);
}
-void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
- const struct intel_c10pll_state *hw_state)
+static void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
+ const struct intel_c10pll_state *hw_state)
{
bool fracen;
int i;
@@ -2061,10 +2239,20 @@ static const struct intel_c20pll_state * const *
intel_c20_pll_tables_get(struct intel_crtc_state *crtc_state,
struct intel_encoder *encoder)
{
- if (intel_crtc_has_dp_encoder(crtc_state))
- return mtl_c20_dp_tables;
- else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_crtc_has_dp_encoder(crtc_state)) {
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return xe2hpd_c20_edp_tables;
+
+ if (DISPLAY_VER_FULL(i915) == IP_VER(14, 1))
+ return xe2hpd_c20_dp_tables;
+ else
+ return mtl_c20_dp_tables;
+
+ } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
return mtl_c20_hdmi_tables;
+ }
MISSING_CASE(encoder->type);
return NULL;
@@ -2090,6 +2278,7 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
for (i = 0; tables[i]; i++) {
if (crtc_state->port_clock == tables[i]->clock) {
crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
+ crtc_state->dpll_hw_state.cx0pll.use_c10 = false;
return 0;
}
}
@@ -2161,6 +2350,7 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
bool cntx;
intel_wakeref_t wakeref;
int i;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
wakeref = intel_cx0_phy_transaction_begin(encoder);
@@ -2170,42 +2360,50 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
/* Read Tx configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->tx); i++) {
if (cntx)
- pll_state->tx[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_TX_CNTX_CFG(i));
+ pll_state->tx[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_TX_CNTX_CFG(i915, i));
else
- pll_state->tx[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_TX_CNTX_CFG(i));
+ pll_state->tx[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_TX_CNTX_CFG(i915, i));
}
/* Read common configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->cmn); i++) {
if (cntx)
- pll_state->cmn[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_CMN_CNTX_CFG(i));
+ pll_state->cmn[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_CMN_CNTX_CFG(i915, i));
else
- pll_state->cmn[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_CMN_CNTX_CFG(i));
+ pll_state->cmn[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_CMN_CNTX_CFG(i915, i));
}
if (intel_c20phy_use_mpllb(pll_state)) {
/* MPLLB configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->mpllb); i++) {
if (cntx)
- pll_state->mpllb[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLB_CNTX_CFG(i));
+ pll_state->mpllb[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_MPLLB_CNTX_CFG(i915, i));
else
- pll_state->mpllb[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLB_CNTX_CFG(i));
+ pll_state->mpllb[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_MPLLB_CNTX_CFG(i915, i));
}
} else {
/* MPLLA configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->mplla); i++) {
if (cntx)
- pll_state->mplla[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLA_CNTX_CFG(i));
+ pll_state->mplla[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_MPLLA_CNTX_CFG(i915, i));
else
- pll_state->mplla[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLA_CNTX_CFG(i));
+ pll_state->mplla[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_MPLLA_CNTX_CFG(i915, i));
}
}
@@ -2214,8 +2412,8 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
intel_cx0_phy_transaction_end(encoder, wakeref);
}
-void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
- const struct intel_c20pll_state *hw_state)
+static void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
+ const struct intel_c20pll_state *hw_state)
{
int i;
@@ -2234,6 +2432,15 @@ void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
}
}
+void intel_cx0pll_dump_hw_state(struct drm_i915_private *i915,
+ const struct intel_cx0pll_state *hw_state)
+{
+ if (hw_state->use_c10)
+ intel_c10pll_dump_hw_state(i915, &hw_state->c10);
+ else
+ intel_c20pll_dump_hw_state(i915, &hw_state->c20);
+}
+
static u8 intel_c20_get_dp_rate(u32 clock)
{
switch (clock) {
@@ -2337,7 +2544,7 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
{
const struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
bool dp = false;
- int lane = crtc_state->lane_count > 2 ? INTEL_CX0_BOTH_LANES : INTEL_CX0_LANE0;
+ u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
u32 clock = crtc_state->port_clock;
bool cntx;
int i;
@@ -2363,17 +2570,25 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
/* 3.1 Tx configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->tx); i++) {
if (cntx)
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_A_TX_CNTX_CFG(i), pll_state->tx[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_A_TX_CNTX_CFG(i915, i),
+ pll_state->tx[i]);
else
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_B_TX_CNTX_CFG(i), pll_state->tx[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_B_TX_CNTX_CFG(i915, i),
+ pll_state->tx[i]);
}
/* 3.2 common configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->cmn); i++) {
if (cntx)
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_A_CMN_CNTX_CFG(i), pll_state->cmn[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_A_CMN_CNTX_CFG(i915, i),
+ pll_state->cmn[i]);
else
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_B_CMN_CNTX_CFG(i), pll_state->cmn[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_B_CMN_CNTX_CFG(i915, i),
+ pll_state->cmn[i]);
}
/* 3.3 mpllb or mplla configuration */
@@ -2381,40 +2596,40 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
for (i = 0; i < ARRAY_SIZE(pll_state->mpllb); i++) {
if (cntx)
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLB_CNTX_CFG(i),
+ PHY_C20_A_MPLLB_CNTX_CFG(i915, i),
pll_state->mpllb[i]);
else
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLB_CNTX_CFG(i),
+ PHY_C20_B_MPLLB_CNTX_CFG(i915, i),
pll_state->mpllb[i]);
}
} else {
for (i = 0; i < ARRAY_SIZE(pll_state->mplla); i++) {
if (cntx)
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLA_CNTX_CFG(i),
+ PHY_C20_A_MPLLA_CNTX_CFG(i915, i),
pll_state->mplla[i]);
else
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLA_CNTX_CFG(i),
+ PHY_C20_B_MPLLA_CNTX_CFG(i915, i),
pll_state->mplla[i]);
}
}
/* 4. Program custom width to match the link protocol */
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_WIDTH,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_WIDTH,
PHY_C20_CUSTOM_WIDTH_MASK,
PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(clock, dp)),
MB_WRITE_COMMITTED);
/* 5. For DP or 6. For HDMI */
if (dp) {
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
BIT(6) | PHY_C20_CUSTOM_SERDES_MASK,
BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(clock)),
MB_WRITE_COMMITTED);
} else {
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
BIT(7) | PHY_C20_CUSTOM_SERDES_MASK,
is_hdmi_frl(clock) ? BIT(7) : 0,
MB_WRITE_COMMITTED);
@@ -2428,7 +2643,7 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
* 7. Write Vendor specific registers to toggle context setting to load
* the updated programming toggle context bit
*/
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
BIT(0), cntx ? 0 : 1, MB_WRITE_COMMITTED);
}
@@ -2900,17 +3115,28 @@ void intel_mtl_pll_enable(struct intel_encoder *encoder,
intel_cx0pll_enable(encoder, crtc_state);
}
+static u8 cx0_power_control_disable_val(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_encoder_is_c10phy(encoder))
+ return CX0_P2PG_STATE_DISABLE;
+
+ if (IS_BATTLEMAGE(i915) && encoder->port == PORT_A)
+ return CX0_P2PG_STATE_DISABLE;
+
+ return CX0_P4PG_STATE_DISABLE;
+}
+
static void intel_cx0pll_disable(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_encoder_to_phy(encoder);
- bool is_c10 = intel_encoder_is_c10phy(encoder);
intel_wakeref_t wakeref = intel_cx0_phy_transaction_begin(encoder);
/* 1. Change owned PHY lane power to Disable state. */
intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES,
- is_c10 ? CX0_P2PG_STATE_DISABLE :
- CX0_P4PG_STATE_DISABLE);
+ cx0_power_control_disable_val(encoder));
/*
* 2. Follow the Display Voltage Frequency Switching Sequence Before
@@ -3028,9 +3254,6 @@ static void intel_c10pll_state_verify(const struct intel_crtc_state *state,
const struct intel_c10pll_state *mpllb_sw_state = &state->dpll_hw_state.cx0pll.c10;
int i;
- if (intel_crtc_needs_fastset(state))
- return;
-
for (i = 0; i < ARRAY_SIZE(mpllb_sw_state->pll); i++) {
u8 expected = mpllb_sw_state->pll[i];
@@ -3054,10 +3277,70 @@ static void intel_c10pll_state_verify(const struct intel_crtc_state *state,
void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
struct intel_cx0pll_state *pll_state)
{
- if (intel_encoder_is_c10phy(encoder))
+ pll_state->use_c10 = false;
+
+ pll_state->tbt_mode = intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder));
+ if (pll_state->tbt_mode)
+ return;
+
+ if (intel_encoder_is_c10phy(encoder)) {
intel_c10pll_readout_hw_state(encoder, &pll_state->c10);
- else
+ pll_state->use_c10 = true;
+ } else {
intel_c20pll_readout_hw_state(encoder, &pll_state->c20);
+ }
+}
+
+static bool mtl_compare_hw_state_c10(const struct intel_c10pll_state *a,
+ const struct intel_c10pll_state *b)
+{
+ if (a->tx != b->tx)
+ return false;
+
+ if (a->cmn != b->cmn)
+ return false;
+
+ if (memcmp(&a->pll, &b->pll, sizeof(a->pll)) != 0)
+ return false;
+
+ return true;
+}
+
+static bool mtl_compare_hw_state_c20(const struct intel_c20pll_state *a,
+ const struct intel_c20pll_state *b)
+{
+ if (memcmp(&a->tx, &b->tx, sizeof(a->tx)) != 0)
+ return false;
+
+ if (memcmp(&a->cmn, &b->cmn, sizeof(a->cmn)) != 0)
+ return false;
+
+ if (a->tx[0] & C20_PHY_USE_MPLLB) {
+ if (memcmp(&a->mpllb, &b->mpllb, sizeof(a->mpllb)) != 0)
+ return false;
+ } else {
+ if (memcmp(&a->mplla, &b->mplla, sizeof(a->mplla)) != 0)
+ return false;
+ }
+
+ return true;
+}
+
+bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
+ const struct intel_cx0pll_state *b)
+{
+ if (a->tbt_mode || b->tbt_mode)
+ return true;
+
+ if (a->use_c10 != b->use_c10)
+ return false;
+
+ if (a->use_c10)
+ return mtl_compare_hw_state_c10(&a->c10,
+ &b->c10);
+ else
+ return mtl_compare_hw_state_c20(&a->c20,
+ &b->c20);
}
int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
@@ -3078,9 +3361,10 @@ static void intel_c20pll_state_verify(const struct intel_crtc_state *state,
const struct intel_c20pll_state *mpll_sw_state = &state->dpll_hw_state.cx0pll.c20;
bool sw_use_mpllb = intel_c20phy_use_mpllb(mpll_sw_state);
bool hw_use_mpllb = intel_c20phy_use_mpllb(mpll_hw_state);
+ int clock = intel_c20pll_calc_port_clock(encoder, mpll_sw_state);
int i;
- I915_STATE_WARN(i915, mpll_hw_state->clock != mpll_sw_state->clock,
+ I915_STATE_WARN(i915, mpll_hw_state->clock != clock,
"[CRTC:%d:%s] mismatch in C20: Register CLOCK (expected %d, found %d)",
crtc->base.base.id, crtc->base.name,
mpll_sw_state->clock, mpll_hw_state->clock);
@@ -3142,12 +3426,11 @@ void intel_cx0pll_state_verify(struct intel_atomic_state *state,
return;
encoder = intel_get_crtc_new_encoder(state, new_crtc_state);
+ intel_cx0pll_readout_hw_state(encoder, &mpll_hw_state);
- if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder)))
+ if (mpll_hw_state.tbt_mode)
return;
- intel_cx0pll_readout_hw_state(encoder, &mpll_hw_state);
-
if (intel_encoder_is_c10phy(encoder))
intel_c10pll_state_verify(new_crtc_state, crtc, encoder, &mpll_hw_state.c10);
else
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
index 3e03af3e006c..9004b99bb51f 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
@@ -35,12 +35,12 @@ void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
const struct intel_cx0pll_state *pll_state);
-void intel_c10pll_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_c10pll_state *hw_state);
+void intel_cx0pll_dump_hw_state(struct drm_i915_private *dev_priv,
+ const struct intel_cx0pll_state *hw_state);
void intel_cx0pll_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc);
-void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
- const struct intel_c20pll_state *hw_state);
+bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
+ const struct intel_cx0pll_state *b);
void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
index bdd0c8c4ef97..ab3ae110b68f 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
@@ -254,18 +254,50 @@
#define PHY_C20_VDR_CUSTOM_WIDTH 0xD02
#define PHY_C20_CUSTOM_WIDTH_MASK REG_GENMASK(1, 0)
#define PHY_C20_CUSTOM_WIDTH(val) REG_FIELD_PREP8(PHY_C20_CUSTOM_WIDTH_MASK, val)
-#define PHY_C20_A_TX_CNTX_CFG(idx) (0xCF2E - (idx))
-#define PHY_C20_B_TX_CNTX_CFG(idx) (0xCF2A - (idx))
+
+#define _MTL_C20_A_TX_CNTX_CFG 0xCF2E
+#define _MTL_C20_B_TX_CNTX_CFG 0xCF2A
+#define _MTL_C20_A_CMN_CNTX_CFG 0xCDAA
+#define _MTL_C20_B_CMN_CNTX_CFG 0xCDA5
+#define _MTL_C20_A_MPLLA_CFG 0xCCF0
+#define _MTL_C20_B_MPLLA_CFG 0xCCE5
+#define _MTL_C20_A_MPLLB_CFG 0xCB5A
+#define _MTL_C20_B_MPLLB_CFG 0xCB4E
+
+#define _XE2HPD_C20_A_TX_CNTX_CFG 0xCF5E
+#define _XE2HPD_C20_B_TX_CNTX_CFG 0xCF5A
+#define _XE2HPD_C20_A_CMN_CNTX_CFG 0xCE8E
+#define _XE2HPD_C20_B_CMN_CNTX_CFG 0xCE89
+#define _XE2HPD_C20_A_MPLLA_CFG 0xCE58
+#define _XE2HPD_C20_B_MPLLA_CFG 0xCE4D
+#define _XE2HPD_C20_A_MPLLB_CFG 0xCCC2
+#define _XE2HPD_C20_B_MPLLB_CFG 0xCCB6
+
+#define _IS_XE2HPD_C20(i915) (DISPLAY_VER_FULL(i915) == IP_VER(14, 1))
+
+#define PHY_C20_A_TX_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_TX_CNTX_CFG : _MTL_C20_A_TX_CNTX_CFG) - (idx))
+#define PHY_C20_B_TX_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_TX_CNTX_CFG : _MTL_C20_B_TX_CNTX_CFG) - (idx))
#define C20_PHY_TX_RATE REG_GENMASK(2, 0)
-#define PHY_C20_A_CMN_CNTX_CFG(idx) (0xCDAA - (idx))
-#define PHY_C20_B_CMN_CNTX_CFG(idx) (0xCDA5 - (idx))
-#define PHY_C20_A_MPLLA_CNTX_CFG(idx) (0xCCF0 - (idx))
-#define PHY_C20_B_MPLLA_CNTX_CFG(idx) (0xCCE5 - (idx))
+
+#define PHY_C20_A_CMN_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_CMN_CNTX_CFG : _MTL_C20_A_CMN_CNTX_CFG) - (idx))
+#define PHY_C20_B_CMN_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_CMN_CNTX_CFG : _MTL_C20_B_CMN_CNTX_CFG) - (idx))
+#define PHY_C20_A_MPLLA_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_MPLLA_CFG : _MTL_C20_A_MPLLA_CFG) - (idx))
+#define PHY_C20_B_MPLLA_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_MPLLA_CFG : _MTL_C20_B_MPLLA_CFG) - (idx))
#define C20_MPLLA_FRACEN REG_BIT(14)
#define C20_FB_CLK_DIV4_EN REG_BIT(13)
#define C20_MPLLA_TX_CLK_DIV_MASK REG_GENMASK(10, 8)
-#define PHY_C20_A_MPLLB_CNTX_CFG(idx) (0xCB5A - (idx))
-#define PHY_C20_B_MPLLB_CNTX_CFG(idx) (0xCB4E - (idx))
+
+#define PHY_C20_A_MPLLB_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_MPLLB_CFG : _MTL_C20_A_MPLLB_CFG) - (idx))
+#define PHY_C20_B_MPLLB_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_MPLLB_CFG : _MTL_C20_B_MPLLB_CFG) - (idx))
+
#define C20_MPLLB_TX_CLK_DIV_MASK REG_GENMASK(15, 13)
#define C20_MPLLB_FRACEN REG_BIT(13)
#define C20_REF_CLK_MPLLB_DIV_MASK REG_GENMASK(12, 10)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 6bff169fa8d4..a07aca96e551 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -57,6 +57,7 @@
#include "intel_dp_tunnel.h"
#include "intel_dpio_phy.h"
#include "intel_dsi.h"
+#include "intel_encoder.h"
#include "intel_fdi.h"
#include "intel_fifo_underrun.h"
#include "intel_gmbus.h"
@@ -440,7 +441,8 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
if (intel_dp_needs_vsc_sdp(crtc_state, conn_state))
temp |= DP_MSA_MISC_COLOR_VSC_SDP;
- intel_de_write(dev_priv, TRANS_MSA_MISC(cpu_transcoder), temp);
+ intel_de_write(dev_priv, TRANS_MSA_MISC(dev_priv, cpu_transcoder),
+ temp);
}
static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder)
@@ -603,10 +605,11 @@ void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder,
}
intel_de_write(dev_priv,
- TRANS_DDI_FUNC_CTL2(cpu_transcoder), ctl2);
+ TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder),
+ ctl2);
}
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
intel_ddi_transcoder_func_reg_val_get(encoder,
crtc_state));
}
@@ -626,7 +629,8 @@ intel_ddi_config_transcoder_func(struct intel_encoder *encoder,
ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state);
ctl &= ~TRANS_DDI_FUNC_ENABLE;
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
+ intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
+ ctl);
}
void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
@@ -639,9 +643,11 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
if (DISPLAY_VER(dev_priv) >= 11)
intel_de_write(dev_priv,
- TRANS_DDI_FUNC_CTL2(cpu_transcoder), 0);
+ TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder),
+ 0);
- ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ ctl = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING);
@@ -660,7 +666,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK);
}
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
+ intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
+ ctl);
if (intel_has_quirk(display, QUIRK_INCREASE_DDI_DISABLED_TIME) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
@@ -684,7 +691,7 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder,
if (drm_WARN_ON(dev, !wakeref))
return -ENXIO;
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
hdcp_mask, enable ? hdcp_mask : 0);
intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
return ret;
@@ -718,7 +725,8 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
else
cpu_transcoder = (enum transcoder) pipe;
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
case TRANS_DDI_MODE_SELECT_HDMI:
@@ -782,7 +790,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) {
tmp = intel_de_read(dev_priv,
- TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
+ TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_EDP));
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
default:
@@ -823,7 +831,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
}
tmp = intel_de_read(dev_priv,
- TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder),
trans_wakeref);
@@ -2072,9 +2080,9 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
!encoder->is_clock_enabled(encoder))
return;
- drm_notice(&i915->drm,
- "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n",
- encoder->base.base.id, encoder->base.name);
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n",
+ encoder->base.base.id, encoder->base.name);
encoder->disable_clock(encoder);
}
@@ -2181,7 +2189,8 @@ i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (DISPLAY_VER(dev_priv) >= 12)
- return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state));
+ return TGL_DP_TP_CTL(dev_priv,
+ tgl_dp_tp_transcoder(crtc_state));
else
return DP_TP_CTL(encoder->port);
}
@@ -2192,7 +2201,8 @@ i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (DISPLAY_VER(dev_priv) >= 12)
- return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state));
+ return TGL_DP_TP_STATUS(dev_priv,
+ tgl_dp_tp_transcoder(crtc_state));
else
return DP_TP_STATUS(encoder->port);
}
@@ -2589,7 +2599,7 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us)
*/
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(state, intel_dp, crtc_state);
/* 6.n Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state))
@@ -2731,7 +2741,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us)
*/
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(state, intel_dp, crtc_state);
/* 7.k Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state))
@@ -2798,7 +2808,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
to_intel_connector(conn_state->connector),
crtc_state);
intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(state, intel_dp, crtc_state);
if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
!is_trans_port_sync_mode(crtc_state))
intel_dp_stop_link_train(intel_dp, crtc_state);
@@ -3028,7 +3038,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
if (is_mst) {
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK,
0);
}
@@ -3509,11 +3520,10 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
bool is_tc_port = intel_encoder_is_tc(encoder);
if (is_tc_port) {
- struct intel_crtc *master_crtc =
- to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
intel_tc_port_get_link(dig_port, crtc_state->lane_count);
- intel_ddi_update_active_dpll(state, encoder, master_crtc);
+ intel_ddi_update_active_dpll(state, encoder, crtc);
}
main_link_aux_power_domain_get(dig_port, crtc_state);
@@ -3755,14 +3765,16 @@ static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *de
u32 master_select;
if (DISPLAY_VER(dev_priv) >= 11) {
- u32 ctl2 = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL2(cpu_transcoder));
+ u32 ctl2 = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder));
if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0)
return INVALID_TRANSCODER;
master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2);
} else {
- u32 ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ u32 ctl = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0)
return INVALID_TRANSCODER;
@@ -3818,7 +3830,8 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
u32 temp, flags = 0;
- temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ temp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
if (temp & TRANS_DDI_PHSYNC)
flags |= DRM_MODE_FLAG_PHSYNC;
else
@@ -4014,14 +4027,12 @@ void intel_ddi_get_clock(struct intel_encoder *encoder,
static void mtl_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
- struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+ intel_cx0pll_readout_hw_state(encoder, &crtc_state->dpll_hw_state.cx0pll);
- if (intel_tc_port_in_tbt_alt_mode(dig_port)) {
+ if (crtc_state->dpll_hw_state.cx0pll.tbt_mode)
crtc_state->port_clock = intel_mtl_tbt_calc_port_clock(encoder);
- } else {
- intel_cx0pll_readout_hw_state(encoder, &crtc_state->dpll_hw_state.cx0pll);
+ else
crtc_state->port_clock = intel_cx0pll_calc_port_clock(encoder, &crtc_state->dpll_hw_state.cx0pll);
- }
intel_ddi_get_config(encoder, crtc_state);
}
@@ -4267,10 +4278,10 @@ static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state
{
/*
* FIXME the modeset sequence is currently wrong and
- * can't deal with bigjoiner + port sync at the same time.
+ * can't deal with joiner + port sync at the same time.
*/
return crtc_state1->hw.active && crtc_state2->hw.active &&
- !crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes &&
+ !crtc_state1->joiner_pipes && !crtc_state2->joiner_pipes &&
crtc_state1->output_types == crtc_state2->output_types &&
crtc_state1->output_format == crtc_state2->output_format &&
crtc_state1->lane_count == crtc_state2->lane_count &&
@@ -4444,35 +4455,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
return connector;
}
-static int modeset_pipe(struct drm_crtc *crtc,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct drm_atomic_state *state;
- struct drm_crtc_state *crtc_state;
- int ret;
-
- state = drm_atomic_state_alloc(crtc->dev);
- if (!state)
- return -ENOMEM;
-
- state->acquire_ctx = ctx;
- to_intel_atomic_state(state)->internal = true;
-
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto out;
- }
-
- crtc_state->connectors_changed = true;
-
- ret = drm_atomic_commit(state);
-out:
- drm_atomic_state_put(state);
-
- return ret;
-}
-
static int intel_hdmi_reset_link(struct intel_encoder *encoder,
struct drm_modeset_acquire_ctx *ctx)
{
@@ -4542,7 +4524,18 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
* would be perfectly happy if were to just reconfigure
* the SCDC settings on the fly.
*/
- return modeset_pipe(&crtc->base, ctx);
+ return intel_modeset_commit_pipes(dev_priv, BIT(crtc->pipe), ctx);
+}
+
+static void intel_ddi_link_check(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+ /* TODO: Move checking the HDMI link state here as well. */
+ drm_WARN_ON(&i915->drm, !dig_port->dp.attached_connector);
+
+ intel_dp_link_check(encoder);
}
static enum intel_hotplug_state
@@ -4566,14 +4559,13 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
state = intel_encoder_hotplug(encoder, connector);
if (!intel_tc_port_link_reset(dig_port)) {
- intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret) {
- if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA)
+ if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+ intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret)
ret = intel_hdmi_reset_link(encoder, &ctx);
- else
- ret = intel_dp_retrain_link(encoder, &ctx);
+ drm_WARN_ON(encoder->base.dev, ret);
+ } else {
+ intel_dp_check_link_state(intel_dp);
}
-
- drm_WARN_ON(encoder->base.dev, ret);
}
/*
@@ -4788,6 +4780,11 @@ static void intel_ddi_tc_encoder_suspend_complete(struct intel_encoder *encoder)
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ /*
+ * TODO: Move this to intel_dp_encoder_suspend(),
+ * once modeset locking around that is removed.
+ */
+ intel_encoder_link_check_flush_work(encoder);
intel_tc_port_suspend(dig_port);
}
@@ -4978,6 +4975,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv,
"DDI %c/PHY %c", port_name(port), phy_name(phy));
}
+ intel_encoder_link_check_init(encoder, intel_ddi_link_check);
+
mutex_init(&dig_port->hdcp_mutex);
dig_port->num_hdcp_streams = 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 273323f30ae2..c2c388212e2e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -54,6 +54,7 @@
#include "i915_reg.h"
#include "i915_utils.h"
#include "i9xx_plane.h"
+#include "i9xx_plane_regs.h"
#include "i9xx_wm.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
@@ -65,6 +66,9 @@
#include "intel_crt.h"
#include "intel_crtc.h"
#include "intel_crtc_state_dump.h"
+#include "intel_cursor_regs.h"
+#include "intel_cx0_phy.h"
+#include "intel_cursor.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_driver.h"
@@ -109,6 +113,7 @@
#include "intel_sdvo.h"
#include "intel_snps_phy.h"
#include "intel_tc.h"
+#include "intel_tdf.h"
#include "intel_tv.h"
#include "intel_vblank.h"
#include "intel_vdsc.h"
@@ -118,6 +123,7 @@
#include "intel_wm.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
+#include "skl_universal_plane_regs.h"
#include "skl_watermark.h"
#include "vlv_dpio_phy_regs.h"
#include "vlv_dsi.h"
@@ -241,53 +247,53 @@ is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
is_trans_port_sync_slave(crtc_state);
}
-static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state)
+static enum pipe joiner_primary_pipe(const struct intel_crtc_state *crtc_state)
{
- return ffs(crtc_state->bigjoiner_pipes) - 1;
+ return ffs(crtc_state->joiner_pipes) - 1;
}
-u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state)
+u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state)
{
- if (crtc_state->bigjoiner_pipes)
- return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state));
+ if (crtc_state->joiner_pipes)
+ return crtc_state->joiner_pipes & ~BIT(joiner_primary_pipe(crtc_state));
else
return 0;
}
-bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state)
+bool intel_crtc_is_joiner_secondary(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- return crtc_state->bigjoiner_pipes &&
- crtc->pipe != bigjoiner_master_pipe(crtc_state);
+ return crtc_state->joiner_pipes &&
+ crtc->pipe != joiner_primary_pipe(crtc_state);
}
-bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state)
+bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- return crtc_state->bigjoiner_pipes &&
- crtc->pipe == bigjoiner_master_pipe(crtc_state);
+ return crtc_state->joiner_pipes &&
+ crtc->pipe == joiner_primary_pipe(crtc_state);
}
-static int intel_bigjoiner_num_pipes(const struct intel_crtc_state *crtc_state)
+static int intel_joiner_num_pipes(const struct intel_crtc_state *crtc_state)
{
- return hweight8(crtc_state->bigjoiner_pipes);
+ return hweight8(crtc_state->joiner_pipes);
}
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- return BIT(crtc->pipe) | crtc_state->bigjoiner_pipes;
+ return BIT(crtc->pipe) | crtc_state->joiner_pipes;
}
-struct intel_crtc *intel_master_crtc(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);
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
- return intel_crtc_for_pipe(i915, bigjoiner_master_pipe(crtc_state));
+ if (intel_crtc_is_joiner_secondary(crtc_state))
+ return intel_crtc_for_pipe(i915, joiner_primary_pipe(crtc_state));
else
return to_intel_crtc(crtc_state->uapi.crtc);
}
@@ -302,7 +308,7 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
/* Wait for the Pipe State to go off */
- if (intel_de_wait_for_clear(dev_priv, TRANSCONF(cpu_transcoder),
+ if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
TRANSCONF_STATE_ENABLE, 100))
drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n");
} else {
@@ -324,7 +330,8 @@ void assert_transcoder(struct drm_i915_private *dev_priv,
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
if (wakeref) {
- u32 val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ u32 val = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
cur_state = !!(val & TRANSCONF_ENABLE);
intel_display_power_put(dev_priv, power_domain, wakeref);
@@ -377,11 +384,11 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
fallthrough;
case PORT_B:
port_mask = DPLL_PORTB_READY_MASK;
- dpll_reg = DPLL(0);
+ dpll_reg = DPLL(dev_priv, 0);
break;
case PORT_C:
port_mask = DPLL_PORTC_READY_MASK;
- dpll_reg = DPLL(0);
+ dpll_reg = DPLL(dev_priv, 0);
expected_mask <<= 4;
break;
case PORT_D:
@@ -433,7 +440,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
/* Wa_22012358565:adl-p */
if (DISPLAY_VER(dev_priv) == 13)
- intel_de_rmw(dev_priv, PIPE_ARB_CTL(pipe),
+ intel_de_rmw(dev_priv, PIPE_ARB_CTL(dev_priv, pipe),
0, PIPE_ARB_USE_PROG_SLOTS);
if (DISPLAY_VER(dev_priv) >= 14) {
@@ -448,7 +455,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
clear, set);
}
- val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
if (val & TRANSCONF_ENABLE) {
/* we keep both pipes enabled on 830 */
drm_WARN_ON(&dev_priv->drm, !IS_I830(dev_priv));
@@ -463,9 +470,9 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
TRANSCONF_PIXEL_COUNT_SCALING_X4);
}
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder),
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
val | TRANSCONF_ENABLE);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
/*
* Until the pipe starts PIPEDSL reads will return a stale value,
@@ -494,7 +501,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
*/
assert_planes_disabled(crtc);
- val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
if ((val & TRANSCONF_ENABLE) == 0)
return;
@@ -514,7 +521,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
old_crtc_state->dsc.compression_enable)
val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK;
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
if (DISPLAY_VER(dev_priv) >= 12)
intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
@@ -797,14 +804,14 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
const struct drm_connector_state *connector_state;
const struct drm_connector *connector;
struct intel_encoder *encoder = NULL;
- struct intel_crtc *master_crtc;
+ struct intel_crtc *primary_crtc;
int num_encoders = 0;
int i;
- master_crtc = intel_master_crtc(crtc_state);
+ primary_crtc = intel_primary_crtc(crtc_state);
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
- if (connector_state->crtc != &master_crtc->base)
+ if (connector_state->crtc != &primary_crtc->base)
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
@@ -813,7 +820,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
drm_WARN(state->base.dev, num_encoders != 1,
"%d encoders for pipe %c\n",
- num_encoders, pipe_name(master_crtc->pipe));
+ num_encoders, pipe_name(primary_crtc->pipe));
return encoder;
}
@@ -1000,6 +1007,13 @@ static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state,
old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full;
}
+static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state,
+ const struct intel_crtc_state *new_crtc_state)
+{
+ return old_crtc_state->cmrr.cmrr_m != new_crtc_state->cmrr.cmrr_m ||
+ old_crtc_state->cmrr.cmrr_n != new_crtc_state->cmrr.cmrr_n;
+}
+
static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
@@ -1140,15 +1154,15 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,
int i;
for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
- if (plane->need_async_flip_disable_wa &&
+ if (plane->need_async_flip_toggle_wa &&
plane->pipe == crtc->pipe &&
disable_async_flip_planes & BIT(plane->id)) {
/*
* Apart from the async flip bit we want to
* preserve the old state for the plane.
*/
- plane->async_flip(plane, old_crtc_state,
- old_plane_state, false);
+ intel_plane_async_flip(plane, old_crtc_state,
+ old_plane_state, false);
need_vbl_wait = true;
}
}
@@ -1641,7 +1655,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
intel_vrr_set_transcoder_timings(crtc_state);
if (cpu_transcoder != TRANSCODER_EDP)
- intel_de_write(dev_priv, TRANS_MULT(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_MULT(dev_priv, cpu_transcoder),
crtc_state->pixel_multiplier - 1);
hsw_set_frame_start_delay(crtc_state);
@@ -1856,16 +1870,17 @@ static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
* according to register description and PRM.
*/
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, PFIT_CONTROL) & PFIT_ENABLE);
+ intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)) & PFIT_ENABLE);
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
- intel_de_write(dev_priv, PFIT_PGM_RATIOS,
+ intel_de_write(dev_priv, PFIT_PGM_RATIOS(dev_priv),
crtc_state->gmch_pfit.pgm_ratios);
- intel_de_write(dev_priv, PFIT_CONTROL, crtc_state->gmch_pfit.control);
+ intel_de_write(dev_priv, PFIT_CONTROL(dev_priv),
+ crtc_state->gmch_pfit.control);
/* Border color in case we don't scale up to the full screen. Black by
* default, change to something else for debugging. */
- intel_de_write(dev_priv, BCLRPAT(crtc->pipe), 0);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, crtc->pipe), 0);
}
/* Prefer intel_encoder_is_combo() */
@@ -1894,11 +1909,10 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy)
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
{
/*
- * DG2's "TC1", although TC-capable output, doesn't share the same flow
- * as other platforms on the display engine side and rather rely on the
- * SNPS PHY, that is programmed separately
+ * Discrete GPU phy's are not attached to FIA's to support TC
+ * subsystem Legacy or non-legacy, and only support native DP/HDMI
*/
- if (IS_DG2(dev_priv))
+ if (IS_DGFX(dev_priv))
return false;
if (DISPLAY_VER(dev_priv) >= 13)
@@ -2102,8 +2116,9 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
intel_de_write(dev_priv, VLV_PIPE_MSA_MISC(pipe), 0);
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
- intel_de_write(dev_priv, CHV_BLEND(pipe), CHV_BLEND_LEGACY);
- intel_de_write(dev_priv, CHV_CANVAS(pipe), 0);
+ intel_de_write(dev_priv, CHV_BLEND(dev_priv, pipe),
+ CHV_BLEND_LEGACY);
+ intel_de_write(dev_priv, CHV_CANVAS(dev_priv, pipe), 0);
}
crtc->active = true;
@@ -2191,8 +2206,8 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder);
drm_dbg_kms(&dev_priv->drm, "disabling pfit, current: 0x%08x\n",
- intel_de_read(dev_priv, PFIT_CONTROL));
- intel_de_write(dev_priv, PFIT_CONTROL, 0);
+ intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)));
+ intel_de_write(dev_priv, PFIT_CONTROL(dev_priv), 0);
}
static void i9xx_crtc_disable(struct intel_atomic_state *state,
@@ -2314,10 +2329,10 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
ilk_pipe_pixel_rate(crtc_state);
}
-static void intel_bigjoiner_adjust_timings(const struct intel_crtc_state *crtc_state,
- struct drm_display_mode *mode)
+static void intel_joiner_adjust_timings(const struct intel_crtc_state *crtc_state,
+ struct drm_display_mode *mode)
{
- int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
+ int num_pipes = intel_joiner_num_pipes(crtc_state);
if (num_pipes < 2)
return;
@@ -2381,11 +2396,11 @@ 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_bigjoiner_num_pipes(crtc_state) ?: 1);
+ (intel_joiner_num_pipes(crtc_state) ?: 1);
mode->vdisplay = drm_rect_height(&crtc_state->pipe_src);
- /* Derive per-pipe timings in case bigjoiner is used */
- intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
+ /* Derive per-pipe timings in case joiner is used */
+ intel_joiner_adjust_timings(crtc_state, pipe_mode);
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
intel_crtc_compute_pixel_rate(crtc_state);
@@ -2399,9 +2414,9 @@ void intel_encoder_get_config(struct intel_encoder *encoder,
intel_crtc_readout_derived_state(crtc_state);
}
-static void intel_bigjoiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
+static void intel_joiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
{
- int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
+ int num_pipes = intel_joiner_num_pipes(crtc_state);
int width, height;
if (num_pipes < 2)
@@ -2419,7 +2434,7 @@ static int intel_crtc_compute_pipe_src(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);
- intel_bigjoiner_compute_pipe_src(crtc_state);
+ intel_joiner_compute_pipe_src(crtc_state);
/*
* Pipe horizontal size must be even in:
@@ -2464,8 +2479,8 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
/* Expand MSO per-segment transcoder timings to full */
intel_splitter_adjust_timings(crtc_state, pipe_mode);
- /* Derive per-pipe timings in case bigjoiner is used */
- intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
+ /* Derive per-pipe timings in case joiner is used */
+ intel_joiner_adjust_timings(crtc_state, pipe_mode);
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
if (DISPLAY_VER(i915) < 4) {
@@ -2634,8 +2649,10 @@ void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) >= 5)
intel_set_m_n(dev_priv, m_n,
- PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
- PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
+ PIPE_DATA_M1(dev_priv, transcoder),
+ PIPE_DATA_N1(dev_priv, transcoder),
+ PIPE_LINK_M1(dev_priv, transcoder),
+ PIPE_LINK_N1(dev_priv, transcoder));
else
intel_set_m_n(dev_priv, m_n,
PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
@@ -2652,8 +2669,10 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc,
return;
intel_set_m_n(dev_priv, m_n,
- PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
- PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
+ PIPE_DATA_M2(dev_priv, transcoder),
+ PIPE_DATA_N2(dev_priv, transcoder),
+ PIPE_LINK_M2(dev_priv, transcoder),
+ PIPE_LINK_N2(dev_priv, transcoder));
}
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
@@ -2692,7 +2711,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
* TRANS_SET_CONTEXT_LATENCY to configure the pipe vblank start.
*/
if (DISPLAY_VER(dev_priv) >= 13) {
- intel_de_write(dev_priv, TRANS_SET_CONTEXT_LATENCY(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder),
crtc_vblank_start - crtc_vdisplay);
/*
@@ -2703,26 +2723,27 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
}
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write(dev_priv, TRANS_VSYNCSHIFT(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_VSYNCSHIFT(dev_priv, cpu_transcoder),
vsyncshift);
- intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder),
HACTIVE(adjusted_mode->crtc_hdisplay - 1) |
HTOTAL(adjusted_mode->crtc_htotal - 1));
- intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder),
HBLANK_START(adjusted_mode->crtc_hblank_start - 1) |
HBLANK_END(adjusted_mode->crtc_hblank_end - 1));
- intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder),
HSYNC_START(adjusted_mode->crtc_hsync_start - 1) |
HSYNC_END(adjusted_mode->crtc_hsync_end - 1));
- intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(crtc_vblank_start - 1) |
VBLANK_END(crtc_vblank_end - 1));
- intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder),
VSYNC_START(adjusted_mode->crtc_vsync_start - 1) |
VSYNC_END(adjusted_mode->crtc_vsync_end - 1));
@@ -2732,7 +2753,7 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
* bits. */
if (IS_HASWELL(dev_priv) && cpu_transcoder == TRANSCODER_EDP &&
(pipe == PIPE_B || pipe == PIPE_C))
- intel_de_write(dev_priv, TRANS_VTOTAL(pipe),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, pipe),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
}
@@ -2756,14 +2777,14 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc
* The hardware actually ignores TRANS_VBLANK.VBLANK_END in DP mode.
* But let's write it anyway to keep the state checker happy.
*/
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(crtc_vblank_start - 1) |
VBLANK_END(crtc_vblank_end - 1));
/*
* The double buffer latch point for TRANS_VTOTAL
* is the transcoder's undelayed vblank.
*/
- intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
}
@@ -2779,7 +2800,7 @@ static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
/* pipesrc controls the size that is scaled from, which should
* always be the user's requested size.
*/
- intel_de_write(dev_priv, PIPESRC(pipe),
+ intel_de_write(dev_priv, PIPESRC(dev_priv, pipe),
PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1));
}
@@ -2793,9 +2814,11 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
if (DISPLAY_VER(dev_priv) >= 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
- return intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW;
+ return intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW;
else
- return intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)) & TRANSCONF_INTERLACE_MASK;
+ return intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK;
}
static void intel_get_transcoder_timings(struct intel_crtc *crtc,
@@ -2807,31 +2830,33 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
u32 tmp;
- tmp = intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder));
adjusted_mode->crtc_hdisplay = REG_FIELD_GET(HACTIVE_MASK, tmp) + 1;
adjusted_mode->crtc_htotal = REG_FIELD_GET(HTOTAL_MASK, tmp) + 1;
if (!transcoder_is_dsi(cpu_transcoder)) {
- tmp = intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_HBLANK(dev_priv, cpu_transcoder));
adjusted_mode->crtc_hblank_start = REG_FIELD_GET(HBLANK_START_MASK, tmp) + 1;
adjusted_mode->crtc_hblank_end = REG_FIELD_GET(HBLANK_END_MASK, tmp) + 1;
}
- tmp = intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder));
adjusted_mode->crtc_hsync_start = REG_FIELD_GET(HSYNC_START_MASK, tmp) + 1;
adjusted_mode->crtc_hsync_end = REG_FIELD_GET(HSYNC_END_MASK, tmp) + 1;
- tmp = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder));
adjusted_mode->crtc_vdisplay = REG_FIELD_GET(VACTIVE_MASK, tmp) + 1;
adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1;
/* FIXME TGL+ DSI transcoders have this! */
if (!transcoder_is_dsi(cpu_transcoder)) {
- tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder));
adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1;
adjusted_mode->crtc_vblank_end = REG_FIELD_GET(VBLANK_END_MASK, tmp) + 1;
}
- tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder));
adjusted_mode->crtc_vsync_start = REG_FIELD_GET(VSYNC_START_MASK, tmp) + 1;
adjusted_mode->crtc_vsync_end = REG_FIELD_GET(VSYNC_END_MASK, tmp) + 1;
@@ -2844,24 +2869,25 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) >= 13 && !transcoder_is_dsi(cpu_transcoder))
adjusted_mode->crtc_vblank_start =
adjusted_mode->crtc_vdisplay +
- intel_de_read(dev_priv, TRANS_SET_CONTEXT_LATENCY(cpu_transcoder));
+ intel_de_read(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder));
}
-static void intel_bigjoiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
+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_bigjoiner_num_pipes(crtc_state);
- enum pipe master_pipe, pipe = crtc->pipe;
+ int num_pipes = intel_joiner_num_pipes(crtc_state);
+ enum pipe primary_pipe, pipe = crtc->pipe;
int width;
if (num_pipes < 2)
return;
- master_pipe = bigjoiner_master_pipe(crtc_state);
+ primary_pipe = joiner_primary_pipe(crtc_state);
width = drm_rect_width(&crtc_state->pipe_src);
drm_rect_translate_to(&crtc_state->pipe_src,
- (pipe - master_pipe) * width, 0);
+ (pipe - primary_pipe) * width, 0);
}
static void intel_get_pipe_src_size(struct intel_crtc *crtc,
@@ -2871,13 +2897,13 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = to_i915(dev);
u32 tmp;
- tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe));
+ tmp = intel_de_read(dev_priv, PIPESRC(dev_priv, crtc->pipe));
drm_rect_init(&pipe_config->pipe_src, 0, 0,
REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1,
REG_FIELD_GET(PIPESRC_HEIGHT_MASK, tmp) + 1);
- intel_bigjoiner_adjust_pipe_src(pipe_config);
+ intel_joiner_adjust_pipe_src(pipe_config);
}
void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
@@ -2944,8 +2970,8 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
static bool i9xx_has_pfit(struct drm_i915_private *dev_priv)
@@ -2967,7 +2993,7 @@ static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
if (!i9xx_has_pfit(dev_priv))
return;
- tmp = intel_de_read(dev_priv, PFIT_CONTROL);
+ tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv));
if (!(tmp & PFIT_ENABLE))
return;
@@ -2982,7 +3008,7 @@ static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
crtc_state->gmch_pfit.control = tmp;
crtc_state->gmch_pfit.pgm_ratios =
- intel_de_read(dev_priv, PFIT_PGM_RATIOS);
+ intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv));
}
static enum intel_output_format
@@ -3027,7 +3053,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
ret = false;
- tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
if (!(tmp & TRANSCONF_ENABLE))
goto out;
@@ -3174,8 +3201,8 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)
val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
val |= TRANSCONF_MSA_TIMING_DELAY(crtc_state->msa_timing_delay);
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
@@ -3204,8 +3231,8 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
val |= TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW;
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state)
@@ -3324,8 +3351,10 @@ void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) >= 5)
intel_get_m_n(dev_priv, m_n,
- PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
- PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
+ PIPE_DATA_M1(dev_priv, transcoder),
+ PIPE_DATA_N1(dev_priv, transcoder),
+ PIPE_LINK_M1(dev_priv, transcoder),
+ PIPE_LINK_N1(dev_priv, transcoder));
else
intel_get_m_n(dev_priv, m_n,
PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
@@ -3342,8 +3371,10 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
return;
intel_get_m_n(dev_priv, m_n,
- PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
- PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
+ PIPE_DATA_M2(dev_priv, transcoder),
+ PIPE_DATA_N2(dev_priv, transcoder),
+ PIPE_LINK_M2(dev_priv, transcoder),
+ PIPE_LINK_N2(dev_priv, transcoder));
}
static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state)
@@ -3400,7 +3431,8 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
pipe_config->shared_dpll = NULL;
ret = false;
- tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
if (!(tmp & TRANSCONF_ENABLE))
goto out;
@@ -3461,7 +3493,7 @@ out:
return ret;
}
-static u8 bigjoiner_pipes(struct drm_i915_private *i915)
+static u8 joiner_pipes(struct drm_i915_private *i915)
{
u8 pipes;
@@ -3485,21 +3517,22 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref)
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
return tmp & TRANS_DDI_FUNC_ENABLE;
}
-static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
- u8 *master_pipes, u8 *slave_pipes)
+static void enabled_joiner_pipes(struct drm_i915_private *dev_priv,
+ u8 *primary_pipes, u8 *secondary_pipes)
{
struct intel_crtc *crtc;
- *master_pipes = 0;
- *slave_pipes = 0;
+ *primary_pipes = 0;
+ *secondary_pipes = 0;
for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc,
- bigjoiner_pipes(dev_priv)) {
+ joiner_pipes(dev_priv)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
intel_wakeref_t wakeref;
@@ -3511,10 +3544,10 @@ static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
if (!(tmp & BIG_JOINER_ENABLE))
continue;
- if (tmp & MASTER_BIG_JOINER_ENABLE)
- *master_pipes |= BIT(pipe);
+ if (tmp & PRIMARY_BIG_JOINER_ENABLE)
+ *primary_pipes |= BIT(pipe);
else
- *slave_pipes |= BIT(pipe);
+ *secondary_pipes |= BIT(pipe);
}
if (DISPLAY_VER(dev_priv) < 13)
@@ -3524,48 +3557,48 @@ static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
- if (tmp & UNCOMPRESSED_JOINER_MASTER)
- *master_pipes |= BIT(pipe);
- if (tmp & UNCOMPRESSED_JOINER_SLAVE)
- *slave_pipes |= BIT(pipe);
+ if (tmp & UNCOMPRESSED_JOINER_PRIMARY)
+ *primary_pipes |= BIT(pipe);
+ if (tmp & UNCOMPRESSED_JOINER_SECONDARY)
+ *secondary_pipes |= BIT(pipe);
}
}
- /* Bigjoiner pipes should always be consecutive master and slave */
- drm_WARN(&dev_priv->drm, *slave_pipes != *master_pipes << 1,
- "Bigjoiner misconfigured (master pipes 0x%x, slave pipes 0x%x)\n",
- *master_pipes, *slave_pipes);
+ /* 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 enum pipe get_bigjoiner_master_pipe(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
+static enum pipe get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes)
{
- if ((slave_pipes & BIT(pipe)) == 0)
+ if ((secondary_pipes & BIT(pipe)) == 0)
return pipe;
/* ignore everything above our pipe */
- master_pipes &= ~GENMASK(7, pipe);
+ primary_pipes &= ~GENMASK(7, pipe);
- /* highest remaining bit should be our master pipe */
- return fls(master_pipes) - 1;
+ /* highest remaining bit should be our primary pipe */
+ return fls(primary_pipes) - 1;
}
-static u8 get_bigjoiner_slave_pipes(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
+static u8 get_joiner_secondary_pipes(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes)
{
- enum pipe master_pipe, next_master_pipe;
+ enum pipe primary_pipe, next_primary_pipe;
- master_pipe = get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes);
+ primary_pipe = get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes);
- if ((master_pipes & BIT(master_pipe)) == 0)
+ if ((primary_pipes & BIT(primary_pipe)) == 0)
return 0;
- /* ignore our master pipe and everything below it */
- master_pipes &= ~GENMASK(master_pipe, 0);
+ /* ignore our primary pipe and everything below it */
+ primary_pipes &= ~GENMASK(primary_pipe, 0);
/* make sure a high bit is set for the ffs() */
- master_pipes |= BIT(7);
- /* lowest remaining bit should be the next master pipe */
- next_master_pipe = ffs(master_pipes) - 1;
+ primary_pipes |= BIT(7);
+ /* lowest remaining bit should be the next primary pipe */
+ next_primary_pipe = ffs(primary_pipes) - 1;
- return slave_pipes & GENMASK(next_master_pipe - 1, master_pipe);
+ return secondary_pipes & GENMASK(next_primary_pipe - 1, primary_pipe);
}
static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
@@ -3584,7 +3617,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = to_i915(dev);
u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv);
enum transcoder cpu_transcoder;
- u8 master_pipes, slave_pipes;
+ u8 primary_pipes, secondary_pipes;
u8 enabled_transcoders = 0;
/*
@@ -3600,7 +3633,8 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref)
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
if (!(tmp & TRANS_DDI_FUNC_ENABLE))
continue;
@@ -3630,16 +3664,16 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
enabled_transcoders |= BIT(cpu_transcoder);
}
- /* single pipe or bigjoiner master */
+ /* single pipe or joiner primary */
cpu_transcoder = (enum transcoder) crtc->pipe;
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
enabled_transcoders |= BIT(cpu_transcoder);
- /* bigjoiner slave -> consider the master pipe's transcoder as well */
- enabled_bigjoiner_pipes(dev_priv, &master_pipes, &slave_pipes);
- if (slave_pipes & BIT(crtc->pipe)) {
+ /* joiner secondary -> consider the primary pipe's transcoder as well */
+ enabled_joiner_pipes(dev_priv, &primary_pipes, &secondary_pipes);
+ if (secondary_pipes & BIT(crtc->pipe)) {
cpu_transcoder = (enum transcoder)
- get_bigjoiner_master_pipe(crtc->pipe, master_pipes, slave_pipes);
+ get_joiner_primary_pipe(crtc->pipe, primary_pipes, secondary_pipes);
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
enabled_transcoders |= BIT(cpu_transcoder);
}
@@ -3707,13 +3741,15 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
return false;
if (hsw_panel_transcoders(dev_priv) & BIT(pipe_config->cpu_transcoder)) {
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, pipe_config->cpu_transcoder));
if ((tmp & TRANS_DDI_EDP_INPUT_MASK) == TRANS_DDI_EDP_INPUT_A_ONOFF)
pipe_config->pch_pfit.force_thru = true;
}
- tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
return tmp & TRANSCONF_ENABLE;
}
@@ -3764,21 +3800,21 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
return transcoder_is_dsi(pipe_config->cpu_transcoder);
}
-static void intel_bigjoiner_get_config(struct intel_crtc_state *crtc_state)
+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 master_pipes, slave_pipes;
+ u8 primary_pipes, secondary_pipes;
enum pipe pipe = crtc->pipe;
- enabled_bigjoiner_pipes(i915, &master_pipes, &slave_pipes);
+ enabled_joiner_pipes(i915, &primary_pipes, &secondary_pipes);
- if (((master_pipes | slave_pipes) & BIT(pipe)) == 0)
+ if (((primary_pipes | secondary_pipes) & BIT(pipe)) == 0)
return;
- crtc_state->bigjoiner_pipes =
- BIT(get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes)) |
- get_bigjoiner_slave_pipes(pipe, master_pipes, slave_pipes);
+ crtc_state->joiner_pipes =
+ BIT(get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes)) |
+ get_joiner_secondary_pipes(pipe, primary_pipes, secondary_pipes);
}
static bool hsw_get_pipe_config(struct intel_crtc *crtc,
@@ -3805,7 +3841,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
if (!active)
goto out;
- intel_bigjoiner_get_config(pipe_config);
+ intel_joiner_get_config(pipe_config);
intel_dsc_get_config(pipe_config);
if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
@@ -3819,7 +3855,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
if (IS_HASWELL(dev_priv)) {
u32 tmp = intel_de_read(dev_priv,
- TRANSCONF(pipe_config->cpu_transcoder));
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
if (tmp & TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW)
pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
@@ -3854,7 +3890,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
pipe_config->pixel_multiplier =
intel_de_read(dev_priv,
- TRANS_MULT(pipe_config->cpu_transcoder)) + 1;
+ TRANS_MULT(dev_priv, pipe_config->cpu_transcoder)) + 1;
} else {
pipe_config->pixel_multiplier = 1;
}
@@ -4030,11 +4066,12 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
return 0;
}
-static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
+static int icl_check_nv12_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.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 *plane, *linked;
struct intel_plane_state *plane_state;
int i;
@@ -4119,13 +4156,13 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
linked_state->uapi.dst = plane_state->uapi.dst;
if (icl_is_hdr_plane(dev_priv, plane->id)) {
- if (linked->id == PLANE_SPRITE5)
+ if (linked->id == PLANE_7)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL;
- else if (linked->id == PLANE_SPRITE4)
+ else if (linked->id == PLANE_6)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL;
- else if (linked->id == PLANE_SPRITE3)
+ else if (linked->id == PLANE_5)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL;
- else if (linked->id == PLANE_SPRITE2)
+ else if (linked->id == PLANE_4)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL;
else
MISSING_CASE(linked->id);
@@ -4135,17 +4172,6 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
return 0;
}
-static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
- const struct intel_crtc_state *old_crtc_state =
- intel_atomic_get_old_crtc_state(state, crtc);
-
- return !old_crtc_state->c8_planes != !new_crtc_state->c8_planes;
-}
-
static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_state)
{
const struct drm_display_mode *pipe_mode =
@@ -4244,18 +4270,9 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
return ret;
}
- /*
- * May need to update pipe gamma enable bits
- * when C8 planes are getting enabled/disabled.
- */
- if (c8_planes_changed(crtc_state))
- crtc_state->uapi.color_mgmt_changed = true;
-
- if (intel_crtc_needs_color_update(crtc_state)) {
- ret = intel_color_check(crtc_state);
- if (ret)
- return ret;
- }
+ ret = intel_color_check(state, crtc);
+ if (ret)
+ return ret;
ret = intel_compute_pipe_wm(state, crtc);
if (ret) {
@@ -4464,7 +4481,7 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
crtc_state->uapi.degamma_lut);
@@ -4481,7 +4498,7 @@ intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state,
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
crtc_state->hw.enable = crtc_state->uapi.enable;
crtc_state->hw.active = crtc_state->uapi.active;
@@ -4495,79 +4512,79 @@ intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state,
}
static void
-copy_bigjoiner_crtc_state_nomodeset(struct intel_atomic_state *state,
- struct intel_crtc *slave_crtc)
+copy_joiner_crtc_state_nomodeset(struct intel_atomic_state *state,
+ struct intel_crtc *secondary_crtc)
{
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, slave_crtc);
- struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
- const struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
+ struct intel_crtc_state *secondary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, secondary_crtc);
+ struct intel_crtc *primary_crtc = intel_primary_crtc(secondary_crtc_state);
+ const struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
- drm_property_replace_blob(&slave_crtc_state->hw.degamma_lut,
- master_crtc_state->hw.degamma_lut);
- drm_property_replace_blob(&slave_crtc_state->hw.gamma_lut,
- master_crtc_state->hw.gamma_lut);
- drm_property_replace_blob(&slave_crtc_state->hw.ctm,
- master_crtc_state->hw.ctm);
+ drm_property_replace_blob(&secondary_crtc_state->hw.degamma_lut,
+ primary_crtc_state->hw.degamma_lut);
+ drm_property_replace_blob(&secondary_crtc_state->hw.gamma_lut,
+ primary_crtc_state->hw.gamma_lut);
+ drm_property_replace_blob(&secondary_crtc_state->hw.ctm,
+ primary_crtc_state->hw.ctm);
- slave_crtc_state->uapi.color_mgmt_changed = master_crtc_state->uapi.color_mgmt_changed;
+ secondary_crtc_state->uapi.color_mgmt_changed = primary_crtc_state->uapi.color_mgmt_changed;
}
static int
-copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
- struct intel_crtc *slave_crtc)
-{
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, slave_crtc);
- struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
- const struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
+copy_joiner_crtc_state_modeset(struct intel_atomic_state *state,
+ struct intel_crtc *secondary_crtc)
+{
+ struct intel_crtc_state *secondary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, secondary_crtc);
+ struct intel_crtc *primary_crtc = intel_primary_crtc(secondary_crtc_state);
+ const struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
struct intel_crtc_state *saved_state;
- WARN_ON(master_crtc_state->bigjoiner_pipes !=
- slave_crtc_state->bigjoiner_pipes);
+ WARN_ON(primary_crtc_state->joiner_pipes !=
+ secondary_crtc_state->joiner_pipes);
- saved_state = kmemdup(master_crtc_state, sizeof(*saved_state), GFP_KERNEL);
+ saved_state = kmemdup(primary_crtc_state, sizeof(*saved_state), GFP_KERNEL);
if (!saved_state)
return -ENOMEM;
/* preserve some things from the slave's original crtc state */
- saved_state->uapi = slave_crtc_state->uapi;
- saved_state->scaler_state = slave_crtc_state->scaler_state;
- saved_state->shared_dpll = slave_crtc_state->shared_dpll;
- saved_state->crc_enabled = slave_crtc_state->crc_enabled;
-
- intel_crtc_free_hw_state(slave_crtc_state);
- if (slave_crtc_state->dp_tunnel_ref.tunnel)
- drm_dp_tunnel_ref_put(&slave_crtc_state->dp_tunnel_ref);
- memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
+ saved_state->uapi = secondary_crtc_state->uapi;
+ saved_state->scaler_state = secondary_crtc_state->scaler_state;
+ saved_state->shared_dpll = secondary_crtc_state->shared_dpll;
+ saved_state->crc_enabled = secondary_crtc_state->crc_enabled;
+
+ intel_crtc_free_hw_state(secondary_crtc_state);
+ if (secondary_crtc_state->dp_tunnel_ref.tunnel)
+ drm_dp_tunnel_ref_put(&secondary_crtc_state->dp_tunnel_ref);
+ memcpy(secondary_crtc_state, saved_state, sizeof(*secondary_crtc_state));
kfree(saved_state);
/* Re-init hw state */
- memset(&slave_crtc_state->hw, 0, sizeof(slave_crtc_state->hw));
- slave_crtc_state->hw.enable = master_crtc_state->hw.enable;
- slave_crtc_state->hw.active = master_crtc_state->hw.active;
- drm_mode_copy(&slave_crtc_state->hw.mode,
- &master_crtc_state->hw.mode);
- drm_mode_copy(&slave_crtc_state->hw.pipe_mode,
- &master_crtc_state->hw.pipe_mode);
- drm_mode_copy(&slave_crtc_state->hw.adjusted_mode,
- &master_crtc_state->hw.adjusted_mode);
- slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter;
-
- if (master_crtc_state->dp_tunnel_ref.tunnel)
- drm_dp_tunnel_ref_get(master_crtc_state->dp_tunnel_ref.tunnel,
- &slave_crtc_state->dp_tunnel_ref);
-
- copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
-
- slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
- slave_crtc_state->uapi.connectors_changed = master_crtc_state->uapi.connectors_changed;
- slave_crtc_state->uapi.active_changed = master_crtc_state->uapi.active_changed;
-
- WARN_ON(master_crtc_state->bigjoiner_pipes !=
- slave_crtc_state->bigjoiner_pipes);
+ memset(&secondary_crtc_state->hw, 0, sizeof(secondary_crtc_state->hw));
+ secondary_crtc_state->hw.enable = primary_crtc_state->hw.enable;
+ secondary_crtc_state->hw.active = primary_crtc_state->hw.active;
+ drm_mode_copy(&secondary_crtc_state->hw.mode,
+ &primary_crtc_state->hw.mode);
+ drm_mode_copy(&secondary_crtc_state->hw.pipe_mode,
+ &primary_crtc_state->hw.pipe_mode);
+ drm_mode_copy(&secondary_crtc_state->hw.adjusted_mode,
+ &primary_crtc_state->hw.adjusted_mode);
+ secondary_crtc_state->hw.scaling_filter = primary_crtc_state->hw.scaling_filter;
+
+ if (primary_crtc_state->dp_tunnel_ref.tunnel)
+ drm_dp_tunnel_ref_get(primary_crtc_state->dp_tunnel_ref.tunnel,
+ &secondary_crtc_state->dp_tunnel_ref);
+
+ copy_joiner_crtc_state_nomodeset(state, secondary_crtc);
+
+ secondary_crtc_state->uapi.mode_changed = primary_crtc_state->uapi.mode_changed;
+ secondary_crtc_state->uapi.connectors_changed = primary_crtc_state->uapi.connectors_changed;
+ secondary_crtc_state->uapi.active_changed = primary_crtc_state->uapi.active_changed;
+
+ WARN_ON(primary_crtc_state->joiner_pipes !=
+ secondary_crtc_state->joiner_pipes);
return 0;
}
@@ -5000,6 +5017,24 @@ pipe_config_pll_mismatch(struct drm_printer *p, bool fastset,
intel_dpll_dump_hw_state(i915, p, b);
}
+static void
+pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset,
+ const struct intel_crtc *crtc,
+ const char *name,
+ const struct intel_cx0pll_state *a,
+ const struct intel_cx0pll_state *b)
+{
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ char *chipname = a->use_c10 ? "C10" : "C20";
+
+ pipe_config_mismatch(p, fastset, crtc, name, chipname);
+
+ drm_printf(p, "expected:\n");
+ intel_cx0pll_dump_hw_state(i915, a);
+ drm_printf(p, "found:\n");
+ intel_cx0pll_dump_hw_state(i915, b);
+}
+
bool
intel_pipe_config_compare(const struct intel_crtc_state *current_config,
const struct intel_crtc_state *pipe_config,
@@ -5051,6 +5086,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
} \
} while (0)
+#define PIPE_CONF_CHECK_LLI(name) do { \
+ if (current_config->name != pipe_config->name) { \
+ pipe_config_mismatch(&p, fastset, crtc, __stringify(name), \
+ "(expected %lli, found %lli)", \
+ current_config->name, \
+ pipe_config->name); \
+ ret = false; \
+ } \
+} while (0)
+
#define PIPE_CONF_CHECK_BOOL(name) do { \
if (current_config->name != pipe_config->name) { \
BUILD_BUG_ON_MSG(!__same_type(current_config->name, bool), \
@@ -5103,6 +5148,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
} \
} while (0)
+#define PIPE_CONF_CHECK_PLL_CX0(name) do { \
+ if (!intel_cx0pll_compare_hw_state(&current_config->name, \
+ &pipe_config->name)) { \
+ pipe_config_cx0pll_mismatch(&p, fastset, crtc, __stringify(name), \
+ &current_config->name, \
+ &pipe_config->name); \
+ ret = false; \
+ } \
+} while (0)
+
#define PIPE_CONF_CHECK_TIMINGS(name) do { \
PIPE_CONF_CHECK_I(name.crtc_hdisplay); \
PIPE_CONF_CHECK_I(name.crtc_htotal); \
@@ -5318,9 +5373,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
* Panel replay has to be enabled before link training. PSR doesn't have
* this requirement -> check these only if using panel replay
*/
- if (current_config->has_panel_replay || pipe_config->has_panel_replay) {
+ if (current_config->active_planes &&
+ (current_config->has_panel_replay ||
+ pipe_config->has_panel_replay)) {
PIPE_CONF_CHECK_BOOL(has_psr);
- PIPE_CONF_CHECK_BOOL(has_psr2);
+ PIPE_CONF_CHECK_BOOL(has_sel_update);
PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
PIPE_CONF_CHECK_BOOL(enable_psr2_su_region_et);
PIPE_CONF_CHECK_BOOL(has_panel_replay);
@@ -5335,6 +5392,10 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
if (dev_priv->display.dpll.mgr || HAS_GMCH(dev_priv))
PIPE_CONF_CHECK_PLL(dpll_hw_state);
+ /* FIXME convert MTL+ platforms over to dpll_mgr */
+ if (DISPLAY_VER(dev_priv) >= 14)
+ PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll);
+
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
PIPE_CONF_CHECK_X(dsi_pll.div);
@@ -5365,7 +5426,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_X(sync_mode_slaves_mask);
PIPE_CONF_CHECK_I(master_transcoder);
- PIPE_CONF_CHECK_X(bigjoiner_pipes);
+ PIPE_CONF_CHECK_X(joiner_pipes);
PIPE_CONF_CHECK_BOOL(dsc.config.block_pred_enable);
PIPE_CONF_CHECK_BOOL(dsc.config.convert_rgb);
@@ -5415,10 +5476,14 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_I(vrr.guardband);
PIPE_CONF_CHECK_I(vrr.vsync_start);
PIPE_CONF_CHECK_I(vrr.vsync_end);
+ PIPE_CONF_CHECK_LLI(cmrr.cmrr_m);
+ PIPE_CONF_CHECK_LLI(cmrr.cmrr_n);
+ PIPE_CONF_CHECK_BOOL(cmrr.enable);
}
#undef PIPE_CONF_CHECK_X
#undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_LLI
#undef PIPE_CONF_CHECK_BOOL
#undef PIPE_CONF_CHECK_P
#undef PIPE_CONF_CHECK_FLAGS
@@ -5567,6 +5632,40 @@ int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
return 0;
}
+int intel_modeset_commit_pipes(struct drm_i915_private *i915,
+ u8 pipe_mask,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ struct drm_atomic_state *state;
+ struct intel_crtc *crtc;
+ int ret;
+
+ state = drm_atomic_state_alloc(&i915->drm);
+ if (!state)
+ return -ENOMEM;
+
+ state->acquire_ctx = ctx;
+ to_intel_atomic_state(state)->internal = true;
+
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_crtc_state(state, crtc);
+
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto out;
+ }
+
+ crtc_state->uapi.connectors_changed = true;
+ }
+
+ ret = drm_atomic_commit(state);
+out:
+ drm_atomic_state_put(state);
+
+ return ret;
+}
+
/*
* This implements the workaround described in the "notes" section of the mode
* set sequence documentation. When going from no pipes or single pipe to
@@ -5729,9 +5828,9 @@ static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv)
IS_IVYBRIDGE(dev_priv);
}
-static int intel_crtc_add_bigjoiner_planes(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_crtc *other)
+static int intel_crtc_add_joiner_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_crtc *other)
{
const struct intel_plane_state __maybe_unused *plane_state;
struct intel_plane *plane;
@@ -5746,7 +5845,7 @@ static int intel_crtc_add_bigjoiner_planes(struct intel_atomic_state *state,
return intel_crtc_add_planes_to_state(state, other, plane_ids);
}
-static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
+static int intel_joiner_add_affected_planes(struct intel_atomic_state *state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *crtc_state;
@@ -5757,13 +5856,13 @@ static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
struct intel_crtc *other;
for_each_intel_crtc_in_pipe_mask(&i915->drm, other,
- crtc_state->bigjoiner_pipes) {
+ crtc_state->joiner_pipes) {
int ret;
if (crtc == other)
continue;
- ret = intel_crtc_add_bigjoiner_planes(state, crtc, other);
+ ret = intel_crtc_add_joiner_planes(state, crtc, other);
if (ret)
return ret;
}
@@ -5785,7 +5884,7 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
if (ret)
return ret;
- ret = intel_bigjoiner_add_affected_planes(state);
+ ret = intel_joiner_add_affected_planes(state);
if (ret)
return ret;
@@ -5803,7 +5902,7 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
new_crtc_state, i) {
u8 old_active_planes, new_active_planes;
- ret = icl_check_nv12_planes(new_crtc_state);
+ ret = icl_check_nv12_planes(state, crtc);
if (ret)
return ret;
@@ -5885,70 +5984,70 @@ static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
return false;
}
-static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
- struct intel_crtc *master_crtc)
+static int intel_atomic_check_joiner(struct intel_atomic_state *state,
+ struct intel_crtc *primary_crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
- struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
- struct intel_crtc *slave_crtc;
+ struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
+ struct intel_crtc *secondary_crtc;
- if (!master_crtc_state->bigjoiner_pipes)
+ if (!primary_crtc_state->joiner_pipes)
return 0;
/* sanity check */
if (drm_WARN_ON(&i915->drm,
- master_crtc->pipe != bigjoiner_master_pipe(master_crtc_state)))
+ primary_crtc->pipe != joiner_primary_pipe(primary_crtc_state)))
return -EINVAL;
- if (master_crtc_state->bigjoiner_pipes & ~bigjoiner_pipes(i915)) {
+ if (primary_crtc_state->joiner_pipes & ~joiner_pipes(i915)) {
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] Cannot act as big joiner master "
+ "[CRTC:%d:%s] Cannot act as joiner primary "
"(need 0x%x as pipes, only 0x%x possible)\n",
- master_crtc->base.base.id, master_crtc->base.name,
- master_crtc_state->bigjoiner_pipes, bigjoiner_pipes(i915));
+ primary_crtc->base.base.id, primary_crtc->base.name,
+ primary_crtc_state->joiner_pipes, joiner_pipes(i915));
return -EINVAL;
}
- for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
- intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
- struct intel_crtc_state *slave_crtc_state;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
+ intel_crtc_joiner_secondary_pipes(primary_crtc_state)) {
+ struct intel_crtc_state *secondary_crtc_state;
int ret;
- slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave_crtc);
- if (IS_ERR(slave_crtc_state))
- return PTR_ERR(slave_crtc_state);
+ secondary_crtc_state = intel_atomic_get_crtc_state(&state->base, secondary_crtc);
+ if (IS_ERR(secondary_crtc_state))
+ return PTR_ERR(secondary_crtc_state);
- /* master being enabled, slave was already configured? */
- if (slave_crtc_state->uapi.enable) {
+ /* primary being enabled, secondary was already configured? */
+ if (secondary_crtc_state->uapi.enable) {
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
- "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
- slave_crtc->base.base.id, slave_crtc->base.name,
- master_crtc->base.base.id, master_crtc->base.name);
+ "[CRTC:%d:%s] secondary is enabled as normal CRTC, but "
+ "[CRTC:%d:%s] claiming this CRTC for joiner.\n",
+ secondary_crtc->base.base.id, secondary_crtc->base.name,
+ primary_crtc->base.base.id, primary_crtc->base.name);
return -EINVAL;
}
/*
- * The state copy logic assumes the master crtc gets processed
- * before the slave crtc during the main compute_config loop.
+ * The state copy logic assumes the primary crtc gets processed
+ * before the secondary crtc during the main compute_config loop.
* This works because the crtcs are created in pipe order,
- * and the hardware requires master pipe < slave pipe as well.
+ * and the hardware requires primary pipe < secondary pipe as well.
* Should that change we need to rethink the logic.
*/
- if (WARN_ON(drm_crtc_index(&master_crtc->base) >
- drm_crtc_index(&slave_crtc->base)))
+ if (WARN_ON(drm_crtc_index(&primary_crtc->base) >
+ drm_crtc_index(&secondary_crtc->base)))
return -EINVAL;
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] Used as slave for big joiner master [CRTC:%d:%s]\n",
- slave_crtc->base.base.id, slave_crtc->base.name,
- master_crtc->base.base.id, master_crtc->base.name);
+ "[CRTC:%d:%s] Used as secondary for joiner primary [CRTC:%d:%s]\n",
+ secondary_crtc->base.base.id, secondary_crtc->base.name,
+ primary_crtc->base.base.id, primary_crtc->base.name);
- slave_crtc_state->bigjoiner_pipes =
- master_crtc_state->bigjoiner_pipes;
+ secondary_crtc_state->joiner_pipes =
+ primary_crtc_state->joiner_pipes;
- ret = copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
+ ret = copy_joiner_crtc_state_modeset(state, secondary_crtc);
if (ret)
return ret;
}
@@ -5956,25 +6055,25 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
return 0;
}
-static void kill_bigjoiner_slave(struct intel_atomic_state *state,
- struct intel_crtc *master_crtc)
+static void kill_joiner_secondaries(struct intel_atomic_state *state,
+ struct intel_crtc *primary_crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
- struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
- struct intel_crtc *slave_crtc;
+ struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
+ struct intel_crtc *secondary_crtc;
- for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
- intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, slave_crtc);
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
+ intel_crtc_joiner_secondary_pipes(primary_crtc_state)) {
+ struct intel_crtc_state *secondary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, secondary_crtc);
- slave_crtc_state->bigjoiner_pipes = 0;
+ secondary_crtc_state->joiner_pipes = 0;
- intel_crtc_copy_uapi_to_hw_state_modeset(state, slave_crtc);
+ intel_crtc_copy_uapi_to_hw_state_modeset(state, secondary_crtc);
}
- master_crtc_state->bigjoiner_pipes = 0;
+ primary_crtc_state->joiner_pipes = 0;
}
/**
@@ -6024,12 +6123,12 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
}
/*
- * FIXME: Bigjoiner+async flip is busted currently.
+ * FIXME: joiner+async flip is busted currently.
* Remove this check once the issues are fixed.
*/
- if (new_crtc_state->bigjoiner_pipes) {
+ if (new_crtc_state->joiner_pipes) {
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] async flip disallowed with bigjoiner\n",
+ "[CRTC:%d:%s] async flip disallowed with joiner\n",
crtc->base.base.id, crtc->base.name);
return -EINVAL;
}
@@ -6166,6 +6265,13 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
return -EINVAL;
}
+ /*
+ * We turn the first async flip request into a sync flip
+ * so that we can reconfigure the plane (eg. change modifier).
+ */
+ if (!new_crtc_state->do_async_flip)
+ continue;
+
if (old_plane_state->view.color_plane[0].mapping_stride !=
new_plane_state->view.color_plane[0].mapping_stride) {
drm_dbg_kms(&i915->drm,
@@ -6247,7 +6353,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
return 0;
}
-static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
+static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state;
@@ -6257,9 +6363,9 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
int i;
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- affected_pipes |= crtc_state->bigjoiner_pipes;
+ affected_pipes |= crtc_state->joiner_pipes;
if (intel_crtc_needs_modeset(crtc_state))
- modeset_pipes |= crtc_state->bigjoiner_pipes;
+ modeset_pipes |= crtc_state->joiner_pipes;
}
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, affected_pipes) {
@@ -6285,10 +6391,10 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
}
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- /* Kill old bigjoiner link, we may re-establish afterwards */
+ /* Kill old joiner link, we may re-establish afterwards */
if (intel_crtc_needs_modeset(crtc_state) &&
- intel_crtc_is_bigjoiner_master(crtc_state))
- kill_bigjoiner_slave(state, crtc);
+ intel_crtc_is_joiner_primary(crtc_state))
+ kill_joiner_secondaries(state, crtc);
}
return 0;
@@ -6306,7 +6412,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
*failed_pipe = INVALID_PIPE;
- ret = intel_bigjoiner_add_affected_crtcs(state);
+ ret = intel_joiner_add_affected_crtcs(state);
if (ret)
return ret;
@@ -6316,14 +6422,14 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
if (!intel_crtc_needs_modeset(new_crtc_state)) {
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
- copy_bigjoiner_crtc_state_nomodeset(state, crtc);
+ if (intel_crtc_is_joiner_secondary(new_crtc_state))
+ copy_joiner_crtc_state_nomodeset(state, crtc);
else
intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
continue;
}
- if (drm_WARN_ON(&i915->drm, intel_crtc_is_bigjoiner_slave(new_crtc_state)))
+ if (drm_WARN_ON(&i915->drm, intel_crtc_is_joiner_secondary(new_crtc_state)))
continue;
ret = intel_crtc_prepare_cleared_state(state, crtc);
@@ -6342,7 +6448,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
- if (drm_WARN_ON(&i915->drm, intel_crtc_is_bigjoiner_slave(new_crtc_state)))
+ if (drm_WARN_ON(&i915->drm, intel_crtc_is_joiner_secondary(new_crtc_state)))
continue;
if (!new_crtc_state->hw.enable)
@@ -6453,12 +6559,12 @@ int intel_atomic_check(struct drm_device *dev,
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
+ if (intel_crtc_is_joiner_secondary(new_crtc_state)) {
drm_WARN_ON(&dev_priv->drm, new_crtc_state->uapi.enable);
continue;
}
- ret = intel_atomic_check_bigjoiner(state, crtc);
+ ret = intel_atomic_check_joiner(state, crtc);
if (ret)
goto fail;
}
@@ -6468,7 +6574,7 @@ int intel_atomic_check(struct drm_device *dev,
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
- intel_bigjoiner_adjust_pipe_src(new_crtc_state);
+ intel_joiner_adjust_pipe_src(new_crtc_state);
intel_crtc_check_fastset(old_crtc_state, new_crtc_state);
}
@@ -6508,8 +6614,8 @@ int intel_atomic_check(struct drm_device *dev,
intel_crtc_flag_modeset(new_crtc_state);
}
- if (new_crtc_state->bigjoiner_pipes) {
- if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes))
+ if (new_crtc_state->joiner_pipes) {
+ if (intel_pipes_need_modeset(state, new_crtc_state->joiner_pipes))
intel_crtc_flag_modeset(new_crtc_state);
}
}
@@ -6613,7 +6719,7 @@ int intel_atomic_check(struct drm_device *dev,
static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
{
- struct intel_crtc_state *crtc_state;
+ struct intel_crtc_state __maybe_unused *crtc_state;
struct intel_crtc *crtc;
int i, ret;
@@ -6621,10 +6727,8 @@ static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
if (ret < 0)
return ret;
- for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- if (intel_crtc_needs_color_update(crtc_state))
- intel_color_prepare_commit(crtc_state);
- }
+ for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
+ intel_color_prepare_commit(state, crtc);
return 0;
}
@@ -6800,7 +6904,8 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
intel_crtc_needs_fastset(new_crtc_state))
icl_set_pipe_chicken(new_crtc_state);
- if (vrr_params_changed(old_crtc_state, new_crtc_state))
+ if (vrr_params_changed(old_crtc_state, new_crtc_state) ||
+ cmrr_params_changed(old_crtc_state, new_crtc_state))
intel_vrr_set_transcoder_timings(new_crtc_state);
}
@@ -6916,6 +7021,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
continue;
intel_crtc_disable_planes(state, crtc);
+
+ drm_vblank_work_flush_all(&crtc->base);
}
/* Only disable port sync and MST slaves */
@@ -6923,7 +7030,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+ if (intel_crtc_is_joiner_secondary(old_crtc_state))
continue;
/* In case of Transcoder port Sync master slave CRTCs can be
@@ -6945,7 +7052,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+ if (intel_crtc_is_joiner_secondary(old_crtc_state))
continue;
intel_old_crtc_state_disables(state, crtc);
@@ -7024,8 +7131,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
while (update_pipes) {
/*
- * Commit in reverse order to make bigjoiner master
- * send the uapi events after slaves are done.
+ * Commit in reverse order to make joiner primary
+ * send the uapi events after secondaries are done.
*/
for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
new_crtc_state, i) {
@@ -7070,7 +7177,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
if ((modeset_pipes & BIT(pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
+ if (intel_crtc_is_joiner_secondary(new_crtc_state))
continue;
if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
@@ -7084,7 +7191,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
/*
* Then we enable all remaining pipes that depend on other
- * pipes: MST slaves and port sync masters, big joiner master
+ * pipes: MST slaves and port sync masters
*/
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
enum pipe pipe = crtc->pipe;
@@ -7092,7 +7199,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
if ((modeset_pipes & BIT(pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
+ if (intel_crtc_is_joiner_secondary(new_crtc_state))
continue;
modeset_pipes &= ~intel_crtc_joined_pipe_mask(new_crtc_state);
@@ -7113,8 +7220,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
}
/*
- * Commit in reverse order to make bigjoiner master
- * send the uapi events after slaves are done.
+ * Commit in reverse order to make joiner primary
+ * send the uapi events after secondaries are done.
*/
for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state, i) {
enum pipe pipe = crtc->pipe;
@@ -7227,6 +7334,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_atomic_commit_fence_wait(state);
+ intel_td_flush(dev_priv);
+
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);
@@ -7839,7 +7948,7 @@ static int max_dotclock(struct drm_i915_private *i915)
{
int max_dotclock = i915->display.cdclk.max_dotclk_freq;
- /* icl+ might use bigjoiner */
+ /* icl+ might use joiner */
if (DISPLAY_VER(i915) >= 11)
max_dotclock *= 2;
@@ -7964,7 +8073,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 bigjoiner)
+ bool joiner)
{
int plane_width_max, plane_height_max;
@@ -7981,7 +8090,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 << bigjoiner;
+ plane_width_max = 5120 << joiner;
plane_height_max = 4320;
} else {
plane_width_max = 5120;
@@ -8163,19 +8272,19 @@ 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(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder),
HACTIVE(640 - 1) | HTOTAL(800 - 1));
- intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder),
HBLANK_START(640 - 1) | HBLANK_END(800 - 1));
- intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder),
HSYNC_START(656 - 1) | HSYNC_END(752 - 1));
- intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
VACTIVE(480 - 1) | VTOTAL(525 - 1));
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(480 - 1) | VBLANK_END(525 - 1));
- intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder),
VSYNC_START(490 - 1) | VSYNC_END(492 - 1));
- intel_de_write(dev_priv, PIPESRC(pipe),
+ intel_de_write(dev_priv, PIPESRC(dev_priv, pipe),
PIPESRC_WIDTH(640 - 1) | PIPESRC_HEIGHT(480 - 1));
intel_de_write(dev_priv, FP0(pipe), fp);
@@ -8186,11 +8295,12 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
* 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(pipe), dpll & ~DPLL_VGA_MODE_DIS);
- intel_de_write(dev_priv, DPLL(pipe), dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
+ dpll & ~DPLL_VGA_MODE_DIS);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
/* Wait for the clocks to stabilize. */
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150);
/* The pixel multiplier can only be updated once the
@@ -8198,17 +8308,17 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
*
* So write it again.
*/
- intel_de_write(dev_priv, DPLL(pipe), dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
/* We do this three times for luck */
for (i = 0; i < 3 ; i++) {
- intel_de_write(dev_priv, DPLL(pipe), dpll);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150); /* wait for warmup */
}
- intel_de_write(dev_priv, TRANSCONF(pipe), TRANSCONF_ENABLE);
- intel_de_posting_read(dev_priv, TRANSCONF(pipe));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), TRANSCONF_ENABLE);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe));
intel_wait_for_pipe_scanline_moving(crtc);
}
@@ -8221,23 +8331,23 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
pipe_name(pipe));
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & DISP_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_A)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & DISP_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_B)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & DISP_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_C)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE_MASK);
+ 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(PIPE_B)) & MCURSOR_MODE_MASK);
+ intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_B)) & MCURSOR_MODE_MASK);
- intel_de_write(dev_priv, TRANSCONF(pipe), 0);
- intel_de_posting_read(dev_priv, TRANSCONF(pipe));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), 0);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe));
intel_wait_for_pipe_scanline_stopped(crtc);
- intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, 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 56d1c0e3e62c..b0cf6ca70952 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -415,7 +415,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 bigjoiner);
+ bool joiner);
enum drm_mode_status
intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915,
const struct drm_display_mode *mode);
@@ -423,10 +423,10 @@ enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
bool 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_bigjoiner_slave(const struct intel_crtc_state *crtc_state);
-bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state);
-u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state);
-struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state);
+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);
+u8 intel_crtc_joiner_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,
const struct intel_crtc_state *pipe_config,
@@ -537,6 +537,9 @@ int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
const char *reason, u8 pipe_mask);
int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
const char *reason);
+int intel_modeset_commit_pipes(struct drm_i915_private *i915,
+ u8 pipe_mask,
+ struct drm_modeset_acquire_ctx *ctx);
void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
struct intel_power_domain_mask *old_domains);
void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 35f9f86ef70f..91757fed9c6d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -13,6 +13,7 @@
#include "i915_debugfs.h"
#include "i915_irq.h"
#include "i915_reg.h"
+#include "intel_alpm.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_crtc_state_dump.h"
@@ -23,6 +24,7 @@
#include "intel_display_types.h"
#include "intel_dmc.h"
#include "intel_dp.h"
+#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
#include "intel_drrs.h"
#include "intel_fbc.h"
@@ -76,7 +78,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
else if (IS_I915GM(dev_priv))
sr_enabled = intel_de_read(dev_priv, INSTPM) & INSTPM_SELF_EN;
else if (IS_PINEVIEW(dev_priv))
- sr_enabled = intel_de_read(dev_priv, DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
+ sr_enabled = intel_de_read(dev_priv, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN;
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
@@ -574,10 +576,10 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
intel_scaler_info(m, crtc);
- if (crtc_state->bigjoiner_pipes)
+ if (crtc_state->joiner_pipes)
seq_printf(m, "\tLinked to 0x%x pipes as a %s\n",
- crtc_state->bigjoiner_pipes,
- intel_crtc_is_bigjoiner_slave(crtc_state) ? "slave" : "master");
+ crtc_state->joiner_pipes,
+ intel_crtc_is_joiner_secondary(crtc_state) ? "slave" : "master");
for_each_intel_encoder_mask(&dev_priv->drm, encoder,
crtc_state->uapi.encoder_mask)
@@ -1515,6 +1517,8 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
intel_drrs_connector_debugfs_add(connector);
intel_pps_connector_debugfs_add(connector);
intel_psr_connector_debugfs_add(connector);
+ intel_alpm_lobf_debugfs_add(connector);
+ intel_dp_link_training_debugfs_add(connector);
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
connector_type == DRM_MODE_CONNECTOR_HDMIA ||
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index 120e209ee74a..dd7dce4b0e7a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -3,7 +3,7 @@
* Copyright © 2023 Intel Corporation
*/
-#include <drm/i915_pciids.h>
+#include <drm/intel/i915_pciids.h>
#include <drm/drm_color_mgmt.h>
#include <linux/pci.h>
@@ -20,6 +20,25 @@
__diag_push();
__diag_ignore_all("-Woverride-init", "Allow field initialization overrides for display info");
+struct subplatform_desc {
+ enum intel_display_subplatform subplatform;
+ const char *name;
+ const u16 *pciidlist;
+};
+
+struct platform_desc {
+ enum intel_display_platform platform;
+ const char *name;
+ const struct subplatform_desc *subplatforms;
+ const struct intel_display_device_info *info; /* NULL for GMD ID */
+};
+
+#define PLATFORM(_platform) \
+ .platform = (INTEL_DISPLAY_##_platform), \
+ .name = #_platform
+
+#define ID(id) (id)
+
static const struct intel_display_device_info no_display = {};
#define PIPE_A_OFFSET 0x70000
@@ -200,33 +219,45 @@ static const struct intel_display_device_info no_display = {};
.__runtime_defaults.pipe_mask = BIT(PIPE_A), \
.__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
-static const struct intel_display_device_info i830_display = {
- I830_DISPLAY,
+static const struct platform_desc i830_desc = {
+ PLATFORM(I830),
+ .info = &(const struct intel_display_device_info) {
+ I830_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
+ },
};
-static const struct intel_display_device_info i845_display = {
- I845_DISPLAY,
+static const struct platform_desc i845_desc = {
+ PLATFORM(I845G),
+ .info = &(const struct intel_display_device_info) {
+ I845_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ },
};
-static const struct intel_display_device_info i85x_display = {
- I830_DISPLAY,
+static const struct platform_desc i85x_desc = {
+ PLATFORM(I85X),
+ .info = &(const struct intel_display_device_info) {
+ I830_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info i865g_display = {
- I845_DISPLAY,
+static const struct platform_desc i865g_desc = {
+ PLATFORM(I865G),
+ .info = &(const struct intel_display_device_info) {
+ I845_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-#define GEN3_DISPLAY \
+#define GEN3_DISPLAY \
.has_gmch = 1, \
.has_overlay = 1, \
I9XX_PIPE_OFFSETS, \
@@ -238,52 +269,70 @@ static const struct intel_display_device_info i865g_display = {
BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) /* SDVO B/C */
-static const struct intel_display_device_info i915g_display = {
- GEN3_DISPLAY,
- I845_COLORS,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
+static const struct platform_desc i915g_desc = {
+ PLATFORM(I915G),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I845_COLORS,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ },
};
-static const struct intel_display_device_info i915gm_display = {
- GEN3_DISPLAY,
- I9XX_COLORS,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
- .supports_tv = 1,
-
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+static const struct platform_desc i915gm_desc = {
+ PLATFORM(I915GM),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I9XX_COLORS,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ .supports_tv = 1,
+
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info i945g_display = {
- GEN3_DISPLAY,
- I845_COLORS,
- .has_hotplug = 1,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
+static const struct platform_desc i945g_desc = {
+ PLATFORM(I945G),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I845_COLORS,
+ .has_hotplug = 1,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ },
};
-static const struct intel_display_device_info i945gm_display = {
- GEN3_DISPLAY,
- I9XX_COLORS,
- .has_hotplug = 1,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
- .supports_tv = 1,
-
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+static const struct platform_desc i945gm_desc = {
+ PLATFORM(I915GM),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I9XX_COLORS,
+ .has_hotplug = 1,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ .supports_tv = 1,
+
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info g33_display = {
- GEN3_DISPLAY,
- I845_COLORS,
- .has_hotplug = 1,
+static const struct platform_desc g33_desc = {
+ PLATFORM(G33),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I845_COLORS,
+ .has_hotplug = 1,
+ },
};
-static const struct intel_display_device_info pnv_display = {
- GEN3_DISPLAY,
- I9XX_COLORS,
- .has_hotplug = 1,
+static const struct platform_desc pnv_desc = {
+ PLATFORM(PINEVIEW),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I9XX_COLORS,
+ .has_hotplug = 1,
+ },
};
#define GEN4_DISPLAY \
@@ -298,34 +347,46 @@ static const struct intel_display_device_info pnv_display = {
.__runtime_defaults.cpu_transcoder_mask = \
BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
-static const struct intel_display_device_info i965g_display = {
- GEN4_DISPLAY,
- .has_overlay = 1,
+static const struct platform_desc i965g_desc = {
+ PLATFORM(I965G),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
+ .has_overlay = 1,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
+ },
};
-static const struct intel_display_device_info i965gm_display = {
- GEN4_DISPLAY,
- .has_overlay = 1,
- .supports_tv = 1,
+static const struct platform_desc i965gm_desc = {
+ PLATFORM(I965GM),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
+ .has_overlay = 1,
+ .supports_tv = 1,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info g45_display = {
- GEN4_DISPLAY,
+static const struct platform_desc g45_desc = {
+ PLATFORM(G45),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
+ },
};
-static const struct intel_display_device_info gm45_display = {
- GEN4_DISPLAY,
- .supports_tv = 1,
+static const struct platform_desc gm45_desc = {
+ PLATFORM(GM45),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
+ .supports_tv = 1,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
#define ILK_DISPLAY \
@@ -340,112 +401,175 @@ static const struct intel_display_device_info gm45_display = {
BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
-static const struct intel_display_device_info ilk_d_display = {
- ILK_DISPLAY,
+static const struct platform_desc ilk_d_desc = {
+ PLATFORM(IRONLAKE),
+ .info = &(const struct intel_display_device_info) {
+ ILK_DISPLAY,
+ },
};
-static const struct intel_display_device_info ilk_m_display = {
- ILK_DISPLAY,
+static const struct platform_desc ilk_m_desc = {
+ PLATFORM(IRONLAKE),
+ .info = &(const struct intel_display_device_info) {
+ ILK_DISPLAY,
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info snb_display = {
- .has_hotplug = 1,
- I9XX_PIPE_OFFSETS,
- I9XX_CURSOR_OFFSETS,
- ILK_COLORS,
-
- .__runtime_defaults.ip.ver = 6,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc snb_desc = {
+ PLATFORM(SANDYBRIDGE),
+ .info = &(const struct intel_display_device_info) {
+ .has_hotplug = 1,
+ I9XX_PIPE_OFFSETS,
+ I9XX_CURSOR_OFFSETS,
+ ILK_COLORS,
+
+ .__runtime_defaults.ip.ver = 6,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info ivb_display = {
- .has_hotplug = 1,
- IVB_PIPE_OFFSETS,
- IVB_CURSOR_OFFSETS,
- IVB_COLORS,
-
- .__runtime_defaults.ip.ver = 7,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc ivb_desc = {
+ PLATFORM(IVYBRIDGE),
+ .info = &(const struct intel_display_device_info) {
+ .has_hotplug = 1,
+ IVB_PIPE_OFFSETS,
+ IVB_CURSOR_OFFSETS,
+ IVB_COLORS,
+
+ .__runtime_defaults.ip.ver = 7,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info vlv_display = {
- .has_gmch = 1,
- .has_hotplug = 1,
- .mmio_offset = VLV_DISPLAY_BASE,
- I9XX_PIPE_OFFSETS,
- I9XX_CURSOR_OFFSETS,
- I9XX_COLORS,
-
- .__runtime_defaults.ip.ver = 7,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc vlv_desc = {
+ PLATFORM(VALLEYVIEW),
+ .info = &(const struct intel_display_device_info) {
+ .has_gmch = 1,
+ .has_hotplug = 1,
+ .mmio_offset = VLV_DISPLAY_BASE,
+ I9XX_PIPE_OFFSETS,
+ I9XX_CURSOR_OFFSETS,
+ I9XX_COLORS,
+
+ .__runtime_defaults.ip.ver = 7,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
+ },
};
-static const struct intel_display_device_info hsw_display = {
- .has_ddi = 1,
- .has_dp_mst = 1,
- .has_fpga_dbg = 1,
- .has_hotplug = 1,
- .has_psr = 1,
- .has_psr_hw_tracking = 1,
- HSW_PIPE_OFFSETS,
- IVB_CURSOR_OFFSETS,
- IVB_COLORS,
+static const u16 hsw_ult_ids[] = {
+ INTEL_HSW_ULT_GT1_IDS(ID),
+ INTEL_HSW_ULT_GT2_IDS(ID),
+ INTEL_HSW_ULT_GT3_IDS(ID),
+ 0
+};
- .__runtime_defaults.ip.ver = 7,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const u16 hsw_ulx_ids[] = {
+ INTEL_HSW_ULX_GT1_IDS(ID),
+ INTEL_HSW_ULX_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc hsw_desc = {
+ PLATFORM(HASWELL),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_HASWELL_ULT, "ULT", hsw_ult_ids },
+ { INTEL_DISPLAY_HASWELL_ULX, "ULX", hsw_ulx_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ .has_ddi = 1,
+ .has_dp_mst = 1,
+ .has_fpga_dbg = 1,
+ .has_hotplug = 1,
+ .has_psr = 1,
+ .has_psr_hw_tracking = 1,
+ HSW_PIPE_OFFSETS,
+ IVB_CURSOR_OFFSETS,
+ IVB_COLORS,
+
+ .__runtime_defaults.ip.ver = 7,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info bdw_display = {
- .has_ddi = 1,
- .has_dp_mst = 1,
- .has_fpga_dbg = 1,
- .has_hotplug = 1,
- .has_psr = 1,
- .has_psr_hw_tracking = 1,
- HSW_PIPE_OFFSETS,
- IVB_CURSOR_OFFSETS,
- IVB_COLORS,
+static const u16 bdw_ult_ids[] = {
+ INTEL_BDW_ULT_GT1_IDS(ID),
+ INTEL_BDW_ULT_GT2_IDS(ID),
+ INTEL_BDW_ULT_GT3_IDS(ID),
+ INTEL_BDW_ULT_RSVD_IDS(ID),
+ 0
+};
- .__runtime_defaults.ip.ver = 8,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const u16 bdw_ulx_ids[] = {
+ INTEL_BDW_ULX_GT1_IDS(ID),
+ INTEL_BDW_ULX_GT2_IDS(ID),
+ INTEL_BDW_ULX_GT3_IDS(ID),
+ INTEL_BDW_ULX_RSVD_IDS(ID),
+ 0
+};
+
+static const struct platform_desc bdw_desc = {
+ PLATFORM(BROADWELL),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_BROADWELL_ULT, "ULT", bdw_ult_ids },
+ { INTEL_DISPLAY_BROADWELL_ULX, "ULX", bdw_ulx_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ .has_ddi = 1,
+ .has_dp_mst = 1,
+ .has_fpga_dbg = 1,
+ .has_hotplug = 1,
+ .has_psr = 1,
+ .has_psr_hw_tracking = 1,
+ HSW_PIPE_OFFSETS,
+ IVB_CURSOR_OFFSETS,
+ IVB_COLORS,
+
+ .__runtime_defaults.ip.ver = 8,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info chv_display = {
- .has_hotplug = 1,
- .has_gmch = 1,
- .mmio_offset = VLV_DISPLAY_BASE,
- CHV_PIPE_OFFSETS,
- CHV_CURSOR_OFFSETS,
- CHV_COLORS,
-
- .__runtime_defaults.ip.ver = 8,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc chv_desc = {
+ PLATFORM(CHERRYVIEW),
+ .info = &(const struct intel_display_device_info) {
+ .has_hotplug = 1,
+ .has_gmch = 1,
+ .mmio_offset = VLV_DISPLAY_BASE,
+ CHV_PIPE_OFFSETS,
+ CHV_CURSOR_OFFSETS,
+ CHV_COLORS,
+
+ .__runtime_defaults.ip.ver = 8,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
+ },
};
static const struct intel_display_device_info skl_display = {
@@ -467,13 +591,99 @@ static const struct intel_display_device_info skl_display = {
.__runtime_defaults.has_hdcp = 1,
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
.__runtime_defaults.cpu_transcoder_mask =
- BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
- BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
+ BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
+ BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
};
-#define GEN9_LP_DISPLAY \
+static const u16 skl_ult_ids[] = {
+ INTEL_SKL_ULT_GT1_IDS(ID),
+ INTEL_SKL_ULT_GT2_IDS(ID),
+ INTEL_SKL_ULT_GT3_IDS(ID),
+ 0
+};
+
+static const u16 skl_ulx_ids[] = {
+ INTEL_SKL_ULX_GT1_IDS(ID),
+ INTEL_SKL_ULX_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc skl_desc = {
+ PLATFORM(SKYLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_SKYLAKE_ULT, "ULT", skl_ult_ids },
+ { INTEL_DISPLAY_SKYLAKE_ULX, "ULX", skl_ulx_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+static const u16 kbl_ult_ids[] = {
+ INTEL_KBL_ULT_GT1_IDS(ID),
+ INTEL_KBL_ULT_GT2_IDS(ID),
+ INTEL_KBL_ULT_GT3_IDS(ID),
+ 0
+};
+
+static const u16 kbl_ulx_ids[] = {
+ INTEL_KBL_ULX_GT1_IDS(ID),
+ INTEL_KBL_ULX_GT2_IDS(ID),
+ INTEL_AML_KBL_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc kbl_desc = {
+ PLATFORM(KABYLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_KABYLAKE_ULT, "ULT", kbl_ult_ids },
+ { INTEL_DISPLAY_KABYLAKE_ULX, "ULX", kbl_ulx_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+static const u16 cfl_ult_ids[] = {
+ INTEL_CFL_U_GT2_IDS(ID),
+ INTEL_CFL_U_GT3_IDS(ID),
+ INTEL_WHL_U_GT1_IDS(ID),
+ INTEL_WHL_U_GT2_IDS(ID),
+ INTEL_WHL_U_GT3_IDS(ID),
+ 0
+};
+
+static const u16 cfl_ulx_ids[] = {
+ INTEL_AML_CFL_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc cfl_desc = {
+ PLATFORM(COFFEELAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_COFFEELAKE_ULT, "ULT", cfl_ult_ids },
+ { INTEL_DISPLAY_COFFEELAKE_ULX, "ULX", cfl_ulx_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+static const u16 cml_ult_ids[] = {
+ INTEL_CML_U_GT1_IDS(ID),
+ INTEL_CML_U_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc cml_desc = {
+ PLATFORM(COMETLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_COMETLAKE_ULT, "ULT", cml_ult_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+#define GEN9_LP_DISPLAY \
.dbuf.slice_mask = BIT(DBUF_S1), \
.has_dp_mst = 1, \
.has_ddi = 1, \
@@ -496,19 +706,25 @@ static const struct intel_display_device_info skl_display = {
BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C)
-static const struct intel_display_device_info bxt_display = {
- GEN9_LP_DISPLAY,
- .dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
+static const struct platform_desc bxt_desc = {
+ PLATFORM(BROXTON),
+ .info = &(const struct intel_display_device_info) {
+ GEN9_LP_DISPLAY,
+ .dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
- .__runtime_defaults.ip.ver = 9,
+ .__runtime_defaults.ip.ver = 9,
+ },
};
-static const struct intel_display_device_info glk_display = {
- GEN9_LP_DISPLAY,
- .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
- GLK_COLORS,
+static const struct platform_desc glk_desc = {
+ PLATFORM(GEMINILAKE),
+ .info = &(const struct intel_display_device_info) {
+ GEN9_LP_DISPLAY,
+ .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
+ GLK_COLORS,
- .__runtime_defaults.ip.ver = 10,
+ .__runtime_defaults.ip.ver = 10,
+ },
};
#define ICL_DISPLAY \
@@ -552,10 +768,22 @@ static const struct intel_display_device_info glk_display = {
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
-static const struct intel_display_device_info icl_display = {
- ICL_DISPLAY,
+static const u16 icl_port_f_ids[] = {
+ INTEL_ICL_PORT_F_IDS(ID),
+ 0
+};
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+static const struct platform_desc icl_desc = {
+ PLATFORM(ICELAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_ICELAKE_PORT_F, "Port F", icl_port_f_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ ICL_DISPLAY,
+
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+ },
};
static const struct intel_display_device_info jsl_ehl_display = {
@@ -564,6 +792,16 @@ static const struct intel_display_device_info jsl_ehl_display = {
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D),
};
+static const struct platform_desc jsl_desc = {
+ PLATFORM(JASPERLAKE),
+ .info = &jsl_ehl_display,
+};
+
+static const struct platform_desc ehl_desc = {
+ PLATFORM(ELKHARTLAKE),
+ .info = &jsl_ehl_display,
+};
+
#define XE_D_DISPLAY \
.abox_mask = GENMASK(2, 1), \
.dbuf.size = 2048, \
@@ -607,44 +845,74 @@ static const struct intel_display_device_info jsl_ehl_display = {
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
-static const struct intel_display_device_info tgl_display = {
- XE_D_DISPLAY,
+static const u16 tgl_uy_ids[] = {
+ INTEL_TGL_GT2_IDS(ID),
+ 0
+};
- /*
- * FIXME DDI C/combo PHY C missing due to combo PHY
- * code making a mess on SKUs where the PHY is missing.
- */
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
+static const struct platform_desc tgl_desc = {
+ PLATFORM(TIGERLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_TIGERLAKE_UY, "UY", tgl_uy_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
+
+ /*
+ * FIXME DDI C/combo PHY C missing due to combo PHY
+ * code making a mess on SKUs where the PHY is missing.
+ */
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4) | BIT(PORT_TC5) | BIT(PORT_TC6),
+ },
};
-static const struct intel_display_device_info dg1_display = {
- XE_D_DISPLAY,
+static const struct platform_desc dg1_desc = {
+ PLATFORM(DG1),
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
BIT(PORT_TC1) | BIT(PORT_TC2),
+ },
};
-static const struct intel_display_device_info rkl_display = {
- XE_D_DISPLAY,
- .abox_mask = BIT(0),
- .has_hti = 1,
- .has_psr_hw_tracking = 0,
+static const struct platform_desc rkl_desc = {
+ PLATFORM(ROCKETLAKE),
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
+ .abox_mask = BIT(0),
+ .has_hti = 1,
+ .has_psr_hw_tracking = 0,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
BIT(PORT_TC1) | BIT(PORT_TC2),
+ },
};
-static const struct intel_display_device_info adl_s_display = {
- XE_D_DISPLAY,
- .has_hti = 1,
- .has_psr_hw_tracking = 0,
+static const u16 adls_rpls_ids[] = {
+ INTEL_RPLS_IDS(ID),
+ 0
+};
- .__runtime_defaults.port_mask = BIT(PORT_A) |
+static const struct platform_desc adl_s_desc = {
+ PLATFORM(ALDERLAKE_S),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S, "RPL-S", adls_rpls_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
+ .has_hti = 1,
+ .has_psr_hw_tracking = 0,
+
+ .__runtime_defaults.port_mask = BIT(PORT_A) |
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
+ },
};
#define XE_LPD_FEATURES \
@@ -703,6 +971,32 @@ static const struct intel_display_device_info xe_lpd_display = {
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
};
+static const u16 adlp_adln_ids[] = {
+ INTEL_ADLN_IDS(ID),
+ 0
+};
+
+static const u16 adlp_rplu_ids[] = {
+ INTEL_RPLU_IDS(ID),
+ 0
+};
+
+static const u16 adlp_rplp_ids[] = {
+ INTEL_RPLP_IDS(ID),
+ 0
+};
+
+static const struct platform_desc adl_p_desc = {
+ PLATFORM(ALDERLAKE_P),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N, "ADL-N", adlp_adln_ids },
+ { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U, "RPL-U", adlp_rplu_ids },
+ { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P, "RPL-P", adlp_rplp_ids },
+ {},
+ },
+ .info = &xe_lpd_display,
+};
+
static const struct intel_display_device_info xe_hpd_display = {
XE_LPD_FEATURES,
.has_cdclk_squash = 1,
@@ -714,6 +1008,32 @@ static const struct intel_display_device_info xe_hpd_display = {
BIT(PORT_TC1),
};
+static const u16 dg2_g10_ids[] = {
+ INTEL_DG2_G10_IDS(ID),
+ 0
+};
+
+static const u16 dg2_g11_ids[] = {
+ INTEL_DG2_G11_IDS(ID),
+ 0
+};
+
+static const u16 dg2_g12_ids[] = {
+ INTEL_DG2_G12_IDS(ID),
+ 0
+};
+
+static const struct platform_desc dg2_desc = {
+ PLATFORM(DG2),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_DG2_G10, "G10", dg2_g10_ids },
+ { INTEL_DISPLAY_DG2_G11, "G11", dg2_g11_ids },
+ { INTEL_DISPLAY_DG2_G12, "G12", dg2_g12_ids },
+ {},
+ },
+ .info = &xe_hpd_display,
+};
+
#define XE_LPDP_FEATURES \
.abox_mask = GENMASK(1, 0), \
.color = { \
@@ -771,6 +1091,29 @@ static const struct intel_display_device_info xe2_lpd_display = {
BIT(INTEL_FBC_C) | BIT(INTEL_FBC_D),
};
+static const struct intel_display_device_info xe2_hpd_display = {
+ XE_LPDP_FEATURES,
+ .__runtime_defaults.port_mask = BIT(PORT_A) |
+ BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
+};
+
+/*
+ * Do not initialize the .info member of the platform desc for GMD ID based
+ * platforms. Their display will be probed automatically based on the IP version
+ * reported by the hardware.
+ */
+static const struct platform_desc mtl_desc = {
+ PLATFORM(METEORLAKE),
+};
+
+static const struct platform_desc lnl_desc = {
+ PLATFORM(LUNARLAKE),
+};
+
+static const struct platform_desc bmg_desc = {
+ PLATFORM(BATTLEMAGE),
+};
+
__diag_pop();
/*
@@ -782,68 +1125,64 @@ __diag_pop();
static bool has_no_display(struct pci_dev *pdev)
{
static const struct pci_device_id ids[] = {
- INTEL_IVB_Q_IDS(0),
+ INTEL_IVB_Q_IDS(INTEL_VGA_DEVICE, 0),
{}
};
return pci_match_id(ids, pdev);
}
-#undef INTEL_VGA_DEVICE
-#define INTEL_VGA_DEVICE(id, info) { id, info }
+#define INTEL_DISPLAY_DEVICE(_id, _desc) { .devid = (_id), .desc = (_desc) }
static const struct {
u32 devid;
- const struct intel_display_device_info *info;
+ const struct platform_desc *desc;
} intel_display_ids[] = {
- INTEL_I830_IDS(&i830_display),
- INTEL_I845G_IDS(&i845_display),
- INTEL_I85X_IDS(&i85x_display),
- INTEL_I865G_IDS(&i865g_display),
- INTEL_I915G_IDS(&i915g_display),
- INTEL_I915GM_IDS(&i915gm_display),
- INTEL_I945G_IDS(&i945g_display),
- INTEL_I945GM_IDS(&i945gm_display),
- INTEL_I965G_IDS(&i965g_display),
- INTEL_G33_IDS(&g33_display),
- INTEL_I965GM_IDS(&i965gm_display),
- INTEL_GM45_IDS(&gm45_display),
- INTEL_G45_IDS(&g45_display),
- INTEL_PINEVIEW_G_IDS(&pnv_display),
- INTEL_PINEVIEW_M_IDS(&pnv_display),
- INTEL_IRONLAKE_D_IDS(&ilk_d_display),
- INTEL_IRONLAKE_M_IDS(&ilk_m_display),
- INTEL_SNB_D_IDS(&snb_display),
- INTEL_SNB_M_IDS(&snb_display),
- INTEL_IVB_M_IDS(&ivb_display),
- INTEL_IVB_D_IDS(&ivb_display),
- INTEL_HSW_IDS(&hsw_display),
- INTEL_VLV_IDS(&vlv_display),
- INTEL_BDW_IDS(&bdw_display),
- INTEL_CHV_IDS(&chv_display),
- INTEL_SKL_IDS(&skl_display),
- INTEL_BXT_IDS(&bxt_display),
- INTEL_GLK_IDS(&glk_display),
- INTEL_KBL_IDS(&skl_display),
- INTEL_CFL_IDS(&skl_display),
- INTEL_ICL_11_IDS(&icl_display),
- INTEL_EHL_IDS(&jsl_ehl_display),
- INTEL_JSL_IDS(&jsl_ehl_display),
- INTEL_TGL_12_IDS(&tgl_display),
- INTEL_DG1_IDS(&dg1_display),
- INTEL_RKL_IDS(&rkl_display),
- INTEL_ADLS_IDS(&adl_s_display),
- INTEL_RPLS_IDS(&adl_s_display),
- INTEL_ADLP_IDS(&xe_lpd_display),
- INTEL_ADLN_IDS(&xe_lpd_display),
- INTEL_RPLP_IDS(&xe_lpd_display),
- INTEL_DG2_IDS(&xe_hpd_display),
-
- /*
- * Do not add any GMD_ID-based platforms to this list. They will
- * be probed automatically based on the IP version reported by
- * the hardware.
- */
+ INTEL_I830_IDS(INTEL_DISPLAY_DEVICE, &i830_desc),
+ INTEL_I845G_IDS(INTEL_DISPLAY_DEVICE, &i845_desc),
+ INTEL_I85X_IDS(INTEL_DISPLAY_DEVICE, &i85x_desc),
+ INTEL_I865G_IDS(INTEL_DISPLAY_DEVICE, &i865g_desc),
+ INTEL_I915G_IDS(INTEL_DISPLAY_DEVICE, &i915g_desc),
+ INTEL_I915GM_IDS(INTEL_DISPLAY_DEVICE, &i915gm_desc),
+ INTEL_I945G_IDS(INTEL_DISPLAY_DEVICE, &i945g_desc),
+ INTEL_I945GM_IDS(INTEL_DISPLAY_DEVICE, &i945gm_desc),
+ INTEL_I965G_IDS(INTEL_DISPLAY_DEVICE, &i965g_desc),
+ INTEL_G33_IDS(INTEL_DISPLAY_DEVICE, &g33_desc),
+ INTEL_I965GM_IDS(INTEL_DISPLAY_DEVICE, &i965gm_desc),
+ INTEL_GM45_IDS(INTEL_DISPLAY_DEVICE, &gm45_desc),
+ INTEL_G45_IDS(INTEL_DISPLAY_DEVICE, &g45_desc),
+ INTEL_PNV_IDS(INTEL_DISPLAY_DEVICE, &pnv_desc),
+ INTEL_ILK_D_IDS(INTEL_DISPLAY_DEVICE, &ilk_d_desc),
+ INTEL_ILK_M_IDS(INTEL_DISPLAY_DEVICE, &ilk_m_desc),
+ INTEL_SNB_IDS(INTEL_DISPLAY_DEVICE, &snb_desc),
+ INTEL_IVB_IDS(INTEL_DISPLAY_DEVICE, &ivb_desc),
+ INTEL_HSW_IDS(INTEL_DISPLAY_DEVICE, &hsw_desc),
+ INTEL_VLV_IDS(INTEL_DISPLAY_DEVICE, &vlv_desc),
+ INTEL_BDW_IDS(INTEL_DISPLAY_DEVICE, &bdw_desc),
+ INTEL_CHV_IDS(INTEL_DISPLAY_DEVICE, &chv_desc),
+ INTEL_SKL_IDS(INTEL_DISPLAY_DEVICE, &skl_desc),
+ INTEL_BXT_IDS(INTEL_DISPLAY_DEVICE, &bxt_desc),
+ INTEL_GLK_IDS(INTEL_DISPLAY_DEVICE, &glk_desc),
+ INTEL_KBL_IDS(INTEL_DISPLAY_DEVICE, &kbl_desc),
+ INTEL_CFL_IDS(INTEL_DISPLAY_DEVICE, &cfl_desc),
+ INTEL_WHL_IDS(INTEL_DISPLAY_DEVICE, &cfl_desc),
+ INTEL_CML_IDS(INTEL_DISPLAY_DEVICE, &cml_desc),
+ INTEL_ICL_IDS(INTEL_DISPLAY_DEVICE, &icl_desc),
+ INTEL_EHL_IDS(INTEL_DISPLAY_DEVICE, &ehl_desc),
+ INTEL_JSL_IDS(INTEL_DISPLAY_DEVICE, &jsl_desc),
+ INTEL_TGL_IDS(INTEL_DISPLAY_DEVICE, &tgl_desc),
+ INTEL_DG1_IDS(INTEL_DISPLAY_DEVICE, &dg1_desc),
+ INTEL_RKL_IDS(INTEL_DISPLAY_DEVICE, &rkl_desc),
+ INTEL_ADLS_IDS(INTEL_DISPLAY_DEVICE, &adl_s_desc),
+ INTEL_RPLS_IDS(INTEL_DISPLAY_DEVICE, &adl_s_desc),
+ INTEL_ADLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
+ INTEL_ADLN_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
+ 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_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
+ INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc),
+ INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
};
static const struct {
@@ -852,30 +1191,23 @@ static const struct {
const struct intel_display_device_info *display;
} gmdid_display_map[] = {
{ 14, 0, &xe_lpdp_display },
+ { 14, 1, &xe2_hpd_display },
{ 20, 0, &xe2_lpd_display },
};
static const struct intel_display_device_info *
-probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step)
+probe_gmdid_display(struct drm_i915_private *i915, struct intel_display_ip_ver *ip_ver)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ struct intel_display_ip_ver gmd_id;
void __iomem *addr;
u32 val;
int i;
- /* The caller expects to ver, rel and step to be initialized
- * here, and there's no good way to check when there was a
- * failure and no_display was returned. So initialize all these
- * values here zero, to be sure.
- */
- *ver = 0;
- *rel = 0;
- *step = 0;
-
addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
if (!addr) {
drm_err(&i915->drm, "Cannot map MMIO BAR to read display GMD_ID\n");
- return &no_display;
+ return NULL;
}
val = ioread32(addr);
@@ -883,57 +1215,82 @@ probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step
if (val == 0) {
drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
- return &no_display;
+ return NULL;
}
- *ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
- *rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
- *step = REG_FIELD_GET(GMD_ID_STEP, val);
+ gmd_id.ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
+ gmd_id.rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
+ gmd_id.step = REG_FIELD_GET(GMD_ID_STEP, val);
- for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++)
- if (*ver == gmdid_display_map[i].ver &&
- *rel == gmdid_display_map[i].rel)
+ for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++) {
+ if (gmd_id.ver == gmdid_display_map[i].ver &&
+ gmd_id.rel == gmdid_display_map[i].rel) {
+ *ip_ver = gmd_id;
return gmdid_display_map[i].display;
+ }
+ }
drm_err(&i915->drm, "Unrecognized display IP version %d.%02d; disabling display.\n",
- *ver, *rel);
- return &no_display;
+ gmd_id.ver, gmd_id.rel);
+ return NULL;
}
-static const struct intel_display_device_info *
-probe_display(struct drm_i915_private *i915)
+static const struct platform_desc *find_platform_desc(struct pci_dev *pdev)
{
- struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
int i;
- if (has_no_display(pdev)) {
- drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
- return &no_display;
- }
-
for (i = 0; i < ARRAY_SIZE(intel_display_ids); i++) {
if (intel_display_ids[i].devid == pdev->device)
- return intel_display_ids[i].info;
+ return intel_display_ids[i].desc;
}
- drm_dbg(&i915->drm, "No display ID found for device ID %04x; disabling display.\n",
- pdev->device);
+ return NULL;
+}
+
+static const struct subplatform_desc *
+find_subplatform_desc(struct pci_dev *pdev, const struct platform_desc *desc)
+{
+ const struct subplatform_desc *sp;
+ const u16 *id;
+
+ for (sp = desc->subplatforms; sp && sp->subplatform; sp++)
+ for (id = sp->pciidlist; *id; id++)
+ if (*id == pdev->device)
+ return sp;
- return &no_display;
+ return NULL;
}
void intel_display_device_probe(struct drm_i915_private *i915)
{
+ struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
const struct intel_display_device_info *info;
- u16 ver, rel, step;
+ struct intel_display_ip_ver ip_ver = {};
+ const struct platform_desc *desc;
+ const struct subplatform_desc *subdesc;
/* Add drm device backpointer as early as possible. */
i915->display.drm = &i915->drm;
- if (HAS_GMD_ID(i915))
- info = probe_gmdid_display(i915, &ver, &rel, &step);
- else
- info = probe_display(i915);
+ intel_display_params_copy(&i915->display.params);
+
+ if (has_no_display(pdev)) {
+ drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
+ goto no_display;
+ }
+
+ desc = find_platform_desc(pdev);
+ if (!desc) {
+ drm_dbg_kms(&i915->drm, "Unknown device ID %04x; disabling display.\n",
+ pdev->device);
+ goto no_display;
+ }
+
+ info = desc->info;
+ if (!info)
+ info = probe_gmdid_display(i915, &ip_ver);
+ if (!info)
+ goto no_display;
DISPLAY_INFO(i915) = info;
@@ -941,13 +1298,27 @@ void intel_display_device_probe(struct drm_i915_private *i915)
&DISPLAY_INFO(i915)->__runtime_defaults,
sizeof(*DISPLAY_RUNTIME_INFO(i915)));
- if (HAS_GMD_ID(i915)) {
- DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
- DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
- DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
+ drm_WARN_ON(&i915->drm, !desc->platform || !desc->name);
+ DISPLAY_RUNTIME_INFO(i915)->platform = desc->platform;
+
+ subdesc = find_subplatform_desc(pdev, desc);
+ if (subdesc) {
+ drm_WARN_ON(&i915->drm, !subdesc->subplatform || !subdesc->name);
+ DISPLAY_RUNTIME_INFO(i915)->subplatform = subdesc->subplatform;
}
- intel_display_params_copy(&i915->display.params);
+ if (ip_ver.ver || ip_ver.rel || ip_ver.step)
+ DISPLAY_RUNTIME_INFO(i915)->ip = ip_ver;
+
+ drm_info(&i915->drm, "Found %s%s%s (device ID %04x) display version %u.%02u\n",
+ desc->name, subdesc ? "/" : "", subdesc ? subdesc->name : "",
+ pdev->device, DISPLAY_RUNTIME_INFO(i915)->ip.ver,
+ DISPLAY_RUNTIME_INFO(i915)->ip.rel);
+
+ return;
+
+no_display:
+ DISPLAY_INFO(i915) = &no_display;
}
void intel_display_device_remove(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index 17ddf82f0b6e..13453ea4daea 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -14,6 +14,89 @@
struct drm_i915_private;
struct drm_printer;
+/* Keep in gen based order, and chronological order within a gen */
+enum intel_display_platform {
+ INTEL_DISPLAY_PLATFORM_UNINITIALIZED = 0,
+ /* Display ver 2 */
+ INTEL_DISPLAY_I830,
+ INTEL_DISPLAY_I845G,
+ INTEL_DISPLAY_I85X,
+ INTEL_DISPLAY_I865G,
+ /* Display ver 3 */
+ INTEL_DISPLAY_I915G,
+ INTEL_DISPLAY_I915GM,
+ INTEL_DISPLAY_I945G,
+ INTEL_DISPLAY_I945GM,
+ INTEL_DISPLAY_G33,
+ INTEL_DISPLAY_PINEVIEW,
+ /* Display ver 4 */
+ INTEL_DISPLAY_I965G,
+ INTEL_DISPLAY_I965GM,
+ INTEL_DISPLAY_G45,
+ INTEL_DISPLAY_GM45,
+ /* Display ver 5 */
+ INTEL_DISPLAY_IRONLAKE,
+ /* Display ver 6 */
+ INTEL_DISPLAY_SANDYBRIDGE,
+ /* Display ver 7 */
+ INTEL_DISPLAY_IVYBRIDGE,
+ INTEL_DISPLAY_VALLEYVIEW,
+ INTEL_DISPLAY_HASWELL,
+ /* Display ver 8 */
+ INTEL_DISPLAY_BROADWELL,
+ INTEL_DISPLAY_CHERRYVIEW,
+ /* Display ver 9 */
+ INTEL_DISPLAY_SKYLAKE,
+ INTEL_DISPLAY_BROXTON,
+ INTEL_DISPLAY_KABYLAKE,
+ INTEL_DISPLAY_GEMINILAKE,
+ INTEL_DISPLAY_COFFEELAKE,
+ INTEL_DISPLAY_COMETLAKE,
+ /* Display ver 11 */
+ INTEL_DISPLAY_ICELAKE,
+ INTEL_DISPLAY_JASPERLAKE,
+ INTEL_DISPLAY_ELKHARTLAKE,
+ /* Display ver 12 */
+ INTEL_DISPLAY_TIGERLAKE,
+ INTEL_DISPLAY_ROCKETLAKE,
+ INTEL_DISPLAY_DG1,
+ INTEL_DISPLAY_ALDERLAKE_S,
+ /* Display ver 13 */
+ INTEL_DISPLAY_ALDERLAKE_P,
+ INTEL_DISPLAY_DG2,
+ /* Display ver 14 (based on GMD ID) */
+ INTEL_DISPLAY_METEORLAKE,
+ /* Display ver 20 (based on GMD ID) */
+ INTEL_DISPLAY_LUNARLAKE,
+ /* Display ver 14.1 (based on GMD ID) */
+ INTEL_DISPLAY_BATTLEMAGE,
+};
+
+enum intel_display_subplatform {
+ INTEL_DISPLAY_SUBPLATFORM_UNINITIALIZED = 0,
+ INTEL_DISPLAY_HASWELL_ULT,
+ INTEL_DISPLAY_HASWELL_ULX,
+ INTEL_DISPLAY_BROADWELL_ULT,
+ INTEL_DISPLAY_BROADWELL_ULX,
+ INTEL_DISPLAY_SKYLAKE_ULT,
+ INTEL_DISPLAY_SKYLAKE_ULX,
+ INTEL_DISPLAY_KABYLAKE_ULT,
+ INTEL_DISPLAY_KABYLAKE_ULX,
+ INTEL_DISPLAY_COFFEELAKE_ULT,
+ INTEL_DISPLAY_COFFEELAKE_ULX,
+ INTEL_DISPLAY_COMETLAKE_ULT,
+ INTEL_DISPLAY_COMETLAKE_ULX,
+ INTEL_DISPLAY_ICELAKE_PORT_F,
+ INTEL_DISPLAY_TIGERLAKE_UY,
+ INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S,
+ INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N,
+ INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P,
+ INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U,
+ INTEL_DISPLAY_DG2_G10,
+ INTEL_DISPLAY_DG2_G11,
+ INTEL_DISPLAY_DG2_G12,
+};
+
#define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \
/* Keep in alphabetical order */ \
func(cursor_needs_physical); \
@@ -71,6 +154,7 @@ struct drm_printer;
BIT(trans)) != 0)
#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)
#define INTEL_NUM_PIPES(i915) (hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
#define I915_HAS_HOTPLUG(i915) (DISPLAY_INFO(i915)->has_hotplug)
#define OVERLAY_NEEDS_PHYSICAL(i915) (DISPLAY_INFO(i915)->overlay_needs_physical)
@@ -111,7 +195,10 @@ struct drm_printer;
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
struct intel_display_runtime_info {
- struct {
+ enum intel_display_platform platform;
+ enum intel_display_subplatform subplatform;
+
+ struct intel_display_ip_ver {
u16 ver;
u16 rel;
u16 step;
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index c337e0597541..5219ba295c74 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -18,6 +18,7 @@
#include "intel_fifo_underrun.h"
#include "intel_gmbus.h"
#include "intel_hotplug_irq.h"
+#include "intel_pipe_crc_regs.h"
#include "intel_pmdemand.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
@@ -224,7 +225,7 @@ out:
void i915_enable_pipestat(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 status_mask)
{
- i915_reg_t reg = PIPESTAT(pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, pipe);
u32 enable_mask;
drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK,
@@ -247,7 +248,7 @@ void i915_enable_pipestat(struct drm_i915_private *dev_priv,
void i915_disable_pipestat(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 status_mask)
{
- i915_reg_t reg = PIPESTAT(pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, pipe);
u32 enable_mask;
drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK,
@@ -345,6 +346,7 @@ static void flip_done_handler(struct drm_i915_private *i915,
spin_lock(&i915->drm.event_lock);
if (crtc->flip_done_event) {
+ trace_intel_crtc_flip_done(crtc);
drm_crtc_send_vblank_event(&crtc->base, crtc->flip_done_event);
crtc->flip_done_event = NULL;
}
@@ -356,7 +358,7 @@ static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
display_pipe_crc_irq_handler(dev_priv, pipe,
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_1_IVB(pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_HSW(pipe)),
0, 0, 0, 0);
}
@@ -377,19 +379,21 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
u32 res1, res2;
if (DISPLAY_VER(dev_priv) >= 3)
- res1 = intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RES1_I915(pipe));
+ res1 = intel_uncore_read(&dev_priv->uncore,
+ PIPE_CRC_RES_RES1_I915(dev_priv, pipe));
else
res1 = 0;
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
- res2 = intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RES2_G4X(pipe));
+ res2 = intel_uncore_read(&dev_priv->uncore,
+ PIPE_CRC_RES_RES2_G4X(dev_priv, pipe));
else
res2 = 0;
display_pipe_crc_irq_handler(dev_priv, pipe,
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RED(pipe)),
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_GREEN(pipe)),
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_BLUE(pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RED(dev_priv, pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_GREEN(dev_priv, pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_BLUE(dev_priv, pipe)),
res1, res2);
}
@@ -398,7 +402,8 @@ void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv)
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
- intel_uncore_write(&dev_priv->uncore, PIPESTAT(pipe),
+ intel_uncore_write(&dev_priv->uncore,
+ PIPESTAT(dev_priv, pipe),
PIPESTAT_INT_STATUS_MASK |
PIPE_FIFO_UNDERRUN_STATUS);
@@ -451,7 +456,7 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
if (!status_mask)
continue;
- reg = PIPESTAT(pipe);
+ reg = PIPESTAT(dev_priv, pipe);
pipe_stats[pipe] = intel_uncore_read(&dev_priv->uncore, reg) & status_mask;
enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
@@ -832,14 +837,53 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv)
static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
{
+ if (DISPLAY_VER(dev_priv) >= 14)
+ return MTL_PIPEDMC_ATS_FAULT |
+ MTL_PLANE_ATS_FAULT |
+ GEN12_PIPEDMC_FAULT |
+ GEN9_PIPE_CURSOR_FAULT |
+ GEN11_PIPE_PLANE5_FAULT |
+ GEN9_PIPE_PLANE4_FAULT |
+ GEN9_PIPE_PLANE3_FAULT |
+ GEN9_PIPE_PLANE2_FAULT |
+ GEN9_PIPE_PLANE1_FAULT;
if (DISPLAY_VER(dev_priv) >= 13 || HAS_D12_PLANE_MINIMIZATION(dev_priv))
- return RKL_DE_PIPE_IRQ_FAULT_ERRORS;
- else if (DISPLAY_VER(dev_priv) >= 11)
- return GEN11_DE_PIPE_IRQ_FAULT_ERRORS;
+ return GEN12_PIPEDMC_FAULT |
+ GEN9_PIPE_CURSOR_FAULT |
+ GEN11_PIPE_PLANE5_FAULT |
+ GEN9_PIPE_PLANE4_FAULT |
+ GEN9_PIPE_PLANE3_FAULT |
+ GEN9_PIPE_PLANE2_FAULT |
+ GEN9_PIPE_PLANE1_FAULT;
+ else if (DISPLAY_VER(dev_priv) == 12)
+ return GEN12_PIPEDMC_FAULT |
+ GEN9_PIPE_CURSOR_FAULT |
+ GEN11_PIPE_PLANE7_FAULT |
+ GEN11_PIPE_PLANE6_FAULT |
+ GEN11_PIPE_PLANE5_FAULT |
+ GEN9_PIPE_PLANE4_FAULT |
+ GEN9_PIPE_PLANE3_FAULT |
+ GEN9_PIPE_PLANE2_FAULT |
+ GEN9_PIPE_PLANE1_FAULT;
+ else if (DISPLAY_VER(dev_priv) == 11)
+ return GEN9_PIPE_CURSOR_FAULT |
+ GEN11_PIPE_PLANE7_FAULT |
+ GEN11_PIPE_PLANE6_FAULT |
+ GEN11_PIPE_PLANE5_FAULT |
+ GEN9_PIPE_PLANE4_FAULT |
+ GEN9_PIPE_PLANE3_FAULT |
+ GEN9_PIPE_PLANE2_FAULT |
+ GEN9_PIPE_PLANE1_FAULT;
else if (DISPLAY_VER(dev_priv) >= 9)
- return GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
+ return GEN9_PIPE_CURSOR_FAULT |
+ GEN9_PIPE_PLANE4_FAULT |
+ GEN9_PIPE_PLANE3_FAULT |
+ GEN9_PIPE_PLANE2_FAULT |
+ GEN9_PIPE_PLANE1_FAULT;
else
- return GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
+ return GEN8_PIPE_CURSOR_FAULT |
+ GEN8_PIPE_SPRITE_FAULT |
+ GEN8_PIPE_PRIMARY_FAULT;
}
static void intel_pmdemand_irq_handler(struct drm_i915_private *dev_priv)
@@ -876,7 +920,8 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
if (DISPLAY_VER(dev_priv) >= 12)
- iir_reg = TRANS_PSR_IIR(intel_dp->psr.transcoder);
+ iir_reg = TRANS_PSR_IIR(dev_priv,
+ intel_dp->psr.transcoder);
else
iir_reg = EDP_PSR_IIR;
@@ -909,7 +954,8 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
* Incase of dual link, TE comes from DSI_1
* this is to check if dual link is enabled
*/
- val = intel_uncore_read(&dev_priv->uncore, TRANS_DDI_FUNC_CTL2(TRANSCODER_DSI_0));
+ val = intel_uncore_read(&dev_priv->uncore,
+ TRANS_DDI_FUNC_CTL2(dev_priv, TRANSCODER_DSI_0));
val &= PORT_SYNC_MODE_ENABLE;
/*
@@ -930,7 +976,8 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
}
/* Get PIPE for handling VBLANK event */
- val = intel_uncore_read(&dev_priv->uncore, TRANS_DDI_FUNC_CTL(dsi_trans));
+ val = intel_uncore_read(&dev_priv->uncore,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
switch (val & TRANS_DDI_EDP_INPUT_MASK) {
case TRANS_DDI_EDP_INPUT_A_ON:
pipe = PIPE_A;
@@ -1374,7 +1421,7 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK_VLV);
i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0);
- intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
+ intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT(dev_priv), 0, 0);
i9xx_pipestat_irq_reset(dev_priv);
@@ -1455,8 +1502,12 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
if (!intel_display_power_is_enabled(dev_priv, domain))
continue;
- intel_uncore_write(uncore, TRANS_PSR_IMR(trans), 0xffffffff);
- intel_uncore_write(uncore, TRANS_PSR_IIR(trans), 0xffffffff);
+ intel_uncore_write(uncore,
+ TRANS_PSR_IMR(dev_priv, trans),
+ 0xffffffff);
+ intel_uncore_write(uncore,
+ TRANS_PSR_IIR(dev_priv, trans),
+ 0xffffffff);
}
} else {
intel_uncore_write(uncore, EDP_PSR_IMR, 0xffffffff);
@@ -1688,7 +1739,8 @@ 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, TRANS_PSR_IIR(trans));
+ gen3_assert_iir_is_zero(uncore,
+ TRANS_PSR_IIR(dev_priv, trans));
}
} else {
gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR);
diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.h b/drivers/gpu/drm/i915/display/intel_display_limits.h
index 5126d0b5ae5d..c4775c99dc83 100644
--- a/drivers/gpu/drm/i915/display/intel_display_limits.h
+++ b/drivers/gpu/drm/i915/display/intel_display_limits.h
@@ -60,16 +60,23 @@ enum transcoder {
* (eg. PLANE_CTL(), PS_PLANE_SEL(), etc.) so adjust with care.
*/
enum plane_id {
- PLANE_PRIMARY,
- PLANE_SPRITE0,
- PLANE_SPRITE1,
- PLANE_SPRITE2,
- PLANE_SPRITE3,
- PLANE_SPRITE4,
- PLANE_SPRITE5,
+ /* skl+ universal plane names */
+ PLANE_1,
+ PLANE_2,
+ PLANE_3,
+ PLANE_4,
+ PLANE_5,
+ PLANE_6,
+ PLANE_7,
+
PLANE_CURSOR,
I915_MAX_PLANES,
+
+ /* pre-skl plane names */
+ PLANE_PRIMARY = PLANE_1,
+ PLANE_SPRITE0,
+ PLANE_SPRITE1,
};
enum port {
diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c
index 1799a6643128..e82bd72d32fa 100644
--- a/drivers/gpu/drm/i915/display/intel_display_params.c
+++ b/drivers/gpu/drm/i915/display/intel_display_params.c
@@ -54,6 +54,9 @@ intel_display_param_named_unsafe(enable_dc, int, 0400,
intel_display_param_named_unsafe(enable_dpt, bool, 0400,
"Enable display page table (DPT) (default: true)");
+intel_display_param_named_unsafe(enable_dsb, bool, 0400,
+ "Enable display state buffer (DSB) (default: true)");
+
intel_display_param_named_unsafe(enable_sagv, bool, 0400,
"Enable system agent voltage/frequency scaling (SAGV) (default: true)");
@@ -116,7 +119,7 @@ intel_display_param_named(psr_safest_params, bool, 0400,
"Default: 0");
intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400,
- "Enable PSR2 selective fetch "
+ "Enable PSR2 and Panel Replay selective fetch "
"(0=disabled, 1=enabled) "
"Default: 1");
diff --git a/drivers/gpu/drm/i915/display/intel_display_params.h b/drivers/gpu/drm/i915/display/intel_display_params.h
index 1208a62c16d2..48c29c55c939 100644
--- a/drivers/gpu/drm/i915/display/intel_display_params.h
+++ b/drivers/gpu/drm/i915/display/intel_display_params.h
@@ -31,6 +31,7 @@ struct drm_i915_private;
param(int, vbt_sdvo_panel_type, -1, 0400) \
param(int, enable_dc, -1, 0400) \
param(bool, enable_dpt, true, 0400) \
+ param(bool, enable_dsb, true, 0600) \
param(bool, enable_sagv, true, 0600) \
param(int, disable_power_well, -1, 0400) \
param(bool, enable_ips, true, 0600) \
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 03dc7edcc443..e288a1b21d7e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -675,6 +675,12 @@ intel_display_power_put_async_work(struct work_struct *work)
release_async_put_domains(power_domains,
&power_domains->async_put_domains[0]);
+ /*
+ * Cancel the work that got queued after this one got dequeued,
+ * since here we released the corresponding async-put reference.
+ */
+ cancel_async_put_work(power_domains, false);
+
/* Requeue the work if more domains were async put meanwhile. */
if (!bitmap_empty(power_domains->async_put_domains[1].bits, POWER_DOMAIN_NUM)) {
bitmap_copy(power_domains->async_put_domains[0].bits,
@@ -686,12 +692,6 @@ intel_display_power_put_async_work(struct work_struct *work)
fetch_and_zero(&new_work_wakeref),
power_domains->async_put_next_delay);
power_domains->async_put_next_delay = 0;
- } else {
- /*
- * Cancel the work that got queued after this one got dequeued,
- * since here we released the corresponding async-put reference.
- */
- cancel_async_put_work(power_domains, false);
}
out_verify:
@@ -1207,7 +1207,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
intel_de_read(dev_priv, WRPLL_CTL(1)) & WRPLL_PLL_ENABLE,
"WRPLL2 enabled\n");
I915_STATE_WARN(dev_priv,
- intel_de_read(dev_priv, PP_STATUS(0)) & PP_ON,
+ intel_de_read(dev_priv, PP_STATUS(dev_priv, 0)) & PP_ON,
"Panel power on\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
@@ -1688,6 +1688,10 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
if (IS_DG2(dev_priv))
intel_snps_phy_wait_for_calibration(dev_priv);
+ /* 9. XE2_HPD: Program CHICKEN_MISC_2 before any cursor or planes are enabled */
+ if (DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 1))
+ intel_de_rmw(dev_priv, CHICKEN_MISC_2, BMG_DARB_HALF_BLK_END_BURST, 1);
+
if (resume)
intel_dmc_load_program(dev_priv);
@@ -1768,7 +1772,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
* current lane status.
*/
if (intel_power_well_is_enabled(dev_priv, cmn_bc)) {
- u32 status = intel_de_read(dev_priv, DPLL(PIPE_A));
+ u32 status = intel_de_read(dev_priv, DPLL(dev_priv, PIPE_A));
unsigned int mask;
mask = status & DPLL_PORTB_READY_MASK;
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 83f616097a29..919f712fef13 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -1044,9 +1044,9 @@ 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(PIPE_A)) & TRANSCONF_ENABLE) == 0)
+ 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(PIPE_B)) & TRANSCONF_ENABLE) == 0)
+ if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE) == 0)
i830_enable_pipe(dev_priv, PIPE_B);
}
@@ -1060,8 +1060,8 @@ static void i830_pipes_power_well_disable(struct drm_i915_private *dev_priv,
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(PIPE_A)) & TRANSCONF_ENABLE &&
- intel_de_read(dev_priv, TRANSCONF(PIPE_B)) & TRANSCONF_ENABLE;
+ 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;
}
static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv,
@@ -1196,13 +1196,13 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
* CHV DPLL B/C have some issues if VGA mode is enabled.
*/
for_each_pipe(dev_priv, pipe) {
- u32 val = intel_de_read(dev_priv, DPLL(pipe));
+ u32 val = intel_de_read(dev_priv, DPLL(dev_priv, pipe));
val |= DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
- intel_de_write(dev_priv, DPLL(pipe), val);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
}
vlv_init_display_clock_gating(dev_priv);
@@ -1355,7 +1355,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
*/
if (BITS_SET(phy_control,
PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)) &&
- (intel_de_read(dev_priv, DPLL(PIPE_B)) & DPLL_VCO_ENABLE) == 0)
+ (intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) & DPLL_VCO_ENABLE) == 0)
phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1);
if (BITS_SET(phy_control,
diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h
index 49a5e6d9dc0d..c734ef1fba3c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_trace.h
+++ b/drivers/gpu/drm/i915/display/intel_display_trace.h
@@ -78,6 +78,29 @@ TRACE_EVENT(intel_pipe_disable,
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
);
+TRACE_EVENT(intel_crtc_flip_done,
+ TP_PROTO(struct intel_crtc *crtc),
+ TP_ARGS(crtc),
+
+ TP_STRUCT__entry(
+ __string(dev, __dev_name_kms(crtc))
+ __field(enum pipe, pipe)
+ __field(u32, frame)
+ __field(u32, scanline)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev);
+ __entry->pipe = crtc->pipe;
+ __entry->frame = intel_crtc_get_vblank_counter(crtc);
+ __entry->scanline = intel_get_crtc_scanline(crtc);
+ ),
+
+ TP_printk("dev %s, pipe %c, frame=%u, scanline=%u",
+ __get_str(dev), pipe_name(__entry->pipe),
+ __entry->frame, __entry->scanline)
+);
+
TRACE_EVENT(intel_pipe_crc,
TP_PROTO(struct intel_crtc *crtc, const u32 *crcs),
TP_ARGS(crtc, crcs),
@@ -308,6 +331,33 @@ TRACE_EVENT(vlv_fifo_size,
__entry->sprite0_start, __entry->sprite1_start, __entry->fifo_size)
);
+TRACE_EVENT(intel_plane_async_flip,
+ TP_PROTO(struct intel_plane *plane, struct intel_crtc *crtc, bool async_flip),
+ TP_ARGS(plane, crtc, async_flip),
+
+ TP_STRUCT__entry(
+ __string(dev, __dev_name_kms(plane))
+ __field(enum pipe, pipe)
+ __field(u32, frame)
+ __field(u32, scanline)
+ __field(bool, async_flip)
+ __string(name, plane->base.name)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev);
+ __assign_str(name);
+ __entry->pipe = crtc->pipe;
+ __entry->frame = intel_crtc_get_vblank_counter(crtc);
+ __entry->scanline = intel_get_crtc_scanline(crtc);
+ __entry->async_flip = async_flip;
+ ),
+
+ TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, async_flip=%s",
+ __get_str(dev), pipe_name(__entry->pipe), __get_str(name),
+ __entry->frame, __entry->scanline, str_yes_no(__entry->async_flip))
+);
+
TRACE_EVENT(intel_plane_update_noarm,
TP_PROTO(struct intel_plane *plane, struct intel_crtc *crtc),
TP_ARGS(plane, crtc),
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 62f7a30c37dc..8713835e2307 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -44,9 +44,10 @@
#include <drm/drm_rect.h>
#include <drm/drm_vblank.h>
#include <drm/drm_vblank_work.h>
-#include <drm/i915_hdcp_interface.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"
@@ -145,6 +146,8 @@ struct intel_framebuffer {
};
struct i915_address_space *dpt_vm;
+
+ unsigned int min_alignment;
};
enum intel_hotplug_state {
@@ -160,6 +163,11 @@ struct intel_encoder {
enum port port;
u16 cloneable;
u8 pipe_mask;
+
+ /* Check and recover a bad link state. */
+ struct delayed_work link_check_work;
+ void (*link_check)(struct intel_encoder *encoder);
+
enum intel_hotplug_state (*hotplug)(struct intel_encoder *encoder,
struct intel_connector *connector);
enum intel_output_type (*compute_output_type)(struct intel_encoder *,
@@ -305,7 +313,7 @@ enum drrs_type {
};
struct intel_vbt_panel_data {
- struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
+ struct drm_display_mode *lfp_vbt_mode; /* if any */
struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
/* Feature bits */
@@ -329,6 +337,7 @@ struct intel_vbt_panel_data {
u8 drrs_msa_timing_delay;
bool low_vswing;
bool hobl;
+ bool dsc_disable;
} edp;
struct {
@@ -401,7 +410,12 @@ struct intel_panel {
} vesa;
struct {
bool sdr_uses_aux;
- } intel;
+ bool supports_2084_decode;
+ bool supports_2020_gamut;
+ bool supports_segmented_backlight;
+ bool supports_sdp_colorimetry;
+ bool supports_tone_mapping;
+ } intel_cap;
} edp;
struct backlight_device *device;
@@ -730,6 +744,9 @@ struct intel_plane_state {
struct intel_fb_view view;
u32 phys_dma_addr; /* for cursor_needs_physical */
+ /* for legacy cursor fb unpin */
+ struct drm_vblank_work unpin_work;
+
/* Plane pxp decryption state */
bool decrypt;
@@ -1042,7 +1059,7 @@ struct intel_crtc_state {
*
* During initial hw readout, they need to be copied to uapi.
*
- * Bigjoiner will allow a transcoder mode that spans 2 pipes;
+ * Joiner will allow a transcoder mode that spans 2 pipes;
* Use the pipe_mode for calculations like watermarks, pipe
* scaler, and bandwidth.
*
@@ -1189,7 +1206,7 @@ struct intel_crtc_state {
/* PSR is supported but might not be enabled due the lack of enabled planes */
bool has_psr;
- bool has_psr2;
+ bool has_sel_update;
bool enable_psr2_sel_fetch;
bool enable_psr2_su_region_et;
bool req_psr2_sdp_prior_scanline;
@@ -1338,8 +1355,8 @@ struct intel_crtc_state {
/* enable vlv/chv wgc csc? */
bool wgc_enable;
- /* big joiner pipe bitmask */
- u8 bigjoiner_pipes;
+ /* joiner pipe bitmask */
+ u8 joiner_pipes;
/* Display Stream compression state */
struct {
@@ -1396,6 +1413,12 @@ struct intel_crtc_state {
u32 vsync_end, vsync_start;
} vrr;
+ /* Content Match Refresh Rate state */
+ struct {
+ bool enable;
+ u64 cmrr_n, cmrr_m;
+ } cmrr;
+
/* Stream Splitter for eDP MSO */
struct {
bool enable;
@@ -1405,6 +1428,9 @@ struct intel_crtc_state {
/* for loading single buffered registers during vblank */
struct drm_vblank_work vblank_work;
+
+ /* LOBF flag */
+ bool has_lobf;
};
enum intel_pipe_crc_source {
@@ -1521,7 +1547,7 @@ struct intel_plane {
enum i9xx_plane_id i9xx_plane;
enum plane_id id;
enum pipe pipe;
- bool need_async_flip_disable_wa;
+ bool need_async_flip_toggle_wa;
u32 frontbuffer_bit;
struct {
@@ -1545,6 +1571,9 @@ struct intel_plane {
int (*max_height)(const struct drm_framebuffer *fb,
int color_plane,
unsigned int rotation);
+ unsigned int (*min_alignment)(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane);
unsigned int (*max_stride)(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation);
@@ -1682,6 +1711,7 @@ struct intel_psr {
#define I915_PSR_DEBUG_ENABLE_SEL_FETCH 0x4
#define I915_PSR_DEBUG_IRQ 0x10
#define I915_PSR_DEBUG_SU_REGION_ET_DISABLE 0x20
+#define I915_PSR_DEBUG_PANEL_REPLAY_DISABLE 0x40
u32 debug;
bool sink_support;
@@ -1695,22 +1725,12 @@ struct intel_psr {
unsigned int busy_frontbuffer_bits;
bool sink_psr2_support;
bool link_standby;
- bool psr2_enabled;
+ bool sel_update_enabled;
bool psr2_sel_fetch_enabled;
bool psr2_sel_fetch_cff_enabled;
+ bool su_region_et_enabled;
bool req_psr2_sdp_prior_scanline;
u8 sink_sync_latency;
-
- struct {
- u8 io_wake_lines;
- u8 fast_wake_lines;
-
- /* LNL and beyond */
- u8 check_entry_lines;
- u8 silence_period_sym_clocks;
- u8 lfps_half_cycle_num_of_syms;
- } alpm_parameters;
-
ktime_t last_entry_attempt;
ktime_t last_exit;
bool sink_not_reliable;
@@ -1719,6 +1739,7 @@ struct intel_psr {
u16 su_y_granularity;
bool source_panel_replay_support;
bool sink_panel_replay_support;
+ bool sink_panel_replay_su_support;
bool panel_replay_enabled;
u32 dc3co_exitline;
u32 dc3co_exit_delay;
@@ -1733,10 +1754,10 @@ struct intel_dp {
u8 lane_count;
u8 sink_count;
bool link_trained;
- bool reset_link_params;
bool use_max_params;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
+ u8 pr_dpcd;
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
@@ -1754,10 +1775,21 @@ struct intel_dp {
/* intersection of source and sink rates */
int num_common_rates;
int common_rates[DP_MAX_SUPPORTED_RATES];
- /* Max lane count for the current link */
- int max_link_lane_count;
- /* Max rate for the current link */
- int max_link_rate;
+ struct {
+ /* TODO: move the rest of link specific fields to here */
+ /* Max lane count for the current link */
+ int max_lane_count;
+ /* Max rate for the current link */
+ int max_rate;
+ int force_lane_count;
+ int force_rate;
+ bool retrain_disabled;
+ /* Sequential link training failures after a passing LT */
+ int seq_train_failures;
+ int force_train_failure;
+ bool force_retrain;
+ } link;
+ bool reset_link_params;
int mso_link_count;
int mso_pixel_overlap;
/* sink or branch descriptor */
@@ -1840,6 +1872,19 @@ struct intel_dp {
unsigned long last_oui_write;
bool colorimetry_support;
+
+ struct {
+ u8 io_wake_lines;
+ u8 fast_wake_lines;
+
+ /* LNL and beyond */
+ u8 check_entry_lines;
+ u8 aux_less_wake_lines;
+ u8 silence_period_sym_clocks;
+ u8 lfps_half_cycle_num_of_syms;
+ } alpm_parameters;
+
+ u8 alpm_dpcd;
};
enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c
index a001232ad445..b146b4c46943 100644
--- a/drivers/gpu/drm/i915/display/intel_dkl_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.c
@@ -4,7 +4,6 @@
*/
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_de.h"
#include "intel_display.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index cbd2ac5671b1..73977b173898 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -30,6 +30,7 @@
#include "intel_de.h"
#include "intel_dmc.h"
#include "intel_dmc_regs.h"
+#include "intel_step.h"
/**
* DOC: DMC Firmware Support
@@ -115,6 +116,9 @@ static bool dmc_firmware_param_disabled(struct drm_i915_private *i915)
#define XE2LPD_DMC_PATH DMC_PATH(xe2lpd)
MODULE_FIRMWARE(XE2LPD_DMC_PATH);
+#define BMG_DMC_PATH DMC_PATH(bmg)
+MODULE_FIRMWARE(BMG_DMC_PATH);
+
#define MTL_DMC_PATH DMC_PATH(mtl)
MODULE_FIRMWARE(MTL_DMC_PATH);
@@ -166,6 +170,9 @@ static const char *dmc_firmware_default(struct drm_i915_private *i915, u32 *size
if (DISPLAY_VER_FULL(i915) == 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)) {
+ fw_path = BMG_DMC_PATH;
+ max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
fw_path = MTL_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
@@ -1177,7 +1184,7 @@ void intel_dmc_fini(struct drm_i915_private *i915)
}
}
-void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m,
+void intel_dmc_print_error_state(struct drm_printer *p,
struct drm_i915_private *i915)
{
struct intel_dmc *dmc = i915_to_dmc(i915);
@@ -1185,13 +1192,13 @@ void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m,
if (!HAS_DMC(i915))
return;
- i915_error_printf(m, "DMC initialized: %s\n", str_yes_no(dmc));
- i915_error_printf(m, "DMC loaded: %s\n",
- str_yes_no(intel_dmc_has_payload(i915)));
+ 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)));
if (dmc)
- i915_error_printf(m, "DMC fw version: %d.%d\n",
- DMC_VERSION_MAJOR(dmc->version),
- DMC_VERSION_MINOR(dmc->version));
+ drm_printf(p, "DMC fw version: %d.%d\n",
+ DMC_VERSION_MAJOR(dmc->version),
+ DMC_VERSION_MINOR(dmc->version));
}
static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
index fd607afff2ef..54cff6002e31 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc.h
@@ -8,9 +8,9 @@
#include <linux/types.h>
-struct drm_i915_error_state_buf;
-struct drm_i915_private;
enum pipe;
+struct drm_i915_private;
+struct drm_printer;
void intel_dmc_init(struct drm_i915_private *i915);
void intel_dmc_load_program(struct drm_i915_private *i915);
@@ -22,7 +22,7 @@ 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_i915_error_state_buf *m,
+void intel_dmc_print_error_state(struct drm_printer *p,
struct drm_i915_private *i915);
void assert_dmc_loaded(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5b3b6ae1e3d7..3903f6ead6e6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -48,6 +48,7 @@
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
+#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_backlight.h"
@@ -68,6 +69,7 @@
#include "intel_dpio_phy.h"
#include "intel_dpll.h"
#include "intel_drrs.h"
+#include "intel_encoder.h"
#include "intel_fifo_underrun.h"
#include "intel_hdcp.h"
#include "intel_hdmi.h"
@@ -75,6 +77,7 @@
#include "intel_hotplug_irq.h"
#include "intel_lspcon.h"
#include "intel_lvds.h"
+#include "intel_modeset_lock.h"
#include "intel_panel.h"
#include "intel_pch_display.h"
#include "intel_pps.h"
@@ -329,7 +332,7 @@ static int intel_dp_common_len_rate_limit(const struct intel_dp *intel_dp,
intel_dp->num_common_rates, max_rate);
}
-static int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
+int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
{
if (drm_WARN_ON(&dp_to_i915(intel_dp)->drm,
index < 0 || index >= intel_dp->num_common_rates))
@@ -344,7 +347,7 @@ int intel_dp_max_common_rate(struct intel_dp *intel_dp)
return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1);
}
-static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
+int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
{
int vbt_max_lanes = intel_bios_dp_max_lane_count(dig_port->base.devdata);
int max_lanes = dig_port->max_lanes;
@@ -370,19 +373,39 @@ int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
return min3(source_max, sink_max, lane_max);
}
+static int forced_lane_count(struct intel_dp *intel_dp)
+{
+ return clamp(intel_dp->link.force_lane_count, 1, intel_dp_max_common_lane_count(intel_dp));
+}
+
int intel_dp_max_lane_count(struct intel_dp *intel_dp)
{
- switch (intel_dp->max_link_lane_count) {
+ int lane_count;
+
+ if (intel_dp->link.force_lane_count)
+ lane_count = forced_lane_count(intel_dp);
+ else
+ lane_count = intel_dp->link.max_lane_count;
+
+ switch (lane_count) {
case 1:
case 2:
case 4:
- return intel_dp->max_link_lane_count;
+ return lane_count;
default:
- MISSING_CASE(intel_dp->max_link_lane_count);
+ MISSING_CASE(lane_count);
return 1;
}
}
+static int intel_dp_min_lane_count(struct intel_dp *intel_dp)
+{
+ if (intel_dp->link.force_lane_count)
+ return forced_lane_count(intel_dp);
+
+ return 1;
+}
+
/*
* The required data bandwidth for a mode with given pixel clock and bpp. This
* is the required net bandwidth independent of the data bandwidth efficiency.
@@ -436,7 +459,7 @@ int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
return max_rate;
}
-bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp)
+bool intel_dp_has_joiner(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *encoder = &intel_dig_port->base;
@@ -481,6 +504,9 @@ static int mtl_max_source_rate(struct intel_dp *intel_dp)
if (intel_encoder_is_c10phy(encoder))
return 810000;
+ if (DISPLAY_VER_FULL(to_i915(encoder->base.dev)) == IP_VER(14, 1))
+ return 1350000;
+
return 2000000;
}
@@ -605,7 +631,7 @@ static int intersect_rates(const int *source_rates, int source_len,
}
/* return index of rate in rates array, or -1 if not found */
-static int intel_dp_rate_index(const int *rates, int len, int rate)
+int intel_dp_rate_index(const int *rates, int len, int rate)
{
int i;
@@ -645,7 +671,7 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
* boot-up.
*/
if (link_rate == 0 ||
- link_rate > intel_dp->max_link_rate)
+ link_rate > intel_dp->link.max_rate)
return false;
if (lane_count == 0 ||
@@ -655,78 +681,6 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
return true;
}
-static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
- int link_rate,
- u8 lane_count)
-{
- /* FIXME figure out what we actually want here */
- const struct drm_display_mode *fixed_mode =
- intel_panel_preferred_fixed_mode(intel_dp->attached_connector);
- int mode_rate, max_rate;
-
- mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
- max_rate = intel_dp_max_link_data_rate(intel_dp, link_rate, lane_count);
- if (mode_rate > max_rate)
- return false;
-
- return true;
-}
-
-int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
- int link_rate, u8 lane_count)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int index;
-
- /*
- * TODO: Enable fallback on MST links once MST link compute can handle
- * the fallback params.
- */
- if (intel_dp->is_mst) {
- drm_err(&i915->drm, "Link Training Unsuccessful\n");
- return -1;
- }
-
- if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
- drm_dbg_kms(&i915->drm,
- "Retrying Link training for eDP with max parameters\n");
- intel_dp->use_max_params = true;
- return 0;
- }
-
- index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- link_rate);
- if (index > 0) {
- if (intel_dp_is_edp(intel_dp) &&
- !intel_dp_can_link_train_fallback_for_edp(intel_dp,
- intel_dp_common_rate(intel_dp, index - 1),
- lane_count)) {
- drm_dbg_kms(&i915->drm,
- "Retrying Link training for eDP with same parameters\n");
- return 0;
- }
- intel_dp->max_link_rate = intel_dp_common_rate(intel_dp, index - 1);
- intel_dp->max_link_lane_count = lane_count;
- } else if (lane_count > 1) {
- if (intel_dp_is_edp(intel_dp) &&
- !intel_dp_can_link_train_fallback_for_edp(intel_dp,
- intel_dp_max_common_rate(intel_dp),
- lane_count >> 1)) {
- drm_dbg_kms(&i915->drm,
- "Retrying Link training for eDP with same parameters\n");
- return 0;
- }
- intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
- intel_dp->max_link_lane_count = lane_count >> 1;
- } else {
- drm_err(&i915->drm, "Link Training Unsuccessful\n");
- return -1;
- }
-
- return 0;
-}
-
u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
{
return div_u64(mul_u32_u32(mode_clock, DP_DSC_FEC_OVERHEAD_FACTOR),
@@ -1208,19 +1162,39 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
return MODE_OK;
}
-bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
- struct intel_connector *connector,
- int hdisplay, int clock)
+bool intel_dp_need_joiner(struct intel_dp *intel_dp,
+ struct intel_connector *connector,
+ int hdisplay, int clock)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- if (!intel_dp_has_bigjoiner(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;
}
+bool intel_dp_has_dsc(const struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+
+ if (!HAS_DSC(i915))
+ return false;
+
+ if (connector->mst_port && !HAS_DSC_MST(i915))
+ return false;
+
+ if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
+ connector->panel.vbt.edp.dsc_disable)
+ return false;
+
+ if (!drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd))
+ return false;
+
+ return true;
+}
+
static enum drm_mode_status
intel_dp_mode_valid(struct drm_connector *_connector,
struct drm_display_mode *mode)
@@ -1235,7 +1209,7 @@ 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, bigjoiner = false;
+ bool dsc = false, joiner = false;
status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
if (status != MODE_OK)
@@ -1256,9 +1230,9 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock = fixed_mode->clock;
}
- if (intel_dp_need_bigjoiner(intel_dp, connector,
- mode->hdisplay, target_clock)) {
- bigjoiner = true;
+ if (intel_dp_need_joiner(intel_dp, connector,
+ mode->hdisplay, target_clock)) {
+ joiner = true;
max_dotclk *= 2;
}
if (target_clock > max_dotclk)
@@ -1275,8 +1249,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
mode_rate = intel_dp_link_required(target_clock,
intel_dp_mode_min_output_bpp(connector, mode));
- if (HAS_DSC(dev_priv) &&
- drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd)) {
+ if (intel_dp_has_dsc(connector)) {
enum intel_output_format sink_format, output_format;
int pipe_bpp;
@@ -1305,20 +1278,20 @@ intel_dp_mode_valid(struct drm_connector *_connector,
max_lanes,
target_clock,
mode->hdisplay,
- bigjoiner,
+ joiner,
output_format,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(connector,
target_clock,
mode->hdisplay,
- bigjoiner);
+ joiner);
}
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
- if (intel_dp_joiner_needs_dsc(dev_priv, bigjoiner) && !dsc)
+ if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc)
return MODE_CLOCK_HIGH;
if (mode_rate > max_rate && !dsc)
@@ -1328,7 +1301,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, bigjoiner);
+ return intel_mode_valid_max_plane_size(dev_priv, mode, joiner);
}
bool intel_dp_source_supports_tps3(struct drm_i915_private *i915)
@@ -1378,16 +1351,38 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
drm_dbg_kms(&i915->drm, "common rates: %s\n", str);
}
+static int forced_link_rate(struct intel_dp *intel_dp)
+{
+ int len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.force_rate);
+
+ if (len == 0)
+ return intel_dp_common_rate(intel_dp, 0);
+
+ return intel_dp_common_rate(intel_dp, len - 1);
+}
+
int
intel_dp_max_link_rate(struct intel_dp *intel_dp)
{
int len;
- len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->max_link_rate);
+ if (intel_dp->link.force_rate)
+ return forced_link_rate(intel_dp);
+
+ len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.max_rate);
return intel_dp_common_rate(intel_dp, len - 1);
}
+static int
+intel_dp_min_link_rate(struct intel_dp *intel_dp)
+{
+ if (intel_dp->link.force_rate)
+ return forced_link_rate(intel_dp);
+
+ return intel_dp_common_rate(intel_dp, 0);
+}
+
int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -1445,15 +1440,16 @@ bool intel_dp_supports_fec(struct intel_dp *intel_dp,
drm_dp_sink_supports_fec(connector->dp.fec_capability);
}
-static bool intel_dp_supports_dsc(const struct intel_connector *connector,
- const struct intel_crtc_state *crtc_state)
+bool intel_dp_supports_dsc(const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state)
{
+ if (!intel_dp_has_dsc(connector))
+ return false;
+
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
return false;
- return intel_dsc_source_support(crtc_state) &&
- connector->dp.dsc_decompression_aux &&
- drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
+ return intel_dsc_source_support(crtc_state);
}
static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp,
@@ -2019,7 +2015,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->bigjoiner_pipes);
+ pipe_config->joiner_pipes);
dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp);
dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
@@ -2253,7 +2249,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->bigjoiner_pipes);
+ pipe_config->joiner_pipes);
if (!dsc_dp_slice_count) {
drm_dbg_kms(&dev_priv->drm,
"Compressed Slice Count not supported\n");
@@ -2267,7 +2263,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
* is greater than the maximum Cdclock and if slice count is even
* then we need to use 2 VDSC instances.
*/
- if (pipe_config->bigjoiner_pipes || pipe_config->dsc.slice_count > 1)
+ if (pipe_config->joiner_pipes || pipe_config->dsc.slice_count > 1)
pipe_config->dsc.dsc_split = true;
ret = intel_dp_dsc_compute_params(connector, pipe_config);
@@ -2357,13 +2353,14 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
bool dsc,
struct link_config_limits *limits)
{
- limits->min_rate = intel_dp_common_rate(intel_dp, 0);
+ limits->min_rate = intel_dp_min_link_rate(intel_dp);
limits->max_rate = intel_dp_max_link_rate(intel_dp);
/* FIXME 128b/132b SST support missing */
limits->max_rate = min(limits->max_rate, 810000);
+ limits->min_rate = min(limits->min_rate, limits->max_rate);
- limits->min_lane_count = 1;
+ limits->min_lane_count = intel_dp_min_lane_count(intel_dp);
limits->max_lane_count = intel_dp_max_lane_count(intel_dp);
limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format);
@@ -2433,12 +2430,12 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
!intel_dp_supports_fec(intel_dp, connector, pipe_config))
return -EINVAL;
- if (intel_dp_need_bigjoiner(intel_dp, connector,
- adjusted_mode->crtc_hdisplay,
- adjusted_mode->crtc_clock))
- pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
+ 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);
- joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, pipe_config->bigjoiner_pipes);
+ joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, pipe_config->joiner_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_compute_config_limits(intel_dp, pipe_config,
@@ -2637,11 +2634,19 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
/* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
- as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
- as_sdp->vtotal = adjusted_mode->vtotal;
- as_sdp->target_rr = 0;
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;
+ as_sdp->vtotal = adjusted_mode->vtotal;
+ as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode);
+ as_sdp->target_rr_divider = true;
+ } else {
+ as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+ as_sdp->vtotal = adjusted_mode->vtotal;
+ as_sdp->target_rr = 0;
+ }
}
static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
@@ -2664,14 +2669,6 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
intel_dp_compute_vsc_colorimetry(crtc_state, conn_state,
vsc);
- } else if (crtc_state->has_psr2) {
- /*
- * [PSR2 without colorimetry]
- * Prepare VSC Header for SU as per eDP 1.4 spec, Table 6-11
- * 3D stereo + PSR/PSR2 + Y-coordinate.
- */
- vsc->revision = 0x4;
- vsc->length = 0xe;
} else if (crtc_state->has_panel_replay) {
/*
* [Panel Replay without colorimetry info]
@@ -2680,6 +2677,14 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
*/
vsc->revision = 0x6;
vsc->length = 0x10;
+ } else if (crtc_state->has_sel_update) {
+ /*
+ * [PSR2 without colorimetry]
+ * Prepare VSC Header for SU as per eDP 1.4 spec, Table 6-11
+ * 3D stereo + PSR/PSR2 + Y-coordinate.
+ */
+ vsc->revision = 0x4;
+ vsc->length = 0xe;
} else {
/*
* [PSR1]
@@ -2758,7 +2763,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
* FIXME all joined pipes share the same transcoder.
* Need to account for that when updating M/N live.
*/
- if (has_seamless_m_n(connector) && !pipe_config->bigjoiner_pipes)
+ if (has_seamless_m_n(connector) && !pipe_config->joiner_pipes)
pipe_config->update_m_n = true;
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
@@ -2787,7 +2792,6 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
}
static bool intel_dp_has_audio(struct intel_encoder *encoder,
- struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
@@ -2796,8 +2800,7 @@ static bool intel_dp_has_audio(struct intel_encoder *encoder,
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
- if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
- !intel_dp_port_has_audio(i915, encoder->port))
+ if (!intel_dp_port_has_audio(i915, encoder->port))
return false;
if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
@@ -2856,14 +2859,14 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state)
{
pipe_config->has_audio =
- intel_dp_has_audio(encoder, pipe_config, conn_state) &&
+ intel_dp_has_audio(encoder, conn_state) &&
intel_audio_compute_config(encoder, pipe_config, conn_state);
pipe_config->sdp_split_enable = pipe_config->has_audio &&
intel_dp_is_uhbr(pipe_config);
}
-void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
+static void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
@@ -2872,6 +2875,7 @@ void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
drm_connector_put(&connector->base);
}
+/* NOTE: @state is only valid for MST links and can be %NULL for SST. */
void
intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
struct intel_encoder *encoder,
@@ -2880,6 +2884,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
struct intel_connector *connector;
struct intel_digital_connector_state *conn_state;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i;
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
@@ -2888,6 +2893,9 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
return;
}
+ if (drm_WARN_ON(&i915->drm, !state))
+ return;
+
for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
if (!conn_state->base.crtc)
continue;
@@ -3001,6 +3009,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
intel_vrr_compute_config(pipe_config, conn_state);
intel_dp_compute_as_sdp(intel_dp, pipe_config);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
+ intel_alpm_lobf_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
@@ -3018,10 +3027,12 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
intel_dp->lane_count = lane_count;
}
-static void intel_dp_reset_max_link_params(struct intel_dp *intel_dp)
+void intel_dp_reset_link_params(struct intel_dp *intel_dp)
{
- intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp);
- intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
+ intel_dp->link.max_lane_count = intel_dp_max_common_lane_count(intel_dp);
+ intel_dp->link.max_rate = intel_dp_max_common_rate(intel_dp);
+ intel_dp->link.retrain_disabled = false;
+ intel_dp->link.seq_train_failures = 0;
}
/* Enable backlight PWM and backlight PP control. */
@@ -3356,7 +3367,7 @@ void intel_dp_sync_state(struct intel_encoder *encoder,
intel_dp_tunnel_resume(intel_dp, crtc_state, dpcd_updated);
if (crtc_state)
- intel_dp_reset_max_link_params(intel_dp);
+ intel_dp_reset_link_params(intel_dp);
}
bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
@@ -4231,6 +4242,9 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,
sdp->db[3] = as_sdp->target_rr & 0xFF;
sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+ if (as_sdp->target_rr_divider)
+ sdp->db[4] |= 0x20;
+
return length;
}
@@ -4354,7 +4368,8 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
+ i915_reg_t reg = HSW_TVIDEO_DIP_CTL(dev_priv,
+ crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
@@ -4411,6 +4426,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
as_sdp->mode = sdp->db[0] & DP_ADAPTIVE_SYNC_SDP_OPERATION_MODE;
as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1];
as_sdp->target_rr = (u64)sdp->db[3] | ((u64)sdp->db[4] & 0x3);
+ as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false;
return 0;
}
@@ -4436,7 +4452,8 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
vsc->length = sdp->sdp_header.HB3;
if ((sdp->sdp_header.HB2 == 0x2 && sdp->sdp_header.HB3 == 0x8) ||
- (sdp->sdp_header.HB2 == 0x4 && sdp->sdp_header.HB3 == 0xe)) {
+ (sdp->sdp_header.HB2 == 0x4 && sdp->sdp_header.HB3 == 0xe) ||
+ (sdp->sdp_header.HB2 == 0x6 && sdp->sdp_header.HB3 == 0x10)) {
/*
* - HB2 = 0x2, HB3 = 0x8
* VSC SDP supporting 3D stereo + PSR
@@ -4444,6 +4461,8 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
* VSC SDP supporting 3D stereo + PSR2 with Y-coordinate of
* first scan line of the SU region (applies to eDP v1.4b
* and higher).
+ * - HB2 = 0x6, HB3 = 0x10
+ * VSC SDP supporting 3D stereo + Panel Replay.
*/
return 0;
} else if (sdp->sdp_header.HB2 == 0x5 && sdp->sdp_header.HB3 == 0x13) {
@@ -5021,6 +5040,8 @@ static bool
intel_dp_check_mst_status(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
bool link_ok = true;
bool reprobe_needed = false;
@@ -5066,7 +5087,10 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr);
}
- return link_ok && !reprobe_needed;
+ if (!link_ok || intel_dp->link.force_retrain)
+ intel_encoder_link_check_queue_work(encoder, 0);
+
+ return !reprobe_needed;
}
static void
@@ -5112,6 +5136,9 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
if (intel_psr_enabled(intel_dp))
return false;
+ if (intel_dp->link.force_retrain)
+ return true;
+
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
link_status) < 0)
return false;
@@ -5128,6 +5155,12 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
intel_dp->lane_count))
return false;
+ if (intel_dp->link.retrain_disabled)
+ return false;
+
+ if (intel_dp->link.seq_train_failures)
+ return true;
+
/* Retrain if link not ok */
return !intel_dp_link_ok(intel_dp, link_status);
}
@@ -5213,12 +5246,13 @@ static bool intel_dp_is_connected(struct intel_dp *intel_dp)
intel_dp->is_mst;
}
-int intel_dp_retrain_link(struct intel_encoder *encoder,
- struct drm_modeset_acquire_ctx *ctx)
+static int intel_dp_retrain_link(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;
+ bool mst_output = false;
u8 pipe_mask;
int ret;
@@ -5243,13 +5277,19 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
if (!intel_dp_needs_link_retrain(intel_dp))
return 0;
- drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link\n",
- encoder->base.base.id, encoder->base.name);
+ drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link (forced %s)\n",
+ encoder->base.base.id, encoder->base.name,
+ str_yes_no(intel_dp->link.force_retrain));
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);
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
+ mst_output = true;
+ break;
+ }
+
/* Suppress underruns caused by re-training */
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
if (crtc_state->has_pch_encoder)
@@ -5257,19 +5297,26 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), false);
}
+ /* TODO: use a modeset for SST as well. */
+ if (mst_output) {
+ ret = intel_modeset_commit_pipes(dev_priv, pipe_mask, ctx);
+
+ if (ret && ret != -EDEADLK)
+ drm_dbg_kms(&dev_priv->drm,
+ "[ENCODER:%d:%s] link retraining failed: %pe\n",
+ encoder->base.base.id, encoder->base.name,
+ ERR_PTR(ret));
+
+ goto out;
+ }
+
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);
- /* retrain 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_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(NULL, intel_dp, crtc_state);
intel_dp_stop_link_train(intel_dp, crtc_state);
break;
}
@@ -5287,7 +5334,37 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), true);
}
- return 0;
+out:
+ if (ret != -EDEADLK)
+ intel_dp->link.force_retrain = false;
+
+ return ret;
+}
+
+void intel_dp_link_check(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret)
+ ret = intel_dp_retrain_link(encoder, &ctx);
+
+ drm_WARN_ON(&i915->drm, ret);
+}
+
+void intel_dp_check_link_state(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
+
+ if (!intel_dp_is_connected(intel_dp))
+ return;
+
+ if (!intel_dp_needs_link_retrain(intel_dp))
+ return;
+
+ intel_encoder_link_check_queue_work(encoder, 0);
}
static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
@@ -5500,9 +5577,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
/* Handle CEC interrupts, if any */
drm_dp_cec_irq(&intel_dp->aux);
- /* defer to the hotplug work for link retraining if needed */
- if (intel_dp_needs_link_retrain(intel_dp))
- return false;
+ intel_dp_check_link_state(intel_dp);
intel_psr_short_pulse(intel_dp);
@@ -5862,6 +5937,7 @@ intel_dp_detect(struct drm_connector *connector,
memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
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;
intel_dp_mst_disconnect(intel_dp);
@@ -5884,12 +5960,8 @@ intel_dp_detect(struct drm_connector *connector,
intel_dp_mst_configure(intel_dp);
- /*
- * TODO: Reset link params when switching to MST mode, until MST
- * supports link training fallback params.
- */
- if (intel_dp->reset_link_params || intel_dp->is_mst) {
- intel_dp_reset_max_link_params(intel_dp);
+ if (intel_dp->reset_link_params) {
+ intel_dp_reset_link_params(intel_dp);
intel_dp->reset_link_params = false;
}
@@ -5908,12 +5980,13 @@ intel_dp_detect(struct drm_connector *connector,
/*
* Some external monitors do not signal loss of link synchronization
* with an IRQ_HPD, so force a link status check.
+ *
+ * TODO: this probably became redundant, so remove it: the link state
+ * is rechecked/recovered now after modesets, where the loss of
+ * synchronization tends to occur.
*/
- if (!intel_dp_is_edp(intel_dp)) {
- ret = intel_dp_retrain_link(encoder, ctx);
- if (ret)
- return ret;
- }
+ if (!intel_dp_is_edp(intel_dp))
+ intel_dp_check_link_state(intel_dp);
/*
* Clearing NACK and defer counts to get their exact values
@@ -6055,11 +6128,14 @@ void intel_dp_connector_sync_state(struct intel_connector *connector,
}
}
-void intel_dp_encoder_flush_work(struct drm_encoder *encoder)
+void intel_dp_encoder_flush_work(struct drm_encoder *_encoder)
{
- struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
+ struct intel_encoder *encoder = to_intel_encoder(_encoder);
+ struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_dp *intel_dp = &dig_port->dp;
+ intel_encoder_link_check_flush_work(encoder);
+
intel_dp_mst_encoder_cleanup(dig_port);
intel_dp_tunnel_destroy(intel_dp);
@@ -6365,8 +6441,8 @@ bool intel_dp_is_port_edp(struct drm_i915_private *i915, enum port port)
return _intel_dp_is_port_edp(i915, devdata, port);
}
-static bool
-has_gamut_metadata_dip(struct intel_encoder *encoder)
+bool
+intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum port port = encoder->port;
@@ -6413,7 +6489,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
intel_attach_dp_colorspace_property(connector);
}
- if (has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
+ if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
drm_connector_attach_hdr_output_metadata_property(connector);
if (HAS_VRR(dev_priv))
@@ -6512,6 +6588,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
*/
intel_hpd_enable_detection(encoder);
+ intel_alpm_init_dpcd(intel_dp);
+
/* Cache DPCD and EDID for edp. */
has_dpcd = intel_edp_init_dpcd(intel_dp, intel_connector);
@@ -6741,7 +6819,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_dp_set_source_rates(intel_dp);
intel_dp_set_common_rates(intel_dp);
- intel_dp_reset_max_link_params(intel_dp);
+ intel_dp_reset_link_params(intel_dp);
/* init MST on ports that can support it */
intel_dp_mst_encoder_init(dig_port,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 106ecfde36d9..a0f990a95ecc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -44,7 +44,6 @@ 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);
void intel_dp_init_modeset_retry_work(struct intel_connector *connector);
-void intel_dp_queue_modeset_retry_work(struct intel_connector *connector);
void
intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
struct intel_encoder *encoder,
@@ -55,13 +54,11 @@ void intel_dp_connector_sync_state(struct intel_connector *connector,
const struct intel_crtc_state *crtc_state);
void intel_dp_set_link_params(struct intel_dp *intel_dp,
int link_rate, int lane_count);
-int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
- int link_rate, u8 lane_count);
int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
struct drm_modeset_acquire_ctx *ctx,
u8 *pipe_mask);
-int intel_dp_retrain_link(struct intel_encoder *encoder,
- struct drm_modeset_acquire_ctx *ctx);
+void intel_dp_link_check(struct intel_encoder *encoder);
+void intel_dp_check_link_state(struct intel_dp *intel_dp);
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
@@ -90,6 +87,7 @@ bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);
bool intel_dp_is_edp(struct intel_dp *intel_dp);
bool intel_dp_as_sdp_supported(struct intel_dp *intel_dp);
bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
+bool intel_dp_has_dsc(const struct intel_connector *connector);
int intel_dp_link_symbol_size(int rate);
int intel_dp_link_symbol_clock(int rate);
bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
@@ -101,13 +99,17 @@ void intel_edp_backlight_off(const struct drm_connector_state *conn_state);
void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
void intel_dp_mst_suspend(struct drm_i915_private *dev_priv);
void intel_dp_mst_resume(struct drm_i915_private *dev_priv);
+int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port);
int intel_dp_max_link_rate(struct intel_dp *intel_dp);
int intel_dp_max_lane_count(struct intel_dp *intel_dp);
int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state);
int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
int intel_dp_max_common_rate(struct intel_dp *intel_dp);
int intel_dp_max_common_lane_count(struct intel_dp *intel_dp);
+int intel_dp_common_rate(struct intel_dp *intel_dp, int index);
+int intel_dp_rate_index(const int *rates, int len, int rate);
void intel_dp_update_sink_caps(struct intel_dp *intel_dp);
+void intel_dp_reset_link_params(struct intel_dp *intel_dp);
void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
u8 *link_bw, u8 *rate_select);
@@ -121,7 +123,7 @@ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
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_has_bigjoiner(struct intel_dp *intel_dp);
+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);
void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
@@ -150,9 +152,9 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
bool bigjoiner);
-bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
- struct intel_connector *connector,
- int hdisplay, int clock);
+bool intel_dp_need_joiner(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)
{
@@ -169,6 +171,9 @@ bool intel_dp_supports_fec(struct intel_dp *intel_dp,
const struct intel_connector *connector,
const struct intel_crtc_state *pipe_config);
+bool intel_dp_supports_dsc(const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state);
+
u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 pipe_bpp);
void intel_ddi_update_pipe(struct intel_atomic_state *state,
@@ -196,5 +201,6 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
struct link_config_limits *limits);
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);
#endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 4f58efdc688a..8ce60d53dcde 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -40,11 +40,6 @@
#include "intel_dp.h"
#include "intel_dp_aux_backlight.h"
-/* TODO:
- * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we
- * can make people's backlights work in the mean time
- */
-
/*
* DP AUX registers for Intel's proprietary HDR backlight interface. We define
* them here since we'll likely be the only driver to ever use these.
@@ -69,14 +64,14 @@
#define INTEL_EDP_HDR_GETSET_CTRL_PARAMS 0x344
# define INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE BIT(0)
# define INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE BIT(1)
-# define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE BIT(2) /* Pre-TGL+ */
+# define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE BIT(2)
# define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE BIT(3)
# define INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE BIT(4)
# define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_ENABLE BIT(5)
/* Bit 6 is reserved */
-# define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_ENABLE BIT(7)
+# define INTEL_EDP_HDR_TCON_SDP_OVERRIDE_AUX BIT(7)
-#define INTEL_EDP_HDR_CONTENT_LUMINANCE 0x346 /* Pre-TGL+ */
+#define INTEL_EDP_HDR_CONTENT_LUMINANCE 0x346
#define INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE 0x34A
#define INTEL_EDP_SDR_LUMINANCE_LEVEL 0x352
#define INTEL_EDP_BRIGHTNESS_NITS_LSB 0x354
@@ -127,9 +122,6 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
if (ret != sizeof(tcon_cap))
return false;
- if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
- return false;
-
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Detected %s HDR backlight interface version %d\n",
connector->base.base.id, connector->base.name,
is_intel_tcon_cap(tcon_cap) ? "Intel" : "unsupported", tcon_cap[0]);
@@ -137,6 +129,9 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
if (!is_intel_tcon_cap(tcon_cap))
return false;
+ if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
+ return false;
+
/*
* If we don't have HDR static metadata there is no way to
* runtime detect used range for nits based control. For now
@@ -156,8 +151,18 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
return false;
}
- panel->backlight.edp.intel.sdr_uses_aux =
+ panel->backlight.edp.intel_cap.sdr_uses_aux =
tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP;
+ panel->backlight.edp.intel_cap.supports_2084_decode =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_2084_DECODE_CAP;
+ panel->backlight.edp.intel_cap.supports_2020_gamut =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_2020_GAMUT_CAP;
+ panel->backlight.edp.intel_cap.supports_segmented_backlight =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_CAP;
+ panel->backlight.edp.intel_cap.supports_sdp_colorimetry =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_CAP;
+ panel->backlight.edp.intel_cap.supports_tone_mapping =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_TONE_MAPPING_CAP;
return true;
}
@@ -178,7 +183,7 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe
}
if (!(tmp & INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE)) {
- if (!panel->backlight.edp.intel.sdr_uses_aux) {
+ if (!panel->backlight.edp.intel_cap.sdr_uses_aux) {
u32 pwm_level = panel->backlight.pwm_funcs->get(connector, pipe);
return intel_backlight_level_from_pwm(connector, pwm_level);
@@ -215,13 +220,27 @@ intel_dp_aux_hdr_set_aux_backlight(const struct drm_connector_state *conn_state,
connector->base.base.id, connector->base.name);
}
+static bool
+intel_dp_in_hdr_mode(const struct drm_connector_state *conn_state)
+{
+ struct hdr_output_metadata *hdr_metadata;
+
+ if (!conn_state->hdr_output_metadata)
+ return false;
+
+ hdr_metadata = conn_state->hdr_output_metadata->data;
+
+ return hdr_metadata->hdmi_metadata_type1.eotf == HDMI_EOTF_SMPTE_ST2084;
+}
+
static void
intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32 level)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_panel *panel = &connector->panel;
- if (panel->backlight.edp.intel.sdr_uses_aux) {
+ if (intel_dp_in_hdr_mode(conn_state) ||
+ panel->backlight.edp.intel_cap.sdr_uses_aux) {
intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
} else {
const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
@@ -231,6 +250,64 @@ intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32
}
static void
+intel_dp_aux_write_content_luminance(struct intel_connector *connector,
+ struct hdr_output_metadata *hdr_metadata)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ int ret;
+ u8 buf[4];
+
+ if (!intel_dp_has_gamut_metadata_dip(connector->encoder))
+ return;
+
+ buf[0] = hdr_metadata->hdmi_metadata_type1.max_cll & 0xFF;
+ buf[1] = (hdr_metadata->hdmi_metadata_type1.max_cll & 0xFF00) >> 8;
+ buf[2] = hdr_metadata->hdmi_metadata_type1.max_fall & 0xFF;
+ buf[3] = (hdr_metadata->hdmi_metadata_type1.max_fall & 0xFF00) >> 8;
+
+ ret = drm_dp_dpcd_write(&intel_dp->aux,
+ INTEL_EDP_HDR_CONTENT_LUMINANCE,
+ buf, sizeof(buf));
+ if (ret < 0)
+ drm_dbg_kms(&i915->drm,
+ "Content Luminance DPCD reg write failed, err:-%d\n",
+ ret);
+}
+
+static void
+intel_dp_aux_fill_hdr_tcon_params(const struct drm_connector_state *conn_state, u8 *ctrl)
+{
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
+ struct intel_panel *panel = &connector->panel;
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+
+ /*
+ * According to spec segmented backlight needs to be set whenever panel is in
+ * HDR mode.
+ */
+ if (intel_dp_in_hdr_mode(conn_state)) {
+ *ctrl |= INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE;
+ *ctrl |= INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE;
+ }
+
+ if (DISPLAY_VER(i915) < 11)
+ *ctrl &= ~INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE;
+
+ if (panel->backlight.edp.intel_cap.supports_2020_gamut &&
+ (conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB ||
+ conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC ||
+ conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_CYCC))
+ *ctrl |= INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE;
+
+ if (panel->backlight.edp.intel_cap.supports_sdp_colorimetry &&
+ intel_dp_has_gamut_metadata_dip(connector->encoder))
+ *ctrl |= INTEL_EDP_HDR_TCON_SDP_OVERRIDE_AUX;
+ else
+ *ctrl &= ~INTEL_EDP_HDR_TCON_SDP_OVERRIDE_AUX;
+}
+
+static void
intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state, u32 level)
{
@@ -238,6 +315,7 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
struct intel_panel *panel = &connector->panel;
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
+ struct hdr_output_metadata *hdr_metadata;
int ret;
u8 old_ctrl, ctrl;
@@ -251,8 +329,10 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
}
ctrl = old_ctrl;
- if (panel->backlight.edp.intel.sdr_uses_aux) {
+ if (intel_dp_in_hdr_mode(conn_state) ||
+ panel->backlight.edp.intel_cap.sdr_uses_aux) {
ctrl |= INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE;
+
intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
} else {
u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
@@ -262,10 +342,17 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
ctrl &= ~INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE;
}
+ intel_dp_aux_fill_hdr_tcon_params(conn_state, &ctrl);
+
if (ctrl != old_ctrl &&
drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl) != 1)
drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to configure DPCD brightness controls\n",
connector->base.base.id, connector->base.name);
+
+ if (intel_dp_in_hdr_mode(conn_state)) {
+ hdr_metadata = conn_state->hdr_output_metadata->data;
+ intel_dp_aux_write_content_luminance(connector, hdr_metadata);
+ }
}
static void
@@ -275,7 +362,7 @@ intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *conn_state,
struct intel_panel *panel = &connector->panel;
/* Nothing to do for AUX based backlight controls */
- if (panel->backlight.edp.intel.sdr_uses_aux)
+ if (panel->backlight.edp.intel_cap.sdr_uses_aux)
return;
/* Note we want the actual pwm_level to be 0, regardless of pwm_min */
@@ -287,6 +374,29 @@ static const char *dpcd_vs_pwm_str(bool aux)
return aux ? "DPCD" : "PWM";
}
+static void
+intel_dp_aux_write_panel_luminance_override(struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_panel *panel = &connector->panel;
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
+ int ret;
+ u8 buf[4] = {};
+
+ buf[0] = panel->backlight.min & 0xFF;
+ buf[1] = (panel->backlight.min & 0xFF00) >> 8;
+ buf[2] = panel->backlight.max & 0xFF;
+ buf[3] = (panel->backlight.max & 0xFF00) >> 8;
+
+ ret = drm_dp_dpcd_write(&intel_dp->aux,
+ INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE,
+ buf, sizeof(buf));
+ if (ret < 0)
+ drm_dbg_kms(&i915->drm,
+ "Panel Luminance DPCD reg write failed, err:-%d\n",
+ ret);
+}
+
static int
intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pipe)
{
@@ -298,9 +408,9 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDR backlight is controlled through %s\n",
connector->base.base.id, connector->base.name,
- dpcd_vs_pwm_str(panel->backlight.edp.intel.sdr_uses_aux));
+ dpcd_vs_pwm_str(panel->backlight.edp.intel_cap.sdr_uses_aux));
- if (!panel->backlight.edp.intel.sdr_uses_aux) {
+ if (!panel->backlight.edp.intel_cap.sdr_uses_aux) {
ret = panel->backlight.pwm_funcs->setup(connector, pipe);
if (ret < 0) {
drm_err(&i915->drm,
@@ -318,11 +428,12 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi
panel->backlight.min = 0;
}
+ intel_dp_aux_write_panel_luminance_override(connector);
+
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Using AUX HDR interface for backlight control (range %d..%d)\n",
connector->base.base.id, connector->base.name,
panel->backlight.min, panel->backlight.max);
-
panel->backlight.level = intel_dp_aux_hdr_get_backlight(connector, pipe);
panel->backlight.enabled = panel->backlight.level != 0;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h b/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h
index e642445364d2..4e109e81409b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h
@@ -23,12 +23,17 @@
#define _DPA_AUX_CH_CTL 0x64010
#define _DPB_AUX_CH_CTL 0x64110
-#define _XELPDP_USBC1_AUX_CH_CTL 0x16f210
-#define _XELPDP_USBC2_AUX_CH_CTL 0x16f410
#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, \
_DPB_AUX_CH_CTL)
#define VLV_DP_AUX_CH_CTL(aux_ch) _MMIO(VLV_DISPLAY_BASE + \
_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL))
+
+#define _PCH_DPB_AUX_CH_CTL 0xe4110
+#define _PCH_DPC_AUX_CH_CTL 0xe4210
+#define PCH_DP_AUX_CH_CTL(aux_ch) _MMIO_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_CTL, _PCH_DPC_AUX_CH_CTL)
+
+#define _XELPDP_USBC1_AUX_CH_CTL 0x16f210
+#define _XELPDP_USBC2_AUX_CH_CTL 0x16f410
#define _XELPDP_DP_AUX_CH_CTL(aux_ch) \
_MMIO(_PICK_EVEN_2RANGES(aux_ch, AUX_CH_USBC1, \
_DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL, \
@@ -72,12 +77,17 @@
#define _DPA_AUX_CH_DATA1 0x64014
#define _DPB_AUX_CH_DATA1 0x64114
-#define _XELPDP_USBC1_AUX_CH_DATA1 0x16f214
-#define _XELPDP_USBC2_AUX_CH_DATA1 0x16f414
#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, \
_DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
#define VLV_DP_AUX_CH_DATA(aux_ch, i) _MMIO(VLV_DISPLAY_BASE + _PORT(aux_ch, _DPA_AUX_CH_DATA1, \
_DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+
+#define _PCH_DPB_AUX_CH_DATA1 0xe4114
+#define _PCH_DPC_AUX_CH_DATA1 0xe4214
+#define PCH_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_DATA1, _PCH_DPC_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+
+#define _XELPDP_USBC1_AUX_CH_DATA1 0x16f214
+#define _XELPDP_USBC2_AUX_CH_DATA1 0x16f414
#define _XELPDP_DP_AUX_CH_DATA(aux_ch, i) \
_MMIO(_PICK_EVEN_2RANGES(aux_ch, AUX_CH_USBC1, \
_DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1, \
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 92b03073acdd..2edffe62f360 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -687,15 +687,16 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
bool *hdcp2_capable)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
- struct drm_dp_aux *aux = &connector->port->aux;
+ struct drm_dp_aux *aux;
u8 bcaps;
int ret;
*hdcp_capable = false;
*hdcp2_capable = false;
- if (!intel_encoder_is_mst(connector->encoder))
+ if (!connector->mst_port)
return -EINVAL;
+ aux = &connector->port->aux;
ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
if (ret)
drm_dbg_kms(&i915->drm,
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 947575140059..1bc4ef84ff3b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -25,6 +25,9 @@
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_link_training.h"
+#include "intel_encoder.h"
+#include "intel_hotplug.h"
+#include "intel_panel.h"
#define LT_MSG_PREFIX "[CONNECTOR:%d:%s][ENCODER:%d:%s][%s] "
#define LT_MSG_ARGS(_intel_dp, _dp_phy) (_intel_dp)->attached_connector->base.base.id, \
@@ -1091,28 +1094,129 @@ out:
return ret;
}
-static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
+static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
+ int link_rate,
+ u8 lane_count)
+{
+ /* FIXME figure out what we actually want here */
+ const struct drm_display_mode *fixed_mode =
+ intel_panel_preferred_fixed_mode(intel_dp->attached_connector);
+ int mode_rate, max_rate;
+
+ mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
+ max_rate = intel_dp_max_link_data_rate(intel_dp, link_rate, lane_count);
+ if (mode_rate > max_rate)
+ return false;
+
+ return true;
+}
+
+static int reduce_link_rate(struct intel_dp *intel_dp, int current_rate)
+{
+ int rate_index;
+ int new_rate;
+
+ if (intel_dp->link.force_rate)
+ return -1;
+
+ rate_index = intel_dp_rate_index(intel_dp->common_rates,
+ intel_dp->num_common_rates,
+ current_rate);
+
+ if (rate_index <= 0)
+ return -1;
+
+ new_rate = intel_dp_common_rate(intel_dp, rate_index - 1);
+
+ /* TODO: Make switching from UHBR to non-UHBR rates work. */
+ if (drm_dp_is_uhbr_rate(current_rate) != drm_dp_is_uhbr_rate(new_rate))
+ return -1;
+
+ return new_rate;
+}
+
+static int reduce_lane_count(struct intel_dp *intel_dp, int current_lane_count)
+{
+ if (intel_dp->link.force_lane_count)
+ return -1;
+
+ if (current_lane_count == 1)
+ return -1;
+
+ return current_lane_count >> 1;
+}
+
+static int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ int new_link_rate;
+ int new_lane_count;
+
+ if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
+ lt_dbg(intel_dp, DP_PHY_DPRX,
+ "Retrying Link training for eDP with max parameters\n");
+ intel_dp->use_max_params = true;
+ return 0;
+ }
+
+ new_lane_count = crtc_state->lane_count;
+ new_link_rate = reduce_link_rate(intel_dp, crtc_state->port_clock);
+ if (new_link_rate < 0) {
+ new_lane_count = reduce_lane_count(intel_dp, crtc_state->lane_count);
+ new_link_rate = intel_dp_max_common_rate(intel_dp);
+ }
+
+ if (new_lane_count < 0)
+ return -1;
+
+ if (intel_dp_is_edp(intel_dp) &&
+ !intel_dp_can_link_train_fallback_for_edp(intel_dp, new_link_rate, new_lane_count)) {
+ lt_dbg(intel_dp, DP_PHY_DPRX,
+ "Retrying Link training for eDP with same parameters\n");
+ return 0;
+ }
+
+ lt_dbg(intel_dp, DP_PHY_DPRX,
+ "Reducing link parameters from %dx%d to %dx%d\n",
+ crtc_state->lane_count, crtc_state->port_clock,
+ new_lane_count, new_link_rate);
+
+ intel_dp->link.max_rate = new_link_rate;
+ intel_dp->link.max_lane_count = new_lane_count;
+
+ return 0;
+}
+
+/* NOTE: @state is only valid for MST links and can be %NULL for SST. */
+static bool intel_dp_schedule_fallback_link_training(struct intel_atomic_state *state,
+ struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
- struct intel_connector *intel_connector = intel_dp->attached_connector;
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
if (!intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) {
lt_dbg(intel_dp, DP_PHY_DPRX, "Link Training failed on disconnected sink.\n");
- return;
+ return true;
}
if (intel_dp->hobl_active) {
lt_dbg(intel_dp, DP_PHY_DPRX,
"Link Training failed with HOBL active, not enabling it from now on\n");
intel_dp->hobl_failed = true;
- } else if (intel_dp_get_link_train_fallback_values(intel_dp,
- crtc_state->port_clock,
- crtc_state->lane_count)) {
- return;
+ } else if (intel_dp_get_link_train_fallback_values(intel_dp, crtc_state)) {
+ return false;
}
+ if (drm_WARN_ON(&i915->drm,
+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+ !state))
+ return false;
+
/* Schedule a Hotplug Uevent to userspace to start modeset */
- intel_dp_queue_modeset_retry_work(intel_connector);
+ intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
+
+ return true;
}
/* Perform the link training on all LTTPRs and the DPRX on a link. */
@@ -1359,6 +1463,7 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp,
/**
* intel_dp_start_link_train - start link training
+ * @state: Atomic state
* @intel_dp: DP struct
* @crtc_state: state for CRTC attached to the encoder
*
@@ -1366,11 +1471,16 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp,
* retraining with reduced link rate/lane parameters if the link training
* fails.
* After calling this function intel_dp_stop_link_train() must be called.
+ *
+ * NOTE: @state is only valid for MST links and can be %NULL for SST.
*/
-void intel_dp_start_link_train(struct intel_dp *intel_dp,
+void intel_dp_start_link_train(struct intel_atomic_state *state,
+ struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
bool passed;
/*
@@ -1379,6 +1489,11 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
*/
int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
+ if (drm_WARN_ON(&i915->drm,
+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+ !state))
+ return;
+
if (lttpr_count < 0)
/* Still continue with enabling the port and link training. */
lttpr_count = 0;
@@ -1390,6 +1505,17 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
else
passed = intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count);
+ if (intel_dp->link.force_train_failure) {
+ intel_dp->link.force_train_failure--;
+ lt_dbg(intel_dp, DP_PHY_DPRX, "Forcing link training failure\n");
+ } else if (passed) {
+ intel_dp->link.seq_train_failures = 0;
+ intel_encoder_link_check_queue_work(encoder, 2000);
+ return;
+ }
+
+ intel_dp->link.seq_train_failures++;
+
/*
* Ignore the link failure in CI
*
@@ -1402,13 +1528,25 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
* For test cases which rely on the link training or processing of HPDs
* ignore_long_hpd flag can unset from the testcase.
*/
- if (!passed && i915->display.hotplug.ignore_long_hpd) {
+ if (i915->display.hotplug.ignore_long_hpd) {
lt_dbg(intel_dp, DP_PHY_DPRX, "Ignore the link failure\n");
return;
}
+ if (intel_dp->link.seq_train_failures < 2) {
+ intel_encoder_link_check_queue_work(encoder, 0);
+ return;
+ }
+
+ if (intel_dp_schedule_fallback_link_training(state, intel_dp, crtc_state))
+ return;
+
+ intel_dp->link.retrain_disabled = true;
+
if (!passed)
- intel_dp_schedule_fallback_link_training(intel_dp, crtc_state);
+ lt_err(intel_dp, DP_PHY_DPRX, "Can't reduce link training parameters after failure\n");
+ else
+ lt_dbg(intel_dp, DP_PHY_DPRX, "Can't reduce link training parameters after forced failure\n");
}
void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
@@ -1430,3 +1568,381 @@ 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 drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int current_rate = -1;
+ int force_rate;
+ int err;
+ int i;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ if (intel_dp->link_trained)
+ current_rate = intel_dp->link_rate;
+ force_rate = intel_dp->link.force_rate;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ seq_printf(m, "%sauto%s",
+ force_rate == 0 ? "[" : "",
+ force_rate == 0 ? "]" : "");
+
+ for (i = 0; i < intel_dp->num_source_rates; i++)
+ seq_printf(m, " %s%d%s%s",
+ intel_dp->source_rates[i] == force_rate ? "[" : "",
+ intel_dp->source_rates[i],
+ intel_dp->source_rates[i] == current_rate ? "*" : "",
+ intel_dp->source_rates[i] == force_rate ? "]" : "");
+
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static int parse_link_rate(struct intel_dp *intel_dp, const char __user *ubuf, size_t len)
+{
+ char *kbuf;
+ const char *p;
+ int rate;
+ int ret = 0;
+
+ kbuf = memdup_user_nul(ubuf, len);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
+
+ p = strim(kbuf);
+
+ if (!strcmp(p, "auto")) {
+ rate = 0;
+ } else {
+ ret = kstrtoint(p, 0, &rate);
+ if (ret < 0)
+ goto out_free;
+
+ if (intel_dp_rate_index(intel_dp->source_rates,
+ intel_dp->num_source_rates,
+ rate) < 0)
+ ret = -EINVAL;
+ }
+
+out_free:
+ kfree(kbuf);
+
+ return ret < 0 ? ret : rate;
+}
+
+static ssize_t i915_dp_force_link_rate_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 = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int rate;
+ int err;
+
+ rate = parse_link_rate(intel_dp, ubuf, len);
+ if (rate < 0)
+ return rate;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp_reset_link_params(intel_dp);
+ intel_dp->link.force_rate = rate;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ *offp += len;
+
+ return len;
+}
+DEFINE_SHOW_STORE_ATTRIBUTE(i915_dp_force_link_rate);
+
+static int i915_dp_force_lane_count_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int current_lane_count = -1;
+ int force_lane_count;
+ int err;
+ int i;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ if (intel_dp->link_trained)
+ current_lane_count = intel_dp->lane_count;
+ force_lane_count = intel_dp->link.force_lane_count;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ seq_printf(m, "%sauto%s",
+ force_lane_count == 0 ? "[" : "",
+ force_lane_count == 0 ? "]" : "");
+
+ for (i = 1; i <= 4; i <<= 1)
+ seq_printf(m, " %s%d%s%s",
+ i == force_lane_count ? "[" : "",
+ i,
+ i == current_lane_count ? "*" : "",
+ i == force_lane_count ? "]" : "");
+
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static int parse_lane_count(const char __user *ubuf, size_t len)
+{
+ char *kbuf;
+ const char *p;
+ int lane_count;
+ int ret = 0;
+
+ kbuf = memdup_user_nul(ubuf, len);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
+
+ p = strim(kbuf);
+
+ if (!strcmp(p, "auto")) {
+ lane_count = 0;
+ } else {
+ ret = kstrtoint(p, 0, &lane_count);
+ if (ret < 0)
+ goto out_free;
+
+ switch (lane_count) {
+ case 1:
+ case 2:
+ case 4:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ }
+
+out_free:
+ kfree(kbuf);
+
+ return ret < 0 ? ret : lane_count;
+}
+
+static ssize_t i915_dp_force_lane_count_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 = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int lane_count;
+ int err;
+
+ lane_count = parse_lane_count(ubuf, len);
+ if (lane_count < 0)
+ return lane_count;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp_reset_link_params(intel_dp);
+ intel_dp->link.force_lane_count = lane_count;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ *offp += len;
+
+ return len;
+}
+DEFINE_SHOW_STORE_ATTRIBUTE(i915_dp_force_lane_count);
+
+static int i915_dp_max_link_rate_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.max_rate;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_max_link_rate_fops, i915_dp_max_link_rate_show, NULL, "%llu\n");
+
+static int i915_dp_max_lane_count_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.max_lane_count;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_max_lane_count_fops, i915_dp_max_lane_count_show, NULL, "%llu\n");
+
+static int i915_dp_force_link_training_failure_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.force_train_failure;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+
+static int i915_dp_force_link_training_failure_write(void *data, u64 val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ if (val > 2)
+ return -EINVAL;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp->link.force_train_failure = val;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_force_link_training_failure_fops,
+ i915_dp_force_link_training_failure_show,
+ i915_dp_force_link_training_failure_write, "%llu\n");
+
+static int i915_dp_force_link_retrain_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.force_retrain;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+
+static int i915_dp_force_link_retrain_write(void *data, u64 val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp->link.force_retrain = val;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ intel_hpd_trigger_irq(dp_to_dig_port(intel_dp));
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_force_link_retrain_fops,
+ i915_dp_force_link_retrain_show,
+ i915_dp_force_link_retrain_write, "%llu\n");
+
+static int i915_dp_link_retrain_disabled_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ seq_printf(m, "%s\n", str_yes_no(intel_dp->link.retrain_disabled));
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(i915_dp_link_retrain_disabled);
+
+void intel_dp_link_training_debugfs_add(struct intel_connector *connector)
+{
+ struct dentry *root = connector->base.debugfs_entry;
+
+ if (connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort &&
+ connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
+ return;
+
+ debugfs_create_file("i915_dp_force_link_rate", 0644, root,
+ connector, &i915_dp_force_link_rate_fops);
+
+ debugfs_create_file("i915_dp_force_lane_count", 0644, root,
+ connector, &i915_dp_force_lane_count_fops);
+
+ debugfs_create_file("i915_dp_max_link_rate", 0444, root,
+ connector, &i915_dp_max_link_rate_fops);
+
+ debugfs_create_file("i915_dp_max_lane_count", 0444, root,
+ connector, &i915_dp_max_lane_count_fops);
+
+ debugfs_create_file("i915_dp_force_link_training_failure", 0644, root,
+ connector, &i915_dp_force_link_training_failure_fops);
+
+ debugfs_create_file("i915_dp_force_link_retrain", 0644, root,
+ connector, &i915_dp_force_link_retrain_fops);
+
+ debugfs_create_file("i915_dp_link_retrain_disabled", 0444, root,
+ connector, &i915_dp_link_retrain_disabled_fops);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 19836a8a4f90..42e7fc6cb171 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -8,6 +8,8 @@
#include <drm/display/drm_dp_helper.h>
+struct intel_atomic_state;
+struct intel_connector;
struct intel_crtc_state;
struct intel_dp;
@@ -25,7 +27,8 @@ void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
enum drm_dp_phy dp_phy);
-void intel_dp_start_link_train(struct intel_dp *intel_dp,
+void intel_dp_start_link_train(struct intel_atomic_state *state,
+ struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
@@ -42,4 +45,7 @@ static inline u8 intel_dp_training_pattern_symbol(u8 pattern)
void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
+
+void intel_dp_link_training_debugfs_add(struct intel_connector *connector);
+
#endif /* __INTEL_DP_LINK_TRAINING_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 715d2f59f565..27ce5c3f5951 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -105,7 +105,7 @@ static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state,
dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
adjusted_mode->clock,
adjusted_mode->hdisplay,
- crtc_state->bigjoiner_pipes);
+ crtc_state->joiner_pipes);
}
overhead = drm_dp_bw_overhead(crtc_state->lane_count,
@@ -207,6 +207,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
int remote_bw_overhead;
int link_bpp_x16;
int remote_tu;
+ fixed20_12 pbn;
drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp);
@@ -237,11 +238,29 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
* crtc_state->dp_m_n.tu), provided that the driver doesn't
* enable SSC on the corresponding link.
*/
- crtc_state->pbn = intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock,
- link_bpp_x16,
- remote_bw_overhead);
+ pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock,
+ link_bpp_x16,
+ remote_bw_overhead));
+ remote_tu = DIV_ROUND_UP(pbn.full, mst_state->pbn_div.full);
- remote_tu = DIV_ROUND_UP(dfixed_const(crtc_state->pbn), mst_state->pbn_div.full);
+ /*
+ * Aligning the TUs ensures that symbols consisting of multiple
+ * (4) symbol cycles don't get split between two consecutive
+ * MTPs, as required by Bspec.
+ * TODO: remove the alignment restriction for 128b/132b links
+ * on some platforms, where Bspec allows this.
+ */
+ remote_tu = ALIGN(remote_tu, 4 / crtc_state->lane_count);
+
+ /*
+ * Also align PBNs accordingly, since MST core will derive its
+ * own copy of TU from the PBN in drm_dp_atomic_find_time_slots().
+ * The above comment about the difference between the PBN
+ * allocated for the whole path and the TUs allocated for the
+ * first branch device's link also applies here.
+ */
+ pbn.full = remote_tu * mst_state->pbn_div.full;
+ crtc_state->pbn = dfixed_trunc(pbn);
drm_WARN_ON(&i915->drm, remote_tu < crtc_state->dp_m_n.tu);
crtc_state->dp_m_n.tu = remote_tu;
@@ -349,6 +368,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder,
if (max_bpp > sink_max_bpp)
max_bpp = sink_max_bpp;
+ crtc_state->pipe_bpp = max_bpp;
+
max_compressed_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector,
crtc_state,
max_bpp / 3);
@@ -400,18 +421,6 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
return 0;
}
-static bool
-intel_dp_mst_dsc_source_support(const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-
- /*
- * FIXME: Enabling DSC on ICL results in blank screen and FIFO pipe /
- * transcoder underruns, re-enable DSC after fixing this issue.
- */
- return DISPLAY_VER(i915) >= 12 && intel_dsc_source_support(crtc_state);
-}
-
static int mode_hblank_period_ns(const struct drm_display_mode *mode)
{
return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(mode->htotal - mode->hdisplay,
@@ -456,7 +465,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne
return true;
if (!dsc) {
- if (intel_dp_mst_dsc_source_support(crtc_state)) {
+ if (intel_dp_supports_dsc(connector, crtc_state)) {
drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s][CONNECTOR:%d:%s] DSC needed by hblank expansion quirk\n",
crtc->base.base.id, crtc->base.name,
@@ -567,16 +576,16 @@ 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_bigjoiner(intel_dp, connector,
- adjusted_mode->crtc_hdisplay,
- adjusted_mode->crtc_clock))
- pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
+ 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);
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->bigjoiner_pipes);
+ joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, pipe_config->joiner_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_mst_compute_config_limits(intel_dp,
@@ -602,7 +611,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
str_yes_no(ret), str_yes_no(joiner_needs_dsc),
str_yes_no(intel_dp->force_dsc_en));
- if (!intel_dp_mst_dsc_source_support(pipe_config))
+ if (!intel_dp_supports_dsc(connector, pipe_config))
return -EINVAL;
if (!intel_dp_mst_compute_config_limits(intel_dp,
@@ -962,6 +971,9 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
drm_dbg_kms(&i915->drm, "active links %d\n",
intel_dp->active_mst_links);
+ if (intel_dp->active_mst_links == 1)
+ intel_dp->link_trained = false;
+
intel_hdcp_disable(intel_mst->connector);
intel_dp_sink_disable_decompression(state, connector, old_crtc_state);
@@ -1009,7 +1021,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
clear_act_sent(encoder, old_crtc_state);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, old_crtc_state->cpu_transcoder),
TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0);
wait_for_act_sent(encoder, old_crtc_state);
@@ -1230,7 +1243,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
clear_act_sent(encoder, pipe_config);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(trans), 0,
+ intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, trans), 0,
TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
drm_dbg_kms(&dev_priv->drm, "active links %d\n",
@@ -1375,7 +1388,7 @@ 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, bigjoiner = false;
+ bool dsc = false, joiner = false;
u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
int target_clock = mode->clock;
@@ -1418,9 +1431,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_bigjoiner(intel_dp, intel_connector,
- mode->hdisplay, target_clock)) {
- bigjoiner = true;
+ if (intel_dp_need_joiner(intel_dp, intel_connector,
+ mode->hdisplay, target_clock)) {
+ joiner = true;
max_dotclk *= 2;
}
@@ -1434,8 +1447,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
return 0;
}
- if (HAS_DSC_MST(dev_priv) &&
- drm_dp_sink_supports_dsc(intel_connector->dp.dsc_dpcd)) {
+ if (intel_dp_has_dsc(intel_connector)) {
/*
* TBD pass the connector BPC,
* for now U8_MAX so that max BPC on that platform would be picked
@@ -1449,20 +1461,20 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
max_lanes,
target_clock,
mode->hdisplay,
- bigjoiner,
+ joiner,
INTEL_OUTPUT_FORMAT_RGB,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_connector,
target_clock,
mode->hdisplay,
- bigjoiner);
+ joiner);
}
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
- if (intel_dp_joiner_needs_dsc(dev_priv, bigjoiner) && !dsc) {
+ if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc) {
*status = MODE_CLOCK_HIGH;
return 0;
}
@@ -1472,7 +1484,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
return 0;
}
- *status = intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
+ *status = intel_mode_valid_max_plane_size(dev_priv, mode, joiner);
return 0;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index a981f45facb3..d67d5e2fd570 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -398,12 +398,13 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A)
tmp = dev_priv->display.state.chv_dpll_md[crtc->pipe];
else
- tmp = intel_de_read(dev_priv, DPLL_MD(crtc->pipe));
+ tmp = intel_de_read(dev_priv,
+ DPLL_MD(dev_priv, crtc->pipe));
hw_state->dpll_md = tmp;
}
- hw_state->dpll = intel_de_read(dev_priv, DPLL(crtc->pipe));
+ hw_state->dpll = intel_de_read(dev_priv, DPLL(dev_priv, crtc->pipe));
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
hw_state->fp0 = intel_de_read(dev_priv, FP0(crtc->pipe));
@@ -1842,28 +1843,30 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state)
* 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(pipe), hw_state->dpll & ~DPLL_VGA_MODE_DIS);
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
+ hw_state->dpll & ~DPLL_VGA_MODE_DIS);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
/* Wait for the clocks to stabilize. */
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150);
if (DISPLAY_VER(dev_priv) >= 4) {
- intel_de_write(dev_priv, DPLL_MD(pipe), hw_state->dpll_md);
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe),
+ hw_state->dpll_md);
} else {
/* The pixel multiplier can only be updated once the
* DPLL is enabled and the clocks are stable.
*
* So write it again.
*/
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
}
/* We do this three times for luck */
for (i = 0; i < 3; i++) {
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150); /* wait for warmup */
}
}
@@ -1991,11 +1994,11 @@ static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state)
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
enum pipe pipe = crtc->pipe;
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150);
- if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
+ if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1))
drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
}
@@ -2012,7 +2015,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
assert_pps_unlocked(dev_priv, pipe);
/* Enable Refclk */
- intel_de_write(dev_priv, DPLL(pipe),
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
hw_state->dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
if (hw_state->dpll & DPLL_VCO_ENABLE) {
@@ -2020,8 +2023,8 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
_vlv_enable_pll(crtc_state);
}
- intel_de_write(dev_priv, DPLL_MD(pipe), hw_state->dpll_md);
- intel_de_posting_read(dev_priv, DPLL_MD(pipe));
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), hw_state->dpll_md);
+ intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe));
}
static void chv_prepare_pll(const struct intel_crtc_state *crtc_state)
@@ -2138,10 +2141,10 @@ static void _chv_enable_pll(const struct intel_crtc_state *crtc_state)
udelay(1);
/* Enable PLL */
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
/* Check PLL is locked */
- if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
+ if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1))
drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
}
@@ -2158,7 +2161,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
assert_pps_unlocked(dev_priv, pipe);
/* Enable Refclk and SSC */
- intel_de_write(dev_priv, DPLL(pipe),
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
hw_state->dpll & ~DPLL_VCO_ENABLE);
if (hw_state->dpll & DPLL_VCO_ENABLE) {
@@ -2174,7 +2177,8 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
* the value from DPLLBMD to either pipe B or C.
*/
intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
- intel_de_write(dev_priv, DPLL_MD(PIPE_B), hw_state->dpll_md);
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, PIPE_B),
+ hw_state->dpll_md);
intel_de_write(dev_priv, CBR4_VLV, 0);
dev_priv->display.state.chv_dpll_md[pipe] = hw_state->dpll_md;
@@ -2183,11 +2187,12 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
* We should always have it disabled.
*/
drm_WARN_ON(&dev_priv->drm,
- (intel_de_read(dev_priv, DPLL(PIPE_B)) &
+ (intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) &
DPLL_VGA_MODE_DIS) == 0);
} else {
- intel_de_write(dev_priv, DPLL_MD(pipe), hw_state->dpll_md);
- intel_de_posting_read(dev_priv, DPLL_MD(pipe));
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe),
+ hw_state->dpll_md);
+ intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe));
}
}
@@ -2241,8 +2246,8 @@ void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
- intel_de_write(dev_priv, DPLL(pipe), val);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
}
void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
@@ -2259,8 +2264,8 @@ void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
- intel_de_write(dev_priv, DPLL(pipe), val);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
vlv_dpio_get(dev_priv);
@@ -2285,8 +2290,8 @@ void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
/* Make sure the pipe isn't still relying on us */
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
- intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
}
@@ -2312,7 +2317,7 @@ static void assert_pll(struct drm_i915_private *dev_priv,
{
bool cur_state;
- cur_state = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE;
+ cur_state = intel_de_read(dev_priv, DPLL(dev_priv, pipe)) & DPLL_VCO_ENABLE;
I915_STATE_WARN(dev_priv, cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index f09e513ce05b..6af325b8e27d 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -264,6 +264,8 @@ struct intel_cx0pll_state {
struct intel_c20pll_state c20;
};
bool ssc_enabled;
+ bool use_c10;
+ bool tbt_mode;
};
struct intel_dpll_hw_state {
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index b29bceff73f2..73a1918e2537 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -121,7 +121,8 @@ static void dpt_cleanup(struct i915_address_space *vm)
i915_gem_object_put(dpt->obj);
}
-struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
+struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
+ unsigned int alignment)
{
struct drm_i915_private *i915 = vm->i915;
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
@@ -143,8 +144,8 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
if (err)
continue;
- vma = i915_gem_object_ggtt_pin_ww(dpt->obj, &ww, NULL, 0, 4096,
- pin_flags);
+ vma = i915_gem_object_ggtt_pin_ww(dpt->obj, &ww, NULL, 0,
+ alignment, pin_flags);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
continue;
@@ -172,7 +173,7 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
return err ? ERR_PTR(err) : vma;
}
-void intel_dpt_unpin(struct i915_address_space *vm)
+void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm)
{
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h
index e18a9f767b11..ff18a525bfbe 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.h
+++ b/drivers/gpu/drm/i915/display/intel_dpt.h
@@ -13,8 +13,9 @@ struct i915_vma;
struct intel_framebuffer;
void intel_dpt_destroy(struct i915_address_space *vm);
-struct i915_vma *intel_dpt_pin(struct i915_address_space *vm);
-void intel_dpt_unpin(struct i915_address_space *vm);
+struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
+ unsigned int alignment);
+void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm);
void intel_dpt_suspend(struct drm_i915_private *i915);
void intel_dpt_resume(struct drm_i915_private *i915);
struct i915_address_space *
diff --git a/drivers/gpu/drm/i915/display/intel_dpt_common.c b/drivers/gpu/drm/i915/display/intel_dpt_common.c
index cdba47165c04..573f72068899 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt_common.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt_common.c
@@ -7,6 +7,7 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dpt_common.h"
+#include "skl_universal_plane_regs.h"
void intel_dpt_configure(struct intel_crtc *crtc)
{
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 597f8bd6aa1a..3ca29afa5422 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -85,7 +85,7 @@ intel_drrs_set_refresh_rate_pipeconf(struct intel_crtc *crtc,
else
bit = TRANSCONF_REFRESH_RATE_ALT_ILK;
- intel_de_rmw(dev_priv, TRANSCONF(cpu_transcoder),
+ intel_de_rmw(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
bit, refresh_rate == DRRS_REFRESH_RATE_LOW ? bit : 0);
}
@@ -135,7 +135,7 @@ static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *c
frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
- crtc_state->bigjoiner_pipes)
+ crtc_state->joiner_pipes)
frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
return frontbuffer_bits;
@@ -157,7 +157,7 @@ void intel_drrs_activate(const struct intel_crtc_state *crtc_state)
if (!crtc_state->hw.active)
return;
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
+ if (intel_crtc_is_joiner_secondary(crtc_state))
return;
mutex_lock(&crtc->drrs.mutex);
@@ -189,7 +189,7 @@ void intel_drrs_deactivate(const struct intel_crtc_state *old_crtc_state)
if (!old_crtc_state->hw.active)
return;
- if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+ if (intel_crtc_is_joiner_secondary(old_crtc_state))
return;
mutex_lock(&crtc->drrs.mutex);
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index 4baaa92ceaec..2ab3765f6c06 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -6,7 +6,6 @@
#include "i915_drv.h"
#include "i915_irq.h"
-#include "i915_reg.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -19,16 +18,8 @@
#define CACHELINE_BYTES 64
-enum dsb_id {
- INVALID_DSB = -1,
- DSB1,
- DSB2,
- DSB3,
- MAX_DSB_PER_PIPE
-};
-
struct intel_dsb {
- enum dsb_id id;
+ enum intel_dsb_id id;
struct intel_dsb_buffer dsb_buf;
struct intel_crtc *crtc;
@@ -94,10 +85,10 @@ struct intel_dsb {
static bool assert_dsb_has_room(struct intel_dsb *dsb)
{
struct intel_crtc *crtc = dsb->crtc;
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
/* each instruction is 2 dwords */
- return !drm_WARN(&i915->drm, dsb->free_pos > dsb->size - 2,
+ return !drm_WARN(display->drm, dsb->free_pos > dsb->size - 2,
"[CRTC:%d:%s] DSB %d buffer overflow\n",
crtc->base.base.id, crtc->base.name, dsb->id);
}
@@ -105,25 +96,25 @@ static bool assert_dsb_has_room(struct intel_dsb *dsb)
static void intel_dsb_dump(struct intel_dsb *dsb)
{
struct intel_crtc *crtc = dsb->crtc;
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
int i;
- drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] DSB %d commands {\n",
+ drm_dbg_kms(display->drm, "[CRTC:%d:%s] DSB %d commands {\n",
crtc->base.base.id, crtc->base.name, dsb->id);
for (i = 0; i < ALIGN(dsb->free_pos, 64 / 4); i += 4)
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
" 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i * 4,
intel_dsb_buffer_read(&dsb->dsb_buf, i),
intel_dsb_buffer_read(&dsb->dsb_buf, i + 1),
intel_dsb_buffer_read(&dsb->dsb_buf, i + 2),
intel_dsb_buffer_read(&dsb->dsb_buf, i + 3));
- drm_dbg_kms(&i915->drm, "}\n");
+ drm_dbg_kms(display->drm, "}\n");
}
-static bool is_dsb_busy(struct drm_i915_private *i915, enum pipe pipe,
- enum dsb_id id)
+static bool is_dsb_busy(struct intel_display *display, enum pipe pipe,
+ enum intel_dsb_id dsb_id)
{
- return intel_de_read_fw(i915, DSB_CTRL(pipe, id)) & DSB_STATUS_BUSY;
+ return intel_de_read_fw(display, DSB_CTRL(pipe, dsb_id)) & DSB_STATUS_BUSY;
}
static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)
@@ -328,14 +319,10 @@ static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state)
unsigned int latency = skl_watermark_max_latency(i915, 0);
int vblank_start;
- if (crtc_state->vrr.enable) {
+ if (crtc_state->vrr.enable)
vblank_start = intel_vrr_vmin_vblank_start(crtc_state);
- } else {
- vblank_start = adjusted_mode->crtc_vblank_start;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- vblank_start = DIV_ROUND_UP(vblank_start, 2);
- }
+ else
+ vblank_start = intel_mode_vblank_start(adjusted_mode);
return max(0, vblank_start - intel_usecs_to_scanlines(adjusted_mode, latency));
}
@@ -356,27 +343,27 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
int dewake_scanline)
{
struct intel_crtc *crtc = dsb->crtc;
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
enum pipe pipe = crtc->pipe;
u32 tail;
tail = dsb->free_pos * 4;
- if (drm_WARN_ON(&dev_priv->drm, !IS_ALIGNED(tail, CACHELINE_BYTES)))
+ if (drm_WARN_ON(display->drm, !IS_ALIGNED(tail, CACHELINE_BYTES)))
return;
- if (is_dsb_busy(dev_priv, pipe, dsb->id)) {
- drm_err(&dev_priv->drm, "[CRTC:%d:%s] DSB %d is busy\n",
+ if (is_dsb_busy(display, pipe, dsb->id)) {
+ drm_err(display->drm, "[CRTC:%d:%s] DSB %d is busy\n",
crtc->base.base.id, crtc->base.name, dsb->id);
return;
}
- intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id),
ctrl | DSB_ENABLE);
- intel_de_write_fw(dev_priv, DSB_CHICKEN(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_CHICKEN(pipe, dsb->id),
dsb_chicken(crtc));
- intel_de_write_fw(dev_priv, DSB_HEAD(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_HEAD(pipe, dsb->id),
intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));
if (dewake_scanline >= 0) {
@@ -384,7 +371,7 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
hw_dewake_scanline = intel_crtc_scanline_to_hw(crtc, dewake_scanline);
- intel_de_write_fw(dev_priv, DSB_PMCTRL(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_PMCTRL(pipe, dsb->id),
DSB_ENABLE_DEWAKE |
DSB_SCANLINE_FOR_DEWAKE(hw_dewake_scanline));
@@ -393,12 +380,12 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
* or close to racing past the target scanline.
*/
diff = dewake_scanline - intel_get_crtc_scanline(crtc);
- intel_de_write_fw(dev_priv, DSB_PMCTRL_2(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_PMCTRL_2(pipe, dsb->id),
(diff >= 0 && diff < 5 ? DSB_FORCE_DEWAKE : 0) |
DSB_BLOCK_DEWAKE_EXTENSION);
}
- intel_de_write_fw(dev_priv, DSB_TAIL(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_TAIL(pipe, dsb->id),
intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf) + tail);
}
@@ -420,21 +407,21 @@ void intel_dsb_commit(struct intel_dsb *dsb,
void intel_dsb_wait(struct intel_dsb *dsb)
{
struct intel_crtc *crtc = dsb->crtc;
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc->base.dev);
enum pipe pipe = crtc->pipe;
- if (wait_for(!is_dsb_busy(dev_priv, pipe, dsb->id), 1)) {
+ if (wait_for(!is_dsb_busy(display, pipe, dsb->id), 1)) {
u32 offset = intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf);
- intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
+ intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id),
DSB_ENABLE | DSB_HALT);
- drm_err(&dev_priv->drm,
+ drm_err(display->drm,
"[CRTC:%d:%s] DSB %d timed out waiting for idle (current head=0x%x, head=0x%x, tail=0x%x)\n",
crtc->base.base.id, crtc->base.name, dsb->id,
- intel_de_read_fw(dev_priv, DSB_CURRENT_HEAD(pipe, dsb->id)) - offset,
- intel_de_read_fw(dev_priv, DSB_HEAD(pipe, dsb->id)) - offset,
- intel_de_read_fw(dev_priv, DSB_TAIL(pipe, dsb->id)) - offset);
+ intel_de_read_fw(display, DSB_CURRENT_HEAD(pipe, dsb->id)) - offset,
+ intel_de_read_fw(display, DSB_HEAD(pipe, dsb->id)) - offset,
+ intel_de_read_fw(display, DSB_TAIL(pipe, dsb->id)) - offset);
intel_dsb_dump(dsb);
}
@@ -442,12 +429,14 @@ void intel_dsb_wait(struct intel_dsb *dsb)
/* Attempt to reset it */
dsb->free_pos = 0;
dsb->ins_start_offset = 0;
- intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id), 0);
+ intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id), 0);
}
/**
* intel_dsb_prepare() - Allocate, pin and map the DSB command buffer.
- * @crtc_state: the CRTC state
+ * @state: the atomic state
+ * @crtc: the CRTC
+ * @dsb_id: the DSB engine to use
* @max_cmds: number of commands we need to fit into command buffer
*
* This function prepare the command buffer which is used to store dsb
@@ -456,11 +445,14 @@ void intel_dsb_wait(struct intel_dsb *dsb)
* Returns:
* DSB context, NULL on failure
*/
-struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
+struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ enum intel_dsb_id dsb_id,
unsigned int max_cmds)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
intel_wakeref_t wakeref;
struct intel_dsb *dsb;
unsigned int size;
@@ -468,6 +460,9 @@ struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
if (!HAS_DSB(i915))
return NULL;
+ if (!i915->display.params.enable_dsb)
+ return NULL;
+
/* TODO: DSB is broken in Xe KMD, so disabling it until fixed */
if (!IS_ENABLED(I915))
return NULL;
@@ -486,7 +481,7 @@ struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
- dsb->id = DSB1;
+ dsb->id = dsb_id;
dsb->crtc = crtc;
dsb->size = size / 4; /* in dwords */
dsb->free_pos = 0;
@@ -501,7 +496,7 @@ out_put_rpm:
out:
drm_info_once(&i915->drm,
"[CRTC:%d:%s] DSB %d queue setup failed, will fallback to MMIO for display HW programming\n",
- crtc->base.base.id, crtc->base.name, DSB1);
+ crtc->base.base.id, crtc->base.name, dsb_id);
return NULL;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h
index 16d80f434356..bb42749f2ea4 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.h
+++ b/drivers/gpu/drm/i915/display/intel_dsb.h
@@ -10,11 +10,22 @@
#include "i915_reg_defs.h"
+struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_dsb;
-struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
+enum intel_dsb_id {
+ INTEL_DSB_0,
+ INTEL_DSB_1,
+ INTEL_DSB_2,
+
+ I915_MAX_DSBS,
+};
+
+struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ enum intel_dsb_id dsb_id,
unsigned int max_cmds);
void intel_dsb_finish(struct intel_dsb *dsb);
void intel_dsb_cleanup(struct intel_dsb *dsb);
diff --git a/drivers/gpu/drm/i915/display/intel_dsb_regs.h b/drivers/gpu/drm/i915/display/intel_dsb_regs.h
index 210e2665441d..cb6e0e5624a6 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_dsb_regs.h
@@ -45,18 +45,18 @@
#define DSB_TLBTRANS_SM_STATE_MASK REG_GENMASK(21, 20)
#define DSB_SAFE_WINDOW REG_BIT(19)
#define DSB_POINTERS_SM_STATE_MASK REG_GENMASK(18, 17)
-#define DSB_BUSY_ON_DELAYED_VBLANK REG_BIT(16)
+#define DSB_BUSY_DURING_DELAYED_VBLANK REG_BIT(16)
#define DSB_MMIO_ARB_SM_STATE_MASK REG_GENMASK(15, 13)
#define DSB_MMIO_INST_SM_STATE_MASK REG_GENMASK(11, 7)
#define DSB_RESET_SM_STATE_MASK REG_GENMASK(5, 4)
#define DSB_RUN_SM_STATE_MASK REG_GENMASK(2, 0)
#define DSB_INTERRUPT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x28)
-#define DSB_ATS_FAULT_INT_EN REG_BIT(20)
+#define DSB_ATS_FAULT_INT_EN REG_BIT(20) /* mtl+ */
#define DSB_GTT_FAULT_INT_EN REG_BIT(19)
#define DSB_RSPTIMEOUT_INT_EN REG_BIT(18)
#define DSB_POLL_ERR_INT_EN REG_BIT(17)
#define DSB_PROG_INT_EN REG_BIT(16)
-#define DSB_ATS_FAULT_INT_STATUS REG_BIT(4)
+#define DSB_ATS_FAULT_INT_STATUS REG_BIT(4) /* mtl+ */
#define DSB_GTT_FAULT_INT_STATUS REG_BIT(3)
#define DSB_RSPTIMEOUT_INT_STATUS REG_BIT(2)
#define DSB_POLL_ERR_INT_STATUS REG_BIT(1)
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index a5d7fc8418c9..072ef1d62bda 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -353,14 +353,14 @@ static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
case MIPI_AVDD_EN_2:
index = gpio == MIPI_AVDD_EN_1 ? 0 : 1;
- intel_de_rmw(dev_priv, PP_CONTROL(index), PANEL_POWER_ON,
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, index), PANEL_POWER_ON,
value ? PANEL_POWER_ON : 0);
break;
case MIPI_BKLT_EN_1:
case MIPI_BKLT_EN_2:
index = gpio == MIPI_BKLT_EN_1 ? 0 : 1;
- intel_de_rmw(dev_priv, PP_CONTROL(index), EDP_BLC_ENABLE,
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, index), EDP_BLC_ENABLE,
value ? EDP_BLC_ENABLE : 0);
break;
case MIPI_AVEE_EN_1:
@@ -751,7 +751,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
struct mipi_pps_data *pps = connector->panel.vbt.dsi.pps;
- struct drm_display_mode *mode = connector->panel.vbt.lfp_lvds_vbt_mode;
+ struct drm_display_mode *mode = connector->panel.vbt.lfp_vbt_mode;
u16 burst_mode_ratio;
enum port port;
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 1840f5b59229..091824334f26 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -456,13 +456,14 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv,
* the device.
*/
for_each_pipe(dev_priv, pipe)
- dpll[pipe] = intel_de_rmw(dev_priv, DPLL(pipe), 0, DPLL_DVO_2X_MODE);
+ dpll[pipe] = intel_de_rmw(dev_priv, DPLL(dev_priv, pipe), 0,
+ DPLL_DVO_2X_MODE);
ret = dvo->dev_ops->init(&intel_dvo->dev, i2c);
/* restore the DVO 2x clock state to original */
for_each_pipe(dev_priv, pipe) {
- intel_de_write(dev_priv, DPLL(pipe), dpll[pipe]);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll[pipe]);
}
intel_gmbus_force_bit(i2c, false);
diff --git a/drivers/gpu/drm/i915/display/intel_encoder.c b/drivers/gpu/drm/i915/display/intel_encoder.c
new file mode 100644
index 000000000000..21d638535497
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_encoder.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <linux/workqueue.h>
+
+#include "i915_drv.h"
+
+#include "intel_display_types.h"
+#include "intel_encoder.h"
+
+static void intel_encoder_link_check_work_fn(struct work_struct *work)
+{
+ struct intel_encoder *encoder =
+ container_of(work, typeof(*encoder), link_check_work.work);
+
+ encoder->link_check(encoder);
+}
+
+void intel_encoder_link_check_init(struct intel_encoder *encoder,
+ void (*callback)(struct intel_encoder *encoder))
+{
+ INIT_DELAYED_WORK(&encoder->link_check_work, intel_encoder_link_check_work_fn);
+ encoder->link_check = callback;
+}
+
+void intel_encoder_link_check_flush_work(struct intel_encoder *encoder)
+{
+ cancel_delayed_work_sync(&encoder->link_check_work);
+}
+
+void intel_encoder_link_check_queue_work(struct intel_encoder *encoder, int delay_ms)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ mod_delayed_work(i915->unordered_wq,
+ &encoder->link_check_work, msecs_to_jiffies(delay_ms));
+}
+
+void intel_encoder_suspend_all(struct intel_display *display)
+{
+ struct intel_encoder *encoder;
+
+ if (!HAS_DISPLAY(display))
+ return;
+
+ /*
+ * TODO: check and remove holding the modeset locks if none of
+ * the encoders depends on this.
+ */
+ drm_modeset_lock_all(display->drm);
+ for_each_intel_encoder(display->drm, encoder)
+ if (encoder->suspend)
+ encoder->suspend(encoder);
+ drm_modeset_unlock_all(display->drm);
+
+ for_each_intel_encoder(display->drm, encoder)
+ if (encoder->suspend_complete)
+ encoder->suspend_complete(encoder);
+}
+
+void intel_encoder_shutdown_all(struct intel_display *display)
+{
+ struct intel_encoder *encoder;
+
+ if (!HAS_DISPLAY(display))
+ return;
+
+ /*
+ * TODO: check and remove holding the modeset locks if none of
+ * the encoders depends on this.
+ */
+ drm_modeset_lock_all(display->drm);
+ for_each_intel_encoder(display->drm, encoder)
+ if (encoder->shutdown)
+ encoder->shutdown(encoder);
+ drm_modeset_unlock_all(display->drm);
+
+ for_each_intel_encoder(display->drm, encoder)
+ if (encoder->shutdown_complete)
+ encoder->shutdown_complete(encoder);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_encoder.h b/drivers/gpu/drm/i915/display/intel_encoder.h
new file mode 100644
index 000000000000..3fa5589f0b1c
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_encoder.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_ENCODER_H__
+#define __INTEL_ENCODER_H__
+
+struct intel_display;
+struct intel_encoder;
+
+void intel_encoder_link_check_init(struct intel_encoder *encoder,
+ void (*callback)(struct intel_encoder *encoder));
+void intel_encoder_link_check_queue_work(struct intel_encoder *encoder, int delay_ms);
+void intel_encoder_link_check_flush_work(struct intel_encoder *encoder);
+
+void intel_encoder_suspend_all(struct intel_display *display);
+void intel_encoder_shutdown_all(struct intel_display *display);
+
+#endif /* __INTEL_ENCODER_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 86b443433e8b..f23547a88b1f 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -9,7 +9,9 @@
#include <linux/dma-fence.h>
#include <linux/dma-resv.h>
+#include "gem/i915_gem_object.h"
#include "i915_drv.h"
+#include "intel_atomic_plane.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_dpt.h"
@@ -583,12 +585,6 @@ static bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int color_pl
return intel_fb_rc_ccs_cc_plane(fb) == color_plane;
}
-static bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane)
-{
- return intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
- color_plane == 1;
-}
-
bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane)
{
return fb->modifier == DRM_FORMAT_MOD_LINEAR ||
@@ -775,90 +771,6 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier);
}
-unsigned int intel_cursor_alignment(const struct drm_i915_private *i915)
-{
- if (IS_I830(i915))
- return 16 * 1024;
- else if (IS_I85X(i915))
- return 256;
- else if (IS_I845G(i915) || IS_I865G(i915))
- return 32;
- else
- return 4 * 1024;
-}
-
-static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv)
-{
- if (DISPLAY_VER(dev_priv) >= 9)
- return 256 * 1024;
- else if (IS_I965G(dev_priv) || IS_I965GM(dev_priv) ||
- IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- return 128 * 1024;
- else if (DISPLAY_VER(dev_priv) >= 4)
- return 4 * 1024;
- else
- return 0;
-}
-
-unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
- int color_plane)
-{
- struct drm_i915_private *dev_priv = to_i915(fb->dev);
-
- if (intel_fb_uses_dpt(fb))
- return 512 * 4096;
-
- /* AUX_DIST needs only 4K alignment */
- if (intel_fb_is_ccs_aux_plane(fb, color_plane))
- return 4096;
-
- if (is_semiplanar_uv_plane(fb, color_plane)) {
- /*
- * TODO: cross-check wrt. the bspec stride in bytes * 64 bytes
- * alignment for linear UV planes on all platforms.
- */
- if (DISPLAY_VER(dev_priv) >= 12) {
- if (fb->modifier == DRM_FORMAT_MOD_LINEAR)
- return intel_linear_alignment(dev_priv);
-
- return intel_tile_row_size(fb, color_plane);
- }
-
- return 4096;
- }
-
- drm_WARN_ON(&dev_priv->drm, color_plane != 0);
-
- switch (fb->modifier) {
- case DRM_FORMAT_MOD_LINEAR:
- return intel_linear_alignment(dev_priv);
- case I915_FORMAT_MOD_X_TILED:
- if (HAS_ASYNC_FLIPS(dev_priv))
- return 256 * 1024;
- return 0;
- case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
- case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
- case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
- case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
- case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
- case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
- return 16 * 1024;
- case I915_FORMAT_MOD_Y_TILED_CCS:
- case I915_FORMAT_MOD_Yf_TILED_CCS:
- case I915_FORMAT_MOD_Y_TILED:
- case I915_FORMAT_MOD_4_TILED:
- case I915_FORMAT_MOD_Yf_TILED:
- return 1 * 1024 * 1024;
- case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
- case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
- case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
- return 16 * 1024;
- default:
- MISSING_CASE(fb->modifier);
- return 0;
- }
-}
-
void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
const struct drm_framebuffer *fb,
int color_plane)
@@ -1030,7 +942,7 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *i915,
int color_plane,
unsigned int pitch,
unsigned int rotation,
- u32 alignment)
+ unsigned int alignment)
{
unsigned int cpp = fb->format->cpp[color_plane];
u32 offset, offset_aligned;
@@ -1083,17 +995,12 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
const struct intel_plane_state *state,
int color_plane)
{
- struct intel_plane *intel_plane = to_intel_plane(state->uapi.plane);
- struct drm_i915_private *i915 = to_i915(intel_plane->base.dev);
+ struct intel_plane *plane = to_intel_plane(state->uapi.plane);
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = state->hw.fb;
unsigned int rotation = state->hw.rotation;
- int pitch = state->view.color_plane[color_plane].mapping_stride;
- u32 alignment;
-
- if (intel_plane->id == PLANE_CURSOR)
- alignment = intel_cursor_alignment(i915);
- else
- alignment = intel_surf_alignment(fb, color_plane);
+ unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;
+ unsigned int alignment = plane->min_alignment(plane, fb, color_plane);
return intel_compute_aligned_offset(i915, x, y, fb, color_plane,
pitch, rotation, alignment);
@@ -1105,14 +1012,9 @@ static int intel_fb_offset_to_xy(int *x, int *y,
int color_plane)
{
struct drm_i915_private *i915 = to_i915(fb->dev);
- unsigned int height;
- u32 alignment, unused;
-
- if (DISPLAY_VER(i915) >= 12 &&
- !intel_fb_needs_pot_stride_remap(to_intel_framebuffer(fb)) &&
- is_semiplanar_uv_plane(fb, color_plane))
- alignment = intel_tile_row_size(fb, color_plane);
- else if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
+ unsigned int height, alignment, unused;
+
+ if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
alignment = intel_tile_size(i915);
else
alignment = 0;
@@ -1493,8 +1395,8 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
check_array_bounds(i915, view->gtt.remapped.plane, color_plane);
if (view->gtt.remapped.plane_alignment) {
- unsigned int aligned_offset = ALIGN(gtt_offset,
- view->gtt.remapped.plane_alignment);
+ u32 aligned_offset = ALIGN(gtt_offset,
+ view->gtt.remapped.plane_alignment);
size += aligned_offset - gtt_offset;
gtt_offset = aligned_offset;
@@ -1602,6 +1504,32 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb)
fb->base.modifier == I915_FORMAT_MOD_Yf_TILED;
}
+static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
+{
+ struct drm_i915_private *i915 = to_i915(fb->dev);
+ struct intel_plane *plane;
+ unsigned int min_alignment = 0;
+
+ for_each_intel_plane(&i915->drm, plane) {
+ unsigned int plane_min_alignment;
+
+ if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
+ continue;
+
+ plane_min_alignment = plane->min_alignment(plane, fb, 0);
+
+ drm_WARN_ON(&i915->drm, plane_min_alignment &&
+ !is_power_of_2(plane_min_alignment));
+
+ if (intel_plane_needs_physical(plane))
+ continue;
+
+ min_alignment = max(min_alignment, plane_min_alignment);
+ }
+
+ return min_alignment;
+}
+
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);
@@ -1684,6 +1612,8 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
return -EINVAL;
}
+ fb->min_alignment = intel_fb_min_alignment(&fb->base);
+
return 0;
}
@@ -1780,16 +1710,16 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
return 128 * 1024;
}
-static u32
+static unsigned int
intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
{
struct drm_i915_private *dev_priv = to_i915(fb->dev);
- u32 tile_width;
+ unsigned int tile_width;
if (is_surface_linear(fb, color_plane)) {
- u32 max_stride = intel_plane_fb_max_stride(dev_priv,
- fb->format->format,
- fb->modifier);
+ unsigned int max_stride = intel_plane_fb_max_stride(dev_priv,
+ fb->format->format,
+ fb->modifier);
/*
* To make remapping with linear generally feasible
@@ -2046,7 +1976,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
for (i = 0; i < fb->format->num_planes; i++) {
- u32 stride_alignment;
+ unsigned int stride_alignment;
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n",
@@ -2063,7 +1993,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
}
if (intel_fb_is_gen12_ccs_aux_plane(fb, i)) {
- int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
+ unsigned int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
if (fb->pitches[i] != ccs_aux_stride) {
drm_dbg_kms(&dev_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h
index 23db6628f53e..6dee0c8b7f22 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fb.h
@@ -60,9 +60,6 @@ unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane
unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane);
unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
int color_plane, unsigned int height);
-unsigned int intel_cursor_alignment(const struct drm_i915_private *i915);
-unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
- int color_plane);
void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
const struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index b6df9baf481b..575b271e012b 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -11,24 +11,24 @@
#include "gem/i915_gem_object.h"
#include "i915_drv.h"
+#include "intel_atomic_plane.h"
#include "intel_display_types.h"
#include "intel_dpt.h"
#include "intel_fb.h"
#include "intel_fb_pin.h"
static struct i915_vma *
-intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags,
- struct i915_address_space *vm)
+intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
+ const struct i915_gtt_view *view,
+ unsigned int alignment,
+ unsigned long *out_flags,
+ struct i915_address_space *vm)
{
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 i915_gem_ww_ctx ww;
struct i915_vma *vma;
- u32 alignment;
int ret;
/*
@@ -41,8 +41,6 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
return ERR_PTR(-EINVAL);
- alignment = 4096 * 512;
-
atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
for_i915_gem_ww(&ww, ret, true) {
@@ -104,11 +102,12 @@ err:
}
struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
- bool phys_cursor,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags)
+intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
+ const struct i915_gtt_view *view,
+ unsigned int alignment,
+ unsigned int phys_alignment,
+ bool uses_fence,
+ unsigned long *out_flags)
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -117,16 +116,11 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
struct i915_gem_ww_ctx ww;
struct i915_vma *vma;
unsigned int pinctl;
- u32 alignment;
int ret;
if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj)))
return ERR_PTR(-EINVAL);
- if (phys_cursor)
- alignment = intel_cursor_alignment(dev_priv);
- else
- alignment = intel_surf_alignment(fb, 0);
if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment)))
return ERR_PTR(-EINVAL);
@@ -164,8 +158,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
i915_gem_ww_ctx_init(&ww, true);
retry:
ret = i915_gem_object_lock(obj, &ww);
- if (!ret && phys_cursor)
- ret = i915_gem_object_attach_phys(obj, alignment);
+ if (!ret && phys_alignment)
+ ret = i915_gem_object_attach_phys(obj, phys_alignment);
else if (!ret && HAS_LMEM(dev_priv))
ret = i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM_0);
if (!ret)
@@ -228,7 +222,7 @@ err:
return vma;
}
-void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
+void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags)
{
if (flags & PLANE_HAS_FENCE)
i915_vma_unpin_fence(vma);
@@ -236,21 +230,39 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
i915_vma_put(vma);
}
+static unsigned int
+intel_plane_fb_min_alignment(const struct intel_plane_state *plane_state)
+{
+ const struct intel_framebuffer *fb = to_intel_framebuffer(plane_state->hw.fb);
+
+ return fb->min_alignment;
+}
+
+static unsigned int
+intel_plane_fb_min_phys_alignment(const struct intel_plane_state *plane_state)
+{
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
+
+ if (!intel_plane_needs_physical(plane))
+ return 0;
+
+ return plane->min_alignment(plane, fb, 0);
+}
+
int intel_plane_pin_fb(struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
- struct drm_framebuffer *fb = plane_state->hw.fb;
+ const struct intel_framebuffer *fb =
+ to_intel_framebuffer(plane_state->hw.fb);
struct i915_vma *vma;
- bool phys_cursor =
- plane->id == PLANE_CURSOR &&
- DISPLAY_INFO(dev_priv)->cursor_needs_physical;
-
- if (!intel_fb_uses_dpt(fb)) {
- vma = intel_pin_and_fence_fb_obj(fb, phys_cursor,
- &plane_state->view.gtt,
- intel_plane_uses_fence(plane_state),
- &plane_state->flags);
+
+ if (!intel_fb_uses_dpt(&fb->base)) {
+ vma = intel_fb_pin_to_ggtt(&fb->base, &plane_state->view.gtt,
+ intel_plane_fb_min_alignment(plane_state),
+ intel_plane_fb_min_phys_alignment(plane_state),
+ intel_plane_uses_fence(plane_state),
+ &plane_state->flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
@@ -262,22 +274,23 @@ 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 (phys_cursor)
+ if (intel_plane_needs_physical(plane))
plane_state->phys_dma_addr =
- i915_gem_object_get_dma_address(intel_fb_obj(fb), 0);
+ i915_gem_object_get_dma_address(intel_fb_obj(&fb->base), 0);
} else {
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+ unsigned int alignment = intel_plane_fb_min_alignment(plane_state);
- vma = intel_dpt_pin(intel_fb->dpt_vm);
+ vma = intel_dpt_pin_to_ggtt(fb->dpt_vm, alignment / 512);
if (IS_ERR(vma))
return PTR_ERR(vma);
plane_state->ggtt_vma = vma;
- vma = intel_pin_fb_obj_dpt(fb, &plane_state->view.gtt, false,
- &plane_state->flags, intel_fb->dpt_vm);
+ vma = intel_fb_pin_to_dpt(&fb->base, &plane_state->view.gtt,
+ alignment, &plane_state->flags,
+ fb->dpt_vm);
if (IS_ERR(vma)) {
- intel_dpt_unpin(intel_fb->dpt_vm);
+ intel_dpt_unpin_from_ggtt(fb->dpt_vm);
plane_state->ggtt_vma = NULL;
return PTR_ERR(vma);
}
@@ -292,22 +305,21 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state)
{
- struct drm_framebuffer *fb = old_plane_state->hw.fb;
+ const struct intel_framebuffer *fb =
+ to_intel_framebuffer(old_plane_state->hw.fb);
struct i915_vma *vma;
- if (!intel_fb_uses_dpt(fb)) {
+ if (!intel_fb_uses_dpt(&fb->base)) {
vma = fetch_and_zero(&old_plane_state->ggtt_vma);
if (vma)
- intel_unpin_fb_vma(vma, old_plane_state->flags);
+ intel_fb_unpin_vma(vma, old_plane_state->flags);
} else {
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-
vma = fetch_and_zero(&old_plane_state->dpt_vma);
if (vma)
- intel_unpin_fb_vma(vma, old_plane_state->flags);
+ intel_fb_unpin_vma(vma, old_plane_state->flags);
vma = fetch_and_zero(&old_plane_state->ggtt_vma);
if (vma)
- intel_dpt_unpin(intel_fb->dpt_vm);
+ intel_dpt_unpin_from_ggtt(fb->dpt_vm);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h
index de0efaa25905..ac0319b53af0 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.h
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h
@@ -14,13 +14,14 @@ struct intel_plane_state;
struct i915_gtt_view;
struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
- bool phys_cursor,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags);
+intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
+ const struct i915_gtt_view *view,
+ unsigned int alignment,
+ unsigned int phys_alignment,
+ bool uses_fence,
+ unsigned long *out_flags);
-void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags);
+void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags);
int intel_plane_pin_fb(struct intel_plane_state *plane_state);
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 151dcd0c45b6..67116c9f1464 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -43,11 +43,14 @@
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
+#include "gem/i915_gem_stolen.h"
+#include "gt/intel_gt_types.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "i915_vgpu.h"
#include "i915_vma.h"
+#include "i9xx_plane_regs.h"
#include "intel_cdclk.h"
#include "intel_de.h"
#include "intel_display_device.h"
@@ -326,8 +329,8 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915;
- intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
- intel_de_read_fw(dev_priv, DSPADDR(i9xx_plane)));
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
+ intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane)));
}
static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
@@ -363,8 +366,8 @@ static void i965_fbc_nuke(struct intel_fbc *fbc)
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915;
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
- intel_de_read_fw(dev_priv, DSPSURF(i9xx_plane)));
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
+ intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane)));
}
static const struct intel_fbc_funcs i965_fbc_funcs = {
@@ -1234,6 +1237,12 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
return 0;
}
+ /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
+ if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
+ plane_state->no_fbc_reason = "VT-d enabled";
+ return 0;
+ }
+
crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
@@ -1251,7 +1260,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
* Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002
*/
- if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_psr2) {
+ if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_sel_update &&
+ !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR2 enabled";
return 0;
}
@@ -1259,7 +1269,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
/* Wa_14016291713 */
if ((IS_DISPLAY_VER(i915, 12, 13) ||
IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0)) &&
- crtc_state->has_psr) {
+ crtc_state->has_psr && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";
return 0;
}
@@ -1818,19 +1828,6 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *i915)
return 0;
}
-static bool need_fbc_vtd_wa(struct drm_i915_private *i915)
-{
- /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
- if (i915_vtd_active(i915) &&
- (IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
- drm_info(&i915->drm,
- "Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
- return true;
- }
-
- return false;
-}
-
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
{
plane->fbc = fbc;
@@ -1876,9 +1873,6 @@ void intel_fbc_init(struct drm_i915_private *i915)
{
enum intel_fbc_id fbc_id;
- if (need_fbc_vtd_wa(i915))
- DISPLAY_RUNTIME_INFO(i915)->fbc_mask = 0;
-
i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
i915->display.params.enable_fbc);
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index bda702c2cab8..49a1ac4f5491 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -44,6 +44,7 @@
#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_display_types.h"
@@ -146,7 +147,7 @@ static void intel_fbdev_fb_destroy(struct fb_info *info)
* the info->screen_base mmaping. Leaking the VMA is simpler than
* trying to rectify all the possible error paths leading here.
*/
- intel_unpin_fb_vma(ifbdev->vma, ifbdev->vma_flags);
+ intel_fb_unpin_vma(ifbdev->vma, ifbdev->vma_flags);
drm_framebuffer_remove(&ifbdev->fb->base);
drm_client_release(&fb_helper->client);
@@ -175,7 +176,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
- struct intel_framebuffer *intel_fb = ifbdev->fb;
+ struct intel_framebuffer *fb = ifbdev->fb;
struct drm_device *dev = helper->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
const struct i915_gtt_view view = {
@@ -195,30 +196,30 @@ static int intelfb_create(struct drm_fb_helper *helper,
if (ret)
return ret;
- if (intel_fb &&
- (sizes->fb_width > intel_fb->base.width ||
- sizes->fb_height > intel_fb->base.height)) {
+ ifbdev->fb = NULL;
+
+ if (fb &&
+ (sizes->fb_width > fb->base.width ||
+ sizes->fb_height > fb->base.height)) {
drm_dbg_kms(&dev_priv->drm,
"BIOS fb too small (%dx%d), we require (%dx%d),"
" releasing it\n",
- intel_fb->base.width, intel_fb->base.height,
+ fb->base.width, fb->base.height,
sizes->fb_width, sizes->fb_height);
- drm_framebuffer_put(&intel_fb->base);
- intel_fb = ifbdev->fb = NULL;
+ drm_framebuffer_put(&fb->base);
+ fb = NULL;
}
- if (!intel_fb || drm_WARN_ON(dev, !intel_fb_obj(&intel_fb->base))) {
- struct drm_framebuffer *fb;
+ if (!fb || drm_WARN_ON(dev, !intel_fb_obj(&fb->base))) {
drm_dbg_kms(&dev_priv->drm,
"no BIOS fb, allocating a new one\n");
fb = intel_fbdev_fb_alloc(helper, sizes);
if (IS_ERR(fb))
return PTR_ERR(fb);
- intel_fb = ifbdev->fb = to_intel_framebuffer(fb);
} else {
drm_dbg_kms(&dev_priv->drm, "re-using BIOS fb\n");
prealloc = true;
- sizes->fb_width = intel_fb->base.width;
- sizes->fb_height = intel_fb->base.height;
+ sizes->fb_width = fb->base.width;
+ sizes->fb_height = fb->base.height;
}
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
@@ -227,8 +228,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
* This also validates that any existing fb inherited from the
* BIOS is suitable for own access.
*/
- vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, false,
- &view, false, &flags);
+ vma = intel_fb_pin_to_ggtt(&fb->base, &view,
+ fb->min_alignment, 0,
+ false, &flags);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto out_unlock;
@@ -241,11 +243,11 @@ static int intelfb_create(struct drm_fb_helper *helper,
goto out_unpin;
}
- ifbdev->helper.fb = &ifbdev->fb->base;
+ ifbdev->helper.fb = &fb->base;
info->fbops = &intelfb_ops;
- obj = intel_fb_obj(&intel_fb->base);
+ obj = intel_fb_obj(&fb->base);
ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma);
if (ret)
@@ -263,8 +265,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
drm_dbg_kms(&dev_priv->drm, "allocated %dx%d fb: 0x%08x\n",
- ifbdev->fb->base.width, ifbdev->fb->base.height,
+ fb->base.width, fb->base.height,
i915_ggtt_offset(vma));
+ ifbdev->fb = fb;
ifbdev->vma = vma;
ifbdev->vma_flags = flags;
@@ -273,7 +276,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
return 0;
out_unpin:
- intel_unpin_fb_vma(vma, flags);
+ intel_fb_unpin_vma(vma, flags);
out_unlock:
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
return ret;
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
index 0665f943f65f..497525ef9668 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
@@ -11,8 +11,8 @@
#include "intel_display_types.h"
#include "intel_fbdev_fb.h"
-struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes)
+struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
{
struct drm_framebuffer *fb;
struct drm_device *dev = helper->dev;
@@ -63,7 +63,7 @@ struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
fb = intel_framebuffer_create(obj, &mode_cmd);
i915_gem_object_put(obj);
- return fb;
+ return to_intel_framebuffer(fb);
}
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
index a395b2c65d33..4832fe688fbf 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
@@ -13,8 +13,8 @@ struct drm_i915_private;
struct fb_info;
struct i915_vma;
-struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes);
+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);
diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c
index 295a0f24ebbf..d33befd7994d 100644
--- a/drivers/gpu/drm/i915/display/intel_fdi.c
+++ b/drivers/gpu/drm/i915/display/intel_fdi.c
@@ -34,7 +34,8 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
* so pipe->transcoder cast is fine here.
*/
enum transcoder cpu_transcoder = (enum transcoder)pipe;
- cur_state = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
+ cur_state = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
} else {
cur_state = intel_de_read(dev_priv, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE;
}
@@ -514,7 +515,7 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc,
* detection works.
*/
intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
- intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+ intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
/* FDI needs bits from pipe first */
assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder);
@@ -616,7 +617,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc,
* detection works.
*/
intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
- intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+ intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
@@ -754,7 +755,7 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
* detection works.
*/
intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
- intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+ intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
@@ -1034,7 +1035,7 @@ void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
temp = intel_de_read(dev_priv, reg);
temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
- temp |= (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) << 11;
+ temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11;
intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE);
intel_de_posting_read(dev_priv, reg);
@@ -1090,7 +1091,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc)
reg = FDI_RX_CTL(pipe);
temp = intel_de_read(dev_priv, reg);
temp &= ~(0x7 << 16);
- temp |= (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) << 11;
+ temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11;
intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE);
intel_de_posting_read(dev_priv, reg);
@@ -1116,7 +1117,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc)
}
/* BPC in FDI rx is consistent with that in TRANSCONF */
temp &= ~(0x07 << 16);
- temp |= (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) << 11;
+ temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11;
intel_de_write(dev_priv, reg, temp);
intel_de_posting_read(dev_priv, reg);
diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
index 09a7fa6c0c37..e5e4ca7cc499 100644
--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
@@ -94,7 +94,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev)
static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- i915_reg_t reg = PIPESTAT(crtc->pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, crtc->pipe);
u32 enable_mask;
lockdep_assert_held(&dev_priv->irq_lock);
@@ -115,7 +115,7 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
bool enable, bool old)
{
struct drm_i915_private *dev_priv = to_i915(dev);
- i915_reg_t reg = PIPESTAT(pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, pipe);
lockdep_assert_held(&dev_priv->irq_lock);
@@ -209,7 +209,8 @@ static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
if (enable) {
if (DISPLAY_VER(dev_priv) >= 11)
- intel_de_write(dev_priv, ICL_PIPESTATUS(pipe),
+ intel_de_write(dev_priv,
+ ICL_PIPESTATUS(dev_priv, pipe),
icl_pipe_status_underrun_mask(dev_priv));
bdw_enable_pipe_irq(dev_priv, pipe, mask);
@@ -418,9 +419,11 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
* the underrun was caused by the downstream port.
*/
if (DISPLAY_VER(dev_priv) >= 11) {
- underruns = intel_de_read(dev_priv, ICL_PIPESTATUS(pipe)) &
+ underruns = intel_de_read(dev_priv,
+ ICL_PIPESTATUS(dev_priv, pipe)) &
icl_pipe_status_underrun_mask(dev_priv);
- intel_de_write(dev_priv, ICL_PIPESTATUS(pipe), underruns);
+ intel_de_write(dev_priv, ICL_PIPESTATUS(dev_priv, pipe),
+ underruns);
}
if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 2ea37c0414a9..4923c340a0b6 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -65,6 +65,7 @@
#include "intel_fbc.h"
#include "intel_frontbuffer.h"
#include "intel_psr.h"
+#include "intel_tdf.h"
/**
* frontbuffer_flush - flush frontbuffer
@@ -93,6 +94,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
trace_intel_frontbuffer_flush(i915, frontbuffer_bits, origin);
might_sleep();
+ intel_td_flush(i915);
intel_drrs_flush(i915, frontbuffer_bits);
intel_psr_flush(i915, frontbuffer_bits, origin);
intel_fbc_flush(i915, frontbuffer_bits, origin);
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index d5ed4c7dfbc0..3ebe035f382e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -13,7 +13,7 @@
#include <linux/random.h>
#include <drm/display/drm_hdcp_helper.h>
-#include <drm/i915_component.h>
+#include <drm/intel/i915_component.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -30,6 +30,29 @@
#define KEY_LOAD_TRIES 5
#define HDCP2_LC_RETRY_CNT 3
+/* WA: 16022217614 */
+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);
+
+ /* 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_IP_STEP(dev_priv, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
+ intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
+ 0, HDCP_LINE_REKEY_DISABLE);
+ else if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
+ IS_DISPLAY_IP_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),
+ 0, TRANS_DDI_HDCP_LINE_REKEY_DISABLE);
+ }
+}
+
static int intel_conn_to_vcpi(struct intel_atomic_state *state,
struct intel_connector *connector)
{
@@ -2005,6 +2028,8 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state,
connector->base.base.id, connector->base.name,
hdcp->content_type);
+ intel_hdcp_disable_hdcp_line_rekeying(connector->encoder, hdcp);
+
ret = hdcp2_authenticate_and_encrypt(state, connector);
if (ret) {
drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n",
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index 35823e1f65d6..16afeb8a3a8d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -3,7 +3,7 @@
* Copyright 2023, Intel Corporation.
*/
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include "gem/i915_gem_region.h"
#include "gt/intel_gt.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 240b00849f3d..6548e71b4c49 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
@@ -4,7 +4,7 @@
*/
#include <linux/err.h>
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include "i915_drv.h"
#include "intel_hdcp_gsc_message.h"
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 5f6deceaf8ba..19498ee455fa 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -38,7 +38,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
-#include <drm/intel_lpe_audio.h>
+#include <drm/intel/intel_lpe_audio.h>
#include "g4x_hdmi.h"
#include "i915_drv.h"
@@ -83,7 +83,7 @@ assert_hdmi_transcoder_func_disabled(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
drm_WARN(&dev_priv->drm,
- intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) &
+ intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) &
TRANS_DDI_FUNC_ENABLE,
"HDMI transcoder function enabled, expecting disabled\n");
}
@@ -165,21 +165,21 @@ hsw_dip_data_reg(struct drm_i915_private *dev_priv,
{
switch (type) {
case HDMI_PACKET_TYPE_GAMUT_METADATA:
- return HSW_TVIDEO_DIP_GMP_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_GMP_DATA(dev_priv, cpu_transcoder, i);
case DP_SDP_VSC:
- return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_VSC_DATA(dev_priv, cpu_transcoder, i);
case DP_SDP_ADAPTIVE_SYNC:
- return ADL_TVIDEO_DIP_AS_SDP_DATA(cpu_transcoder, i);
+ return ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, cpu_transcoder, i);
case DP_SDP_PPS:
- return ICL_VIDEO_DIP_PPS_DATA(cpu_transcoder, i);
+ return ICL_VIDEO_DIP_PPS_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_AVI:
- return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_AVI_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_SPD:
- return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_SPD_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_VENDOR:
- return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_VS_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_DRM:
- return GLK_TVIDEO_DIP_DRM_DATA(cpu_transcoder, i);
+ return GLK_TVIDEO_DIP_DRM_DATA(dev_priv, cpu_transcoder, i);
default:
MISSING_CASE(type);
return INVALID_MMIO_REG;
@@ -507,7 +507,7 @@ void hsw_write_infoframe(struct intel_encoder *encoder,
const u32 *data = frame;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
+ i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(dev_priv, cpu_transcoder);
int data_size;
int i;
u32 val = intel_de_read(dev_priv, ctl_reg);
@@ -532,7 +532,8 @@ void hsw_write_infoframe(struct intel_encoder *encoder,
0);
/* Wa_14013475917 */
- if (!(IS_DISPLAY_VER(dev_priv, 13, 14) && crtc_state->has_psr && type == DP_SDP_VSC))
+ if (!(IS_DISPLAY_VER(dev_priv, 13, 14) && crtc_state->has_psr &&
+ !crtc_state->has_panel_replay && type == DP_SDP_VSC))
val |= hsw_infoframe_enable(type);
if (type == DP_SDP_VSC)
@@ -561,7 +562,7 @@ static u32 hsw_infoframes_enabled(struct intel_encoder *encoder,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u32 val = intel_de_read(dev_priv,
- HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
+ HSW_TVIDEO_DIP_CTL(dev_priv, pipe_config->cpu_transcoder));
u32 mask;
mask = (VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW |
@@ -985,7 +986,7 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
return false;
if (HAS_DDI(dev_priv))
- reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
+ reg = HSW_TVIDEO_DIP_GCP(dev_priv, crtc_state->cpu_transcoder);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
else if (HAS_PCH_SPLIT(dev_priv))
@@ -1010,7 +1011,7 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
return;
if (HAS_DDI(dev_priv))
- reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
+ reg = HSW_TVIDEO_DIP_GCP(dev_priv, crtc_state->cpu_transcoder);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
else if (HAS_PCH_SPLIT(dev_priv))
@@ -1215,7 +1216,8 @@ static void hsw_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
+ i915_reg_t reg = HSW_TVIDEO_DIP_CTL(dev_priv,
+ crtc_state->cpu_transcoder);
u32 val = intel_de_read(dev_priv, reg);
assert_hdmi_transcoder_func_disabled(dev_priv,
@@ -1474,7 +1476,8 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
int ret;
for (;;) {
- scanline = intel_de_read(dev_priv, PIPEDSL(crtc->pipe));
+ scanline = intel_de_read(dev_priv,
+ PIPEDSL(dev_priv, crtc->pipe));
if (scanline > 100 && scanline < 200)
break;
usleep_range(25, 50);
@@ -1783,7 +1786,9 @@ static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
int max_tmds_clock, vbt_max_tmds_clock;
- if (DISPLAY_VER(dev_priv) >= 10)
+ if (DISPLAY_VER(dev_priv) >= 13 || IS_ALDERLAKE_S(dev_priv))
+ max_tmds_clock = 600000;
+ else if (DISPLAY_VER(dev_priv) >= 10)
max_tmds_clock = 594000;
else if (DISPLAY_VER(dev_priv) >= 8 || IS_HASWELL(dev_priv))
max_tmds_clock = 300000;
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
index d270bb7b9462..a1f07ee69a86 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
@@ -186,7 +186,8 @@ void i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
lockdep_assert_held(&dev_priv->irq_lock);
drm_WARN_ON(&dev_priv->drm, bits & ~mask);
- intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN, mask, bits);
+ intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN(dev_priv), mask,
+ bits);
}
/**
@@ -434,18 +435,21 @@ u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
* bits can itself generate a new hotplug interrupt :(
*/
for (i = 0; i < 10; i++) {
- u32 tmp = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT) & hotplug_status_mask;
+ u32 tmp = intel_uncore_read(&dev_priv->uncore,
+ PORT_HOTPLUG_STAT(dev_priv)) & hotplug_status_mask;
if (tmp == 0)
return hotplug_status;
hotplug_status |= tmp;
- intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, hotplug_status);
+ intel_uncore_write(&dev_priv->uncore,
+ PORT_HOTPLUG_STAT(dev_priv),
+ hotplug_status);
}
drm_WARN_ONCE(&dev_priv->drm, 1,
"PORT_HOTPLUG_STAT did not clear (0x%08x)\n",
- intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
+ intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT(dev_priv)));
return hotplug_status;
}
diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c
index 93e6cac9a4ed..f11626176fe2 100644
--- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c
@@ -68,7 +68,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <drm/intel_lpe_audio.h>
+#include <drm/intel/intel_lpe_audio.h>
#include "i915_drv.h"
#include "i915_irq.h"
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index 1d048fa98561..8b26354d6e53 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -641,7 +641,7 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder,
if (lspcon->hdr_supported) {
tmp = intel_de_read(dev_priv,
- HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
+ HSW_TVIDEO_DIP_CTL(dev_priv, pipe_config->cpu_transcoder));
mask = VIDEO_DIP_ENABLE_GMP_HSW;
if (tmp & mask)
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index 8b8959073466..9f018503d4fd 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -148,7 +148,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
/* gen2/3 store dither state in pfit control, needs to match */
if (DISPLAY_VER(dev_priv) < 4) {
- tmp = intel_de_read(dev_priv, PFIT_CONTROL);
+ tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv));
crtc_state->gmch_pfit.control |= tmp & PFIT_PANEL_8TO6_DITHER_ENABLE;
}
@@ -161,18 +161,19 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
{
u32 val;
- pps->powerdown_on_reset = intel_de_read(dev_priv, PP_CONTROL(0)) & PANEL_POWER_RESET;
+ pps->powerdown_on_reset = intel_de_read(dev_priv,
+ PP_CONTROL(dev_priv, 0)) & PANEL_POWER_RESET;
- val = intel_de_read(dev_priv, PP_ON_DELAYS(0));
+ val = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0));
pps->port = REG_FIELD_GET(PANEL_PORT_SELECT_MASK, val);
pps->t1_t2 = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, val);
pps->t5 = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, val);
- val = intel_de_read(dev_priv, PP_OFF_DELAYS(0));
+ val = intel_de_read(dev_priv, PP_OFF_DELAYS(dev_priv, 0));
pps->t3 = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, val);
pps->tx = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, val);
- val = intel_de_read(dev_priv, PP_DIVISOR(0));
+ val = intel_de_read(dev_priv, PP_DIVISOR(dev_priv, 0));
pps->divider = REG_FIELD_GET(PP_REFERENCE_DIVIDER_MASK, val);
val = REG_FIELD_GET(PANEL_POWER_CYCLE_DELAY_MASK, val);
/*
@@ -209,23 +210,23 @@ static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
{
u32 val;
- val = intel_de_read(dev_priv, PP_CONTROL(0));
+ val = intel_de_read(dev_priv, PP_CONTROL(dev_priv, 0));
drm_WARN_ON(&dev_priv->drm,
(val & PANEL_UNLOCK_MASK) != PANEL_UNLOCK_REGS);
if (pps->powerdown_on_reset)
val |= PANEL_POWER_RESET;
- intel_de_write(dev_priv, PP_CONTROL(0), val);
+ intel_de_write(dev_priv, PP_CONTROL(dev_priv, 0), val);
- intel_de_write(dev_priv, PP_ON_DELAYS(0),
+ intel_de_write(dev_priv, PP_ON_DELAYS(dev_priv, 0),
REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, pps->port) |
REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, pps->t1_t2) |
REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, pps->t5));
- intel_de_write(dev_priv, PP_OFF_DELAYS(0),
+ intel_de_write(dev_priv, PP_OFF_DELAYS(dev_priv, 0),
REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, pps->t3) |
REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, pps->tx));
- intel_de_write(dev_priv, PP_DIVISOR(0),
+ intel_de_write(dev_priv, PP_DIVISOR(dev_priv, 0),
REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, pps->divider) |
REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK, DIV_ROUND_UP(pps->t4, 1000) + 1));
}
@@ -321,10 +322,10 @@ static void intel_enable_lvds(struct intel_atomic_state *state,
intel_de_rmw(dev_priv, lvds_encoder->reg, 0, LVDS_PORT_EN);
- intel_de_rmw(dev_priv, PP_CONTROL(0), 0, PANEL_POWER_ON);
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, 0), 0, PANEL_POWER_ON);
intel_de_posting_read(dev_priv, lvds_encoder->reg);
- if (intel_de_wait_for_set(dev_priv, PP_STATUS(0), PP_ON, 5000))
+ if (intel_de_wait_for_set(dev_priv, PP_STATUS(dev_priv, 0), PP_ON, 5000))
drm_err(&dev_priv->drm,
"timed out waiting for panel to power on\n");
@@ -339,8 +340,8 @@ static void intel_disable_lvds(struct intel_atomic_state *state,
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- intel_de_rmw(dev_priv, PP_CONTROL(0), PANEL_POWER_ON, 0);
- if (intel_de_wait_for_clear(dev_priv, PP_STATUS(0), PP_ON, 1000))
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, 0), PANEL_POWER_ON, 0);
+ if (intel_de_wait_for_clear(dev_priv, PP_STATUS(dev_priv, 0), PP_ON, 1000))
drm_err(&dev_priv->drm,
"timed out waiting for panel to power off\n");
@@ -379,7 +380,7 @@ static void intel_lvds_shutdown(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- if (intel_de_wait_for_clear(dev_priv, PP_STATUS(0), PP_CYCLE_DELAY_ACTIVE, 5000))
+ if (intel_de_wait_for_clear(dev_priv, PP_STATUS(dev_priv, 0), PP_CYCLE_DELAY_ACTIVE, 5000))
drm_err(&dev_priv->drm,
"timed out waiting for panel power cycle delay\n");
}
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
index caeca3a8442c..7602cb30ebf1 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
@@ -68,7 +68,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
/* Everything's already locked, -EDEADLK can't happen. */
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc,
BIT(pipe) |
- intel_crtc_bigjoiner_slave_pipes(crtc_state)) {
+ intel_crtc_joiner_secondary_pipes(crtc_state)) {
struct intel_crtc_state *temp_crtc_state =
intel_atomic_get_crtc_state(state, temp_crtc);
int ret;
@@ -189,7 +189,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc)
/*
* Return all the pipes using a transcoder in @transcoder_mask.
- * For bigjoiner configs return only the bigjoiner master.
+ * For joiner configs return only the joiner primary.
*/
static u8 get_transcoder_pipes(struct drm_i915_private *i915,
u8 transcoder_mask)
@@ -204,7 +204,7 @@ static u8 get_transcoder_pipes(struct drm_i915_private *i915,
if (temp_crtc_state->cpu_transcoder == INVALID_TRANSCODER)
continue;
- if (intel_crtc_is_bigjoiner_slave(temp_crtc_state))
+ if (intel_crtc_is_joiner_secondary(temp_crtc_state))
continue;
if (transcoder_mask & BIT(temp_crtc_state->cpu_transcoder))
@@ -216,7 +216,7 @@ static u8 get_transcoder_pipes(struct drm_i915_private *i915,
/*
* Return the port sync master and slave pipes linked to @crtc.
- * For bigjoiner configs return only the bigjoiner master pipes.
+ * For joiner configs return only the joiner primary pipes.
*/
static void get_portsync_pipes(struct intel_crtc *crtc,
u8 *master_pipe_mask, u8 *slave_pipes_mask)
@@ -248,16 +248,16 @@ static void get_portsync_pipes(struct intel_crtc *crtc,
*slave_pipes_mask = get_transcoder_pipes(i915, master_crtc_state->sync_mode_slaves_mask);
}
-static u8 get_bigjoiner_slave_pipes(struct drm_i915_private *i915, u8 master_pipes_mask)
+static u8 get_joiner_secondary_pipes(struct drm_i915_private *i915, u8 primary_pipes_mask)
{
- struct intel_crtc *master_crtc;
+ struct intel_crtc *primary_crtc;
u8 pipes = 0;
- for_each_intel_crtc_in_pipe_mask(&i915->drm, master_crtc, master_pipes_mask) {
- struct intel_crtc_state *master_crtc_state =
- to_intel_crtc_state(master_crtc->base.state);
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, primary_crtc, primary_pipes_mask) {
+ struct intel_crtc_state *primary_crtc_state =
+ to_intel_crtc_state(primary_crtc->base.state);
- pipes |= intel_crtc_bigjoiner_slave_pipes(master_crtc_state);
+ pipes |= intel_crtc_joiner_secondary_pipes(primary_crtc_state);
}
return pipes;
@@ -269,21 +269,21 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
u8 portsync_master_mask;
u8 portsync_slaves_mask;
- u8 bigjoiner_slaves_mask;
+ u8 joiner_secondaries_mask;
struct intel_crtc *temp_crtc;
/* TODO: Add support for MST */
get_portsync_pipes(crtc, &portsync_master_mask, &portsync_slaves_mask);
- bigjoiner_slaves_mask = get_bigjoiner_slave_pipes(i915,
- portsync_master_mask |
- portsync_slaves_mask);
+ joiner_secondaries_mask = get_joiner_secondary_pipes(i915,
+ portsync_master_mask |
+ portsync_slaves_mask);
drm_WARN_ON(&i915->drm,
portsync_master_mask & portsync_slaves_mask ||
- portsync_master_mask & bigjoiner_slaves_mask ||
- portsync_slaves_mask & bigjoiner_slaves_mask);
+ portsync_master_mask & joiner_secondaries_mask ||
+ portsync_slaves_mask & joiner_secondaries_mask);
- for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, bigjoiner_slaves_mask)
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, joiner_secondaries_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, portsync_slaves_mask)
@@ -293,7 +293,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc,
- bigjoiner_slaves_mask |
+ joiner_secondaries_mask |
portsync_slaves_mask |
portsync_master_mask)
intel_crtc_disable_noatomic_complete(temp_crtc);
@@ -326,7 +326,7 @@ static void intel_modeset_update_connector_atomic_state(struct drm_i915_private
static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
{
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
+ if (intel_crtc_is_joiner_secondary(crtc_state))
return;
crtc_state->uapi.enable = crtc_state->hw.enable;
@@ -474,7 +474,7 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc,
}
if (!crtc_state->hw.active ||
- intel_crtc_is_bigjoiner_slave(crtc_state))
+ intel_crtc_is_joiner_secondary(crtc_state))
return false;
needs_link_reset = intel_crtc_needs_link_reset(crtc);
@@ -728,19 +728,19 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
encoder->base.crtc = &crtc->base;
intel_encoder_get_config(encoder, crtc_state);
- /* read out to slave crtc as well for bigjoiner */
- if (crtc_state->bigjoiner_pipes) {
- struct intel_crtc *slave_crtc;
+ /* read out to secondary crtc as well for joiner */
+ if (crtc_state->joiner_pipes) {
+ struct intel_crtc *secondary_crtc;
- /* encoder should read be linked to bigjoiner master */
- WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+ /* encoder should read be linked to joiner primary */
+ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
- for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
- intel_crtc_bigjoiner_slave_pipes(crtc_state)) {
- struct intel_crtc_state *slave_crtc_state;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
+ intel_crtc_joiner_secondary_pipes(crtc_state)) {
+ struct intel_crtc_state *secondary_crtc_state;
- slave_crtc_state = to_intel_crtc_state(slave_crtc->base.state);
- intel_encoder_get_config(encoder, slave_crtc_state);
+ secondary_crtc_state = to_intel_crtc_state(secondary_crtc->base.state);
+ intel_encoder_get_config(encoder, secondary_crtc_state);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_verify.c b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
index 076298a8d405..3491db5cad31 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_verify.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
@@ -166,7 +166,7 @@ verify_crtc_state(struct intel_atomic_state *state,
const struct intel_crtc_state *sw_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_crtc_state *hw_crtc_state;
- struct intel_crtc *master_crtc;
+ struct intel_crtc *primary_crtc;
struct intel_encoder *encoder;
hw_crtc_state = intel_crtc_state_alloc(crtc);
@@ -193,9 +193,9 @@ verify_crtc_state(struct intel_atomic_state *state,
"transitional active state does not match atomic hw state (expected %i, found %i)\n",
sw_crtc_state->hw.active, crtc->active);
- master_crtc = intel_master_crtc(sw_crtc_state);
+ primary_crtc = intel_primary_crtc(sw_crtc_state);
- for_each_encoder_on_crtc(dev, &master_crtc->base, encoder) {
+ for_each_encoder_on_crtc(dev, &primary_crtc->base, encoder) {
enum pipe pipe;
bool active;
@@ -205,7 +205,7 @@ verify_crtc_state(struct intel_atomic_state *state,
encoder->base.base.id, active,
sw_crtc_state->hw.active);
- I915_STATE_WARN(i915, active && master_crtc->pipe != pipe,
+ I915_STATE_WARN(i915, active && primary_crtc->pipe != pipe,
"Encoder connected to wrong pipe %c\n",
pipe_name(pipe));
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c
index 1c2099ed5514..06b1122ec13e 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.c
+++ b/drivers/gpu/drm/i915/display/intel_overlay.c
@@ -943,17 +943,19 @@ static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
* line with the intel documentation for the i965
*/
if (DISPLAY_VER(dev_priv) >= 4) {
- u32 tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS);
+ u32 tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv));
/* on i965 use the PGM reg to read out the autoscaler values */
ratio = REG_FIELD_GET(PFIT_VERT_SCALE_MASK_965, tmp);
} else {
u32 tmp;
- if (intel_de_read(dev_priv, PFIT_CONTROL) & PFIT_VERT_AUTO_SCALE)
- tmp = intel_de_read(dev_priv, PFIT_AUTO_RATIOS);
+ if (intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)) & PFIT_VERT_AUTO_SCALE)
+ tmp = intel_de_read(dev_priv,
+ PFIT_AUTO_RATIOS(dev_priv));
else
- tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS);
+ tmp = intel_de_read(dev_priv,
+ PFIT_PGM_RATIOS(dev_priv));
ratio = REG_FIELD_GET(PFIT_VERT_SCALE_MASK, tmp);
}
@@ -1485,15 +1487,14 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
}
void
-intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
+intel_overlay_print_error_state(struct drm_printer *p,
struct intel_overlay_error_state *error)
{
- i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
- error->dovsta, error->isr);
- i915_error_printf(m, " Register file at 0x%08lx:\n",
- error->base);
+ 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);
-#define P(x) i915_error_printf(m, " " #x ": 0x%08x\n", error->regs.x)
+#define P(x) drm_printf(p, " " #x ": 0x%08x\n", error->regs.x)
P(OBUF_0Y);
P(OBUF_1Y);
P(OBUF_0U);
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.h b/drivers/gpu/drm/i915/display/intel_overlay.h
index c3f68fce6f08..f28a09c062d0 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.h
+++ b/drivers/gpu/drm/i915/display/intel_overlay.h
@@ -8,8 +8,8 @@
struct drm_device;
struct drm_file;
-struct drm_i915_error_state_buf;
struct drm_i915_private;
+struct drm_printer;
struct intel_overlay;
struct intel_overlay_error_state;
@@ -24,7 +24,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
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_i915_error_state_buf *e,
+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)
@@ -55,7 +55,7 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
{
return NULL;
}
-static inline void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
+static inline void intel_overlay_print_error_state(struct drm_printer *p,
struct intel_overlay_error_state *error)
{
}
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 6f4ff6a89c32..71454ddef20f 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -352,7 +352,7 @@ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector)
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *mode;
- mode = connector->panel.vbt.lfp_lvds_vbt_mode;
+ mode = connector->panel.vbt.lfp_vbt_mode;
if (!mode)
return;
diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c
index 826e38a9e6a4..0d48b9bec29c 100644
--- a/drivers/gpu/drm/i915/display/intel_pch_display.c
+++ b/drivers/gpu/drm/i915/display/intel_pch_display.c
@@ -224,20 +224,20 @@ static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_s
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
intel_de_write(dev_priv, PCH_TRANS_HTOTAL(pch_transcoder),
- intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_HBLANK(pch_transcoder),
- intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_HSYNC(pch_transcoder),
- intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VTOTAL(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VBLANK(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VSYNC(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VSYNCSHIFT(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VSYNCSHIFT(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VSYNCSHIFT(dev_priv, cpu_transcoder)));
}
static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
@@ -271,7 +271,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
reg = PCH_TRANSCONF(pipe);
val = intel_de_read(dev_priv, reg);
- pipeconf_val = intel_de_read(dev_priv, TRANSCONF(pipe));
+ pipeconf_val = intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe));
if (HAS_PCH_IBX(dev_priv)) {
/* Configure frame start delay to match the CPU */
@@ -413,7 +413,7 @@ void ilk_pch_enable(struct intel_atomic_state *state,
intel_crtc_has_dp_encoder(crtc_state)) {
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
- u32 bpc = (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) >> 5;
+ u32 bpc = (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) >> 5;
i915_reg_t reg = TRANS_DP_CTL(pipe);
enum port port;
@@ -557,7 +557,8 @@ static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
intel_de_write(dev_priv, TRANS_CHICKEN2(PIPE_A), val);
val = TRANS_ENABLE;
- pipeconf_val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ pipeconf_val = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_HSW) == TRANSCONF_INTERLACE_IF_ID_ILK)
val |= TRANS_INTERLACE_INTERLACED;
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
index 5a468ed6e26c..82ceede0b2b1 100644
--- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
@@ -34,6 +34,7 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_pipe_crc.h"
+#include "intel_pipe_crc_regs.h"
static const char * const pipe_crc_sources[] = {
[INTEL_PIPE_CRC_SOURCE_NONE] = "none",
@@ -167,7 +168,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
* - DisplayPort scrambling: used for EMI reduction
*/
if (need_stable_symbols) {
- u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
+ u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X(dev_priv));
tmp |= DC_BALANCE_RESET_VLV;
switch (pipe) {
@@ -183,7 +184,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
default:
return -EINVAL;
}
- intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
+ intel_de_write(dev_priv, PORT_DFT2_G4X(dev_priv), tmp);
}
return 0;
@@ -229,7 +230,7 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
- u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
+ u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X(dev_priv));
switch (pipe) {
case PIPE_A:
@@ -246,7 +247,7 @@ static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
}
if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
tmp &= ~DC_BALANCE_RESET_VLV;
- intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
+ intel_de_write(dev_priv, PORT_DFT2_G4X(dev_priv), tmp);
}
static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
@@ -608,8 +609,8 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name)
goto out;
pipe_crc->source = source;
- intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
- intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
+ intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe));
if (!source) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
@@ -643,8 +644,8 @@ void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
/* Don't need pipe_crc->lock here, IRQs are not generated. */
pipe_crc->skipped = 0;
- intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
- intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
+ intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe));
}
void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
@@ -658,7 +659,7 @@ void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
pipe_crc->skipped = INT_MIN;
spin_unlock_irq(&pipe_crc->lock);
- intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), 0);
- intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
+ intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), 0);
+ intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe));
intel_synchronize_irq(dev_priv);
}
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h b/drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h
new file mode 100644
index 000000000000..4e65f51d34e6
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_PIPE_CRC_REGS_H__
+#define __INTEL_PIPE_CRC_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _PIPE_CRC_CTL_A 0x60050
+#define PIPE_CRC_CTL(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_CTL_A)
+#define PIPE_CRC_ENABLE REG_BIT(31)
+/* skl+ source selection */
+#define PIPE_CRC_SOURCE_MASK_SKL REG_GENMASK(30, 28)
+#define PIPE_CRC_SOURCE_PLANE_1_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 0)
+#define PIPE_CRC_SOURCE_PLANE_2_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 2)
+#define PIPE_CRC_SOURCE_DMUX_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 4)
+#define PIPE_CRC_SOURCE_PLANE_3_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 6)
+#define PIPE_CRC_SOURCE_PLANE_4_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 7)
+#define PIPE_CRC_SOURCE_PLANE_5_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 5)
+#define PIPE_CRC_SOURCE_PLANE_6_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 3)
+#define PIPE_CRC_SOURCE_PLANE_7_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 1)
+/* ivb+ source selection */
+#define PIPE_CRC_SOURCE_MASK_IVB REG_GENMASK(30, 29)
+#define PIPE_CRC_SOURCE_PRIMARY_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 0)
+#define PIPE_CRC_SOURCE_SPRITE_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 1)
+#define PIPE_CRC_SOURCE_PF_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 2)
+/* ilk+ source selection */
+#define PIPE_CRC_SOURCE_MASK_ILK REG_GENMASK(30, 28)
+#define PIPE_CRC_SOURCE_PRIMARY_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 0)
+#define PIPE_CRC_SOURCE_SPRITE_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 1)
+#define PIPE_CRC_SOURCE_PIPE_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 2)
+/* embedded DP port on the north display block */
+#define PIPE_CRC_SOURCE_PORT_A_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 4)
+#define PIPE_CRC_SOURCE_FDI_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 5)
+/* vlv source selection */
+#define PIPE_CRC_SOURCE_MASK_VLV REG_GENMASK(30, 27)
+#define PIPE_CRC_SOURCE_PIPE_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 0)
+#define PIPE_CRC_SOURCE_HDMIB_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 1)
+#define PIPE_CRC_SOURCE_HDMIC_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 2)
+/* with DP port the pipe source is invalid */
+#define PIPE_CRC_SOURCE_DP_D_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 3)
+#define PIPE_CRC_SOURCE_DP_B_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 6)
+#define PIPE_CRC_SOURCE_DP_C_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 7)
+/* gen3+ source selection */
+#define PIPE_CRC_SOURCE_MASK_I9XX REG_GENMASK(30, 28)
+#define PIPE_CRC_SOURCE_PIPE_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 0)
+#define PIPE_CRC_SOURCE_SDVOB_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 1)
+#define PIPE_CRC_SOURCE_SDVOC_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 2)
+/* with DP/TV port the pipe source is invalid */
+#define PIPE_CRC_SOURCE_DP_D_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 3)
+#define PIPE_CRC_SOURCE_TV_PRE REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 4)
+#define PIPE_CRC_SOURCE_TV_POST REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 5)
+#define PIPE_CRC_SOURCE_DP_B_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 6)
+#define PIPE_CRC_SOURCE_DP_C_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 7)
+/* gen2 doesn't have source selection bits */
+#define PIPE_CRC_INCLUDE_BORDER_I8XX REG_BIT(30)
+#define PIPE_CRC_EXP_RED_MASK REG_BIT(22, 0) /* pre-ivb */
+#define PIPE_CRC_EXP_1_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+#define _PIPE_CRC_EXP_GREEN_A 0x60054
+#define PIPE_CRC_EXP_GREEN(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_GREEN_A)
+#define PIPE_CRC_EXP_GREEN_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_EXP_BLUE_A 0x60058
+#define PIPE_CRC_EXP_BLUE(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_BLUE_A)
+#define PIPE_CRC_EXP_BLUE_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_EXP_RES1_A_I915 0x6005c /* i915+ */
+#define PIPE_CRC_EXP_RES1_I915(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_RES1_A_I915)
+#define PIPE_CRC_EXP_RES1_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_EXP_RES2_A_G4X 0x60080 /* g4x+ */
+#define PIPE_CRC_EXP_RES2_G4X(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_RES2_A_G4X)
+#define PIPE_CRC_EXP_RES2_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_RES_RED_A 0x60060
+#define PIPE_CRC_RES_RED(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_RED_A)
+
+#define _PIPE_CRC_RES_GREEN_A 0x60064
+#define PIPE_CRC_RES_GREEN(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_GREEN_A)
+
+#define _PIPE_CRC_RES_BLUE_A 0x60068
+#define PIPE_CRC_RES_BLUE(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_BLUE_A)
+
+#define _PIPE_CRC_RES_RES1_A_I915 0x6006c /* i915+ */
+#define PIPE_CRC_RES_RES1_I915(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_RES1_A_I915)
+
+#define _PIPE_CRC_RES_RES2_A_G4X 0x60080 /* g4x+ */
+#define PIPE_CRC_RES_RES2_G4X(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_RES2_A_G4X)
+
+/* ivb */
+#define _PIPE_CRC_EXP_2_A_IVB 0x60054
+#define _PIPE_CRC_EXP_2_B_IVB 0x61054
+#define PIPE_CRC_EXP_2_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_2_A_IVB, _PIPE_CRC_EXP_2_B_IVB)
+#define PIPE_CRC_EXP_2_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_EXP_3_A_IVB 0x60058
+#define _PIPE_CRC_EXP_3_B_IVB 0x61058
+#define PIPE_CRC_EXP_3_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_3_A_IVB, _PIPE_CRC_EXP_3_B_IVB)
+#define PIPE_CRC_EXP_3_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_EXP_4_A_IVB 0x6005c
+#define _PIPE_CRC_EXP_4_B_IVB 0x6105c
+#define PIPE_CRC_EXP_4_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_2_A_IVB, _PIPE_CRC_EXP_2_B_IVB)
+#define PIPE_CRC_EXP_4_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_EXP_5_A_IVB 0x60060
+#define _PIPE_CRC_EXP_5_B_IVB 0x61060
+#define PIPE_CRC_EXP_5_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_2_A_IVB, _PIPE_CRC_EXP_2_B_IVB)
+#define PIPE_CRC_EXP_5_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_RES_1_A_IVB 0x60064
+#define _PIPE_CRC_RES_1_B_IVB 0x61064
+#define PIPE_CRC_RES_1_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_1_A_IVB, _PIPE_CRC_RES_1_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_2_A_IVB 0x60068
+#define _PIPE_CRC_RES_2_B_IVB 0x61068
+#define PIPE_CRC_RES_2_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_2_A_IVB, _PIPE_CRC_RES_2_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_3_A_IVB 0x6006c
+#define _PIPE_CRC_RES_3_B_IVB 0x6106c
+#define PIPE_CRC_RES_3_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_3_A_IVB, _PIPE_CRC_RES_3_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_4_A_IVB 0x60070
+#define _PIPE_CRC_RES_4_B_IVB 0x61070
+#define PIPE_CRC_RES_4_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_4_A_IVB, _PIPE_CRC_RES_4_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_5_A_IVB 0x60074
+#define _PIPE_CRC_RES_5_B_IVB 0x61074
+#define PIPE_CRC_RES_5_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_5_A_IVB, _PIPE_CRC_RES_5_B_IVB)
+
+/* hsw+ */
+#define _PIPE_CRC_EXP_A_HSW 0x60054
+#define _PIPE_CRC_EXP_B_HSW 0x61054
+#define PIPE_CRC_EXP_HSW(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_EXP_A_HSW, _PIPE_CRC_EXP_B_HSW)
+
+/* hsw+ */
+#define _PIPE_CRC_RES_A_HSW 0x60064
+#define _PIPE_CRC_RES_B_HSW 0x61064
+#define PIPE_CRC_RES_HSW(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_A_HSW, _PIPE_CRC_RES_B_HSW)
+
+#endif /* __INTEL_PIPE_CRC_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index 0ccbf9a85914..42306bc4ba86 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -119,7 +119,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
else
DP |= DP_PIPE_SEL(pipe);
- pll_enabled = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE;
+ pll_enabled = intel_de_read(dev_priv, DPLL(dev_priv, pipe)) & DPLL_VCO_ENABLE;
/*
* The DPLL for the pipe must be enabled for this to work.
@@ -272,12 +272,12 @@ typedef bool (*pps_check)(struct drm_i915_private *dev_priv, int pps_idx);
static bool pps_has_pp_on(struct drm_i915_private *dev_priv, int pps_idx)
{
- return intel_de_read(dev_priv, PP_STATUS(pps_idx)) & PP_ON;
+ return intel_de_read(dev_priv, PP_STATUS(dev_priv, pps_idx)) & PP_ON;
}
static bool pps_has_vdd_on(struct drm_i915_private *dev_priv, int pps_idx)
{
- return intel_de_read(dev_priv, PP_CONTROL(pps_idx)) & EDP_FORCE_VDD;
+ return intel_de_read(dev_priv, PP_CONTROL(dev_priv, pps_idx)) & EDP_FORCE_VDD;
}
static bool pps_any(struct drm_i915_private *dev_priv, int pps_idx)
@@ -292,7 +292,7 @@ vlv_initial_pps_pipe(struct drm_i915_private *dev_priv,
enum pipe pipe;
for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
- u32 port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(pipe)) &
+ u32 port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, pipe)) &
PANEL_PORT_SELECT_MASK;
if (port_sel != PANEL_PORT_SELECT_VLV(port))
@@ -491,17 +491,17 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
else
pps_idx = intel_dp->pps.pps_idx;
- regs->pp_ctrl = PP_CONTROL(pps_idx);
- regs->pp_stat = PP_STATUS(pps_idx);
- regs->pp_on = PP_ON_DELAYS(pps_idx);
- regs->pp_off = PP_OFF_DELAYS(pps_idx);
+ regs->pp_ctrl = PP_CONTROL(dev_priv, pps_idx);
+ regs->pp_stat = PP_STATUS(dev_priv, pps_idx);
+ regs->pp_on = PP_ON_DELAYS(dev_priv, pps_idx);
+ regs->pp_off = PP_OFF_DELAYS(dev_priv, pps_idx);
/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
regs->pp_div = INVALID_MMIO_REG;
else
- regs->pp_div = PP_DIVISOR(pps_idx);
+ regs->pp_div = PP_DIVISOR(dev_priv, pps_idx);
}
static i915_reg_t
@@ -1111,7 +1111,7 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum pipe pipe = intel_dp->pps.pps_pipe;
- i915_reg_t pp_on_reg = PP_ON_DELAYS(pipe);
+ i915_reg_t pp_on_reg = PP_ON_DELAYS(dev_priv, pipe);
drm_WARN_ON(&dev_priv->drm, intel_dp->pps.active_pipe != INVALID_PIPE);
@@ -1656,7 +1656,7 @@ void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv)
pps_num = intel_num_pps(dev_priv);
for (pps_idx = 0; pps_idx < pps_num; pps_idx++)
- intel_de_rmw(dev_priv, PP_CONTROL(pps_idx),
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, pps_idx),
PANEL_UNLOCK_MASK, PANEL_UNLOCK_REGS);
}
@@ -1714,8 +1714,8 @@ void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
if (HAS_PCH_SPLIT(dev_priv)) {
u32 port_sel;
- pp_reg = PP_CONTROL(0);
- port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
+ pp_reg = PP_CONTROL(dev_priv, 0);
+ port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0)) & PANEL_PORT_SELECT_MASK;
switch (port_sel) {
case PANEL_PORT_SELECT_LVDS:
@@ -1736,13 +1736,13 @@ void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
}
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
/* presumably write lock depends on pipe, not port select */
- pp_reg = PP_CONTROL(pipe);
+ pp_reg = PP_CONTROL(dev_priv, pipe);
panel_pipe = pipe;
} else {
u32 port_sel;
- pp_reg = PP_CONTROL(0);
- port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
+ pp_reg = PP_CONTROL(dev_priv, 0);
+ port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0)) & PANEL_PORT_SELECT_MASK;
drm_WARN_ON(&dev_priv->drm,
port_sel != PANEL_PORT_SELECT_LVDS);
diff --git a/drivers/gpu/drm/i915/display/intel_pps_regs.h b/drivers/gpu/drm/i915/display/intel_pps_regs.h
index 60edd2a27100..8f9dbfab9523 100644
--- a/drivers/gpu/drm/i915/display/intel_pps_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_pps_regs.h
@@ -6,6 +6,7 @@
#ifndef __INTEL_PPS_REGS_H__
#define __INTEL_PPS_REGS_H__
+#include "intel_display_conversion.h"
#include "intel_display_reg_defs.h"
/* Panel power sequencing */
@@ -13,12 +14,11 @@
#define VLV_PPS_BASE (VLV_DISPLAY_BASE + PPS_BASE)
#define PCH_PPS_BASE 0xC7200
-#define _MMIO_PPS(pps_idx, reg) _MMIO(dev_priv->display.pps.mmio_base - \
- PPS_BASE + (reg) + \
- (pps_idx) * 0x100)
+#define _MMIO_PPS(dev_priv, pps_idx, reg) \
+ _MMIO(__to_intel_display(dev_priv)->pps.mmio_base - PPS_BASE + (reg) + (pps_idx) * 0x100)
#define _PP_STATUS 0x61200
-#define PP_STATUS(pps_idx) _MMIO_PPS(pps_idx, _PP_STATUS)
+#define PP_STATUS(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_STATUS)
#define PP_ON REG_BIT(31)
/*
* Indicates that all dependencies of the panel are on:
@@ -45,7 +45,7 @@
#define PP_SEQUENCE_STATE_RESET REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xf)
#define _PP_CONTROL 0x61204
-#define PP_CONTROL(pps_idx) _MMIO_PPS(pps_idx, _PP_CONTROL)
+#define PP_CONTROL(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_CONTROL)
#define PANEL_UNLOCK_MASK REG_GENMASK(31, 16)
#define PANEL_UNLOCK_REGS REG_FIELD_PREP(PANEL_UNLOCK_MASK, 0xabcd)
#define BXT_POWER_CYCLE_DELAY_MASK REG_GENMASK(8, 4)
@@ -55,7 +55,7 @@
#define PANEL_POWER_ON REG_BIT(0)
#define _PP_ON_DELAYS 0x61208
-#define PP_ON_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_ON_DELAYS)
+#define PP_ON_DELAYS(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_ON_DELAYS)
#define PANEL_PORT_SELECT_MASK REG_GENMASK(31, 30)
#define PANEL_PORT_SELECT_LVDS REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 0)
#define PANEL_PORT_SELECT_DPA REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 1)
@@ -66,12 +66,12 @@
#define PANEL_LIGHT_ON_DELAY_MASK REG_GENMASK(12, 0)
#define _PP_OFF_DELAYS 0x6120C
-#define PP_OFF_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_OFF_DELAYS)
+#define PP_OFF_DELAYS(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_OFF_DELAYS)
#define PANEL_POWER_DOWN_DELAY_MASK REG_GENMASK(28, 16)
#define PANEL_LIGHT_OFF_DELAY_MASK REG_GENMASK(12, 0)
#define _PP_DIVISOR 0x61210
-#define PP_DIVISOR(pps_idx) _MMIO_PPS(pps_idx, _PP_DIVISOR)
+#define PP_DIVISOR(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_DIVISOR)
#define PP_REFERENCE_DIVIDER_MASK REG_GENMASK(31, 8)
#define PANEL_POWER_CYCLE_DELAY_MASK REG_GENMASK(4, 0)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index f5b33335a9ae..9cb1cdaaeefa 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -27,8 +27,10 @@
#include "i915_drv.h"
#include "i915_reg.h"
+#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
+#include "intel_cursor_regs.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -233,6 +235,26 @@ static bool psr2_global_enabled(struct intel_dp *intel_dp)
}
}
+static bool psr2_su_region_et_global_enabled(struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ if (i915->display.params.enable_psr != -1)
+ return false;
+
+ return true;
+}
+
+static bool panel_replay_global_enabled(struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ if ((i915->display.params.enable_psr != -1) ||
+ (intel_dp->psr.debug & I915_PSR_DEBUG_PANEL_REPLAY_DISABLE))
+ return false;
+ return true;
+}
+
static u32 psr_irq_psr_error_bit_get(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -269,7 +291,7 @@ static i915_reg_t psr_ctl_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_CTL(cpu_transcoder);
+ return EDP_PSR_CTL(dev_priv, cpu_transcoder);
else
return HSW_SRD_CTL;
}
@@ -278,7 +300,7 @@ static i915_reg_t psr_debug_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_DEBUG(cpu_transcoder);
+ return EDP_PSR_DEBUG(dev_priv, cpu_transcoder);
else
return HSW_SRD_DEBUG;
}
@@ -287,7 +309,7 @@ static i915_reg_t psr_perf_cnt_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_PERF_CNT(cpu_transcoder);
+ return EDP_PSR_PERF_CNT(dev_priv, cpu_transcoder);
else
return HSW_SRD_PERF_CNT;
}
@@ -296,7 +318,7 @@ static i915_reg_t psr_status_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_STATUS(cpu_transcoder);
+ return EDP_PSR_STATUS(dev_priv, cpu_transcoder);
else
return HSW_SRD_STATUS;
}
@@ -305,7 +327,7 @@ static i915_reg_t psr_imr_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 12)
- return TRANS_PSR_IMR(cpu_transcoder);
+ return TRANS_PSR_IMR(dev_priv, cpu_transcoder);
else
return EDP_PSR_IMR;
}
@@ -314,7 +336,7 @@ static i915_reg_t psr_iir_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 12)
- return TRANS_PSR_IIR(cpu_transcoder);
+ return TRANS_PSR_IIR(dev_priv, cpu_transcoder);
else
return EDP_PSR_IIR;
}
@@ -323,7 +345,7 @@ static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_AUX_CTL(cpu_transcoder);
+ return EDP_PSR_AUX_CTL(dev_priv, cpu_transcoder);
else
return HSW_SRD_AUX_CTL;
}
@@ -332,7 +354,7 @@ static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder, int i)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_AUX_DATA(cpu_transcoder, i);
+ return EDP_PSR_AUX_DATA(dev_priv, cpu_transcoder, i);
else
return HSW_SRD_AUX_DATA(i);
}
@@ -356,12 +378,12 @@ static void psr_irq_control(struct intel_dp *intel_dp)
}
static void psr_event_print(struct drm_i915_private *i915,
- u32 val, bool psr2_enabled)
+ u32 val, bool sel_update_enabled)
{
drm_dbg_kms(&i915->drm, "PSR exit events: 0x%x\n", val);
if (val & PSR_EVENT_PSR2_WD_TIMER_EXPIRE)
drm_dbg_kms(&i915->drm, "\tPSR2 watchdog timer expired\n");
- if ((val & PSR_EVENT_PSR2_DISABLED) && psr2_enabled)
+ if ((val & PSR_EVENT_PSR2_DISABLED) && sel_update_enabled)
drm_dbg_kms(&i915->drm, "\tPSR2 disabled\n");
if (val & PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN)
drm_dbg_kms(&i915->drm, "\tSU dirty FIFO underrun\n");
@@ -389,7 +411,7 @@ static void psr_event_print(struct drm_i915_private *i915,
drm_dbg_kms(&i915->drm, "\tVBI enabled\n");
if (val & PSR_EVENT_LPSP_MODE_EXIT)
drm_dbg_kms(&i915->drm, "\tLPSP mode exited\n");
- if ((val & PSR_EVENT_PSR_DISABLE) && !psr2_enabled)
+ if ((val & PSR_EVENT_PSR_DISABLE) && !sel_update_enabled)
drm_dbg_kms(&i915->drm, "\tPSR disabled\n");
}
@@ -415,9 +437,11 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
if (DISPLAY_VER(dev_priv) >= 9) {
u32 val;
- val = intel_de_rmw(dev_priv, PSR_EVENT(cpu_transcoder), 0, 0);
+ val = intel_de_rmw(dev_priv,
+ PSR_EVENT(dev_priv, cpu_transcoder),
+ 0, 0);
- psr_event_print(dev_priv, val, intel_dp->psr.psr2_enabled);
+ psr_event_print(dev_priv, val, intel_dp->psr.sel_update_enabled);
}
}
@@ -442,16 +466,6 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
}
}
-static bool intel_dp_get_alpm_status(struct intel_dp *intel_dp)
-{
- u8 alpm_caps = 0;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP,
- &alpm_caps) != 1)
- return false;
- return alpm_caps & DP_ALPM_CAP;
-}
-
static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -466,6 +480,40 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
return val;
}
+static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp)
+{
+ u8 su_capability = 0;
+
+ if (intel_dp->psr.sink_panel_replay_su_support)
+ drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_PANEL_PANEL_REPLAY_CAPABILITY,
+ &su_capability);
+ else
+ su_capability = intel_dp->psr_dpcd[1];
+
+ return su_capability;
+}
+
+static unsigned int
+intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp)
+{
+ return intel_dp->psr.sink_panel_replay_su_support ?
+ DP_PANEL_PANEL_REPLAY_X_GRANULARITY :
+ DP_PSR2_SU_X_GRANULARITY;
+}
+
+static unsigned int
+intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp)
+{
+ return intel_dp->psr.sink_panel_replay_su_support ?
+ DP_PANEL_PANEL_REPLAY_Y_GRANULARITY :
+ DP_PSR2_SU_Y_GRANULARITY;
+}
+
+/*
+ * Note: Bits related to granularity are same in panel replay and psr
+ * registers. Rely on PSR definitions on these "common" bits.
+ */
static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -473,18 +521,29 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
u16 w;
u8 y;
- /* If sink don't have specific granularity requirements set legacy ones */
- if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED)) {
+ /*
+ * TODO: Do we need to take into account panel supporting both PSR and
+ * Panel replay?
+ */
+
+ /*
+ * If sink don't have specific granularity requirements set legacy
+ * ones.
+ */
+ if (!(intel_dp_get_su_capability(intel_dp) &
+ DP_PSR2_SU_GRANULARITY_REQUIRED)) {
/* As PSR2 HW sends full lines, we do not care about x granularity */
w = 4;
y = 4;
goto exit;
}
- r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, 2);
+ r = drm_dp_dpcd_read(&intel_dp->aux,
+ intel_dp_get_su_x_granularity_offset(intel_dp),
+ &w, 2);
if (r != 2)
drm_dbg_kms(&i915->drm,
- "Unable to read DP_PSR2_SU_X_GRANULARITY\n");
+ "Unable to read selective update x granularity\n");
/*
* Spec says that if the value read is 0 the default granularity should
* be used instead.
@@ -492,10 +551,12 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
if (r != 2 || w == 0)
w = 4;
- r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1);
+ r = drm_dp_dpcd_read(&intel_dp->aux,
+ intel_dp_get_su_y_granularity_offset(intel_dp),
+ &y, 1);
if (r != 1) {
drm_dbg_kms(&i915->drm,
- "Unable to read DP_PSR2_SU_Y_GRANULARITY\n");
+ "Unable to read selective update y granularity\n");
y = 4;
}
if (y == 0)
@@ -509,20 +570,30 @@ exit:
static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 pr_dpcd = 0;
- intel_dp->psr.sink_panel_replay_support = false;
- drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP, &pr_dpcd);
+ if (intel_dp_is_edp(intel_dp)) {
+ if (!intel_alpm_aux_less_wake_supported(intel_dp)) {
+ drm_dbg_kms(&i915->drm,
+ "Panel doesn't support AUX-less ALPM, eDP Panel Replay not possible\n");
+ return;
+ }
- if (!(pr_dpcd & DP_PANEL_REPLAY_SUPPORT)) {
- drm_dbg_kms(&i915->drm,
- "Panel replay is not supported by panel\n");
- return;
+ if (!(intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)) {
+ drm_dbg_kms(&i915->drm,
+ "Panel doesn't support early transport, eDP Panel Replay not possible\n");
+ return;
+ }
}
- drm_dbg_kms(&i915->drm,
- "Panel replay is supported by panel\n");
intel_dp->psr.sink_panel_replay_support = true;
+
+ if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_SU_SUPPORT)
+ intel_dp->psr.sink_panel_replay_su_support = true;
+
+ drm_dbg_kms(&i915->drm,
+ "Panel replay %sis supported by panel\n",
+ intel_dp->psr.sink_panel_replay_su_support ?
+ "selective_update " : "");
}
static void _psr_init_dpcd(struct intel_dp *intel_dp)
@@ -553,7 +624,6 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
intel_dp->psr_dpcd[0] >= DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) {
bool y_req = intel_dp->psr_dpcd[1] &
DP_PSR2_SU_Y_COORDINATE_REQUIRED;
- bool alpm = intel_dp_get_alpm_status(intel_dp);
/*
* All panels that supports PSR version 03h (PSR2 +
@@ -566,7 +636,8 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
* Y-coordinate requirement panels we would need to enable
* GTC first.
*/
- intel_dp->psr.sink_psr2_support = y_req && alpm;
+ intel_dp->psr.sink_psr2_support = y_req &&
+ intel_alpm_aux_wake_supported(intel_dp);
drm_dbg_kms(&i915->drm, "PSR2 %ssupported\n",
intel_dp->psr.sink_psr2_support ? "" : "not ");
}
@@ -574,15 +645,19 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
void intel_psr_init_dpcd(struct intel_dp *intel_dp)
{
- _panel_replay_init_dpcd(intel_dp);
-
drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd,
sizeof(intel_dp->psr_dpcd));
+ drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP,
+ &intel_dp->pr_dpcd);
+
+ if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_SUPPORT)
+ _panel_replay_init_dpcd(intel_dp);
if (intel_dp->psr_dpcd[0])
_psr_init_dpcd(intel_dp);
- if (intel_dp->psr.sink_psr2_support)
+ if (intel_dp->psr.sink_psr2_support ||
+ intel_dp->psr.sink_panel_replay_su_support)
intel_dp_get_su_granularity(intel_dp);
}
@@ -623,68 +698,103 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
aux_ctl);
}
-static bool psr2_su_region_et_valid(struct intel_dp *intel_dp)
+static bool psr2_su_region_et_valid(struct intel_dp *intel_dp, bool panel_replay)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- if (DISPLAY_VER(i915) >= 20 &&
- intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED &&
- !(intel_dp->psr.debug & I915_PSR_DEBUG_SU_REGION_ET_DISABLE))
- return true;
+ if (DISPLAY_VER(i915) < 20 || !intel_dp_is_edp(intel_dp) ||
+ intel_dp->psr.debug & I915_PSR_DEBUG_SU_REGION_ET_DISABLE)
+ return false;
- return false;
+ return panel_replay ?
+ intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT :
+ intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED &&
+ psr2_su_region_et_global_enabled(intel_dp);
}
-static unsigned int intel_psr_get_enable_sink_offset(struct intel_dp *intel_dp)
+static void _panel_replay_enable_sink(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
- return intel_dp->psr.panel_replay_enabled ?
- PANEL_REPLAY_CONFIG : DP_PSR_EN_CFG;
-}
+ u8 val = DP_PANEL_REPLAY_ENABLE |
+ DP_PANEL_REPLAY_VSC_SDP_CRC_EN |
+ DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN |
+ DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN |
+ DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN;
+ u8 panel_replay_config2 = DP_PANEL_REPLAY_CRC_VERIFICATION;
-/*
- * Note: Most of the bits are same in PANEL_REPLAY_CONFIG and DP_PSR_EN_CFG. We
- * are relying on PSR definitions on these "common" bits.
- */
-void intel_psr_enable_sink(struct intel_dp *intel_dp,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- u8 dpcd_val = DP_PSR_ENABLE;
+ if (crtc_state->has_sel_update)
+ val |= DP_PANEL_REPLAY_SU_ENABLE;
- if (crtc_state->has_psr2) {
- /* Enable ALPM at sink for psr2 */
- if (!crtc_state->has_panel_replay) {
- drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_RECEIVER_ALPM_CONFIG,
- DP_ALPM_ENABLE |
- DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
+ if (crtc_state->enable_psr2_su_region_et)
+ val |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET;
- if (psr2_su_region_et_valid(intel_dp))
- dpcd_val |= DP_PSR_ENABLE_SU_REGION_ET;
- }
+ if (crtc_state->req_psr2_sdp_prior_scanline)
+ panel_replay_config2 |=
+ DP_PANEL_REPLAY_SU_REGION_SCANLINE_CAPTURE;
+
+ drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG, val);
- dpcd_val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
+ drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG2,
+ panel_replay_config2);
+}
+
+static void _psr_enable_sink(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ u8 val = DP_PSR_ENABLE;
+
+ if (crtc_state->has_sel_update) {
+ val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
} else {
if (intel_dp->psr.link_standby)
- dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
+ val |= DP_PSR_MAIN_LINK_ACTIVE;
- if (!crtc_state->has_panel_replay && DISPLAY_VER(dev_priv) >= 8)
- dpcd_val |= DP_PSR_CRC_VERIFICATION;
+ if (DISPLAY_VER(i915) >= 8)
+ val |= DP_PSR_CRC_VERIFICATION;
}
- if (crtc_state->has_panel_replay)
- dpcd_val |= DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN |
- DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN;
-
if (crtc_state->req_psr2_sdp_prior_scanline)
- dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
+ val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
+
+ if (crtc_state->enable_psr2_su_region_et)
+ val |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET;
if (intel_dp->psr.entry_setup_frames > 0)
- dpcd_val |= DP_PSR_FRAME_CAPTURE;
+ val |= DP_PSR_FRAME_CAPTURE;
+
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
+}
+
+static void intel_psr_enable_sink_alpm(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ u8 val;
+
+ /*
+ * eDP Panel Replay uses always ALPM
+ * PSR2 uses ALPM but PSR1 doesn't
+ */
+ if (!intel_dp_is_edp(intel_dp) || (!crtc_state->has_panel_replay &&
+ !crtc_state->has_sel_update))
+ return;
+
+ val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE;
+
+ if (crtc_state->has_panel_replay)
+ val |= DP_ALPM_MODE_AUX_LESS;
+
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
+}
- drm_dp_dpcd_writeb(&intel_dp->aux,
- intel_psr_get_enable_sink_offset(intel_dp),
- dpcd_val);
+void intel_psr_enable_sink(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ intel_psr_enable_sink_alpm(intel_dp, crtc_state);
+
+ crtc_state->has_panel_replay ?
+ _panel_replay_enable_sink(intel_dp, crtc_state) :
+ _psr_enable_sink(intel_dp, crtc_state);
if (intel_dp_is_edp(intel_dp))
drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
@@ -814,8 +924,8 @@ static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
static int psr2_block_count_lines(struct intel_dp *intel_dp)
{
- return intel_dp->psr.alpm_parameters.io_wake_lines < 9 &&
- intel_dp->psr.alpm_parameters.fast_wake_lines < 9 ? 8 : 12;
+ return intel_dp->alpm_parameters.io_wake_lines < 9 &&
+ intel_dp->alpm_parameters.fast_wake_lines < 9 ? 8 : 12;
}
static int psr2_block_count(struct intel_dp *intel_dp)
@@ -841,8 +951,22 @@ static u8 frames_before_su_entry(struct intel_dp *intel_dp)
static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ struct intel_psr *psr = &intel_dp->psr;
+ enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
- intel_de_rmw(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
+ if (intel_dp_is_edp(intel_dp) && psr->sel_update_enabled) {
+ u32 val = psr->su_region_et_enabled ?
+ LNL_EDP_PSR2_SU_REGION_ET_ENABLE : 0;
+
+ if (intel_dp->psr.req_psr2_sdp_prior_scanline)
+ val |= EDP_PSR2_SU_SDP_SCANLINE;
+
+ intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder),
+ val);
+ }
+
+ intel_de_rmw(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, intel_dp->psr.transcoder),
0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
intel_de_rmw(dev_priv, TRANS_DP2_CTL(intel_dp->psr.transcoder), 0,
@@ -852,7 +976,6 @@ static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
static void hsw_activate_psr2(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- struct intel_psr *psr = &intel_dp->psr;
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
u32 val = EDP_PSR2_ENABLE;
u32 psr_val = 0;
@@ -869,7 +992,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
val |= intel_psr2_get_tp_time(intel_dp);
- if (DISPLAY_VER(dev_priv) >= 12) {
+ if (DISPLAY_VER(dev_priv) >= 12 && DISPLAY_VER(dev_priv) < 20) {
if (psr2_block_count(intel_dp) > 2)
val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_3;
else
@@ -894,18 +1017,20 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
*/
int tmp;
- tmp = map[psr->alpm_parameters.io_wake_lines -
+ tmp = map[intel_dp->alpm_parameters.io_wake_lines -
TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(tmp + TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES);
- tmp = map[psr->alpm_parameters.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
+ tmp = map[intel_dp->alpm_parameters.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
val |= TGL_EDP_PSR2_FAST_WAKE(tmp + TGL_EDP_PSR2_FAST_WAKE_MIN_LINES);
+ } else if (DISPLAY_VER(dev_priv) >= 20) {
+ val |= LNL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->alpm_parameters.io_wake_lines);
} else if (DISPLAY_VER(dev_priv) >= 12) {
- val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines);
- val |= TGL_EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines);
+ val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->alpm_parameters.io_wake_lines);
+ val |= TGL_EDP_PSR2_FAST_WAKE(intel_dp->alpm_parameters.fast_wake_lines);
} else if (DISPLAY_VER(dev_priv) >= 9) {
- val |= EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines);
- val |= EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines);
+ val |= EDP_PSR2_IO_BUFFER_WAKE(intel_dp->alpm_parameters.io_wake_lines);
+ val |= EDP_PSR2_FAST_WAKE(intel_dp->alpm_parameters.fast_wake_lines);
}
if (intel_dp->psr.req_psr2_sdp_prior_scanline)
@@ -917,13 +1042,15 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
if (intel_dp->psr.psr2_sel_fetch_enabled) {
u32 tmp;
- tmp = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder));
drm_WARN_ON(&dev_priv->drm, !(tmp & PSR2_MAN_TRK_CTL_ENABLE));
} else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder), 0);
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder), 0);
}
- if (psr2_su_region_et_valid(intel_dp))
+ if (intel_dp->psr.su_region_et_enabled)
val |= LNL_EDP_PSR2_SU_REGION_ET_ENABLE;
/*
@@ -932,7 +1059,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
*/
intel_de_write(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder), psr_val);
- intel_de_write(dev_priv, EDP_PSR2_CTL(cpu_transcoder), val);
+ intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder), val);
}
static bool
@@ -963,7 +1090,7 @@ static void psr2_program_idle_frames(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
- intel_de_rmw(dev_priv, EDP_PSR2_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder),
EDP_PSR2_IDLE_FRAMES_MASK,
EDP_PSR2_IDLE_FRAMES(idle_frames));
}
@@ -1088,9 +1215,6 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (psr2_su_region_et_valid(intel_dp))
- crtc_state->enable_psr2_su_region_et = true;
-
return crtc_state->enable_psr2_sel_fetch = true;
}
@@ -1161,237 +1285,6 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d
return true;
}
-/*
- * See Bspec: 71632 for the table
- *
- * Silence_period = tSilence,Min + ((tSilence,Max - tSilence,Min) / 2)
- *
- * Half cycle duration:
- *
- * Link rates 1.62 - 4.32 and tLFPS_Cycle = 70 ns
- * FLOOR( (Link Rate * tLFPS_Cycle) / (2 * 10) )
- *
- * Link rates 5.4 - 8.1
- * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ] = 10
- * LFPS Period chosen is the mid-point of the min:max values from the table
- * FLOOR( LFPS Period in Symbol clocks /
- * (2 * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ]) )
- */
-static bool _lnl_get_silence_period_and_lfps_half_cycle(int link_rate,
- int *silence_period,
- int *lfps_half_cycle)
-{
- switch (link_rate) {
- case 162000:
- *silence_period = 20;
- *lfps_half_cycle = 5;
- break;
- case 216000:
- *silence_period = 27;
- *lfps_half_cycle = 7;
- break;
- case 243000:
- *silence_period = 31;
- *lfps_half_cycle = 8;
- break;
- case 270000:
- *silence_period = 34;
- *lfps_half_cycle = 9;
- break;
- case 324000:
- *silence_period = 41;
- *lfps_half_cycle = 11;
- break;
- case 432000:
- *silence_period = 56;
- *lfps_half_cycle = 15;
- break;
- case 540000:
- *silence_period = 69;
- *lfps_half_cycle = 12;
- break;
- case 648000:
- *silence_period = 84;
- *lfps_half_cycle = 15;
- break;
- case 675000:
- *silence_period = 87;
- *lfps_half_cycle = 15;
- break;
- case 810000:
- *silence_period = 104;
- *lfps_half_cycle = 19;
- break;
- default:
- *silence_period = *lfps_half_cycle = -1;
- return false;
- }
- return true;
-}
-
-/*
- * AUX-Less Wake Time = CEILING( ((PHY P2 to P0) + tLFPS_Period, Max+
- * tSilence, Max+ tPHY Establishment + tCDS) / tline)
- * For the "PHY P2 to P0" latency see the PHY Power Control page
- * (PHY P2 to P0) : https://gfxspecs.intel.com/Predator/Home/Index/68965
- * : 12 us
- * The tLFPS_Period, Max term is 800ns
- * The tSilence, Max term is 180ns
- * The tPHY Establishment (a.k.a. t1) term is 50us
- * The tCDS term is 1 or 2 times t2
- * t2 = Number ML_PHY_LOCK * tML_PHY_LOCK
- * Number ML_PHY_LOCK = ( 7 + CEILING( 6.5us / tML_PHY_LOCK ) + 1)
- * Rounding up the 6.5us padding to the next ML_PHY_LOCK boundary and
- * adding the "+ 1" term ensures all ML_PHY_LOCK sequences that start
- * within the CDS period complete within the CDS period regardless of
- * entry into the period
- * tML_PHY_LOCK = TPS4 Length * ( 10 / (Link Rate in MHz) )
- * TPS4 Length = 252 Symbols
- */
-static int _lnl_compute_aux_less_wake_time(int port_clock)
-{
- int tphy2_p2_to_p0 = 12 * 1000;
- int tlfps_period_max = 800;
- int tsilence_max = 180;
- int t1 = 50 * 1000;
- int tps4 = 252;
- int tml_phy_lock = 1000 * 1000 * tps4 * 10 / port_clock;
- int num_ml_phy_lock = 7 + DIV_ROUND_UP(6500, tml_phy_lock) + 1;
- int t2 = num_ml_phy_lock * tml_phy_lock;
- int tcds = 1 * t2;
-
- return DIV_ROUND_UP(tphy2_p2_to_p0 + tlfps_period_max + tsilence_max +
- t1 + tcds, 1000);
-}
-
-static int _lnl_compute_aux_less_alpm_params(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int aux_less_wake_time, aux_less_wake_lines, silence_period,
- lfps_half_cycle;
-
- aux_less_wake_time =
- _lnl_compute_aux_less_wake_time(crtc_state->port_clock);
- aux_less_wake_lines = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode,
- aux_less_wake_time);
-
- if (!_lnl_get_silence_period_and_lfps_half_cycle(crtc_state->port_clock,
- &silence_period,
- &lfps_half_cycle))
- return false;
-
- if (aux_less_wake_lines > ALPM_CTL_AUX_LESS_WAKE_TIME_MASK ||
- silence_period > PORT_ALPM_CTL_SILENCE_PERIOD_MASK ||
- lfps_half_cycle > PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK)
- return false;
-
- if (i915->display.params.psr_safest_params)
- aux_less_wake_lines = ALPM_CTL_AUX_LESS_WAKE_TIME_MASK;
-
- intel_dp->psr.alpm_parameters.fast_wake_lines = aux_less_wake_lines;
- intel_dp->psr.alpm_parameters.silence_period_sym_clocks = silence_period;
- intel_dp->psr.alpm_parameters.lfps_half_cycle_num_of_syms = lfps_half_cycle;
-
- return true;
-}
-
-static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int check_entry_lines;
-
- if (DISPLAY_VER(i915) < 20)
- return true;
-
- /* ALPM Entry Check = 2 + CEILING( 5us /tline ) */
- check_entry_lines = 2 +
- intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5);
-
- if (check_entry_lines > 15)
- return false;
-
- if (!_lnl_compute_aux_less_alpm_params(intel_dp, crtc_state))
- return false;
-
- if (i915->display.params.psr_safest_params)
- check_entry_lines = 15;
-
- intel_dp->psr.alpm_parameters.check_entry_lines = check_entry_lines;
-
- return true;
-}
-
-/*
- * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There
- * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are
- * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us.
- */
-static int skl_io_buffer_wake_time(void)
-{
- return 18;
-}
-
-static int tgl_io_buffer_wake_time(void)
-{
- return 10;
-}
-
-static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-
- if (DISPLAY_VER(i915) >= 12)
- return tgl_io_buffer_wake_time();
- else
- return skl_io_buffer_wake_time();
-}
-
-static bool _compute_alpm_params(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time;
- int tfw_exit_latency = 20; /* eDP spec */
- int phy_wake = 4; /* eDP spec */
- int preamble = 8; /* eDP spec */
- int precharge = intel_dp_aux_fw_sync_len() - preamble;
- u8 max_wake_lines;
-
- io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) +
- preamble + phy_wake + tfw_exit_latency;
- fast_wake_time = precharge + preamble + phy_wake +
- tfw_exit_latency;
-
- if (DISPLAY_VER(i915) >= 12)
- /* TODO: Check how we can use ALPM_CTL fast wake extended field */
- max_wake_lines = 12;
- else
- max_wake_lines = 8;
-
- io_wake_lines = intel_usecs_to_scanlines(
- &crtc_state->hw.adjusted_mode, io_wake_time);
- fast_wake_lines = intel_usecs_to_scanlines(
- &crtc_state->hw.adjusted_mode, fast_wake_time);
-
- if (io_wake_lines > max_wake_lines ||
- fast_wake_lines > max_wake_lines)
- return false;
-
- if (!_lnl_compute_alpm_params(intel_dp, crtc_state))
- return false;
-
- if (i915->display.params.psr_safest_params)
- io_wake_lines = fast_wake_lines = max_wake_lines;
-
- /* According to Bspec lower limit should be set as 7 lines. */
- intel_dp->psr.alpm_parameters.io_wake_lines = max(io_wake_lines, 7);
- intel_dp->psr.alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7);
-
- return true;
-}
-
static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
const struct drm_display_mode *adjusted_mode)
{
@@ -1425,6 +1318,53 @@ static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
return entry_setup_frames;
}
+static bool wake_lines_fit_into_vblank(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ bool aux_less)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int vblank = crtc_state->hw.adjusted_mode.crtc_vblank_end -
+ crtc_state->hw.adjusted_mode.crtc_vblank_start;
+ int wake_lines;
+
+ if (aux_less)
+ wake_lines = intel_dp->alpm_parameters.aux_less_wake_lines;
+ else
+ wake_lines = DISPLAY_VER(i915) < 20 ?
+ psr2_block_count_lines(intel_dp) :
+ intel_dp->alpm_parameters.io_wake_lines;
+
+ if (crtc_state->req_psr2_sdp_prior_scanline)
+ vblank -= 1;
+
+ /* Vblank >= PSR2_CTL Block Count Number maximum line count */
+ if (vblank < wake_lines)
+ return false;
+
+ return true;
+}
+
+static bool alpm_config_valid(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ bool aux_less)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ if (!intel_alpm_compute_params(intel_dp, crtc_state)) {
+ drm_dbg_kms(&i915->drm,
+ "PSR2/Panel Replay not enabled, Unable to use long enough wake times\n");
+ return false;
+ }
+
+ if (!wake_lines_fit_into_vblank(intel_dp, crtc_state, aux_less)) {
+ drm_dbg_kms(&i915->drm,
+ "PSR2/Panel Replay not enabled, too short vblank time\n");
+ return false;
+ }
+
+ return true;
+}
+
static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
@@ -1461,11 +1401,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (!psr2_global_enabled(intel_dp)) {
- drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by flag\n");
- return false;
- }
-
/*
* DSC and PSR2 cannot be enabled simultaneously. If a requested
* resolution requires DSC to be enabled, priority is given to DSC
@@ -1478,12 +1413,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (crtc_state->crc_enabled) {
- drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled because it would inhibit pipe CRC calculation\n");
- return false;
- }
-
if (DISPLAY_VER(dev_priv) >= 12) {
psr_max_h = 5120;
psr_max_v = 3200;
@@ -1513,51 +1442,69 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) {
- drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, PSR2 SDP indication do not fit in hblank\n");
+ if (!alpm_config_valid(intel_dp, crtc_state, false))
return false;
- }
- if (!_compute_alpm_params(intel_dp, crtc_state)) {
+ if (!crtc_state->enable_psr2_sel_fetch &&
+ (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, Unable to use long enough wake times\n");
+ "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
+ crtc_hdisplay, crtc_vdisplay,
+ psr_max_h, psr_max_v);
return false;
}
- /* Vblank >= PSR2_CTL Block Count Number maximum line count */
- if (crtc_state->hw.adjusted_mode.crtc_vblank_end -
- crtc_state->hw.adjusted_mode.crtc_vblank_start <
- psr2_block_count_lines(intel_dp)) {
+ tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
+
+ return true;
+}
+
+static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+ if (HAS_PSR2_SEL_FETCH(dev_priv) &&
+ !intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
+ !HAS_PSR_HW_TRACKING(dev_priv)) {
drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, too short vblank time\n");
- return false;
+ "Selective update not enabled, selective fetch not valid and no HW tracking available\n");
+ goto unsupported;
}
- if (HAS_PSR2_SEL_FETCH(dev_priv)) {
- if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
- !HAS_PSR_HW_TRACKING(dev_priv)) {
- drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
- return false;
- }
+ if (!psr2_global_enabled(intel_dp)) {
+ drm_dbg_kms(&dev_priv->drm, "Selective update disabled by flag\n");
+ goto unsupported;
}
- if (!psr2_granularity_check(intel_dp, crtc_state)) {
- drm_dbg_kms(&dev_priv->drm, "PSR2 not enabled, SU granularity not compatible\n");
+ if (!crtc_state->has_panel_replay && !intel_psr2_config_valid(intel_dp, crtc_state))
+ goto unsupported;
+
+ if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "Selective update not enabled, SDP indication do not fit in hblank\n");
goto unsupported;
}
- if (!crtc_state->enable_psr2_sel_fetch &&
- (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
+ if (crtc_state->has_panel_replay && (DISPLAY_VER(dev_priv) < 14 ||
+ !intel_dp->psr.sink_panel_replay_su_support))
+ goto unsupported;
+
+ if (crtc_state->crc_enabled) {
drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
- crtc_hdisplay, crtc_vdisplay,
- psr_max_h, psr_max_v);
+ "Selective update not enabled because it would inhibit pipe CRC calculation\n");
goto unsupported;
}
- tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
+ if (!psr2_granularity_check(intel_dp, crtc_state)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "Selective update not enabled, SU granularity not compatible\n");
+ goto unsupported;
+ }
+
+ crtc_state->enable_psr2_su_region_et =
+ psr2_su_region_et_valid(intel_dp, crtc_state->has_panel_replay);
+
return true;
unsupported:
@@ -1595,6 +1542,53 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
return true;
}
+static bool
+_panel_replay_compute_config(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ const struct drm_connector_state *conn_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_connector *connector =
+ to_intel_connector(conn_state->connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+
+ if (!CAN_PANEL_REPLAY(intel_dp))
+ return false;
+
+ if (!panel_replay_global_enabled(intel_dp)) {
+ drm_dbg_kms(&i915->drm, "Panel Replay disabled by flag\n");
+ return false;
+ }
+
+ if (!intel_dp_is_edp(intel_dp))
+ return true;
+
+ /* Remaining checks are for eDP only */
+
+ /* 128b/132b Panel Replay is not supported on eDP */
+ if (intel_dp_is_uhbr(crtc_state)) {
+ drm_dbg_kms(&i915->drm,
+ "Panel Replay is not supported with 128b/132b\n");
+ return false;
+ }
+
+ /* HW will not allow Panel Replay on eDP when HDCP enabled */
+ if (conn_state->content_protection ==
+ DRM_MODE_CONTENT_PROTECTION_DESIRED ||
+ (conn_state->content_protection ==
+ DRM_MODE_CONTENT_PROTECTION_ENABLED && hdcp->value ==
+ DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
+ drm_dbg_kms(&i915->drm,
+ "Panel Replay is not supported with HDCP\n");
+ return false;
+ }
+
+ if (!alpm_config_valid(intel_dp, crtc_state, true))
+ return false;
+
+ return true;
+}
+
void intel_psr_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -1620,18 +1614,19 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
}
/*
- * FIXME figure out what is wrong with PSR+bigjoiner and
+ * FIXME figure out what is wrong with PSR+joiner and
* fix it. Presumably something related to the fact that
* PSR is a transcoder level feature.
*/
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
drm_dbg_kms(&dev_priv->drm,
- "PSR disabled due to bigjoiner\n");
+ "PSR disabled due to joiner\n");
return;
}
- if (CAN_PANEL_REPLAY(intel_dp))
- crtc_state->has_panel_replay = true;
+ crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp,
+ crtc_state,
+ conn_state);
crtc_state->has_psr = crtc_state->has_panel_replay ? true :
_psr_compute_config(intel_dp, crtc_state);
@@ -1639,7 +1634,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
if (!crtc_state->has_psr)
return;
- crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state);
+ crtc_state->has_sel_update = intel_sel_update_config_valid(intel_dp, crtc_state);
}
void intel_psr_get_config(struct intel_encoder *encoder,
@@ -1672,20 +1667,24 @@ void intel_psr_get_config(struct intel_encoder *encoder,
pipe_config->has_psr = true;
}
- pipe_config->has_psr2 = intel_dp->psr.psr2_enabled;
+ pipe_config->has_sel_update = intel_dp->psr.sel_update_enabled;
pipe_config->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
- if (!intel_dp->psr.psr2_enabled)
+ if (!intel_dp->psr.sel_update_enabled)
goto unlock;
if (HAS_PSR2_SEL_FETCH(dev_priv)) {
- val = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder));
if (val & PSR2_MAN_TRK_CTL_ENABLE)
pipe_config->enable_psr2_sel_fetch = true;
}
+ pipe_config->enable_psr2_su_region_et = intel_dp->psr.su_region_et_enabled;
+
if (DISPLAY_VER(dev_priv) >= 12) {
- val = intel_de_read(dev_priv, TRANS_EXITLINE(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ TRANS_EXITLINE(dev_priv, cpu_transcoder));
pipe_config->dc3co_exitline = REG_FIELD_GET(EXITLINE_MASK, val);
}
unlock:
@@ -1699,7 +1698,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
drm_WARN_ON(&dev_priv->drm,
transcoder_has_psr2(dev_priv, cpu_transcoder) &&
- intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder)) & EDP_PSR2_ENABLE);
+ intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder)) & EDP_PSR2_ENABLE);
drm_WARN_ON(&dev_priv->drm,
intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder)) & EDP_PSR_ENABLE);
@@ -1711,7 +1710,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
/* psr1, psr2 and panel-replay are mutually exclusive.*/
if (intel_dp->psr.panel_replay_enabled)
dg2_activate_panel_replay(intel_dp);
- else if (intel_dp->psr.psr2_enabled)
+ else if (intel_dp->psr.sel_update_enabled)
hsw_activate_psr2(intel_dp);
else
hsw_activate_psr1(intel_dp);
@@ -1763,51 +1762,6 @@ static void wm_optimization_wa(struct intel_dp *intel_dp,
wa_16013835468_bit_get(intel_dp), 0);
}
-static void lnl_alpm_configure(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
- struct intel_psr *psr = &intel_dp->psr;
- u32 alpm_ctl;
-
- if (DISPLAY_VER(dev_priv) < 20 || (!intel_dp->psr.psr2_enabled &&
- !intel_dp_is_edp(intel_dp)))
- return;
-
- /*
- * Panel Replay on eDP is always using ALPM aux less. I.e. no need to
- * check panel support at this point.
- */
- if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) {
- alpm_ctl = ALPM_CTL_ALPM_ENABLE |
- ALPM_CTL_ALPM_AUX_LESS_ENABLE |
- ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS;
-
- intel_de_write(dev_priv, PORT_ALPM_CTL(cpu_transcoder),
- PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
- PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
- PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
- PORT_ALPM_CTL_SILENCE_PERIOD(
- psr->alpm_parameters.silence_period_sym_clocks));
-
- intel_de_write(dev_priv, PORT_ALPM_LFPS_CTL(cpu_transcoder),
- PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) |
- PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
- psr->alpm_parameters.lfps_half_cycle_num_of_syms) |
- PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
- psr->alpm_parameters.lfps_half_cycle_num_of_syms) |
- PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
- psr->alpm_parameters.lfps_half_cycle_num_of_syms));
- } else {
- alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
- ALPM_CTL_EXTENDED_FAST_WAKE_TIME(psr->alpm_parameters.fast_wake_lines);
- }
-
- alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(psr->alpm_parameters.check_entry_lines);
-
- intel_de_write(dev_priv, ALPM_CTL(cpu_transcoder), alpm_ctl);
-}
-
static void intel_psr_enable_source(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
@@ -1877,7 +1831,9 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
* transcoder, EXITLINE will need to be unset when disabling PSR
*/
if (intel_dp->psr.dc3co_exitline)
- intel_de_rmw(dev_priv, TRANS_EXITLINE(cpu_transcoder), EXITLINE_MASK,
+ intel_de_rmw(dev_priv,
+ TRANS_EXITLINE(dev_priv, cpu_transcoder),
+ EXITLINE_MASK,
intel_dp->psr.dc3co_exitline << EXITLINE_SHIFT | EXITLINE_ENABLE);
if (HAS_PSR_HW_TRACKING(dev_priv) && HAS_PSR2_SEL_FETCH(dev_priv))
@@ -1886,7 +1842,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
IGNORE_PSR2_HW_TRACKING : 0);
if (intel_dp_is_edp(intel_dp))
- lnl_alpm_configure(intel_dp);
+ intel_alpm_configure(intel_dp, crtc_state);
/*
* Wa_16013835468
@@ -1894,7 +1850,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
*/
wm_optimization_wa(intel_dp, crtc_state);
- if (intel_dp->psr.psr2_enabled) {
+ if (intel_dp->psr.sel_update_enabled) {
if (DISPLAY_VER(dev_priv) == 9)
intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0,
PSR2_VSC_ENABLE_PROG_HEADER |
@@ -1905,15 +1861,18 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
* All supported adlp panels have 1-based X granularity, this may
* cause issues if non-supported panels are used.
*/
- if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
- IS_ALDERLAKE_P(dev_priv))
+ if (!intel_dp->psr.panel_replay_enabled &&
+ (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
+ IS_ALDERLAKE_P(dev_priv)))
intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
0, ADLP_1_BASED_X_GRANULARITY);
/* Wa_16012604467:adlp,mtl[a0,b0] */
- if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
+ if (!intel_dp->psr.panel_replay_enabled &&
+ IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
intel_de_rmw(dev_priv,
- MTL_CLKGATE_DIS_TRANS(cpu_transcoder), 0,
+ MTL_CLKGATE_DIS_TRANS(dev_priv, cpu_transcoder),
+ 0,
MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS);
else if (IS_ALDERLAKE_P(dev_priv))
intel_de_rmw(dev_priv, CLKGATE_DIS_MISC, 0,
@@ -1960,7 +1919,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
- intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
+ intel_dp->psr.sel_update_enabled = crtc_state->has_sel_update;
intel_dp->psr.panel_replay_enabled = crtc_state->has_panel_replay;
intel_dp->psr.busy_frontbuffer_bits = 0;
intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
@@ -1970,6 +1929,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.dc3co_exit_delay = val;
intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline;
intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
+ intel_dp->psr.su_region_et_enabled = crtc_state->enable_psr2_su_region_et;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
intel_dp->psr.req_psr2_sdp_prior_scanline =
crtc_state->req_psr2_sdp_prior_scanline;
@@ -1981,7 +1941,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
drm_dbg_kms(&dev_priv->drm, "Enabling Panel Replay\n");
} else {
drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
- intel_dp->psr.psr2_enabled ? "2" : "1");
+ intel_dp->psr.sel_update_enabled ? "2" : "1");
/*
* Panel replay has to be enabled before link training: doing it
@@ -2008,7 +1968,8 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
if (!intel_dp->psr.active) {
if (transcoder_has_psr2(dev_priv, cpu_transcoder)) {
- val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ EDP_PSR2_CTL(dev_priv, cpu_transcoder));
drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE);
}
@@ -2021,10 +1982,11 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
if (intel_dp->psr.panel_replay_enabled) {
intel_de_rmw(dev_priv, TRANS_DP2_CTL(intel_dp->psr.transcoder),
TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
- } else if (intel_dp->psr.psr2_enabled) {
+ } else if (intel_dp->psr.sel_update_enabled) {
tgl_disallow_dc3co_on_psr2_exit(intel_dp);
- val = intel_de_rmw(dev_priv, EDP_PSR2_CTL(cpu_transcoder),
+ val = intel_de_rmw(dev_priv,
+ EDP_PSR2_CTL(dev_priv, cpu_transcoder),
EDP_PSR2_ENABLE, 0);
drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE));
@@ -2044,8 +2006,9 @@ static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp)
i915_reg_t psr_status;
u32 psr_status_mask;
- if (intel_dp->psr.psr2_enabled) {
- psr_status = EDP_PSR2_STATUS(cpu_transcoder);
+ if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled ||
+ intel_dp->psr.panel_replay_enabled)) {
+ psr_status = EDP_PSR2_STATUS(dev_priv, cpu_transcoder);
psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
} else {
psr_status = psr_status_reg(dev_priv, cpu_transcoder);
@@ -2072,7 +2035,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
drm_dbg_kms(&dev_priv->drm, "Disabling Panel Replay\n");
else
drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
- intel_dp->psr.psr2_enabled ? "2" : "1");
+ intel_dp->psr.sel_update_enabled ? "2" : "1");
intel_psr_exit(intel_dp);
intel_psr_wait_exit_locked(intel_dp);
@@ -2085,11 +2048,12 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1,
wa_16013835468_bit_get(intel_dp), 0);
- if (intel_dp->psr.psr2_enabled) {
+ if (intel_dp->psr.sel_update_enabled) {
/* Wa_16012604467:adlp,mtl[a0,b0] */
- if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
+ if (!intel_dp->psr.panel_replay_enabled &&
+ IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
intel_de_rmw(dev_priv,
- MTL_CLKGATE_DIS_TRANS(cpu_transcoder),
+ MTL_CLKGATE_DIS_TRANS(dev_priv, cpu_transcoder),
MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS, 0);
else if (IS_ALDERLAKE_P(dev_priv))
intel_de_rmw(dev_priv, CLKGATE_DIS_MISC,
@@ -2101,26 +2065,29 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
/* Panel Replay on eDP is always using ALPM aux less. */
if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) {
- intel_de_rmw(dev_priv, ALPM_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv, ALPM_CTL(dev_priv, cpu_transcoder),
ALPM_CTL_ALPM_ENABLE |
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
- intel_de_rmw(dev_priv, PORT_ALPM_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv,
+ PORT_ALPM_CTL(dev_priv, cpu_transcoder),
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
}
/* Disable PSR on Sink */
- drm_dp_dpcd_writeb(&intel_dp->aux,
- intel_psr_get_enable_sink_offset(intel_dp), 0);
+ if (!intel_dp->psr.panel_replay_enabled) {
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
- if (!intel_dp->psr.panel_replay_enabled &&
- intel_dp->psr.psr2_enabled)
- drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0);
+ if (intel_dp->psr.sel_update_enabled)
+ drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_RECEIVER_ALPM_CONFIG, 0);
+ }
intel_dp->psr.enabled = false;
intel_dp->psr.panel_replay_enabled = false;
- intel_dp->psr.psr2_enabled = false;
+ intel_dp->psr.sel_update_enabled = false;
intel_dp->psr.psr2_sel_fetch_enabled = false;
+ intel_dp->psr.su_region_et_enabled = false;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
}
@@ -2244,7 +2211,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
if (intel_dp->psr.psr2_sel_fetch_enabled)
intel_de_write(dev_priv,
- PSR2_MAN_TRK_CTL(cpu_transcoder),
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
man_trk_ctl_enable_bit_get(dev_priv) |
man_trk_ctl_partial_frame_bit_get(dev_priv) |
man_trk_ctl_single_full_frame_bit_get(dev_priv) |
@@ -2263,7 +2230,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
* but testing proved that it works for up display 13, for newer
* than that testing will be needed.
*/
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv, CURSURFLIVE(dev_priv, intel_dp->psr.pipe), 0);
}
void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
@@ -2286,7 +2253,7 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
break;
}
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder),
+ intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
crtc_state->psr2_man_track_ctl);
if (!crtc_state->enable_psr2_su_region_et)
@@ -2332,19 +2299,14 @@ exit:
crtc_state->psr2_man_track_ctl = val;
}
-static u32
-psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state,
- bool full_update, bool cursor_in_su_area)
+static u32 psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state,
+ bool full_update)
{
int width, height;
if (!crtc_state->enable_psr2_su_region_et || full_update)
return 0;
- if (!cursor_in_su_area)
- return PIPESRC_WIDTH(0) |
- PIPESRC_HEIGHT(drm_rect_height(&crtc_state->pipe_src));
-
width = drm_rect_width(&crtc_state->psr2_su_area);
height = drm_rect_height(&crtc_state->psr2_su_area);
@@ -2484,7 +2446,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
crtc_state->psr2_su_area.x1 = 0;
crtc_state->psr2_su_area.y1 = -1;
- crtc_state->psr2_su_area.x2 = INT_MAX;
+ crtc_state->psr2_su_area.x2 = drm_rect_width(&crtc_state->pipe_src);
crtc_state->psr2_su_area.y2 = -1;
/*
@@ -2573,8 +2535,9 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
goto skip_sel_fetch_set_loop;
/* Wa_14014971492 */
- if ((IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
- IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
+ if (!crtc_state->has_panel_replay &&
+ ((IS_DISPLAY_IP_STEP(dev_priv, 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;
@@ -2652,8 +2615,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
skip_sel_fetch_set_loop:
psr2_man_trk_ctl_calc(crtc_state, full_update);
crtc_state->pipe_srcsz_early_tpt =
- psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update,
- cursor_in_su_area);
+ psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update);
return 0;
}
@@ -2683,12 +2645,15 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state,
* - PSR disabled in new state
* - All planes will go inactive
* - Changing between PSR versions
+ * - Region Early Transport changing
* - Display WA #1136: skl, bxt
*/
needs_to_disable |= intel_crtc_needs_modeset(new_crtc_state);
needs_to_disable |= !new_crtc_state->has_psr;
needs_to_disable |= !new_crtc_state->active_planes;
- needs_to_disable |= new_crtc_state->has_psr2 != psr->psr2_enabled;
+ needs_to_disable |= new_crtc_state->has_sel_update != psr->sel_update_enabled;
+ needs_to_disable |= new_crtc_state->enable_psr2_su_region_et !=
+ psr->su_region_et_enabled;
needs_to_disable |= DISPLAY_VER(i915) < 11 &&
new_crtc_state->wm_level_disabled;
@@ -2761,7 +2726,7 @@ static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
* EDP_PSR2_STATUS_STATE_DEEP_SLEEP to be cleared.
*/
return intel_de_wait_for_clear(dev_priv,
- EDP_PSR2_STATUS(cpu_transcoder),
+ EDP_PSR2_STATUS(dev_priv, cpu_transcoder),
EDP_PSR2_STATUS_STATE_DEEP_SLEEP, 50);
}
@@ -2781,6 +2746,13 @@ static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
EDP_PSR_STATUS_STATE_MASK, 50);
}
+static int _panel_replay_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
+{
+ return intel_dp_is_edp(intel_dp) ?
+ _psr2_ready_for_pipe_update_locked(intel_dp) :
+ _psr1_ready_for_pipe_update_locked(intel_dp);
+}
+
/**
* intel_psr_wait_for_idle_locked - wait for PSR be ready for a pipe update
* @new_crtc_state: new CRTC state
@@ -2806,7 +2778,9 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat
if (!intel_dp->psr.enabled)
continue;
- if (intel_dp->psr.psr2_enabled)
+ if (intel_dp->psr.panel_replay_enabled)
+ ret = _panel_replay_ready_for_pipe_update_locked(intel_dp);
+ else if (intel_dp->psr.sel_update_enabled)
ret = _psr2_ready_for_pipe_update_locked(intel_dp);
else
ret = _psr1_ready_for_pipe_update_locked(intel_dp);
@@ -2827,8 +2801,9 @@ static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
if (!intel_dp->psr.enabled)
return false;
- if (intel_dp->psr.psr2_enabled) {
- reg = EDP_PSR2_STATUS(cpu_transcoder);
+ if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled ||
+ intel_dp->psr.panel_replay_enabled)) {
+ reg = EDP_PSR2_STATUS(dev_priv, cpu_transcoder);
mask = EDP_PSR2_STATUS_STATE_MASK;
} else {
reg = psr_status_reg(dev_priv, cpu_transcoder);
@@ -2914,10 +2889,14 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
const u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
- u32 old_mode;
+ const u32 disable_bits = val & (I915_PSR_DEBUG_SU_REGION_ET_DISABLE |
+ I915_PSR_DEBUG_PANEL_REPLAY_DISABLE);
+ u32 old_mode, old_disable_bits;
int ret;
- if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK) ||
+ if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_SU_REGION_ET_DISABLE |
+ I915_PSR_DEBUG_PANEL_REPLAY_DISABLE |
+ I915_PSR_DEBUG_MODE_MASK) ||
mode > I915_PSR_DEBUG_ENABLE_SEL_FETCH) {
drm_dbg_kms(&dev_priv->drm, "Invalid debug mask %llx\n", val);
return -EINVAL;
@@ -2928,6 +2907,10 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
return ret;
old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK;
+ old_disable_bits = intel_dp->psr.debug &
+ (I915_PSR_DEBUG_SU_REGION_ET_DISABLE |
+ I915_PSR_DEBUG_PANEL_REPLAY_DISABLE);
+
intel_dp->psr.debug = val;
/*
@@ -2939,7 +2922,7 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
mutex_unlock(&intel_dp->psr.lock);
- if (old_mode != mode)
+ if (old_mode != mode || old_disable_bits != disable_bits)
ret = intel_psr_fastset_force(dev_priv);
return ret;
@@ -3000,15 +2983,20 @@ static void _psr_invalidate_handle(struct intel_dp *intel_dp)
if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
/* Send one update otherwise lag is observed in screen */
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv,
+ CURSURFLIVE(dev_priv, intel_dp->psr.pipe),
+ 0);
return;
}
val = man_trk_ctl_enable_bit_get(dev_priv) |
man_trk_ctl_partial_frame_bit_get(dev_priv) |
man_trk_ctl_continuos_full_frame(dev_priv);
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder), val);
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
+ val);
+ intel_de_write(dev_priv,
+ CURSURFLIVE(dev_priv, intel_dp->psr.pipe), 0);
intel_dp->psr.psr2_sel_fetch_cff_enabled = true;
} else {
intel_psr_exit(intel_dp);
@@ -3068,7 +3056,7 @@ tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.psr2_enabled ||
+ if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled ||
!intel_dp->psr.active)
return;
@@ -3105,9 +3093,12 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
* SU configuration in case update is sent for any reason after
* sff bit gets cleared by the HW on next vblank.
*/
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder),
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
val);
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv,
+ CURSURFLIVE(dev_priv, intel_dp->psr.pipe),
+ 0);
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
}
} else {
@@ -3214,13 +3205,12 @@ void intel_psr_init(struct intel_dp *intel_dp)
return;
}
- if (HAS_DP20(dev_priv) && !intel_dp_is_edp(intel_dp))
+ if ((HAS_DP20(dev_priv) && !intel_dp_is_edp(intel_dp)) ||
+ DISPLAY_VER(dev_priv) >= 20)
intel_dp->psr.source_panel_replay_support = true;
- else
- intel_dp->psr.source_support = true;
- /* Disable early transport for now */
- intel_dp->psr.debug |= I915_PSR_DEBUG_SU_REGION_ET_DISABLE;
+ if (HAS_PSR(dev_priv) && intel_dp_is_edp(intel_dp))
+ intel_dp->psr.source_support = true;
/* Set link_standby x link_off defaults */
if (DISPLAY_VER(dev_priv) < 12)
@@ -3266,7 +3256,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp)
u8 val;
int r;
- if (!psr->psr2_enabled)
+ if (!psr->sel_update_enabled)
return;
r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val);
@@ -3446,7 +3436,8 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
const char *status = "unknown";
u32 val, status_val;
- if (intel_dp->psr.psr2_enabled) {
+ if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled ||
+ intel_dp->psr.panel_replay_enabled)) {
static const char * const live_status[] = {
"IDLE",
"CAPTURE",
@@ -3460,7 +3451,8 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
"BUF_ON",
"TG_ON"
};
- val = intel_de_read(dev_priv, EDP_PSR2_STATUS(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ EDP_PSR2_STATUS(dev_priv, cpu_transcoder));
status_val = REG_FIELD_GET(EDP_PSR2_STATUS_STATE_MASK, val);
if (status_val < ARRAY_SIZE(live_status))
status = live_status[status_val];
@@ -3484,22 +3476,66 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
seq_printf(m, "Source PSR/PanelReplay status: %s [0x%08x]\n", status, val);
}
-static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
+static void intel_psr_sink_capability(struct intel_dp *intel_dp,
+ struct seq_file *m)
{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
struct intel_psr *psr = &intel_dp->psr;
- intel_wakeref_t wakeref;
- const char *status;
- bool enabled;
- u32 val;
seq_printf(m, "Sink support: PSR = %s",
str_yes_no(psr->sink_support));
if (psr->sink_support)
seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
- seq_printf(m, ", Panel Replay = %s\n", str_yes_no(psr->sink_panel_replay_support));
+ if (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED)
+ seq_printf(m, " (Early Transport)");
+ seq_printf(m, ", Panel Replay = %s", str_yes_no(psr->sink_panel_replay_support));
+ seq_printf(m, ", Panel Replay Selective Update = %s",
+ str_yes_no(psr->sink_panel_replay_su_support));
+ if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)
+ seq_printf(m, " (Early Transport)");
+ seq_printf(m, "\n");
+}
+
+static void intel_psr_print_mode(struct intel_dp *intel_dp,
+ struct seq_file *m)
+{
+ struct intel_psr *psr = &intel_dp->psr;
+ const char *status, *mode, *region_et;
+
+ if (psr->enabled)
+ status = " enabled";
+ else
+ status = "disabled";
+
+ if (psr->panel_replay_enabled && psr->sel_update_enabled)
+ mode = "Panel Replay Selective Update";
+ else if (psr->panel_replay_enabled)
+ mode = "Panel Replay";
+ else if (psr->sel_update_enabled)
+ mode = "PSR2";
+ else if (psr->enabled)
+ mode = "PSR1";
+ else
+ mode = "";
+
+ if (psr->su_region_et_enabled)
+ region_et = " (Early Transport)";
+ else
+ region_et = "";
+
+ seq_printf(m, "PSR mode: %s%s%s\n", mode, status, region_et);
+}
+
+static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
+ struct intel_psr *psr = &intel_dp->psr;
+ intel_wakeref_t wakeref;
+ bool enabled;
+ u32 val, psr2_ctl;
+
+ intel_psr_sink_capability(intel_dp, m);
if (!(psr->sink_support || psr->sink_panel_replay_support))
return 0;
@@ -3507,13 +3543,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
mutex_lock(&psr->lock);
- if (psr->panel_replay_enabled)
- status = "Panel Replay Enabled";
- else if (psr->enabled)
- status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1 enabled";
- else
- status = "disabled";
- seq_printf(m, "PSR mode: %s\n", status);
+ intel_psr_print_mode(intel_dp, m);
if (!psr->enabled) {
seq_printf(m, "PSR sink not reliable: %s\n",
@@ -3524,9 +3554,16 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
if (psr->panel_replay_enabled) {
val = intel_de_read(dev_priv, TRANS_DP2_CTL(cpu_transcoder));
+
+ if (intel_dp_is_edp(intel_dp))
+ psr2_ctl = intel_de_read(dev_priv,
+ EDP_PSR2_CTL(dev_priv,
+ cpu_transcoder));
+
enabled = val & TRANS_DP2_PANEL_REPLAY_ENABLE;
- } else if (psr->psr2_enabled) {
- val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
+ } else if (psr->sel_update_enabled) {
+ val = intel_de_read(dev_priv,
+ EDP_PSR2_CTL(dev_priv, cpu_transcoder));
enabled = val & EDP_PSR2_ENABLE;
} else {
val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder));
@@ -3534,6 +3571,9 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
}
seq_printf(m, "Source PSR/PanelReplay ctl: %s [0x%08x]\n",
str_enabled_disabled(enabled), val);
+ if (psr->panel_replay_enabled && intel_dp_is_edp(intel_dp))
+ seq_printf(m, "PSR2_CTL: 0x%08x\n",
+ psr2_ctl);
psr_source_status(intel_dp, m);
seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
psr->busy_frontbuffer_bits);
@@ -3551,7 +3591,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
seq_printf(m, "Last exit at: %lld\n", psr->last_exit);
}
- if (psr->psr2_enabled) {
+ if (psr->sel_update_enabled) {
u32 su_frames_val[3];
int frame;
@@ -3560,7 +3600,8 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
* frame boundary between register reads
*/
for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) {
- val = intel_de_read(dev_priv, PSR2_SU_STATUS(cpu_transcoder, frame));
+ val = intel_de_read(dev_priv,
+ PSR2_SU_STATUS(dev_priv, cpu_transcoder, frame));
su_frames_val[frame / 3] = val;
}
@@ -3694,16 +3735,9 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
"reserved",
"sink internal error",
};
- static const char * const panel_replay_status[] = {
- "Sink device frame is locked to the Source device",
- "Sink device is coasting, using the VTotal target",
- "Sink device is governing the frame rate (frame rate unlock is granted)",
- "Sink device in the process of re-locking with the Source device",
- };
const char *str;
int ret;
u8 status, error_status;
- u32 idx;
if (!(CAN_PSR(intel_dp) || CAN_PANEL_REPLAY(intel_dp))) {
seq_puts(m, "PSR/Panel-Replay Unsupported\n");
@@ -3717,16 +3751,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
if (ret)
return ret;
- str = "unknown";
- if (intel_dp->psr.panel_replay_enabled) {
- idx = (status & DP_SINK_FRAME_LOCKED_MASK) >> DP_SINK_FRAME_LOCKED_SHIFT;
- if (idx < ARRAY_SIZE(panel_replay_status))
- str = panel_replay_status[idx];
- } else if (intel_dp->psr.enabled) {
- idx = status & DP_PSR_SINK_STATE_MASK;
- if (idx < ARRAY_SIZE(sink_status))
- str = sink_status[idx];
- }
+ status &= DP_PSR_SINK_STATE_MASK;
+ if (status < ARRAY_SIZE(sink_status))
+ str = sink_status[status];
+ else
+ str = "unknown";
seq_printf(m, "Sink %s status: 0x%x [%s]\n", psr_mode_str(intel_dp), status, str);
diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h
index ebc22999572c..642bb15fb547 100644
--- a/drivers/gpu/drm/i915/display/intel_psr_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h
@@ -9,7 +9,7 @@
#include "intel_display_reg_defs.h"
#include "intel_dp_aux_regs.h"
-#define TRANS_EXITLINE(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_EXITLINE_A)
+#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)
#define EXITLINE_SHIFT 0
@@ -23,7 +23,7 @@
#define HSW_SRD_CTL _MMIO(0x64800)
#define _SRD_CTL_A 0x60800
#define _SRD_CTL_EDP 0x6f800
-#define EDP_PSR_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_CTL_A)
+#define EDP_PSR_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_CTL_A)
#define EDP_PSR_ENABLE REG_BIT(31)
#define BDW_PSR_SINGLE_FRAME REG_BIT(30)
#define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK REG_BIT(29) /* SW can't modify */
@@ -66,8 +66,8 @@
#define EDP_PSR_IIR _MMIO(0x64838)
#define _PSR_IMR_A 0x60814
#define _PSR_IIR_A 0x60818
-#define TRANS_PSR_IMR(tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IMR_A)
-#define TRANS_PSR_IIR(tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IIR_A)
+#define TRANS_PSR_IMR(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IMR_A)
+#define TRANS_PSR_IIR(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IIR_A)
#define _EDP_PSR_TRANS_SHIFT(trans) ((trans) == TRANSCODER_EDP ? \
0 : ((trans) - TRANSCODER_A + 1) * 8)
#define TGL_PSR_MASK REG_GENMASK(2, 0)
@@ -86,7 +86,7 @@
#define HSW_SRD_AUX_CTL _MMIO(0x64810)
#define _SRD_AUX_CTL_A 0x60810
#define _SRD_AUX_CTL_EDP 0x6f810
-#define EDP_PSR_AUX_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_CTL_A)
+#define EDP_PSR_AUX_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_CTL_A)
#define EDP_PSR_AUX_CTL_TIME_OUT_MASK DP_AUX_CH_CTL_TIME_OUT_MASK
#define EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK DP_AUX_CH_CTL_MESSAGE_SIZE_MASK
#define EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK DP_AUX_CH_CTL_PRECHARGE_2US_MASK
@@ -96,12 +96,12 @@
#define HSW_SRD_AUX_DATA(i) _MMIO(0x64814 + (i) * 4) /* 5 registers */
#define _SRD_AUX_DATA_A 0x60814
#define _SRD_AUX_DATA_EDP 0x6f814
-#define EDP_PSR_AUX_DATA(tran, i) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_DATA_A + (i) * 4) /* 5 registers */
+#define EDP_PSR_AUX_DATA(dev_priv, tran, i) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_DATA_A + (i) * 4) /* 5 registers */
#define HSW_SRD_STATUS _MMIO(0x64840)
#define _SRD_STATUS_A 0x60840
#define _SRD_STATUS_EDP 0x6f840
-#define EDP_PSR_STATUS(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_STATUS_A)
+#define EDP_PSR_STATUS(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_STATUS_A)
#define EDP_PSR_STATUS_STATE_MASK REG_GENMASK(31, 29)
#define EDP_PSR_STATUS_STATE_IDLE REG_FIELD_PREP(EDP_PSR_STATUS_STATE_MASK, 0)
#define EDP_PSR_STATUS_STATE_SRDONACK REG_FIELD_PREP(EDP_PSR_STATUS_STATE_MASK, 1)
@@ -126,14 +126,14 @@
#define HSW_SRD_PERF_CNT _MMIO(0x64844)
#define _SRD_PERF_CNT_A 0x60844
#define _SRD_PERF_CNT_EDP 0x6f844
-#define EDP_PSR_PERF_CNT(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_PERF_CNT_A)
+#define EDP_PSR_PERF_CNT(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_PERF_CNT_A)
#define EDP_PSR_PERF_CNT_MASK REG_GENMASK(23, 0)
/* PSR_MASK on SKL+ */
#define HSW_SRD_DEBUG _MMIO(0x64860)
#define _SRD_DEBUG_A 0x60860
#define _SRD_DEBUG_EDP 0x6f860
-#define EDP_PSR_DEBUG(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_DEBUG_A)
+#define EDP_PSR_DEBUG(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_DEBUG_A)
#define EDP_PSR_DEBUG_MASK_MAX_SLEEP REG_BIT(28)
#define EDP_PSR_DEBUG_MASK_LPSP REG_BIT(27)
#define EDP_PSR_DEBUG_MASK_MEMUP REG_BIT(26)
@@ -153,7 +153,7 @@
#define _PSR2_CTL_A 0x60900
#define _PSR2_CTL_EDP 0x6f900
-#define EDP_PSR2_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_CTL_A)
+#define EDP_PSR2_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_CTL_A)
#define EDP_PSR2_ENABLE REG_BIT(31)
#define EDP_SU_TRACK_ENABLE REG_BIT(30) /* up to adl-p */
#define TGL_EDP_PSR2_BLOCK_COUNT_MASK REG_BIT(28)
@@ -172,6 +172,10 @@
#define TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES 5
#define TGL_EDP_PSR2_IO_BUFFER_WAKE(lines) REG_FIELD_PREP(TGL_EDP_PSR2_IO_BUFFER_WAKE_MASK, \
(lines) - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES)
+#define LNL_EDP_PSR2_IO_BUFFER_WAKE_MASK REG_GENMASK(18, 13)
+#define LNL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES 5
+#define LNL_EDP_PSR2_IO_BUFFER_WAKE(lines) REG_FIELD_PREP(LNL_EDP_PSR2_IO_BUFFER_WAKE_MASK, \
+ (lines) - LNL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES)
#define EDP_PSR2_FAST_WAKE_MASK REG_GENMASK(12, 11)
#define EDP_PSR2_FAST_WAKE_MAX_LINES 8
#define EDP_PSR2_FAST_WAKE(lines) REG_FIELD_PREP(EDP_PSR2_FAST_WAKE_MASK, \
@@ -195,7 +199,7 @@
#define _PSR_EVENT_TRANS_C 0x62848
#define _PSR_EVENT_TRANS_D 0x63848
#define _PSR_EVENT_TRANS_EDP 0x6f848
-#define PSR_EVENT(tran) _MMIO_TRANS2(dev_priv, tran, _PSR_EVENT_TRANS_A)
+#define PSR_EVENT(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR_EVENT_TRANS_A)
#define PSR_EVENT_PSR2_WD_TIMER_EXPIRE REG_BIT(17)
#define PSR_EVENT_PSR2_DISABLED REG_BIT(16)
#define PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN REG_BIT(15)
@@ -215,21 +219,21 @@
#define _PSR2_STATUS_A 0x60940
#define _PSR2_STATUS_EDP 0x6f940
-#define EDP_PSR2_STATUS(tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_STATUS_A)
+#define EDP_PSR2_STATUS(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_STATUS_A)
#define EDP_PSR2_STATUS_STATE_MASK REG_GENMASK(31, 28)
#define EDP_PSR2_STATUS_STATE_DEEP_SLEEP REG_FIELD_PREP(EDP_PSR2_STATUS_STATE_MASK, 0x8)
#define _PSR2_SU_STATUS_A 0x60914
#define _PSR2_SU_STATUS_EDP 0x6f914
-#define _PSR2_SU_STATUS(tran, index) _MMIO_TRANS2(dev_priv, tran, _PSR2_SU_STATUS_A + (index) * 4)
-#define PSR2_SU_STATUS(tran, frame) (_PSR2_SU_STATUS(tran, (frame) / 3))
+#define _PSR2_SU_STATUS(dev_priv, tran, index) _MMIO_TRANS2(dev_priv, tran, _PSR2_SU_STATUS_A + (index) * 4)
+#define PSR2_SU_STATUS(dev_priv, tran, frame) (_PSR2_SU_STATUS(dev_priv, tran, (frame) / 3))
#define PSR2_SU_STATUS_SHIFT(frame) (((frame) % 3) * 10)
#define PSR2_SU_STATUS_MASK(frame) (0x3ff << PSR2_SU_STATUS_SHIFT(frame))
#define PSR2_SU_STATUS_FRAMES 8
#define _PSR2_MAN_TRK_CTL_A 0x60910
#define _PSR2_MAN_TRK_CTL_EDP 0x6f910
-#define PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_MAN_TRK_CTL_A)
+#define PSR2_MAN_TRK_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_MAN_TRK_CTL_A)
#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31)
#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21)
#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val)
@@ -248,56 +252,11 @@
/* PSR2 Early transport */
#define _PIPE_SRCSZ_ERLY_TPT_A 0x70074
-
-#define PIPE_SRCSZ_ERLY_TPT(trans) _MMIO_TRANS2(dev_priv, trans, _PIPE_SRCSZ_ERLY_TPT_A)
-
-#define _SEL_FETCH_PLANE_BASE_1_A 0x70890
-#define _SEL_FETCH_PLANE_BASE_2_A 0x708B0
-#define _SEL_FETCH_PLANE_BASE_3_A 0x708D0
-#define _SEL_FETCH_PLANE_BASE_4_A 0x708F0
-#define _SEL_FETCH_PLANE_BASE_5_A 0x70920
-#define _SEL_FETCH_PLANE_BASE_6_A 0x70940
-#define _SEL_FETCH_PLANE_BASE_7_A 0x70960
-#define _SEL_FETCH_PLANE_BASE_CUR_A 0x70880
-#define _SEL_FETCH_PLANE_BASE_1_B 0x71890
-
-#define _SEL_FETCH_PLANE_BASE_A(plane) _PICK(plane, \
- _SEL_FETCH_PLANE_BASE_1_A, \
- _SEL_FETCH_PLANE_BASE_2_A, \
- _SEL_FETCH_PLANE_BASE_3_A, \
- _SEL_FETCH_PLANE_BASE_4_A, \
- _SEL_FETCH_PLANE_BASE_5_A, \
- _SEL_FETCH_PLANE_BASE_6_A, \
- _SEL_FETCH_PLANE_BASE_7_A, \
- _SEL_FETCH_PLANE_BASE_CUR_A)
-#define _SEL_FETCH_PLANE_BASE_1(pipe) _PIPE(pipe, _SEL_FETCH_PLANE_BASE_1_A, _SEL_FETCH_PLANE_BASE_1_B)
-#define _SEL_FETCH_PLANE_BASE(pipe, plane) (_SEL_FETCH_PLANE_BASE_1(pipe) - \
- _SEL_FETCH_PLANE_BASE_1_A + \
- _SEL_FETCH_PLANE_BASE_A(plane))
-
-#define _SEL_FETCH_PLANE_CTL_1_A 0x70890
-#define PLANE_SEL_FETCH_CTL(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_CTL_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
-#define PLANE_SEL_FETCH_CTL_ENABLE REG_BIT(31)
-
-#define _SEL_FETCH_PLANE_POS_1_A 0x70894
-#define PLANE_SEL_FETCH_POS(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_POS_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
-
-#define _SEL_FETCH_PLANE_SIZE_1_A 0x70898
-#define PLANE_SEL_FETCH_SIZE(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_SIZE_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
-
-#define _SEL_FETCH_PLANE_OFFSET_1_A 0x7089C
-#define PLANE_SEL_FETCH_OFFSET(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_OFFSET_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
+#define _PIPE_SRCSZ_ERLY_TPT_B 0x71074
+#define PIPE_SRCSZ_ERLY_TPT(pipe) _MMIO_PIPE((pipe), _PIPE_SRCSZ_ERLY_TPT_A, _PIPE_SRCSZ_ERLY_TPT_B)
#define _ALPM_CTL_A 0x60950
-#define ALPM_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL_A)
+#define ALPM_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL_A)
#define ALPM_CTL_ALPM_ENABLE REG_BIT(31)
#define ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(30)
#define ALPM_CTL_LOBF_ENABLE REG_BIT(29)
@@ -321,7 +280,7 @@
#define ALPM_CTL_AUX_LESS_WAKE_TIME(val) REG_FIELD_PREP(ALPM_CTL_AUX_LESS_WAKE_TIME_MASK, val)
#define _ALPM_CTL2_A 0x60954
-#define ALPM_CTL2(tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL2_A)
+#define ALPM_CTL2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL2_A)
#define ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK REG_GENMASK(28, 24)
#define ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY(val) REG_FIELD_PREP(ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK, val)
#define ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION_MASK REG_GENMASK(19, 16)
@@ -335,7 +294,8 @@
#define ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES(val) REG_FIELD_PREP(ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES_MASK, val)
#define _PORT_ALPM_CTL_A 0x16fa2c
-#define PORT_ALPM_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PORT_ALPM_CTL_A)
+#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_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)
@@ -345,7 +305,8 @@
#define PORT_ALPM_CTL_SILENCE_PERIOD(val) REG_FIELD_PREP(PORT_ALPM_CTL_SILENCE_PERIOD_MASK, val)
#define _PORT_ALPM_LFPS_CTL_A 0x16fa30
-#define PORT_ALPM_LFPS_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PORT_ALPM_LFPS_CTL_A)
+#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_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_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 36a253a19c74..f8cceb3e5d8e 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -39,7 +39,6 @@
#include <drm/drm_rect.h>
#include "i915_drv.h"
-#include "i915_reg.h"
#include "i9xx_plane.h"
#include "intel_atomic_plane.h"
#include "intel_de.h"
@@ -254,6 +253,21 @@ int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
return DIV_ROUND_UP(pixel_rate * num, den);
}
+static unsigned int vlv_sprite_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ switch (fb->modifier) {
+ case I915_FORMAT_MOD_X_TILED:
+ return 4 * 1024;
+ case DRM_FORMAT_MOD_LINEAR:
+ return 128 * 1024;
+ default:
+ MISSING_CASE(fb->modifier);
+ return 0;
+ }
+}
+
static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
{
u32 sprctl = 0;
@@ -965,6 +979,13 @@ hsw_sprite_max_stride(struct intel_plane *plane,
return min(8192 * cpp, 16 * 1024);
}
+static unsigned int g4x_sprite_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ return 4 * 1024;
+}
+
static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
{
u32 dvscntr = 0;
@@ -1571,6 +1592,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane->get_hw_state = vlv_sprite_get_hw_state;
plane->check_plane = vlv_sprite_check;
plane->max_stride = i965_plane_max_stride;
+ plane->min_alignment = vlv_sprite_min_alignment;
plane->min_cdclk = vlv_plane_min_cdclk;
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
@@ -1597,6 +1619,8 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane->min_cdclk = ivb_sprite_min_cdclk;
}
+ plane->min_alignment = g4x_sprite_min_alignment;
+
formats = snb_sprite_formats;
num_formats = ARRAY_SIZE(snb_sprite_formats);
@@ -1608,6 +1632,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane->get_hw_state = g4x_sprite_get_hw_state;
plane->check_plane = g4x_sprite_check;
plane->max_stride = g4x_sprite_max_stride;
+ plane->min_alignment = g4x_sprite_min_alignment;
plane->min_cdclk = g4x_sprite_min_cdclk;
if (IS_SANDYBRIDGE(dev_priv)) {
diff --git a/drivers/gpu/drm/i915/display/intel_sprite_regs.h b/drivers/gpu/drm/i915/display/intel_sprite_regs.h
index bb67705652b2..73021e3ced6d 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_sprite_regs.h
@@ -6,7 +6,10 @@
#include "intel_display_reg_defs.h"
+/* g4x/ilk/snb video sprite */
#define _DVSACNTR 0x72180
+#define _DVSBCNTR 0x73180
+#define DVSCNTR(pipe) _MMIO_PIPE(pipe, _DVSACNTR, _DVSBCNTR)
#define DVS_ENABLE REG_BIT(31)
#define DVS_PIPE_GAMMA_ENABLE REG_BIT(30)
#define DVS_YUV_RANGE_CORRECTION_DISABLE REG_BIT(27)
@@ -28,31 +31,67 @@
#define DVS_TRICKLE_FEED_DISABLE REG_BIT(14)
#define DVS_TILED REG_BIT(10)
#define DVS_DEST_KEY REG_BIT(2)
+
#define _DVSALINOFF 0x72184
+#define _DVSBLINOFF 0x73184
+#define DVSLINOFF(pipe) _MMIO_PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
+
#define _DVSASTRIDE 0x72188
+#define _DVSBSTRIDE 0x73188
+#define DVSSTRIDE(pipe) _MMIO_PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+
#define _DVSAPOS 0x7218c
+#define _DVSBPOS 0x7318c
+#define DVSPOS(pipe) _MMIO_PIPE(pipe, _DVSAPOS, _DVSBPOS)
#define DVS_POS_Y_MASK REG_GENMASK(31, 16)
#define DVS_POS_Y(y) REG_FIELD_PREP(DVS_POS_Y_MASK, (y))
#define DVS_POS_X_MASK REG_GENMASK(15, 0)
#define DVS_POS_X(x) REG_FIELD_PREP(DVS_POS_X_MASK, (x))
+
#define _DVSASIZE 0x72190
+#define _DVSBSIZE 0x73190
+#define DVSSIZE(pipe) _MMIO_PIPE(pipe, _DVSASIZE, _DVSBSIZE)
#define DVS_HEIGHT_MASK REG_GENMASK(31, 16)
#define DVS_HEIGHT(h) REG_FIELD_PREP(DVS_HEIGHT_MASK, (h))
#define DVS_WIDTH_MASK REG_GENMASK(15, 0)
#define DVS_WIDTH(w) REG_FIELD_PREP(DVS_WIDTH_MASK, (w))
+
#define _DVSAKEYVAL 0x72194
+#define _DVSBKEYVAL 0x73194
+#define DVSKEYVAL(pipe) _MMIO_PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+
#define _DVSAKEYMSK 0x72198
+#define _DVSBKEYMSK 0x73198
+#define DVSKEYMSK(pipe) _MMIO_PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
+
#define _DVSASURF 0x7219c
+#define _DVSBSURF 0x7319c
+#define DVSSURF(pipe) _MMIO_PIPE(pipe, _DVSASURF, _DVSBSURF)
#define DVS_ADDR_MASK REG_GENMASK(31, 12)
+
#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSBKEYMAXVAL 0x731a0
+#define DVSKEYMAX(pipe) _MMIO_PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
+
#define _DVSATILEOFF 0x721a4
+#define _DVSBTILEOFF 0x731a4
+#define DVSTILEOFF(pipe) _MMIO_PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
#define DVS_OFFSET_Y_MASK REG_GENMASK(31, 16)
#define DVS_OFFSET_Y(y) REG_FIELD_PREP(DVS_OFFSET_Y_MASK, (y))
#define DVS_OFFSET_X_MASK REG_GENMASK(15, 0)
#define DVS_OFFSET_X(x) REG_FIELD_PREP(DVS_OFFSET_X_MASK, (x))
+
#define _DVSASURFLIVE 0x721ac
+#define _DVSBSURFLIVE 0x731ac
+#define DVSSURFLIVE(pipe) _MMIO_PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE)
+
#define _DVSAGAMC_G4X 0x721e0 /* g4x */
+#define _DVSBGAMC_G4X 0x731e0 /* g4x */
+#define DVSGAMC_G4X(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMC_G4X, _DVSBGAMC_G4X) + (5 - (i)) * 4) /* 6 x u0.8 */
+
#define _DVSASCALE 0x72204
+#define _DVSBSCALE 0x73204
+#define DVSSCALE(pipe) _MMIO_PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVS_SCALE_ENABLE REG_BIT(31)
#define DVS_FILTER_MASK REG_GENMASK(30, 29)
#define DVS_FILTER_MEDIUM REG_FIELD_PREP(DVS_FILTER_MASK, 0)
@@ -64,42 +103,19 @@
#define DVS_SRC_WIDTH(w) REG_FIELD_PREP(DVS_SRC_WIDTH_MASK, (w))
#define DVS_SRC_HEIGHT_MASK REG_GENMASK(10, 0)
#define DVS_SRC_HEIGHT(h) REG_FIELD_PREP(DVS_SRC_HEIGHT_MASK, (h))
-#define _DVSAGAMC_ILK 0x72300 /* ilk/snb */
-#define _DVSAGAMCMAX_ILK 0x72340 /* ilk/snb */
-#define _DVSBCNTR 0x73180
-#define _DVSBLINOFF 0x73184
-#define _DVSBSTRIDE 0x73188
-#define _DVSBPOS 0x7318c
-#define _DVSBSIZE 0x73190
-#define _DVSBKEYVAL 0x73194
-#define _DVSBKEYMSK 0x73198
-#define _DVSBSURF 0x7319c
-#define _DVSBKEYMAXVAL 0x731a0
-#define _DVSBTILEOFF 0x731a4
-#define _DVSBSURFLIVE 0x731ac
-#define _DVSBGAMC_G4X 0x731e0 /* g4x */
-#define _DVSBSCALE 0x73204
+#define _DVSAGAMC_ILK 0x72300 /* ilk/snb */
#define _DVSBGAMC_ILK 0x73300 /* ilk/snb */
-#define _DVSBGAMCMAX_ILK 0x73340 /* ilk/snb */
-
-#define DVSCNTR(pipe) _MMIO_PIPE(pipe, _DVSACNTR, _DVSBCNTR)
-#define DVSLINOFF(pipe) _MMIO_PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
-#define DVSSTRIDE(pipe) _MMIO_PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
-#define DVSPOS(pipe) _MMIO_PIPE(pipe, _DVSAPOS, _DVSBPOS)
-#define DVSSURF(pipe) _MMIO_PIPE(pipe, _DVSASURF, _DVSBSURF)
-#define DVSKEYMAX(pipe) _MMIO_PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
-#define DVSSIZE(pipe) _MMIO_PIPE(pipe, _DVSASIZE, _DVSBSIZE)
-#define DVSSCALE(pipe) _MMIO_PIPE(pipe, _DVSASCALE, _DVSBSCALE)
-#define DVSTILEOFF(pipe) _MMIO_PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
-#define DVSKEYVAL(pipe) _MMIO_PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
-#define DVSKEYMSK(pipe) _MMIO_PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
-#define DVSSURFLIVE(pipe) _MMIO_PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE)
-#define DVSGAMC_G4X(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMC_G4X, _DVSBGAMC_G4X) + (5 - (i)) * 4) /* 6 x u0.8 */
#define DVSGAMC_ILK(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMC_ILK, _DVSBGAMC_ILK) + (i) * 4) /* 16 x u0.10 */
+
+#define _DVSAGAMCMAX_ILK 0x72340 /* ilk/snb */
+#define _DVSBGAMCMAX_ILK 0x73340 /* ilk/snb */
#define DVSGAMCMAX_ILK(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMCMAX_ILK, _DVSBGAMCMAX_ILK) + (i) * 4) /* 3 x u1.10 */
+/* ivb/hsw/bdw sprite */
#define _SPRA_CTL 0x70280
+#define _SPRB_CTL 0x71280
+#define SPRCTL(pipe) _MMIO_PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
#define SPRITE_ENABLE REG_BIT(31)
#define SPRITE_PIPE_GAMMA_ENABLE REG_BIT(30)
#define SPRITE_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
@@ -125,31 +141,67 @@
#define SPRITE_PLANE_GAMMA_DISABLE REG_BIT(13)
#define SPRITE_TILED REG_BIT(10)
#define SPRITE_DEST_KEY REG_BIT(2)
-#define _SPRA_LINOFF 0x70284
+
+#define _SPRA_LINOFF 0x70284 /* ivb */
+#define _SPRB_LINOFF 0x71284 /* ivb */
+#define SPRLINOFF(pipe) _MMIO_PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
+
#define _SPRA_STRIDE 0x70288
+#define _SPRB_STRIDE 0x71288
+#define SPRSTRIDE(pipe) _MMIO_PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+
#define _SPRA_POS 0x7028c
+#define _SPRB_POS 0x7128c
+#define SPRPOS(pipe) _MMIO_PIPE(pipe, _SPRA_POS, _SPRB_POS)
#define SPRITE_POS_Y_MASK REG_GENMASK(31, 16)
#define SPRITE_POS_Y(y) REG_FIELD_PREP(SPRITE_POS_Y_MASK, (y))
#define SPRITE_POS_X_MASK REG_GENMASK(15, 0)
#define SPRITE_POS_X(x) REG_FIELD_PREP(SPRITE_POS_X_MASK, (x))
+
#define _SPRA_SIZE 0x70290
+#define _SPRB_SIZE 0x71290
+#define SPRSIZE(pipe) _MMIO_PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
#define SPRITE_HEIGHT_MASK REG_GENMASK(31, 16)
#define SPRITE_HEIGHT(h) REG_FIELD_PREP(SPRITE_HEIGHT_MASK, (h))
#define SPRITE_WIDTH_MASK REG_GENMASK(15, 0)
#define SPRITE_WIDTH(w) REG_FIELD_PREP(SPRITE_WIDTH_MASK, (w))
+
#define _SPRA_KEYVAL 0x70294
+#define _SPRB_KEYVAL 0x71294
+#define SPRKEYVAL(pipe) _MMIO_PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+
#define _SPRA_KEYMSK 0x70298
+#define _SPRB_KEYMSK 0x71298
+#define SPRKEYMSK(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+
#define _SPRA_SURF 0x7029c
+#define _SPRB_SURF 0x7129c
+#define SPRSURF(pipe) _MMIO_PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
#define SPRITE_ADDR_MASK REG_GENMASK(31, 12)
+
#define _SPRA_KEYMAX 0x702a0
-#define _SPRA_TILEOFF 0x702a4
+#define _SPRB_KEYMAX 0x712a0
+#define SPRKEYMAX(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+
+#define _SPRA_TILEOFF 0x702a4 /* ivb */
+#define _SPRB_TILEOFF 0x712a4 /* ivb */
+#define SPRTILEOFF(pipe) _MMIO_PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
#define SPRITE_OFFSET_Y_MASK REG_GENMASK(31, 16)
#define SPRITE_OFFSET_Y(y) REG_FIELD_PREP(SPRITE_OFFSET_Y_MASK, (y))
#define SPRITE_OFFSET_X_MASK REG_GENMASK(15, 0)
#define SPRITE_OFFSET_X(x) REG_FIELD_PREP(SPRITE_OFFSET_X_MASK, (x))
-#define _SPRA_OFFSET 0x702a4
+
+#define _SPRA_OFFSET 0x702a4 /* hsw/bdw */
+#define _SPRB_OFFSET 0x712a4 /* hsw/bdw */
+#define SPROFFSET(pipe) _MMIO_PIPE(pipe, _SPRA_OFFSET, _SPRB_OFFSET)
+
#define _SPRA_SURFLIVE 0x702ac
-#define _SPRA_SCALE 0x70304
+#define _SPRB_SURFLIVE 0x712ac
+#define SPRSURFLIVE(pipe) _MMIO_PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
+
+#define _SPRA_SCALE 0x70304 /* ivb */
+#define _SPRB_SCALE 0x71304 /* ivb */
+#define SPRSCALE(pipe) _MMIO_PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
#define SPRITE_SCALE_ENABLE REG_BIT(31)
#define SPRITE_FILTER_MASK REG_GENMASK(30, 29)
#define SPRITE_FILTER_MEDIUM REG_FIELD_PREP(SPRITE_FILTER_MASK, 0)
@@ -161,45 +213,28 @@
#define SPRITE_SRC_WIDTH(w) REG_FIELD_PREP(SPRITE_SRC_WIDTH_MASK, (w))
#define SPRITE_SRC_HEIGHT_MASK REG_GENMASK(10, 0)
#define SPRITE_SRC_HEIGHT(h) REG_FIELD_PREP(SPRITE_SRC_HEIGHT_MASK, (h))
-#define _SPRA_GAMC 0x70400
-#define _SPRA_GAMC16 0x70440
-#define _SPRA_GAMC17 0x7044c
-#define _SPRB_CTL 0x71280
-#define _SPRB_LINOFF 0x71284
-#define _SPRB_STRIDE 0x71288
-#define _SPRB_POS 0x7128c
-#define _SPRB_SIZE 0x71290
-#define _SPRB_KEYVAL 0x71294
-#define _SPRB_KEYMSK 0x71298
-#define _SPRB_SURF 0x7129c
-#define _SPRB_KEYMAX 0x712a0
-#define _SPRB_TILEOFF 0x712a4
-#define _SPRB_OFFSET 0x712a4
-#define _SPRB_SURFLIVE 0x712ac
-#define _SPRB_SCALE 0x71304
+#define _SPRA_GAMC 0x70400
#define _SPRB_GAMC 0x71400
-#define _SPRB_GAMC16 0x71440
-#define _SPRB_GAMC17 0x7144c
-
-#define SPRCTL(pipe) _MMIO_PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
-#define SPRLINOFF(pipe) _MMIO_PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
-#define SPRSTRIDE(pipe) _MMIO_PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
-#define SPRPOS(pipe) _MMIO_PIPE(pipe, _SPRA_POS, _SPRB_POS)
-#define SPRSIZE(pipe) _MMIO_PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
-#define SPRKEYVAL(pipe) _MMIO_PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
-#define SPRKEYMSK(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
-#define SPRSURF(pipe) _MMIO_PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
-#define SPRKEYMAX(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
-#define SPRTILEOFF(pipe) _MMIO_PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
-#define SPROFFSET(pipe) _MMIO_PIPE(pipe, _SPRA_OFFSET, _SPRB_OFFSET)
-#define SPRSCALE(pipe) _MMIO_PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
#define SPRGAMC(pipe, i) _MMIO(_PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC) + (i) * 4) /* 16 x u0.10 */
+
+#define _SPRA_GAMC16 0x70440
+#define _SPRB_GAMC16 0x71440
#define SPRGAMC16(pipe, i) _MMIO(_PIPE(pipe, _SPRA_GAMC16, _SPRB_GAMC16) + (i) * 4) /* 3 x u1.10 */
+
+#define _SPRA_GAMC17 0x7044c
+#define _SPRB_GAMC17 0x7144c
#define SPRGAMC17(pipe, i) _MMIO(_PIPE(pipe, _SPRA_GAMC17, _SPRB_GAMC17) + (i) * 4) /* 3 x u2.10 */
-#define SPRSURFLIVE(pipe) _MMIO_PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
+
+/* vlv/chv sprite */
+#define _VLV_SPR(pipe, plane_id, reg_a, reg_b) \
+ _PIPE((pipe) * 2 + (plane_id) - PLANE_SPRITE0, (reg_a), (reg_b))
+#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \
+ _MMIO(_VLV_SPR((pipe), (plane_id), (reg_a), (reg_b)))
#define _SPACNTR (VLV_DISPLAY_BASE + 0x72180)
+#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280)
+#define SPCNTR(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACNTR, _SPBCNTR)
#define SP_ENABLE REG_BIT(31)
#define SP_PIPE_GAMMA_ENABLE REG_BIT(30)
#define SP_FORMAT_MASK REG_GENMASK(29, 26)
@@ -225,80 +260,85 @@
#define SP_ROTATE_180 REG_BIT(15)
#define SP_TILED REG_BIT(10)
#define SP_MIRROR REG_BIT(8) /* CHV pipe B */
+
#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184)
+#define _SPBLINOFF (VLV_DISPLAY_BASE + 0x72284)
+#define SPLINOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPALINOFF, _SPBLINOFF)
+
#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188)
+#define _SPBSTRIDE (VLV_DISPLAY_BASE + 0x72288)
+#define SPSTRIDE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASTRIDE, _SPBSTRIDE)
+
#define _SPAPOS (VLV_DISPLAY_BASE + 0x7218c)
+#define _SPBPOS (VLV_DISPLAY_BASE + 0x7228c)
+#define SPPOS(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAPOS, _SPBPOS)
#define SP_POS_Y_MASK REG_GENMASK(31, 16)
#define SP_POS_Y(y) REG_FIELD_PREP(SP_POS_Y_MASK, (y))
#define SP_POS_X_MASK REG_GENMASK(15, 0)
#define SP_POS_X(x) REG_FIELD_PREP(SP_POS_X_MASK, (x))
+
#define _SPASIZE (VLV_DISPLAY_BASE + 0x72190)
+#define _SPBSIZE (VLV_DISPLAY_BASE + 0x72290)
+#define SPSIZE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASIZE, _SPBSIZE)
#define SP_HEIGHT_MASK REG_GENMASK(31, 16)
#define SP_HEIGHT(h) REG_FIELD_PREP(SP_HEIGHT_MASK, (h))
#define SP_WIDTH_MASK REG_GENMASK(15, 0)
#define SP_WIDTH(w) REG_FIELD_PREP(SP_WIDTH_MASK, (w))
+
#define _SPAKEYMINVAL (VLV_DISPLAY_BASE + 0x72194)
+#define _SPBKEYMINVAL (VLV_DISPLAY_BASE + 0x72294)
+#define SPKEYMINVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMINVAL, _SPBKEYMINVAL)
+
#define _SPAKEYMSK (VLV_DISPLAY_BASE + 0x72198)
+#define _SPBKEYMSK (VLV_DISPLAY_BASE + 0x72298)
+#define SPKEYMSK(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMSK, _SPBKEYMSK)
+
#define _SPASURF (VLV_DISPLAY_BASE + 0x7219c)
+#define _SPBSURF (VLV_DISPLAY_BASE + 0x7229c)
+#define SPSURF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURF, _SPBSURF)
#define SP_ADDR_MASK REG_GENMASK(31, 12)
+
#define _SPAKEYMAXVAL (VLV_DISPLAY_BASE + 0x721a0)
+#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0)
+#define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
+
#define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4)
+#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4)
+#define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF)
#define SP_OFFSET_Y_MASK REG_GENMASK(31, 16)
#define SP_OFFSET_Y(y) REG_FIELD_PREP(SP_OFFSET_Y_MASK, (y))
#define SP_OFFSET_X_MASK REG_GENMASK(15, 0)
#define SP_OFFSET_X(x) REG_FIELD_PREP(SP_OFFSET_X_MASK, (x))
+
#define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8)
+#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8)
+#define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA)
#define SP_CONST_ALPHA_ENABLE REG_BIT(31)
#define SP_CONST_ALPHA_MASK REG_GENMASK(7, 0)
#define SP_CONST_ALPHA(alpha) REG_FIELD_PREP(SP_CONST_ALPHA_MASK, (alpha))
+
#define _SPASURFLIVE (VLV_DISPLAY_BASE + 0x721ac)
+#define _SPBSURFLIVE (VLV_DISPLAY_BASE + 0x722ac)
+#define SPSURFLIVE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURFLIVE, _SPBSURFLIVE)
+
#define _SPACLRC0 (VLV_DISPLAY_BASE + 0x721d0)
+#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0)
+#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0)
#define SP_CONTRAST_MASK REG_GENMASK(26, 18)
#define SP_CONTRAST(x) REG_FIELD_PREP(SP_CONTRAST_MASK, (x)) /* u3.6 */
#define SP_BRIGHTNESS_MASK REG_GENMASK(7, 0)
#define SP_BRIGHTNESS(x) REG_FIELD_PREP(SP_BRIGHTNESS_MASK, (x)) /* s8 */
+
#define _SPACLRC1 (VLV_DISPLAY_BASE + 0x721d4)
+#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4)
+#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1)
#define SP_SH_SIN_MASK REG_GENMASK(26, 16)
#define SP_SH_SIN(x) REG_FIELD_PREP(SP_SH_SIN_MASK, (x)) /* s4.7 */
#define SP_SH_COS_MASK REG_GENMASK(9, 0)
#define SP_SH_COS(x) REG_FIELD_PREP(SP_SH_COS_MASK, (x)) /* u3.7 */
-#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721e0)
-#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280)
-#define _SPBLINOFF (VLV_DISPLAY_BASE + 0x72284)
-#define _SPBSTRIDE (VLV_DISPLAY_BASE + 0x72288)
-#define _SPBPOS (VLV_DISPLAY_BASE + 0x7228c)
-#define _SPBSIZE (VLV_DISPLAY_BASE + 0x72290)
-#define _SPBKEYMINVAL (VLV_DISPLAY_BASE + 0x72294)
-#define _SPBKEYMSK (VLV_DISPLAY_BASE + 0x72298)
-#define _SPBSURF (VLV_DISPLAY_BASE + 0x7229c)
-#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0)
-#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4)
-#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8)
-#define _SPBSURFLIVE (VLV_DISPLAY_BASE + 0x722ac)
-#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0)
-#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4)
+#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721e0)
#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722e0)
-
-#define _VLV_SPR(pipe, plane_id, reg_a, reg_b) \
- _PIPE((pipe) * 2 + (plane_id) - PLANE_SPRITE0, (reg_a), (reg_b))
-#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \
- _MMIO(_VLV_SPR((pipe), (plane_id), (reg_a), (reg_b)))
-
-#define SPCNTR(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACNTR, _SPBCNTR)
-#define SPLINOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPALINOFF, _SPBLINOFF)
-#define SPSTRIDE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASTRIDE, _SPBSTRIDE)
-#define SPPOS(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAPOS, _SPBPOS)
-#define SPSIZE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASIZE, _SPBSIZE)
-#define SPKEYMINVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMINVAL, _SPBKEYMINVAL)
-#define SPKEYMSK(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMSK, _SPBKEYMSK)
-#define SPSURF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURF, _SPBSURF)
-#define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
-#define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF)
-#define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA)
-#define SPSURFLIVE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURFLIVE, _SPBSURFLIVE)
-#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0)
-#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1)
#define SPGAMC(pipe, plane_id, i) _MMIO(_VLV_SPR((pipe), (plane_id), _SPAGAMC, _SPBGAMC) + (5 - (i)) * 4) /* 6 x u0.10 */
/*
diff --git a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
index a76b48ebc2d3..4853c4806004 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
@@ -74,7 +74,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
* pipe simultaneously.
*/
if (DISPLAY_VER(dev_priv) >= 9 &&
- to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
+ to_intel_plane(plane)->id >= PLANE_3 &&
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/display/intel_tdf.h b/drivers/gpu/drm/i915/display/intel_tdf.h
new file mode 100644
index 000000000000..353cde21f6c2
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_tdf.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_TDF_H__
+#define __INTEL_TDF_H__
+
+/*
+ * TDF (Transient-Data-Flush) is needed for Xe2+ where special L3:XD caching can
+ * be enabled through various PAT index modes. Idea is to use this caching mode
+ * when for example rendering onto the display surface, with the promise that
+ * KMD will ensure transient cache entries are always flushed by the time we do
+ * the display flip, since display engine is never coherent with CPU/GPU caches.
+ */
+
+struct drm_i915_private;
+
+#ifdef I915
+static inline void intel_td_flush(struct drm_i915_private *i915) {}
+#else
+void intel_td_flush(struct drm_i915_private *i915);
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c
index baf7354cb6e2..5b065e1cd4e4 100644
--- a/drivers/gpu/drm/i915/display/intel_vblank.c
+++ b/drivers/gpu/drm/i915/display/intel_vblank.c
@@ -5,6 +5,7 @@
#include "i915_drv.h"
#include "i915_reg.h"
+#include "intel_color.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -89,9 +90,7 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
htotal = mode->crtc_htotal;
hsync_start = mode->crtc_hsync_start;
- vbl_start = mode->crtc_vblank_start;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- vbl_start = DIV_ROUND_UP(vbl_start, 2);
+ vbl_start = intel_mode_vblank_start(mode);
/* Convert to pixel count */
vbl_start *= htotal;
@@ -104,7 +103,8 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
* we get a low value that's stable across two reads of the high
* register.
*/
- frame = intel_de_read64_2x32(dev_priv, PIPEFRAMEPIXEL(pipe), PIPEFRAME(pipe));
+ frame = intel_de_read64_2x32(dev_priv, PIPEFRAMEPIXEL(dev_priv, pipe),
+ PIPEFRAME(dev_priv, pipe));
pixel = frame & PIPE_PIXEL_MASK;
frame = (frame >> PIPE_FRAME_LOW_SHIFT) & 0xffffff;
@@ -126,14 +126,13 @@ u32 g4x_get_vblank_counter(struct drm_crtc *crtc)
if (!vblank->max_vblank_count)
return 0;
- return intel_de_read(dev_priv, PIPE_FRMCOUNT_G4X(pipe));
+ return intel_de_read(dev_priv, PIPE_FRMCOUNT_G4X(dev_priv, pipe));
}
static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct drm_vblank_crtc *vblank =
- &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
const struct drm_display_mode *mode = &vblank->hwmode;
u32 htotal = mode->crtc_htotal;
u32 clock = mode->crtc_clock;
@@ -178,8 +177,7 @@ static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
*/
static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
{
- struct drm_vblank_crtc *vblank =
- &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
const struct drm_display_mode *mode = &vblank->hwmode;
u32 vblank_start = mode->crtc_vblank_start;
u32 vtotal = mode->crtc_vtotal;
@@ -192,6 +190,44 @@ static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
return scanline;
}
+static int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ /*
+ * The scanline counter increments at the leading edge of hsync.
+ *
+ * On most platforms it starts counting from vtotal-1 on the
+ * first active line. That means the scanline counter value is
+ * always one less than what we would expect. Ie. just after
+ * start of vblank, which also occurs at start of hsync (on the
+ * last active line), the scanline counter will read vblank_start-1.
+ *
+ * On gen2 the scanline counter starts counting from 1 instead
+ * of vtotal-1, so we have to subtract one.
+ *
+ * On HSW+ the behaviour of the scanline counter depends on the output
+ * type. For DP ports it behaves like most other platforms, but on HDMI
+ * there's an extra 1 line difference. So we need to add two instead of
+ * one to the value.
+ *
+ * On VLV/CHV DSI the scanline counter would appear to increment
+ * approx. 1/3 of a scanline before start of vblank. Unfortunately
+ * that means we can't tell whether we're in vblank or not while
+ * we're on that particular line. We must still set scanline_offset
+ * to 1 so that the vblank timestamps come out correct when we query
+ * the scanline counter from within the vblank interrupt handler.
+ * However if queried just before the start of vblank we'll get an
+ * answer that's slightly in the future.
+ */
+ if (DISPLAY_VER(i915) == 2)
+ return -1;
+ else if (HAS_DDI(i915) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return 2;
+ else
+ return 1;
+}
+
/*
* intel_de_read_fw(), only for fast reads of display block, no need for
* forcewake etc.
@@ -200,25 +236,20 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- const struct drm_display_mode *mode;
- struct drm_vblank_crtc *vblank;
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
+ const struct drm_display_mode *mode = &vblank->hwmode;
enum pipe pipe = crtc->pipe;
int position, vtotal;
if (!crtc->active)
return 0;
- vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
- mode = &vblank->hwmode;
-
if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP)
return __intel_get_crtc_scanline_from_timestamp(crtc);
- vtotal = mode->crtc_vtotal;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- vtotal /= 2;
+ vtotal = intel_mode_vtotal(mode);
- position = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & PIPEDSL_LINE_MASK;
+ position = intel_de_read_fw(dev_priv, PIPEDSL(dev_priv, pipe)) & PIPEDSL_LINE_MASK;
/*
* On HSW, the DSL reg (0x70000) appears to return 0 if we
@@ -237,7 +268,8 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
for (i = 0; i < 100; i++) {
udelay(1);
- temp = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & PIPEDSL_LINE_MASK;
+ temp = intel_de_read_fw(dev_priv,
+ PIPEDSL(dev_priv, pipe)) & PIPEDSL_LINE_MASK;
if (temp != position) {
position = temp;
break;
@@ -249,19 +281,14 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
* See update_scanline_offset() for the details on the
* scanline_offset adjustment.
*/
- return (position + crtc->scanline_offset) % vtotal;
+ return (position + vtotal + crtc->scanline_offset) % vtotal;
}
int intel_crtc_scanline_to_hw(struct intel_crtc *crtc, int scanline)
{
- const struct drm_vblank_crtc *vblank =
- &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
+ const struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
const struct drm_display_mode *mode = &vblank->hwmode;
- int vtotal;
-
- vtotal = mode->crtc_vtotal;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- vtotal /= 2;
+ int vtotal = intel_mode_vtotal(mode);
return (scanline + vtotal - crtc->scanline_offset) % vtotal;
}
@@ -318,15 +345,9 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
htotal = mode->crtc_htotal;
hsync_start = mode->crtc_hsync_start;
- vtotal = mode->crtc_vtotal;
- vbl_start = mode->crtc_vblank_start;
- vbl_end = mode->crtc_vblank_end;
-
- if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
- vbl_start = DIV_ROUND_UP(vbl_start, 2);
- vbl_end /= 2;
- vtotal /= 2;
- }
+ vtotal = intel_mode_vtotal(mode);
+ vbl_start = intel_mode_vblank_start(mode);
+ vbl_end = intel_mode_vblank_end(mode);
/*
* Enter vblank critical section, as we will do multiple
@@ -366,7 +387,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
* We can split this into vertical and horizontal
* scanout position.
*/
- position = (intel_de_read_fw(dev_priv, PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
+ position = (intel_de_read_fw(dev_priv, PIPEFRAMEPIXEL(dev_priv, pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
/* convert to pixel counts */
vbl_start *= htotal;
@@ -455,7 +476,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc)
static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
- i915_reg_t reg = PIPEDSL(pipe);
+ i915_reg_t reg = PIPEDSL(dev_priv, pipe);
u32 line1, line2;
line1 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
@@ -487,53 +508,6 @@ void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
wait_for_pipe_scanline_moving(crtc, true);
}
-static int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
- const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
-
- /*
- * The scanline counter increments at the leading edge of hsync.
- *
- * On most platforms it starts counting from vtotal-1 on the
- * first active line. That means the scanline counter value is
- * always one less than what we would expect. Ie. just after
- * start of vblank, which also occurs at start of hsync (on the
- * last active line), the scanline counter will read vblank_start-1.
- *
- * On gen2 the scanline counter starts counting from 1 instead
- * of vtotal-1, so we have to subtract one (or rather add vtotal-1
- * to keep the value positive), instead of adding one.
- *
- * On HSW+ the behaviour of the scanline counter depends on the output
- * type. For DP ports it behaves like most other platforms, but on HDMI
- * there's an extra 1 line difference. So we need to add two instead of
- * one to the value.
- *
- * On VLV/CHV DSI the scanline counter would appear to increment
- * approx. 1/3 of a scanline before start of vblank. Unfortunately
- * that means we can't tell whether we're in vblank or not while
- * we're on that particular line. We must still set scanline_offset
- * to 1 so that the vblank timestamps come out correct when we query
- * the scanline counter from within the vblank interrupt handler.
- * However if queried just before the start of vblank we'll get an
- * answer that's slightly in the future.
- */
- if (DISPLAY_VER(i915) == 2) {
- int vtotal;
-
- vtotal = adjusted_mode->crtc_vtotal;
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- vtotal /= 2;
-
- return vtotal - 1;
- } else if (HAS_DDI(i915) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
- return 2;
- } else {
- return 1;
- }
-}
-
void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,
bool vrr_enable)
{
@@ -583,7 +557,17 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,
spin_unlock_irqrestore(&i915->drm.vblank_time_lock, irqflags);
}
-static int intel_mode_vblank_start(const struct drm_display_mode *mode)
+int intel_mode_vdisplay(const struct drm_display_mode *mode)
+{
+ int vdisplay = mode->crtc_vdisplay;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ vdisplay = DIV_ROUND_UP(vdisplay, 2);
+
+ return vdisplay;
+}
+
+int intel_mode_vblank_start(const struct drm_display_mode *mode)
{
int vblank_start = mode->crtc_vblank_start;
@@ -593,6 +577,26 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode)
return vblank_start;
}
+int intel_mode_vblank_end(const struct drm_display_mode *mode)
+{
+ int vblank_end = mode->crtc_vblank_end;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ vblank_end /= 2;
+
+ return vblank_end;
+}
+
+int intel_mode_vtotal(const struct drm_display_mode *mode)
+{
+ int vtotal = mode->crtc_vtotal;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ vtotal /= 2;
+
+ return vtotal;
+}
+
void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state,
struct intel_vblank_evade_ctx *evade)
@@ -646,7 +650,8 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
* DSB execution waits for the transcoder's undelayed vblank,
* hence we must kick off the commit before that.
*/
- if (new_crtc_state->dsb || new_crtc_state->update_m_n || new_crtc_state->update_lrr)
+ if (intel_color_uses_dsb(new_crtc_state) ||
+ new_crtc_state->update_m_n || new_crtc_state->update_lrr)
evade->min -= adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
}
diff --git a/drivers/gpu/drm/i915/display/intel_vblank.h b/drivers/gpu/drm/i915/display/intel_vblank.h
index ec6c3da3eeac..7e526f6861e4 100644
--- a/drivers/gpu/drm/i915/display/intel_vblank.h
+++ b/drivers/gpu/drm/i915/display/intel_vblank.h
@@ -10,6 +10,7 @@
#include <linux/types.h>
struct drm_crtc;
+struct drm_display_mode;
struct intel_crtc;
struct intel_crtc_state;
@@ -19,6 +20,11 @@ struct intel_vblank_evade_ctx {
bool need_vlv_dsi_wa;
};
+int intel_mode_vdisplay(const struct drm_display_mode *mode);
+int intel_mode_vblank_start(const struct drm_display_mode *mode);
+int intel_mode_vblank_end(const struct drm_display_mode *mode);
+int intel_mode_vtotal(const struct drm_display_mode *mode);
+
void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state,
struct intel_vblank_evade_ctx *evade);
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index 228702c0e492..1af8407e2081 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -39,6 +39,50 @@
#include "intel_bios.h"
+/* EDID derived structures */
+struct bdb_edid_pnp_id {
+ u16 mfg_name;
+ u16 product_code;
+ u32 serial;
+ u8 mfg_week;
+ u8 mfg_year;
+} __packed;
+
+struct bdb_edid_product_name {
+ char name[13];
+} __packed;
+
+struct bdb_edid_dtd {
+ u16 clock; /**< In 10khz */
+ u8 hactive_lo;
+ u8 hblank_lo;
+ u8 hblank_hi:4;
+ u8 hactive_hi:4;
+ u8 vactive_lo;
+ u8 vblank_lo;
+ u8 vblank_hi:4;
+ u8 vactive_hi:4;
+ u8 hsync_off_lo;
+ u8 hsync_pulse_width_lo;
+ u8 vsync_pulse_width_lo:4;
+ u8 vsync_off_lo:4;
+ u8 vsync_pulse_width_hi:2;
+ u8 vsync_off_hi:2;
+ u8 hsync_pulse_width_hi:2;
+ u8 hsync_off_hi:2;
+ u8 himage_lo;
+ u8 vimage_lo;
+ u8 vimage_hi:4;
+ u8 himage_hi:4;
+ u8 h_border;
+ u8 v_border;
+ u8 rsvd1:3;
+ u8 digital:2;
+ u8 vsync_positive:1;
+ u8 hsync_positive:1;
+ u8 non_interlaced:1;
+} __packed;
+
/**
* struct vbt_header - VBT Header structure
* @signature: VBT signature, always starts with "$VBT"
@@ -97,40 +141,56 @@ struct bdb_header {
enum bdb_block_id {
BDB_GENERAL_FEATURES = 1,
BDB_GENERAL_DEFINITIONS = 2,
- BDB_OLD_TOGGLE_LIST = 3,
+ BDB_DISPLAY_TOGGLE = 3,
BDB_MODE_SUPPORT_LIST = 4,
BDB_GENERIC_MODE_TABLE = 5,
- BDB_EXT_MMIO_REGS = 6,
- BDB_SWF_IO = 7,
- BDB_SWF_MMIO = 8,
- BDB_PSR = 9,
+ BDB_EXT_MMIO_REGS = 6, /* VBIOS only */
+ BDB_SWF_IO = 7, /* VBIOS only */
+ BDB_SWF_MMIO = 8, /* VBIOS only */
+ BDB_DOT_CLOCK_OVERRIDE_ALM = 9,
+ BDB_PSR = 9, /* 165+ */
BDB_MODE_REMOVAL_TABLE = 10,
BDB_CHILD_DEVICE_TABLE = 11,
BDB_DRIVER_FEATURES = 12,
BDB_DRIVER_PERSISTENCE = 13,
- BDB_EXT_TABLE_PTRS = 14,
+ BDB_EXT_TABLE_PTRS = 14, /* VBIOS only */
BDB_DOT_CLOCK_OVERRIDE = 15,
- BDB_DISPLAY_SELECT = 16,
+ BDB_DISPLAY_SELECT_OLD = 16,
+ BDB_SV_TEST_FUNCTIONS = 17,
BDB_DRIVER_ROTATION = 18,
- BDB_DISPLAY_REMOVE = 19,
+ BDB_DISPLAY_REMOVE_OLD = 19,
BDB_OEM_CUSTOM = 20,
BDB_EFP_LIST = 21, /* workarounds for VGA hsync/vsync */
BDB_SDVO_LVDS_OPTIONS = 22,
- BDB_SDVO_PANEL_DTDS = 23,
- BDB_SDVO_LVDS_PNP_IDS = 24,
- BDB_SDVO_LVDS_POWER_SEQ = 25,
+ BDB_SDVO_LVDS_DTD = 23,
+ BDB_SDVO_LVDS_PNP_ID = 24,
+ BDB_SDVO_LVDS_PPS = 25,
BDB_TV_OPTIONS = 26,
BDB_EDP = 27,
- BDB_LVDS_OPTIONS = 40,
- BDB_LVDS_LFP_DATA_PTRS = 41,
- BDB_LVDS_LFP_DATA = 42,
- BDB_LVDS_BACKLIGHT = 43,
+ BDB_EFP_DTD = 28, /* 161+ */
+ BDB_DISPLAY_SELECT_IVB = 29, /* 164+ */
+ BDB_DISPLAY_REMOVE_IVB = 30, /* 164+ */
+ BDB_DISPLAY_SELECT_HSW = 31, /* 166+ */
+ BDB_DISPLAY_REMOVE_HSW = 32, /* 166+ */
+ BDB_LFP_OPTIONS = 40,
+ BDB_LFP_DATA_PTRS = 41,
+ BDB_LFP_DATA = 42,
+ BDB_LFP_BACKLIGHT = 43,
BDB_LFP_POWER = 44,
- BDB_MIPI_CONFIG = 52,
- BDB_MIPI_SEQUENCE = 53,
- BDB_COMPRESSION_PARAMETERS = 56,
- BDB_GENERIC_DTD = 58,
- BDB_SKIP = 254, /* VBIOS private block, ignore */
+ BDB_EDP_BFI = 45, /* 160+ */
+ BDB_CHROMATICITY = 46, /* 169+ */
+ BDB_MIPI = 50, /* 170-172 */
+ BDB_FIXED_SET_MODE = 51, /* 172+ */
+ BDB_MIPI_CONFIG = 52, /* 175+ */
+ BDB_MIPI_SEQUENCE = 53, /* 177+ */
+ BDB_RGB_PALETTE = 54, /* 180+ */
+ BDB_COMPRESSION_PARAMETERS_OLD = 55, /* 198-212 */
+ BDB_COMPRESSION_PARAMETERS = 56, /* 213+ */
+ BDB_VSWING_PREEMPH = 57, /* 218+ */
+ BDB_GENERIC_DTD = 58, /* 229+ */
+ BDB_INT15_HOOK = 252, /* VBIOS only */
+ BDB_PRD_TABLE = 253,
+ BDB_SKIP = 254, /* VBIOS only */
};
/*
@@ -198,10 +258,11 @@ struct bdb_general_features {
/* Device handle */
#define DEVICE_HANDLE_CRT 0x0001
+#define DEVICE_HANDLE_TV 0x0002 /* ???-214 */
#define DEVICE_HANDLE_EFP1 0x0004
#define DEVICE_HANDLE_EFP2 0x0040
#define DEVICE_HANDLE_EFP3 0x0020
-#define DEVICE_HANDLE_EFP4 0x0010 /* 194+ */
+#define DEVICE_HANDLE_EFP4 0x0010
#define DEVICE_HANDLE_EFP5 0x0002 /* 215+ */
#define DEVICE_HANDLE_EFP6 0x0001 /* 217+ */
#define DEVICE_HANDLE_EFP7 0x0100 /* 217+ */
@@ -517,6 +578,114 @@ struct bdb_general_definitions {
} __packed;
/*
+ * Block 3 - Display Toggle Option Block
+ */
+
+struct bdb_display_toggle {
+ u8 feature_bits;
+ u16 num_entries; /* ALM only */
+ u16 list[]; /* ALM only */
+} __packed;
+
+/*
+ * Block 4 - Mode Support List
+ */
+
+struct bdb_mode_support_list {
+ u8 intel_mode_number[0];
+ u16 mode_list_length;
+} __packed;
+
+/*
+ * Block 5 - Generic Mode Table
+ */
+
+struct generic_mode_table {
+ u16 x_res;
+ u16 y_res;
+ u8 color_depths;
+ u8 refresh_rate[3];
+ u8 reserved;
+ u8 text_cols;
+ u8 text_rows;
+ u8 font_height;
+ u16 page_size;
+ u8 misc;
+} __packed;
+
+struct generic_mode_timings {
+ u32 dotclock_khz;
+ u16 hdisplay;
+ u16 htotal;
+ u16 hblank_start;
+ u16 hblank_end;
+ u16 hsync_start;
+ u16 hsync_end;
+ u16 vdisplay;
+ u16 vtotal;
+ u16 vblank_start;
+ u16 vblank_end;
+ u16 vsync_start;
+ u16 vsync_end;
+} __packed;
+
+struct generic_mode_timings_alm {
+ struct generic_mode_timings timings;
+ u8 wm_8bpp;
+ u8 burst_8bpp;
+ u8 wm_16bpp;
+ u8 burst_16bpp;
+ u8 wm_32bpp;
+ u8 burst_32bpp;
+} __packed;
+
+struct bdb_generic_mode_table_alm {
+ struct generic_mode_table table;
+ struct generic_mode_timings_alm timings[3];
+} __packed;
+
+struct bdb_generic_mode_table_mgm {
+ u16 mode_flag;
+ struct generic_mode_table table;
+ struct generic_mode_timings timings[3];
+} __packed;
+
+/*
+ * Block 6 - Extended MMIO Register Table, VBIOS only
+ * Block 7 - IO Software Flag Table, VBIOS only
+ * Block 8 - MMIO SWF Register Table, VBIOS only
+ */
+struct bdb_reg_table {
+ u16 table_id;
+ u8 data_access_size;
+ /*
+ * offset,value tuples:
+ * data_access_size==0xce -> u8,u8
+ * data_access_size==0x02 -> u32,u32
+ */
+ /* u16 table_end_marker; */
+} __packed;
+
+/*
+ * Block 9 - Undocumented table (ALM only)
+ */
+
+struct dot_clock_override_entry_gen2 {
+ u32 dotclock;
+ u8 n;
+ u8 m1;
+ u8 m2;
+ u8 p1:5;
+ u8 p1_div_by_2:1;
+ u8 reserved:1;
+ u8 p2_div_by_4:1;
+} __packed;
+
+struct bdb_dot_clock_override_alm {
+ struct dot_clock_override_entry_gen2 t[0];
+} __packed;
+
+/*
* Block 9 - SRD Feature Block
*/
@@ -544,6 +713,29 @@ struct bdb_psr {
} __packed;
/*
+ * Block 10 - Mode Removal Table
+ */
+
+struct mode_removal_table {
+ u16 x_res;
+ u16 y_res;
+ u8 bpp;
+ u16 refresh_rate;
+ u8 removal_flags;
+ u16 panel_flags;
+} __packed;
+
+struct bdb_mode_removal {
+ u8 row_size; /* 8 or 10 bytes */
+ /*
+ * VBT spec says this is always 20 entries,
+ * but ALM seems to have only 15 entries.
+ */
+ struct mode_removal_table modes[];
+ /* u16 terminator; 0x0000 */
+} __packed;
+
+/*
* Block 12 - Driver Features Data Block
*/
@@ -622,6 +814,139 @@ struct bdb_driver_features {
} __packed;
/*
+ * Block 13 - Driver Persistent Algorithm
+ */
+
+struct bdb_driver_persistence {
+ u16 hotkey_persistent_algorithm:1;
+ u16 lid_switch_persistent_algorithm:1;
+ u16 power_management_persistent_algorithm:1;
+ u16 hotkey_persistent_on_mds_twin:1;
+ u16 hotkey_persistent_on_refresh_rate:1;
+ u16 hotkey_persistent_on_restore_pipe:1;
+ u16 hotkey_persistent_on_mode:1;
+ u16 edid_persistent_on_mode:1;
+ u16 dvo_hotplug_persistent_on_mode:1;
+ u16 docking_persistent_algorithm:1;
+ u16 rsvd:6;
+ u8 persistent_max_config;
+} __packed;
+
+/*
+ * Block 15 - Dot Clock Override Table
+ */
+
+struct dot_clock_override_entry_gen3 {
+ u32 dotclock;
+ u8 n;
+ u8 m1;
+ u8 m2;
+ u8 p1;
+ u8 p2;
+} __packed;
+
+struct bdb_dot_clock_override {
+ u8 row_size; /* 8 == gen2, 9 == gen3+ */
+ u8 num_rows;
+ struct dot_clock_override_entry_gen3 table[]; /* or _gen2 */
+} __packed;
+
+/*
+ * Block 16 - Toggle List Block (pre-HSW)
+ */
+
+struct toggle_list_entry_old {
+ u8 display_select_pipe_a;
+ u8 display_select_pipe_b;
+ u8 caps;
+} __packed;
+
+struct toggle_list_table_old {
+ u16 num_entries;
+ u8 entry_size;
+ struct toggle_list_entry_old list[];
+} __packed;
+
+struct bdb_display_select_old {
+ /* each table has variable size! */
+ struct toggle_list_table_old tables[4];
+} __packed;
+
+/*
+ * Block 17 - SV Test Functions
+ */
+
+struct bdb_sv_test_functions {
+ u8 sv_bits[8];
+} __packed;
+
+/*
+ * Block 18 - Driver Rotation
+ */
+
+struct bdb_driver_rotation {
+ u8 rotation_enable;
+ u8 rotation_flags_1;
+ u16 rotation_flags_2;
+ u32 rotation_flags_3;
+ u32 rotation_flags_4;
+} __packed;
+
+/*
+ * Block 19 - Display Configuration Removal Table (pre-IVB)
+ */
+
+struct display_remove_entry_old {
+ u8 display_select_pipe_a;
+ u8 display_select_pipe_b;
+} __packed;
+
+struct bdb_display_remove_old {
+ u8 num_entries;
+ u8 entry_size;
+ struct display_remove_entry_old table[];
+} __packed;
+
+/*
+ * Block 20 - OEM Customizable Modes
+ */
+
+struct oem_mode {
+ u8 enable_in_vbios:1;
+ u8 enable_in_os:1;
+ u8 enable_in_gop:1; /* 207+ */
+ u8 reserved:5;
+ u8 display_flags; /* ???-216 */
+ u16 x_res;
+ u16 y_res;
+ u8 color_depth;
+ u8 refresh_rate;
+ struct bdb_edid_dtd dtd;
+ u16 display_flags_2; /* 217+ */
+} __packed;
+
+struct bdb_oem_custom {
+ u8 num_entries;
+ u8 entry_size;
+ struct oem_mode modes[];
+} __packed;
+
+/*
+ * Block 21 - EFP List
+ */
+
+struct efp_entry {
+ u16 mfg_name;
+ u16 product_code;
+} __packed;
+
+struct bdb_efp_list {
+ u8 num_entries;
+ u8 entry_size;
+ struct efp_entry efp[];
+} __packed;
+
+/*
* Block 22 - SDVO LVDS General Options
*/
@@ -642,42 +967,47 @@ struct bdb_sdvo_lvds_options {
} __packed;
/*
- * Block 23 - SDVO LVDS Panel DTDs
+ * Block 23 - SDVO LVDS DTD
*/
-struct lvds_dvo_timing {
- u16 clock; /**< In 10khz */
- u8 hactive_lo;
- u8 hblank_lo;
- u8 hblank_hi:4;
- u8 hactive_hi:4;
- u8 vactive_lo;
- u8 vblank_lo;
- u8 vblank_hi:4;
- u8 vactive_hi:4;
- u8 hsync_off_lo;
- u8 hsync_pulse_width_lo;
- u8 vsync_pulse_width_lo:4;
- u8 vsync_off_lo:4;
- u8 vsync_pulse_width_hi:2;
- u8 vsync_off_hi:2;
- u8 hsync_pulse_width_hi:2;
- u8 hsync_off_hi:2;
- u8 himage_lo;
- u8 vimage_lo;
- u8 vimage_hi:4;
- u8 himage_hi:4;
- u8 h_border;
- u8 v_border;
- u8 rsvd1:3;
- u8 digital:2;
- u8 vsync_positive:1;
- u8 hsync_positive:1;
- u8 non_interlaced:1;
+struct bdb_sdvo_lvds_dtd {
+ struct bdb_edid_dtd dtd[4];
} __packed;
-struct bdb_sdvo_panel_dtds {
- struct lvds_dvo_timing dtds[4];
+/*
+ * Block 24 - SDVO LVDS PnP ID
+ */
+
+struct bdb_sdvo_lvds_pnp_id {
+ struct bdb_edid_pnp_id pnp_id[4];
+} __packed;
+
+/*
+ * Block 25 - SDVO LVDS PPS
+ */
+
+struct sdvo_lvds_pps {
+ u16 t0; /* power on */
+ u16 t1; /* backlight on */
+ u16 t2; /* backlight off */
+ u16 t3; /* power off */
+ u16 t4; /* power cycle */
+} __packed;
+
+struct bdb_sdvo_lvds_pps {
+ struct sdvo_lvds_pps pps[4];
+} __packed;
+
+/*
+ * Block 26 - TV Options Block
+ */
+
+struct bdb_tv_options {
+ u16 underscan_overscan_hdtv_component:2;
+ u16 rsvd1:10;
+ u16 underscan_overscan_hdtv_dvi:2;
+ u16 add_modes_to_avoid_overscan_issue:1;
+ u16 d_connector_support:1;
} __packed;
/*
@@ -749,13 +1079,88 @@ struct bdb_edp {
struct edp_apical_params apical_params[16]; /* 203+ */
u16 edp_fast_link_training_rate[16]; /* 224+ */
u16 edp_max_port_link_rate[16]; /* 244+ */
+ u16 edp_dsc_disable; /* 251+ */
+} __packed;
+
+/*
+ * Block 28 - EFP DTD Block
+ */
+
+struct bdb_efp_dtd {
+ struct bdb_edid_dtd dtd[3];
+} __packed;
+
+/*
+ * Block 29 - Toggle List Block (IVB)
+ */
+
+struct toggle_list_entry_ivb {
+ u8 display_select;
+} __packed;
+
+struct toggle_list_table_ivb {
+ u16 num_entries;
+ u8 entry_size;
+ struct toggle_list_entry_ivb list[];
+} __packed;
+
+struct bdb_display_select_ivb {
+ /* each table has variable size! */
+ struct toggle_list_table_ivb tables[4];
+} __packed;
+
+/*
+ * Block 30 - Display Configuration Removal Table (IVB)
+ */
+
+struct display_remove_entry_ivb {
+ u8 display_select;
+} __packed;
+
+struct bdb_display_remove_ivb {
+ u8 num_entries;
+ u8 entry_size;
+ struct display_remove_entry_ivb table[];
+} __packed;
+
+/*
+ * Block 31 - Toggle List Block (HSW+)
+ */
+
+struct toggle_list_entry_hsw {
+ u16 display_select;
+} __packed;
+
+struct toggle_list_table_hsw {
+ u16 num_entries;
+ u8 entry_size;
+ struct toggle_list_entry_hsw list[];
+} __packed;
+
+struct bdb_display_select_hsw {
+ /* each table has variable size! */
+ struct toggle_list_table_hsw tables[4];
+} __packed;
+
+/*
+ * Block 32 - Display Configuration Removal Table (HSW+)
+ */
+
+struct display_remove_entry_hsw {
+ u16 display_select;
+} __packed;
+
+struct bdb_display_remove_hsw {
+ u8 num_entries;
+ u8 entry_size;
+ struct display_remove_entry_hsw table[];
} __packed;
/*
* Block 40 - LFP Data Block
*/
-struct bdb_lvds_options {
+struct bdb_lfp_options {
u8 panel_type;
u8 panel_type2; /* 212+ */
/* LVDS capabilities, stored in a dword */
@@ -788,22 +1193,22 @@ struct bdb_lvds_options {
/*
* Block 41 - LFP Data Table Pointers
*/
-struct lvds_lfp_data_ptr_table {
+struct lfp_data_ptr_table {
u16 offset; /* offsets are from start of bdb */
u8 table_size;
} __packed;
/* LFP pointer table contains entries to the struct below */
-struct lvds_lfp_data_ptr {
- struct lvds_lfp_data_ptr_table fp_timing;
- struct lvds_lfp_data_ptr_table dvo_timing;
- struct lvds_lfp_data_ptr_table panel_pnp_id;
+struct lfp_data_ptr {
+ struct lfp_data_ptr_table fp_timing;
+ struct lfp_data_ptr_table dvo_timing;
+ struct lfp_data_ptr_table panel_pnp_id;
} __packed;
-struct bdb_lvds_lfp_data_ptrs {
- u8 lvds_entries;
- struct lvds_lfp_data_ptr ptr[16];
- struct lvds_lfp_data_ptr_table panel_name; /* (156-163?)+ */
+struct bdb_lfp_data_ptrs {
+ u8 num_entries;
+ struct lfp_data_ptr ptr[16];
+ struct lfp_data_ptr_table panel_name; /* (156-163?)+ */
} __packed;
/*
@@ -811,7 +1216,7 @@ struct bdb_lvds_lfp_data_ptrs {
*/
/* LFP data has 3 blocks per entry */
-struct lvds_fp_timing {
+struct fp_timing {
u16 x_res;
u16 y_res;
u32 lvds_reg;
@@ -827,46 +1232,34 @@ struct lvds_fp_timing {
u16 terminator;
} __packed;
-struct lvds_pnp_id {
- u16 mfg_name;
- u16 product_code;
- u32 serial;
- u8 mfg_week;
- u8 mfg_year;
-} __packed;
-
/*
* For reference only. fp_timing has variable size so
* the data must be accessed using the data table pointers.
* Do not use this directly!
*/
-struct lvds_lfp_data_entry {
- struct lvds_fp_timing fp_timing;
- struct lvds_dvo_timing dvo_timing;
- struct lvds_pnp_id pnp_id;
+struct lfp_data_entry {
+ struct fp_timing fp_timing;
+ struct bdb_edid_dtd dvo_timing;
+ struct bdb_edid_pnp_id pnp_id;
} __packed;
-struct bdb_lvds_lfp_data {
- struct lvds_lfp_data_entry data[16];
+struct bdb_lfp_data {
+ struct lfp_data_entry data[16];
} __packed;
-struct lvds_lfp_panel_name {
- u8 name[13];
-} __packed;
-
-struct lvds_lfp_black_border {
+struct lfp_black_border {
u8 top; /* 227+ */
u8 bottom; /* 227+ */
u8 left; /* 238+ */
u8 right; /* 238+ */
} __packed;
-struct bdb_lvds_lfp_data_tail {
- struct lvds_lfp_panel_name panel_name[16]; /* (156-163?)+ */
+struct bdb_lfp_data_tail {
+ struct bdb_edid_product_name panel_name[16]; /* (156-163?)+ */
u16 scaling_enable; /* 187+ */
u8 seamless_drrs_min_refresh_rate[16]; /* 188+ */
u8 pixel_overlap_count[16]; /* 208+ */
- struct lvds_lfp_black_border black_border[16]; /* 227+ */
+ struct lfp_black_border black_border[16]; /* 227+ */
u16 dual_lfp_port_sync_enable; /* 231+ */
u16 gpu_dithering_for_banding_artifacts; /* 245+ */
} __packed;
@@ -899,7 +1292,7 @@ struct lfp_brightness_level {
u16 reserved;
} __packed;
-struct bdb_lfp_backlight_data {
+struct bdb_lfp_backlight {
u8 entry_size;
struct lfp_backlight_data_entry data[16];
u8 level[16]; /* 162-233 */
@@ -959,6 +1352,122 @@ struct bdb_lfp_power {
} __packed;
/*
+ * Block 45 - eDP BFI Block
+ */
+
+struct edp_bfi {
+ u8 enable_bfi_in_driver:1;
+ u8 enable_brightness_control_in_cui:1;
+ u8 reserved:6;
+ u8 brightness_percentage_when_bfi_disabled;
+} __packed;
+
+struct bdb_edp_bfi {
+ u8 bfi_structure_size;
+ struct edp_bfi bfi[16];
+} __packed;
+
+/*
+ * Block 46 - Chromaticity For Narrow Gamut Panel Configuration Block
+ */
+
+struct chromaticity {
+ u8 chromaticity_enable:1;
+ u8 chromaticity_from_edid_base_block:1;
+ u8 rsvd:6;
+
+ u8 green_y_lo:2;
+ u8 green_x_lo:2;
+ u8 red_y_lo:2;
+ u8 red_x_lo:2;
+ u8 white_y_lo:2;
+ u8 white_x_lo:2;
+ u8 blue_y_lo:2;
+ u8 blue_x_lo:2;
+
+ u8 red_x_hi;
+ u8 red_y_hi;
+ u8 green_x_hi;
+ u8 green_y_hi;
+ u8 blue_x_hi;
+ u8 blue_y_hi;
+ u8 white_x_hi;
+ u8 white_y_hi;
+} __packed;
+
+struct luminance_and_gamma {
+ u8 luminance_enable:1; /* 211+ */
+ u8 gamma_enable:1; /* 211+ */
+ u8 rsvd:6;
+
+ u16 min_luminance; /* 211+ */
+ u16 max_luminance; /* 211+ */
+ u16 one_percent_max_luminance; /* 211+ */
+ u8 gamma; /* 211+ */
+} __packed;
+
+struct bdb_chromaticity {
+ struct chromaticity chromaticity[16];
+ struct luminance_and_gamma luminance_and_gamma[16]; /* 211+ */
+} __packed;
+
+/*
+ * Block 50 - MIPI Block
+ */
+
+struct mipi_data {
+ u16 panel_identifier;
+ u16 bridge_revision;
+
+ u32 dithering:1;
+ u32 pixel_format_18bpp:1;
+ u32 reserved1:1;
+ u32 dphy_params_valid:1;
+ u32 reserved2:28;
+
+ u16 port_info;
+
+ u16 reserved3:2;
+ u16 num_lanes:2;
+ u16 reserved4:12;
+
+ u16 virtual_channel_num:2;
+ u16 video_transfer_mode:2;
+ u16 reserved5:12;
+
+ u32 dsi_ddr_clock;
+ u32 renesas_bridge_ref_clock;
+ u16 power_conservation;
+
+ u32 prepare_count:5;
+ u32 reserved6:3;
+ u32 clk_zero_count:8;
+ u32 trail_count:5;
+ u32 reserved7:3;
+ u32 exit_zero_count:6;
+ u32 reserved8:2;
+
+ u32 high_low_switch_count;
+ u32 lp_byte_clock;
+ u32 clock_lane_switch_time_counter;
+ u32 panel_color_depth;
+} __packed;
+
+struct bdb_mipi {
+ struct mipi_data mipi[16];
+} __packed;
+
+/*
+ * Block 51 - Fixed Set Mode Table
+ */
+
+struct bdb_fixed_set_mode {
+ u8 enable;
+ u32 x_res;
+ u32 y_res;
+} __packed;
+
+/*
* Block 52 - MIPI Configuration Block
*/
@@ -981,6 +1490,17 @@ struct bdb_mipi_sequence {
} __packed;
/*
+ * Block 55 - RGB Palette Table
+ */
+
+struct bdb_rgb_palette {
+ u8 is_enabled;
+ u8 red[256];
+ u8 blue[256];
+ u8 green[256];
+} __packed;
+
+/*
* Block 56 - Compression Parameters
*/
@@ -1032,6 +1552,16 @@ struct bdb_compression_parameters {
} __packed;
/*
+ * Block 57 - Vswing PreEmphasis Table
+ */
+
+struct bdb_vswing_preemph {
+ u8 num_tables;
+ u8 num_columns;
+ u32 tables[];
+} __packed;
+
+/*
* Block 58 - Generic DTD Block
*/
@@ -1061,4 +1591,29 @@ struct bdb_generic_dtd {
struct generic_dtd_entry dtd[]; /* up to 24 DTD's */
} __packed;
+/*
+ * Block 253 - PRD Table
+ */
+
+struct prd_entry_old {
+ u8 displays_attached;
+ u8 display_in_pipe_a;
+ u8 display_in_pipe_b;
+} __packed;
+
+struct bdb_prd_table_old {
+ struct prd_entry_old list[0]; /* ???-216 */
+ u16 num_entries; /* ???-216 */
+} __packed;
+
+struct prd_entry_new {
+ u16 primary_display;
+ u16 secondary_display;
+} __packed;
+
+struct bdb_prd_table_new {
+ u16 num_entries; /* 217+ */
+ struct prd_entry_new list[]; /* 217+ */
+} __packed;
+
#endif /* _INTEL_VBT_DEFS_H_ */
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 17d6572f9d0a..b9687b7692b8 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -10,7 +10,6 @@
#include <drm/display/drm_dsc_helper.h>
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -380,7 +379,7 @@ 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);
- if (crtc_state->bigjoiner_pipes)
+ if (crtc_state->joiner_pipes)
num_vdsc_instances *= 2;
return num_vdsc_instances;
@@ -761,11 +760,11 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dss_ctl1_val = 0;
- if (crtc_state->bigjoiner_pipes && !crtc_state->dsc.compression_enable) {
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
- dss_ctl1_val |= UNCOMPRESSED_JOINER_SLAVE;
+ if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) {
+ if (intel_crtc_is_joiner_secondary(crtc_state))
+ dss_ctl1_val |= UNCOMPRESSED_JOINER_SECONDARY;
else
- dss_ctl1_val |= UNCOMPRESSED_JOINER_MASTER;
+ dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY;
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
}
@@ -789,10 +788,10 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
dss_ctl1_val |= JOINER_ENABLE;
}
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
dss_ctl1_val |= BIG_JOINER_ENABLE;
- if (!intel_crtc_is_bigjoiner_slave(crtc_state))
- dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
+ if (!intel_crtc_is_joiner_secondary(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);
intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val);
@@ -805,7 +804,7 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
/* Disable only if either of them is enabled */
if (old_crtc_state->dsc.compression_enable ||
- old_crtc_state->bigjoiner_pipes) {
+ old_crtc_state->joiner_pipes) {
intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
index 8b21dc8e26d5..f921ad67b587 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
@@ -32,13 +32,13 @@
_ICL_PIPE_DSS_CTL1_PB, \
_ICL_PIPE_DSS_CTL1_PC)
#define BIG_JOINER_ENABLE (1 << 29)
-#define MASTER_BIG_JOINER_ENABLE (1 << 28)
+#define PRIMARY_BIG_JOINER_ENABLE (1 << 28)
#define VGA_CENTERING_ENABLE (1 << 27)
#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 UNCOMPRESSED_JOINER_MASTER (1 << 21)
-#define UNCOMPRESSED_JOINER_SLAVE (1 << 20)
+#define UNCOMPRESSED_JOINER_PRIMARY (1 << 21)
+#define UNCOMPRESSED_JOINER_SECONDARY (1 << 20)
#define _ICL_PIPE_DSS_CTL2_PB 0x78204
#define _ICL_PIPE_DSS_CTL2_PC 0x78404
diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
index 4b98833bfa8c..0b5916c15307 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -3,6 +3,7 @@
* Copyright © 2019 Intel Corporation
*/
+#include <linux/delay.h>
#include <linux/vgaarb.h>
#include <video/vga.h>
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 894ee97b3e1b..5a0da64c7db3 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -9,8 +9,12 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_vrr.h"
+#include "intel_vrr_regs.h"
#include "intel_dp.h"
+#define FIXED_POINT_PRECISION 100
+#define CMRR_PRECISION_TOLERANCE 10
+
bool intel_vrr_is_capable(struct intel_connector *connector)
{
const struct drm_display_info *info = &connector->base.display_info;
@@ -106,6 +110,53 @@ int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state)
return crtc_state->vrr.vmax - intel_vrr_vblank_exit_length(crtc_state);
}
+static bool
+is_cmrr_frac_required(struct intel_crtc_state *crtc_state)
+{
+ int calculated_refresh_k, actual_refresh_k, pixel_clock_per_line;
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ if (!HAS_CMRR(i915))
+ return false;
+
+ actual_refresh_k =
+ drm_mode_vrefresh(adjusted_mode) * FIXED_POINT_PRECISION;
+ pixel_clock_per_line =
+ adjusted_mode->crtc_clock * 1000 / adjusted_mode->crtc_htotal;
+ calculated_refresh_k =
+ pixel_clock_per_line * FIXED_POINT_PRECISION / adjusted_mode->crtc_vtotal;
+
+ if ((actual_refresh_k - calculated_refresh_k) < CMRR_PRECISION_TOLERANCE)
+ return false;
+
+ return true;
+}
+
+static unsigned int
+cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required)
+{
+ int multiplier_m = 1, multiplier_n = 1, vtotal, desired_refresh_rate;
+ u64 adjusted_pixel_rate;
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+
+ desired_refresh_rate = drm_mode_vrefresh(adjusted_mode);
+
+ if (video_mode_required) {
+ multiplier_m = 1001;
+ multiplier_n = 1000;
+ }
+
+ crtc_state->cmrr.cmrr_n = mul_u32_u32(desired_refresh_rate * adjusted_mode->crtc_htotal,
+ multiplier_n);
+ vtotal = DIV_ROUND_UP_ULL(mul_u32_u32(adjusted_mode->crtc_clock * 1000, multiplier_n),
+ crtc_state->cmrr.cmrr_n);
+ adjusted_pixel_rate = mul_u32_u32(adjusted_mode->crtc_clock * 1000, multiplier_m);
+ crtc_state->cmrr.cmrr_m = do_div(adjusted_pixel_rate, crtc_state->cmrr.cmrr_n);
+
+ return vtotal;
+}
+
void
intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -115,6 +166,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
struct intel_dp *intel_dp = intel_attached_dp(connector);
+ bool is_edp = intel_dp_is_edp(intel_dp);
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct drm_display_info *info = &connector->base.display_info;
int vmin, vmax;
@@ -123,7 +175,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
* FIXME all joined pipes share the same transcoder.
* Need to account for that during VRR toggle/push/etc.
*/
- if (crtc_state->bigjoiner_pipes)
+ if (crtc_state->joiner_pipes)
return;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
@@ -159,6 +211,39 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
/*
+ * When panel is VRR capable and userspace has
+ * not enabled adaptive sync mode then Fixed Average
+ * Vtotal mode should be enabled.
+ */
+ if (crtc_state->uapi.vrr_enabled) {
+ crtc_state->vrr.enable = true;
+ crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+ } else if (is_cmrr_frac_required(crtc_state) && is_edp) {
+ crtc_state->vrr.enable = true;
+ crtc_state->cmrr.enable = true;
+ /*
+ * TODO: Compute precise target refresh rate to determine
+ * if video_mode_required should be true. Currently set to
+ * false due to uncertainty about the precise target
+ * refresh Rate.
+ */
+ crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false);
+ crtc_state->vrr.vmin = crtc_state->vrr.vmax;
+ crtc_state->vrr.flipline = crtc_state->vrr.vmin;
+ crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+ }
+
+ if (intel_dp_as_sdp_supported(intel_dp) &&
+ crtc_state->vrr.enable) {
+ crtc_state->vrr.vsync_start =
+ (crtc_state->hw.adjusted_mode.crtc_vtotal -
+ crtc_state->hw.adjusted_mode.vsync_start);
+ crtc_state->vrr.vsync_end =
+ (crtc_state->hw.adjusted_mode.crtc_vtotal -
+ crtc_state->hw.adjusted_mode.vsync_end);
+ }
+
+ /*
* For XE_LPD+, we use guardband and pipeline override
* is deprecated.
*/
@@ -170,19 +255,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start -
crtc_state->framestart_delay - 1);
}
-
- if (crtc_state->uapi.vrr_enabled) {
- crtc_state->vrr.enable = true;
- crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
- if (intel_dp_as_sdp_supported(intel_dp)) {
- crtc_state->vrr.vsync_start =
- (crtc_state->hw.adjusted_mode.crtc_vtotal -
- crtc_state->hw.adjusted_mode.vsync_start);
- crtc_state->vrr.vsync_end =
- (crtc_state->hw.adjusted_mode.crtc_vtotal -
- crtc_state->hw.adjusted_mode.vsync_end);
- }
- }
}
static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state)
@@ -213,14 +285,30 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
0, PIPE_VBLANK_WITH_DELAY);
if (!crtc_state->vrr.flipline) {
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 0);
+ intel_de_write(dev_priv,
+ TRANS_VRR_CTL(dev_priv, cpu_transcoder), 0);
return;
}
- intel_de_write(dev_priv, TRANS_VRR_VMIN(cpu_transcoder), crtc_state->vrr.vmin - 1);
- intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), crtc_state->vrr.vmax - 1);
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), trans_vrr_ctl(crtc_state));
- intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), crtc_state->vrr.flipline - 1);
+ if (crtc_state->cmrr.enable) {
+ intel_de_write(dev_priv, TRANS_CMRR_M_HI(dev_priv, cpu_transcoder),
+ upper_32_bits(crtc_state->cmrr.cmrr_m));
+ intel_de_write(dev_priv, TRANS_CMRR_M_LO(dev_priv, cpu_transcoder),
+ lower_32_bits(crtc_state->cmrr.cmrr_m));
+ intel_de_write(dev_priv, TRANS_CMRR_N_HI(dev_priv, cpu_transcoder),
+ upper_32_bits(crtc_state->cmrr.cmrr_n));
+ intel_de_write(dev_priv, TRANS_CMRR_N_LO(dev_priv, cpu_transcoder),
+ lower_32_bits(crtc_state->cmrr.cmrr_n));
+ }
+
+ intel_de_write(dev_priv, TRANS_VRR_VMIN(dev_priv, cpu_transcoder),
+ crtc_state->vrr.vmin - 1);
+ intel_de_write(dev_priv, TRANS_VRR_VMAX(dev_priv, cpu_transcoder),
+ crtc_state->vrr.vmax - 1);
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
+ trans_vrr_ctl(crtc_state));
+ intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(dev_priv, cpu_transcoder),
+ crtc_state->vrr.flipline - 1);
}
void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
@@ -232,7 +320,7 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
TRANS_PUSH_EN | TRANS_PUSH_SEND);
}
@@ -245,7 +333,7 @@ bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return false;
- return intel_de_read(dev_priv, TRANS_PUSH(cpu_transcoder)) & TRANS_PUSH_SEND;
+ return intel_de_read(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder)) & TRANS_PUSH_SEND;
}
void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
@@ -256,15 +344,23 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), TRANS_PUSH_EN);
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
+ TRANS_PUSH_EN);
if (HAS_AS_SDP(dev_priv))
- intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_VRR_VSYNC(dev_priv, cpu_transcoder),
VRR_VSYNC_END(crtc_state->vrr.vsync_end) |
VRR_VSYNC_START(crtc_state->vrr.vsync_start));
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder),
- VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
+ if (crtc_state->cmrr.enable) {
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
+ VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE |
+ trans_vrr_ctl(crtc_state));
+ } else {
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
+ VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
+ }
}
void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
@@ -276,14 +372,16 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
if (!old_crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
trans_vrr_ctl(old_crtc_state));
- intel_de_wait_for_clear(dev_priv, TRANS_VRR_STATUS(cpu_transcoder),
+ intel_de_wait_for_clear(dev_priv,
+ TRANS_VRR_STATUS(dev_priv, cpu_transcoder),
VRR_STATUS_VRR_EN_LIVE, 1000);
- intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), 0);
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder), 0);
if (HAS_AS_SDP(dev_priv))
- intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder), 0);
+ intel_de_write(dev_priv,
+ TRANS_VRR_VSYNC(dev_priv, cpu_transcoder), 0);
}
void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
@@ -292,9 +390,21 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
u32 trans_vrr_ctl, trans_vrr_vsync;
- trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder));
+ trans_vrr_ctl = intel_de_read(dev_priv,
+ TRANS_VRR_CTL(dev_priv, cpu_transcoder));
crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE;
+ if (HAS_CMRR(dev_priv))
+ crtc_state->cmrr.enable = (trans_vrr_ctl & VRR_CTL_CMRR_ENABLE);
+
+ if (crtc_state->cmrr.enable) {
+ crtc_state->cmrr.cmrr_n =
+ intel_de_read64_2x32(dev_priv, TRANS_CMRR_N_LO(dev_priv, cpu_transcoder),
+ TRANS_CMRR_N_HI(dev_priv, cpu_transcoder));
+ crtc_state->cmrr.cmrr_m =
+ intel_de_read64_2x32(dev_priv, TRANS_CMRR_M_LO(dev_priv, cpu_transcoder),
+ TRANS_CMRR_M_HI(dev_priv, cpu_transcoder));
+ }
if (DISPLAY_VER(dev_priv) >= 13)
crtc_state->vrr.guardband =
@@ -305,9 +415,12 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl);
if (trans_vrr_ctl & VRR_CTL_FLIP_LINE_EN) {
- crtc_state->vrr.flipline = intel_de_read(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder)) + 1;
- crtc_state->vrr.vmax = intel_de_read(dev_priv, TRANS_VRR_VMAX(cpu_transcoder)) + 1;
- crtc_state->vrr.vmin = intel_de_read(dev_priv, TRANS_VRR_VMIN(cpu_transcoder)) + 1;
+ crtc_state->vrr.flipline = intel_de_read(dev_priv,
+ TRANS_VRR_FLIPLINE(dev_priv, cpu_transcoder)) + 1;
+ crtc_state->vrr.vmax = intel_de_read(dev_priv,
+ TRANS_VRR_VMAX(dev_priv, cpu_transcoder)) + 1;
+ crtc_state->vrr.vmin = intel_de_read(dev_priv,
+ TRANS_VRR_VMIN(dev_priv, cpu_transcoder)) + 1;
}
if (crtc_state->vrr.enable) {
@@ -315,7 +428,8 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
if (HAS_AS_SDP(dev_priv)) {
trans_vrr_vsync =
- intel_de_read(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder));
+ intel_de_read(dev_priv,
+ TRANS_VRR_VSYNC(dev_priv, cpu_transcoder));
crtc_state->vrr.vsync_start =
REG_FIELD_GET(VRR_VSYNC_START_MASK, trans_vrr_vsync);
crtc_state->vrr.vsync_end =
diff --git a/drivers/gpu/drm/i915/display/intel_vrr_regs.h b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
new file mode 100644
index 000000000000..6ed0e0dc97e7
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_VRR_REGS_H__
+#define __INTEL_VRR_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+/* VRR registers */
+#define _TRANS_VRR_CTL_A 0x60420
+#define _TRANS_VRR_CTL_B 0x61420
+#define _TRANS_VRR_CTL_C 0x62420
+#define _TRANS_VRR_CTL_D 0x63420
+#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_CTL_A)
+#define VRR_CTL_VRR_ENABLE REG_BIT(31)
+#define VRR_CTL_IGN_MAX_SHIFT REG_BIT(30)
+#define VRR_CTL_FLIP_LINE_EN REG_BIT(29)
+#define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3)
+#define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x))
+#define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0)
+#define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0)
+#define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x))
+
+#define _TRANS_VRR_VMAX_A 0x60424
+#define _TRANS_VRR_VMAX_B 0x61424
+#define _TRANS_VRR_VMAX_C 0x62424
+#define _TRANS_VRR_VMAX_D 0x63424
+#define TRANS_VRR_VMAX(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMAX_A)
+#define VRR_VMAX_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_VMIN_A 0x60434
+#define _TRANS_VRR_VMIN_B 0x61434
+#define _TRANS_VRR_VMIN_C 0x62434
+#define _TRANS_VRR_VMIN_D 0x63434
+#define TRANS_VRR_VMIN(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMIN_A)
+#define VRR_VMIN_MASK REG_GENMASK(15, 0)
+
+#define _TRANS_VRR_VMAXSHIFT_A 0x60428
+#define _TRANS_VRR_VMAXSHIFT_B 0x61428
+#define _TRANS_VRR_VMAXSHIFT_C 0x62428
+#define _TRANS_VRR_VMAXSHIFT_D 0x63428
+#define TRANS_VRR_VMAXSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \
+ _TRANS_VRR_VMAXSHIFT_A)
+#define VRR_VMAXSHIFT_DEC_MASK REG_GENMASK(29, 16)
+#define VRR_VMAXSHIFT_DEC REG_BIT(16)
+#define VRR_VMAXSHIFT_INC_MASK REG_GENMASK(12, 0)
+
+#define _TRANS_VRR_STATUS_A 0x6042c
+#define _TRANS_VRR_STATUS_B 0x6142c
+#define _TRANS_VRR_STATUS_C 0x6242c
+#define _TRANS_VRR_STATUS_D 0x6342c
+#define TRANS_VRR_STATUS(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS_A)
+#define VRR_STATUS_VMAX_REACHED REG_BIT(31)
+#define VRR_STATUS_NOFLIP_TILL_BNDR REG_BIT(30)
+#define VRR_STATUS_FLIP_BEF_BNDR REG_BIT(29)
+#define VRR_STATUS_NO_FLIP_FRAME REG_BIT(28)
+#define VRR_STATUS_VRR_EN_LIVE REG_BIT(27)
+#define VRR_STATUS_FLIPS_SERVICED REG_BIT(26)
+#define VRR_STATUS_VBLANK_MASK REG_GENMASK(22, 20)
+#define STATUS_FSM_IDLE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 0)
+#define STATUS_FSM_WAIT_TILL_FDB REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 1)
+#define STATUS_FSM_WAIT_TILL_FS REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 2)
+#define STATUS_FSM_WAIT_TILL_FLIP REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 3)
+#define STATUS_FSM_PIPELINE_FILL REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 4)
+#define STATUS_FSM_ACTIVE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 5)
+#define STATUS_FSM_LEGACY_VBLANK REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 6)
+
+#define _TRANS_VRR_VTOTAL_PREV_A 0x60480
+#define _TRANS_VRR_VTOTAL_PREV_B 0x61480
+#define _TRANS_VRR_VTOTAL_PREV_C 0x62480
+#define _TRANS_VRR_VTOTAL_PREV_D 0x63480
+#define TRANS_VRR_VTOTAL_PREV(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \
+ _TRANS_VRR_VTOTAL_PREV_A)
+#define VRR_VTOTAL_FLIP_BEFR_BNDR REG_BIT(31)
+#define VRR_VTOTAL_FLIP_AFTER_BNDR REG_BIT(30)
+#define VRR_VTOTAL_FLIP_AFTER_DBLBUF REG_BIT(29)
+#define VRR_VTOTAL_PREV_FRAME_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_FLIPLINE_A 0x60438
+#define _TRANS_VRR_FLIPLINE_B 0x61438
+#define _TRANS_VRR_FLIPLINE_C 0x62438
+#define _TRANS_VRR_FLIPLINE_D 0x63438
+#define TRANS_VRR_FLIPLINE(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \
+ _TRANS_VRR_FLIPLINE_A)
+#define VRR_FLIPLINE_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_STATUS2_A 0x6043c
+#define _TRANS_VRR_STATUS2_B 0x6143c
+#define _TRANS_VRR_STATUS2_C 0x6243c
+#define _TRANS_VRR_STATUS2_D 0x6343c
+#define TRANS_VRR_STATUS2(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS2_A)
+#define VRR_STATUS2_VERT_LN_CNT_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_PUSH_A 0x60a70
+#define _TRANS_PUSH_B 0x61a70
+#define _TRANS_PUSH_C 0x62a70
+#define _TRANS_PUSH_D 0x63a70
+#define TRANS_PUSH(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_PUSH_A)
+#define TRANS_PUSH_EN REG_BIT(31)
+#define TRANS_PUSH_SEND REG_BIT(30)
+
+#define _TRANS_VRR_VSYNC_A 0x60078
+#define TRANS_VRR_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VSYNC_A)
+#define VRR_VSYNC_END_MASK REG_GENMASK(28, 16)
+#define VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VRR_VSYNC_END_MASK, (vsync_end))
+#define VRR_VSYNC_START_MASK REG_GENMASK(12, 0)
+#define VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VRR_VSYNC_START_MASK, (vsync_start))
+
+/*CMRR Registers*/
+
+#define _TRANS_CMRR_M_LO_A 0x604F0
+#define TRANS_CMRR_M_LO(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_M_LO_A)
+
+#define _TRANS_CMRR_M_HI_A 0x604F4
+#define TRANS_CMRR_M_HI(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_M_HI_A)
+
+#define _TRANS_CMRR_N_LO_A 0x604F8
+#define TRANS_CMRR_N_LO(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_N_LO_A)
+
+#define _TRANS_CMRR_N_HI_A 0x604FC
+#define TRANS_CMRR_N_HI(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_N_HI_A)
+
+#define VRR_CTL_CMRR_ENABLE REG_BIT(27)
+
+#endif /* __INTEL_VRR_REGS__ */
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 860574d04f88..ba5a628b4757 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -21,6 +21,7 @@
#include "intel_psr_regs.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
+#include "skl_universal_plane_regs.h"
#include "skl_watermark.h"
#include "pxp/intel_pxp.h"
@@ -237,9 +238,9 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
{
if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
- return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
+ return BIT(PLANE_4) | BIT(PLANE_5);
else
- return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
+ return BIT(PLANE_6) | BIT(PLANE_7);
}
bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
@@ -251,7 +252,7 @@ bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
u8 icl_hdr_plane_mask(void)
{
- return BIT(PLANE_PRIMARY) | BIT(PLANE_SPRITE0) | BIT(PLANE_SPRITE1);
+ return BIT(PLANE_1) | BIT(PLANE_2) | BIT(PLANE_3);
}
bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
@@ -461,41 +462,117 @@ static int icl_plane_max_height(const struct drm_framebuffer *fb,
}
static unsigned int
+plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation,
+ unsigned int max_pixels,
+ unsigned int max_bytes)
+{
+ const struct drm_format_info *info = drm_format_info(pixel_format);
+ int cpp = info->cpp[0];
+
+ if (drm_rotation_90_or_270(rotation))
+ return min(max_pixels, max_bytes / cpp);
+ else
+ return min(max_pixels * cpp, max_bytes);
+}
+
+static unsigned int
+adl_plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation)
+{
+ unsigned int max_pixels = 65536; /* PLANE_OFFSET limit */
+ unsigned int max_bytes = 128 * 1024;
+
+ return plane_max_stride(plane, pixel_format,
+ modifier, rotation,
+ max_pixels, max_bytes);
+}
+
+static unsigned int
skl_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation)
{
+ unsigned int max_pixels = 8192; /* PLANE_OFFSET limit */
+ unsigned int max_bytes = 32 * 1024;
+
+ return plane_max_stride(plane, pixel_format,
+ modifier, rotation,
+ max_pixels, max_bytes);
+}
+
+static u32 tgl_plane_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
- const struct drm_format_info *info = drm_format_info(pixel_format);
- int cpp = info->cpp[0];
- int max_horizontal_pixels = 8192;
- int max_stride_bytes;
+ /* PLANE_SURF GGTT -> DPT alignment */
+ int mult = intel_fb_uses_dpt(fb) ? 512 : 1;
+
+ /* AUX_DIST needs only 4K alignment */
+ if (intel_fb_is_ccs_aux_plane(fb, color_plane))
+ return mult * 4 * 1024;
- if (DISPLAY_VER(i915) >= 13) {
+ switch (fb->modifier) {
+ case DRM_FORMAT_MOD_LINEAR:
+ case I915_FORMAT_MOD_X_TILED:
+ case I915_FORMAT_MOD_Y_TILED:
+ case I915_FORMAT_MOD_4_TILED:
/*
- * The stride in bytes must not exceed of the size
- * of 128K bytes. For pixel formats of 64bpp will allow
- * for a 16K pixel surface.
+ * FIXME ADL sees GGTT/DMAR faults with async
+ * flips unless we align to 16k at least.
+ * Figure out what's going on here...
*/
- max_stride_bytes = 131072;
- if (cpp == 8)
- max_horizontal_pixels = 16384;
- else
- max_horizontal_pixels = 65536;
- } else {
+ if (IS_ALDERLAKE_P(i915) && HAS_ASYNC_FLIPS(i915))
+ return mult * 16 * 1024;
+ return mult * 4 * 1024;
+ case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
+ case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+ case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
+ case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
+ case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
+ case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
+ case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
+ case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
+ case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
/*
- * "The stride in bytes must not exceed the
- * of the size of 8K pixels and 32K bytes."
+ * Align to at least 4x1 main surface
+ * tiles (16K) to match 64B of AUX.
*/
- max_stride_bytes = 32768;
+ return max(mult * 4 * 1024, 16 * 1024);
+ default:
+ MISSING_CASE(fb->modifier);
+ return 0;
}
-
- if (drm_rotation_90_or_270(rotation))
- return min(max_horizontal_pixels, max_stride_bytes / cpp);
- else
- return min(max_horizontal_pixels * cpp, max_stride_bytes);
}
+static u32 skl_plane_min_alignment(struct intel_plane *plane,
+ const struct drm_framebuffer *fb,
+ int color_plane)
+{
+ /*
+ * AUX_DIST needs only 4K alignment,
+ * as does ICL UV PLANE_SURF.
+ */
+ if (color_plane != 0)
+ return 4 * 1024;
+
+ switch (fb->modifier) {
+ case DRM_FORMAT_MOD_LINEAR:
+ case I915_FORMAT_MOD_X_TILED:
+ return 256 * 1024;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ case I915_FORMAT_MOD_Y_TILED:
+ case I915_FORMAT_MOD_Yf_TILED:
+ return 1 * 1024 * 1024;
+ default:
+ MISSING_CASE(fb->modifier);
+ return 0;
+ }
+}
/* Preoffset values for YUV to RGB Conversion */
#define PREOFF_YUV_TO_RGB_HI 0x1800
@@ -616,6 +693,66 @@ static u32 skl_plane_stride(const struct intel_plane_state *plane_state,
return stride / skl_plane_stride_mult(fb, color_plane, rotation);
}
+static u32 skl_plane_ddb_reg_val(const struct skl_ddb_entry *entry)
+{
+ if (!entry->end)
+ return 0;
+
+ return PLANE_BUF_END(entry->end - 1) |
+ PLANE_BUF_START(entry->start);
+}
+
+static u32 skl_plane_wm_reg_val(const struct skl_wm_level *level)
+{
+ u32 val = 0;
+
+ if (level->enable)
+ val |= PLANE_WM_EN;
+ if (level->ignore_lines)
+ val |= PLANE_WM_IGNORE_LINES;
+ val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
+ val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
+
+ return val;
+}
+
+static void skl_write_plane_wm(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ enum plane_id plane_id = plane->id;
+ enum pipe pipe = plane->pipe;
+ const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+ const struct skl_ddb_entry *ddb =
+ &crtc_state->wm.skl.plane_ddb[plane_id];
+ const struct skl_ddb_entry *ddb_y =
+ &crtc_state->wm.skl.plane_ddb_y[plane_id];
+ 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_fw(i915, 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_fw(i915, 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));
+}
+
static void
skl_plane_disable_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
@@ -639,7 +776,7 @@ static void icl_plane_disable_sel_fetch_arm(struct intel_plane *plane,
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
}
static void
@@ -1174,6 +1311,11 @@ skl_plane_update_arm(struct intel_plane *plane,
plane_ctl = plane_state->ctl |
skl_plane_ctl_crtc(crtc_state);
+ /* see intel_plane_atomic_calc_changes() */
+ if (plane->need_async_flip_toggle_wa &&
+ crtc_state->async_flip_planes & BIT(plane->id))
+ plane_ctl |= PLANE_CTL_ASYNC_FLIP;
+
if (DISPLAY_VER(dev_priv) >= 10)
plane_color_ctl = plane_state->color_ctl |
glk_plane_color_ctl_crtc(crtc_state);
@@ -1231,9 +1373,13 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
clip = &plane_state->psr2_sel_fetch_area;
- val = (clip->y1 + plane_state->uapi.dst.y1) << 16;
+ if (crtc_state->enable_psr2_su_region_et)
+ y = max(0, plane_state->uapi.dst.y1 - crtc_state->psr2_su_area.y1);
+ else
+ y = (clip->y1 + plane_state->uapi.dst.y1);
+ val = y << 16;
val |= plane_state->uapi.dst.x1;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_POS(pipe, plane->id), val);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_POS(pipe, plane->id), val);
x = plane_state->view.color_plane[color_plane].x;
@@ -1248,13 +1394,13 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
val = y << 16 | x;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
+ intel_de_write_fw(i915, 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, PLANE_SEL_FETCH_SIZE(pipe, plane->id), val);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val);
}
static void
@@ -1343,8 +1489,8 @@ static void icl_plane_update_sel_fetch_arm(struct intel_plane *plane,
return;
if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
- intel_de_write_fw(i915, PLANE_SEL_FETCH_CTL(pipe, plane->id),
- PLANE_SEL_FETCH_CTL_ENABLE);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id),
+ SEL_FETCH_PLANE_CTL_ENABLE);
else
icl_plane_disable_sel_fetch_arm(plane, crtc_state);
}
@@ -1605,11 +1751,12 @@ skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
int main_x, int main_y, u32 main_offset,
int ccs_plane)
{
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
const struct drm_framebuffer *fb = plane_state->hw.fb;
int aux_x = plane_state->view.color_plane[ccs_plane].x;
int aux_y = plane_state->view.color_plane[ccs_plane].y;
u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
- u32 alignment = intel_surf_alignment(fb, ccs_plane);
+ unsigned int alignment = plane->min_alignment(plane, fb, ccs_plane);
int hsub;
int vsub;
@@ -1629,8 +1776,7 @@ skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
plane_state,
ccs_plane,
aux_offset,
- aux_offset -
- alignment);
+ aux_offset - alignment);
aux_x = x * hsub + aux_x % hsub;
aux_y = y * vsub + aux_y % vsub;
}
@@ -1652,10 +1798,10 @@ int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
- const int aux_plane = skl_main_to_aux_plane(fb, 0);
- const u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
- const u32 alignment = intel_surf_alignment(fb, 0);
- const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
+ int aux_plane = skl_main_to_aux_plane(fb, 0);
+ u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
+ unsigned int alignment = plane->min_alignment(plane, fb, 0);
+ int w = drm_rect_width(&plane_state->uapi.src) >> 16;
intel_add_fb_offsets(x, y, plane_state, 0);
*offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
@@ -1702,16 +1848,16 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
- const unsigned int rotation = plane_state->hw.rotation;
+ unsigned int rotation = plane_state->hw.rotation;
int x = plane_state->uapi.src.x1 >> 16;
int y = plane_state->uapi.src.y1 >> 16;
- const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
- const int h = drm_rect_height(&plane_state->uapi.src) >> 16;
- const int min_width = intel_plane_min_width(plane, fb, 0, rotation);
- const int max_width = intel_plane_max_width(plane, fb, 0, rotation);
- const int max_height = intel_plane_max_height(plane, fb, 0, rotation);
- const int aux_plane = skl_main_to_aux_plane(fb, 0);
- const u32 alignment = intel_surf_alignment(fb, 0);
+ int w = drm_rect_width(&plane_state->uapi.src) >> 16;
+ int h = drm_rect_height(&plane_state->uapi.src) >> 16;
+ int min_width = intel_plane_min_width(plane, fb, 0, rotation);
+ int max_width = intel_plane_max_width(plane, fb, 0, rotation);
+ int max_height = intel_plane_max_height(plane, fb, 0, rotation);
+ unsigned int alignment = plane->min_alignment(plane, fb, 0);
+ int aux_plane = skl_main_to_aux_plane(fb, 0);
u32 offset;
int ret;
@@ -1799,7 +1945,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
if (ccs_plane) {
u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
- u32 alignment = intel_surf_alignment(fb, uv_plane);
+ unsigned int alignment = plane->min_alignment(plane, fb, uv_plane);
if (offset > aux_offset)
offset = intel_plane_adjust_aligned_offset(&x, &y,
@@ -2029,7 +2175,7 @@ static bool skl_plane_has_fbc(struct drm_i915_private *i915,
if (DISPLAY_VER(i915) >= 20)
return icl_is_hdr_plane(i915, plane_id);
else
- return plane_id == PLANE_PRIMARY;
+ return plane_id == PLANE_1;
}
static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
@@ -2053,7 +2199,7 @@ static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C)
return false;
- if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
+ if (plane_id != PLANE_1 && plane_id != PLANE_2)
return false;
return true;
@@ -2261,8 +2407,7 @@ static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
return pipe != PIPE_C;
return pipe != PIPE_C &&
- (plane_id == PLANE_PRIMARY ||
- plane_id == PLANE_SPRITE0);
+ (plane_id == PLANE_1 || plane_id == PLANE_2);
}
static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
@@ -2280,7 +2425,7 @@ static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
return false;
- return plane_id < PLANE_SPRITE4;
+ return plane_id < PLANE_6;
}
static u8 skl_get_plane_caps(struct drm_i915_private *i915,
@@ -2352,7 +2497,16 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->min_cdclk = skl_plane_min_cdclk;
}
- plane->max_stride = skl_plane_max_stride;
+ if (DISPLAY_VER(dev_priv) >= 13)
+ plane->max_stride = adl_plane_max_stride;
+ else
+ plane->max_stride = skl_plane_max_stride;
+
+ if (DISPLAY_VER(dev_priv) >= 12)
+ plane->min_alignment = tgl_plane_min_alignment;
+ else
+ plane->min_alignment = skl_plane_min_alignment;
+
if (DISPLAY_VER(dev_priv) >= 11) {
plane->update_noarm = icl_plane_update_noarm;
plane->update_arm = icl_plane_update_arm;
@@ -2365,9 +2519,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->get_hw_state = skl_plane_get_hw_state;
plane->check_plane = skl_plane_check;
- if (plane_id == PLANE_PRIMARY) {
- plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv,
- 9, 10);
+ if (plane_id == PLANE_1) {
+ plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(dev_priv, 9, 10);
plane->async_flip = skl_plane_async_flip;
plane->enable_flip_done = skl_plane_enable_flip_done;
plane->disable_flip_done = skl_plane_disable_flip_done;
@@ -2388,7 +2541,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
else
plane_funcs = &skl_plane_funcs;
- if (plane_id == PLANE_PRIMARY)
+ if (plane_id == PLANE_1)
plane_type = DRM_PLANE_TYPE_PRIMARY;
else
plane_type = DRM_PLANE_TYPE_OVERLAY;
@@ -2482,9 +2635,9 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
drm_WARN_ON(dev, pipe != crtc->pipe);
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
drm_dbg_kms(&dev_priv->drm,
- "Unsupported bigjoiner configuration for initial FB\n");
+ "Unsupported joiner configuration for initial FB\n");
return;
}
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h
index e92e00c01b29..541489479135 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.h
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h
@@ -12,6 +12,8 @@ struct drm_i915_private;
struct intel_crtc;
struct intel_initial_plane_config;
struct intel_plane_state;
+struct skl_ddb_entry;
+struct skl_wm_level;
enum pipe;
enum plane_id;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
new file mode 100644
index 000000000000..4ddcd7d46bbd
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
@@ -0,0 +1,442 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __SKL_UNIVERSAL_PLANE_REGS_H__
+#define __SKL_UNIVERSAL_PLANE_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _SKL_PLANE(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ _PLANE((plane), _PIPE((pipe), (reg_1_a), (reg_1_b)), _PIPE((pipe), (reg_2_a), (reg_2_b)))
+#define _SKL_PLANE_DW(pipe, plane, dw, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ (_SKL_PLANE((pipe), (plane), (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b)) + (dw) * 4)
+#define _MMIO_SKL_PLANE(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ _MMIO(_SKL_PLANE((pipe), (plane), (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b)))
+#define _MMIO_SKL_PLANE_DW(pipe, plane, dw, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ _MMIO(_SKL_PLANE_DW((pipe), (plane), (dw), (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b)))
+
+#define _SEL_FETCH(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b, reg_5_a, reg_5_b, reg_6_a, reg_6_b) \
+ _PICK_EVEN_2RANGES((plane), PLANE_5, \
+ _PIPE((pipe), (reg_1_a), (reg_1_b)), \
+ _PIPE((pipe), (reg_2_a), (reg_2_b)), \
+ _PIPE((pipe), (reg_5_a), (reg_5_b)), \
+ _PIPE((pipe), (reg_6_a), (reg_6_b)))
+#define _MMIO_SEL_FETCH(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b, reg_5_a, reg_5_b, reg_6_a, reg_6_b) \
+ _MMIO(_SEL_FETCH((pipe), (plane), \
+ (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b), \
+ (reg_5_a), (reg_5_b), (reg_6_a), (reg_6_b)))
+
+#define _PLANE_CTL_1_A 0x70180
+#define _PLANE_CTL_2_A 0x70280
+#define _PLANE_CTL_1_B 0x71180
+#define _PLANE_CTL_2_B 0x71280
+#define PLANE_CTL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_CTL_1_A, _PLANE_CTL_1_B, \
+ _PLANE_CTL_2_A, _PLANE_CTL_2_B)
+#define PLANE_CTL_ENABLE REG_BIT(31)
+#define PLANE_CTL_ARB_SLOTS_MASK REG_GENMASK(30, 28) /* icl+ */
+#define PLANE_CTL_ARB_SLOTS(x) REG_FIELD_PREP(PLANE_CTL_ARB_SLOTS_MASK, (x)) /* icl+ */
+#define PLANE_CTL_PIPE_GAMMA_ENABLE REG_BIT(30) /* Pre-GLK */
+#define PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
+/*
+ * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition
+ * expanded to include bit 23 as well. However, the shift-24 based values
+ * correctly map to the same formats in ICL, as long as bit 23 is set to 0
+ */
+#define PLANE_CTL_FORMAT_MASK_SKL REG_GENMASK(27, 24) /* pre-icl */
+#define PLANE_CTL_FORMAT_MASK_ICL REG_GENMASK(27, 23) /* icl+ */
+#define PLANE_CTL_FORMAT_YUV422 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 0)
+#define PLANE_CTL_FORMAT_NV12 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 1)
+#define PLANE_CTL_FORMAT_XRGB_2101010 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 2)
+#define PLANE_CTL_FORMAT_P010 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 3)
+#define PLANE_CTL_FORMAT_XRGB_8888 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 4)
+#define PLANE_CTL_FORMAT_P012 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 5)
+#define PLANE_CTL_FORMAT_XRGB_16161616F REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 6)
+#define PLANE_CTL_FORMAT_P016 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 7)
+#define PLANE_CTL_FORMAT_XYUV REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 8)
+#define PLANE_CTL_FORMAT_INDEXED REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 12)
+#define PLANE_CTL_FORMAT_RGB_565 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 14)
+#define PLANE_CTL_FORMAT_Y210 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 1)
+#define PLANE_CTL_FORMAT_Y212 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 3)
+#define PLANE_CTL_FORMAT_Y216 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 5)
+#define PLANE_CTL_FORMAT_Y410 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
+#define PLANE_CTL_FORMAT_Y412 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
+#define PLANE_CTL_FORMAT_Y416 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
+#define PLANE_CTL_PIPE_CSC_ENABLE REG_BIT(23) /* Pre-GLK */
+#define PLANE_CTL_KEY_ENABLE_MASK REG_GENMASK(22, 21)
+#define PLANE_CTL_KEY_ENABLE_SOURCE REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)
+#define PLANE_CTL_KEY_ENABLE_DESTINATION REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 2)
+#define PLANE_CTL_ORDER_RGBX REG_BIT(20)
+#define PLANE_CTL_YUV420_Y_PLANE REG_BIT(19)
+#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 REG_BIT(18)
+#define PLANE_CTL_YUV422_ORDER_MASK REG_GENMASK(17, 16)
+#define PLANE_CTL_YUV422_ORDER_YUYV REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 0)
+#define PLANE_CTL_YUV422_ORDER_UYVY REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 1)
+#define PLANE_CTL_YUV422_ORDER_YVYU REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 2)
+#define PLANE_CTL_YUV422_ORDER_VYUY REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 3)
+#define PLANE_CTL_RENDER_DECOMPRESSION_ENABLE REG_BIT(15)
+#define PLANE_CTL_TRICKLE_FEED_DISABLE REG_BIT(14)
+#define PLANE_CTL_CLEAR_COLOR_DISABLE REG_BIT(13) /* TGL+ */
+#define PLANE_CTL_PLANE_GAMMA_DISABLE REG_BIT(13) /* Pre-GLK */
+#define PLANE_CTL_TILED_MASK REG_GENMASK(12, 10)
+#define PLANE_CTL_TILED_LINEAR REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 0)
+#define PLANE_CTL_TILED_X REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 1)
+#define PLANE_CTL_TILED_Y REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 4)
+#define PLANE_CTL_TILED_YF REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
+#define PLANE_CTL_TILED_4 REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
+#define PLANE_CTL_ASYNC_FLIP REG_BIT(9)
+#define PLANE_CTL_FLIP_HORIZONTAL REG_BIT(8)
+#define PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE REG_BIT(4) /* TGL+ */
+#define PLANE_CTL_ALPHA_MASK REG_GENMASK(5, 4) /* Pre-GLK */
+#define PLANE_CTL_ALPHA_DISABLE REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 0)
+#define PLANE_CTL_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 2)
+#define PLANE_CTL_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 3)
+#define PLANE_CTL_ROTATE_MASK REG_GENMASK(1, 0)
+#define PLANE_CTL_ROTATE_0 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 0)
+#define PLANE_CTL_ROTATE_90 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 1)
+#define PLANE_CTL_ROTATE_180 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 2)
+#define PLANE_CTL_ROTATE_270 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 3)
+
+#define _PLANE_STRIDE_1_A 0x70188
+#define _PLANE_STRIDE_2_A 0x70288
+#define _PLANE_STRIDE_1_B 0x71188
+#define _PLANE_STRIDE_2_B 0x71288
+#define PLANE_STRIDE(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B, \
+ _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
+#define PLANE_STRIDE__MASK REG_GENMASK(11, 0)
+#define PLANE_STRIDE_(stride) REG_FIELD_PREP(PLANE_STRIDE__MASK, (stride))
+
+#define _PLANE_POS_1_A 0x7018c
+#define _PLANE_POS_2_A 0x7028c
+#define _PLANE_POS_1_B 0x7118c
+#define _PLANE_POS_2_B 0x7128c
+#define PLANE_POS(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_POS_1_A, _PLANE_POS_1_B, \
+ _PLANE_POS_2_A, _PLANE_POS_2_B)
+#define PLANE_POS_Y_MASK REG_GENMASK(31, 16)
+#define PLANE_POS_Y(y) REG_FIELD_PREP(PLANE_POS_Y_MASK, (y))
+#define PLANE_POS_X_MASK REG_GENMASK(15, 0)
+#define PLANE_POS_X(x) REG_FIELD_PREP(PLANE_POS_X_MASK, (x))
+
+#define _PLANE_SIZE_1_A 0x70190
+#define _PLANE_SIZE_2_A 0x70290
+#define _PLANE_SIZE_1_B 0x71190
+#define _PLANE_SIZE_2_B 0x71290
+#define PLANE_SIZE(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_SIZE_1_A, _PLANE_SIZE_1_B, \
+ _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
+#define PLANE_HEIGHT_MASK REG_GENMASK(31, 16)
+#define PLANE_HEIGHT(h) REG_FIELD_PREP(PLANE_HEIGHT_MASK, (h))
+#define PLANE_WIDTH_MASK REG_GENMASK(15, 0)
+#define PLANE_WIDTH(w) REG_FIELD_PREP(PLANE_WIDTH_MASK, (w))
+
+#define _PLANE_KEYVAL_1_A 0x70194
+#define _PLANE_KEYVAL_2_A 0x70294
+#define _PLANE_KEYVAL_1_B 0x71194
+#define _PLANE_KEYVAL_2_B 0x71294
+#define PLANE_KEYVAL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane),\
+ _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B, \
+ _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B)
+
+#define _PLANE_KEYMSK_1_A 0x70198
+#define _PLANE_KEYMSK_2_A 0x70298
+#define _PLANE_KEYMSK_1_B 0x71198
+#define _PLANE_KEYMSK_2_B 0x71298
+#define PLANE_KEYMSK(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B, \
+ _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B)
+#define PLANE_KEYMSK_ALPHA_ENABLE REG_BIT(31)
+
+#define _PLANE_SURF_1_A 0x7019c
+#define _PLANE_SURF_2_A 0x7029c
+#define _PLANE_SURF_1_B 0x7119c
+#define _PLANE_SURF_2_B 0x7129c
+#define PLANE_SURF(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_SURF_1_A, _PLANE_SURF_1_B, \
+ _PLANE_SURF_2_A, _PLANE_SURF_2_B)
+#define PLANE_SURF_ADDR_MASK REG_GENMASK(31, 12)
+#define PLANE_SURF_DECRYPT REG_BIT(2)
+
+#define _PLANE_KEYMAX_1_A 0x701a0
+#define _PLANE_KEYMAX_2_A 0x702a0
+#define _PLANE_KEYMAX_1_B 0x711a0
+#define _PLANE_KEYMAX_2_B 0x712a0
+#define PLANE_KEYMAX(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B, \
+ _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B)
+#define PLANE_KEYMAX_ALPHA_MASK REG_GENMASK(31, 24)
+#define PLANE_KEYMAX_ALPHA(a) REG_FIELD_PREP(PLANE_KEYMAX_ALPHA_MASK, (a))
+
+#define _PLANE_OFFSET_1_A 0x701a4
+#define _PLANE_OFFSET_2_A 0x702a4
+#define _PLANE_OFFSET_1_B 0x711a4
+#define _PLANE_OFFSET_2_B 0x712a4
+#define PLANE_OFFSET(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B, \
+ _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
+#define PLANE_OFFSET_Y_MASK REG_GENMASK(31, 16)
+#define PLANE_OFFSET_Y(y) REG_FIELD_PREP(PLANE_OFFSET_Y_MASK, (y))
+#define PLANE_OFFSET_X_MASK REG_GENMASK(15, 0)
+#define PLANE_OFFSET_X(x) REG_FIELD_PREP(PLANE_OFFSET_X_MASK, (x))
+
+#define _PLANE_SURFLIVE_1_A 0x701ac
+#define _PLANE_SURFLIVE_2_A 0x702ac
+#define _PLANE_SURFLIVE_1_B 0x711ac
+#define _PLANE_SURFLIVE_2_B 0x712ac
+#define PLANE_SURFLIVE(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_SURFLIVE_1_A, _PLANE_SURFLIVE_1_B, \
+ _PLANE_SURFLIVE_2_A, _PLANE_SURFLIVE_2_B)
+
+#define _PLANE_CC_VAL_1_A 0x701b4
+#define _PLANE_CC_VAL_2_A 0x702b4
+#define _PLANE_CC_VAL_1_B 0x711b4
+#define _PLANE_CC_VAL_2_B 0x712b4
+#define PLANE_CC_VAL(pipe, plane, dw) _MMIO_SKL_PLANE_DW((pipe), (plane), (dw), \
+ _PLANE_CC_VAL_1_A, _PLANE_CC_VAL_1_B, \
+ _PLANE_CC_VAL_2_A, _PLANE_CC_VAL_2_B)
+
+#define _PLANE_AUX_DIST_1_A 0x701c0
+#define _PLANE_AUX_DIST_2_A 0x702c0
+#define _PLANE_AUX_DIST_1_B 0x711c0
+#define _PLANE_AUX_DIST_2_B 0x712c0
+#define PLANE_AUX_DIST(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B, \
+ _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B)
+#define PLANE_AUX_DISTANCE_MASK REG_GENMASK(31, 12)
+#define PLANE_AUX_STRIDE_MASK REG_GENMASK(11, 0)
+#define PLANE_AUX_STRIDE(stride) REG_FIELD_PREP(PLANE_AUX_STRIDE_MASK, (stride))
+
+#define _PLANE_AUX_OFFSET_1_A 0x701c4
+#define _PLANE_AUX_OFFSET_2_A 0x702c4
+#define _PLANE_AUX_OFFSET_1_B 0x711c4
+#define _PLANE_AUX_OFFSET_2_B 0x712c4
+#define PLANE_AUX_OFFSET(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B, \
+ _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B)
+
+#define _PLANE_CUS_CTL_1_A 0x701c8
+#define _PLANE_CUS_CTL_2_A 0x702c8
+#define _PLANE_CUS_CTL_1_B 0x711c8
+#define _PLANE_CUS_CTL_2_B 0x712c8
+#define PLANE_CUS_CTL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_CUS_CTL_1_A, _PLANE_CUS_CTL_1_B, \
+ _PLANE_CUS_CTL_2_A, _PLANE_CUS_CTL_2_B)
+#define PLANE_CUS_ENABLE REG_BIT(31)
+#define PLANE_CUS_Y_PLANE_MASK REG_BIT(30)
+#define PLANE_CUS_Y_PLANE_4_RKL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 0)
+#define PLANE_CUS_Y_PLANE_5_RKL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 1)
+#define PLANE_CUS_Y_PLANE_6_ICL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 0)
+#define PLANE_CUS_Y_PLANE_7_ICL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 1)
+#define PLANE_CUS_HPHASE_SIGN_NEGATIVE REG_BIT(19)
+#define PLANE_CUS_HPHASE_MASK REG_GENMASK(17, 16)
+#define PLANE_CUS_HPHASE_0 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 0)
+#define PLANE_CUS_HPHASE_0_25 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 1)
+#define PLANE_CUS_HPHASE_0_5 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 2)
+#define PLANE_CUS_VPHASE_SIGN_NEGATIVE REG_BIT(15)
+#define PLANE_CUS_VPHASE_MASK REG_GENMASK(13, 12)
+#define PLANE_CUS_VPHASE_0 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 0)
+#define PLANE_CUS_VPHASE_0_25 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 1)
+#define PLANE_CUS_VPHASE_0_5 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 2)
+
+#define _PLANE_COLOR_CTL_1_A 0x701cc /* GLK+ */
+#define _PLANE_COLOR_CTL_2_A 0x702cc
+#define _PLANE_COLOR_CTL_1_B 0x711cc
+#define _PLANE_COLOR_CTL_2_B 0x712cc
+#define PLANE_COLOR_CTL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_COLOR_CTL_1_A, _PLANE_COLOR_CTL_1_B, \
+ _PLANE_COLOR_CTL_2_A, _PLANE_COLOR_CTL_2_B)
+#define PLANE_COLOR_PIPE_GAMMA_ENABLE REG_BIT(30) /* Pre-ICL */
+#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
+#define PLANE_COLOR_PIPE_CSC_ENABLE REG_BIT(23) /* Pre-ICL */
+#define PLANE_COLOR_PLANE_CSC_ENABLE REG_BIT(21) /* ICL+ */
+#define PLANE_COLOR_INPUT_CSC_ENABLE REG_BIT(20) /* ICL+ */
+#define PLANE_COLOR_CSC_MODE_MASK REG_GENMASK(19, 17)
+#define PLANE_COLOR_CSC_MODE_BYPASS REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 0)
+#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 1)
+#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 2)
+#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 3)
+#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 4)
+#define PLANE_COLOR_PLANE_GAMMA_DISABLE REG_BIT(13)
+#define PLANE_COLOR_ALPHA_MASK REG_GENMASK(5, 4)
+#define PLANE_COLOR_ALPHA_DISABLE REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 0)
+#define PLANE_COLOR_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 2)
+#define PLANE_COLOR_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 3)
+
+#define _PLANE_INPUT_CSC_RY_GY_1_A 0x701e0
+#define _PLANE_INPUT_CSC_RY_GY_2_A 0x702e0
+#define _PLANE_INPUT_CSC_RY_GY_1_B 0x711e0
+#define _PLANE_INPUT_CSC_RY_GY_2_B 0x712e0
+#define PLANE_INPUT_CSC_COEFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_INPUT_CSC_RY_GY_1_A, _PLANE_INPUT_CSC_RY_GY_1_B, \
+ _PLANE_INPUT_CSC_RY_GY_2_A, _PLANE_INPUT_CSC_RY_GY_2_B)
+
+#define _PLANE_INPUT_CSC_PREOFF_HI_1_A 0x701f8
+#define _PLANE_INPUT_CSC_PREOFF_HI_2_A 0x702f8
+#define _PLANE_INPUT_CSC_PREOFF_HI_1_B 0x711f8
+#define _PLANE_INPUT_CSC_PREOFF_HI_2_B 0x712f8
+#define PLANE_INPUT_CSC_PREOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_INPUT_CSC_PREOFF_HI_1_A, _PLANE_INPUT_CSC_PREOFF_HI_1_B, \
+ _PLANE_INPUT_CSC_PREOFF_HI_2_A, _PLANE_INPUT_CSC_PREOFF_HI_2_B)
+
+#define _PLANE_INPUT_CSC_POSTOFF_HI_1_A 0x70204
+#define _PLANE_INPUT_CSC_POSTOFF_HI_2_A 0x70304
+#define _PLANE_INPUT_CSC_POSTOFF_HI_1_B 0x71204
+#define _PLANE_INPUT_CSC_POSTOFF_HI_2_B 0x71304
+#define PLANE_INPUT_CSC_POSTOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_INPUT_CSC_POSTOFF_HI_1_A, _PLANE_INPUT_CSC_POSTOFF_HI_1_B, \
+ _PLANE_INPUT_CSC_POSTOFF_HI_2_A, _PLANE_INPUT_CSC_POSTOFF_HI_2_B)
+
+#define _PLANE_CSC_RY_GY_1_A 0x70210
+#define _PLANE_CSC_RY_GY_2_A 0x70310
+#define _PLANE_CSC_RY_GY_1_B 0x71210
+#define _PLANE_CSC_RY_GY_2_B 0x71310
+#define PLANE_CSC_COEFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_CSC_RY_GY_1_A, _PLANE_CSC_RY_GY_1_B, \
+ _PLANE_CSC_RY_GY_2_A, _PLANE_CSC_RY_GY_2_B)
+
+#define _PLANE_CSC_PREOFF_HI_1_A 0x70228
+#define _PLANE_CSC_PREOFF_HI_2_A 0x70328
+#define _PLANE_CSC_PREOFF_HI_1_B 0x71228
+#define _PLANE_CSC_PREOFF_HI_2_B 0x71328
+#define PLANE_CSC_PREOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_CSC_PREOFF_HI_1_A, _PLANE_CSC_PREOFF_HI_1_B, \
+ _PLANE_CSC_PREOFF_HI_2_A, _PLANE_CSC_PREOFF_HI_2_B)
+
+#define _PLANE_CSC_POSTOFF_HI_1_A 0x70234
+#define _PLANE_CSC_POSTOFF_HI_2_A 0x70334
+#define _PLANE_CSC_POSTOFF_HI_1_B 0x71234
+#define _PLANE_CSC_POSTOFF_HI_2_B 0x71334
+#define PLANE_CSC_POSTOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_CSC_POSTOFF_HI_1_A, _PLANE_CSC_POSTOFF_HI_1_B, \
+ _PLANE_CSC_POSTOFF_HI_2_A, _PLANE_CSC_POSTOFF_HI_2_B)
+#define _PLANE_WM_1_A_0 0x70240
+#define _PLANE_WM_1_B_0 0x71240
+#define _PLANE_WM_2_A_0 0x70340
+#define _PLANE_WM_2_B_0 0x71340
+#define PLANE_WM(pipe, plane, level) _MMIO_SKL_PLANE_DW((pipe), (plane), (level), \
+ _PLANE_WM_1_A_0, _PLANE_WM_1_B_0, \
+ _PLANE_WM_2_A_0, _PLANE_WM_2_B_0)
+#define PLANE_WM_EN REG_BIT(31)
+#define PLANE_WM_IGNORE_LINES REG_BIT(30)
+#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
+#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0)
+
+#define _PLANE_WM_SAGV_1_A 0x70258
+#define _PLANE_WM_SAGV_1_B 0x71258
+#define _PLANE_WM_SAGV_2_A 0x70358
+#define _PLANE_WM_SAGV_2_B 0x71358
+#define PLANE_WM_SAGV(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B, \
+ _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B)
+
+#define _PLANE_WM_SAGV_TRANS_1_A 0x7025c
+#define _PLANE_WM_SAGV_TRANS_1_B 0x7125c
+#define _PLANE_WM_SAGV_TRANS_2_A 0x7035c
+#define _PLANE_WM_SAGV_TRANS_2_B 0x7135c
+#define PLANE_WM_SAGV_TRANS(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B, \
+ _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B)
+
+#define _PLANE_WM_TRANS_1_A 0x70268
+#define _PLANE_WM_TRANS_1_B 0x71268
+#define _PLANE_WM_TRANS_2_A 0x70368
+#define _PLANE_WM_TRANS_2_B 0x71368
+#define PLANE_WM_TRANS(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B, \
+ _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B)
+
+#define _PLANE_CHICKEN_1_A 0x7026c /* tgl+ */
+#define _PLANE_CHICKEN_2_A 0x7036c
+#define _PLANE_CHICKEN_1_B 0x7126c
+#define _PLANE_CHICKEN_2_B 0x7136c
+#define PLANE_CHICKEN(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_CHICKEN_1_A, _PLANE_CHICKEN_1_B, \
+ _PLANE_CHICKEN_2_A, _PLANE_CHICKEN_2_B)
+#define PLANE_CHICKEN_DISABLE_DPT REG_BIT(19) /* mtl+ */
+
+#define _PLANE_NV12_BUF_CFG_1_A 0x70278
+#define _PLANE_NV12_BUF_CFG_2_A 0x70378
+#define _PLANE_NV12_BUF_CFG_1_B 0x71278
+#define _PLANE_NV12_BUF_CFG_2_B 0x71378
+#define PLANE_NV12_BUF_CFG(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B, \
+ _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B)
+
+#define _PLANE_BUF_CFG_1_A 0x7027c
+#define _PLANE_BUF_CFG_2_A 0x7037c
+#define _PLANE_BUF_CFG_1_B 0x7127c
+#define _PLANE_BUF_CFG_2_B 0x7137c
+#define PLANE_BUF_CFG(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B, \
+ _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
+/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
+#define PLANE_BUF_END_MASK REG_GENMASK(27, 16)
+#define PLANE_BUF_END(end) REG_FIELD_PREP(PLANE_BUF_END_MASK, (end))
+#define PLANE_BUF_START_MASK REG_GENMASK(11, 0)
+#define PLANE_BUF_START(start) REG_FIELD_PREP(PLANE_BUF_START_MASK, (start))
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_CTL_1_A 0x70890
+#define _SEL_FETCH_PLANE_CTL_2_A 0x708b0
+#define _SEL_FETCH_PLANE_CTL_5_A 0x70920
+#define _SEL_FETCH_PLANE_CTL_6_A 0x70940
+#define _SEL_FETCH_PLANE_CTL_1_B 0x71890
+#define _SEL_FETCH_PLANE_CTL_2_B 0x718b0
+#define _SEL_FETCH_PLANE_CTL_5_B 0x71920
+#define _SEL_FETCH_PLANE_CTL_6_B 0x71940
+#define SEL_FETCH_PLANE_CTL(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_CTL_1_A, _SEL_FETCH_PLANE_CTL_1_B, \
+ _SEL_FETCH_PLANE_CTL_2_A, _SEL_FETCH_PLANE_CTL_2_B, \
+ _SEL_FETCH_PLANE_CTL_5_A, _SEL_FETCH_PLANE_CTL_5_B, \
+ _SEL_FETCH_PLANE_CTL_6_A, _SEL_FETCH_PLANE_CTL_6_B)
+#define SEL_FETCH_PLANE_CTL_ENABLE REG_BIT(31)
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_POS_1_A 0x70894
+#define _SEL_FETCH_PLANE_POS_2_A 0x708b4
+#define _SEL_FETCH_PLANE_POS_5_A 0x70924
+#define _SEL_FETCH_PLANE_POS_6_A 0x70944
+#define _SEL_FETCH_PLANE_POS_1_B 0x71894
+#define _SEL_FETCH_PLANE_POS_2_B 0x718b4
+#define _SEL_FETCH_PLANE_POS_5_B 0x71924
+#define _SEL_FETCH_PLANE_POS_6_B 0x71944
+#define SEL_FETCH_PLANE_POS(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_POS_1_A, _SEL_FETCH_PLANE_POS_1_B, \
+ _SEL_FETCH_PLANE_POS_2_A, _SEL_FETCH_PLANE_POS_2_B, \
+ _SEL_FETCH_PLANE_POS_5_A, _SEL_FETCH_PLANE_POS_5_B, \
+ _SEL_FETCH_PLANE_POS_6_A, _SEL_FETCH_PLANE_POS_6_B)
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_SIZE_1_A 0x70898
+#define _SEL_FETCH_PLANE_SIZE_2_A 0x708b8
+#define _SEL_FETCH_PLANE_SIZE_5_A 0x70928
+#define _SEL_FETCH_PLANE_SIZE_6_A 0x70948
+#define _SEL_FETCH_PLANE_SIZE_1_B 0x71898
+#define _SEL_FETCH_PLANE_SIZE_2_B 0x718b8
+#define _SEL_FETCH_PLANE_SIZE_5_B 0x71928
+#define _SEL_FETCH_PLANE_SIZE_6_B 0x71948
+#define SEL_FETCH_PLANE_SIZE(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_SIZE_1_A, _SEL_FETCH_PLANE_SIZE_1_B, \
+ _SEL_FETCH_PLANE_SIZE_2_A, _SEL_FETCH_PLANE_SIZE_2_B, \
+ _SEL_FETCH_PLANE_SIZE_5_A, _SEL_FETCH_PLANE_SIZE_5_B, \
+ _SEL_FETCH_PLANE_SIZE_6_A, _SEL_FETCH_PLANE_SIZE_6_B)
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_OFFSET_1_A 0x7089c
+#define _SEL_FETCH_PLANE_OFFSET_2_A 0x708bc
+#define _SEL_FETCH_PLANE_OFFSET_5_A 0x7092c
+#define _SEL_FETCH_PLANE_OFFSET_6_A 0x7094c
+#define _SEL_FETCH_PLANE_OFFSET_1_B 0x7189c
+#define _SEL_FETCH_PLANE_OFFSET_2_B 0x718bc
+#define _SEL_FETCH_PLANE_OFFSET_5_B 0x7192c
+#define _SEL_FETCH_PLANE_OFFSET_6_B 0x7194c
+#define SEL_FETCH_PLANE_OFFSET(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_OFFSET_1_A, _SEL_FETCH_PLANE_OFFSET_1_B, \
+ _SEL_FETCH_PLANE_OFFSET_2_A, _SEL_FETCH_PLANE_OFFSET_2_B, \
+ _SEL_FETCH_PLANE_OFFSET_5_A, _SEL_FETCH_PLANE_OFFSET_5_B, \
+ _SEL_FETCH_PLANE_OFFSET_6_A, _SEL_FETCH_PLANE_OFFSET_6_B)
+
+#endif /* __SKL_UNIVERSAL_PLANE_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 7c6187b4479f..a2726364b34d 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -13,6 +13,7 @@
#include "intel_bw.h"
#include "intel_cdclk.h"
#include "intel_crtc.h"
+#include "intel_cursor_regs.h"
#include "intel_de.h"
#include "intel_display.h"
#include "intel_display_power.h"
@@ -21,6 +22,7 @@
#include "intel_fixed.h"
#include "intel_pcode.h"
#include "intel_wm.h"
+#include "skl_universal_plane_regs.h"
#include "skl_watermark.h"
#include "skl_watermark_regs.h"
@@ -1394,7 +1396,7 @@ skl_total_relative_data_rate(const struct intel_crtc_state *crtc_state)
return data_rate;
}
-static const struct skl_wm_level *
+const struct skl_wm_level *
skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
enum plane_id plane_id,
int level)
@@ -1407,7 +1409,7 @@ skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
return &wm->wm[level];
}
-static const struct skl_wm_level *
+const struct skl_wm_level *
skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
enum plane_id plane_id)
{
@@ -2363,101 +2365,6 @@ static int skl_build_pipe_wm(struct intel_atomic_state *state,
return skl_wm_check_vblank(crtc_state);
}
-static void skl_ddb_entry_write(struct drm_i915_private *i915,
- i915_reg_t reg,
- const struct skl_ddb_entry *entry)
-{
- if (entry->end)
- intel_de_write_fw(i915, reg,
- PLANE_BUF_END(entry->end - 1) |
- PLANE_BUF_START(entry->start));
- else
- intel_de_write_fw(i915, reg, 0);
-}
-
-static void skl_write_wm_level(struct drm_i915_private *i915,
- i915_reg_t reg,
- const struct skl_wm_level *level)
-{
- u32 val = 0;
-
- if (level->enable)
- val |= PLANE_WM_EN;
- if (level->ignore_lines)
- val |= PLANE_WM_IGNORE_LINES;
- val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
- val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
-
- intel_de_write_fw(i915, reg, val);
-}
-
-void skl_write_plane_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
- enum plane_id plane_id = plane->id;
- enum pipe pipe = plane->pipe;
- const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
- const struct skl_ddb_entry *ddb =
- &crtc_state->wm.skl.plane_ddb[plane_id];
- const struct skl_ddb_entry *ddb_y =
- &crtc_state->wm.skl.plane_ddb_y[plane_id];
- int level;
-
- for (level = 0; level < i915->display.wm.num_levels; level++)
- skl_write_wm_level(i915, PLANE_WM(pipe, plane_id, level),
- skl_plane_wm_level(pipe_wm, plane_id, level));
-
- skl_write_wm_level(i915, PLANE_WM_TRANS(pipe, plane_id),
- 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];
-
- skl_write_wm_level(i915, PLANE_WM_SAGV(pipe, plane_id),
- &wm->sagv.wm0);
- skl_write_wm_level(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id),
- &wm->sagv.trans_wm);
- }
-
- skl_ddb_entry_write(i915,
- PLANE_BUF_CFG(pipe, plane_id), ddb);
-
- if (DISPLAY_VER(i915) < 11)
- skl_ddb_entry_write(i915,
- PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_y);
-}
-
-void skl_write_cursor_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
- enum plane_id plane_id = plane->id;
- enum pipe pipe = plane->pipe;
- const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
- const struct skl_ddb_entry *ddb =
- &crtc_state->wm.skl.plane_ddb[plane_id];
- int level;
-
- for (level = 0; level < i915->display.wm.num_levels; level++)
- skl_write_wm_level(i915, CUR_WM(pipe, level),
- skl_plane_wm_level(pipe_wm, plane_id, level));
-
- skl_write_wm_level(i915, CUR_WM_TRANS(pipe),
- 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];
-
- skl_write_wm_level(i915, CUR_WM_SAGV(pipe),
- &wm->sagv.wm0);
- skl_write_wm_level(i915, CUR_WM_SAGV_TRANS(pipe),
- &wm->sagv.trans_wm);
- }
-
- skl_ddb_entry_write(i915, CUR_BUF_CFG(pipe), ddb);
-}
-
static bool skl_wm_level_equals(const struct skl_wm_level *l1,
const struct skl_wm_level *l2)
{
@@ -2522,12 +2429,14 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
}
static int
-skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
- struct intel_crtc_state *new_crtc_state)
+skl_ddb_add_affected_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state);
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane *plane;
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
@@ -2540,6 +2449,12 @@ skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
&new_crtc_state->wm.skl.plane_ddb_y[plane_id]))
continue;
+ if (new_crtc_state->do_async_flip) {
+ drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change DDB during async flip\n",
+ plane->base.base.id, plane->base.name);
+ return -EINVAL;
+ }
+
plane_state = intel_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
@@ -2576,7 +2491,6 @@ skl_compute_ddb(struct intel_atomic_state *state)
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_dbuf_state *old_dbuf_state;
struct intel_dbuf_state *new_dbuf_state = NULL;
- const struct intel_crtc_state *old_crtc_state;
struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
int ret, i;
@@ -2664,14 +2578,12 @@ skl_compute_ddb(struct intel_atomic_state *state)
return ret;
}
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
ret = skl_crtc_allocate_plane_ddb(state, crtc);
if (ret)
return ret;
- ret = skl_ddb_add_affected_planes(old_crtc_state,
- new_crtc_state);
+ ret = skl_ddb_add_affected_planes(state, crtc);
if (ret)
return ret;
}
@@ -2899,6 +2811,12 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
&new_crtc_state->wm.skl.optimal))
continue;
+ if (new_crtc_state->do_async_flip) {
+ drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change watermarks during async flip\n",
+ plane->base.base.id, plane->base.name);
+ return -EINVAL;
+ }
+
plane_state = intel_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
@@ -3604,7 +3522,7 @@ static void intel_mbus_dbox_update(struct intel_atomic_state *state)
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, new_dbuf_state->active_pipes) {
u32 pipe_val = val;
- if (DISPLAY_VER(i915) >= 14) {
+ if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
if (xelpdp_is_only_pipe_per_dbuf_bank(crtc->pipe,
new_dbuf_state->active_pipes))
pipe_val |= MBUS_DBOX_BW_8CREDITS_MTL;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h
index 91f92c0e706e..78b121941237 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark.h
@@ -18,6 +18,8 @@ struct intel_bw_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_plane;
+struct skl_pipe_wm;
+struct skl_wm_level;
u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *i915);
@@ -30,11 +32,6 @@ bool intel_has_sagv(struct drm_i915_private *i915);
u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915,
const struct skl_ddb_entry *entry);
-void skl_write_plane_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state);
-void skl_write_cursor_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state);
-
bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
const struct skl_ddb_entry *entries,
int num_entries, int ignore_idx);
@@ -51,6 +48,12 @@ unsigned int skl_watermark_max_latency(struct drm_i915_private *i915,
int initial_wm_level);
void skl_wm_init(struct drm_i915_private *i915);
+const struct skl_wm_level *skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
+ enum plane_id plane_id,
+ int level);
+const struct skl_wm_level *skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
+ enum plane_id plane_id);
+
struct intel_dbuf_state {
struct intel_global_state base;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
index 269163fa3350..c5572fc0e847 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
@@ -43,89 +43,6 @@
#define MBUS_TRANSLATION_THROTTLE_MIN_MASK REG_GENMASK(15, 13)
#define MBUS_TRANSLATION_THROTTLE_MIN(val) REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
-/* Watermark register definitions for SKL */
-#define _CUR_WM_A_0 0x70140
-#define _CUR_WM_B_0 0x71140
-#define _CUR_WM_SAGV_A 0x70158
-#define _CUR_WM_SAGV_B 0x71158
-#define _CUR_WM_SAGV_TRANS_A 0x7015C
-#define _CUR_WM_SAGV_TRANS_B 0x7115C
-#define _CUR_WM_TRANS_A 0x70168
-#define _CUR_WM_TRANS_B 0x71168
-#define _PLANE_WM_1_A_0 0x70240
-#define _PLANE_WM_1_B_0 0x71240
-#define _PLANE_WM_2_A_0 0x70340
-#define _PLANE_WM_2_B_0 0x71340
-#define _PLANE_WM_SAGV_1_A 0x70258
-#define _PLANE_WM_SAGV_1_B 0x71258
-#define _PLANE_WM_SAGV_2_A 0x70358
-#define _PLANE_WM_SAGV_2_B 0x71358
-#define _PLANE_WM_SAGV_TRANS_1_A 0x7025C
-#define _PLANE_WM_SAGV_TRANS_1_B 0x7125C
-#define _PLANE_WM_SAGV_TRANS_2_A 0x7035C
-#define _PLANE_WM_SAGV_TRANS_2_B 0x7135C
-#define _PLANE_WM_TRANS_1_A 0x70268
-#define _PLANE_WM_TRANS_1_B 0x71268
-#define _PLANE_WM_TRANS_2_A 0x70368
-#define _PLANE_WM_TRANS_2_B 0x71368
-#define PLANE_WM_EN (1 << 31)
-#define PLANE_WM_IGNORE_LINES (1 << 30)
-#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
-#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0)
-
-#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0)
-#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level)))
-#define CUR_WM_SAGV(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_A, _CUR_WM_SAGV_B)
-#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B)
-#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A, _CUR_WM_TRANS_B)
-#define _PLANE_WM_1(pipe) _PIPE(pipe, _PLANE_WM_1_A_0, _PLANE_WM_1_B_0)
-#define _PLANE_WM_2(pipe) _PIPE(pipe, _PLANE_WM_2_A_0, _PLANE_WM_2_B_0)
-#define _PLANE_WM_BASE(pipe, plane) \
- _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
-#define PLANE_WM(pipe, plane, level) \
- _MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
-#define _PLANE_WM_SAGV_1(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B)
-#define _PLANE_WM_SAGV_2(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B)
-#define PLANE_WM_SAGV(pipe, plane) \
- _MMIO(_PLANE(plane, _PLANE_WM_SAGV_1(pipe), _PLANE_WM_SAGV_2(pipe)))
-#define _PLANE_WM_SAGV_TRANS_1(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B)
-#define _PLANE_WM_SAGV_TRANS_2(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B)
-#define PLANE_WM_SAGV_TRANS(pipe, plane) \
- _MMIO(_PLANE(plane, _PLANE_WM_SAGV_TRANS_1(pipe), _PLANE_WM_SAGV_TRANS_2(pipe)))
-#define _PLANE_WM_TRANS_1(pipe) \
- _PIPE(pipe, _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B)
-#define _PLANE_WM_TRANS_2(pipe) \
- _PIPE(pipe, _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B)
-#define PLANE_WM_TRANS(pipe, plane) \
- _MMIO(_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe)))
-
-#define _PLANE_BUF_CFG_1_B 0x7127c
-#define _PLANE_BUF_CFG_2_B 0x7137c
-#define _PLANE_BUF_CFG_1(pipe) \
- _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
-#define _PLANE_BUF_CFG_2(pipe) \
- _PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
-#define PLANE_BUF_CFG(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe))
-
-#define _PLANE_NV12_BUF_CFG_1_B 0x71278
-#define _PLANE_NV12_BUF_CFG_2_B 0x71378
-#define _PLANE_NV12_BUF_CFG_1(pipe) \
- _PIPE(pipe, _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B)
-#define _PLANE_NV12_BUF_CFG_2(pipe) \
- _PIPE(pipe, _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B)
-#define PLANE_NV12_BUF_CFG(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe))
-
-/* SKL new cursor registers */
-#define _CUR_BUF_CFG_A 0x7017c
-#define _CUR_BUF_CFG_B 0x7117c
-#define CUR_BUF_CFG(pipe) _MMIO_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
-
/*
* The below are numbered starting from "S1" on gen11/gen12, but starting
* with display 13, the bspec switches to a 0-based numbering scheme
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index ee9923c7b115..eae5b5e09aa8 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -972,7 +972,8 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
*/
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
port == PORT_C)
- enabled = intel_de_read(display, TRANSCONF(PIPE_B)) & TRANSCONF_ENABLE;
+ enabled = intel_de_read(display,
+ TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE;
/* Try command mode if video mode not enabled */
if (!enabled) {