mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
Merge tag 'drm-next-2025-12-03' of https://gitlab.freedesktop.org/drm/kernel
Pull drm updates from Dave Airlie:
"There was a rather late merge of a new color pipeline feature, that
some userspace projects are blocked on, and has seen a lot of work in
amdgpu. This should have seen some time in -next. There is additional
support for this for Intel, that if it arrives in the next day or two
I'll pass it on in another pull request and you can decide if you want
to take it.
Highlights:
- Arm Ethos NPU accelerator driver
- new DRM color pipeline support
- amdgpu will now run discrete SI/CIK cards instead of radeon, which
enables vulkan support in userspace
- msm gets gen8 gpu support
- initial Xe3P support in xe
Full detail summary:
New driver:
- Arm Ethos-U65/U85 accel driver
Core:
- support the drm color pipeline in vkms/amdgfx
- add support for drm colorop pipeline
- add COLOR PIPELINE plane property
- add DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE
- throttle dirty worker with vblank
- use drm_for_each_bridge_in_chain_scoped in drm's bridge code
- Ensure drm_client_modeset tests are enabled in UML
- add simulated vblank interrupt - use in drivers
- dumb buffer sizing helper
- move freeing of drm client memory to driver
- crtc sharpness strength property
- stop using system_wq in scheduler/drivers
- support emergency restore in drm-client
Rust:
- make slice::as_flattened usable on all supported rustc
- add FromBytes::from_bytes_prefix() method
- remove redundant device ptr from Rust GEM object
- Change how AlwaysRefCounted is implemented for GEM objects
gpuvm:
- Add deferred vm_bo cleanup to GPUVM (for rust)
atomic:
- cleanup and improve state handling interfaces
buddy:
- optimize block management
dma-buf:
- heaps: Create heap per CMA reserved location
- improve userspace documentation
dp:
- add POST_LT_ADJ_REQ training sequence
- DPCD dSC quirk for synaptics panamera devices
- helpers to query branch DSC max throughput
ttm:
- Rename ttm_bo_put to ttm_bo_fini
- allow page protection flags on risc-v
- rework pipelined eviction fence handling
amdgpu:
- enable amdgpu by default for SI/CI dGPUs
- enable DC by default on SI
- refactor CIK/SI enablement
- add ABM KMS property
- Re-enable DM idle optimizations
- DC Analog encoders support
- Powerplay fixes for fiji/iceland
- Enable DC on bonaire by default
- HMM cleanup
- Add new RAS framework
- DML2.1 updates
- YCbCr420 fixes
- DC FP fixes
- DMUB fixes
- LTTPR fixes
- DTBCLK fixes
- DMU cursor offload handling
- Userq validation improvements
- Unify shutdown callback handling
- Suspend improvements
- Power limit code cleanup
- SR-IOV fixes
- AUX backlight fixes
- DCN 3.5 fixes
- HDMI compliance fixes
- DCN 4.0.1 cursor updates
- DCN interrupt fix
- DC KMS full update improvements
- Add additional HDCP traces
- DCN 3.2 fixes
- DP MST fixes
- Add support for new SR-IOV mailbox interface
- UQ reset support
- HDP flush rework
- VCE1 support
amdkfd:
- HMM cleanups
- Relax checks on save area overallocations
- Fix GPU mappings after prefetch
radeon:
- refactor CIK/SI enablement
xe:
- Initial Xe3P support
- panic support on VRAM for display
- fix stolen size check
- Loosen used tracking restriction
- New SR-IOV debugfs structure and debugfs updates
- Hide the GPU madvise flag behind a VM_BIND flag
- Always expose VRAM provisioning data on discrete GPUs
- Allow VRAM mappings for userptr when used with SVM
- Allow pinning of p2p dma-buf
- Use per-tile debugfs where appropriate
- Add documentation for Execution Queues
- PF improvements
- VF migration recovery redesign work
- User / Kernel VRAM partitioning
- Update Tile-based messages
- Allow configfs to disable specific GT types
- VF provisioning and migration improvements
- use SVM range helpers in PT layer
- Initial CRI support
- access VF registers using dedicated MMIO view
- limit number of jobs per exec queue
- add sriov_admin sysfs tree
- more crescent island specific support
- debugfs residency counter
- SRIOV migration work
- runtime registers for GFX 35
i915:
- add initial Xe3p_LPD display version 35 support
- Enable LNL+ content adaptive sharpness filter
- Use optimized VRR guardband
- Enable Xe3p LT PHY
- enable FBC support for Xe3p_LPD display
- add display 30.02 firmware support
- refactor SKL+ watermark latency setup
- refactor fbdev handling
- call i915/xe runtime PM via function pointers
- refactor i915/xe stolen memory/display interfaces
- use display version instead of gfx version in display code
- extend i915_display_info with Type-C port details
- lots of display cleanups/refactorings
- set O_LARGEFILE in __create_shmem
- skuip guc communication warning on reset
- fix time conversions
- defeature DRRS on LNL+
- refactor intel_frontbuffer split between i915/xe/display
- convert inteL_rom interfaces to struct drm_device
- unify display register polling interfaces
- aovid lock inversion when pinning to GGTT on CHV/BXT+VTD
panel:
- Add KD116N3730A08/A12, chromebook mt8189
- JT101TM023, LQ079L1SX01,
- GLD070WX3-SL01 MIPI DSI
- Samsung LTL106AL0, Samsung LTL106AL01
- Raystar RFF500F-AWH-DNN
- Winstar WF70A8SYJHLNGA
- Wanchanglong w552946aaa
- Samsung SOFEF00
- Lenovo X13s panel
- ilitek-ili9881c - add rpi 5" support
- visionx-rm69299 - add backlight support
- edp - support AUI B116XAN02.0
bridge:
- improve ref counting
- ti-sn65dsi86 - add support for DP mode with HPD
- synopsis: support CEC, init timer with correct freq
- ASL CS5263 DP-to-HDMI bridge support
nova-core:
- introduce bitfield! macro
- introduce safe integer converters
- GSP inits to fully booted state on Ampere
- Use more future-proof register for GPU identification
nova-drm:
- select NOVA_CORE
- 64-bit only
nouveau:
- improve reclocking on tegra 186+
- add large page and compression support
msm:
- GPU:
- Gen8 support: A840 (Kaanapali) and X2-85 (Glymur)
- A612 support
- MDSS:
- Added support for Glymur and QCS8300 platforms
- DPU:
- Enabled Quad-Pipe support, unlocking higher resolutions support
- Added support for Glymur platform
- Documented DPU on QCS8300 platform as supported
- DisplayPort:
- Added support for Glymur platform
- Added support lame remapping inside DP block
- Documented DisplayPort controller on QCS8300 and SM6150/QCS615
as supported
tegra:
- NVJPG driver
panfrost:
- display JM contexts over debugfs
- export JM contexts to userspace
- improve error and job handling
panthor:
- support custom ASN_HASH for mt8196
- support mali-G1 GPU
- flush shmem write before mapping buffers uncached
- make timeout per-queue instead of per-job
mediatek:
- MT8195/88 HDMIv2/DDCv2 support
rockchip:
- dsi: add support for RK3368
amdxdna:
- enhance runtime PM
- last hardware error reading uapi
- support firmware debug output
- add resource and telemetry data uapi
- preemption support
imx:
- add driver for HDMI TX Parallel audio interface
ivpu:
- add support for user-managed preemption buffer
- add userptr support
- update JSM firware API to 3.33.0
- add better alloc/free warnings
- fix page fault in unbind all bos
- rework bind/unbind of imported buffers
- enable MCA ECC signalling
- split fw runtime and global memory buffers
- add fdinfo memory statistics
tidss:
- convert to drm logging
- logging cleanup
ast:
- refactor generation init paths
- add per chip generation detect_tx_chip
- set quirks for each chip model
atmel-hlcdc:
- set LCDC_ATTRE register in plane disable
- set correct values for plane scaler
solomon:
- use drm helper for get_modes and move_valid
sitronix:
- fix output position when clearing screens
qaic:
- support dma-buf exports
- support new firmware's READ_DATA implementation
- sahara AIC200 image table update
- add sysfs support
- add coredump support
- add uevents support
- PM support
sun4i:
- layer refactors to decouple plane from output
- improve DE33 support
vc4:
- switch to generic CEC helpers
komeda:
- use drm_ logging functions
vkms:
- configfs support for display configuration
vgem:
- fix fence timer deadlock
etnaviv:
- add HWDB entry for GC8000 Nano Ultra VIP r6205"
* tag 'drm-next-2025-12-03' of https://gitlab.freedesktop.org/drm/kernel: (1869 commits)
Revert "drm/amd: Skip power ungate during suspend for VPE"
drm/amdgpu: use common defines for HUB faults
drm/amdgpu/gmc12: add amdgpu_vm_handle_fault() handling
drm/amdgpu/gmc11: add amdgpu_vm_handle_fault() handling
drm/amdgpu: use static ids for ACP platform devs
drm/amdgpu/sdma6: Update SDMA 6.0.3 FW version to include UMQ protected-fence fix
drm/amdgpu: Forward VMID reservation errors
drm/amdgpu/gmc8: Delegate VM faults to soft IRQ handler ring
drm/amdgpu/gmc7: Delegate VM faults to soft IRQ handler ring
drm/amdgpu/gmc6: Delegate VM faults to soft IRQ handler ring
drm/amdgpu/gmc6: Cache VM fault info
drm/amdgpu/gmc6: Don't print MC client as it's unknown
drm/amdgpu/cz_ih: Enable soft IRQ handler ring
drm/amdgpu/tonga_ih: Enable soft IRQ handler ring
drm/amdgpu/iceland_ih: Enable soft IRQ handler ring
drm/amdgpu/cik_ih: Enable soft IRQ handler ring
drm/amdgpu/si_ih: Enable soft IRQ handler ring
drm/amd/display: fix typo in display_mode_core_structs.h
drm/amd/display: fix Smart Power OLED not working after S4
drm/amd/display: Move RGB-type check for audio sync to DCE HW sequence
...
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fixed.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_rect.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
@@ -51,7 +52,6 @@
|
||||
#include "i915_config.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "i9xx_plane.h"
|
||||
#include "i9xx_plane_regs.h"
|
||||
#include "i9xx_wm.h"
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "intel_audio.h"
|
||||
#include "intel_bo.h"
|
||||
#include "intel_bw.h"
|
||||
#include "intel_casf.h"
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_clock_gating.h"
|
||||
#include "intel_color.h"
|
||||
@@ -76,6 +77,7 @@
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_display_utils.h"
|
||||
#include "intel_display_wa.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dp.h"
|
||||
@@ -99,6 +101,7 @@
|
||||
#include "intel_hdmi.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_link_bw.h"
|
||||
#include "intel_lt_phy.h"
|
||||
#include "intel_lvds.h"
|
||||
#include "intel_lvds_regs.h"
|
||||
#include "intel_modeset_setup.h"
|
||||
@@ -129,11 +132,9 @@
|
||||
#include "skl_scaler.h"
|
||||
#include "skl_universal_plane.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "vlv_dpio_phy_regs.h"
|
||||
#include "vlv_dsi.h"
|
||||
#include "vlv_dsi_pll.h"
|
||||
#include "vlv_dsi_regs.h"
|
||||
#include "vlv_sideband.h"
|
||||
|
||||
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
|
||||
static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
|
||||
@@ -141,65 +142,6 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);
|
||||
static void bdw_set_pipe_misc(struct intel_dsb *dsb,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
/* returns HPLL frequency in kHz */
|
||||
int vlv_get_hpll_vco(struct drm_device *drm)
|
||||
{
|
||||
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
|
||||
|
||||
/* Obtain SKU information */
|
||||
hpll_freq = vlv_cck_read(drm, CCK_FUSE_REG) &
|
||||
CCK_FUSE_HPLL_FREQ_MASK;
|
||||
|
||||
return vco_freq[hpll_freq] * 1000;
|
||||
}
|
||||
|
||||
int vlv_get_cck_clock(struct drm_device *drm,
|
||||
const char *name, u32 reg, int ref_freq)
|
||||
{
|
||||
u32 val;
|
||||
int divider;
|
||||
|
||||
val = vlv_cck_read(drm, reg);
|
||||
divider = val & CCK_FREQUENCY_VALUES;
|
||||
|
||||
drm_WARN(drm, (val & CCK_FREQUENCY_STATUS) !=
|
||||
(divider << CCK_FREQUENCY_STATUS_SHIFT),
|
||||
"%s change in progress\n", name);
|
||||
|
||||
return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
|
||||
}
|
||||
|
||||
int vlv_get_cck_clock_hpll(struct drm_device *drm,
|
||||
const char *name, u32 reg)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(drm);
|
||||
int hpll;
|
||||
|
||||
vlv_cck_get(drm);
|
||||
|
||||
if (dev_priv->hpll_freq == 0)
|
||||
dev_priv->hpll_freq = vlv_get_hpll_vco(drm);
|
||||
|
||||
hpll = vlv_get_cck_clock(drm, name, reg, dev_priv->hpll_freq);
|
||||
|
||||
vlv_cck_put(drm);
|
||||
|
||||
return hpll;
|
||||
}
|
||||
|
||||
void intel_update_czclk(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (!display->platform.valleyview && !display->platform.cherryview)
|
||||
return;
|
||||
|
||||
dev_priv->czclk_freq = vlv_get_cck_clock_hpll(display->drm, "czclk",
|
||||
CCK_CZ_CLOCK_CONTROL);
|
||||
|
||||
drm_dbg_kms(display->drm, "CZ clock rate: %d kHz\n", dev_priv->czclk_freq);
|
||||
}
|
||||
|
||||
static bool is_hdr_mode(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return (crtc_state->active_planes &
|
||||
@@ -417,8 +359,8 @@ 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(display, TRANSCONF(display, cpu_transcoder),
|
||||
TRANSCONF_STATE_ENABLE, 100))
|
||||
if (intel_de_wait_for_clear_ms(display, TRANSCONF(display, cpu_transcoder),
|
||||
TRANSCONF_STATE_ENABLE, 100))
|
||||
drm_WARN(display->drm, 1, "pipe_off wait timed out\n");
|
||||
} else {
|
||||
intel_wait_for_pipe_scanline_stopped(crtc);
|
||||
@@ -605,16 +547,13 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
|
||||
intel_wait_for_pipe_off(old_crtc_state);
|
||||
}
|
||||
|
||||
u32 intel_plane_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier)
|
||||
u32 intel_plane_fb_max_stride(struct intel_display *display,
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(drm);
|
||||
struct intel_crtc *crtc;
|
||||
struct intel_plane *plane;
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We assume the primary plane for pipe A has
|
||||
* the highest stride limits of them all,
|
||||
@@ -626,10 +565,23 @@ u32 intel_plane_fb_max_stride(struct drm_device *drm,
|
||||
|
||||
plane = to_intel_plane(crtc->base.primary);
|
||||
|
||||
return plane->max_stride(plane, pixel_format, modifier,
|
||||
return plane->max_stride(plane, info, modifier,
|
||||
DRM_MODE_ROTATE_0);
|
||||
}
|
||||
|
||||
u32 intel_dumb_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(drm);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
return intel_plane_fb_max_stride(display,
|
||||
drm_get_format_info(drm, pixel_format, modifier),
|
||||
modifier);
|
||||
}
|
||||
|
||||
void intel_set_plane_visible(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state,
|
||||
bool visible)
|
||||
@@ -891,9 +843,8 @@ static void intel_async_flip_vtd_wa(struct intel_display *display,
|
||||
static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
|
||||
return crtc_state->uapi.async_flip && i915_vtd_active(i915) &&
|
||||
return crtc_state->uapi.async_flip && intel_display_vtd_active(display) &&
|
||||
(DISPLAY_VER(display) == 9 || display->platform.broadwell ||
|
||||
display->platform.haswell);
|
||||
}
|
||||
@@ -1040,6 +991,24 @@ static bool audio_disabling(const struct intel_crtc_state *old_crtc_state,
|
||||
memcmp(old_crtc_state->eld, new_crtc_state->eld, MAX_ELD_BYTES) != 0);
|
||||
}
|
||||
|
||||
static bool intel_casf_enabling(const struct intel_crtc_state *new_crtc_state,
|
||||
const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
if (!new_crtc_state->hw.active)
|
||||
return false;
|
||||
|
||||
return is_enabling(hw.casf_params.casf_enable, old_crtc_state, new_crtc_state);
|
||||
}
|
||||
|
||||
static bool intel_casf_disabling(const struct intel_crtc_state *old_crtc_state,
|
||||
const struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
if (!new_crtc_state->hw.active)
|
||||
return false;
|
||||
|
||||
return is_disabling(hw.casf_params.casf_enable, old_crtc_state, new_crtc_state);
|
||||
}
|
||||
|
||||
#undef is_disabling
|
||||
#undef is_enabling
|
||||
|
||||
@@ -1195,6 +1164,9 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
|
||||
if (audio_disabling(old_crtc_state, new_crtc_state))
|
||||
intel_encoders_audio_disable(state, crtc);
|
||||
|
||||
if (intel_casf_disabling(old_crtc_state, new_crtc_state))
|
||||
intel_casf_disable(new_crtc_state);
|
||||
|
||||
intel_drrs_deactivate(old_crtc_state);
|
||||
|
||||
if (hsw_ips_pre_update(state, crtc))
|
||||
@@ -1642,8 +1614,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
|
||||
}
|
||||
|
||||
intel_set_transcoder_timings(crtc_state);
|
||||
if (HAS_VRR(display))
|
||||
intel_vrr_set_transcoder_timings(crtc_state);
|
||||
intel_vrr_set_transcoder_timings(crtc_state);
|
||||
|
||||
if (cpu_transcoder != TRANSCODER_EDP)
|
||||
intel_de_write(display, TRANS_MULT(display, cpu_transcoder),
|
||||
@@ -2422,39 +2393,44 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state)
|
||||
static int intel_crtc_set_context_latency(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
int vblank_delay = 0;
|
||||
int set_context_latency = 0;
|
||||
|
||||
if (!HAS_DSB(display))
|
||||
return 0;
|
||||
|
||||
vblank_delay = max(vblank_delay, intel_psr_min_vblank_delay(crtc_state));
|
||||
set_context_latency = max(set_context_latency,
|
||||
intel_psr_min_set_context_latency(crtc_state));
|
||||
|
||||
return vblank_delay;
|
||||
return set_context_latency;
|
||||
}
|
||||
|
||||
static int intel_crtc_compute_vblank_delay(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
static int intel_crtc_compute_set_context_latency(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
int vblank_delay, max_vblank_delay;
|
||||
int set_context_latency, max_vblank_delay;
|
||||
|
||||
set_context_latency = intel_crtc_set_context_latency(crtc_state);
|
||||
|
||||
vblank_delay = intel_crtc_vblank_delay(crtc_state);
|
||||
max_vblank_delay = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start - 1;
|
||||
|
||||
if (vblank_delay > max_vblank_delay) {
|
||||
drm_dbg_kms(display->drm, "[CRTC:%d:%s] vblank delay (%d) exceeds max (%d)\n",
|
||||
crtc->base.base.id, crtc->base.name, vblank_delay, max_vblank_delay);
|
||||
if (set_context_latency > max_vblank_delay) {
|
||||
drm_dbg_kms(display->drm, "[CRTC:%d:%s] set context latency (%d) exceeds max (%d)\n",
|
||||
crtc->base.base.id, crtc->base.name,
|
||||
set_context_latency,
|
||||
max_vblank_delay);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adjusted_mode->crtc_vblank_start += vblank_delay;
|
||||
crtc_state->set_context_latency = set_context_latency;
|
||||
adjusted_mode->crtc_vblank_start += set_context_latency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2466,11 +2442,11 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
int ret;
|
||||
|
||||
ret = intel_crtc_compute_vblank_delay(state, crtc);
|
||||
ret = intel_dpll_crtc_compute_clock(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = intel_dpll_crtc_compute_clock(state, crtc);
|
||||
ret = intel_crtc_compute_set_context_latency(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2487,6 +2463,8 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
|
||||
if (crtc_state->has_pch_encoder)
|
||||
return ilk_fdi_compute_config(crtc, crtc_state);
|
||||
|
||||
intel_vrr_compute_guardband(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2678,16 +2656,19 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
|
||||
if (DISPLAY_VER(display) >= 13) {
|
||||
intel_de_write(display,
|
||||
TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder),
|
||||
crtc_vblank_start - crtc_vdisplay);
|
||||
crtc_state->set_context_latency);
|
||||
|
||||
/*
|
||||
* VBLANK_START not used by hw, just clear it
|
||||
* to make it stand out in register dumps.
|
||||
*/
|
||||
crtc_vblank_start = 1;
|
||||
} else if (DISPLAY_VER(display) == 12) {
|
||||
/* VBLANK_START - VACTIVE defines SCL on TGL */
|
||||
crtc_vblank_start = crtc_vdisplay + crtc_state->set_context_latency;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4 && DISPLAY_VER(display) < 35)
|
||||
intel_de_write(display,
|
||||
TRANS_VSYNCSHIFT(display, cpu_transcoder),
|
||||
vsyncshift);
|
||||
@@ -2768,13 +2749,16 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc
|
||||
if (DISPLAY_VER(display) >= 13) {
|
||||
intel_de_write(display,
|
||||
TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder),
|
||||
crtc_vblank_start - crtc_vdisplay);
|
||||
crtc_state->set_context_latency);
|
||||
|
||||
/*
|
||||
* VBLANK_START not used by hw, just clear it
|
||||
* to make it stand out in register dumps.
|
||||
*/
|
||||
crtc_vblank_start = 1;
|
||||
} else if (DISPLAY_VER(display) == 12) {
|
||||
/* VBLANK_START - VACTIVE defines SCL on TGL */
|
||||
crtc_vblank_start = crtc_vdisplay + crtc_state->set_context_latency;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2825,7 +2809,7 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
|
||||
if (DISPLAY_VER(display) == 2)
|
||||
if (DISPLAY_VER(display) == 2 || DISPLAY_VER(display) >= 35)
|
||||
return false;
|
||||
|
||||
if (DISPLAY_VER(display) >= 9 ||
|
||||
@@ -2881,11 +2865,24 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
|
||||
adjusted_mode->crtc_vblank_end += 1;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 13 && !transcoder_is_dsi(cpu_transcoder))
|
||||
adjusted_mode->crtc_vblank_start =
|
||||
adjusted_mode->crtc_vdisplay +
|
||||
if (DISPLAY_VER(display) >= 13 && !transcoder_is_dsi(cpu_transcoder)) {
|
||||
pipe_config->set_context_latency =
|
||||
intel_de_read(display,
|
||||
TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder));
|
||||
adjusted_mode->crtc_vblank_start =
|
||||
adjusted_mode->crtc_vdisplay +
|
||||
pipe_config->set_context_latency;
|
||||
} else if (DISPLAY_VER(display) == 12) {
|
||||
/*
|
||||
* TGL doesn't have a dedicated register for SCL.
|
||||
* Instead, the hardware derives SCL from the difference between
|
||||
* TRANS_VBLANK.vblank_start and TRANS_VTOTAL.vactive.
|
||||
* To reflect the HW behaviour, readout the value for SCL as
|
||||
* Vblank start - Vactive.
|
||||
*/
|
||||
pipe_config->set_context_latency =
|
||||
adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 30)
|
||||
pipe_config->min_hblank = intel_de_read(display,
|
||||
@@ -3203,10 +3200,12 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
|
||||
if (display->platform.haswell && crtc_state->dither)
|
||||
val |= TRANSCONF_DITHER_EN | TRANSCONF_DITHER_TYPE_SP;
|
||||
|
||||
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
val |= TRANSCONF_INTERLACE_IF_ID_ILK;
|
||||
else
|
||||
val |= TRANSCONF_INTERLACE_PF_PD_ILK;
|
||||
if (DISPLAY_VER(display) < 35) {
|
||||
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
val |= TRANSCONF_INTERLACE_IF_ID_ILK;
|
||||
else
|
||||
val |= TRANSCONF_INTERLACE_PF_PD_ILK;
|
||||
}
|
||||
|
||||
if (display->platform.haswell &&
|
||||
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
|
||||
@@ -3952,6 +3951,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
||||
intel_joiner_get_config(pipe_config);
|
||||
intel_dsc_get_config(pipe_config);
|
||||
|
||||
/* intel_vrr_get_config() depends on .framestart_delay */
|
||||
if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
||||
tmp = intel_de_read(display, CHICKEN_TRANS(display, pipe_config->cpu_transcoder));
|
||||
|
||||
pipe_config->framestart_delay = REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1;
|
||||
} else {
|
||||
/* no idea if this is correct */
|
||||
pipe_config->framestart_delay = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* intel_vrr_get_config() depends on TRANS_SET_CONTEXT_LATENCY
|
||||
* readout done by intel_get_transcoder_timings().
|
||||
*/
|
||||
if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
|
||||
DISPLAY_VER(display) >= 11)
|
||||
intel_get_transcoder_timings(crtc, pipe_config);
|
||||
@@ -4003,15 +4016,6 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
||||
pipe_config->pixel_multiplier = 1;
|
||||
}
|
||||
|
||||
if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
||||
tmp = intel_de_read(display, CHICKEN_TRANS(display, pipe_config->cpu_transcoder));
|
||||
|
||||
pipe_config->framestart_delay = REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1;
|
||||
} else {
|
||||
/* no idea if this is correct */
|
||||
pipe_config->framestart_delay = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
intel_display_power_put_all_in_set(display, &crtc->hw_readout_power_domains);
|
||||
|
||||
@@ -4258,9 +4262,14 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_casf_compute_config(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (DISPLAY_VER(display) >= 9) {
|
||||
if (intel_crtc_needs_modeset(crtc_state) ||
|
||||
intel_crtc_needs_fastset(crtc_state)) {
|
||||
intel_crtc_needs_fastset(crtc_state) ||
|
||||
intel_casf_needs_scaler(crtc_state)) {
|
||||
ret = skl_update_scaler_crtc(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -4639,7 +4648,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state->fec_enable = limits->force_fec_pipes & BIT(crtc->pipe);
|
||||
crtc_state->dsc.compression_enabled_on_link = limits->link_dsc_pipes & BIT(crtc->pipe);
|
||||
crtc_state->max_link_bpp_x16 = limits->max_bpp_x16[crtc->pipe];
|
||||
|
||||
if (crtc_state->pipe_bpp > fxp_q4_to_int(crtc_state->max_link_bpp_x16)) {
|
||||
@@ -4760,8 +4769,6 @@ intel_modeset_pipe_config_late(struct intel_atomic_state *state,
|
||||
struct drm_connector *connector;
|
||||
int i;
|
||||
|
||||
intel_vrr_compute_config_late(crtc_state);
|
||||
|
||||
for_each_new_connector_in_state(&state->base, connector,
|
||||
conn_state, i) {
|
||||
struct intel_encoder *encoder =
|
||||
@@ -4996,9 +5003,33 @@ static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_s
|
||||
* Allow fastboot to fix up vblank delay (handled via LRR
|
||||
* codepaths), a bit dodgy as the registers aren't
|
||||
* double buffered but seems to be working more or less...
|
||||
*
|
||||
* Also allow this when the VRR timing generator is always on,
|
||||
* and optimized guardband is used. In such cases,
|
||||
* vblank delay may vary even without inherited state, but it's
|
||||
* still safe as VRR guardband is still same.
|
||||
*/
|
||||
return HAS_LRR(display) && old_crtc_state->inherited &&
|
||||
!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
|
||||
return HAS_LRR(display) &&
|
||||
(old_crtc_state->inherited || intel_vrr_always_use_vrr_tg(display)) &&
|
||||
!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI);
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_config_lt_phy_pll_mismatch(struct drm_printer *p, bool fastset,
|
||||
const struct intel_crtc *crtc,
|
||||
const char *name,
|
||||
const struct intel_lt_phy_pll_state *a,
|
||||
const struct intel_lt_phy_pll_state *b)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
char *chipname = "LTPHY";
|
||||
|
||||
pipe_config_mismatch(p, fastset, crtc, name, chipname);
|
||||
|
||||
drm_printf(p, "expected:\n");
|
||||
intel_lt_phy_dump_hw_state(display, a);
|
||||
drm_printf(p, "found:\n");
|
||||
intel_lt_phy_dump_hw_state(display, b);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -5125,6 +5156,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_CONF_CHECK_PLL_LT(name) do { \
|
||||
if (!intel_lt_phy_pll_compare_hw_state(¤t_config->name, \
|
||||
&pipe_config->name)) { \
|
||||
pipe_config_lt_phy_pll_mismatch(&p, fastset, crtc, __stringify(name), \
|
||||
¤t_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); \
|
||||
@@ -5319,6 +5360,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
|
||||
PIPE_CONF_CHECK_I(scaler_state.scaler_id);
|
||||
PIPE_CONF_CHECK_I(pixel_rate);
|
||||
PIPE_CONF_CHECK_BOOL(hw.casf_params.casf_enable);
|
||||
PIPE_CONF_CHECK_I(hw.casf_params.win_size);
|
||||
PIPE_CONF_CHECK_I(hw.casf_params.strength);
|
||||
|
||||
PIPE_CONF_CHECK_X(gamma_mode);
|
||||
if (display->platform.cherryview)
|
||||
@@ -5349,7 +5393,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
PIPE_CONF_CHECK_PLL(dpll_hw_state);
|
||||
|
||||
/* FIXME convert MTL+ platforms over to dpll_mgr */
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
if (HAS_LT_PHY(display))
|
||||
PIPE_CONF_CHECK_PLL_LT(dpll_hw_state.ltpll);
|
||||
else if (DISPLAY_VER(display) >= 14)
|
||||
PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll);
|
||||
|
||||
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
|
||||
@@ -5443,6 +5489,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
PIPE_CONF_CHECK_I(vrr.guardband);
|
||||
}
|
||||
|
||||
PIPE_CONF_CHECK_I(set_context_latency);
|
||||
|
||||
#undef PIPE_CONF_CHECK_X
|
||||
#undef PIPE_CONF_CHECK_I
|
||||
#undef PIPE_CONF_CHECK_LLI
|
||||
@@ -5689,6 +5737,23 @@ static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 intel_calc_enabled_pipes(struct intel_atomic_state *state,
|
||||
u8 enabled_pipes)
|
||||
{
|
||||
const struct intel_crtc_state *crtc_state;
|
||||
struct intel_crtc *crtc;
|
||||
int i;
|
||||
|
||||
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
if (crtc_state->hw.enable)
|
||||
enabled_pipes |= BIT(crtc->pipe);
|
||||
else
|
||||
enabled_pipes &= ~BIT(crtc->pipe);
|
||||
}
|
||||
|
||||
return enabled_pipes;
|
||||
}
|
||||
|
||||
u8 intel_calc_active_pipes(struct intel_atomic_state *state,
|
||||
u8 active_pipes)
|
||||
{
|
||||
@@ -5718,12 +5783,16 @@ static int intel_modeset_checks(struct intel_atomic_state *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool lrr_params_changed(const struct drm_display_mode *old_adjusted_mode,
|
||||
const struct drm_display_mode *new_adjusted_mode)
|
||||
static bool lrr_params_changed(const struct intel_crtc_state *old_crtc_state,
|
||||
const struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
const struct drm_display_mode *old_adjusted_mode = &old_crtc_state->hw.adjusted_mode;
|
||||
const struct drm_display_mode *new_adjusted_mode = &new_crtc_state->hw.adjusted_mode;
|
||||
|
||||
return old_adjusted_mode->crtc_vblank_start != new_adjusted_mode->crtc_vblank_start ||
|
||||
old_adjusted_mode->crtc_vblank_end != new_adjusted_mode->crtc_vblank_end ||
|
||||
old_adjusted_mode->crtc_vtotal != new_adjusted_mode->crtc_vtotal;
|
||||
old_adjusted_mode->crtc_vtotal != new_adjusted_mode->crtc_vtotal ||
|
||||
old_crtc_state->set_context_latency != new_crtc_state->set_context_latency;
|
||||
}
|
||||
|
||||
static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state,
|
||||
@@ -5749,8 +5818,7 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
|
||||
&new_crtc_state->dp_m_n))
|
||||
new_crtc_state->update_m_n = false;
|
||||
|
||||
if (!lrr_params_changed(&old_crtc_state->hw.adjusted_mode,
|
||||
&new_crtc_state->hw.adjusted_mode))
|
||||
if (!lrr_params_changed(old_crtc_state, new_crtc_state))
|
||||
new_crtc_state->update_lrr = false;
|
||||
|
||||
if (intel_crtc_needs_modeset(new_crtc_state))
|
||||
@@ -6350,7 +6418,6 @@ int intel_atomic_check(struct drm_device *dev,
|
||||
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct intel_crtc *crtc;
|
||||
int ret, i;
|
||||
bool any_ms = false;
|
||||
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return -ENODEV;
|
||||
@@ -6458,14 +6525,11 @@ int intel_atomic_check(struct drm_device *dev,
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state))
|
||||
continue;
|
||||
|
||||
any_ms = true;
|
||||
|
||||
intel_dpll_release(state, crtc);
|
||||
}
|
||||
|
||||
if (any_ms && !check_digital_port_conflicts(state)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"rejecting conflicting digital port configuration\n");
|
||||
if (intel_any_crtc_needs_modeset(state) && !check_digital_port_conflicts(state)) {
|
||||
drm_dbg_kms(display->drm, "rejecting conflicting digital port configuration\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@@ -6474,29 +6538,25 @@ int intel_atomic_check(struct drm_device *dev,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
|
||||
new_crtc_state->min_cdclk = intel_crtc_min_cdclk(new_crtc_state);
|
||||
|
||||
ret = intel_compute_global_watermarks(state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = intel_bw_atomic_check(state, any_ms);
|
||||
ret = intel_bw_atomic_check(state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = intel_cdclk_atomic_check(state, &any_ms);
|
||||
ret = intel_cdclk_atomic_check(state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (intel_any_crtc_needs_modeset(state))
|
||||
any_ms = true;
|
||||
|
||||
if (any_ms) {
|
||||
if (intel_any_crtc_needs_modeset(state)) {
|
||||
ret = intel_modeset_checks(state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = intel_modeset_calc_cdclk(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_pmdemand_atomic_check(state);
|
||||
@@ -6747,6 +6807,11 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
|
||||
intel_vrr_set_transcoder_timings(new_crtc_state);
|
||||
}
|
||||
|
||||
if (intel_casf_enabling(new_crtc_state, old_crtc_state))
|
||||
intel_casf_enable(new_crtc_state);
|
||||
else if (new_crtc_state->hw.casf_params.strength != old_crtc_state->hw.casf_params.strength)
|
||||
intel_casf_update_strength(new_crtc_state);
|
||||
|
||||
intel_fbc_update(state, crtc);
|
||||
|
||||
drm_WARN_ON(display->drm, !intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF));
|
||||
@@ -7315,7 +7380,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state,
|
||||
intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1);
|
||||
|
||||
intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state);
|
||||
intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit);
|
||||
intel_dsb_wait_for_delayed_vblank(state, new_crtc_state->dsb_commit);
|
||||
intel_vrr_check_push_sent(new_crtc_state->dsb_commit,
|
||||
new_crtc_state);
|
||||
intel_dsb_interrupt(new_crtc_state->dsb_commit);
|
||||
@@ -7405,13 +7470,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
*/
|
||||
intel_pmdemand_pre_plane_update(state);
|
||||
|
||||
if (state->modeset) {
|
||||
if (state->modeset)
|
||||
drm_atomic_helper_update_legacy_modeset_state(display->drm, &state->base);
|
||||
|
||||
intel_set_cdclk_pre_plane_update(state);
|
||||
intel_set_cdclk_pre_plane_update(state);
|
||||
|
||||
if (state->modeset)
|
||||
intel_modeset_verify_disabled(state);
|
||||
}
|
||||
|
||||
intel_sagv_pre_plane_update(state);
|
||||
|
||||
@@ -7524,8 +7589,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
intel_verify_planes(state);
|
||||
|
||||
intel_sagv_post_plane_update(state);
|
||||
if (state->modeset)
|
||||
intel_set_cdclk_post_plane_update(state);
|
||||
intel_set_cdclk_post_plane_update(state);
|
||||
intel_pmdemand_post_plane_update(state);
|
||||
|
||||
drm_atomic_helper_commit_hw_done(&state->base);
|
||||
@@ -8011,6 +8075,14 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev,
|
||||
mode->vtotal > vtotal_max)
|
||||
return MODE_V_ILLEGAL;
|
||||
|
||||
/*
|
||||
* WM_LINETIME only goes up to (almost) 64 usec, and also
|
||||
* knowing that the linetime is always bounded will ease the
|
||||
* mind during various calculations.
|
||||
*/
|
||||
if (DIV_ROUND_UP(mode->htotal * 1000, mode->clock) > 64)
|
||||
return MODE_H_ILLEGAL;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
@@ -8335,7 +8407,5 @@ void i830_disable_pipe(struct intel_display *display, enum pipe pipe)
|
||||
|
||||
bool intel_scanout_needs_vtd_wa(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
return IS_DISPLAY_VER(display, 6, 11) && i915_vtd_active(i915);
|
||||
return IS_DISPLAY_VER(display, 6, 11) && intel_display_vtd_active(display);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user