diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-23 18:29:02 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-23 18:29:02 -1000 |
| commit | 5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f (patch) | |
| tree | 61666e82efa4901ddb00101ec9d36bab2d0b6662 /include | |
| parent | 17bb0e2f6c8043f70a693a5f3797471cbed354c8 (diff) | |
| parent | fad06cfaf385787b9ffa2f73f049d42dbe1de57f (diff) | |
| download | linux-5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f.tar.gz linux-5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f.zip | |
Merge tag 'drm-next-2026-10-21' of https://gitlab.freedesktop.org/drm/kernel
Pull drm updates from Dave Airlie:
"Highlights:
- core: a lot of atomic refactoring in progress, panic got split into
a core/helpers model
- amdgpu: enables HDMI 2.1 FRL and other good things finally, UAlink
over Ethernet support
- xe: has a bunch of CRI support, ras error for bad vram, memory
offlining support.
- msm: enables a bunch more GPUs.
Otherwise it's a the usual mountain of stuff all over the place.
Details:
rust:
- I/O tree shared with driver-core
- DMA tree shared with driver-core
- allow aux registration data closures to return covariant sub-fields
- Implement Send and Sync for MapleTree
- add pci resource flags and IORESOURCE_MEM_64
drm/rust:
- add dma_fence abstraction
- init DRM registrations and their data in place
- drop unused flags argument to registration
vgaarb:
- rework API to pass a private ptr instead of pci device
sound:
- adapt to omapdrm changes
gem:
- add callback for handle count going to 0
gpusvm:
- share one HMM fault and keep single mappings inline
pagemap:
- Prevent CPU stalls during unbounded pagemap teardown
dma-fence:
- fix docs
vga_switcheroo:
- disconnect from fbcon
- update fbcon from within fbdev emulation
atomic:
- move DRM from state reset callbacks to atomic_create_state
- remove drm_simple_encoder_init
panic:
- split into core and helpers
buddy:
- improve dirty tracking
clients:
- improve vmap handling
- fbdev: Move helpers from drm_kms_helper.ko to drm_client_lib.ko
display:
- export HDMI SCDC status data via debugfs
- rework SCDC for better HDMI 2.0 support
- dp/mst: improve DPCD compliance
edid:
- parse AMD VSDB
- parse ALLM/VRR capabilities
- support detecting panel size
log:
- add drm_warn_ratelimited
sched:
- cleanup interface
- add missing locking
- fix run-queue cleanup
- fix locking
sysfb:
- remove obsolete quirk for Lenovo D330
- fix panel orientation for non-native display modes
- drop drm_class_device_register
colorop:
- provide DRM_COLOR_OP_FIXED_MATRIX
bridge:
- analogix: Support eDP lane mapping
- ti-sn65dsi83: Support LVDS Channel B on SN65DSI84
- Select DRM_PANEL_BRIDGE for various drivers that require it
- add chrontel ch7218a support
panel:
- panel-edp: Support MNE007QS3-F, TM140VDXP15, and KD116N36-30NB-A001
- samsung-s6d16d0: Use mipi_dsi_*_multi() functions
- support Ilitek ILI7836A OLED plus DT bindings
- support Novatek NT36532 plus DT bindings
- convert several drivers to managed cleanup
- fix Kconfig selections
- edp:
- Add support for BOE NV140FHM-T0A
- Support CSOT MNE007QB1-1
- NV140WU2-M70
- ebbg-ft8719: Fix MODULE_LICENSE() string; Improve initialization
- samsung: Share test-key helpers
- ilitek-ili9882t: Support Ilitek IL79600A plus DT bindings
- simple: Support Truly TFT320240-229-E plus DT bindings; Support BOE
DV215FHM-R01 plus DT bindings
- Refactor struct drm_panel to contain struct drm_bridge plus fallout
in various panel drivers
- Add support for BOE Novatek NT51021, Retroid Pocket 6, Raydium
RM69220 DDIC panels, Sharp LQ138P1JX61 eDP, BOE NV140FHD-N43, AUO
B140HAN04.0, AUO 0x0db3, panels.
amdgpu:
- use AMD VSDB for freesync
- implement YUV-to-RGB with fixed-matrix colorop
- enable FRL for HDMI
- HDMI 2.1 freesync support
- HDMI 2.1 ALLM support
- HDMI 2.1 VRR support
- UALoE (UALink over Ethernet) support
- add syncobj_points to userq signal ioctl
- drop unused kunit tests
- NBIO/GC/MMHUB/SMU updates/fixes
- GPU spatial partitioning updates
- display kunit fixes
- userq fixes
- RGB quantization fixes
- DC RMCM refactor
- DP MST fixes
- USB4 fixes
- add new trace events
- Rework display instance handling
- stack frame size fixes for various compilers/configs
- VCN 4/5 reset fixes
- freesync updates
- cursor refactor
- Fix direct scanout alpha on some DRM_FORMATs
- Expand Mac reserved memory workaround
- Make runtime pm more fine grained
amdkfd:
- updates and fixes
- GC 10 CU occupancy support
radeon:
- eDP fix for DCE3.2 iMacs
xe:
- add drm_ras netlink error event support
- add memory page offlining support
- introduce error threshold to drm_ras
- fix stale GTT mappings on unmap
- reject page faults for non-page fault mode scratch VM
- enable CRI package and VRAM temperatures
- introduce cold reset recovery
- handle CRI+ power interval encoding
- VF migration for multi-queue
- handle exec queue teardown after hot unplug
- alerts and controller enabling modifications
- use IBCv3 on PTL
- VRAM health check
- report GT TDR and VM rebind faults using SIGID
- add multi_queue_active_lrca debugfs
- shrinker: Runtime PM reference for non-system memory
- guc: Add simple KLV decoder helpers
- debugfs: Expose per-engine idle status
- Keep walking on SVM eviction failure
- Nuke PTs only after unlinking contested VMAs
- limit sg segment size to PAGE_SIZE on Xen PV
- keep VF LMEM bar size low if no VFs
- CPU binds and ULLS on migration queue
- New PTL PCI ID
- Enable PXP for NVL-S
- Do not dma_fence_put zero fences in err_out path
- Refresh TTM LRU on SVM prefetch
- export device UID in sysfs
i915:
- rename GEN6_PCODE_DATA to match spec
- fix incorrect RCU teardown order
- fix potential UAF in command parsing
- avoid WARN splat during RPS boosting race
- use simpler min functions
- Fixes to make i915 work well with PREEMPT_RT
i915/display:
- Enable CMRR (Content Match Refresh Rate) in fixed-RR VRR path
- Switch DG2 MPLL to DPLL framework
- DP-HDMI PCON DSC fixes
- limit invalid joiner combinations
- CDCLK related fixes and refactor around PCODE integration
- Gate UHBR SST SDP splitting on sink caps
- add HDMI TMDS audio bandwidth check
- vswing/preemph override
- enable AS SDP Skip frames
- Handle negative configuration index on DP link caps for robustness
- Preparation for enabling SDR plane color pipeline
- An eDP quirk for HP Pavilion Plus
- Introduce PME (Power Management Event) support on display hotplug
- Handle VSC SDP revision 7 in unpack
msm:
- CI:
- Dropped sc7180 trogdor lazor from the CI
- Core:
- Fixed msm_ioremap for resources without a name
- Changed msm.separate_gpu_kms to default to auto selection
- GPU:
- Enable CLX (Current Limit eXtension) for gen8 to avoid exceeding
limits on CX/GX rails
- New GPUs: a830 (Pakala), a845 (Maili), a850 (Hawi), x2-85
(Mahua)
- Fix VBIF halt mask on a306, which was preventing runpm suspend
- Enable THP support for GEM buffers
- Add modparam to disable waiting on fences in shrinker
- Drop use of drm_prime_sg_to_page_array()
- a5xx: don't read the GPMU registers on GPUs without a GPMU
- a2xx/a3xx/a5xx: hangcheck progress detection
- a6xx: gmuwrapper runpm fix
- Calculate reported GMEM size based on active slices
- Split a6xx/a7xx/a8xx catalog
- DP:
- Picked up some preparation patches for the MST support
- Fixed reported status of the link training
- DPU:
- Fixed CRTC bandwidth computation
- Fixed DSC programming
- Fixed encoder disablement path
- DSI:
- Fixed VM leak in error path
- Indention fix
- MDP5:
- Added MSM8952 configuration
- Dropped incorrect cursor pipe on MSM8976/56
- HDMI:
- Small fixes
nouveau:
- improve runtime PM on R570 GSP firmware
- various fixes throughout the driver
- dispnv50: support 2.147 GHz pixel clock in GB20x
nova:
- add initial uapi concept
- add initial PRAMIN access support
- add GpuMm centralized memory manager
- add GPU VM and BAR1 support
- add GPU interrupts and GSP events support
- GSP messaging fixes
tyr:
- use bitfield!
- zero unsupported and newly added GPU info fields
- limit doorbell array to 17 entries
exynos:
- FIMD fixes
- Fix clock leak on resume error path
- Fix Sparse warnings by adding missing __iomem annotation
- VIDI cleanup
- Replace kmalloc() and copy_from_user() with memdup_user()
amdxdna:
- fix BO handling
- Support AIE2 rev 9
- Fix UAF access in scheduler fences
- Update workqueue interface
- expose busy time via fdinfo
ast:
- support 256-byte EDID
hyperv_drm:
- remove support for pre win10 hosts
komeda:
- fix GLB_CORE_ID usage
omap:
- report HDMI hotplug events to ASoC HDMI codec
panthor:
- provide gpu_cache_flush tracepoint
- improve dma_fence signalling latency
- improve locking
- export scheduling information via debugfs
- Validate user-space input against firmware limits
qaic:
- reject BOs that exceed maximum page count
- add missing include statements
verisilicon:
- fix hardware cursor offsets
vkms:
- implement YUV-to-RGB with fixed-matrix colorop
gma500:
- avoid unsupported ARGB formats in primary plane
hibmc:
- handle vblank interrupts correctly
ivpu:
- add DRM_IVPU_CAP_CMDQ_SET_PRIORITY
- support command-queue priority ioctl
- Simplify NULL-pointer handling in cleanup code
arcpgu:
- replace simple-display pipeline with regular atomic helpers
aspeed:
- replace simple-display pipeline with regular atomic helpers
gm12u320:
- replace simple-display pipeline with regular atomic helpers
imagination:
- various improvement to firmware interaction
- add job to pvr_job_submit_fw trace event
mali-dp:
- fix runtime PM leak
mcde:
- replace simple-display pipeline with regular atomic helpers
p111:
- replace simple-display pipeline with regular atomic helpers
- drop unsupported alpha formats from primary plane
rcar-du:
- support Renesas R-Car V4H DSC
- dsi: Support larger transfers with AXI memory
- Support RZ/G3L SoC
repaper:
- replace simple-display pipeline with regular atomic helpers
rockchip:
- dsi: improve PHY timings
ssd130x:
- support Solomon SSD1351 OLED plus DT bindings
- ssd133x: upgrade color format to RGB565
- ssd132x: Set correct hardware window when clearing screen
tve200:
- replace simple-display pipeline with regular atomic helpers
xen:
- replace simple-display pipeline with regular atomic helpers
v3d:
- improve job handling under perfmon
vc4:
- reliably reset V3D
- drop brcm,vc4-v3d compatible
virtio:
- fix damage handling
- Support ARGB8888 for virtio primary planes.
host1x:
- Support partitioning
imx:
- Replace simple-display with regular atomic helpers
mxsfb:
- Support bus formats plus DT bindings
tegra:
- improve syncobj handling on submit
panfrost:
- add Mali-G68 support
- improve GPU reset handling
rockchip:
- add HDMI 2.0 support to dw-hdmi-qp
- improve HPD handling"
* tag 'drm-next-2026-10-21' of https://gitlab.freedesktop.org/drm/kernel: (2324 commits)
drm/adp: Switch to drm_atomic_helper_connector_create_state
drm/malidp: Convert to atomic_create_state
drm/vc4: Switch to drm_atomic_helper_connector_create_state
drm/sysfb: Switch to drm_atomic_helper_connector_create_state
drm/solomon: ssd130x: Switch to drm_atomic_helper_connector_create_state
drm/imx: ipuv3: Switch to drm_atomic_helper_connector_create_state
drm/hyperv: Switch to drm_atomic_helper_connector_create_state
drm/bridge: megachips: Switch to drm_atomic_helper_connector_create_state
drm/bridge: lontium-lt8912b: Switch to drm_atomic_helper_connector_create_state
drm/arm: komeda: Switch to drm_atomic_helper_connector_create_state
drm/appletbdrm: Fix incorrect error message on encoder attach failure
drm/sun4i: hdmi: Convert to drmm_connector_hdmi_init()
drm/rockchip: rk3066_hdmi: Advertise HDMI 1.4 capabilities
drm/bridge: lontium-lt9611: Advertise HDMI 1.4 capabilities
drm/bridge: ite-it66121: Advertise HDMI 1.2 capabilities
drm/bridge: ite-it6263: Advertise HDMI 1.3 capabilities
drm/bridge: ite-it6263: Drop redundant .mode_valid hook
drm/bridge: inno-hdmi: Advertise HDMI 1.2 capabilities
drm/bridge: adv7511: Advertise HDMI 1.2 capabilities
drm/sched: Document entity->stopped is protected by entity->lock
...
Diffstat (limited to 'include')
57 files changed, 1579 insertions, 375 deletions
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 0e0b87abee59..6033137b651e 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -35,7 +35,6 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type) struct analogix_dp_plat_data { enum analogix_dp_devtype dev_type; - struct drm_panel *panel; struct drm_bridge *next_bridge; struct drm_encoder *encoder; struct drm_connector *connector; diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h index 6ea9c561cfef..ad33f9cafdeb 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -16,7 +16,8 @@ struct dw_hdmi_qp_phy_ops { int (*init)(struct dw_hdmi_qp *hdmi, void *data); void (*disable)(struct dw_hdmi_qp *hdmi, void *data); enum drm_connector_status (*read_hpd)(struct dw_hdmi_qp *hdmi, void *data); - void (*setup_hpd)(struct dw_hdmi_qp *hdmi, void *data); + void (*enable_hpd)(struct dw_hdmi_qp *hdmi, void *data); + void (*disable_hpd)(struct dw_hdmi_qp *hdmi, void *data); }; struct dw_hdmi_qp_plat_data { @@ -34,6 +35,7 @@ struct dw_hdmi_qp_plat_data { struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, struct drm_encoder *encoder, const struct dw_hdmi_qp_plat_data *plat_data); +void dw_hdmi_qp_hpd_notify(struct dw_hdmi_qp *hdmi); void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi); void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); #endif /* __DW_HDMI_QP__ */ diff --git a/include/drm/drm_fb_helper.h b/include/drm/clients/drm_fbdev_helper.h index 0c5e5ed7b5e7..7575aaf34c62 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/clients/drm_fbdev_helper.h @@ -27,8 +27,8 @@ * Dave Airlie <airlied@linux.ie> * Jesse Barnes <jesse.barnes@intel.com> */ -#ifndef DRM_FB_HELPER_H -#define DRM_FB_HELPER_H +#ifndef DRM_FBDEV_HELPER_H +#define DRM_FBDEV_HELPER_H struct drm_clip_rect; struct drm_fb_helper; diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 8b0ca36083dd..e63c7f075f54 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -1035,6 +1035,7 @@ # define DP_EDP_14a 0x04 /* eDP 1.4a */ # define DP_EDP_14b 0x05 /* eDP 1.4b */ # define DP_EDP_15 0x06 /* eDP 1.5 */ +# define DP_EDP_20 0x07 /* eDP 2.0 */ #define DP_EDP_GENERAL_CAP_1 0x701 # define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP (1 << 0) diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index ab16c1be3900..5b05a7fbe174 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -139,6 +139,12 @@ bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_C int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]); +static inline bool +drm_dp_lane_count_is_valid(int lane_count) +{ + return lane_count == 1 || lane_count == 2 || lane_count == 4; +} + static inline int drm_dp_max_link_rate(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) { diff --git a/include/drm/display/drm_hdmi_helper.h b/include/drm/display/drm_hdmi_helper.h index 9c31ed90516b..2cdd6e3bc090 100644 --- a/include/drm/display/drm_hdmi_helper.h +++ b/include/drm/display/drm_hdmi_helper.h @@ -8,6 +8,7 @@ struct drm_connector; struct drm_connector_state; struct drm_display_mode; +struct drm_modeset_acquire_ctx; enum drm_output_color_format; void @@ -35,4 +36,18 @@ drm_hdmi_acr_get_n_cts(unsigned long long tmds_char_rate, unsigned int *out_n, unsigned int *out_cts); +bool +drm_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode, + unsigned int bpc, enum drm_output_color_format fmt); + +int +drm_connector_hdmi_enable_scrambling(struct drm_connector *connector, + const struct drm_connector_state *conn_state); +int +drm_connector_hdmi_disable_scrambling(struct drm_connector *connector); + +int +drm_connector_hdmi_sync_scdc(struct drm_connector *connector, bool plugged, + struct drm_modeset_acquire_ctx *ctx); + #endif diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h index 13375bd0f4ae..965342f6bbc9 100644 --- a/include/drm/display/drm_hdmi_state_helper.h +++ b/include/drm/display/drm_hdmi_state_helper.h @@ -3,10 +3,12 @@ #ifndef DRM_HDMI_STATE_HELPER_H_ #define DRM_HDMI_STATE_HELPER_H_ +struct dentry; struct drm_atomic_commit; struct drm_connector; struct drm_connector_state; struct drm_display_mode; +struct drm_modeset_acquire_ctx; struct hdmi_audio_infoframe; enum drm_connector_status; @@ -22,12 +24,17 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector); int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, struct drm_atomic_commit *state); -void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector, - enum drm_connector_status status); +int drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + enum drm_connector_status status); void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector); +int drm_atomic_helper_connector_hdmi_force_ctx(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx); enum drm_mode_status drm_hdmi_connector_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode); +void drm_hdmi_connector_debugfs_init(struct drm_connector *connector, + struct dentry *root); #endif // DRM_HDMI_STATE_HELPER_H_ diff --git a/include/drm/display/drm_scdc.h b/include/drm/display/drm_scdc.h index 3d58f37e8ed8..7f0b05b2f280 100644 --- a/include/drm/display/drm_scdc.h +++ b/include/drm/display/drm_scdc.h @@ -29,6 +29,8 @@ #define SCDC_SOURCE_VERSION 0x02 #define SCDC_UPDATE_0 0x10 +#define SCDC_RSED_UPDATE (1 << 6) +#define SCDC_FLT_UPDATE (1 << 5) #define SCDC_READ_REQUEST_TEST (1 << 2) #define SCDC_CED_UPDATE (1 << 1) #define SCDC_STATUS_UPDATE (1 << 0) @@ -46,14 +48,25 @@ #define SCDC_CONFIG_0 0x30 #define SCDC_READ_REQUEST_ENABLE (1 << 0) +#define SCDC_CONFIG_1 0x31 +#define SCDC_FRL_RATE 0x0f +#define SCDC_FFE_LEVELS 0xf0 + #define SCDC_STATUS_FLAGS_0 0x40 +#define SCDC_DSC_FAIL (1 << 7) +#define SCDC_FLT_READY (1 << 6) +#define SCDC_LN3_LOCK (1 << 4) #define SCDC_CH2_LOCK (1 << 3) #define SCDC_CH1_LOCK (1 << 2) #define SCDC_CH0_LOCK (1 << 1) -#define SCDC_CH_LOCK_MASK (SCDC_CH2_LOCK | SCDC_CH1_LOCK | SCDC_CH0_LOCK) +#define SCDC_CH_LOCK_MASK (SCDC_LN3_LOCK | SCDC_CH2_LOCK | SCDC_CH1_LOCK | \ + SCDC_CH0_LOCK) #define SCDC_CLOCK_DETECT (1 << 0) #define SCDC_STATUS_FLAGS_1 0x41 +#define SCDC_LN_EVEN_TRAIN_PTRN 0x0f +#define SCDC_LN_ODD_TRAIN_PTRN 0xf0 +#define SCDC_STATUS_FLAGS_2 0x42 #define SCDC_ERR_DET_0_L 0x50 #define SCDC_ERR_DET_0_H 0x51 @@ -65,6 +78,12 @@ #define SCDC_ERR_DET_CHECKSUM 0x56 +#define SCDC_ERR_DET_3_L 0x57 +#define SCDC_ERR_DET_3_H 0x58 + +#define SCDC_ERR_DET_RS_L 0x59 +#define SCDC_ERR_DET_RS_H 0x5a + #define SCDC_TEST_CONFIG_0 0xc0 #define SCDC_TEST_READ_REQUEST (1 << 7) #define SCDC_TEST_READ_REQUEST_DELAY(x) ((x) & 0x7f) diff --git a/include/drm/display/drm_scdc_helper.h b/include/drm/display/drm_scdc_helper.h index 34600476a1b9..6a8be1f16ce0 100644 --- a/include/drm/display/drm_scdc_helper.h +++ b/include/drm/display/drm_scdc_helper.h @@ -24,17 +24,108 @@ #ifndef DRM_SCDC_HELPER_H #define DRM_SCDC_HELPER_H +#include <linux/errno.h> #include <linux/types.h> #include <drm/display/drm_scdc.h> struct drm_connector; struct i2c_adapter; +struct dentry; -ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer, - size_t size); -ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset, - const void *buffer, size_t size); +struct drm_scdc_status_flags { + /* Status Register 0 */ + bool clock_detected; + bool ch0_locked; + bool ch1_locked; + bool ch2_locked; + bool ln3_locked; + bool flt_ready; + bool dsc_fail; + + /* Status Register 1 */ + u8 ln0_training_pattern : 4; + u8 ln1_training_pattern : 4; + + /* Status Register 2 */ + u8 ln2_training_pattern : 4; + u8 ln3_training_pattern : 4; +}; + +enum drm_scdc_frl_rate { + SCDC_FRL_RATE_OFF = 0, + SCDC_FRL_RATE_3X3 = 1, + SCDC_FRL_RATE_6X3 = 2, + SCDC_FRL_RATE_6X4 = 3, + SCDC_FRL_RATE_8X4 = 4, + SCDC_FRL_RATE_10X4 = 5, + SCDC_FRL_RATE_12X4 = 6, + SCDC_FRL_RATE_RESV_7 = 7, + SCDC_FRL_RATE_RESV_8 = 8, + SCDC_FRL_RATE_RESV_9 = 9, + SCDC_FRL_RATE_RESV_10 = 10, + SCDC_FRL_RATE_RESV_11 = 11, + SCDC_FRL_RATE_RESV_12 = 12, + SCDC_FRL_RATE_RESV_13 = 13, + SCDC_FRL_RATE_RESV_14 = 14, + SCDC_FRL_RATE_RESV_15 = 15 +}; + +/** + * drm_scdc_num_frl_lanes - get number of lanes for a given FRL rate + * @rate: one of &enum drm_scdc_frl_rate + * + * For a given @rate, return the number of lanes it uses. + * + * Returns: %-EINVAL if @rate is not a valid FRL rate, or the number of lanes + * for a given &enum drm_scdc_frl_rate on success (including %0 for "off") + */ +static inline __pure int drm_scdc_num_frl_lanes(enum drm_scdc_frl_rate rate) +{ + switch (rate) { + case SCDC_FRL_RATE_OFF: + return 0; + case SCDC_FRL_RATE_3X3: + case SCDC_FRL_RATE_6X3: + return 3; + case SCDC_FRL_RATE_6X4: + case SCDC_FRL_RATE_8X4: + case SCDC_FRL_RATE_10X4: + case SCDC_FRL_RATE_12X4: + return 4; + default: + return -EINVAL; + } +} + +struct drm_scdc_state { + /** @stf: contents of the status flag registers */ + struct drm_scdc_status_flags stf; + /** @scramling_enabled: true if TMDS scrambling is on */ + bool scrambling_enabled; + /** @scrambling_detected: true if the sink actually detected scrambling */ + bool scrambling_detected; + /** + * @tmds_bclk_x40: true if TMDS bit period is 1/40th of the TMDS + * clock period, false if it's 1/10th of the clock period. + */ + bool tmds_bclk_x40; + /** @rate: FRL rate set by the source */ + enum drm_scdc_frl_rate rate : 4; + /** @ffe_levels: The FFE levels for @rate set by the source */ + u8 ffe_levels : 4; + /** @error_count: character error counts for each channel/link */ + u16 error_count[4]; + /** @rs_corrections: number of Reed-Solomon Corrections */ + u16 rs_corrections; + /** @scdc: raw SCDC data buffer */ + u8 scdc[256]; +}; + +int drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer, + size_t size); +int drm_scdc_write(struct i2c_adapter *adapter, u8 offset, const void *buffer, + size_t size); /** * drm_scdc_readb - read a single byte from SCDC @@ -77,4 +168,10 @@ bool drm_scdc_get_scrambling_status(struct drm_connector *connector); bool drm_scdc_set_scrambling(struct drm_connector *connector, bool enable); bool drm_scdc_set_high_tmds_clock_ratio(struct drm_connector *connector, bool set); +int drm_scdc_set_source_version(struct drm_connector *connector, u8 ver); + +int drm_scdc_read_state(struct drm_connector *connector, + struct drm_scdc_state *state); +void drm_scdc_debugfs_init(struct drm_connector *connector, struct dentry *root); + #endif diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 88087910ab1a..3ae35b09c0cf 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -159,7 +159,23 @@ struct drm_crtc_commit { struct __drm_colorops_state { struct drm_colorop *ptr; - struct drm_colorop_state *state, *old_state, *new_state; + + /** + * @state_to_destroy: + * + * Used to track the @drm_colorop_state we will need to free + * when tearing down the associated &drm_atomic_commit in + * $drm_mode_config_funcs.atomic_state_clear or + * drm_atomic_commit_default_clear(). + * + * Before a commit, and the call to + * drm_atomic_helper_swap_state() in particular, it points to + * the same state than @new_state. After a commit, it points to + * the same state than @old_state. + */ + struct drm_colorop_state *state_to_destroy; + + struct drm_colorop_state *old_state, *new_state; }; struct __drm_planes_state { @@ -951,9 +967,11 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if ((__state)->connectors[__i].ptr && \ ((connector) = (__state)->connectors[__i].ptr, \ - (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ - (old_connector_state) = (__state)->connectors[__i].old_state, \ - (new_connector_state) = (__state)->connectors[__i].new_state, 1)) + (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ + (old_connector_state) = (__state)->connectors[__i].old_state, \ + (void)(old_connector_state) /* Only to avoid unused-but-set-variable warning */, \ + (new_connector_state) = (__state)->connectors[__i].new_state, \ + (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_old_connector_in_state - iterate over all connectors in an atomic update @@ -973,8 +991,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if ((__state)->connectors[__i].ptr && \ ((connector) = (__state)->connectors[__i].ptr, \ - (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ - (old_connector_state) = (__state)->connectors[__i].old_state, 1)) + (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ + (old_connector_state) = (__state)->connectors[__i].old_state, \ + (void)(old_connector_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_new_connector_in_state - iterate over all connectors in an atomic update @@ -994,9 +1013,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if ((__state)->connectors[__i].ptr && \ ((connector) = (__state)->connectors[__i].ptr, \ - (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ - (new_connector_state) = (__state)->connectors[__i].new_state, \ - (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1)) + (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ + (new_connector_state) = (__state)->connectors[__i].new_state, \ + (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update @@ -1017,10 +1036,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); for_each_if ((__state)->crtcs[__i].ptr && \ ((crtc) = (__state)->crtcs[__i].ptr, \ (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ - (old_crtc_state) = (__state)->crtcs[__i].old_state, \ - (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, \ - (new_crtc_state) = (__state)->crtcs[__i].new_state, \ - (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) + (old_crtc_state) = (__state)->crtcs[__i].old_state, \ + (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, \ + (new_crtc_state) = (__state)->crtcs[__i].new_state, \ + (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_old_crtc_in_state - iterate over all CRTCs in an atomic update @@ -1040,7 +1059,8 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); for_each_if ((__state)->crtcs[__i].ptr && \ ((crtc) = (__state)->crtcs[__i].ptr, \ (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ - (old_crtc_state) = (__state)->crtcs[__i].old_state, 1)) + (old_crtc_state) = (__state)->crtcs[__i].old_state, \ + (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_new_crtc_in_state - iterate over all CRTCs in an atomic update @@ -1126,8 +1146,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); for_each_if ((__state)->planes[__i].ptr && \ ((plane) = (__state)->planes[__i].ptr, \ (void)(plane) /* Only to avoid unused-but-set-variable warning */, \ - (old_plane_state) = (__state)->planes[__i].old_state,\ - (new_plane_state) = (__state)->planes[__i].new_state, 1)) + (old_plane_state) = (__state)->planes[__i].old_state, \ + (void)(old_plane_state) /* Only to avoid unused-but-set-variable warning */, \ + (new_plane_state) = (__state)->planes[__i].new_state, \ + (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic @@ -1148,8 +1170,11 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)--) \ for_each_if ((__state)->planes[__i].ptr && \ ((plane) = (__state)->planes[__i].ptr, \ - (old_plane_state) = (__state)->planes[__i].old_state,\ - (new_plane_state) = (__state)->planes[__i].new_state, 1)) + (void)(plane) /* Only to avoid unused-but-set-variable warning */, \ + (old_plane_state) = (__state)->planes[__i].old_state, \ + (void)(old_plane_state) /* Only to avoid unused-but-set-variable warning */, \ + (new_plane_state) = (__state)->planes[__i].new_state, \ + (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_new_plane_in_state_reverse - other than only tracking new state, @@ -1165,7 +1190,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)--) \ for_each_if ((__state)->planes[__i].ptr && \ ((plane) = (__state)->planes[__i].ptr, \ - (new_plane_state) = (__state)->planes[__i].new_state, 1)) + (void)(plane) /* Only to avoid unused-but-set-variable warning */, \ + (new_plane_state) = (__state)->planes[__i].new_state, \ + (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_old_plane_in_state - iterate over all planes in an atomic update @@ -1184,7 +1211,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if ((__state)->planes[__i].ptr && \ ((plane) = (__state)->planes[__i].ptr, \ - (old_plane_state) = (__state)->planes[__i].old_state, 1)) + (void)(plane) /* Only to avoid unused-but-set-variable warning */, \ + (old_plane_state) = (__state)->planes[__i].old_state, \ + (void)(old_plane_state) /* Only to avoid unused-but-set-variable warning */, 1)) + /** * for_each_new_plane_in_state - iterate over all planes in an atomic update * @__state: &struct drm_atomic_commit pointer @@ -1222,8 +1252,11 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); for ((__i) = 0; \ (__i) < (__state)->num_private_objs && \ ((obj) = (__state)->private_objs[__i].ptr, \ + (void)(obj) /* Only to avoid unused-but-set-variable warning */, \ (old_obj_state) = (__state)->private_objs[__i].old_state, \ - (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ + (void)(old_obj_state) /* Only to avoid unused-but-set-variable warning */, \ + (new_obj_state) = (__state)->private_objs[__i].new_state, \ + (void)(new_obj_state) /* Only to avoid unused-but-set-variable warning */, 1); \ (__i)++) /** @@ -1241,7 +1274,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); for ((__i) = 0; \ (__i) < (__state)->num_private_objs && \ ((obj) = (__state)->private_objs[__i].ptr, \ - (old_obj_state) = (__state)->private_objs[__i].old_state, 1); \ + (void)(obj) /* Only to avoid unused-but-set-variable warning */, \ + (old_obj_state) = (__state)->private_objs[__i].old_state, \ + (void)(old_obj_state) /* Only to avoid unused-but-set-variable warning */, 1); \ (__i)++) /** @@ -1260,7 +1295,8 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i) < (__state)->num_private_objs && \ ((obj) = (__state)->private_objs[__i].ptr, \ (void)(obj) /* Only to avoid unused-but-set-variable warning */, \ - (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ + (new_obj_state) = (__state)->private_objs[__i].new_state, \ + (void)(new_obj_state) /* Only to avoid unused-but-set-variable warning */, 1); \ (__i)++) /** @@ -1361,11 +1397,8 @@ struct drm_bridge_state { struct drm_bus_cfg output_bus_cfg; }; -static inline struct drm_bridge_state * -drm_priv_to_bridge_state(struct drm_private_state *priv) -{ - return container_of(priv, struct drm_bridge_state, base); -} +#define drm_priv_to_bridge_state(priv) \ + container_of_const(priv, struct drm_bridge_state, base) struct drm_bridge_state * drm_atomic_get_bridge_state(struct drm_atomic_commit *state, diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index 34a599c3d86d..4706eeab52c1 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -42,9 +42,6 @@ struct drm_device; void __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *state, struct drm_crtc *crtc); -void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, - struct drm_crtc_state *state); -void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); struct drm_crtc_state * drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc); void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, @@ -59,9 +56,6 @@ void __drm_atomic_helper_plane_state_init(struct drm_plane_state *state, struct drm_plane *plane); struct drm_plane_state * drm_atomic_helper_plane_create_state(struct drm_plane *plane); -void __drm_atomic_helper_plane_reset(struct drm_plane *plane, - struct drm_plane_state *state); -void drm_atomic_helper_plane_reset(struct drm_plane *plane); void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, struct drm_plane_state *state); struct drm_plane_state * diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 58fff047f43b..1981d24a700d 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -562,6 +562,41 @@ struct drm_bridge_funcs { unsigned long long tmds_rate); /** + * @hdmi_scrambler_enable: + * + * Enable source-side scrambling and the high TMDS clock ratio for the + * mode currently being applied. + * + * This only programs the source side. Sink-side SCDC configuration is + * handled by the HDMI connector helpers. + * + * Mandatory for bridges that set the DRM_BRIDGE_OP_HDMI flag in their + * &drm_bridge->ops and advertise HDMI_VERSION_2_0 or later via + * &drm_bridge->supported_hdmi_ver; unused otherwise. + * + * Returns: + * 0 on success, a negative error code otherwise. + */ + int (*hdmi_scrambler_enable)(struct drm_bridge *bridge); + + /** + * @hdmi_scrambler_disable: + * + * Disable source-side scrambling and the high TMDS clock ratio. + * + * This only programs the source side. Sink-side SCDC configuration is + * handled by the HDMI connector helpers. + * + * Mandatory for bridges that set the DRM_BRIDGE_OP_HDMI flag in their + * &drm_bridge->ops and advertise HDMI_VERSION_2_0 or later via + * &drm_bridge->supported_hdmi_ver; unused otherwise. + * + * Returns: + * 0 on success, a negative error code otherwise. + */ + int (*hdmi_scrambler_disable)(struct drm_bridge *bridge); + + /** * @hdmi_clear_avi_infoframe: * * This callback clears the infoframes in the hardware during commit. @@ -1082,6 +1117,12 @@ struct drm_bridge { const char *product; /** + * @supported_hdmi_ver: HDMI version the bridge is conformant with. + * This is only relevant if @DRM_BRIDGE_OP_HDMI is set. + */ + enum hdmi_version supported_hdmi_ver; + + /** * @supported_formats: Bitmask of @drm_output_color_format listing * supported output formats. This is only relevant if * @DRM_BRIDGE_OP_HDMI is set. @@ -1089,6 +1130,14 @@ struct drm_bridge { unsigned int supported_formats; /** + * @max_tmds_char_rate: Maximum TMDS character rate, in Hz, the HDMI + * bridge supports. A value of 0 means the core should use the default + * limit implied by @supported_hdmi_ver. This is only relevant if + * @DRM_BRIDGE_OP_HDMI is set. + */ + unsigned long long max_tmds_char_rate; + + /** * @max_bpc: Maximum bits per char the HDMI bridge supports. Allowed * values are 8, 10 and 12. This is only relevant if * @DRM_BRIDGE_OP_HDMI is set. @@ -1473,60 +1522,6 @@ void drm_bridge_hpd_disable(struct drm_bridge *bridge); void drm_bridge_hpd_notify(struct drm_bridge *bridge, enum drm_connector_status status); -#ifdef CONFIG_DRM_PANEL_BRIDGE -bool drm_bridge_is_panel(const struct drm_bridge *bridge); -struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); -struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, - u32 connector_type); -void drm_panel_bridge_remove(struct drm_bridge *bridge); -int drm_panel_bridge_set_orientation(struct drm_connector *connector, - struct drm_bridge *bridge); -struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, - struct drm_panel *panel); -struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, - struct drm_panel *panel, - u32 connector_type); -struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm, - struct drm_panel *panel); -struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge); -#else -static inline bool drm_bridge_is_panel(const struct drm_bridge *bridge) -{ - return false; -} - -static inline int drm_panel_bridge_set_orientation(struct drm_connector *connector, - struct drm_bridge *bridge) -{ - return -EINVAL; -} -#endif - -#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL_BRIDGE) -struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *node, - u32 port, u32 endpoint); -struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct device_node *node, - u32 port, u32 endpoint); -#else -static inline struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, - struct device_node *node, - u32 port, - u32 endpoint) -{ - return ERR_PTR(-ENODEV); -} - -static inline struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, - struct device_node *node, - u32 port, - u32 endpoint) -{ - return ERR_PTR(-ENODEV); -} -#endif - -void devm_drm_put_bridge(struct device *dev, struct drm_bridge *bridge); - void drm_bridge_debugfs_params(struct dentry *root); void drm_bridge_debugfs_encoder_params(struct dentry *root, struct drm_encoder *encoder); diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 49a21f3dcb36..10a0cae3e48f 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -67,6 +67,20 @@ struct drm_client_funcs { int (*restore)(struct drm_client_dev *client, bool force); /** + * @acquire_outputs: + * + * Called by vga-switcheroo. Informs the client that the outputs will + * be switched to its device. When @acquire_outputs runs, the outputs + * have not been switched yet. The client should only prepare the software + * state. After the switch happened, the client might get a hotplug + * event to update the hardware state. + * + * This callback exists for remapping framebuffers to virtual terminals + * in fbcon. + */ + void (*acquire_outputs)(struct drm_client_dev *client); + + /** * @hotplug: * * Called on drm_kms_helper_hotplug_event(). diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h index 79369c755bc9..c93f404bae1d 100644 --- a/include/drm/drm_client_event.h +++ b/include/drm/drm_client_event.h @@ -11,6 +11,7 @@ struct drm_device; void drm_client_dev_unregister(struct drm_device *dev); void drm_client_dev_hotplug(struct drm_device *dev); void drm_client_dev_restore(struct drm_device *dev, bool force); +void drm_client_dev_acquire_outputs(struct drm_device *dev); void drm_client_dev_suspend(struct drm_device *dev); void drm_client_dev_resume(struct drm_device *dev); #else @@ -20,6 +21,8 @@ static inline void drm_client_dev_hotplug(struct drm_device *dev) { } static inline void drm_client_dev_restore(struct drm_device *dev, bool force) { } +static inline void drm_client_dev_acquire_outputs(struct drm_device *dev) +{ } static inline void drm_client_dev_suspend(struct drm_device *dev) { } static inline void drm_client_dev_resume(struct drm_device *dev) diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 224fae40ed2b..26ef67c835e2 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -135,6 +135,114 @@ enum drm_colorop_curve_1d_type { }; /** + * enum drm_colorop_fixed_matrix_type - type of Fixed Matrix + * + * Describes a Fixed Matrix operation to be applied by the DRM_COLOROP_FIXED_MATRIX + */ +enum drm_colorop_fixed_matrix_type { + /** + * @DRM_COLOROP_FM_YCBCR601_FULL_RGB: + * + * enum string "YCbCr 601 Full to RGB" + * + * Converts full-range YCbCr into full-range RGB using the BT.601 + * coefficients. Y is normalized to [0, 1] and Cb, Cr are centered + * at 0 (the nominal 0.5 offset removed) before the matrix:: + * + * | R | | 1.0 0.000000 1.402000 | | Y | + * | G | = | 1.0 -0.344136 -0.714136 | x | Cb | + * | B | | 1.0 1.772000 0.000000 | | Cr | + */ + DRM_COLOROP_FM_YCBCR601_FULL_RGB, + + /** + * @DRM_COLOROP_FM_YCBCR601_LIMITED_RGB: + * + * enum string "YCbCr 601 Limited to RGB" + * + * Converts limited- (narrow-) range YCbCr into full-range RGB using + * the BT.601 coefficients. Before the matrix Y is offset by 16/255 + * and Cb, Cr are centered at 0, following the studio-range + * convention of ITU-R BT.601:: + * + * | R | | 1.164384 0.000000 1.596027 | | Y - 16/255 | + * | G | = | 1.164384 -0.391762 -0.812968 | x | Cb | + * | B | | 1.164384 2.017232 0.000000 | | Cr | + */ + DRM_COLOROP_FM_YCBCR601_LIMITED_RGB, + + /** + * @DRM_COLOROP_FM_YCBCR709_FULL_RGB: + * + * enum string "YCbCr 709 Full to RGB" + * + * Converts full-range YCbCr into full-range RGB using the BT.709 + * coefficients. Y is normalized to [0, 1] and Cb, Cr are centered + * at 0 (the nominal 0.5 offset removed) before the matrix:: + * + * | R | | 1.0 0.000000 1.574800 | | Y | + * | G | = | 1.0 -0.187324 -0.468124 | x | Cb | + * | B | | 1.0 1.855600 0.000000 | | Cr | + */ + DRM_COLOROP_FM_YCBCR709_FULL_RGB, + + /** + * @DRM_COLOROP_FM_YCBCR709_LIMITED_RGB: + * + * enum string "YCbCr 709 Limited to RGB" + * + * Converts limited- (narrow-) range YCbCr into full-range RGB using + * the BT.709 coefficients. Before the matrix Y is offset by 16/255 + * and Cb, Cr are centered at 0, following the studio-range + * convention of ITU-R BT.709:: + * + * | R | | 1.164384 0.000000 1.792741 | | Y - 16/255 | + * | G | = | 1.164384 -0.213249 -0.532909 | x | Cb | + * | B | | 1.164384 2.112402 0.000000 | | Cr | + */ + DRM_COLOROP_FM_YCBCR709_LIMITED_RGB, + + /** + * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB: + * + * enum string "YCbCr 2020 NC Full to RGB" + * + * Converts full-range YCbCr into full-range RGB using the BT.2020 + * non-constant luminance coefficients. Y is normalized to [0, 1] + * and Cb, Cr are centered at 0 (the nominal 0.5 offset removed) + * before the matrix:: + * + * | R | | 1.0 0.000000 1.474600 | | Y | + * | G | = | 1.0 -0.164553 -0.571353 | x | Cb | + * | B | | 1.0 1.881400 0.000000 | | Cr | + */ + DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB, + + /** + * @DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB: + * + * enum string "YCbCr 2020 NC Limited to RGB" + * + * Converts limited- (narrow-) range YCbCr into full-range RGB using + * the BT.2020 non-constant luminance coefficients. Before the matrix + * Y is offset by 16/255 and Cb, Cr are centered at 0, following the + * studio-range convention of ITU-R BT.2020:: + * + * | R | | 1.164384 0.000000 1.678674 | | Y - 16/255 | + * | G | = | 1.164384 -0.187326 -0.650424 | x | Cb | + * | B | | 1.164384 2.141772 0.000000 | | Cr | + */ + DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB, + + /** + * @DRM_COLOROP_FM_COUNT: + * + * enum value denoting the size of the enum + */ + DRM_COLOROP_FM_COUNT +}; + +/** * struct drm_colorop_state - mutable colorop state */ struct drm_colorop_state { @@ -197,6 +305,13 @@ struct drm_colorop_state { */ enum drm_colorop_lut3d_interpolation_type lut3d_interpolation; + /** + * @fixed_matrix_type: + * + * Type of Fixed Matrix operation. + */ + enum drm_colorop_fixed_matrix_type fixed_matrix_type; + /** @state: backpointer to global drm_atomic_commit */ struct drm_atomic_commit *state; }; @@ -367,6 +482,13 @@ struct drm_colorop { struct drm_property *data_property; /** + * @fixed_matrix_type_property: + * + * Sub-type for DRM_COLOROP_FIXED_MATRIX type. + */ + struct drm_property *fixed_matrix_type_property; + + /** * @next_property: * * Read-only property to next colorop in the pipeline @@ -422,6 +544,10 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col uint32_t lut_size, enum drm_colorop_lut3d_interpolation_type interpolation, uint32_t flags); +int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop, + struct drm_plane *plane, + const struct drm_colorop_funcs *funcs, + u64 supported_fm, uint32_t flags); struct drm_colorop_state * drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop); @@ -480,6 +606,7 @@ drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_ty const char * drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type); +const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type); void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index a0cf0268de48..2ee7c59329aa 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -28,6 +28,7 @@ #include <linux/ctype.h> #include <linux/hdmi.h> #include <linux/notifier.h> +#include <linux/workqueue.h> #include <drm/drm_mode_object.h> #include <drm/drm_util.h> #include <drm/drm_property.h> @@ -255,6 +256,44 @@ struct drm_scdc { }; /** + * struct drm_hdmi_vrr_cap - Information about VRR capabilities of a HDMI sink + * + * Describes the VRR support provided by HDMI 2.1 sink. The information is + * fetched fom additional HFVSDB blocks defined for HDMI 2.1. + */ +struct drm_hdmi_vrr_cap { + /** @fva: flag for Fast VActive (Quick Frame Transport) support */ + bool fva; + + /** @mcnmvrr: flag for Negative M VRR support */ + bool cnmvrr; + + /** @mcinema_vrr: flag for Cinema VRR support */ + bool cinema_vrr; + + /** @mdelta: flag for limited frame-to-frame compensation support */ + bool mdelta; + + /** + * @vrr_min : minimum supported variable refresh rate in Hz. + * Valid values only inide 1 - 48 range + */ + u16 vrr_min; + + /** + * @vrr_max : maximum supported variable refresh rate in Hz (optional). + * Valid values are either 0 (max based on video mode) or >= 100 + */ + u16 vrr_max; + + /** + * @supported: flag for vrr support based on checking for VRRmin and + * VRRmax values having correct values. + */ + bool supported; +}; + +/** * struct drm_hdmi_dsc_cap - DSC capabilities of HDMI sink * * Describes the DSC support provided by HDMI 2.1 sink. @@ -330,6 +369,15 @@ struct drm_hdmi_info { /** @max_lanes: supported by sink */ u8 max_lanes; + /** @fapa_start_location: flag for the FAPA in blanking support */ + bool fapa_start_location; + + /** @allm: flag for Auto Low Latency Mode support by sink */ + bool allm; + + /** @vrr_cap: VRR capabilities of the sink */ + struct drm_hdmi_vrr_cap vrr_cap; + /** @dsc_cap: DSC capabilities of the sink */ struct drm_hdmi_dsc_cap dsc_cap; }; @@ -765,7 +813,7 @@ enum drm_bus_flags { * struct drm_amd_vsdb_info - AMD-specific VSDB information * * This structure holds information parsed from the AMD Vendor-Specific Data - * Block (VSDB) version 3. + * Block (VSDB) versions 1 to 3. */ struct drm_amd_vsdb_info { /** @@ -774,6 +822,26 @@ struct drm_amd_vsdb_info { u8 version; /** + * @freesync_supported: FreeSync (variable refresh rate) supported by panel + */ + bool freesync_supported; + + /** + * @min_frame_rate: FreeSync minimum refresh rate in Hz + */ + u16 min_frame_rate; + + /** + * @max_frame_rate: FreeSync maximum refresh rate in Hz + */ + u16 max_frame_rate; + + /** + * @freesync_vcp_code: MCCS VCP code for FreeSync + */ + u8 freesync_vcp_code; + + /** * @replay_mode: Panel Replay supported */ bool replay_mode; @@ -1131,6 +1199,17 @@ struct drm_connector_hdmi_state { * @tmds_char_rate: TMDS Character Rate, in Hz. */ unsigned long long tmds_char_rate; + + /** + * @scrambler_needed: Whether HDMI 2.0 SCDC scrambling is required + * for the negotiated mode/bpc/format. + * + * Computed by drm_atomic_helper_connector_hdmi_check() according to + * the HDMI 2.0 specification: scrambling is mandatory above a 340 MHz + * TMDS character rate. Optional scrambling at lower rates is + * deliberately not requested by the helper. + */ + bool scrambler_needed; }; /** @@ -1403,9 +1482,51 @@ struct drm_connector_infoframe_funcs { /** * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions + * and controller capabilities */ struct drm_connector_hdmi_funcs { /** + * @vendor: HDMI Controller Vendor name. + */ + const char *vendor; + + /** + * @product: HDMI Controller Product name + */ + const char *product; + + /** + * @supported_hdmi_ver: + * + * Maximum HDMI specification version supported by the controller side + * of this connector. This describes the controller capability only; + * the effective link capabilities may be further restricted by the + * sink, bridge, or mode validation. + */ + enum hdmi_version supported_hdmi_ver; + + /** + * @supported_tmds_char_rate: + * + * Maximum TMDS character rate supported by the controller, in Hz. + * A value of 0 means the core should use the default limit implied by + * @supported_hdmi_ver. + */ + unsigned long long supported_tmds_char_rate; + + /** + * @supported_formats: + * + * Bitmask of @drm_output_color_format listing supported output formats. + */ + unsigned long supported_formats; + + /** + * @max_bpc: Maximum bits per char the HDMI connector supports. + */ + unsigned int max_bpc; + + /** * @tmds_char_rate_valid: * * This callback is invoked at atomic_check time to figure out @@ -1440,6 +1561,36 @@ struct drm_connector_hdmi_funcs { const struct drm_edid *(*read_edid)(struct drm_connector *connector); /** + * @scrambler_enable: + * + * The callback is invoked via @drm_connector_hdmi_enable_scrambling + * during commit to setup SCDC scrambling and high TMDS clock ratio on + * the source side. + * + * The @scrambler_enable callback is mandatory if HDMI 2.0 is to be + * supported. + * + * Returns: + * 0 on success, a negative error code otherwise + */ + int (*scrambler_enable)(struct drm_connector *connector); + + /** + * @scrambler_disable: + * + * The callback is invoked via @drm_connector_hdmi_disable_scrambling + * during commit to tear down SCDC scrambling and high TMDS clock ratio + * on the source side. + * + * The @scrambler_disable callback is mandatory if HDMI 2.0 is to be + * supported. + * + * Returns: + * 0 on success, a negative error code otherwise + */ + int (*scrambler_disable)(struct drm_connector *connector); + + /** * @avi: * * Set of callbacks for handling the AVI InfoFrame. These callbacks are @@ -1561,6 +1712,12 @@ struct drm_connector_funcs { * the sysfs interfaces or on the kernel cmdline. In that case the * @detect callback isn't called. * + * New drivers should implement + * &drm_connector_helper_funcs.force_ctx instead, which gets passed + * the modeset acquire context and thus allows taking additional + * locks. It takes precedence over this callback when both are + * implemented. + * * FIXME: * * Note that this hook is only called by the probe helper. It's not in @@ -2052,7 +2209,38 @@ struct drm_connector_hdmi { unsigned long supported_formats; /** - * @funcs: HDMI connector Control Functions + * @max_tmds_char_rate: Maximum TMDS character rate, in Hz, + * supported by the controller. + * + * This is inferred from &drm_connector_hdmi_funcs.supported_hdmi_ver, + * by default. However, controllers may support a lower rate than that + * specification version would imply. If that is the case, drivers are + * expected to set &drm_connector_hdmi_funcs.supported_tmds_char_rate + * to a non-zero value indicating the actual limit. + */ + unsigned long long max_tmds_char_rate; + + /** + * @scrambler_enabled: Tracks whether HDMI 2.0 scrambler is currently enabled. + */ + bool scrambler_enabled; + + /** + * @scdc_work: Work item currently used to monitor sink-side scrambling + * status and retry setup if the sink resets it. + */ + struct delayed_work scdc_work; + + /** + * @scdc_work_initialized: Tracks whether @scdc_work has been set up via + * INIT_DELAYED_WORK(). The work item is initialized lazily on the first + * scrambling enable, so this guards the teardown paths against touching + * an uninitialized work item. + */ + bool scdc_work_initialized; + + /** + * @funcs: HDMI connector Control Functions and controller capabilities */ const struct drm_connector_hdmi_funcs *funcs; @@ -2551,6 +2739,12 @@ int drmm_connector_init(struct drm_device *dev, struct i2c_adapter *ddc); int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, + int connector_type, + struct i2c_adapter *ddc); +int drmm_connector_hdmi_ini2(struct drm_device *dev, + struct drm_connector *connector, const char *vendor, const char *product, const struct drm_connector_funcs *funcs, const struct drm_connector_hdmi_funcs *hdmi_funcs, @@ -2636,6 +2830,24 @@ drm_connector_is_unregistered(struct drm_connector *connector) DRM_CONNECTOR_UNREGISTERED; } +/** + * drm_connector_hdmi_scrambler_supported - does connector support HDMI + * scrambling? + * @connector: DRM connector + * + * Checks whether or not @connector driver supports HDMI scrambling, based on + * the HDMI version advertised by the controller. + * + * Returns: + * True if the connector supports scrambling, false otherwise. + */ +static inline bool +drm_connector_hdmi_scrambler_supported(const struct drm_connector *connector) +{ + return connector->hdmi.funcs && + connector->hdmi.funcs->supported_hdmi_ver >= HDMI_VERSION_2_0; +} + void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode, enum drm_connector_status status); enum drm_connector_color_format diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 152349f973e3..be5dca538d87 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -424,18 +424,6 @@ struct drm_crtc_state { */ struct drm_crtc_funcs { /** - * @reset: - * - * Reset CRTC hardware and software state to off. This function isn't - * called by the core directly, only through drm_mode_config_reset(). - * It's not a helper hook only for historical reasons. - * - * Atomic drivers can use drm_atomic_helper_crtc_reset() to reset - * atomic state using this hook. - */ - void (*reset)(struct drm_crtc *crtc); - - /** * @cursor_set: * * Update the cursor image. The cursor position is relative to the CRTC diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 768a8dae83c5..75f030d027ee 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -37,6 +37,7 @@ struct pci_controller; #define DRM_WEDGE_RECOVERY_REBIND BIT(1) /* unbind + bind driver */ #define DRM_WEDGE_RECOVERY_BUS_RESET BIT(2) /* unbind + reset bus device + bind */ #define DRM_WEDGE_RECOVERY_VENDOR BIT(3) /* vendor specific recovery method */ +#define DRM_WEDGE_RECOVERY_COLD_RESET BIT(4) /* remove device + slot power cycle + rescan */ /** * struct drm_wedge_task_info - information about the guilty task of a wedge dev diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 04f7a7f1f108..a2617aa34edf 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -490,5 +490,7 @@ u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid); bool drm_edid_match(const struct drm_edid *drm_edid, const struct drm_edid_ident *ident); bool drm_edid_has_quirk(struct drm_connector *connector, enum drm_edid_quirk quirk); +int drm_edid_detect_panel_size(const struct drm_edid *drm_edid, + unsigned int *width, unsigned int *height); #endif /* __DRM_EDID_H__ */ diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 885244e375d3..ed329408acbe 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -228,6 +228,17 @@ struct drm_gem_object_funcs { size_t (*rss)(struct drm_gem_object *obj); /** + * @handle_free: + * + * This callback is called when the GEM handle count goes down to 0. + * It is currently used by AMDGPU driver to release their exported BO + * handles. + * + * This callback is optional. + */ + void (*handle_free)(struct drm_gem_object *obj); + + /** * @vm_ops: * * Virtual memory operations used with mmap. @@ -616,8 +627,7 @@ drm_gem_lru_scan(struct drm_device *dev, struct drm_gem_lru *lru, unsigned int nr_to_scan, unsigned long *remaining, - bool (*shrink)(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket), - struct ww_acquire_ctx *ticket); + bool (*shrink)(struct drm_gem_object *obj)); int drm_gem_evict_locked(struct drm_gem_object *obj); diff --git a/include/drm/drm_gem_atomic_helper.h b/include/drm/drm_gem_atomic_helper.h index 3e01c619a25e..d41877f77b77 100644 --- a/include/drm/drm_gem_atomic_helper.h +++ b/include/drm/drm_gem_atomic_helper.h @@ -91,10 +91,10 @@ to_drm_shadow_plane_state(struct drm_plane_state *state) void __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, struct drm_shadow_plane_state *new_shadow_plane_state); void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state); -void __drm_gem_reset_shadow_plane(struct drm_plane *plane, - struct drm_shadow_plane_state *shadow_plane_state); -void drm_gem_reset_shadow_plane(struct drm_plane *plane); +void __drm_gem_shadow_plane_state_init(struct drm_plane *plane, + struct drm_shadow_plane_state *shadow_plane_state); +struct drm_plane_state *drm_gem_create_shadow_plane_state(struct drm_plane *plane); struct drm_plane_state *drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane); void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane, struct drm_plane_state *plane_state); @@ -107,7 +107,7 @@ void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane, * macro initializes struct drm_plane_funcs to use the rsp helper functions. */ #define DRM_GEM_SHADOW_PLANE_FUNCS \ - .reset = drm_gem_reset_shadow_plane, \ + .atomic_create_state = drm_gem_create_shadow_plane_state, \ .atomic_duplicate_state = drm_gem_duplicate_shadow_plane_state, \ .atomic_destroy_state = drm_gem_destroy_shadow_plane_state @@ -130,7 +130,8 @@ int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pi struct drm_plane_state *plane_state); void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state); -void drm_gem_simple_kms_reset_shadow_plane(struct drm_simple_display_pipe *pipe); +struct drm_plane_state * +drm_gem_simple_kms_create_shadow_plane_state(struct drm_simple_display_pipe *pipe); struct drm_plane_state * drm_gem_simple_kms_duplicate_shadow_plane_state(struct drm_simple_display_pipe *pipe); void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pipe *pipe, @@ -147,7 +148,7 @@ void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pip #define DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS \ .begin_fb_access = drm_gem_simple_kms_begin_shadow_fb_access, \ .end_fb_access = drm_gem_simple_kms_end_shadow_fb_access, \ - .reset_plane = drm_gem_simple_kms_reset_shadow_plane, \ + .create_plane_state = drm_gem_simple_kms_create_shadow_plane_state, \ .duplicate_plane_state = drm_gem_simple_kms_duplicate_shadow_plane_state, \ .destroy_plane_state = drm_gem_simple_kms_destroy_shadow_plane_state diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h index b7d987bf76aa..4d31c6bba745 100644 --- a/include/drm/drm_gpusvm.h +++ b/include/drm/drm_gpusvm.h @@ -10,6 +10,7 @@ #include <linux/kref.h> #include <linux/interval_tree.h> #include <linux/mmu_notifier.h> +#include <drm/drm_pagemap.h> struct dev_pagemap_ops; struct drm_device; @@ -18,7 +19,6 @@ struct drm_gpusvm_notifier; struct drm_gpusvm_ops; struct drm_gpusvm_range; struct drm_pagemap; -struct drm_pagemap_addr; /** * struct drm_gpusvm_ops - Operations structure for GPU SVM @@ -112,6 +112,7 @@ struct drm_gpusvm_notifier { * @unmapped: Flag indicating if the pages has been unmapped * @has_devmem_pages: Flag indicating if the pages has devmem pages * @has_dma_mapping: Flag indicating if the pages has a DMA mapping + * @inline_dma_mapping: Flag indicating if the pages have an inline DMA mapping * @__flags: Flags for pages in u16 form (used for READ_ONCE) */ struct drm_gpusvm_pages_flags { @@ -121,6 +122,7 @@ struct drm_gpusvm_pages_flags { u16 unmapped : 1; u16 has_devmem_pages : 1; u16 has_dma_mapping : 1; + u16 inline_dma_mapping : 1; }; u16 __flags; }; @@ -130,17 +132,27 @@ struct drm_gpusvm_pages_flags { * struct drm_gpusvm_pages - Structure representing a GPU SVM mapped pages * * @drm: The DRM device that owns the dma mappings - * @dma_addr: Device address array + * @dma_addr: Device address array, valid while @flags.inline_dma_mapping is + * not set + * @inline_addr: Device address inline address, valid while + * @flags.inline_dma_mapping is set * @dpagemap: The struct drm_pagemap of the device pages we're dma-mapping. * Note this is assuming only one drm_pagemap per range is allowed. * @state: DMA IOVA state for mapping. * @state_offset: DMA IOVA offset for mapping. * @notifier_seq: Notifier sequence number of the range's pages * @flags: Flags for the range; see &struct drm_gpusvm_pages_flags + * + * @dma_addr and @inline_addr share storage, discriminated by + * @flags.inline_dma_mapping. Driver should use drm_gpusvm_pages_first_dma() + * to access the correct DMA address. */ struct drm_gpusvm_pages { struct drm_device *drm; - struct drm_pagemap_addr *dma_addr; + union { + struct drm_pagemap_addr *dma_addr; + struct drm_pagemap_addr inline_addr; + }; struct drm_pagemap *dpagemap; struct dma_iova_state state; unsigned long state_offset; @@ -254,6 +266,19 @@ struct drm_gpusvm { * @allow_mixed: Allow mixed mappings in get pages. Mixing between system and * single dpagemap is supported, mixing between multiple dpagemap * is unsupported. + * @no_dma_map: Only fault the CPU pages for the range; skip the device DMA + * mapping step. Used by drivers that consume the faulted pages + * without needing a DMA mapping. In this mode @drm on the + * drm_gpusvm_pages is not required, no mapping state is recorded + * and drm_gpusvm_pages_valid() therefore never reports these + * pages as valid; the caller revalidates the snapshot itself, see + * drm_gpusvm_get_pages(). @devmem_only is rejected and no page + * type check is performed, so @allow_mixed has no effect. + * @devmem_fn: Optional callback invoked under the notifier lock, once per + * contiguous run of pages backed by the same &drm_pagemap_devmem. + * Must not sleep and must be idempotent, as a non-contiguous + * allocation is reported more than once. Fires even with + * @no_dma_map. May be NULL. * * Context that is DRM GPUSVM is operating in (i.e. user arguments). */ @@ -261,11 +286,13 @@ struct drm_gpusvm_ctx { void *device_private_page_owner; unsigned long check_pages_threshold; unsigned long timeslice_ms; + void (*devmem_fn)(struct drm_pagemap_devmem *devmem); unsigned int in_notifier :1; unsigned int read_only :1; unsigned int devmem_possible :1; unsigned int devmem_only :1; unsigned int allow_mixed :1; + unsigned int no_dma_map :1; }; int drm_gpusvm_init(struct drm_gpusvm *gpusvm, @@ -324,6 +351,7 @@ void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range, int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, struct drm_gpusvm_pages *svm_pages, + unsigned int num_pages, struct mm_struct *mm, struct mmu_interval_notifier *notifier, unsigned long pages_start, unsigned long pages_end, @@ -356,6 +384,49 @@ static inline void drm_gpusvm_init_pages(struct drm_gpusvm_pages *svm_pages, } /** + * drm_gpusvm_pages_first_dma() - Resolve the device address array + * @svm_pages: Pointer to the drm_gpusvm_pages. + * @contiguous: Where to store whether one entry spans the whole range, or NULL + * + * drm_gpusvm_pages use unions to optimize the storage of DMA addresses, + * this function abstracts the access to the first device address. The driver + * should use this helper instead of reading dma_addr directly to prevent + * array out of bounds access. + * + * @contiguous comes from the same read of the flags as the array itself, so a + * caller cannot see the two disagree and walk past that single entry into the + * fields behind it. When it is set the length comes from the range rather than + * from the order. The order still states what one PTE may cover: the range + * length for a huge page, PAGE_SIZE for an IOVA mapped range of single pages. + * + * Only get_pages() and the free path switch between the two union members. + * Both hold the notifier lock for read, so taking that lock does not stop + * them; callers need the driver lock that does, which every reader of the + * addresses holds anyway. The notifier never touches the union, so the + * pointer returned here stays good and can then be used under the notifier + * lock. + * + * Return: Pointer to the first device address, NULL if none is populated. + */ +static inline const struct drm_pagemap_addr * +drm_gpusvm_pages_first_dma(const struct drm_gpusvm_pages *svm_pages, + bool *contiguous) +{ + struct drm_gpusvm_pages_flags flags = { + /* READ_ONCE pairs with the WRITE_ONCE of the flag writers */ + .__flags = READ_ONCE(svm_pages->flags.__flags), + }; + + if (contiguous) + *contiguous = flags.inline_dma_mapping; + + if (flags.inline_dma_mapping) + return &svm_pages->inline_addr; + + return READ_ONCE(svm_pages->dma_addr); +} + +/** * enum drm_gpusvm_scan_result - Scan result from the drm_gpusvm_scan_mm() function. * @DRM_GPUSVM_SCAN_UNPOPULATED: At least one page was not present or inaccessible. * @DRM_GPUSVM_SCAN_EQUAL: All pages belong to the struct dev_pagemap indicated as diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index 78ab23d844ce..d93e25fdc2e1 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -234,7 +234,7 @@ void drm_mipi_dbi_plane_helper_atomic_update(struct drm_plane *plane, */ #define DRM_MIPI_DBI_CRTC_FUNCS \ - .reset = drm_atomic_helper_crtc_reset, \ + .atomic_create_state = drm_atomic_helper_crtc_create_state, \ .set_config = drm_atomic_helper_set_config, \ .page_flip = drm_atomic_helper_page_flip, \ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, \ diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index d8f5b7e9673e..084517beb924 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -495,8 +495,8 @@ struct drm_mode_config { * * Raw spinlock used to protect critical sections of code that access * the display hardware or modeset software state, which the panic - * printing code must be protected against. See drm_panic_trylock(), - * drm_panic_lock() and drm_panic_unlock(). + * printing code must be protected against. See the documentation on + * DRM panic handling for more information. */ struct raw_spinlock panic_lock; diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index ca6268945c28..60b30cc26940 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -282,6 +282,20 @@ struct drm_crtc_helper_funcs { void (*disable)(struct drm_crtc *crtc); /** + * @hw_reset: + * + * Optional hook for CRTC hardware reset. + * + * Unlike @drm_crtc_funcs.reset, which both resets hardware and + * creates new software state, this hook only resets the + * hardware to a known good state without touching the software + * state at all. + * + * This hook is called by drm_mode_config_reset(). + */ + void (*hw_reset)(struct drm_crtc *crtc); + + /** * @atomic_check: * * Drivers should check plane-update related CRTC constraints in this @@ -922,6 +936,34 @@ struct drm_connector_helper_funcs { bool force); /** + * @force_ctx: + * + * This function is called to update internal encoder state when the + * connector is forced to a certain state by userspace, either through + * the sysfs interfaces or on the kernel cmdline. In that case the + * @detect_ctx callback isn't called. + * + * This is the atomic version of &drm_connector_funcs.force. When + * both are implemented, this one takes precedence and + * &drm_connector_funcs.force is not called. + * + * To avoid races against concurrent connector state updates, the + * helper libraries always call this with ctx set to a valid context, + * and &drm_mode_config.connection_mutex will always be locked with + * the ctx parameter set to this ctx. This allows taking additional + * locks as required. + * + * RETURNS: + * + * Zero on success, or a negative error code otherwise. This includes + * -EDEADLK when a lock acquisition needs to be restarted, in which + * case the helpers take care of backing off and calling this function + * again. + */ + int (*force_ctx)(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx); + + /** * @mode_valid: * * Callback to validate a mode for a connector, irrespective of the @@ -1442,17 +1484,20 @@ struct drm_plane_helper_funcs { /** * @get_scanout_buffer: * - * Get the current scanout buffer, to display a message with drm_panic. + * Get the current scanout buffer to display a message with drm_panic. * The driver should do the minimum changes to provide a buffer, * that can be used to display the panic screen. Currently only linear * buffers are supported. Non-linear buffer support is on the TODO list. * The device &dev.mode_config.panic_lock is taken before calling this * function, so you can safely access the &plane.state * It is called from a panic callback, and must follow its restrictions. - * Please look the documentation at drm_panic_trylock() for an in-depth + * Please look the documentation on DRM panic handling for an in-depth * discussions of what's safe and what is not allowed. + * * It's a best effort mode, so it's expected that in some complex cases - * the panic screen won't be displayed. + * the panic screen won't be displayed. Drivers must not make any + * assumptions about the actual state of the hardware. + * * The returned &drm_scanout_buffer.map must be valid if no error code is * returned. * @@ -1472,7 +1517,7 @@ struct drm_plane_helper_funcs { * It is only called if get_scanout_buffer() returned successfully, and * the &dev.mode_config.panic_lock is held during the entire sequence. * It is called from a panic callback, and must follow its restrictions. - * Please look the documentation at drm_panic_trylock() for an in-depth + * Please look the documentation on DRM panic handling for an in-depth * discussions of what's safe and what is not allowed. */ void (*panic_flush)(struct drm_plane *plane); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index ebebed14c611..002ba1b18eb1 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -7,6 +7,7 @@ #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) #include <linux/of.h> #include <drm/drm_bridge.h> +#include <drm/drm_panel.h> #endif struct component_master_ops; @@ -14,8 +15,6 @@ struct component_match; struct device; struct drm_device; struct drm_encoder; -struct drm_panel; -struct drm_bridge; struct device_node; struct mipi_dsi_device_info; struct mipi_dsi_host; @@ -51,10 +50,6 @@ int drm_of_encoder_active_endpoint(struct device_node *node, struct of_endpoint *endpoint); int drm_of_get_panel_orientation(const struct device_node *np, enum drm_panel_orientation *orientation); -int drm_of_find_panel_or_bridge(const struct device_node *np, - int port, int endpoint, - struct drm_panel **panel, - struct drm_bridge **bridge); int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1, const struct device_node *port2); int drm_of_lvds_get_dual_link_pixel_order_sink(struct device_node *port1, @@ -112,14 +107,6 @@ static inline int drm_of_get_panel_orientation(const struct device_node *np, return -EINVAL; } -static inline int drm_of_find_panel_or_bridge(const struct device_node *np, - int port, int endpoint, - struct drm_panel **panel, - struct drm_bridge **bridge) -{ - return -EINVAL; -} - static inline int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1, const struct device_node *port2) diff --git a/include/drm/drm_pagemap.h b/include/drm/drm_pagemap.h index ebbd3b0ddf36..d12a509d6baf 100644 --- a/include/drm/drm_pagemap.h +++ b/include/drm/drm_pagemap.h @@ -258,6 +258,8 @@ struct drm_pagemap *drm_pagemap_create(struct drm_device *drm, struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page); +struct drm_pagemap_devmem *drm_pagemap_page_to_devmem(struct page *page); + void drm_pagemap_put(struct drm_pagemap *dpagemap); #else @@ -267,6 +269,11 @@ static inline struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page return NULL; } +static inline struct drm_pagemap_devmem *drm_pagemap_page_to_devmem(struct page *page) +{ + return NULL; +} + static inline void drm_pagemap_put(struct drm_pagemap *dpagemap) { } diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index b87323443f49..58113ea7d63a 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -30,10 +30,14 @@ #include <linux/mutex.h> #include <linux/kref.h> +#include <drm/drm_bridge.h> + struct backlight_device; struct dentry; struct device_node; +struct drm_bridge; struct drm_connector; +struct drm_device; struct drm_panel_follower; struct drm_panel; struct display_timing; @@ -229,6 +233,22 @@ struct drm_panel { const struct drm_panel_funcs *funcs; /** + * @bridge: + * + * Bridge to access the panel features through the drm_bridge API. + */ + struct drm_bridge bridge; + + /** + * @connector: + * + * Connector instantiated by the bridge (only for legacy code not + * yet using the drm_bridge_connector and + * DRM_BRIDGE_ATTACH_NO_CONNECTOR). + */ + struct drm_connector connector; + + /** * @connector_type: * * Type of the panel as a DRM_MODE_CONNECTOR_* value. This is used to @@ -281,17 +301,6 @@ struct drm_panel { * If true then the panel has been enabled. */ bool enabled; - - /** - * @container: Pointer to the private driver struct embedding this - * @struct drm_panel. - */ - void *container; - - /** - * @refcount: reference count of users referencing this panel. - */ - struct kref refcount; }; void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset, @@ -335,16 +344,28 @@ void drm_panel_disable(struct drm_panel *panel); int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector); -#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL) +#if defined(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL) struct drm_panel *of_drm_find_panel(const struct device_node *np); +int drm_of_find_panel_or_bridge(const struct device_node *np, + int port, int endpoint, + struct drm_panel **panel, + struct drm_bridge **bridge); #else static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) { return ERR_PTR(-ENODEV); } + +static inline int drm_of_find_panel_or_bridge(const struct device_node *np, + int port, int endpoint, + struct drm_panel **panel, + struct drm_bridge **bridge) +{ + return -EINVAL; +} #endif -#if defined(CONFIG_DRM_PANEL) +#if IS_ENABLED(CONFIG_DRM_PANEL) bool drm_is_panel_follower(struct device *dev); int drm_panel_add_follower(struct device *follower_dev, struct drm_panel_follower *follower); @@ -381,4 +402,56 @@ static inline int drm_panel_of_backlight(struct drm_panel *panel) } #endif +#ifdef CONFIG_DRM_PANEL_BRIDGE +bool drm_bridge_is_panel(const struct drm_bridge *bridge); +struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); +struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, + u32 connector_type); +void drm_panel_bridge_remove(struct drm_bridge *bridge); +int drm_panel_bridge_set_orientation(struct drm_connector *connector, + struct drm_bridge *bridge); +struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, + struct drm_panel *panel); +struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, + struct drm_panel *panel, + u32 connector_type); +struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm, + struct drm_panel *panel); +struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge); +#else +static inline bool drm_bridge_is_panel(const struct drm_bridge *bridge) +{ + return false; +} + +static inline int drm_panel_bridge_set_orientation(struct drm_connector *connector, + struct drm_bridge *bridge) +{ + return -EINVAL; +} +#endif + +#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL_BRIDGE) +struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *node, + u32 port, u32 endpoint); +struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct device_node *node, + u32 port, u32 endpoint); +#else +static inline struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, + struct device_node *node, + u32 port, + u32 endpoint) +{ + return ERR_PTR(-ENODEV); +} + +static inline struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, + struct device_node *node, + u32 port, + u32 endpoint) +{ + return ERR_PTR(-ENODEV); +} +#endif + #endif diff --git a/include/drm/drm_utils.h b/include/drm/drm_panel_quirks.h index 7e077484c5bb..60711a49d403 100644 --- a/include/drm/drm_utils.h +++ b/include/drm/drm_panel_quirks.h @@ -1,14 +1,12 @@ /* SPDX-License-Identifier: MIT */ /* - * Function prototypes for misc. drm utility functions. - * Specifically this file is for function prototypes for functions which - * may also be used outside of drm code (e.g. in fbdev drivers). + * Function prototypes for panel-related quirks. * * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com> */ -#ifndef __DRM_UTILS_H__ -#define __DRM_UTILS_H__ +#ifndef __DRM_PANEL_QUIRKS_H__ +#define __DRM_PANEL_QUIRKS_H__ #include <linux/types.h> @@ -25,6 +23,4 @@ struct drm_panel_backlight_quirk { const struct drm_panel_backlight_quirk * drm_get_panel_backlight_quirk(const struct drm_edid *edid); -signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec); - #endif diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h index ac0e46b73436..3e628cbaffca 100644 --- a/include/drm/drm_panic.h +++ b/include/drm/drm_panic.h @@ -8,13 +8,19 @@ #ifndef __DRM_PANIC_H__ #define __DRM_PANIC_H__ -#include <linux/module.h> #include <linux/types.h> #include <linux/iosys-map.h> -#include <drm/drm_device.h> #include <drm/drm_fourcc.h> +struct page; + +enum drm_panic_type { + DRM_PANIC_TYPE_KMSG, + DRM_PANIC_TYPE_USER, + DRM_PANIC_TYPE_QR, +}; + /** * struct drm_scanout_buffer - DRM scanout buffer * @@ -77,113 +83,6 @@ struct drm_scanout_buffer { * set_pixel() */ void *private; - }; -#ifdef CONFIG_DRM_PANIC - -/** - * drm_panic_trylock - try to enter the panic printing critical section - * @dev: struct drm_device - * @flags: unsigned long irq flags you need to pass to the unlock() counterpart - * - * This function must be called by any panic printing code. The panic printing - * attempt must be aborted if the trylock fails. - * - * Panic printing code can make the following assumptions while holding the - * panic lock: - * - * - Anything protected by drm_panic_lock() and drm_panic_unlock() pairs is safe - * to access. - * - * - Furthermore the panic printing code only registers in drm_dev_unregister() - * and gets removed in drm_dev_unregister(). This allows the panic code to - * safely access any state which is invariant in between these two function - * calls, like the list of planes &drm_mode_config.plane_list or most of the - * struct drm_plane structure. - * - * Specifically thanks to the protection around plane updates in - * drm_atomic_helper_swap_state() the following additional guarantees hold: - * - * - It is safe to deference the drm_plane.state pointer. - * - * - Anything in struct drm_plane_state or the driver's subclass thereof which - * stays invariant after the atomic check code has finished is safe to access. - * Specifically this includes the reference counted pointers to framebuffer - * and buffer objects. - * - * - Anything set up by &drm_plane_helper_funcs.fb_prepare and cleaned up - * &drm_plane_helper_funcs.fb_cleanup is safe to access, as long as it stays - * invariant between these two calls. This also means that for drivers using - * dynamic buffer management the framebuffer is pinned, and therefer all - * relevant datastructures can be accessed without taking any further locks - * (which would be impossible in panic context anyway). - * - * - Importantly, software and hardware state set up by - * &drm_plane_helper_funcs.begin_fb_access and - * &drm_plane_helper_funcs.end_fb_access is not safe to access. - * - * Drivers must not make any assumptions about the actual state of the hardware, - * unless they explicitly protected these hardware access with drm_panic_lock() - * and drm_panic_unlock(). - * - * Return: - * %0 when failing to acquire the raw spinlock, nonzero on success. - */ -#define drm_panic_trylock(dev, flags) \ - raw_spin_trylock_irqsave(&(dev)->mode_config.panic_lock, flags) - -/** - * drm_panic_lock - protect panic printing relevant state - * @dev: struct drm_device - * @flags: unsigned long irq flags you need to pass to the unlock() counterpart - * - * This function must be called to protect software and hardware state that the - * panic printing code must be able to rely on. The protected sections must be - * as small as possible. It uses the irqsave/irqrestore variant, and can be - * called from irq handler. Examples include: - * - * - Access to peek/poke or other similar registers, if that is the way the - * driver prints the pixels into the scanout buffer at panic time. - * - * - Updates to pointers like &drm_plane.state, allowing the panic handler to - * safely deference these. This is done in drm_atomic_helper_swap_state(). - * - * - An state that isn't invariant and that the driver must be able to access - * during panic printing. - */ - -#define drm_panic_lock(dev, flags) \ - raw_spin_lock_irqsave(&(dev)->mode_config.panic_lock, flags) - -/** - * drm_panic_unlock - end of the panic printing critical section - * @dev: struct drm_device - * @flags: irq flags that were returned when acquiring the lock - * - * Unlocks the raw spinlock acquired by either drm_panic_lock() or - * drm_panic_trylock(). - */ -#define drm_panic_unlock(dev, flags) \ - raw_spin_unlock_irqrestore(&(dev)->mode_config.panic_lock, flags) - -#else - -static inline bool drm_panic_trylock(struct drm_device *dev, unsigned long flags) -{ - return true; -} - -static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {} -static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {} - -#endif - -#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) -size_t drm_panic_qr_max_data_size(u8 version, size_t url_len); - -u8 drm_panic_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size, - u8 *tmp, size_t tmp_size); -#endif - #endif /* __DRM_PANIC_H__ */ diff --git a/include/drm/drm_panic_helper.h b/include/drm/drm_panic_helper.h new file mode 100644 index 000000000000..fbfe51161aef --- /dev/null +++ b/include/drm/drm_panic_helper.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 or MIT */ + +#ifndef __DRM_DRM_PANIC_HELPER_H_ +#define __DRM_DRM_PANIC_HELPER_H_ + +#include <linux/types.h> + +enum drm_panic_type; + +struct drm_plane; +struct drm_scanout_buffer; + +/* drm_panic_helper.c */ +int drm_plane_helper_display_panic_screen(struct drm_plane *plane, + const char *description, + enum drm_panic_type panic_type, + u32 fg_color, u32 bg_color, + unsigned int qr_version); +#if IS_ENABLED(CONFIG_KUNIT) +int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color); +int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color); +int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb, + u32 fg_color, u32 bg_color, unsigned int qr_version); +void drm_panic_helper_set_description(const char *description); +void drm_panic_helper_clear_description(void); +#endif + +/* drm_panic_helper_qr.rs */ +size_t drm_panic_helper_qr_max_data_size(u8 version, size_t url_len); +u8 drm_panic_helper_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size, + u8 *tmp, size_t tmp_size); + +#if IS_ENABLED(CONFIG_DRM_PANIC) +#define DRM_PANIC_PLANE_FUNCS \ + .display_panic_screen = drm_plane_helper_display_panic_screen +#else +#define DRM_PANIC_PLANE_FUNCS \ + .display_panic_screen = NULL +#endif + +#endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 2c5a5a70a71b..410d7b02b77a 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -32,6 +32,8 @@ #include <drm/drm_modeset_lock.h> #include <drm/drm_util.h> +enum drm_panic_type; + struct drm_crtc; struct drm_plane_size_hint; struct drm_printer; @@ -360,18 +362,6 @@ struct drm_plane_funcs { void (*destroy)(struct drm_plane *plane); /** - * @reset: - * - * Reset plane hardware and software state to off. This function isn't - * called by the core directly, only through drm_mode_config_reset(). - * It's not a helper hook only for historical reasons. - * - * Atomic drivers can use drm_atomic_helper_plane_reset() to reset - * atomic state using this hook. - */ - void (*reset)(struct drm_plane *plane); - - /** * @set_property: * * This is the legacy entry point to update a property attached to the @@ -590,6 +580,61 @@ struct drm_plane_funcs { bool (*format_mod_supported_async)(struct drm_plane *plane, u32 format, u64 modifier); + /** + * @display_panic_screen: + * + * DRM panic handling invokes this callback on panics. + * + * It is a panic handler, so it can't take locks, allocate memory, run tasks/irq, + * or attempt to sleep. It's a best effort, and it may not be able to display + * the message in all situations (like if the panic occurs in the middle of a + * modesetting). + * + * Panic-printing code must acquire the panic lock before interacting with the + * scanout buffer. Such helpers can make the following assumptions while holding + * the panic lock: + * + * - Anything protected by drm_panic_lock() and drm_panic_unlock() pairs is safe + * to access. + * + * - Furthermore the panic printing code only registers in drm_dev_unregister() + * and gets removed in drm_dev_unregister(). This allows the panic code to + * safely access any state which is invariant in between these two function + * calls, like the list of planes &drm_mode_config.plane_list or most of the + * struct drm_plane structure. + * + * Specifically thanks to the protection around plane updates in + * drm_atomic_helper_swap_state() the following additional guarantees hold: + * + * - It is safe to deference the drm_plane.state pointer. + * + * - Anything in struct drm_plane_state or the driver's subclass thereof which + * stays invariant after the atomic check code has finished is safe to access. + * Specifically this includes the reference counted pointers to framebuffer + * and buffer objects. + * + * - Anything set up by &drm_plane_helper_funcs.fb_prepare and cleaned up + * &drm_plane_helper_funcs.fb_cleanup is safe to access, as long as it stays + * invariant between these two calls. This also means that for drivers using + * dynamic buffer management the framebuffer is pinned, and therefer all + * relevant datastructures can be accessed without taking any further locks + * (which would be impossible in panic context anyway). + * + * - Importantly, software and hardware state set up by + * &drm_plane_helper_funcs.begin_fb_access and + * &drm_plane_helper_funcs.end_fb_access is not safe to access. + * + * It will display only one static frame, so performance optimizations are + * low priority as the machine is already in an unusable state. + * + * This callback is optional. Planes without will not be considered + * for panic output. + */ + int (*display_panic_screen)(struct drm_plane *plane, + const char *description, + enum drm_panic_type panic_type, + u32 fg_color, u32 bg_color, + unsigned int qr_version); }; /** diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 2adc5ac688e1..0805903c093b 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -644,6 +644,9 @@ static inline struct device *__drm_to_dev(const struct drm_device *drm) #define drm_err_ratelimited(drm, fmt, ...) \ __drm_printk((drm), err, _ratelimited, "*ERROR* " fmt, ##__VA_ARGS__) +#define drm_warn_ratelimited(drm, fmt, ...) \ + __drm_printk((drm), warn, _ratelimited, fmt, ##__VA_ARGS__) + #define drm_dbg_core(drm, fmt, ...) \ drm_dev_dbg(__drm_to_dev(drm), DRM_UT_CORE, fmt, ##__VA_ARGS__) diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h index 0beede3ddc4e..1765a3130b09 100644 --- a/include/drm/drm_ras.h +++ b/include/drm/drm_ras.h @@ -71,6 +71,35 @@ struct drm_ras_node { */ int (*clear_error_counter)(struct drm_ras_node *node, u32 error_id); + /** + * @query_error_threshold: + * + * This callback is used by drm-ras to query error threshold of a + * specific counter. + * + * Driver should expect query_error_threshold() to be called with + * error_id from `error_counter_range.first` to + * `error_counter_range.last`. + * + * Returns: 0 on success, negative error code on failure. + */ + int (*query_error_threshold)(struct drm_ras_node *node, u32 error_id, const char **name, + u32 *threshold); + + /** + * @set_error_threshold: + * + * This callback is used by drm-ras to set error threshold of a specific + * counter. + * + * Driver should expect set_error_threshold() to be called with error_id + * from `error_counter_range.first` to `error_counter_range.last`. + * Driver is responsible for error threshold bounds checking. + * + * Returns: 0 on success, negative error code on failure. + */ + int (*set_error_threshold)(struct drm_ras_node *node, u32 error_id, u32 threshold); + /** @priv: Driver private data */ void *priv; }; @@ -80,9 +109,14 @@ struct drm_device; #if IS_ENABLED(CONFIG_DRM_RAS) int drm_ras_node_register(struct drm_ras_node *node); void drm_ras_node_unregister(struct drm_ras_node *node); +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, + u32 value); #else static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; } static inline void drm_ras_node_unregister(struct drm_ras_node *node) { } +static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, + const char *error_name, u32 value) +{ return 0; } #endif #endif diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index cb672ce0e856..2b31c25c57a9 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -39,11 +39,10 @@ struct drm_simple_display_pipe_funcs { struct drm_plane_state *plane_state); int (*enable_vblank)(struct drm_simple_display_pipe *pipe); void (*disable_vblank)(struct drm_simple_display_pipe *pipe); - void (*reset_crtc)(struct drm_simple_display_pipe *pipe); struct drm_crtc_state * (*duplicate_crtc_state)(struct drm_simple_display_pipe *pipe); void (*destroy_crtc_state)(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state); - void (*reset_plane)(struct drm_simple_display_pipe *pipe); + struct drm_plane_state * (*create_plane_state)(struct drm_simple_display_pipe *pipe); struct drm_plane_state * (*duplicate_plane_state)(struct drm_simple_display_pipe *pipe); void (*destroy_plane_state)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state); @@ -68,10 +67,6 @@ int drm_simple_display_pipe_init(struct drm_device *dev, const uint64_t *format_modifiers, struct drm_connector *connector); -int drm_simple_encoder_init(struct drm_device *dev, - struct drm_encoder *encoder, - int encoder_type); - void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size, size_t offset, int encoder_type); diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h index 96a5d858404b..7695873a9456 100644 --- a/include/drm/drm_sysfs.h +++ b/include/drm/drm_sysfs.h @@ -3,13 +3,9 @@ #define _DRM_SYSFS_H_ struct drm_device; -struct device; struct drm_connector; struct drm_property; -int drm_class_device_register(struct device *dev); -void drm_class_device_unregister(struct device *dev); - void drm_sysfs_hotplug_event(struct drm_device *dev); void drm_sysfs_connector_hotplug_event(struct drm_connector *connector); void drm_sysfs_connector_property_event(struct drm_connector *connector, diff --git a/include/drm/drm_timeout.h b/include/drm/drm_timeout.h new file mode 100644 index 000000000000..6ee222a3e97c --- /dev/null +++ b/include/drm/drm_timeout.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Function prototypes for timeout conversion helpers for wait ioctls. + * + * Copyright 2017 Red Hat + * Copyright 2016 Advanced Micro Devices, Inc. + */ + +#ifndef __DRM_TIMEOUT_H__ +#define __DRM_TIMEOUT_H__ + +#include <linux/types.h> + +signed long drm_timeout_abs_to_jiffies(s64 timeout_nsec); +unsigned long drm_timeout_rel_to_jiffies(u64 timeout_nsec); + +#endif diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 7a64cc11de08..3b0978fa8cf0 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -100,8 +100,8 @@ struct drm_sched_entity { * @lock: * * Lock protecting the run-queue (@rq) to which this entity belongs, - * @priority, the list of schedulers (@sched_list, @num_sched_list) and - * the @rr_ts field. + * @priority, @last_scheduled and the list of schedulers (@sched_list, + * @num_sched_list), @rr_ts and @stopped. */ spinlock_t lock; @@ -215,11 +215,9 @@ struct drm_sched_entity { /** * @last_scheduled: * - * Points to the finished fence of the last scheduled job. Only written - * by drm_sched_entity_pop_job(). Can be accessed locklessly from - * drm_sched_job_arm() if the queue is empty. + * Points to the finished fence of the last scheduled job. */ - struct dma_fence __rcu *last_scheduled; + struct dma_fence *last_scheduled; /** * @last_user: last group leader pushing a job into the entity. diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index de395df9ca30..464fb588cb60 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -16,11 +16,11 @@ struct drm_mode_fb_cmd2; struct drm_plane_state; struct drm_scanout_buffer; struct fb_info; -struct i915_gtt_view; struct i915_vma; struct intel_dpt; struct intel_dsb_buffer; struct intel_frontbuffer; +struct intel_gtt_view; struct intel_hdcp_gsc_context; struct intel_initial_plane_config; struct intel_panic; @@ -31,7 +31,7 @@ struct seq_file; struct vm_area_struct; struct intel_fb_pin_params { - const struct i915_gtt_view *view; + const struct intel_gtt_view *view; unsigned int alignment; unsigned int phys_alignment; unsigned int vtd_guard; @@ -101,9 +101,9 @@ struct intel_display_fb_pin_interface { struct i915_vma *ggtt_vma); struct i915_vma *(*reuse_vma)(struct i915_vma *old_ggtt_vma, struct drm_gem_object *old_obj, - const struct i915_gtt_view *old_view, + const struct intel_gtt_view *old_view, struct drm_gem_object *new_obj, - const struct i915_gtt_view *new_view, + const struct intel_gtt_view *new_view, u32 *out_offset); void (*get_map)(struct i915_vma *vma, struct iosys_map *map); }; @@ -179,7 +179,7 @@ struct intel_display_pc8_interface { }; struct intel_display_pcode_interface { - int (*read)(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1); + int (*read)(struct drm_device *drm, u32 mbox, u32 *val0, u32 *val1); int (*write)(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms); int (*request)(struct drm_device *drm, u32 mbox, u32 request, u32 reply_mask, u32 reply, int timeout_base_ms); @@ -196,6 +196,7 @@ struct intel_display_rpm_interface { void (*put_unchecked)(const struct drm_device *drm); bool (*suspended)(const struct drm_device *drm); + bool (*pme_enabled)(const struct drm_device *drm); /* Optional */ void (*assert_held)(const struct drm_device *drm); void (*assert_block)(const struct drm_device *drm); void (*assert_unblock)(const struct drm_device *drm); @@ -230,6 +231,10 @@ struct intel_display_vlv_iosf_interface { int (*write)(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr, u32 val); }; +struct intel_display_wa_interface { + bool (*wa_16023588340)(struct drm_device *drm); +}; + /** * struct intel_display_parent_interface - services parent driver provides to display * @@ -291,6 +296,12 @@ struct intel_display_parent_interface { /** @vlv_iosf: VLV IOSF sideband. Optional. */ const struct intel_display_vlv_iosf_interface *vlv_iosf; + /** + * @wa: Display workarounds query. Use only for workarounds that require + * information only available to the parent driver. Optional. + */ + const struct intel_display_wa_interface *wa; + /* Generic independent functions */ struct { /** @fence_priority_display: Set display priority. Optional. */ @@ -302,6 +313,9 @@ struct intel_display_parent_interface { /** @has_fenced_regions: Support legacy fencing? Optional. */ bool (*has_fenced_regions)(struct drm_device *drm); + /** @transient_data_flush: Transient data flush. Optional. */ + void (*transient_data_flush)(struct drm_device *drm); + /** @vgpu_active: Is vGPU active? Optional. */ bool (*vgpu_active)(struct drm_device *drm); }; diff --git a/include/drm/intel/gtt_view_types.h b/include/drm/intel/gtt_view_types.h new file mode 100644 index 000000000000..128392d98f3a --- /dev/null +++ b/include/drm/intel/gtt_view_types.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __DRM_INTEL_GTT_VIEW_TYPES_H__ +#define __DRM_INTEL_GTT_VIEW_TYPES_H__ + +#include <linux/types.h> + +struct intel_remapped_plane_info { + /* in gtt pages */ + u32 offset:31; + u32 linear:1; + union { + /* in gtt pages for !linear */ + struct { + u16 width; + u16 height; + u16 src_stride; + u16 dst_stride; + }; + + /* in gtt pages for linear */ + u32 size; + }; +} __packed; + +struct intel_rotation_info { + struct intel_remapped_plane_info plane[2]; +} __packed; + +struct intel_partial_info { + u64 offset; + unsigned int size; +} __packed; + +struct intel_remapped_info { + struct intel_remapped_plane_info plane[4]; + /* in gtt pages */ + u32 plane_alignment; +} __packed; + +enum intel_gtt_view_type { + INTEL_GTT_VIEW_NORMAL = 0, + INTEL_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info), + INTEL_GTT_VIEW_PARTIAL = sizeof(struct intel_partial_info), + INTEL_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info), +}; + +struct intel_gtt_view { + enum intel_gtt_view_type type; + union { + /* Members need to contain no holes/padding */ + struct intel_partial_info partial; + struct intel_rotation_info rotated; + struct intel_remapped_info remapped; + }; +}; + +static inline bool intel_gtt_view_is_normal(const struct intel_gtt_view *view) +{ + return view->type == INTEL_GTT_VIEW_NORMAL; +} + +static inline bool intel_gtt_view_is_remapped(const struct intel_gtt_view *view) +{ + return view->type == INTEL_GTT_VIEW_REMAPPED; +} + +static inline bool intel_gtt_view_is_rotated(const struct intel_gtt_view *view) +{ + return view->type == INTEL_GTT_VIEW_ROTATED; +} + +static inline bool intel_gtt_view_is_partial(const struct intel_gtt_view *view) +{ + return view->type == INTEL_GTT_VIEW_PARTIAL; +} + +#endif /* __DRM_INTEL_GTT_VIEW_TYPES_H__ */ diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index dff389b56eb3..32c88a690ad8 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -880,6 +880,7 @@ MACRO__(0xB08F, ## __VA_ARGS__), \ MACRO__(0xB090, ## __VA_ARGS__), \ MACRO__(0xB0A0, ## __VA_ARGS__), \ + MACRO__(0xB0A1, ## __VA_ARGS__), \ MACRO__(0xB0B0, ## __VA_ARGS__) /* WCL */ diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index 3f2812743a7e..714c533622c2 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -35,7 +35,7 @@ #include <drm/ttm/ttm_kmap_iter.h> #define TTM_MAX_BO_PRIORITY 4U -#define TTM_NUM_MEM_TYPES 9 +#define TTM_NUM_MEM_TYPES 10 struct dentry; struct dmem_cgroup_device; diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index ffa99b930843..dd07d128adc3 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -507,7 +507,7 @@ dma_fence_test_signaled_flag(struct dma_fence *fence) * Returns true if the fence was already signaled, false if not. Since this * function doesn't enable signaling, it is not guaranteed to ever return * true if dma_fence_add_callback(), dma_fence_wait() or - * dma_fence_enable_sw_signaling() haven't been called before. + * dma_fence_enable_signaling() haven't been called before. * * This function requires &dma_fence.lock to be held. * diff --git a/include/linux/gpu_buddy.h b/include/linux/gpu_buddy.h index 2c36124bb696..ddc4eca84175 100644 --- a/include/linux/gpu_buddy.h +++ b/include/linux/gpu_buddy.h @@ -43,8 +43,8 @@ /** * GPU_BUDDY_CLEAR_ALLOCATION - Prefer pre-cleared (zeroed) memory * - * Attempt to allocate from the clear tree first. If insufficient clear - * memory is available, falls back to dirty memory. Useful when the + * Attempt to allocate outside dirty-tracked ranges first. If insufficient + * clear memory is available, falls back to dirty memory. Useful when the * caller needs zeroed memory and wants to avoid GPU clear operations. */ #define GPU_BUDDY_CLEAR_ALLOCATION BIT(3) @@ -53,8 +53,8 @@ * GPU_BUDDY_CLEARED - Mark returned blocks as cleared * * Used with gpu_buddy_free_list() to indicate that the memory being - * freed has been cleared (zeroed). The blocks will be placed in the - * clear tree for future GPU_BUDDY_CLEAR_ALLOCATION requests. + * freed has been cleared (zeroed). The blocks will be removed from the + * dirty tracker for future GPU_BUDDY_CLEAR_ALLOCATION requests. */ #define GPU_BUDDY_CLEARED BIT(4) @@ -67,15 +67,17 @@ */ #define GPU_BUDDY_TRIM_DISABLE BIT(5) -enum gpu_buddy_free_tree { - GPU_BUDDY_CLEAR_TREE = 0, - GPU_BUDDY_DIRTY_TREE, - GPU_BUDDY_MAX_FREE_TREES, +/* + * Clear/dirty state of a free block. Ordered so a numerically larger value + * is "more clear" (DIRTY < MIXED < CLEAR) which lets subtree_block_state be + * maintained as a simple max-augment over the per-order free tree. + */ +enum gpu_block_state { + GPU_BLOCK_DIRTY = 0, + GPU_BLOCK_MIXED = 1, + GPU_BLOCK_CLEAR = 2, }; -#define for_each_free_tree(tree) \ - for ((tree) = 0; (tree) < GPU_BUDDY_MAX_FREE_TREES; (tree)++) - /** * struct gpu_buddy_block - Block within a buddy allocator * @@ -103,6 +105,13 @@ struct gpu_buddy_block { #define GPU_BUDDY_ALLOCATED (1 << 10) #define GPU_BUDDY_FREE (2 << 10) #define GPU_BUDDY_SPLIT (3 << 10) +/* + * GPU_BUDDY_HEADER_CLEAR has two roles: + * - FREE state: set when the block's full range is cleared (dirty + * tracker confirmed no overlap). + * - ALLOCATED state: set when the block was served from cleared memory, + * informing the caller that no GPU clear pass is needed. + */ #define GPU_BUDDY_HEADER_CLEAR GENMASK_ULL(9, 9) /* Free to be used, if needed in the future */ #define GPU_BUDDY_HEADER_UNUSED GENMASK_ULL(8, 6) @@ -128,14 +137,45 @@ struct gpu_buddy_block { struct list_head link; }; /* private: */ - struct list_head tmp_link; + enum gpu_block_state subtree_block_state; unsigned int subtree_max_alignment; + struct list_head tmp_link; + bool has_clear; }; /* Order-zero must be at least SZ_4K */ #define GPU_BUDDY_MAX_ORDER (63 - 12) /** + * struct gpu_dirty_extent - a contiguous dirty address range + * + * Tracks a single contiguous address range whose memory content is known + * to be dirty. Extents are non-overlapping and stored in an augmented + * red-black tree sorted by @start. The augmented value @subtree_max_size + * allows O(log N) search for an extent of at least a given size. + */ +struct gpu_dirty_extent { +/* private: */ + struct rb_node rb; + u64 start; + u64 end; + u64 subtree_max_size; +}; + +/** + * struct gpu_dirty_tracker - tracks dirty address intervals + * + * Maintains a set of non-overlapping dirty extents as an augmented + * red-black tree. + */ +struct gpu_dirty_tracker { +/* private: */ + struct rb_root root; + /* Total bytes of dirty memory currently tracked. */ + u64 total_dirty; +}; + +/** * struct gpu_buddy - GPU binary buddy allocator * * The buddy allocator provides efficient power-of-two memory allocation @@ -152,20 +192,21 @@ struct gpu_buddy_block { * @chunk_size: Minimum allocation granularity in bytes. Must be at least SZ_4K. * @size: Total size of the address space managed by this allocator in bytes. * @avail: Total free space currently available for allocation in bytes. - * @clear_avail: Free space available in the clear tree (zeroed memory) in bytes. - * This is a subset of @avail. * @lock_dep_map: Annotates gpu_buddy API with a driver provided lock. */ struct gpu_buddy { /* private: */ + /* Tracker of dirty address ranges (decoupled from free_tree). */ + struct gpu_dirty_tracker dirty; /* - * Array of red-black trees for free block management. - * Indexed as free_trees[clear/dirty][order] where: - * - Index 0 (GPU_BUDDY_CLEAR_TREE): blocks with zeroed content - * - Index 1 (GPU_BUDDY_DIRTY_TREE): blocks with unknown content - * Each tree holds free blocks of the corresponding order. + * One RB-tree per order containing all free blocks (clear and + * dirty alike). The augment field subtree_block_state (a max over + * the subtree of each block's state) lets clear allocations + * find the right-most fully-clear or mixed block in O(log N). + * Dirty free blocks coexist here but are also indexed by the + * @dirty tracker for fast dirty allocation lookups. */ - struct rb_root **free_trees; + struct rb_root *free_tree; /* * Array of root blocks representing the top-level blocks of the * binary tree(s). Multiple roots exist when the total size is not @@ -194,7 +235,6 @@ struct gpu_buddy { u64 chunk_size; u64 size; u64 avail; - u64 clear_avail; #ifdef CONFIG_LOCKDEP struct lockdep_map *lock_dep_map; #endif @@ -226,17 +266,32 @@ struct gpu_buddy { * * Ensure driver lock is held. */ -static inline void gpu_buddy_driver_lock_held(struct gpu_buddy *mm) +static inline void gpu_buddy_driver_lock_held(const struct gpu_buddy *mm) { if (mm->lock_dep_map) lockdep_assert(lock_is_held_type(mm->lock_dep_map, 0)); } #else -static inline void gpu_buddy_driver_lock_held(struct gpu_buddy *mm) +static inline void gpu_buddy_driver_lock_held(const struct gpu_buddy *mm) { } #endif +/** + * gpu_buddy_clear_avail - free space that is clear (zeroed), in bytes + * @mm: gpu buddy allocator + * + * A subset of @mm->avail. Derived on demand as @mm->avail minus the bytes + * the dirty tracker records as dirty, so it is always consistent with the + * tracker without a cached field to keep in sync. Zero for a fresh pool, + * which is fully dirty. + */ +static inline u64 gpu_buddy_clear_avail(const struct gpu_buddy *mm) +{ + gpu_buddy_driver_lock_held(mm); + return mm->avail - mm->dirty.total_dirty; +} + static inline u64 gpu_buddy_block_offset(const struct gpu_buddy_block *block) { diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 8dab78e1f61b..b80a5ee63bb2 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -27,6 +27,18 @@ #include <linux/types.h> #include <linux/device.h> +enum hdmi_version { + HDMI_VERSION_UNKNOWN, + HDMI_VERSION_1_0, + HDMI_VERSION_1_1, + HDMI_VERSION_1_2, + HDMI_VERSION_1_3, + HDMI_VERSION_1_4, + HDMI_VERSION_2_0, + HDMI_VERSION_2_1, + HDMI_VERSION_2_2, +}; + enum hdmi_packet_type { HDMI_PACKET_TYPE_NULL = 0x00, HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN = 0x01, diff --git a/include/linux/host1x.h b/include/linux/host1x.h index a7a675783136..e7ba601b2afb 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -237,6 +237,8 @@ void host1x_syncpt_release_vblank_reservation(struct host1x_client *client, struct dma_fence *host1x_fence_create(struct host1x_syncpt *sp, u32 threshold, bool timeout); void host1x_fence_cancel(struct dma_fence *fence); +int host1x_fence_extract(struct dma_fence *fence, struct host1x **host1x, + u32 *id, u32 *threshold); /* * host1x channel @@ -465,13 +467,26 @@ int host1x_client_resume(struct host1x_client *client); struct host1x_memory_context { struct host1x *host; + struct device *dev; /* Owning engine */ + struct pid *pid; + refcount_t ref; - struct pid *owner; + bool static_alloc; - struct device_dma_parameters dma_parms; - struct device dev; - u64 dma_mask; - u32 stream_id; + struct host1x_hw_memory_context *hw; + struct list_head entry; /* Entry in hw_memory_context's list */ + struct list_head mappings; /* List of mappings */ +}; + +struct host1x_context_mapping { + struct host1x *host; + + struct host1x_bo_mapping *mapping; + + struct host1x_bo *bo; + enum dma_data_direction direction; + + struct list_head entry; }; #ifdef CONFIG_IOMMU_API @@ -480,6 +495,12 @@ struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x, struct pid *pid); void host1x_memory_context_get(struct host1x_memory_context *cd); void host1x_memory_context_put(struct host1x_memory_context *cd); +int host1x_memory_context_active(struct host1x_memory_context *cd); +void host1x_memory_context_inactive(struct host1x_memory_context *cd); +struct host1x_context_mapping *host1x_memory_context_map(struct host1x_memory_context *ctx, + struct host1x_bo *bo, + enum dma_data_direction direction); +void host1x_memory_context_unmap(struct host1x_context_mapping *m); #else static inline struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x, struct device *dev, @@ -495,6 +516,26 @@ static inline void host1x_memory_context_get(struct host1x_memory_context *cd) static inline void host1x_memory_context_put(struct host1x_memory_context *cd) { } + +static inline int host1x_memory_context_active(struct host1x_memory_context *cd) +{ + return -ENODEV; +} + +static inline void host1x_memory_context_inactive(struct host1x_memory_context *cd) +{ +} + +static inline struct host1x_context_mapping * +host1x_memory_context_map(struct host1x_memory_context *ctx, struct host1x_bo *bo, + enum dma_data_direction direction) +{ + return ERR_PTR(-ENODEV); +} + +static inline void host1x_memory_context_unmap(struct host1x_context_mapping *m) +{ +} #endif #endif diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index 7e6ac0114d55..d7eee65664ab 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -31,8 +31,12 @@ #ifndef _LINUX_VGA_SWITCHEROO_H_ #define _LINUX_VGA_SWITCHEROO_H_ -#include <linux/fb.h> +#include <linux/errno.h> +#include <linux/types.h> +struct device; +struct dev_pm_domain; +struct fb_info; struct pci_dev; /** @@ -127,23 +131,28 @@ struct vga_switcheroo_handler { * @set_gpu_state: do the equivalent of suspend/resume for the card. * Mandatory. This should not cut power to the discrete GPU, * which is the job of the handler - * @reprobe: poll outputs. - * Optional. This gets called after waking the GPU and switching - * the outputs to it * @can_switch: check if the device is in a position to switch now. * Mandatory. The client should return false if a user space process * has one of its device files open + * @pre_switch: prepare switch + * Optional. This gets called before switching the outputs to the + * GPU. Allows drivers to prepare for the switch. + * @post_switch: completes switch + * Optional. This gets called after waking the GPU and switching + * the outputs to it. Allows drivers to poll the switched outputs. * @gpu_bound: notify the client id to audio client when the GPU is bound. * * Client callbacks. A client can be either a GPU or an audio device on a GPU. - * The @set_gpu_state and @can_switch methods are mandatory, @reprobe may be - * set to NULL. For audio clients, the @reprobe member is bogus. - * OTOH, @gpu_bound is only for audio clients, and not used for GPU clients. + * The @set_gpu_state and @can_switch methods are mandatory, @pre_switch and + * @post_switch may be set to NULL. For audio clients, the @pre_switch and + * @post_switch members are bogus. OTOH, @gpu_bound is only for audio clients, + * and not used for GPU clients. */ struct vga_switcheroo_client_ops { void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state); - void (*reprobe)(struct pci_dev *dev); bool (*can_switch)(struct pci_dev *dev); + void (*pre_switch)(struct pci_dev *dev); + void (*post_switch)(struct pci_dev *dev); void (*gpu_bound)(struct pci_dev *dev, enum vga_switcheroo_client_id); }; @@ -156,9 +165,6 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev, const struct vga_switcheroo_client_ops *ops, struct pci_dev *vga_dev); -void vga_switcheroo_client_fb_set(struct pci_dev *dev, - struct fb_info *info); - int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler, enum vga_switcheroo_handler_flags_t handler_flags); void vga_switcheroo_unregister_handler(void); @@ -178,7 +184,6 @@ void vga_switcheroo_fini_domain_pm_ops(struct device *dev); static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} static inline int vga_switcheroo_register_client(struct pci_dev *dev, const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; } -static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {} static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler, enum vga_switcheroo_handler_flags_t handler_flags) { return 0; } static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h index e5f82044a404..8dca92360ee0 100644 --- a/include/sound/omap-hdmi-audio.h +++ b/include/sound/omap-hdmi-audio.h @@ -34,6 +34,7 @@ struct omap_hdmi_audio_pdata { phys_addr_t audio_dma_addr; const struct omap_hdmi_audio_ops *ops; + void (*audio_hpd)(struct device *dev, bool connected); }; #endif /* __OMAP_HDMI_AUDIO_H__ */ diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 42a5fa8ad6b0..29009f6aabde 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -59,6 +59,7 @@ extern "C" { #define DRM_AMDGPU_USERQ_WAIT 0x18 #define DRM_AMDGPU_GEM_LIST_HANDLES 0x19 #define DRM_AMDGPU_PROC_OPTIONS 0x1A +#define DRM_AMDGPU_UALINK_HANDLE 0x1B #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) #define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap) @@ -81,6 +82,7 @@ extern "C" { #define DRM_IOCTL_AMDGPU_USERQ_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_WAIT, struct drm_amdgpu_userq_wait) #define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles) #define DRM_IOCTL_AMDGPU_PROC_OPTIONS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_PROC_OPTIONS, struct drm_amdgpu_proc_options) +#define DRM_IOCTL_AMDGPU_UALINK_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_UALINK_HANDLE, union drm_amdgpu_ualink_handle) /** * DOC: memory domains @@ -115,6 +117,12 @@ extern "C" { #define AMDGPU_GEM_DOMAIN_GWS 0x10 #define AMDGPU_GEM_DOMAIN_OA 0x20 #define AMDGPU_GEM_DOMAIN_DOORBELL 0x40 +#define AMDGPU_GEM_DOMAIN_MMIO_REMAP 0x80 +#define AMDGPU_GEM_DOMAIN_NPA 0x100 + +/* User-mode is not allowed to allocate NPA space. As a result, + * we don't add AMDGPU_GEM_DOMAIN_NPA in the DOMAIN_MASK below. + */ #define AMDGPU_GEM_DOMAIN_MASK (AMDGPU_GEM_DOMAIN_CPU | \ AMDGPU_GEM_DOMAIN_GTT | \ AMDGPU_GEM_DOMAIN_VRAM | \ @@ -504,6 +512,11 @@ struct drm_amdgpu_userq_signal { * @bo_write_handles. */ __u32 num_bo_write_handles; + /** + * @syncobj_points: The list of syncobj points submitted by the user queue job + * for the corresponding @syncobj_handles. + */ + __u64 syncobj_points; }; struct drm_amdgpu_userq_fence_info { @@ -1170,6 +1183,8 @@ struct drm_amdgpu_cs_chunk_cp_gfx_shadow { #define AMDGPU_INFO_FW_IMU 0x1b /* Subquery id: Query VPE firmware version */ #define AMDGPU_INFO_FW_VPE 0x1c + /* Subquery id: Query MP5 firmware version */ + #define AMDGPU_INFO_FW_MP5 0x1d /* number of bytes moved for TTM migration */ #define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f @@ -1694,6 +1709,34 @@ struct drm_amdgpu_proc_options { } kfd_sigbus_delay; }; +#define DRM_AMDGPU_UALINK_HANDLE_OP_EXPORT 0 +#define DRM_AMDGPU_UALINK_HANDLE_OP_IMPORT 1 + +struct drm_amdgpu_ualink_handle_in { + /* Export or import */ + __u32 op; + /* For future use, no flags defined so far */ + __u32 flags; + union { + /* GEM handle of the BO to export */ + __u32 gem_handle; + /* UALink handle to import */ + __u64 import_ualink_handle[2]; + }; +}; + +union drm_amdgpu_ualink_handle_out { + /* Exported UALink handle */ + __u64 export_ualink_handle[2]; + /** DMABuf representing the imported UALink handle */ + __u32 import_dmabuf_handle; +}; + +union drm_amdgpu_ualink_handle { + struct drm_amdgpu_ualink_handle_in in; + union drm_amdgpu_ualink_handle_out out; +}; + #if defined(__cplusplus) } #endif diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index a103fdc0b3a3..0bb049f91524 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1627,6 +1627,30 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define DRM_FORMAT_MOD_APPLE_GPU_TILED_COMPRESSED fourcc_mod_code(APPLE, 2) /* + * Apple Interchange layout + * + * Apple Interchange is a compressed framebuffer format used exclusively for + * sharing buffers between hardware blocks (GPU, display controller, video + * codecs) on Apple platforms. It is similar to and uses the same compression + * scheme as GPU_TILED_COMPRESSED. There is no known uncompressed variant + * of Apple Interchange. + * + * Unlike the GPU layouts, tile size is not dependent on bit depth. RGB + * images and the chroma components of YUV images use 16x16 tiles. The + * luma component of YUV images uses 32x32 tiles. Compression tiles + * are once again 16x16 with 8 bytes of metadata per compression subtile. + * + * Following the example set by GPU_TILED_{,COMPRESSED}, Interchange images + * are treated as a single plane by software and do not have a meaningful + * stride. + * + * AGX has limited support for Apple Interchange. It cannot be used for Z/S + * buffers or array images, for example. It is intended for scanout buffer + * sharing only. + */ +#define DRM_FORMAT_MOD_APPLE_INTERCHANGE fourcc_mod_code(APPLE, 3) + +/* * AMD modifiers * * Memory layout: diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index bd435effdcee..ed1a660a3dfd 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -955,6 +955,18 @@ enum drm_colorop_type { * color = lut3d[index] */ DRM_COLOROP_3D_LUT, + + /** + * @DRM_COLOROP_FIXED_MATRIX: + * + * enum string "Fixed Matrix" + * + * A Colorop block that performs a pre-defined matrix operation selected + * via the FIXED_MATRIX_TYPE enum property. The driver advertises the supported + * operations through this property. + */ + DRM_COLOROP_FIXED_MATRIX, + }; /** diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h index 218a3ee86805..2f832275ee6e 100644 --- a/include/uapi/drm/drm_ras.h +++ b/include/uapi/drm/drm_ras.h @@ -33,18 +33,36 @@ enum { DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID, DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_NAME, DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_VALUE, + DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_THRESHOLD, __DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX, DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1) }; enum { + DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1, + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, + + __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, + DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1) +}; + +enum { DRM_RAS_CMD_LIST_NODES = 1, DRM_RAS_CMD_GET_ERROR_COUNTER, DRM_RAS_CMD_CLEAR_ERROR_COUNTER, + DRM_RAS_CMD_ERROR_EVENT, + DRM_RAS_CMD_GET_ERROR_THRESHOLD, + DRM_RAS_CMD_SET_ERROR_THRESHOLD, __DRM_RAS_CMD_MAX, DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1) }; +#define DRM_RAS_MCGRP_ERROR_REPORT "error-report" + #endif /* _UAPI_LINUX_DRM_RAS_H */ diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 264505d54f93..9ce19d9c3131 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * Copyright (C) 2020-2025 Intel Corporation + * Copyright (C) 2020-2026 Intel Corporation */ #ifndef __UAPI_IVPU_DRM_H__ @@ -96,6 +96,7 @@ extern "C" { #define DRM_IVPU_PARAM_SKU 12 #define DRM_IVPU_PARAM_CAPABILITIES 13 #define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14 +#define DRM_IVPU_PARAM_CMDQ_PRIORITY 15 #define DRM_IVPU_PLATFORM_TYPE_SILICON 0 @@ -141,6 +142,15 @@ extern "C" { #define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4 /** + * DRM_IVPU_CAP_CMDQ_SET_PRIORITY + * + * Driver supports DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to get/set command + * queue priority. + * This allows changing command queue priority after creation. + */ +#define DRM_IVPU_CAP_CMDQ_SET_PRIORITY 5 + +/** * struct drm_ivpu_param - Get/Set VPU parameters */ struct drm_ivpu_param { @@ -192,6 +202,11 @@ struct drm_ivpu_param { * * %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE: * Size of the preemption buffer (read-only) + * + * %DRM_IVPU_PARAM_CMDQ_PRIORITY: + * Get/Set command queue priority (see DRM_IVPU_JOB_PRIORITY_*). + * DRM_IVPU_JOB_PRIORITY_DEFAULT is treated as DRM_IVPU_JOB_PRIORITY_NORMAL. + * Command queue ID is given via drm_ivpu_param.index. */ __u32 param; diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h index 3ca90ed9d2bb..d7017ed17143 100644 --- a/include/uapi/drm/nova_drm.h +++ b/include/uapi/drm/nova_drm.h @@ -18,26 +18,56 @@ extern "C" { #endif -/* - * NOVA_GETPARAM_VRAM_BAR_SIZE - * - * Query the VRAM BAR size in bytes. +/** + * enum drm_nova_architecture - GPU architecture identifier */ -#define NOVA_GETPARAM_VRAM_BAR_SIZE 0x1 +enum drm_nova_architecture { + NOVA_DRM_ARCHITECTURE_TURING = 0x16, + NOVA_DRM_ARCHITECTURE_AMPERE = 0x17, + NOVA_DRM_ARCHITECTURE_HOPPER = 0x18, + NOVA_DRM_ARCHITECTURE_ADA = 0x19, + NOVA_DRM_ARCHITECTURE_BLACKWELL_GB10X = 0x1a, + NOVA_DRM_ARCHITECTURE_BLACKWELL_GB20X = 0x1b, +}; /** - * struct drm_nova_getparam - query GPU and driver metadata + * enum drm_nova_chipid - opaque GPU chip identifier + * + * These values identify the chip a GPU is based on. They are otherwise + * opaque: userspace must not assume the values carry any particular meaning + * or encoding, only that they may be compared against this enum. */ -struct drm_nova_getparam { - /** - * @param: The identifier of the parameter to query. - */ - __u64 param; - - /** - * @value: The value for the specified parameter. - */ - __u64 value; +enum drm_nova_chipid { + /* Turing */ + NOVA_DRM_CHIPID_TU102 = 0x162, + NOVA_DRM_CHIPID_TU104 = 0x164, + NOVA_DRM_CHIPID_TU106 = 0x166, + NOVA_DRM_CHIPID_TU117 = 0x167, + NOVA_DRM_CHIPID_TU116 = 0x168, + /* Ampere */ + NOVA_DRM_CHIPID_GA100 = 0x170, + NOVA_DRM_CHIPID_GA102 = 0x172, + NOVA_DRM_CHIPID_GA103 = 0x173, + NOVA_DRM_CHIPID_GA104 = 0x174, + NOVA_DRM_CHIPID_GA106 = 0x176, + NOVA_DRM_CHIPID_GA107 = 0x177, + /* Hopper */ + NOVA_DRM_CHIPID_GH100 = 0x180, + /* Ada */ + NOVA_DRM_CHIPID_AD102 = 0x192, + NOVA_DRM_CHIPID_AD103 = 0x193, + NOVA_DRM_CHIPID_AD104 = 0x194, + NOVA_DRM_CHIPID_AD106 = 0x196, + NOVA_DRM_CHIPID_AD107 = 0x197, + /* Blackwell GB10x */ + NOVA_DRM_CHIPID_GB100 = 0x1a0, + NOVA_DRM_CHIPID_GB102 = 0x1a2, + /* Blackwell GB20x */ + NOVA_DRM_CHIPID_GB202 = 0x1b2, + NOVA_DRM_CHIPID_GB203 = 0x1b3, + NOVA_DRM_CHIPID_GB205 = 0x1b5, + NOVA_DRM_CHIPID_GB206 = 0x1b6, + NOVA_DRM_CHIPID_GB207 = 0x1b7, }; /** @@ -80,14 +110,92 @@ struct drm_nova_gem_info { __u64 size; }; -#define DRM_NOVA_GETPARAM 0x00 +/** + * struct drm_nova_info - query device information + */ +struct drm_nova_info { + /** + * @id: The identifier of the information to query. + */ + __u32 id; + + /** + * @size: The amount of space allocated by userspace at @data. The kernel + * will return the number of bytes it wrote, or the size of the queried + * information structure if @data is NULL. + */ + __u32 size; + + /** + * @data: Pointer to the userspace buffer into which the queried + * information will be written. May be NULL, in which case nothing is + * written and @size is set to the size of the information structure so + * userspace can allocate a suitably sized buffer. + */ + __u64 data; +}; + +/** + * DRM_NOVA_INFO_GPU + * + * Query GPU information. The result is returned in a + * &struct drm_nova_info_gpu. + */ +#define DRM_NOVA_INFO_GPU 0x00 + +/** + * struct drm_nova_info_gpu - GPU information + */ +struct drm_nova_info_gpu { + /** + * @architecture: GPU architecture identifier. + * + * See &enum drm_nova_architecture for currently known architectures. + */ + __u32 architecture; + + /** + * @chipid: Opaque GPU chip identifier. + * + * See &enum drm_nova_chipid for currently known chips. + */ + __u32 chipid; + + /** + * @vram_size: Amount of usable FB, excluding GSP carveouts and protected + * regions. + */ + __u64 vram_size; + + /** + * @vram_bar_size: Size of the PCI BAR aperture used to access VRAM, in bytes. + */ + __u64 vram_bar_size; + + /** + * @gpu_name: NUL-terminated full GPU name. + */ + __u8 gpu_name[64]; + + /** + * @gpu_short_name: NUL-terminated short GPU name. + */ + __u8 gpu_short_name[64]; + + /** + * @gpu_gid: 16-byte SHA-1 GPU identifier supplied by GSP-RM. + */ + __u8 gpu_gid[16]; +}; + +#define DRM_NOVA_INFO 0x00 #define DRM_NOVA_GEM_CREATE 0x01 #define DRM_NOVA_GEM_INFO 0x02 /* Note: this is an enum so that it can be resolved by Rust bindgen. */ enum { - DRM_IOCTL_NOVA_GETPARAM = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GETPARAM, - struct drm_nova_getparam), + DRM_IOCTL_NOVA_INFO = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_INFO, + struct drm_nova_info), DRM_IOCTL_NOVA_GEM_CREATE = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GEM_CREATE, struct drm_nova_gem_create), DRM_IOCTL_NOVA_GEM_INFO = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GEM_INFO, diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index 50d5337f35ef..7831c48c59c0 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -47,7 +47,7 @@ extern "C" { * them for anything but debugging purpose. */ #define DRM_IOCTL_PANFROST_PERFCNT_ENABLE DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_ENABLE, struct drm_panfrost_perfcnt_enable) -#define DRM_IOCTL_PANFROST_PERFCNT_DUMP DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_DUMP, struct drm_panfrost_perfcnt_dump) +#define DRM_IOCTL_PANFROST_PERFCNT_DUMP DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_DUMP, struct drm_panfrost_perfcnt_dump) #define PANFROST_JD_REQ_FS (1 << 0) #define PANFROST_JD_REQ_CYCLE_COUNT (1 << 1) @@ -270,8 +270,35 @@ struct drm_panfrost_perfcnt_enable { __u32 counterset; }; +/* + * The next two flags describe the state of a perfcnt dump request + * as influenced by a device reset. They are the only values the + * perfcnt_dump ioctl state field can take on. + * Only certain state and ioctl retval combinations are legitimate. + */ + +/* A new perfcnt_enable ioctl should be issued before requesting + * more dumps, because a HW reset failed to recreate perfcnt's + * original state. Otherwise further perfcnt_dump's will fail. + * This flag being set means ioctl's retval is always -EIO. + */ +#define PANFROST_PERFCNT_SESSION_DEAD (1 << 0) + +/* A HW reset happened before or during a sample request, and + * perfcnt's internal state was successfully restored. There + * are two possible outcomes depending on the ioctl's retval: + * 0: A reset happened before a dump was requested, but did + * nonetheless succeed. Counter values are relative to last reset. + * -EAGAIN: A reset happened when a counter values sampling + * request was ongoing. Values are undefined so a new dump ioctl + * should be issued. + */ +#define PANFROST_PERFCNT_SESSION_INTERRUPTED_BY_RESET (1 << 1) + struct drm_panfrost_perfcnt_dump { __u64 buf_ptr; + __u32 state; + __u32 pad; /* MBZ */ }; /* madvise provides a way to tell the kernel in case a buffers contents diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h index 8f21f3a44832..b17472103e91 100644 --- a/include/uapi/drm/tegra_drm.h +++ b/include/uapi/drm/tegra_drm.h @@ -986,8 +986,8 @@ struct drm_tegra_channel_submit { /** * @syncobj_in: [in] * - * Handle for DRM syncobj that will be waited before submission. - * Ignored if zero. + * Handle for DRM syncobj that will be waited for before the job + * executes. Ignored if zero. */ __u32 syncobj_in; diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 509202a7b13e..578f0c1eb43e 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1294,8 +1294,8 @@ struct xe_vm_fault { #define FAULT_LEVEL_PML4 3 #define FAULT_LEVEL_PML5 4 __u8 fault_level; - /** @pad: MBZ */ - __u8 pad; + /** @srcid: ID of the faulting hardware unit */ + __u8 srcid; /** @reserved: MBZ */ __u64 reserved[4]; }; @@ -1491,6 +1491,12 @@ struct drm_xe_exec_queue_destroy { * * The @property can be: * - %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN + * + * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, @value is a bitmask of ban reasons: + * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout + * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline + * + * A @value of 0 means the exec queue is not banned. */ struct drm_xe_exec_queue_get_property { /** @extensions: Pointer to the first extension struct, if any */ @@ -1503,7 +1509,17 @@ struct drm_xe_exec_queue_get_property { /** @property: property to get */ __u32 property; - /** @value: property value */ + /** + * @value: property value + * + * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, this is a bitmask of: + * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout + * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline + * + * Value of 0 means the exec queue is not banned. + */ +#define DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG (1 << 0) +#define DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE (1 << 1) __u64 value; /** @reserved: Reserved */ |
