diff options
| author | Linus Torvalds <[email protected]> | 2025-07-31 02:26:49 +0000 |
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2025-07-31 02:26:49 +0000 |
| commit | 260f6f4fda93c8485c8037865c941b42b9cba5d2 (patch) | |
| tree | 587a0ea46d3351f63250d19860b01da8217ac774 /drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | |
| parent | Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm (diff) | |
| parent | Merge tag 'drm-misc-next-fixes-2025-07-24' of https://gitlab.freedesktop.org/... (diff) | |
| download | kernel-260f6f4fda93c8485c8037865c941b42b9cba5d2.tar.gz kernel-260f6f4fda93c8485c8037865c941b42b9cba5d2.zip | |
Merge tag 'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel
Pull drm updates from Dave Airlie:
"Highlights:
- Intel xe enable Panthor Lake, started adding WildCat Lake
- amdgpu has a bunch of reset improvments along with the usual IP
updates
- msm got VM_BIND support which is important for vulkan sparse memory
- more drm_panic users
- gpusvm common code to handle a bunch of core SVM work outside
drivers.
Detail summary:
Changes outside drm subdirectory:
- 'shrink_shmem_memory()' for better shmem/hibernate interaction
- Rust support infrastructure:
- make ETIMEDOUT available
- add size constants up to SZ_2G
- add DMA coherent allocation bindings
- mtd driver for Intel GPU non-volatile storage
- i2c designware quirk for Intel xe
core:
- atomic helpers: tune enable/disable sequences
- add task info to wedge API
- refactor EDID quirks
- connector: move HDR sink to drm_display_info
- fourcc: half-float and 32-bit float formats
- mode_config: pass format info to simplify
dma-buf:
- heaps: Give CMA heap a stable name
ci:
- add device tree validation and kunit
displayport:
- change AUX DPCD access probe address
- add quirk for DPCD probe
- add panel replay definitions
- backlight control helpers
fbdev:
- make CONFIG_FIRMWARE_EDID available on all arches
fence:
- fix UAF issues
format-helper:
- improve tests
gpusvm:
- introduce devmem only flag for allocation
- add timeslicing support to GPU SVM
ttm:
- improve eviction
sched:
- tracing improvements
- kunit improvements
- memory leak fixes
- reset handling improvements
color mgmt:
- add hardware gamma LUT handling helpers
bridge:
- add destroy hook
- switch to reference counted drm_bridge allocations
- tc358767: convert to devm_drm_bridge_alloc
- improve CEC handling
panel:
- switch to reference counter drm_panel allocations
- fwnode panel lookup
- Huiling hl055fhv028c support
- Raspberry Pi 7" 720x1280 support
- edp: KDC KD116N3730A05, N160JCE-ELL CMN, N116BCJ-EAK
- simple: AUO P238HAN01
- st7701: Winstar wf40eswaa6mnn0
- visionox: rm69299-shift
- Renesas R61307, Renesas R69328 support
- DJN HX83112B
hdmi:
- add CEC handling
- YUV420 output support
xe:
- WildCat Lake support
- Enable PanthorLake by default
- mark BMG as SRIOV capable
- update firmware recommendations
- Expose media OA units
- aux-bux support for non-volatile memory
- MTD intel-dg driver for non-volatile memory
- Expose fan control and voltage regulator in sysfs
- restructure migration for multi-device
- Restore GuC submit UAF fix
- make GEM shrinker drm managed
- SRIOV VF Post-migration recovery of GGTT nodes
- W/A additions/reworks
- Prefetch support for svm ranges
- Don't allocate managed BO for each policy change
- HWMON fixes for BMG
- Create LRC BO without VM
- PCI ID updates
- make SLPC debugfs files optional
- rework eviction rejection of bound external BOs
- consolidate PAT programming logic for pre/post Xe2
- init changes for flicker-free boot
- Enable GuC Dynamic Inhibit Context switch
i915:
- drm_panic support for i915/xe
- initial flip queue off by default for LNL/PNL
- Wildcat Lake Display support
- Support for DSC fractional link bpp
- Support for simultaneous Panel Replay and Adaptive sync
- Support for PTL+ double buffer LUT
- initial PIPEDMC event handling
- drm_panel_follower support
- DPLL interface renames
- allocate struct intel_display dynamically
- flip queue preperation
- abstract DRAM detection better
- avoid GuC scheduling stalls
- remove DG1 force probe requirement
- fix MEI interrupt handler on RT kernels
- use backlight control helpers for eDP
- more shared display code refactoring
amdgpu:
- add userq slot to INFO ioctl
- SR-IOV hibernation support
- Suspend improvements
- Backlight improvements
- Use scaling for non-native eDP modes
- cleaner shader updates for GC 9.x
- Remove fence slab
- SDMA fw checks for userq support
- RAS updates
- DMCUB updates
- DP tunneling fixes
- Display idle D3 support
- Per queue reset improvements
- initial smartmux support
amdkfd:
- enable KFD on loongarch
- mtype fix for ext coherent system memory
radeon:
- CS validation additional GL extensions
- drop console lock during suspend/resume
- bump driver version
msm:
- VM BIND support
- CI: infrastructure updates
- UBWC single source of truth
- decouple GPU and KMS support
- DP: rework I/O accessors
- DPU: SM8750 support
- DSI: SM8750 support
- GPU: X1-45 support and speedbin support for X1-85
- MDSS: SM8750 support
nova:
- register! macro improvements
- DMA object abstraction
- VBIOS parser + fwsec lookup
- sysmem flush page support
- falcon: generic falcon boot code and HAL
- FWSEC-FRTS: fb setup and load/execute
ivpu:
- Add Wildcat Lake support
- Add turbo flag
ast:
- improve hardware generations implementation
imx:
- IMX8qxq Display Controller support
lima:
- Rockchip RK3528 GPU support
nouveau:
- fence handling cleanup
panfrost:
- MT8370 support
- bo labeling
- 64-bit register access
qaic:
- add RAS support
rockchip:
- convert inno_hdmi to a bridge
rz-du:
- add RZ/V2H(P) support
- MIPI-DSI DCS support
sitronix:
- ST7567 support
sun4i:
- add H616 support
tidss:
- add TI AM62L support
- AM65x OLDI bridge support
bochs:
- drm panic support
vkms:
- YUV and R* format support
- use faux device
vmwgfx:
- fence improvements
hyperv:
- move out of simple
- add drm_panic support"
* tag 'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel: (1479 commits)
drm/tidss: oldi: convert to devm_drm_bridge_alloc() API
drm/tidss: encoder: convert to devm_drm_bridge_alloc()
drm/amdgpu: move reset support type checks into the caller
drm/amdgpu/sdma7: re-emit unprocessed state on ring reset
drm/amdgpu/sdma6: re-emit unprocessed state on ring reset
drm/amdgpu/sdma5.2: re-emit unprocessed state on ring reset
drm/amdgpu/sdma5: re-emit unprocessed state on ring reset
drm/amdgpu/gfx12: re-emit unprocessed state on ring reset
drm/amdgpu/gfx11: re-emit unprocessed state on ring reset
drm/amdgpu/gfx10: re-emit unprocessed state on ring reset
drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset
drm/amdgpu: Add WARN_ON to the resource clear function
drm/amd/pm: Use cached metrics data on SMUv13.0.6
drm/amd/pm: Use cached data for min/max clocks
gpu: nova-core: fix bounds check in PmuLookupTableEntry::new
drm/amdgpu: Replace HQD terminology with slots naming
drm/amdgpu: Add user queue instance count in HW IP info
drm/amd/amdgpu: Add helper functions for isp buffers
drm/amd/amdgpu: Initialize swnode for ISP MFD device
...
Diffstat (limited to 'drivers/gpu/drm/hyperv/hyperv_drm_modeset.c')
| -rw-r--r-- | drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 206 |
1 files changed, 147 insertions, 59 deletions
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c index 6c6b57298797..945b9482bcb3 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c @@ -5,6 +5,8 @@ #include <linux/hyperv.h> +#include <drm/drm_atomic.h> +#include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> @@ -15,7 +17,8 @@ #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_probe_helper.h> -#include <drm/drm_simple_kms_helper.h> +#include <drm/drm_panic.h> +#include <drm/drm_plane.h> #include "hyperv_drm.h" @@ -38,18 +41,6 @@ static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb, return 0; } -static int hyperv_blit_to_vram_fullscreen(struct drm_framebuffer *fb, - const struct iosys_map *map) -{ - struct drm_rect fullscreen = { - .x1 = 0, - .x2 = fb->width, - .y1 = 0, - .y2 = fb->height, - }; - return hyperv_blit_to_vram_rect(fb, map, &fullscreen); -} - static int hyperv_connector_get_modes(struct drm_connector *connector) { struct hyperv_drm_device *hv = to_hv(connector->dev); @@ -98,30 +89,66 @@ static int hyperv_check_size(struct hyperv_drm_device *hv, int w, int h, return 0; } -static void hyperv_pipe_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state, - struct drm_plane_state *plane_state) +static const uint32_t hyperv_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +static const uint64_t hyperv_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +static void hyperv_crtc_helper_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state) { - struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev); - struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct hyperv_drm_device *hv = to_hv(crtc->dev); + struct drm_plane *plane = &hv->plane; + struct drm_plane_state *plane_state = plane->state; + struct drm_crtc_state *crtc_state = crtc->state; hyperv_hide_hw_ptr(hv->hdev); hyperv_update_situation(hv->hdev, 1, hv->screen_depth, crtc_state->mode.hdisplay, crtc_state->mode.vdisplay, plane_state->fb->pitches[0]); - hyperv_blit_to_vram_fullscreen(plane_state->fb, &shadow_plane_state->data[0]); } -static int hyperv_pipe_check(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *plane_state, - struct drm_crtc_state *crtc_state) +static const struct drm_crtc_helper_funcs hyperv_crtc_helper_funcs = { + .atomic_check = drm_crtc_helper_atomic_check, + .atomic_enable = hyperv_crtc_helper_atomic_enable, +}; + +static const struct drm_crtc_funcs hyperv_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +}; + +static int hyperv_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) { - struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct hyperv_drm_device *hv = to_hv(plane->dev); struct drm_framebuffer *fb = plane_state->fb; + struct drm_crtc *crtc = plane_state->crtc; + struct drm_crtc_state *crtc_state = NULL; + int ret; - if (fb->format->format != DRM_FORMAT_XRGB8888) - return -EINVAL; + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); + if (ret) + return ret; + + if (!plane_state->visible) + return 0; if (fb->pitches[0] * fb->height > hv->fb_size) { drm_err(&hv->dev, "fb size requested by %s for %dX%d (pitch %d) greater than %ld\n", @@ -132,53 +159,120 @@ static int hyperv_pipe_check(struct drm_simple_display_pipe *pipe, return 0; } -static void hyperv_pipe_update(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *old_state) +static void hyperv_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) { - struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev); - struct drm_plane_state *state = pipe->plane.state; - struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state); - struct drm_rect rect; + struct hyperv_drm_device *hv = to_hv(plane->dev); + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state); + struct drm_rect damage; + struct drm_rect dst_clip; + struct drm_atomic_helper_damage_iter iter; + + drm_atomic_helper_damage_iter_init(&iter, old_state, new_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + dst_clip = new_state->dst; - if (drm_atomic_helper_damage_merged(old_state, state, &rect)) { - hyperv_blit_to_vram_rect(state->fb, &shadow_plane_state->data[0], &rect); - hyperv_update_dirt(hv->hdev, &rect); + if (!drm_rect_intersect(&dst_clip, &damage)) + continue; + + hyperv_blit_to_vram_rect(new_state->fb, &shadow_plane_state->data[0], &damage); + hyperv_update_dirt(hv->hdev, &damage); } } -static const struct drm_simple_display_pipe_funcs hyperv_pipe_funcs = { - .enable = hyperv_pipe_enable, - .check = hyperv_pipe_check, - .update = hyperv_pipe_update, - DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, +static int hyperv_plane_get_scanout_buffer(struct drm_plane *plane, + struct drm_scanout_buffer *sb) +{ + struct hyperv_drm_device *hv = to_hv(plane->dev); + struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(hv->vram); + + if (plane->state && plane->state->fb) { + sb->format = plane->state->fb->format; + sb->width = plane->state->fb->width; + sb->height = plane->state->fb->height; + sb->pitch[0] = plane->state->fb->pitches[0]; + sb->map[0] = map; + return 0; + } + return -ENODEV; +} + +static void hyperv_plane_panic_flush(struct drm_plane *plane) +{ + struct hyperv_drm_device *hv = to_hv(plane->dev); + struct drm_rect rect; + + if (!plane->state || !plane->state->fb) + return; + + rect.x1 = 0; + rect.y1 = 0; + rect.x2 = plane->state->fb->width; + rect.y2 = plane->state->fb->height; + + hyperv_update_dirt(hv->hdev, &rect); +} + +static const struct drm_plane_helper_funcs hyperv_plane_helper_funcs = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = hyperv_plane_atomic_check, + .atomic_update = hyperv_plane_atomic_update, + .get_scanout_buffer = hyperv_plane_get_scanout_buffer, + .panic_flush = hyperv_plane_panic_flush, }; -static const uint32_t hyperv_formats[] = { - DRM_FORMAT_XRGB8888, +static const struct drm_plane_funcs hyperv_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + DRM_GEM_SHADOW_PLANE_FUNCS, }; -static const uint64_t hyperv_modifiers[] = { - DRM_FORMAT_MOD_LINEAR, - DRM_FORMAT_MOD_INVALID +static const struct drm_encoder_funcs hyperv_drm_simple_encoder_funcs_cleanup = { + .destroy = drm_encoder_cleanup, }; static inline int hyperv_pipe_init(struct hyperv_drm_device *hv) { + struct drm_device *dev = &hv->dev; + struct drm_encoder *encoder = &hv->encoder; + struct drm_plane *plane = &hv->plane; + struct drm_crtc *crtc = &hv->crtc; + struct drm_connector *connector = &hv->connector; int ret; - ret = drm_simple_display_pipe_init(&hv->dev, - &hv->pipe, - &hyperv_pipe_funcs, - hyperv_formats, - ARRAY_SIZE(hyperv_formats), - hyperv_modifiers, - &hv->connector); + ret = drm_universal_plane_init(dev, plane, 0, + &hyperv_plane_funcs, + hyperv_formats, ARRAY_SIZE(hyperv_formats), + hyperv_modifiers, + DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ret; + drm_plane_helper_add(plane, &hyperv_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(plane); - drm_plane_enable_fb_damage_clips(&hv->pipe.plane); + ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, + &hyperv_crtc_funcs, NULL); + if (ret) + return ret; + drm_crtc_helper_add(crtc, &hyperv_crtc_helper_funcs); - return 0; + encoder->possible_crtcs = drm_crtc_mask(crtc); + ret = drm_encoder_init(dev, encoder, + &hyperv_drm_simple_encoder_funcs_cleanup, + DRM_MODE_ENCODER_NONE, NULL); + if (ret) + return ret; + + ret = hyperv_conn_init(hv); + if (ret) { + drm_err(dev, "Failed to initialized connector.\n"); + return ret; + } + + return drm_connector_attach_encoder(connector, encoder); } static enum drm_mode_status @@ -221,12 +315,6 @@ int hyperv_mode_config_init(struct hyperv_drm_device *hv) dev->mode_config.funcs = &hyperv_mode_config_funcs; - ret = hyperv_conn_init(hv); - if (ret) { - drm_err(dev, "Failed to initialized connector.\n"); - return ret; - } - ret = hyperv_pipe_init(hv); if (ret) { drm_err(dev, "Failed to initialized pipe.\n"); |
