[PULL] drm-misc-next
Hi Dave, Sima, One more pull request for v6.10! Cheers, ~Maarten drm-misc-next-2024-04-25: drm-misc-next for v6.10-rc1: UAPI Changes: Cross-subsystem Changes: - Devicetree updates for rockchip (#sound-dai-cells) - Add dt bindings for new panels. - Change bridge/tc358775 dt bindings. Core Changes: - Fix SIZE_HINTS cursor property doc. - Parse topology blocks for all DispID < 2.0. - Implement support for tracking cleared free memory, use it in amdgpu. - Drop seq_file.h from drm_print.h, and include debugfs.h explicitly where needed (drivers). Driver Changes: - Small fixes to rockchip, panthor, v3d, bridge chaining, xlx. - Add Khadas TS050 V2, EDO RM69380 OLED, CSOT MNB601LS1-1 panels, - Add SAM9X7 SoC's LVDS controller. - More driver conversions to struct drm_edid. - Support tc358765 in tc358775 bridge. The following changes since commit 0208ca55aa9c9b997da1f5bc45c4e98916323f08: Backmerge tag 'v6.9-rc5' into drm-next (2024-04-22 14:35:52 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-04-25 for you to fetch changes up to 9e2b84fb6cd7ee913aa61d461db65c1d6a08dcf2: drm/print: drop include seq_file.h (2024-04-25 17:05:48 +0300) drm-misc-next for v6.10-rc1: UAPI Changes: Cross-subsystem Changes: - Devicetree updates for rockchip (#sound-dai-cells) - Add dt bindings for new panels. - Change bridge/tc358775 dt bindings. Core Changes: - Fix SIZE_HINTS cursor property doc. - Parse topology blocks for all DispID < 2.0. - Implement support for tracking cleared free memory, use it in amdgpu. - Drop seq_file.h from drm_print.h, and include debugfs.h explicitly where needed (drivers). Driver Changes: - Small fixes to rockchip, panthor, v3d, bridge chaining, xlx. - Add Khadas TS050 V2, EDO RM69380 OLED, CSOT MNB601LS1-1 panels, - Add SAM9X7 SoC's LVDS controller. - More driver conversions to struct drm_edid. - Support tc358765 in tc358775 bridge. Adam Ford (1): drm/bridge: imx: Fix unmet depenency for PHY_FSL_SAMSUNG_HDMI_PHY Anatoliy Klymenko (6): drm: xlnx: zynqmp_dpsub: Set layer mode during creation drm: xlnx: zynqmp_dpsub: Update live format defines drm: xlnx: zynqmp_dpsub: Add connected live layer helper drm: xlnx: zynqmp_dpsub: Anounce supported input formats drm: xlnx: zynqmp_dpsub: Minimize usage of global flag drm: xlnx: zynqmp_dpsub: Set input live format Andy Yan (1): drm/rockchip: lvds: Remove include of drm_dp_helper.h Arunpravin Paneer Selvam (3): drm/buddy: Implement tracking clear page feature drm/amdgpu: Enable clear page functionality drm/tests: Add a test case for drm buddy clear allocation Barnabás Czémán (1): drm/panel: jdi-fhd-r63452: make use of prepare_prev_first Dan Carpenter (1): drm/panthor: clean up some types in panthor_sched_suspend() David Wronek (2): dt-bindings: display: panel: Add Raydium RM69380 drm/panel: Add driver for EDO RM69380 OLED panel Detlev Casanova (1): drm/rockchip: vop2: Do not divide height twice for YUV Dharma Balasubiramani (3): dt-bindings: display: bridge: add sam9x75-lvds binding drm/bridge: add lvds controller support for sam9x7 MAINTAINERS: add SAM9X7 SoC's LVDS controller Dmitry Baryshkov (5): drm/panel: novatek-nt36672e: stop setting register load before disable drm/panel: novatek-nt36672e: stop calling regulator_set_load manually drm/panel: novatek-nt36672a: stop calling regulator_set_load manually drm/panel: visionox-rm69299: stop calling regulator_set_load manually drm/bridge: adv7511: make it honour next bridge in DT Jacobe Zang (2): dt-bindings: panel-simple-dsi: add Khadas TS050 V2 panel drm/panel: add Khadas TS050 V2 panel support Jani Nikula (11): drm/panel: simple: switch to struct drm_edid drm/panel-samsung-atna33xc20: switch to struct drm_edid drm/panel-edp: switch to struct drm_edid drm/sun4i: hdmi: switch to struct drm_edid drm/vc4: hdmi: switch to struct drm_edid drm/gud: switch to struct drm_edid drm/rockchip: cdn-dp: switch to struct drm_edid drm/rockchip: inno_hdmi: switch to struct drm_edid drm/rockchip: rk3066_hdmi: switch to struct drm_edid drm/print: drop include debugfs.h and include where needed drm/print: drop include seq_file.h Johan Jonker (3): dt-bindings: display: add #sound-dai-cells property to rockchip dw hdmi dt-bindings: display: add #sound-dai-cells property to rockchip rk3066 hdmi dt-bindings: display: add #sound-dai-cells property to rockchip inno hdmi Krzysztof Kozlowski (3): drm/rockchip: cdn-dp: drop driver owner assignment drm/bridge: chipone-icn6211: drop driver owner assignment drm/bridge: tc358764: drop driver owner
[PATCH 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Changes since previous version: - Call the memset for plane state immediately when scheduling vblank, this prevents a use-after-free in cursor cleanup. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..ab01c2d15afd 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1176,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 25593f6aae7d..7f935c88726e 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -616,6 +629,24 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && +
[PATCH 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 23a122ee20c9..3cebeaa6e8b4 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -674,6 +674,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -817,14 +828,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b9434465d3a7..bb8983715ad6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -65,6 +65,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6916,6 +6917,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 62f7a30c37dc..42fa627e7e14 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -730,6 +730,9 @@ struct intel_plane_state { struct intel_fb_view view; u32 phys_dma_addr; /* for cursor_needs_physical */ + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[PATCH 0/3] drm/i915/display: Unpin cursor worker in vblank worker series.
Use the vblank worker to unpin fb, for the legacy cursor fastpath and atomic cursor slowpath. This prevents pipe fault errors from the cursor plane in Xe. A small race appears to exist in kms_universal_plane@cursor-fb-leak on dg2, not sure why. I tried reproducing it and failed. Maarten Lankhorst (2): drm: Add drm_vblank_work_flush_all(). drm/i915: Use the same vblank worker for atomic unpin Ville Syrjälä (1): drm/i915: Use vblank worker to unpin old legacy cursor fb safely drivers/gpu/drm/drm_vblank_work.c | 22 + .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 26 ++-- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ drivers/gpu/drm/i915/display/intel_display.c | 3 ++ .../drm/i915/display/intel_display_types.h| 3 ++ include/drm/drm_vblank_work.h | 2 ++ 9 files changed, 102 insertions(+), 3 deletions(-) -- 2.43.0
[PATCH 1/3] drm: Add drm_vblank_work_flush_all().
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 4fe9b1d3b00f..83a81a5e8280 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + !waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[PATCH v3 4/4] drm/xe/display: Re-use display vmas when possible
i915 has this really nice, infrastructure where everything becomes complicated, GGTT needs eviction, etc.. Lets not do that, and make the dumbest possible interface instead. Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel fb. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 ++ drivers/gpu/drm/i915/display/intel_fbdev.h| 9 .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c| 46 +-- 8 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..24ba55531e8d 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1106,7 +1106,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 23a122ee20c9..3d3b8e37c0f2 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -761,7 +761,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) goto out_free; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index b6df9baf481b..7b8a1825ccfc 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -236,7 +236,8 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) i915_vma_put(vma); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +int intel_plane_pin_fb(struct intel_plane_state *plane_state, + const struct intel_plane_state *old_plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index de0efaa25905..48675e6233f0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -22,7 +22,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags); -int intel_plane_pin_fb(struct intel_plane_state *plane_state); +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state); void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 43855c6c3509..a010b7a8a468 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -668,3 +668,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) return to_intel_framebuffer(fbdev->helper.fb); } + +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return fbdev ? fbdev->vma : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 04fd523a5023..fa6c0c1ae936 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -22,6 +22,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev); void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); + #else static inline int intel_fbdev_init(struct drm_device *dev) { @@ -51,10 +53,17 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) static inline void intel_fbdev_restore_mode(struct drm_i915_private *i915) { } + static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { return NULL; } + +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return NULL; +} + #endif #endif /* __INTEL_FBDEV_H__ */ diff --git a/drivers/gpu/drm/xe/compat-
[PATCH v3 3/4] drm/xe: Use simple xchg to cache DPT
Preallocate a DPT when creating the FB, and store it in i915_address_space. This can be used to prevent an expensive allocation in the pinning path. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 33 +++--- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 5a8d6857fb89..6ebda3ded8b4 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -112,9 +112,11 @@ static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) return dpt; } -static void xe_fb_dpt_free(struct i915_vma *vma) +static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) { - xe_bo_put(vma->dpt); + if (!fb || cmpxchg((struct xe_bo **)>dpt_vm, NULL, vma->dpt)) + xe_bo_put(vma->dpt); + vma->dpt = NULL; } @@ -152,10 +154,11 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) static int xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) { - struct xe_bo *dpt; + struct xe_bo *dpt = (struct xe_bo *)xchg(>dpt_vm, NULL); int err; - dpt = xe_fb_dpt_alloc(fb); + if (!dpt) + dpt = xe_fb_dpt_alloc(fb); if (IS_ERR(dpt)) return PTR_ERR(dpt); @@ -171,17 +174,17 @@ xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) ttm_bo_unreserve(>ttm); } if (err) - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); return err; } -static void xe_fb_dpt_unpin_free(struct i915_vma *vma) +static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer *fb) { ttm_bo_reserve(>dpt->ttm, false, false, NULL); ttm_bo_unpin(>dpt->ttm); ttm_bo_unreserve(>dpt->ttm); - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); } static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, @@ -237,7 +240,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, ret = xe_fb_dpt_map_ggtt(dpt); if (ret) - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); return ret; } @@ -399,14 +402,14 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, return ERR_PTR(ret); } -static void __xe_unpin_fb_vma(struct i915_vma *vma) +static void __xe_unpin_fb_vma(struct i915_vma *vma, struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(vma->bo->ttm.base.dev); struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt; if (vma->dpt) { xe_ggtt_remove_bo(ggtt, vma->dpt); - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); } else { if (!drm_mm_node_allocated(>bo->ggtt_node) || vma->bo->ggtt_node.start != vma->node.start) @@ -433,7 +436,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) { - __xe_unpin_fb_vma(vma); + __xe_unpin_fb_vma(vma, NULL); } int intel_plane_pin_fb(struct intel_plane_state *plane_state) @@ -455,7 +458,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) { - __xe_unpin_fb_vma(old_plane_state->ggtt_vma); + __xe_unpin_fb_vma(old_plane_state->ggtt_vma, to_intel_framebuffer(old_plane_state->hw.fb)); old_plane_state->ggtt_vma = NULL; } @@ -465,10 +468,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) */ struct i915_address_space *intel_dpt_create(struct intel_framebuffer *fb) { - return NULL; + return (struct i915_address_space *)xe_fb_dpt_alloc(fb); } void intel_dpt_destroy(struct i915_address_space *vm) { - return; + struct xe_bo *bo = (struct xe_bo *)vm; + + xe_bo_put(bo); } -- 2.43.0
[PATCH v3 2/4] drm/xe/display: Preparations for preallocating dpt bo
The DPT bo should not be allocated when pinning, but in advance when creating the framebuffer. Split allocation from bo pinning and GGTT insertion. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 159 +++-- 1 file changed, 123 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 3e1ae37c4c8b..5a8d6857fb89 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -77,47 +77,130 @@ write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, *dpt_ofs = ALIGN(*dpt_ofs, 4096); } -static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma) +static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); - struct xe_ggtt *ggtt = tile0->mem.ggtt; struct xe_bo *bo = intel_fb_obj(>base), *dpt; u32 dpt_size, size = bo->ttm.base.size; - if (view->type == I915_GTT_VIEW_NORMAL) + if (!intel_fb_needs_pot_stride_remap(fb)) dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE); - else if (view->type == I915_GTT_VIEW_REMAPPED) - dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, -XE_PAGE_SIZE); else - /* display uses 4K tiles instead of bytes here, convert to entries.. */ - dpt_size = ALIGN(intel_rotation_info_size(>rotated) * 8, + dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, XE_PAGE_SIZE); if (IS_DGFX(xe)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_VRAM0 | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); - else - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_STOLEN | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + return xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_VRAM0 | + XE_BO_FLAG_PAGETABLE); + + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_STOLEN | + XE_BO_FLAG_PAGETABLE); if (IS_ERR(dpt)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_SYSTEM | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_PAGETABLE); + + return dpt; +} + +static void xe_fb_dpt_free(struct i915_vma *vma) +{ + xe_bo_put(vma->dpt); + vma->dpt = NULL; +} + +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +{ + struct xe_device *xe = xe_bo_device(dpt); + struct xe_tile *tile0 = xe_device_get_root_tile(xe); + struct xe_ggtt *ggtt = tile0->mem.ggtt; + u64 start = 0, end = U64_MAX; + u64 alignment = XE_PAGE_SIZE; + int err; + + if (dpt->flags & XE_BO_FLAG_INTERNAL_64K) + alignment = SZ_64K; + + if (XE_WARN_ON(dpt->ggtt_node.size)) + return -EINVAL; + + xe_pm_runtime_get_noresume(xe); + err = mutex_lock_interruptible(>lock); + if (err) + goto out_put; + + err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, + alignment, 0, start, end, 0); + if (!err) + xe_ggtt_map_bo(ggtt, dpt); + mutex_unlock(>lock); + +out_put: + xe_pm_runtime_put(xe); + return err; +} + +static int +xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) +{ + struct xe
[PATCH v3 1/4] drm/xe: Remove safety check from __xe_ttm_stolen_io_mem_reserve_stolen
This is invalid with display code when reworking DPT pinning. The only reason we added it, was because originally all display allocations also had the bit set. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c index f77367329760..1613290b9eda 100644 --- a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c @@ -298,10 +298,6 @@ static int __xe_ttm_stolen_io_mem_reserve_stolen(struct xe_device *xe, XE_WARN_ON(IS_DGFX(xe)); - /* XXX: Require BO to be mapped to GGTT? */ - if (drm_WARN_ON(>drm, !(bo->flags & XE_BO_FLAG_GGTT))) - return -EIO; - /* GGTT is always contiguously mapped */ mem->bus.offset = xe_bo_ggtt_addr(bo) + mgr->io_base; -- 2.43.0
[PATCH v3 0/4] drm/xe: More fb pinning optimizations.
This reduces the latency of pinning framebuffers by re-using the previous mapping, if available. Additionally, DPT is preallocated when creating the FB, instead of performing a bo allocation on every pin. Remove the safety check in the first patch again, I didn't realize it was needed even without the initial FB GGTT pinning removal. Maarten Lankhorst (4): drm/xe: Remove safety check from __xe_ttm_stolen_io_mem_reserve_stolen drm/xe/display: Preparations for preallocating dpt bo drm/xe: Use simple xchg to cache DPT drm/xe/display: Re-use display vmas when possible .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 + drivers/gpu/drm/i915/display/intel_fbdev.h| 9 + .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 + drivers/gpu/drm/xe/display/xe_fb_pin.c| 220 ++ drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c| 4 - 9 files changed, 198 insertions(+), 53 deletions(-) -- 2.43.0
[PATCH v2 1/3] drm/xe/display: Preparations for preallocating dpt bo
The DPT bo should not be allocated when pinning, but in advance when creating the framebuffer. Split allocation from bo pinning and GGTT insertion. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 159 +++-- 1 file changed, 123 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 3e1ae37c4c8b..5a8d6857fb89 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -77,47 +77,130 @@ write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, *dpt_ofs = ALIGN(*dpt_ofs, 4096); } -static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma) +static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); - struct xe_ggtt *ggtt = tile0->mem.ggtt; struct xe_bo *bo = intel_fb_obj(>base), *dpt; u32 dpt_size, size = bo->ttm.base.size; - if (view->type == I915_GTT_VIEW_NORMAL) + if (!intel_fb_needs_pot_stride_remap(fb)) dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE); - else if (view->type == I915_GTT_VIEW_REMAPPED) - dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, -XE_PAGE_SIZE); else - /* display uses 4K tiles instead of bytes here, convert to entries.. */ - dpt_size = ALIGN(intel_rotation_info_size(>rotated) * 8, + dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, XE_PAGE_SIZE); if (IS_DGFX(xe)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_VRAM0 | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); - else - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_STOLEN | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + return xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_VRAM0 | + XE_BO_FLAG_PAGETABLE); + + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_STOLEN | + XE_BO_FLAG_PAGETABLE); if (IS_ERR(dpt)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_SYSTEM | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_PAGETABLE); + + return dpt; +} + +static void xe_fb_dpt_free(struct i915_vma *vma) +{ + xe_bo_put(vma->dpt); + vma->dpt = NULL; +} + +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +{ + struct xe_device *xe = xe_bo_device(dpt); + struct xe_tile *tile0 = xe_device_get_root_tile(xe); + struct xe_ggtt *ggtt = tile0->mem.ggtt; + u64 start = 0, end = U64_MAX; + u64 alignment = XE_PAGE_SIZE; + int err; + + if (dpt->flags & XE_BO_FLAG_INTERNAL_64K) + alignment = SZ_64K; + + if (XE_WARN_ON(dpt->ggtt_node.size)) + return -EINVAL; + + xe_pm_runtime_get_noresume(xe); + err = mutex_lock_interruptible(>lock); + if (err) + goto out_put; + + err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, + alignment, 0, start, end, 0); + if (!err) + xe_ggtt_map_bo(ggtt, dpt); + mutex_unlock(>lock); + +out_put: + xe_pm_runtime_put(xe); + return err; +} + +static int +xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) +{ + struct xe
[PATCH v2 2/3] drm/xe: Use simple xchg to cache DPT
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 33 +++--- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 5a8d6857fb89..6ebda3ded8b4 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -112,9 +112,11 @@ static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) return dpt; } -static void xe_fb_dpt_free(struct i915_vma *vma) +static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) { - xe_bo_put(vma->dpt); + if (!fb || cmpxchg((struct xe_bo **)>dpt_vm, NULL, vma->dpt)) + xe_bo_put(vma->dpt); + vma->dpt = NULL; } @@ -152,10 +154,11 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) static int xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) { - struct xe_bo *dpt; + struct xe_bo *dpt = (struct xe_bo *)xchg(>dpt_vm, NULL); int err; - dpt = xe_fb_dpt_alloc(fb); + if (!dpt) + dpt = xe_fb_dpt_alloc(fb); if (IS_ERR(dpt)) return PTR_ERR(dpt); @@ -171,17 +174,17 @@ xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) ttm_bo_unreserve(>ttm); } if (err) - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); return err; } -static void xe_fb_dpt_unpin_free(struct i915_vma *vma) +static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer *fb) { ttm_bo_reserve(>dpt->ttm, false, false, NULL); ttm_bo_unpin(>dpt->ttm); ttm_bo_unreserve(>dpt->ttm); - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); } static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, @@ -237,7 +240,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, ret = xe_fb_dpt_map_ggtt(dpt); if (ret) - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); return ret; } @@ -399,14 +402,14 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, return ERR_PTR(ret); } -static void __xe_unpin_fb_vma(struct i915_vma *vma) +static void __xe_unpin_fb_vma(struct i915_vma *vma, struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(vma->bo->ttm.base.dev); struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt; if (vma->dpt) { xe_ggtt_remove_bo(ggtt, vma->dpt); - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); } else { if (!drm_mm_node_allocated(>bo->ggtt_node) || vma->bo->ggtt_node.start != vma->node.start) @@ -433,7 +436,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) { - __xe_unpin_fb_vma(vma); + __xe_unpin_fb_vma(vma, NULL); } int intel_plane_pin_fb(struct intel_plane_state *plane_state) @@ -455,7 +458,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) { - __xe_unpin_fb_vma(old_plane_state->ggtt_vma); + __xe_unpin_fb_vma(old_plane_state->ggtt_vma, to_intel_framebuffer(old_plane_state->hw.fb)); old_plane_state->ggtt_vma = NULL; } @@ -465,10 +468,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) */ struct i915_address_space *intel_dpt_create(struct intel_framebuffer *fb) { - return NULL; + return (struct i915_address_space *)xe_fb_dpt_alloc(fb); } void intel_dpt_destroy(struct i915_address_space *vm) { - return; + struct xe_bo *bo = (struct xe_bo *)vm; + + xe_bo_put(bo); } -- 2.43.0
[PATCH v2 2/3] drm/xe: Use simple xchg to cache DPT
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 33 +++--- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 5a8d6857fb89..6ebda3ded8b4 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -112,9 +112,11 @@ static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) return dpt; } -static void xe_fb_dpt_free(struct i915_vma *vma) +static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) { - xe_bo_put(vma->dpt); + if (!fb || cmpxchg((struct xe_bo **)>dpt_vm, NULL, vma->dpt)) + xe_bo_put(vma->dpt); + vma->dpt = NULL; } @@ -152,10 +154,11 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) static int xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) { - struct xe_bo *dpt; + struct xe_bo *dpt = (struct xe_bo *)xchg(>dpt_vm, NULL); int err; - dpt = xe_fb_dpt_alloc(fb); + if (!dpt) + dpt = xe_fb_dpt_alloc(fb); if (IS_ERR(dpt)) return PTR_ERR(dpt); @@ -171,17 +174,17 @@ xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) ttm_bo_unreserve(>ttm); } if (err) - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); return err; } -static void xe_fb_dpt_unpin_free(struct i915_vma *vma) +static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer *fb) { ttm_bo_reserve(>dpt->ttm, false, false, NULL); ttm_bo_unpin(>dpt->ttm); ttm_bo_unreserve(>dpt->ttm); - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); } static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, @@ -237,7 +240,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, ret = xe_fb_dpt_map_ggtt(dpt); if (ret) - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); return ret; } @@ -399,14 +402,14 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, return ERR_PTR(ret); } -static void __xe_unpin_fb_vma(struct i915_vma *vma) +static void __xe_unpin_fb_vma(struct i915_vma *vma, struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(vma->bo->ttm.base.dev); struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt; if (vma->dpt) { xe_ggtt_remove_bo(ggtt, vma->dpt); - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); } else { if (!drm_mm_node_allocated(>bo->ggtt_node) || vma->bo->ggtt_node.start != vma->node.start) @@ -433,7 +436,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) { - __xe_unpin_fb_vma(vma); + __xe_unpin_fb_vma(vma, NULL); } int intel_plane_pin_fb(struct intel_plane_state *plane_state) @@ -455,7 +458,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) { - __xe_unpin_fb_vma(old_plane_state->ggtt_vma); + __xe_unpin_fb_vma(old_plane_state->ggtt_vma, to_intel_framebuffer(old_plane_state->hw.fb)); old_plane_state->ggtt_vma = NULL; } @@ -465,10 +468,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) */ struct i915_address_space *intel_dpt_create(struct intel_framebuffer *fb) { - return NULL; + return (struct i915_address_space *)xe_fb_dpt_alloc(fb); } void intel_dpt_destroy(struct i915_address_space *vm) { - return; + struct xe_bo *bo = (struct xe_bo *)vm; + + xe_bo_put(bo); } -- 2.43.0
[PATCH v2 1/3] drm/xe/display: Preparations for preallocating dpt bo
The DPT bo should not be allocated when pinning, but in advance when creating the framebuffer. Split allocation from bo pinning and GGTT insertion. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 159 +++-- 1 file changed, 123 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 3e1ae37c4c8b..5a8d6857fb89 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -77,47 +77,130 @@ write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, *dpt_ofs = ALIGN(*dpt_ofs, 4096); } -static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma) +static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); - struct xe_ggtt *ggtt = tile0->mem.ggtt; struct xe_bo *bo = intel_fb_obj(>base), *dpt; u32 dpt_size, size = bo->ttm.base.size; - if (view->type == I915_GTT_VIEW_NORMAL) + if (!intel_fb_needs_pot_stride_remap(fb)) dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE); - else if (view->type == I915_GTT_VIEW_REMAPPED) - dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, -XE_PAGE_SIZE); else - /* display uses 4K tiles instead of bytes here, convert to entries.. */ - dpt_size = ALIGN(intel_rotation_info_size(>rotated) * 8, + dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, XE_PAGE_SIZE); if (IS_DGFX(xe)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_VRAM0 | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); - else - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_STOLEN | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + return xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_VRAM0 | + XE_BO_FLAG_PAGETABLE); + + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_STOLEN | + XE_BO_FLAG_PAGETABLE); if (IS_ERR(dpt)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_SYSTEM | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_PAGETABLE); + + return dpt; +} + +static void xe_fb_dpt_free(struct i915_vma *vma) +{ + xe_bo_put(vma->dpt); + vma->dpt = NULL; +} + +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +{ + struct xe_device *xe = xe_bo_device(dpt); + struct xe_tile *tile0 = xe_device_get_root_tile(xe); + struct xe_ggtt *ggtt = tile0->mem.ggtt; + u64 start = 0, end = U64_MAX; + u64 alignment = XE_PAGE_SIZE; + int err; + + if (dpt->flags & XE_BO_FLAG_INTERNAL_64K) + alignment = SZ_64K; + + if (XE_WARN_ON(dpt->ggtt_node.size)) + return -EINVAL; + + xe_pm_runtime_get_noresume(xe); + err = mutex_lock_interruptible(>lock); + if (err) + goto out_put; + + err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, + alignment, 0, start, end, 0); + if (!err) + xe_ggtt_map_bo(ggtt, dpt); + mutex_unlock(>lock); + +out_put: + xe_pm_runtime_put(xe); + return err; +} + +static int +xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) +{ + struct xe
[PATCH v2 3/3] drm/xe/display: Re-use display vmas when possible
i915 has this really nice, infrastructure where everything becomes complicated, GGTT needs eviction, etc.. Lets not do that, and make the dumbest possible interface instead. Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel fb. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 ++ drivers/gpu/drm/i915/display/intel_fbdev.h| 9 .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c| 46 +-- 8 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..24ba55531e8d 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1106,7 +1106,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 23a122ee20c9..3d3b8e37c0f2 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -761,7 +761,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) goto out_free; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index b6df9baf481b..7b8a1825ccfc 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -236,7 +236,8 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) i915_vma_put(vma); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +int intel_plane_pin_fb(struct intel_plane_state *plane_state, + const struct intel_plane_state *old_plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index de0efaa25905..48675e6233f0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -22,7 +22,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags); -int intel_plane_pin_fb(struct intel_plane_state *plane_state); +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state); void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 43855c6c3509..a010b7a8a468 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -668,3 +668,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) return to_intel_framebuffer(fbdev->helper.fb); } + +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return fbdev ? fbdev->vma : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 04fd523a5023..fa6c0c1ae936 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -22,6 +22,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev); void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); + #else static inline int intel_fbdev_init(struct drm_device *dev) { @@ -51,10 +53,17 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) static inline void intel_fbdev_restore_mode(struct drm_i915_private *i915) { } + static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { return NULL; } + +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return NULL; +} + #endif #endif /* __INTEL_FBDEV_H__ */ diff --git a/drivers/gpu/drm/xe/compat-
[PATCH v2 0/3] drm/xe: More fb pinning optimizations.
This reduces the latency of pinning framebuffers by re-using the previous mapping, if available. Additionally, DPT is preallocated when creating the FB, instead of performing a bo allocation on every pin. Changes since v1: - Drop the patch to prevent overwriting GGTT, to see if this fixes the test results. It's not needed for optimizing FB pinning. Maarten Lankhorst (3): drm/xe/display: Preparations for preallocating dpt bo drm/xe: Use simple xchg to cache DPT drm/xe/display: Re-use display vmas when possible .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 + drivers/gpu/drm/i915/display/intel_fbdev.h| 9 + .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 + drivers/gpu/drm/xe/display/xe_fb_pin.c| 220 ++ 8 files changed, 198 insertions(+), 49 deletions(-) -- 2.43.0
[PATCH v2 3/3] drm/xe/display: Re-use display vmas when possible
i915 has this really nice, infrastructure where everything becomes complicated, GGTT needs eviction, etc.. Lets not do that, and make the dumbest possible interface instead. Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel fb. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 ++ drivers/gpu/drm/i915/display/intel_fbdev.h| 9 .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c| 46 +-- 8 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..24ba55531e8d 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1106,7 +1106,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 23a122ee20c9..3d3b8e37c0f2 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -761,7 +761,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) goto out_free; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index b6df9baf481b..7b8a1825ccfc 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -236,7 +236,8 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) i915_vma_put(vma); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +int intel_plane_pin_fb(struct intel_plane_state *plane_state, + const struct intel_plane_state *old_plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index de0efaa25905..48675e6233f0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -22,7 +22,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags); -int intel_plane_pin_fb(struct intel_plane_state *plane_state); +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state); void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 43855c6c3509..a010b7a8a468 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -668,3 +668,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) return to_intel_framebuffer(fbdev->helper.fb); } + +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return fbdev ? fbdev->vma : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 04fd523a5023..fa6c0c1ae936 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -22,6 +22,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev); void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); + #else static inline int intel_fbdev_init(struct drm_device *dev) { @@ -51,10 +53,17 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) static inline void intel_fbdev_restore_mode(struct drm_i915_private *i915) { } + static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { return NULL; } + +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return NULL; +} + #endif #endif /* __INTEL_FBDEV_H__ */ diff --git a/drivers/gpu/drm/xe/compat-
[PATCH v2 0/3] drm/xe: More fb pinning optimizations.
This reduces the latency of pinning framebuffers by re-using the previous mapping, if available. Additionally, DPT is preallocated when creating the FB, instead of performing a bo allocation on every pin. Changes since v1: - Drop the patch to prevent overwriting GGTT, to see if this fixes the test results. It's not needed for optimizing FB pinning. Maarten Lankhorst (3): drm/xe/display: Preparations for preallocating dpt bo drm/xe: Use simple xchg to cache DPT drm/xe/display: Re-use display vmas when possible .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 + drivers/gpu/drm/i915/display/intel_fbdev.h| 9 + .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 + drivers/gpu/drm/xe/display/xe_fb_pin.c| 220 ++ 8 files changed, 198 insertions(+), 49 deletions(-) -- 2.43.0
[PULL] drm-misc-next
Hi Dave, Sima, Bit late, but with slightly more content. Cheers, ~Maarten drm-misc-next-2024-04-19: drm-misc-next for v6.10-rc1: UAPI Changes: - Add SIZE_HINTS property for cursor planes. Cross-subsystem Changes: Core Changes: - Document the requirements and expectations of adding new driver-specific properties. - Assorted small fixes to ttm. - More Kconfig fixes. - Add struct drm_edid_product_id and helpers. - Use drm device based logging in more drm functions. - Fixes for drm-panic, and option to test it. - Assorted small fixes and updates to edid. - Add drm_crtc_vblank_crtc and use it in vkms, nouveau. Driver Changes: - Assorted small fixes and improvements to bridge/imx8mp-hdmi-tx, nouveau, ast, qaic, lima, vc4, bridge/anx7625, mipi-dsi. - Add drm panic to simpledrm, mgag200, imx, ast. - Use dev_err_probe in bridge/panel drivers. - Add Innolux G121X1-L03, LG sw43408 panels. - Use struct drm_edid in i915 bios parsing. The following changes since commit 29b39672bc1d651010f7b61e106d51998f068aaf: drm/bridge: imx8mp-hdmi-pvi: Convert to platform remove callback returning void (2024-04-10 15:06:45 +0200) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-04-19 for you to fetch changes up to 069a6c0e94f99437652dbb7229a56233c7d39968: drm: panel: Add LG sw43408 panel driver (2024-04-19 04:27:48 +0300) drm-misc-next for v6.10-rc1: UAPI Changes: - Add SIZE_HINTS property for cursor planes. Cross-subsystem Changes: Core Changes: - Document the requirements and expectations of adding new driver-specific properties. - Assorted small fixes to ttm. - More Kconfig fixes. - Add struct drm_edid_product_id and helpers. - Use drm device based logging in more drm functions. - Fixes for drm-panic, and option to test it. - Assorted small fixes and updates to edid. - Add drm_crtc_vblank_crtc and use it in vkms, nouveau. Driver Changes: - Assorted small fixes and improvements to bridge/imx8mp-hdmi-tx, nouveau, ast, qaic, lima, vc4, bridge/anx7625, mipi-dsi. - Add drm panic to simpledrm, mgag200, imx, ast. - Use dev_err_probe in bridge/panel drivers. - Add Innolux G121X1-L03, LG sw43408 panels. - Use struct drm_edid in i915 bios parsing. Aleksandr Mishin (1): drm: vc4: Fix possible null pointer dereference Arnd Bergmann (2): accel/qaic: mark debugfs stub functions as static inline drm: fix DRM_DISPLAY_DP_HELPER dependencies, part 2 Baruch Siach (1): doc: dma-buf: fix grammar typo Daniel Vetter (1): drm/panic: Add drm panic locking Dmitry Baryshkov (2): drm/mipi-dsi: use correct return type for the DSC functions drm/mipi-dsi: add mipi_dsi_compression_mode_ext() Erico Nunes (5): drm/lima: add mask irq callback to gp and pp drm/lima: include pp bcast irq in timeout handler check drm/lima: mask irqs in timeout path before hard reset drm/lima: fix shared irq handling on driver remove drm/lima: fix void pointer to enum lima_gpu_id cast warning Hsin-Te Yuan (1): drm/bridge: anx7625: Update audio status while detecting Huai-Yuan Liu (1): drm/arm/malidp: fix a possible null pointer dereference Jani Nikula (18): drm/edid: add drm_edid_get_product_id() drm/edid: add drm_edid_print_product_id() drm/i915/bios: switch to struct drm_edid and struct drm_edid_product_id drm/i915/bios: return drm_edid_product_id from get_lvds_pnp_id() drm/probe-helper: switch to drm device based logging drm/modes: switch to drm device based error logging drm/sysfs: switch to drm device based logging drm/client: switch to drm device based logging, and more drm/crtc: switch to drm device based logging drm/crtc-helper: switch to drm device based logging and warns drm: prefer DRM_MODE_FMT/ARG over drm_mode_debug_printmodeline() drm/displayid: move drm_displayid.h to drm_displayd_internal.h drm/edid: move all internal declarations to drm_crtc_internal.h drm/edid: group struct drm_edid based declarations together drm/edid: rename drm_find_edid_extension() to drm_edid_find_extension() drm/edid: avoid drm_edid_find_extension() internally drm/edid: make drm_edid_are_equal() static drm/edid: make drm_edid_are_equal() more convenient for its single user Jeffrey Hugo (1): accel/qaic: Add Sahara implementation for firmware loading Jesse Zhang (1): drm/ttm: remove unused paramter Jocelyn Falempe (9): drm/panic: Add a drm panic handler drm/panic: Add support for color format conversion drm/panic: Add debugfs entry to test without triggering panic. drm/fb_dma: Add generic get_scanout_buffer() for drm_panic drm/simpledrm: Add drm_panic support drm/mgag200: Add drm_panic support drm/imx: Add
[PATCH 4/5] drm/xe/display: Prevent overwriting original GGTT when taking over initial FB.
Instead of overwriting the original GGTT mapping accidentally, allocate a new GGTT mapping above the original GGTT mapping. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c| 40 --- drivers/gpu/drm/xe/display/xe_fb_pin.h| 20 ++ drivers/gpu/drm/xe/display/xe_plane_initial.c | 15 --- drivers/gpu/drm/xe/xe_ggtt.c | 9 +++-- drivers/gpu/drm/xe/xe_ggtt.h | 3 +- 5 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 drivers/gpu/drm/xe/display/xe_fb_pin.h diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 16a287cbebc5..dd7a1c4a9430 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -8,6 +8,7 @@ #include "intel_dpt.h" #include "intel_fb.h" #include "intel_fb_pin.h" +#include "xe_fb_pin.h" #include "xe_ggtt.h" #include "xe_gt.h" @@ -119,12 +120,11 @@ static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) vma->dpt = NULL; } -static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt, u64 ggtt_start) { struct xe_device *xe = xe_bo_device(dpt); struct xe_tile *tile0 = xe_device_get_root_tile(xe); struct xe_ggtt *ggtt = tile0->mem.ggtt; - u64 start = 0, end = U64_MAX; u64 alignment = XE_PAGE_SIZE; int err; @@ -139,8 +139,9 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) if (err) goto out_put; - err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, - alignment, 0, start, end, 0); + err = xe_ggtt_insert_special_node_locked(ggtt, >ggtt_node, dpt->size, +alignment, ggtt_start, U64_MAX, +ggtt_start ? DRM_MM_INSERT_HIGH : 0); if (!err) xe_ggtt_map_bo(ggtt, dpt); mutex_unlock(>lock); @@ -188,7 +189,7 @@ static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, const struct i915_gtt_view *view, - struct i915_vma *vma) + struct i915_vma *vma, u64 ggtt_start) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); @@ -237,7 +238,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, rot_info->plane[i].dst_stride); } - ret = xe_fb_dpt_map_ggtt(dpt); + ret = xe_fb_dpt_map_ggtt(dpt, ggtt_start); if (ret) xe_fb_dpt_unpin_free(vma, fb); return ret; @@ -269,7 +270,7 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, const struct i915_gtt_view *view, - struct i915_vma *vma) + struct i915_vma *vma, u64 ggtt_start) { struct xe_bo *bo = intel_fb_obj(>base); struct xe_device *xe = to_xe_device(fb->base.dev); @@ -295,7 +296,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, u32 x, size = bo->ttm.base.size; ret = xe_ggtt_insert_special_node_locked(ggtt, >node, size, -align, 0); +align, ggtt_start, U64_MAX, +ggtt_start ? DRM_MM_INSERT_HIGH : 0); if (ret) goto out_unlock; @@ -313,7 +315,7 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, u32 size = intel_rotation_info_size(rot_info) * XE_PAGE_SIZE; ret = xe_ggtt_insert_special_node_locked(ggtt, >node, size, -align, 0); +align, ggtt_start, U64_MAX, 0); if (ret) goto out_unlock; @@ -336,7 +338,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, } static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, - const struct i915_gtt_view *view) + const struct i915_gtt_view *view, + u64 ggtt_start) { struct drm_device *dev = fb->base.dev; struct xe_device *xe = to_xe_device(dev); @@ -384,9 +387,9 @@ static struct i915_vma *__xe_pin_fb_vma(stru
[PATCH 5/5] drm/xe/display: Re-use display vmas when possible
i915 has this really nice, infrastructure where everything becomes complicated, GGTT needs eviction, etc.. Lets not do that, and make the dumbest possible interface instead. Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel fb. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 ++ drivers/gpu/drm/i915/display/intel_fbdev.h| 9 .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c| 46 +-- 8 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..24ba55531e8d 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1106,7 +1106,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 23a122ee20c9..3d3b8e37c0f2 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -761,7 +761,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) goto out_free; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index b6df9baf481b..7b8a1825ccfc 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -236,7 +236,8 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) i915_vma_put(vma); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +int intel_plane_pin_fb(struct intel_plane_state *plane_state, + const struct intel_plane_state *old_plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index de0efaa25905..48675e6233f0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -22,7 +22,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags); -int intel_plane_pin_fb(struct intel_plane_state *plane_state); +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state); void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 43855c6c3509..a010b7a8a468 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -668,3 +668,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) return to_intel_framebuffer(fbdev->helper.fb); } + +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return fbdev ? fbdev->vma : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 04fd523a5023..fa6c0c1ae936 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -22,6 +22,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev); void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); + #else static inline int intel_fbdev_init(struct drm_device *dev) { @@ -51,10 +53,17 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) static inline void intel_fbdev_restore_mode(struct drm_i915_private *i915) { } + static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { return NULL; } + +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return NULL; +} + #endif #endif /* __INTEL_FBDEV_H__ */ diff --git a/drivers/gpu/drm/xe/compat-
[PATCH 0/5] drm/xe: More fb pinning optimizations.
This reduces the latency of pinning framebuffers by re-using the previous mapping, if available. Additionally, DPT is preallocated when creating the FB, instead of performing a bo allocation on every pin. Maarten Lankhorst (5): drm/xe/display: Preparations for preallocating dpt bo drm/xe: Use simple xchg to cache DPT drm/xe: Remove safety check from __xe_ttm_stolen_io_mem_reserve_stolen drm/xe/display: Prevent overwriting original GGTT when taking over initial FB. drm/xe/display: Re-use display vmas when possible .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 + drivers/gpu/drm/i915/display/intel_fbdev.h| 9 + .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 + drivers/gpu/drm/xe/display/xe_fb_pin.c| 246 ++ drivers/gpu/drm/xe/display/xe_fb_pin.h| 20 ++ drivers/gpu/drm/xe/display/xe_plane_initial.c | 15 +- drivers/gpu/drm/xe/xe_ggtt.c | 9 +- drivers/gpu/drm/xe/xe_ggtt.h | 3 +- drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c| 4 - 13 files changed, 254 insertions(+), 70 deletions(-) create mode 100644 drivers/gpu/drm/xe/display/xe_fb_pin.h -- 2.43.0
[PATCH 1/5] drm/xe/display: Preparations for preallocating dpt bo
The DPT bo should not be allocated when pinning, but in advance when creating the framebuffer. Split allocation from bo pinning and GGTT insertion. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 159 +++-- 1 file changed, 123 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 3a584bc3a0a3..d967d00bbf9d 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -76,47 +76,130 @@ write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, *dpt_ofs = ALIGN(*dpt_ofs, 4096); } -static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma) +static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); - struct xe_ggtt *ggtt = tile0->mem.ggtt; struct xe_bo *bo = intel_fb_obj(>base), *dpt; u32 dpt_size, size = bo->ttm.base.size; - if (view->type == I915_GTT_VIEW_NORMAL) + if (!intel_fb_needs_pot_stride_remap(fb)) dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE); - else if (view->type == I915_GTT_VIEW_REMAPPED) - dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, -XE_PAGE_SIZE); else - /* display uses 4K tiles instead of bytes here, convert to entries.. */ - dpt_size = ALIGN(intel_rotation_info_size(>rotated) * 8, + dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, XE_PAGE_SIZE); if (IS_DGFX(xe)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_VRAM0 | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); - else - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_STOLEN | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + return xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_VRAM0 | + XE_BO_FLAG_PAGETABLE); + + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_STOLEN | + XE_BO_FLAG_PAGETABLE); if (IS_ERR(dpt)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_SYSTEM | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_PAGETABLE); + + return dpt; +} + +static void xe_fb_dpt_free(struct i915_vma *vma) +{ + xe_bo_put(vma->dpt); + vma->dpt = NULL; +} + +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +{ + struct xe_device *xe = xe_bo_device(dpt); + struct xe_tile *tile0 = xe_device_get_root_tile(xe); + struct xe_ggtt *ggtt = tile0->mem.ggtt; + u64 start = 0, end = U64_MAX; + u64 alignment = XE_PAGE_SIZE; + int err; + + if (dpt->flags & XE_BO_FLAG_INTERNAL_64K) + alignment = SZ_64K; + + if (XE_WARN_ON(dpt->ggtt_node.size)) + return -EINVAL; + + xe_device_mem_access_get(tile_to_xe(ggtt->tile)); + err = mutex_lock_interruptible(>lock); + if (err) + goto out_put; + + err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, + alignment, 0, start, end, 0); + if (!err) + xe_ggtt_map_bo(ggtt, dpt); + mutex_unlock(>lock); + +out_put: + xe_device_mem_access_put(tile_to_xe(ggtt->tile)); + return err; +} + +static int +xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct i
[PATCH 3/5] drm/xe: Remove safety check from __xe_ttm_stolen_io_mem_reserve_stolen
This is invalid with display code when reworking DPT. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c index f77367329760..1613290b9eda 100644 --- a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c @@ -298,10 +298,6 @@ static int __xe_ttm_stolen_io_mem_reserve_stolen(struct xe_device *xe, XE_WARN_ON(IS_DGFX(xe)); - /* XXX: Require BO to be mapped to GGTT? */ - if (drm_WARN_ON(>drm, !(bo->flags & XE_BO_FLAG_GGTT))) - return -EIO; - /* GGTT is always contiguously mapped */ mem->bus.offset = xe_bo_ggtt_addr(bo) + mgr->io_base; -- 2.43.0
[PATCH 2/5] drm/xe: Use simple xchg to cache DPT
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 33 +++--- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index d967d00bbf9d..16a287cbebc5 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -111,9 +111,11 @@ static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) return dpt; } -static void xe_fb_dpt_free(struct i915_vma *vma) +static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) { - xe_bo_put(vma->dpt); + if (!fb || cmpxchg((struct xe_bo **)>dpt_vm, NULL, vma->dpt)) + xe_bo_put(vma->dpt); + vma->dpt = NULL; } @@ -151,10 +153,11 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) static int xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) { - struct xe_bo *dpt; + struct xe_bo *dpt = (struct xe_bo *)xchg(>dpt_vm, NULL); int err; - dpt = xe_fb_dpt_alloc(fb); + if (!dpt) + dpt = xe_fb_dpt_alloc(fb); if (IS_ERR(dpt)) return PTR_ERR(dpt); @@ -170,17 +173,17 @@ xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) ttm_bo_unreserve(>ttm); } if (err) - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); return err; } -static void xe_fb_dpt_unpin_free(struct i915_vma *vma) +static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer *fb) { ttm_bo_reserve(>dpt->ttm, false, false, NULL); ttm_bo_unpin(>dpt->ttm); ttm_bo_unreserve(>dpt->ttm); - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); } static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, @@ -236,7 +239,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, ret = xe_fb_dpt_map_ggtt(dpt); if (ret) - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); return ret; } @@ -398,14 +401,14 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, return ERR_PTR(ret); } -static void __xe_unpin_fb_vma(struct i915_vma *vma) +static void __xe_unpin_fb_vma(struct i915_vma *vma, struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(vma->bo->ttm.base.dev); struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt; if (vma->dpt) { xe_ggtt_remove_bo(ggtt, vma->dpt); - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); } else { if (!drm_mm_node_allocated(>bo->ggtt_node) || vma->bo->ggtt_node.start != vma->node.start) @@ -432,7 +435,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) { - __xe_unpin_fb_vma(vma); + __xe_unpin_fb_vma(vma, NULL); } int intel_plane_pin_fb(struct intel_plane_state *plane_state) @@ -454,7 +457,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) { - __xe_unpin_fb_vma(old_plane_state->ggtt_vma); + __xe_unpin_fb_vma(old_plane_state->ggtt_vma, to_intel_framebuffer(old_plane_state->hw.fb)); old_plane_state->ggtt_vma = NULL; } @@ -464,10 +467,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) */ struct i915_address_space *intel_dpt_create(struct intel_framebuffer *fb) { - return NULL; + return (struct i915_address_space *)xe_fb_dpt_alloc(fb); } void intel_dpt_destroy(struct i915_address_space *vm) { - return; + struct xe_bo *bo = (struct xe_bo *)vm; + + xe_bo_put(bo); } -- 2.43.0
[CI-only 8/8] drm/xe/display: Re-use display vmas when possible
i915 has this really nice, infrastructure where everything becomes complicated, GGTT needs eviction, etc.. Lets not do that, and make the dumbest possible interface instead. Try to retrieve the VMA from old_plane_state, or intel_fbdev if kernel fb. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_pin.c | 3 +- drivers/gpu/drm/i915/display/intel_fb_pin.h | 3 +- drivers/gpu/drm/i915/display/intel_fbdev.c| 5 ++ drivers/gpu/drm/i915/display/intel_fbdev.h| 9 .../gpu/drm/xe/compat-i915-headers/i915_vma.h | 3 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c| 46 +-- 8 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index ab01c2d15afd..dcb9b7751261 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1107,7 +1107,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index f08fce0de713..9153a1cdb1f2 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -772,7 +772,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); + ret = intel_plane_pin_fb(new_plane_state, old_plane_state); if (ret) goto out_free; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index b6df9baf481b..7b8a1825ccfc 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -236,7 +236,8 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) i915_vma_put(vma); } -int intel_plane_pin_fb(struct intel_plane_state *plane_state) +int intel_plane_pin_fb(struct intel_plane_state *plane_state, + const struct intel_plane_state *old_plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index de0efaa25905..48675e6233f0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -22,7 +22,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags); -int intel_plane_pin_fb(struct intel_plane_state *plane_state); +int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_plane_state); void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 43855c6c3509..a010b7a8a468 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -668,3 +668,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) return to_intel_framebuffer(fbdev->helper.fb); } + +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return fbdev ? fbdev->vma : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 04fd523a5023..fa6c0c1ae936 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -22,6 +22,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev); void intel_fbdev_restore_mode(struct drm_i915_private *dev_priv); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); +struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); + #else static inline int intel_fbdev_init(struct drm_device *dev) { @@ -51,10 +53,17 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) static inline void intel_fbdev_restore_mode(struct drm_i915_private *i915) { } + static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { return NULL; } + +static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) +{ + return NULL; +} + #endif #endif /* __INTEL_FBDEV_H__ */ diff --git a/drivers/gpu/drm/xe/compat-
[CI-only 3/8] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Changes since previous version: - Call the memset for plane state immediately when scheduling vblank, this prevents a use-after-free in cursor cleanup. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..ab01c2d15afd 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1176,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 22b80004574f..558e9b7404b5 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -618,6 +631,24 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && +
[CI-only 6/8] drm/xe: Use simple xchg to cache DPT
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 33 +++--- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index d967d00bbf9d..16a287cbebc5 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -111,9 +111,11 @@ static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) return dpt; } -static void xe_fb_dpt_free(struct i915_vma *vma) +static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) { - xe_bo_put(vma->dpt); + if (!fb || cmpxchg((struct xe_bo **)>dpt_vm, NULL, vma->dpt)) + xe_bo_put(vma->dpt); + vma->dpt = NULL; } @@ -151,10 +153,11 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) static int xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) { - struct xe_bo *dpt; + struct xe_bo *dpt = (struct xe_bo *)xchg(>dpt_vm, NULL); int err; - dpt = xe_fb_dpt_alloc(fb); + if (!dpt) + dpt = xe_fb_dpt_alloc(fb); if (IS_ERR(dpt)) return PTR_ERR(dpt); @@ -170,17 +173,17 @@ xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct intel_framebuffer *fb) ttm_bo_unreserve(>ttm); } if (err) - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); return err; } -static void xe_fb_dpt_unpin_free(struct i915_vma *vma) +static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer *fb) { ttm_bo_reserve(>dpt->ttm, false, false, NULL); ttm_bo_unpin(>dpt->ttm); ttm_bo_unreserve(>dpt->ttm); - xe_fb_dpt_free(vma); + xe_fb_dpt_free(vma, fb); } static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, @@ -236,7 +239,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, ret = xe_fb_dpt_map_ggtt(dpt); if (ret) - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); return ret; } @@ -398,14 +401,14 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, return ERR_PTR(ret); } -static void __xe_unpin_fb_vma(struct i915_vma *vma) +static void __xe_unpin_fb_vma(struct i915_vma *vma, struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(vma->bo->ttm.base.dev); struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt; if (vma->dpt) { xe_ggtt_remove_bo(ggtt, vma->dpt); - xe_fb_dpt_unpin_free(vma); + xe_fb_dpt_unpin_free(vma, fb); } else { if (!drm_mm_node_allocated(>bo->ggtt_node) || vma->bo->ggtt_node.start != vma->node.start) @@ -432,7 +435,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) { - __xe_unpin_fb_vma(vma); + __xe_unpin_fb_vma(vma, NULL); } int intel_plane_pin_fb(struct intel_plane_state *plane_state) @@ -454,7 +457,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) { - __xe_unpin_fb_vma(old_plane_state->ggtt_vma); + __xe_unpin_fb_vma(old_plane_state->ggtt_vma, to_intel_framebuffer(old_plane_state->hw.fb)); old_plane_state->ggtt_vma = NULL; } @@ -464,10 +467,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) */ struct i915_address_space *intel_dpt_create(struct intel_framebuffer *fb) { - return NULL; + return (struct i915_address_space *)xe_fb_dpt_alloc(fb); } void intel_dpt_destroy(struct i915_address_space *vm) { - return; + struct xe_bo *bo = (struct xe_bo *)vm; + + xe_bo_put(bo); } -- 2.43.0
[CI-only 4/8] drm/xe/display: Preparations for preallocating dpt bo
The DPT bo should not be allocated when pinning, but in advance when creating the framebuffer. Split allocation from bo pinning and GGTT insertion. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 159 +++-- 1 file changed, 123 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 3a584bc3a0a3..d967d00bbf9d 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -76,47 +76,130 @@ write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, *dpt_ofs = ALIGN(*dpt_ofs, 4096); } -static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma) +static struct xe_bo *xe_fb_dpt_alloc(struct intel_framebuffer *fb) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); - struct xe_ggtt *ggtt = tile0->mem.ggtt; struct xe_bo *bo = intel_fb_obj(>base), *dpt; u32 dpt_size, size = bo->ttm.base.size; - if (view->type == I915_GTT_VIEW_NORMAL) + if (!intel_fb_needs_pot_stride_remap(fb)) dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE); - else if (view->type == I915_GTT_VIEW_REMAPPED) - dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, -XE_PAGE_SIZE); else - /* display uses 4K tiles instead of bytes here, convert to entries.. */ - dpt_size = ALIGN(intel_rotation_info_size(>rotated) * 8, + dpt_size = ALIGN(intel_remapped_info_size(>remapped_view.gtt.remapped) * 8, XE_PAGE_SIZE); if (IS_DGFX(xe)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_VRAM0 | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); - else - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_STOLEN | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + return xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_VRAM0 | + XE_BO_FLAG_PAGETABLE); + + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_STOLEN | + XE_BO_FLAG_PAGETABLE); if (IS_ERR(dpt)) - dpt = xe_bo_create_pin_map(xe, tile0, NULL, dpt_size, - ttm_bo_type_kernel, - XE_BO_FLAG_SYSTEM | - XE_BO_FLAG_GGTT | - XE_BO_FLAG_PAGETABLE); + dpt = xe_bo_create(xe, tile0, NULL, dpt_size, + ttm_bo_type_kernel, + XE_BO_FLAG_NEEDS_CPU_ACCESS | + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_PAGETABLE); + + return dpt; +} + +static void xe_fb_dpt_free(struct i915_vma *vma) +{ + xe_bo_put(vma->dpt); + vma->dpt = NULL; +} + +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +{ + struct xe_device *xe = xe_bo_device(dpt); + struct xe_tile *tile0 = xe_device_get_root_tile(xe); + struct xe_ggtt *ggtt = tile0->mem.ggtt; + u64 start = 0, end = U64_MAX; + u64 alignment = XE_PAGE_SIZE; + int err; + + if (dpt->flags & XE_BO_FLAG_INTERNAL_64K) + alignment = SZ_64K; + + if (XE_WARN_ON(dpt->ggtt_node.size)) + return -EINVAL; + + xe_device_mem_access_get(tile_to_xe(ggtt->tile)); + err = mutex_lock_interruptible(>lock); + if (err) + goto out_put; + + err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, + alignment, 0, start, end, 0); + if (!err) + xe_ggtt_map_bo(ggtt, dpt); + mutex_unlock(>lock); + +out_put: + xe_device_mem_access_put(tile_to_xe(ggtt->tile)); + return err; +} + +static int +xe_fb_dpt_alloc_pinned(struct i915_vma *vma, struct i
[CI-only 7/8] drm/xe/display: Prevent overwriting original GGTT when taking over initial FB.
Instead of overwriting the original GGTT mapping accidentally, allocate a new GGTT mapping above the original GGTT mapping. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/xe_fb_pin.c| 40 --- drivers/gpu/drm/xe/display/xe_fb_pin.h| 20 ++ drivers/gpu/drm/xe/display/xe_plane_initial.c | 15 --- drivers/gpu/drm/xe/xe_ggtt.c | 19 ++--- drivers/gpu/drm/xe/xe_ggtt.h | 5 +-- 5 files changed, 61 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/drm/xe/display/xe_fb_pin.h diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 16a287cbebc5..dd7a1c4a9430 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -8,6 +8,7 @@ #include "intel_dpt.h" #include "intel_fb.h" #include "intel_fb_pin.h" +#include "xe_fb_pin.h" #include "xe_ggtt.h" #include "xe_gt.h" @@ -119,12 +120,11 @@ static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb) vma->dpt = NULL; } -static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) +static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt, u64 ggtt_start) { struct xe_device *xe = xe_bo_device(dpt); struct xe_tile *tile0 = xe_device_get_root_tile(xe); struct xe_ggtt *ggtt = tile0->mem.ggtt; - u64 start = 0, end = U64_MAX; u64 alignment = XE_PAGE_SIZE; int err; @@ -139,8 +139,9 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt) if (err) goto out_put; - err = drm_mm_insert_node_in_range(>mm, >ggtt_node, dpt->size, - alignment, 0, start, end, 0); + err = xe_ggtt_insert_special_node_locked(ggtt, >ggtt_node, dpt->size, +alignment, ggtt_start, U64_MAX, +ggtt_start ? DRM_MM_INSERT_HIGH : 0); if (!err) xe_ggtt_map_bo(ggtt, dpt); mutex_unlock(>lock); @@ -188,7 +189,7 @@ static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, const struct i915_gtt_view *view, - struct i915_vma *vma) + struct i915_vma *vma, u64 ggtt_start) { struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); @@ -237,7 +238,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb, rot_info->plane[i].dst_stride); } - ret = xe_fb_dpt_map_ggtt(dpt); + ret = xe_fb_dpt_map_ggtt(dpt, ggtt_start); if (ret) xe_fb_dpt_unpin_free(vma, fb); return ret; @@ -269,7 +270,7 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, const struct i915_gtt_view *view, - struct i915_vma *vma) + struct i915_vma *vma, u64 ggtt_start) { struct xe_bo *bo = intel_fb_obj(>base); struct xe_device *xe = to_xe_device(fb->base.dev); @@ -295,7 +296,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, u32 x, size = bo->ttm.base.size; ret = xe_ggtt_insert_special_node_locked(ggtt, >node, size, -align, 0); +align, ggtt_start, U64_MAX, +ggtt_start ? DRM_MM_INSERT_HIGH : 0); if (ret) goto out_unlock; @@ -313,7 +315,7 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, u32 size = intel_rotation_info_size(rot_info) * XE_PAGE_SIZE; ret = xe_ggtt_insert_special_node_locked(ggtt, >node, size, -align, 0); +align, ggtt_start, U64_MAX, 0); if (ret) goto out_unlock; @@ -336,7 +338,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb, } static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb, - const struct i915_gtt_view *view) + const struct i915_gtt_view *view, + u64 ggtt_start) { struct drm_device *dev = fb->base.dev; struct xe_device *xe = to_xe_device(dev); @@ -384,9 +387,9 @@ static struct i915_vma *__xe_pin_fb_vma(stru
[CI-only 5/8] drm/xe: Remove safety check from __xe_ttm_stolen_io_mem_reserve_stolen
This is invalid with display code when reworking DPT. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c index 6ffecf9f23d1..dce742f5bdc0 100644 --- a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c @@ -302,10 +302,6 @@ static int __xe_ttm_stolen_io_mem_reserve_stolen(struct xe_device *xe, XE_WARN_ON(IS_DGFX(xe)); - /* XXX: Require BO to be mapped to GGTT? */ - if (drm_WARN_ON(>drm, !(bo->flags & XE_BO_FLAG_GGTT))) - return -EIO; - /* GGTT is always contiguously mapped */ mem->bus.offset = xe_bo_ggtt_addr(bo) + mgr->io_base; -- 2.43.0
[CI-only 1/8] drm: Add drm_vblank_work_flush_all().
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..6a53cede547a 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + !waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[CI-only 2/8] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 23a122ee20c9..3cebeaa6e8b4 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -674,6 +674,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -817,14 +828,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a92b67adee9c..46982fdc6a30 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -65,6 +65,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6932,6 +6933,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 0f4bd5710796..563637f20abf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -730,6 +730,9 @@ struct intel_plane_state { struct intel_fb_view view; u32 phys_dma_addr; /* for cursor_needs_physical */ + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[PULL] drm-misc-next
Hi Dave, Sima, Still low amount of patches this week! Cheers, ~Maarten drm-misc-next-2024-04-10: drm-misc-next for v6.10: Cross-subsystem Changes: - Add Tomi as Xilinx maintainer. - Add sound bindings to DT. Core Changes: - Make DP helper depend on KMS helper. Driver Changes: - Assorted small fixes to bridge/dw-hdmi, bridge/cdns-mhdp8456, xlnx, omap, tilcdc, bridge/imx8mp-hdmi-pvi. - Add debugfs entries to qaic. - Add conservative fallback to panel eDP. The following changes since commit d1ef8fc18be6adbbffdee06fbb5b33699e2852be: drm: fix DRM_DISPLAY_DP_HELPER dependencies (2024-04-04 16:20:57 +0200) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-04-10 for you to fetch changes up to 29b39672bc1d651010f7b61e106d51998f068aaf: drm/bridge: imx8mp-hdmi-pvi: Convert to platform remove callback returning void (2024-04-10 15:06:45 +0200) drm-misc-next for v6.10: Cross-subsystem Changes: - Add Tomi as Xilinx maintainer. - Add sound bindings to DT. Core Changes: - Make DP helper depend on KMS helper. Driver Changes: - Assorted small fixes to bridge/dw-hdmi, bridge/cdns-mhdp8456, xlnx, omap, tilcdc, bridge/imx8mp-hdmi-pvi. - Add debugfs entries to qaic. - Add conservative fallback to panel eDP. Aleksandr Mishin (1): drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference Chen-Yu Tsai (1): dt-bindings: display: bridge: it6505: Add #sound-dai-cells Dan Carpenter (1): drm: xlnx: db: fix a memory leak in probe Douglas Anderson (3): drm/panel-edp: Abstract out function to set conservative timings drm/panel-edp: If we fail to powerup/get EDID, use conservative timings drm-panel: If drm_panel_dp_aux_backlight() fails, don't fail panel probe Jani Nikula (1): drm: remove unused header gma_drm.h Jeffrey Hugo (3): accel/qaic: Add bootlog debugfs accel/qaic: Add fifo size debugfs accel/qaic: Add fifo queued debugfs Krzysztof Kozlowski (1): drm/omap: dmm_tiler: drop driver owner assignment Maxime Ripard (2): drm/display: Select DRM_KMS_HELPER for DP helpers drm/bridge: dw-hdmi: Make DRM_DW_HDMI selectable Tomi Valkeinen (1): MAINTAINERS: Add myself as maintainer for Xilinx DRM drivers Uwe Kleine-König (1): drm/bridge: imx8mp-hdmi-pvi: Convert to platform remove callback returning void Wolfram Sang (1): drm: tilcdc: don't use devm_pinctrl_get_select_default() in probe .../bindings/display/bridge/ite,it6505.yaml| 8 +- MAINTAINERS| 1 + drivers/accel/qaic/Makefile| 2 + drivers/accel/qaic/qaic.h | 9 + drivers/accel/qaic/qaic_data.c | 9 + drivers/accel/qaic/qaic_debugfs.c | 338 + drivers/accel/qaic/qaic_debugfs.h | 20 ++ drivers/accel/qaic/qaic_drv.c | 16 +- .../gpu/drm/bridge/cadence/cdns-mhdp8546-core.c| 3 + drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c | 6 +- drivers/gpu/drm/bridge/synopsys/Kconfig| 2 +- drivers/gpu/drm/display/Kconfig| 1 + drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 1 - drivers/gpu/drm/panel/panel-edp.c | 60 ++-- drivers/gpu/drm/panel/panel-samsung-atna33xc20.c | 9 +- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 6 - drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +- include/drm/gma_drm.h | 13 - 18 files changed, 450 insertions(+), 56 deletions(-) create mode 100644 drivers/accel/qaic/qaic_debugfs.c create mode 100644 drivers/accel/qaic/qaic_debugfs.h delete mode 100644 include/drm/gma_drm.h
[CI-only 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Changes since previous version: - Call the memset for plane state immediately when scheduling vblank, this prevents a use-after-free in cursor cleanup. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..ab01c2d15afd 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1176,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 22b80004574f..558e9b7404b5 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -618,6 +631,24 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && +
[CI-only 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 89c26db0730e..f2d18695c21d 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -674,6 +674,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -817,14 +828,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ad04b94c52ee..be65bf9fbd48 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -65,6 +65,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6854,6 +6855,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 0f4bd5710796..563637f20abf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -730,6 +730,9 @@ struct intel_plane_state { struct intel_fb_view view; u32 phys_dma_addr; /* for cursor_needs_physical */ + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[CI-only 1/3] drm: Add drm_vblank_work_flush_all().
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..6a53cede547a 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + !waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[CI-only 2/4] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 89c26db0730e..f2d18695c21d 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -674,6 +674,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -817,14 +828,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ad04b94c52ee..be65bf9fbd48 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -65,6 +65,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6854,6 +6855,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 0f4bd5710796..563637f20abf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -730,6 +730,9 @@ struct intel_plane_state { struct intel_fb_view view; u32 phys_dma_addr; /* for cursor_needs_physical */ + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[CI-only 4/4] drm/i915: Hack to check use-after-free aggressively, and undo purpose of patches
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 558e9b7404b5..0ec6c3a79ec1 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -640,7 +640,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state, if (old_plane_state->uapi.crtc == >base && old_plane_state->unpin_work.vblank) { drm_vblank_work_schedule(_plane_state->unpin_work, - drm_crtc_accurate_vblank_count(>base) + 1, + drm_crtc_accurate_vblank_count(>base), false); /* Remove plane from atomic state, cleanup/free is done from vblank worker. */ diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index e999ee8e9d94..f052c25b0675 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -833,7 +833,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_cursor_unpin_work); drm_vblank_work_schedule(_plane_state->unpin_work, - drm_crtc_accurate_vblank_count(>base) + 1, + drm_crtc_accurate_vblank_count(>base), false); old_plane_state = NULL; -- 2.43.0
[CI-only 3/4] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Changes since previous version: - Call the memset for plane state immediately when scheduling vblank, this prevents a use-after-free in cursor cleanup. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..ab01c2d15afd 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1176,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 22b80004574f..558e9b7404b5 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -618,6 +631,24 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && +
[CI-only 1/4] drm: Add drm_vblank_work_flush_all().
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..6a53cede547a 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + !waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
Re: [rebase 1/3] drm: Add drm_vblank_work_flush_all().
Hey, On 2024-04-05 15:36, Lucas De Marchi wrote: what does "rebase" instead of "PATCH" is supposed to mean here? And then we have a "PATCH v2" as reply to this one. Shouldn't this go to dri-devel (too)? Lucas De Marchi I was rebasing so no changes were originally made. Afterwards I found out why the patch series failed, and sent a v2 patch for that specifically. I think this should go to dri-devel, forgot this patch required it. :) Can send a full v2 patch series in the beginning of next week. It looks like I still missed a uaf even with this fix. :( Cheers, ~Maarten On Thu, Apr 04, 2024 at 12:48:11PM +0200, Maarten Lankhorst wrote: From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..ff86f2b2e052 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[PATCH v2] drm: Add drm_vblank_work_flush_all().
From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) Changes since v1: Check in flush_all for waitqueue_active was inverted. diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..6a53cede547a 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + !waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[PULL] drm-misc-next
Hi Dave, Sima, Everyone seems to be out on vacation, so the pull request is pretty empty. Cheers, ~Maarten drm-misc-next-2024-04-05: drm-misc-next for v6.10: Core Changes: - Fix DRM_DISPLAY_DP_HELPER dependencies. Driver Changes: - i2c and polling fixes to ast. - Small fixes to panthor. - Allow IRQ to share GPIO pins in bridge/adv7511. The following changes since commit 39cd87c4eb2b893354f3b850f916353f2658ae6f: Linux 6.9-rc2 (2024-03-31 14:32:39 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-04-05 for you to fetch changes up to d1ef8fc18be6adbbffdee06fbb5b33699e2852be: drm: fix DRM_DISPLAY_DP_HELPER dependencies (2024-04-04 16:20:57 +0200) drm-misc-next for v6.10: Core Changes: - Fix DRM_DISPLAY_DP_HELPER dependencies. Driver Changes: - i2c and polling fixes to ast. - Small fixes to panthor. - Allow IRQ to share GPIO pins in bridge/adv7511. Adam Ford (1): drm/bridge: adv7511: Allow IRQ to share GPIO pins Adrián Larumbe (1): ABI: sysfs-driver-panfrost-profiling: fix indentation problem Arnd Bergmann (1): drm: fix DRM_DISPLAY_DP_HELPER dependencies Boris Brezillon (3): drm/panthor: Fix IO-page mmap() for 32-bit userspace on 64-bit kernel drm/panthor: Fix ordering in _irq_suspend() drm/panthor: Drop the dev_enter/exit() sections in _irq_suspend/resume() Chris Morgan (3): dt-bindings: vendor-prefix: Add prefix for GameForce dt-bindings: display: Add GameForce Chi Panel drm/panel: st7703: Add GameForce Chi Panel Support Christian Hewitt (1): drm/meson: vclk: fix calculation of 59.94 fractional rates Dan Carpenter (3): drm/panthor: Fix a couple -ENOMEM error codes drm/panthor: Fix error code in panthor_gpu_init() drm/panthor: Fix off by one in panthor_fw_get_cs_iface() Harshit Mogalapalli (2): drm/panthor: Fix NULL vs IS_ERR() bug in panthor_probe() drm/panthor: Don't return NULL from panthor_vm_get_heap_pool() Ian Forbes (1): drm/vmwgfx: Remove unused code Liviu Dudau (2): drm/panthor: Cleanup unused variable 'cookie' drm/panthor: Fix some kerneldoc warnings Nathan Chancellor (1): drm/panthor: Fix clang -Wunused-but-set-variable in tick_ctx_apply() Thomas Zimmermann (14): Merge drm/drm-next into drm-misc-next drm/ast: Include where necessary drm/ast: Fail probing if DDC channel could not be initialized drm/ast: Remove struct ast_{vga,sil165}_connector drm/ast: Allocate instance of struct ast_i2c_chan with managed helpers drm/ast: Move DDC code to ast_ddc.{c,h} drm/ast: Rename struct ast_i2c_chan to struct ast_ddc drm/ast: Pass AST device to ast_ddc_create() drm/ast: Store AST device in struct ast_ddc drm/ast: Rename struct i2c_algo_bit_data callbacks and their parameters drm/ast: Acquire I/O-register lock in DDC code drm/ast: Use drm_connector_helper_get_modes() drm/ast: Implement polling for VGA and SIL164 connectors drm/ast: Automatically clean up poll helper .../ABI/testing/sysfs-driver-panfrost-profiling| 10 + .../bindings/display/bridge/lvds-codec.yaml|1 + .../bindings/display/panel/ilitek,ili9881c.yaml|1 + .../bindings/display/panel/novatek,nt35950.yaml|3 +- .../bindings/display/panel/novatek,nt36523.yaml| 25 +- .../bindings/display/panel/panel-common-dual.yaml | 47 + .../bindings/display/panel/panel-simple-dsi.yaml |2 + .../bindings/display/panel/panel-simple.yaml |4 + .../display/panel/rocktech,jh057n00900.yaml|2 + .../bindings/display/panel/sony,td4353-jdi.yaml|2 + .../bindings/gpu/arm,mali-valhall-csf.yaml | 147 + .../devicetree/bindings/vendor-prefixes.yaml |4 + Documentation/gpu/driver-uapi.rst |5 + Documentation/gpu/panfrost.rst |9 + MAINTAINERS| 183 +- arch/m68k/include/asm/pgtable.h|2 + arch/parisc/configs/generic-32bit_defconfig|2 +- drivers/gpu/drm/Kconfig| 23 +- drivers/gpu/drm/Makefile | 29 + drivers/gpu/drm/amd/amdgpu/Kconfig | 12 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |6 + drivers/gpu/drm/ast/Makefile | 10 +- drivers/gpu/drm/ast/{ast_i2c.c => ast_ddc.c} | 120 +- drivers/gpu/drm/ast/ast_ddc.h | 20 + drivers/gpu/drm/ast/ast_drv.c |1 + drivers/gpu/drm/ast/ast_drv.h | 39 +- drivers/gpu/drm/ast/ast_main.c |1 + drivers/gpu/drm/ast/ast_mode.c | 147 +-
[rebase 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Changes since previous version: - Call the memset for plane state immediately when scheduling vblank, this prevents a use-after-free in cursor cleanup. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..ab01c2d15afd 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1176,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 22b80004574f..558e9b7404b5 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -618,6 +631,24 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && +
[rebase 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 89c26db0730e..f2d18695c21d 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -674,6 +674,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -817,14 +828,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ad04b94c52ee..be65bf9fbd48 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -65,6 +65,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6854,6 +6855,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 0f4bd5710796..563637f20abf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -730,6 +730,9 @@ struct intel_plane_state { struct intel_fb_view view; u32 phys_dma_addr; /* for cursor_needs_physical */ + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[rebase 1/3] drm: Add drm_vblank_work_flush_all().
From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..ff86f2b2e052 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[PULL] drm-misc-next
Hi Dave, Sima, Happy easter!! Cheers, ~Maarten drm-misc-next-2024-03-28: drm-misc-next for v6.10-rc1: The deal of a lifetime! You get ALL of the previous drm-misc-next-2024-03-21-1 tag!! But WAIT, there's MORE! Cross-subsystem Changes: - Assorted DT binding updates. Core Changes: - Clarify how optional wait_hpd_asserted is. - Shuffle Kconfig names around. Driver Changes: - Assorted build fixes for panthor, imagination, - Add AUO B120XAN01.0 panels. - Assorted small fixes to panthor, panfrost. The following changes since commit b9511c6d277c31b13d4f3128eba46f4e0733d734: Merge tag 'drm-msm-next-2024-03-07' of https://gitlab.freedesktop.org/drm/msm into drm-next (2024-03-08 12:45:21 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-03-28 for you to fetch changes up to 4b2d588d8a7520b414290312c9b40bca48b15e39: drm: DRM_WERROR should depend on DRM (2024-03-28 12:36:04 +0200) drm-misc-next for v6.10-rc1: The deal of a lifetime! You get ALL of the previous drm-misc-next-2024-03-21-1 tag!! But WAIT, there's MORE! Cross-subsystem Changes: - Assorted DT binding updates. Core Changes: - Clarify how optional wait_hpd_asserted is. - Shuffle Kconfig names around. Driver Changes: - Assorted build fixes for panthor, imagination, - Add AUO B120XAN01.0 panels. - Assorted small fixes to panthor, panfrost. Adrián Larumbe (2): drm/panfrost: Replace fdinfo's profiling debugfs knob with sysfs drm/panfrost: Only display fdinfo's engine and cycle tags when profiling is on Andrew Halaney (1): drm/tidss: Use dev_err_probe() over dev_dbg() when failing to probe the port Andy Shevchenko (1): drm/gma500: Remove unused intel-mid.h Arnd Bergmann (1): drm/imagination: avoid -Woverflow warning Boris Brezillon (18): drm/panthor: Add uAPI drm/panthor: Add GPU register definitions drm/panthor: Add the device logical block drm/panthor: Add the GPU logical block drm/panthor: Add GEM logical block drm/panthor: Add the devfreq logical block drm/panthor: Add the MMU/VM logical block drm/panthor: Add the FW logical block drm/panthor: Add the heap logical block drm/panthor: Add the scheduler logical block drm/panthor: Add the driver frontend block drm/panthor: Allow driver compilation drm/panthor: Add an entry to MAINTAINERS drm/panthor: Fix panthor_devfreq kerneldoc drm/panthor: Explicitly include mm.h for the {virt, __phys)_to_pfn() defs drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue drm/panthor: Fix the CONFIG_PM=n case drm/panthor: Fix wrong kernel-doc format in the uAPI header Christian König (3): drm/ttm: improve idle/busy handling v5 drm/amdgpu: use GTT only as fallback for VRAM|GTT drm/ttm: warn when resv objs are mixed in a bulk_move Colin Ian King (1): drm/panthor: Fix spelling mistake "readyness" -> "readiness" Dmitry Baryshkov (1): dt-bindings: display/lvds-codec: add ti,sn65lvds94 Douglas Anderson (2): drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't assert drm/dp: Clarify that wait_hpd_asserted() is not optional for panels Geert Uytterhoeven (2): m68k: pgtable: Add missing #include drm: DRM_WERROR should depend on DRM Heiko Stuebner (2): drm/panel: ltk050h3146w: add MIPI_DSI_MODE_VIDEO to LTK050H3148W flags drm/panel: ltk050h3146w: drop duplicate commands from LTK050H3148W init Hsin-Yi Wang (5): drm_edid: Add a function to get EDID base block drm/edid: Add a function to match EDID with identity drm/edid: Match edid quirks with identity drm/panel-edp: Match edp_panels with panel identity drm/panel-edp: Fix AUO 0x405c panel naming and add a variant Jagan Teki (2): drm/bridge: Fix improper bridge init order with pre_enable_prev_first drm/bridge: Document bridge init order with pre_enable_prev_first Jani Nikula (29): drm: enable (most) W=1 warnings by default across the subsystem drm: Add CONFIG_DRM_WERROR drm/crtc: make drm_crtc_internal.h self-contained drm: add missing header guards to drm_internal.h drm/kunit: fix drm_kunit_helpers.h kernel-doc drm/amdgpu: make amd_asic_type.h self-contained drm: bridge: samsung-dsim: make samsung-dsim.h self-contained drm/dp_mst: fix drm_dp_mst_helper.h kernel-doc drm/crc: make drm_debugfs_crc.h self-contained and fix kernel-doc drm: fix drm_format_helper.h kernel-doc warnings drm/lease: make drm_lease.h self-contained drm: fix drm_gem_vram_helper.h kernel-doc drm/of: make drm_of.h self-contained drm/suballoc: fix drm_suballoc.h kernel-doc drm: add missing header guards to
[PULL] drm-misc-next
drm-misc-next-2024-03-21-1: drm-misc-next for v6.10: UAPI Changes: - Move some nouveau magic constants to uapi. Cross-subsystem Changes: - Move drm-misc to gitlab and freedesktop hosting. - Add entries for panfrost. Core Changes: - Improve placement for TTM bo's in idle/busy handling. - Improve drm/bridge init ordering. - Add CONFIG_DRM_WERROR, and use W=1 for drm. - Assorted documentation updates. - Make more (drm and driver) headers self-contained and add header guards. - Grab reservation lock in pin/unpin callbacks. - Fix reservation lock handling for vmap. - Add edp and edid panel matching, use it to fix a nearly identical panel. Driver Changes: - Add drm/panthor driver and assorted fixes. - Assorted small fixes to xlnx, panel-edp, tidss, ci, nouveau, panel and bridge drivers. - Add Samsung s6e3fa7, BOE NT116WHM-N44, CMN N116BCA-EA1, CrystalClear CMT430B19N00, Startek KD050HDFIA020-C020A, powertip PH128800T006-ZHC01 panels. - Fix console for omapdrm. The following changes since commit b9511c6d277c31b13d4f3128eba46f4e0733d734: Merge tag 'drm-msm-next-2024-03-07' of https://gitlab.freedesktop.org/drm/msm into drm-next (2024-03-08 12:45:21 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-03-21-1 for you to fetch changes up to 5e842d55bad7794823a50f24fd645b58f2ef93ab: drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't assert (2024-03-20 08:26:18 -0700) drm-misc-next for v6.10: UAPI Changes: - Move some nouveau magic constants to uapi. Cross-subsystem Changes: - Move drm-misc to gitlab and freedesktop hosting. - Add entries for panfrost. Core Changes: - Improve placement for TTM bo's in idle/busy handling. - Improve drm/bridge init ordering. - Add CONFIG_DRM_WERROR, and use W=1 for drm. - Assorted documentation updates. - Make more (drm and driver) headers self-contained and add header guards. - Grab reservation lock in pin/unpin callbacks. - Fix reservation lock handling for vmap. - Add edp and edid panel matching, use it to fix a nearly identical panel. Driver Changes: - Add drm/panthor driver and assorted fixes. - Assorted small fixes to xlnx, panel-edp, tidss, ci, nouveau, panel and bridge drivers. - Add Samsung s6e3fa7, BOE NT116WHM-N44, CMN N116BCA-EA1, CrystalClear CMT430B19N00, Startek KD050HDFIA020-C020A, powertip PH128800T006-ZHC01 panels. - Fix console for omapdrm. Adrián Larumbe (1): drm/panfrost: Replace fdinfo's profiling debugfs knob with sysfs Andrew Halaney (1): drm/tidss: Use dev_err_probe() over dev_dbg() when failing to probe the port Andy Shevchenko (1): drm/gma500: Remove unused intel-mid.h Boris Brezillon (16): drm/panthor: Add uAPI drm/panthor: Add GPU register definitions drm/panthor: Add the device logical block drm/panthor: Add the GPU logical block drm/panthor: Add GEM logical block drm/panthor: Add the devfreq logical block drm/panthor: Add the MMU/VM logical block drm/panthor: Add the FW logical block drm/panthor: Add the heap logical block drm/panthor: Add the scheduler logical block drm/panthor: Add the driver frontend block drm/panthor: Allow driver compilation drm/panthor: Add an entry to MAINTAINERS drm/panthor: Fix panthor_devfreq kerneldoc drm/panthor: Explicitly include mm.h for the {virt, __phys)_to_pfn() defs drm/panthor: Fix undefined panthor_device_suspend/resume symbol issue Christian König (3): drm/ttm: improve idle/busy handling v5 drm/amdgpu: use GTT only as fallback for VRAM|GTT drm/ttm: warn when resv objs are mixed in a bulk_move Dmitry Baryshkov (1): dt-bindings: display/lvds-codec: add ti,sn65lvds94 Douglas Anderson (1): drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't assert Geert Uytterhoeven (1): m68k: pgtable: Add missing #include Hsin-Yi Wang (5): drm_edid: Add a function to get EDID base block drm/edid: Add a function to match EDID with identity drm/edid: Match edid quirks with identity drm/panel-edp: Match edp_panels with panel identity drm/panel-edp: Fix AUO 0x405c panel naming and add a variant Jagan Teki (2): drm/bridge: Fix improper bridge init order with pre_enable_prev_first drm/bridge: Document bridge init order with pre_enable_prev_first Jani Nikula (29): drm: enable (most) W=1 warnings by default across the subsystem drm: Add CONFIG_DRM_WERROR drm/crtc: make drm_crtc_internal.h self-contained drm: add missing header guards to drm_internal.h drm/kunit: fix drm_kunit_helpers.h kernel-doc drm/amdgpu: make amd_asic_type.h self-contained drm: bridge: samsung-dsim: make samsung-dsim.h self-contained
[PATCH v2 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index f8b33999d43f..9021c0c1683d 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -654,6 +654,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -797,14 +808,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ab2f52d21bad..1b56197a1183 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -65,6 +65,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6784,6 +6785,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 860e867586f4..9b7113cd86fc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -721,6 +721,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[PATCH v2 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Changes since previous version: - Call the memset for plane state immediately when scheduling vblank, this prevents a use-after-free in cursor cleanup. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409..ab01c2d15afd 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1176,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 25593f6aae7d..7f935c88726e 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -616,6 +629,24 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && +
[PATCH v2 0/3] drm/i915: Unpin cursor fb only after vblank.
Fix legacy cursor updates on xe by enforcing wait between updating registers and unpin. In comparison with previous version, there was a small bug in the atomic unpin path. In intel_plane_cleanup_fb we tried to deference plane_state after calling vblank schedule. Remove plane from atomic state immediately after scheduling to prevent this issue. It's unsafe to deference plane_state as soon as schedule occured. Maarten Lankhorst (2): drm: Add drm_vblank_work_flush_all(). drm/i915: Use the same vblank worker for atomic unpin Ville Syrjälä (1): drm/i915: Use vblank worker to unpin old legacy cursor fb safely drivers/gpu/drm/drm_vblank_work.c | 22 + .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 31 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 26 ++-- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ drivers/gpu/drm/i915/display/intel_display.c | 3 ++ .../drm/i915/display/intel_display_types.h| 3 ++ include/drm/drm_vblank_work.h | 2 ++ 9 files changed, 102 insertions(+), 3 deletions(-) -- 2.43.0
[PATCH v2 1/3] drm: Add drm_vblank_work_flush_all().
From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..ff86f2b2e052 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
Re: [PATCH 5/5] drm/xe/hdcp: Add intel_hdcp_gsc_message to Makefile
Hey, Where is xe_hdcp_gsc_message.c defined in this series? I would move this part there. On 2024-02-09 11:14, Suraj Kandpal wrote: Add intel_hdcp_gsc_message to Makefile and add corresponding changes to xe_hdcp_gsc.c to make it build. Signed-off-by: Suraj Kandpal --- drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 18 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index c531210695db..2b654c908ff3 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -254,6 +254,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_global_state.o \ i915-display/intel_gmbus.o \ i915-display/intel_hdcp.o \ + i915-display/intel_hdcp_gsc_message.o \ i915-display/intel_hdmi.o \ i915-display/intel_hotplug.o \ i915-display/intel_hotplug_irq.o \ diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c index aa8c13916bb6..f185465d5682 100644 --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c @@ -5,9 +5,11 @@ #include #include +#include #include "abi/gsc_command_header_abi.h" #include "intel_hdcp_gsc.h" +#include "intel_hdcp_gsc_message.h" #include "xe_device_types.h" #include "xe_gt.h" #include "xe_gsc_proxy.h" @@ -113,6 +115,22 @@ static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe) return ret; } +static const struct i915_hdcp_ops gsc_hdcp_ops = { + .initiate_hdcp2_session = intel_hdcp_gsc_initiate_session, + .verify_receiver_cert_prepare_km = + intel_hdcp_gsc_verify_receiver_cert_prepare_km, + .verify_hprime = intel_hdcp_gsc_verify_hprime, + .store_pairing_info = intel_hdcp_gsc_store_pairing_info, + .initiate_locality_check = intel_hdcp_gsc_initiate_locality_check, + .verify_lprime = intel_hdcp_gsc_verify_lprime, + .get_session_key = intel_hdcp_gsc_get_session_key, + .repeater_check_flow_prepare_ack = + intel_hdcp_gsc_repeater_check_flow_prepare_ack, + .verify_mprime = intel_hdcp_gsc_verify_mprime, + .enable_hdcp_authentication = intel_hdcp_gsc_enable_authentication, + .close_hdcp_session = intel_hdcp_gsc_close_session, +}; The changes to xe_hdcp_gsc seems like it should be part of the previous commit? Presumably also useful to reorder the Makefile change to before 4/5. Cheers, Maarten
[CI 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 28 ++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 28 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 76d77d5a0409f..06c5d82624433 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,21 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ + /* +* This branch can only ever be called after plane update is succesful, +* the error path will not cause unpin_work to be set. +*/ + if (old_plane_state->unpin_work.vblank) { + int i = drm_plane_index(old_plane_state->uapi.plane); + + /* +* Remove plane from atomic commit, +* free is done from vblank worker +*/ + memset(>base.planes[i], 0, sizeof(*state->base.planes)); + return; + } + intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1191,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e6..5a897cf6fa021 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 25593f6aae7de..cafe7e86a7feb 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -500,6 +500,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_vblank_evade_init(old_crtc_state, new_crtc_state, ); if (drm_WARN_ON(_priv->drm, drm_crtc_vblank_get(>base))) @@ -616,6 +629,21 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->ua
[CI 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index f8b33999d43fc..9021c0c1683d6 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -654,6 +654,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -797,14 +808,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, intel_psr_unlock(crtc_state); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a92e959c8ac7b..36425889b5bc2 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -64,6 +64,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6780,6 +6781,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ae2e8cff9d691..5fdb9eccab5a6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -713,6 +713,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[CI 1/3] drm: Add drm_vblank_work_flush_all().
From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6fb..ff86f2b2e052e 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4ff..e04d436b72973 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[CI 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 28 ++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 28 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 06c2455bdd788..cb4153ca1867b 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,21 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ + /* +* This branch can only ever be called after plane update is succesful, +* the error path will not cause unpin_work to be set. +*/ + if (old_plane_state->unpin_work.vblank) { + int i = drm_plane_index(old_plane_state->uapi.plane); + + /* +* Remove plane from atomic commit, +* free is done from vblank worker +*/ + memset(>base.planes[i], 0, sizeof(*state->base.planes)); + return; + } + intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1191,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e6..5a897cf6fa021 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 8a84a31c7b48a..13fa7423b029c 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -566,6 +566,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_crtc_vblank_evade_scanlines(state, crtc, , , _start); if (min <= 0 || max <= 0) goto irq_disable; @@ -728,6 +741,21 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->ua
[CI 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 926e2de00eb58..64bdf0eb7943c 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -635,6 +635,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -762,14 +773,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, local_irq_enable(); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b10aad15a63d9..b3d73ded097c4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -64,6 +64,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6771,6 +6772,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3fdd8a5179831..b7faeeb5ddc1c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -713,6 +713,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[CI 1/3] drm: Add drm_vblank_work_flush_all().
From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6fb..ff86f2b2e052e 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4ff..e04d436b72973 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
[[CI] 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 926e2de00eb58..64bdf0eb7943c 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -635,6 +635,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -762,14 +773,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, local_irq_enable(); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b10aad15a63d9..b3d73ded097c4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -64,6 +64,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6771,6 +6772,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3fdd8a5179831..b7faeeb5ddc1c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -713,6 +713,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.43.0
[[CI] 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 28 ++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 28 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 06c2455bdd788..cb4153ca1867b 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,21 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ + /* +* This branch can only ever be called after plane update is succesful, +* the error path will not cause unpin_work to be set. +*/ + if (old_plane_state->unpin_work.vblank) { + int i = drm_plane_index(old_plane_state->uapi.plane); + + /* +* Remove plane from atomic commit, +* free is done from vblank worker +*/ + memset(>base.planes[i], 0, sizeof(*state->base.planes)); + return; + } + intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1191,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e6..5a897cf6fa021 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 8a84a31c7b48a..13fa7423b029c 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -566,6 +566,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_crtc_vblank_evade_scanlines(state, crtc, , , _start); if (min <= 0 || max <= 0) goto irq_disable; @@ -728,6 +741,21 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->ua
[[CI] 1/3] drm: Add drm_vblank_work_flush_all().
From: Maarten Lankhorst In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6fb..ff86f2b2e052e 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4ff..e04d436b72973 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.43.0
Re: [PATCH 4/5] drm/xe/xe2: Limit ccs framebuffers to tile4 only
Hey, On 2024-01-30 20:16, Juha-Pekka Heikkila wrote: On 29.1.2024 14.02, Matthew Auld wrote: On 26/01/2024 21:08, Juha-Pekka Heikkila wrote: Display engine support ccs only with tile4, prevent other modifiers from using compressed memory. Store pin time pat index to xe_bo. Signed-off-by: Juha-Pekka Heikkila --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 722c84a56607..b2930a226f54 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -10,9 +10,18 @@ #include "intel_fb_pin.h" #include "xe_ggtt.h" #include "xe_gt.h" +#include "xe_pat.h" #include +static bool is_compressed(const struct drm_framebuffer *fb) +{ + struct xe_bo *bo = intel_fb_obj(fb); + struct xe_device *xe = to_xe_device(to_intel_framebuffer(fb)->base.dev); + + return xe_pat_index_has_compression(xe, bo->pat_index); +} + static void write_dpt_rotated(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, u32 bo_ofs, u32 width, u32 height, u32 src_stride, u32 dst_stride) @@ -349,12 +358,22 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags) int intel_plane_pin_fb(struct intel_plane_state *plane_state) { struct drm_framebuffer *fb = plane_state->hw.fb; + struct xe_device *xe = to_xe_device(to_intel_framebuffer(fb)->base.dev); struct xe_bo *bo = intel_fb_obj(fb); struct i915_vma *vma; /* We reject creating !SCANOUT fb's, so this is weird.. */ drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_SCANOUT_BIT)); + if (GRAPHICS_VER(xe) >= 20) { + if (fb->modifier != I915_FORMAT_MOD_4_TILED && + is_compressed(fb)) { + drm_warn(>drm, "Cannot create ccs framebuffer with other than tile4 mofifier\n"); + return -EINVAL; + } + bo->pat_index_scanout = bo->pat_index; + } I think this needs to be moved into __xe_pin_fb_vma() after acquiring the object lock. Also not sure what prevents vm_bind appearing after we drop the lock? Do we need to prevent modifications until the end of _xe_unpin_fb_vma()? I did now put in __xe_unpin_fb_vma() .. vma->bo->has_sealed_pat_index = false; .. as well as moved this above block to correct place. I'm pretty sure this will fail if the BO is pinned more than once simultaneously. Should probably be a refcount protected by bo lock instead. Is the harm from allowing this only having a garbled display? If so, we might as well allow it, and avoid complicating the bind code even more. Cheers, ~Maarten
[PULL] drm-misc-fixes
Hi Dave, Daniel, Happy new year! ~Maarten drm-misc-fixes-2024-01-03: drm-misc-fixes for v6.7 final: - 2 small qaic fixes. - Fixes for overflow in aux xfer. - Fix uninitialised gamma lut in gmag200. - Small compiler warning fix for backports of a ps8640 fix. The following changes since commit 6c9dbee84cd005bed5f9d07b3a2797ae6414b435: drm/panel: ltk050h3146w: Set burst mode for ltk050h3148w (2023-12-13 18:33:43 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2024-01-03 for you to fetch changes up to 11f9eb899ecc8c02b769cf8d2532ba12786a7af7: drm/mgag200: Fix gamma lut not initialized for G200ER, G200EV, G200SE (2023-12-20 13:26:57 +0100) drm-misc-fixes for v6.7 final: - 2 small qaic fixes. - Fixes for overflow in aux xfer. - Fix uninitialised gamma lut in gmag200. - Small compiler warning fix for backports of a ps8640 fix. Douglas Anderson (3): drm/bridge: parade-ps8640: Never store more than msg->size bytes in AUX xfer drm/bridge: ti-sn65dsi86: Never store more than msg->size bytes in AUX xfer drm/bridge: ps8640: Fix size mismatch warning w/ len Jeffrey Hugo (1): accel/qaic: Implement quirk for SOC_HW_VERSION Jocelyn Falempe (1): drm/mgag200: Fix gamma lut not initialized for G200ER, G200EV, G200SE Pranjal Ramajor Asha Kanojiya (1): accel/qaic: Fix GEM import path code drivers/accel/qaic/mhi_controller.c | 15 ++- drivers/accel/qaic/qaic_data.c | 6 ++ drivers/gpu/drm/bridge/parade-ps8640.c | 7 --- drivers/gpu/drm/bridge/ti-sn65dsi86.c| 4 +++- drivers/gpu/drm/mgag200/mgag200_drv.h| 5 + drivers/gpu/drm/mgag200/mgag200_g200er.c | 5 + drivers/gpu/drm/mgag200/mgag200_g200ev.c | 5 + drivers/gpu/drm/mgag200/mgag200_g200se.c | 5 + drivers/gpu/drm/mgag200/mgag200_mode.c | 10 +- 9 files changed, 48 insertions(+), 14 deletions(-)
[PULL] drm-misc-fixes
Hi Dave, Daniel, Small fixes all over the place, one regression fix for master capability. Cheers, ~Maarten drm-misc-fixes-2023-12-14: drm-misc-fixes for v6.7-rc6: - Fix regression for checking if FD is master capable. - Fix uninitialized variables in drm/crtc. - Fix ivpu w/a. - Refresh modes correctly when updating EDID. - Small panel fixes. The following changes since commit e0f04e41e8eedd4e5a1275f2318df7e1841855f2: drm/atomic-helpers: Invoke end_fb_access while owning plane state (2023-12-06 10:51:27 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-12-14 for you to fetch changes up to 6c9dbee84cd005bed5f9d07b3a2797ae6414b435: drm/panel: ltk050h3146w: Set burst mode for ltk050h3148w (2023-12-13 18:33:43 +0100) drm-misc-fixes for v6.7-rc6: - Fix regression for checking if FD is master capable. - Fix uninitialized variables in drm/crtc. - Fix ivpu w/a. - Refresh modes correctly when updating EDID. - Small panel fixes. Andrzej Kacprowski (1): accel/ivpu/37xx: Fix interrupt_clear_with_0 WA initialization David Heidelberg (1): dt-bindings: panel-simple-dsi: move LG 5" HD TFT LCD panel into DSI yaml Farouk Bouabid (1): drm/panel: ltk050h3146w: Set burst mode for ltk050h3148w Jani Nikula (2): drm/crtc: fix uninitialized variable use drm/edid: also call add modes in EDID connector update fallback Lingkai Dong (1): drm: Fix FD ownership check in drm_master_check_perm() Ziqi Zhao (1): drm/crtc: Fix uninit-value bug in drm_mode_setcrtc .../devicetree/bindings/display/panel/panel-simple-dsi.yaml | 2 ++ .../devicetree/bindings/display/panel/panel-simple.yaml | 2 -- drivers/accel/ivpu/ivpu_hw_37xx.c| 12 +--- drivers/gpu/drm/drm_auth.c | 2 +- drivers/gpu/drm/drm_crtc.c | 8 drivers/gpu/drm/drm_edid.c | 3 ++- drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c | 2 +- 7 files changed, 19 insertions(+), 12 deletions(-)
[PULL] drm-misc-fixes
Hi Dave, Daniel, Pull request for v6.7-rc5. Cheers, ~Maarten drm-misc-fixes-2023-12-07: drm-misc-fixes for v6.7-rc5: - Document nouveau's GSP-RM. - Flush vmm harder on nouveau tu102. - Panfrost fix for imported dma-buf objects, and device frequency. - Kconfig Build fix for tc358768. - Call end_fb_access after atomic commit. The following changes since commit fb18fe0fdf22a2f4512a8b644bb5ea1473829cda: drm/panel: nt36523: fix return value check in nt36523_probe() (2023-11-29 16:54:23 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-12-07 for you to fetch changes up to e0f04e41e8eedd4e5a1275f2318df7e1841855f2: drm/atomic-helpers: Invoke end_fb_access while owning plane state (2023-12-06 10:51:27 +0100) drm-misc-fixes for v6.7-rc5: - Document nouveau's GSP-RM. - Flush vmm harder on nouveau tu102. - Panfrost fix for imported dma-buf objects, and device frequency. - Kconfig Build fix for tc358768. - Call end_fb_access after atomic commit. Adrián Larumbe (2): drm/panfrost: Consider dma-buf imported objects as resident drm/panfrost: Fix incorrect updating of current device frequency Arnd Bergmann (1): drm/bridge: tc358768: select CONFIG_VIDEOMODE_HELPERS Dave Airlie (1): nouveau/tu102: flush all pdbs on vmm flush Thomas Zimmermann (1): drm/atomic-helpers: Invoke end_fb_access while owning plane state Timur Tabi (1): nouveau/gsp: document some aspects of GSP-RM drivers/gpu/drm/bridge/Kconfig | 1 + drivers/gpu/drm/drm_atomic_helper.c| 78 +--- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c| 2 +- .../common/shared/msgq/inc/msgq/msgq_priv.h| 51 ++ drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 82 ++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c | 2 +- drivers/gpu/drm/panfrost/panfrost_devfreq.c| 17 - drivers/gpu/drm/panfrost/panfrost_gem.c| 2 +- include/drm/drm_atomic_helper.h| 2 + 10 files changed, 207 insertions(+), 32 deletions(-)
[Intel-gfx] [PATCH] drm/i915/display: Use i915_gem_object_get_dma_address to get dma address
Works better for xe like that. obj is no longer const. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index a515ae2831f8..926e2de00eb5 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -24,6 +24,8 @@ #include "intel_psr_regs.h" #include "skl_watermark.h" +#include "gem/i915_gem_object.h" + /* Cursor formats */ static const u32 intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -34,11 +36,11 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state) struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev); const struct drm_framebuffer *fb = plane_state->hw.fb; - const struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_i915_gem_object *obj = intel_fb_obj(fb); u32 base; if (DISPLAY_INFO(dev_priv)->cursor_needs_physical) - base = sg_dma_address(obj->mm.pages->sgl); + base = i915_gem_object_get_dma_address(obj, 0); else base = intel_plane_ggtt_offset(plane_state); -- 2.40.1
[Intel-gfx] [PULL] drm-misc-fixes
Hi Dave, Daniel, This pull request is a bit confusing, as it first adds the panel fixes and a driver/core change, then immediately revert it. Cheers, ~Maarten drm-misc-fixes-2023-11-29: Fixes for v6.7-rc4: - Revert panel fixes as they require exporting device_is_dependent. - Do not double add fences in dma_resv_add_fence. - Fix GPUVM license identifier. - Assorted nouveau fixes. - Fix error check for nt36523. The following changes since commit ab93edb2f94c3c0d5965be3815782472adbe3f52: nouveau/gsp: allocate enough space for all channel ids. (2023-11-21 22:28:01 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-11-29 for you to fetch changes up to fb18fe0fdf22a2f4512a8b644bb5ea1473829cda: drm/panel: nt36523: fix return value check in nt36523_probe() (2023-11-29 16:54:23 +0100) Fixes for v6.7-rc4: - Revert panel fixes as they require exporting device_is_dependent. - Do not double add fences in dma_resv_add_fence. - Fix GPUVM license identifier. - Assorted nouveau fixes. - Fix error check for nt36523. Christian König (1): dma-buf: fix check in dma_resv_add_fence Dan Carpenter (1): nouveau/gsp/r535: remove a stray unlock in r535_gsp_rpc_send() Dave Airlie (1): nouveau: find the smallest page allocation to cover a buffer alloc. Gustavo A. R. Silva (1): nouveau/gsp: replace zero-length array with flex-array member and use __counted_by Linus Walleij (3): Revert "drm/bridge: panel: Check device dependency before managing device link" Revert "driver core: Export device_is_dependent() to modules" Revert "drm/bridge: panel: Add a device link between drm device and panel device" Liu Ying (2): drm/bridge: panel: Check device dependency before managing device link driver core: Export device_is_dependent() to modules Thomas Hellström (1): drm/gpuvm: Fix deprecated license identifier Yang Yingliang (1): drm/panel: nt36523: fix return value check in nt36523_probe() xiazhengqiao (1): drm/panel: starry-2081101qfh032011-53g: Fine tune the panel power sequence drivers/dma-buf/dma-resv.c | 2 +- drivers/gpu/drm/bridge/panel.c | 17 - drivers/gpu/drm/drm_gpuvm.c | 2 +- .../nvrm/535.113.01/nvidia/generated/g_os_nvoc.h| 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c| 5 +++-- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 6 ++ drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 1 + drivers/gpu/drm/panel/panel-novatek-nt36523.c | 4 ++-- include/drm/drm_gpuvm.h | 2 +- include/linux/dma-fence.h | 15 +++ 10 files changed, 27 insertions(+), 29 deletions(-)
[Intel-gfx] [PATCH 1/3] drm: Add drm_vblank_work_flush_all().
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 43cd5c0f4f6f..ff86f2b2e052 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.40.1
[Intel-gfx] [PATCH 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 26 +-- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../drm/i915/display/intel_display_types.h| 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index a515ae2831f8..e38ea7311047 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -633,6 +633,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -760,14 +771,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, local_irq_enable(); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->ggtt_vma != new_plane_state->ggtt_vma) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5cf162628b95..930fb471a870 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -64,6 +64,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6752,6 +6753,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) continue; intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b3e942f2eeb0..22ec3b42ceca 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -715,6 +715,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.40.1
[Intel-gfx] [PATCH 3/3] drm/i915: Use the same vblank worker for atomic unpin
In case of legacy cursor update, the cursor VMA needs to be unpinned only after vblank. This exceeds the lifetime of the whole atomic commit. Any trick I attempted to keep the atomic commit alive didn't work, as drm_atomic_helper_setup_commit() force throttles on any old commit that wasn't cleaned up. The only option remaining is to remove the plane from the atomic commit, and use the same path as the legacy cursor update to clean the state after vblank. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 28 ++- .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 28 +++ drivers/gpu/drm/i915/display/intel_cursor.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.h | 3 ++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 06c2455bdd78..cb4153ca1867 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -42,6 +42,7 @@ #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" +#include "intel_cursor.h" #include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -1163,7 +1164,21 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); - /* Should only be called after a successful intel_prepare_plane_fb()! */ + /* +* This branch can only ever be called after plane update is succesful, +* the error path will not cause unpin_work to be set. +*/ + if (old_plane_state->unpin_work.vblank) { + int i = drm_plane_index(old_plane_state->uapi.plane); + + /* +* Remove plane from atomic commit, +* free is done from vblank worker +*/ + memset(>base.planes[i], 0, sizeof(*state->base.planes)); + return; + } + intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1191,14 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_cursor_unpin_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 1fd068e6e26c..755c40fd0ac1 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -559,6 +559,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_crtc_vblank_evade_scanlines(state, crtc, , , _start); if (min <= 0 || max <= 0) goto irq_disable; @@ -721,6 +734,21 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->ua
[Intel-gfx] [PULL] drm-misc-fixes
Hi Dave, Daniel, Lots of small fixes for various drivers. Cheers, ~Maarten drm-misc-fixes-2023-11-23: Fixes for v6.7-rc3: - Panel fixes for innolux and auo,b101uan08.3 panel. - Fix ivpu MMIO reset. - AST fix on connetor disconnection. - nouveau gsp fix. - rockchip color fix. - Fix Himax83102-j02 timings. The following changes since commit ae1aadb1eb8d3cbc52e42bee71d67bd4a71f9f07: nouveau: don't fail driver load if no display hw present. (2023-11-15 18:23:31 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-11-23 for you to fetch changes up to ab93edb2f94c3c0d5965be3815782472adbe3f52: nouveau/gsp: allocate enough space for all channel ids. (2023-11-21 22:28:01 +0100) Fixes for v6.7-rc3: - Panel fixes for innolux and auo,b101uan08.3 panel. - Fix ivpu MMIO reset. - AST fix on connetor disconnection. - nouveau gsp fix. - rockchip color fix. - Fix Himax83102-j02 timings. Cong Yang (1): drm/panel: boe-tv101wum-nl6: Fine tune Himax83102-j02 panel HFP and HBP Dave Airlie (1): nouveau/gsp: allocate enough space for all channel ids. Jacek Lawrynowicz (1): accel/ivpu/37xx: Fix hangs related to MMIO reset Jonas Karlman (1): drm/rockchip: vop: Fix color for RGB888/BGR888 format on VOP full Marek Vasut (2): drm/panel: simple: Fix Innolux G101ICE-L01 bus flags drm/panel: simple: Fix Innolux G101ICE-L01 timings Thomas Zimmermann (1): drm/ast: Disconnect BMC if physical connector is connected Xuxin Xiong (1): drm/panel: auo,b101uan08.3: Fine tune the panel power sequence drivers/accel/ivpu/ivpu_hw_37xx.c | 46 +- drivers/gpu/drm/ast/ast_drv.h | 13 +- drivers/gpu/drm/ast/ast_mode.c | 62 ++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c | 2 +- drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 9 ++-- drivers/gpu/drm/panel/panel-simple.c| 13 +++--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 14 -- 7 files changed, 113 insertions(+), 46 deletions(-)
Re: [Intel-gfx] [PATCH v3 02/11] drm/dp_mst: Fix PBN divider calculation for UHBR rates
On 2023-11-17 20:40, Rodrigo Vivi wrote: On Fri, Nov 17, 2023 at 06:21:07PM +0200, Ville Syrjälä wrote: On Fri, Nov 17, 2023 at 05:09:27PM +0200, Imre Deak wrote: The current way of calculating the pbn_div value, the link BW per each MTP slot, worked only for DP 1.4 link rates. Fix things up for UHBR rates calculating with the correct channel coding efficiency based on the link rate. v2: - Return the fractional pbn_div value from drm_dp_get_vc_payload_bw(). v3: - Fix rounding up quotient while calculating req_slots. (Ville) Cc: Ville Syrjälä Cc: Lyude Paul Cc: dri-de...@lists.freedesktop.org Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Dave, Sima, it looks like this whole series is ready for getting merged: https://patchwork.freedesktop.org/series/126526/ But it has these 3 drm/dp_mst here. Ack to merge them through drm-intel? Well, as drm-misc maintainer: Acked-by: Maarten Lankhorst --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 10 +++--- include/drm/display/drm_dp_helper.h | 13 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 000d05e80352a..8ca01a6bf645d 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3585,14 +3585,18 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, fixed20_12 drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr, int link_rate, int link_lane_count) { + int ch_coding_efficiency = + drm_dp_bw_channel_coding_efficiency(drm_dp_is_uhbr_rate(link_rate)); fixed20_12 ret; if (link_rate == 0 || link_lane_count == 0) drm_dbg_kms(mgr->dev, "invalid link rate/lane count: (%d / %d)\n", link_rate, link_lane_count); - /* See DP v2.0 2.6.4.2, VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */ - ret.full = dfixed_const(link_rate * link_lane_count / 54000); + /* See DP v2.0 2.6.4.2, 2.7.6.3 VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */ + ret.full = DIV_ROUND_DOWN_ULL(mul_u32_u32(link_rate * link_lane_count, + ch_coding_efficiency), + (100ULL * 8 * 5400) >> 12); return ret; } @@ -4342,7 +4346,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, } } - req_slots = DIV_ROUND_UP(pbn, dfixed_trunc(topology_state->pbn_div)); + req_slots = DIV_ROUND_UP(dfixed_const(pbn), topology_state->pbn_div.full); drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] TU %d -> %d\n", port->connector->base.id, port->connector->name, diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index c5f1079acb3b1..863b2e7add29e 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -252,6 +252,19 @@ drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]) return !!(edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP); } +/** + * drm_dp_is_uhbr_rate - Determine if a link rate is UHBR + * @link_rate: link rate in 10kbits/s units + * + * Determine if the provided link rate is an UHBR rate. + * + * Returns: %True if @link_rate is an UHBR rate. + */ +static inline bool drm_dp_is_uhbr_rate(int link_rate) +{ + return link_rate >= 100; +} + /* * DisplayPort AUX channel */ -- 2.39.2 -- Ville Syrjälä Intel
[Intel-gfx] [PULL] drm-misc-fixes
Hi Dave, Daniel, Small pull request, mostly nouveau fixes. Cheers, ~Maarten Mostly drm-misc-fixes-2023-11-16: Assorted fixes for v6.7-rc2: - Nouveau GSP fixes. - Fix nouveau driver load without display. - Use rwlock for nouveau's event lock to break a lockdep splat. - Add orientation quirk for Lenovo Legion Go. - Fix build failure in IVPU. The following changes since commit b85ea95d086471afb4ad062012a4d73cd328fa86: Linux 6.7-rc1 (2023-11-12 16:19:07 -0800) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-11-16 for you to fetch changes up to ae1aadb1eb8d3cbc52e42bee71d67bd4a71f9f07: nouveau: don't fail driver load if no display hw present. (2023-11-15 18:23:31 +0100) Assorted fixes for v6.7-rc2: - Nouveau GSP fixes. - Fix nouveau driver load without display. - Use rwlock for nouveau's event lock to break a lockdep splat. - Add orientation quirk for Lenovo Legion Go. - Fix build failure in IVPU. Arnd Bergmann (1): accel/ivpu: avoid build failure with CONFIG_PM=n Brenton Simpson (1): drm: panel-orientation-quirks: Add quirk for Lenovo Legion Go Dan Carpenter (2): nouveau/gsp/r535: uninitialized variable in r535_gsp_acpi_mux_id() nouveau/gsp/r535: Fix a NULL vs error pointer bug Dave Airlie (2): nouveau: use an rwlock for the event lock. nouveau: don't fail driver load if no display hw present. drivers/accel/ivpu/ivpu_pm.c | 3 --- drivers/gpu/drm/drm_panel_orientation_quirks.c| 6 ++ drivers/gpu/drm/nouveau/include/nvkm/core/event.h | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.c | 5 + drivers/gpu/drm/nouveau/nvkm/core/event.c | 12 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c| 6 +++--- 6 files changed, 22 insertions(+), 14 deletions(-)
[Intel-gfx] [PATCH] ALSA: hda: i915: Alays handle -EPROBE_DEFER
It turns out that even if the comment says that the driver can load fine, it's not really the case and no codecs are detected. Specifically for -EPROBE_DEFER, always fail the probe. This fixes a regression when HDA-intel is loaded before i915. Reported-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst Tested-by: Kai Vehmanen Fixes: e6d0c13e9f46 ("ALSA: hda: i915: Remove extra argument from snd_hdac_i915_init") Cc: Takashi Iwai --- Using Takashi's version, as I like the separate -EPROBE_DEFER if more. --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 058f6e6491f9..8e9a003daa8d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2140,6 +2140,9 @@ static int azx_probe(struct pci_dev *pci, if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT) { err = snd_hdac_i915_init(azx_bus(chip)); if (err < 0) { + if (err == -EPROBE_DEFER) + goto out_free; + /* if the controller is bound only with HDMI/DP * (for HSW and BDW), we need to abort the probe; * for other chips, still continue probing as other -- 2.40.1
Re: [Intel-gfx] [Intel-xe] [PATCH 11/14] ALSA: hda/intel: Move snd_hdac_i915_init to before probe_work.
Hey, Den 2023-11-14 kl. 16:50, skrev Takashi Iwai: On Tue, 14 Nov 2023 15:39:16 +0100, Maarten Lankhorst wrote: Hey, Den 2023-11-14 kl. 14:39, skrev Ville Syrjälä: On Tue, Nov 14, 2023 at 02:35:10PM +0200, Jani Nikula wrote: On Tue, 14 Nov 2023, Ville Syrjälä wrote: On Mon, Oct 02, 2023 at 09:38:44PM +0200, maarten.lankho...@linux.intel.com wrote: From: Maarten Lankhorst Now that we can use -EPROBE_DEFER, it's no longer required to spin off the snd_hdac_i915_init into a workqueue. Use the -EPROBE_DEFER mechanism instead, which must be returned in the probe function. This completely broke i915 audio! I also can't see any trace of this stuff ever being posted to intel-gfx so it never went through the CI. Please fix or revert ASAP. Cc: Jani, Suresh Ville, please file a bug at gitlab so we can track this, thanks. https://gitlab.freedesktop.org/drm/intel/-/issues/9671 Looks like a simple patch should be enough, can you test below? Seems that we reached to the same conclusion :) I took a quick look at other code paths, and sound/pci/hda/hda_intel.c is the only place that needs the correction. Other (ASoC) drivers are either simply always returning the error or dealing only with -ENODEV case for skipping the HDMI codec. Yeah, the original comment in the code confused me and led me to not handle -EPROBE_DEFER in the first place there. Cheers, Maarten thanks, Takashi diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 058f6e6491f9a..946aaa487f200 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2145,7 +2145,8 @@ static int azx_probe(struct pci_dev *pci, * for other chips, still continue probing as other * codecs can be on the same link. */ - if (HDA_CONTROLLER_IN_GPU(pci)) { + if (HDA_CONTROLLER_IN_GPU(pci) || + err == -EPROBE_DEFER) { goto out_free; } else { /* don't bother any longer */
Re: [Intel-gfx] [Intel-xe] [PATCH 11/14] ALSA: hda/intel: Move snd_hdac_i915_init to before probe_work.
Hey, Den 2023-11-14 kl. 14:39, skrev Ville Syrjälä: On Tue, Nov 14, 2023 at 02:35:10PM +0200, Jani Nikula wrote: On Tue, 14 Nov 2023, Ville Syrjälä wrote: On Mon, Oct 02, 2023 at 09:38:44PM +0200,maarten.lankho...@linux.intel.com wrote: From: Maarten Lankhorst Now that we can use -EPROBE_DEFER, it's no longer required to spin off the snd_hdac_i915_init into a workqueue. Use the -EPROBE_DEFER mechanism instead, which must be returned in the probe function. This completely broke i915 audio! I also can't see any trace of this stuff ever being posted to intel-gfx so it never went through the CI. Please fix or revert ASAP. Cc: Jani, Suresh Ville, please file a bug at gitlab so we can track this, thanks. https://gitlab.freedesktop.org/drm/intel/-/issues/9671 Looks like a simple patch should be enough, can you test below? diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 058f6e6491f9a..946aaa487f200 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2145,7 +2145,8 @@ static int azx_probe(struct pci_dev *pci, * for other chips, still continue probing as other * codecs can be on the same link. */ - if (HDA_CONTROLLER_IN_GPU(pci)) { + if (HDA_CONTROLLER_IN_GPU(pci) || + err == -EPROBE_DEFER) { goto out_free; } else { /* don't bother any longer */
Re: [Intel-gfx] [Intel-xe] [PATCH 11/14] ALSA: hda/intel: Move snd_hdac_i915_init to before probe_work.
Hey, Den 2023-11-14 kl. 13:35, skrev Jani Nikula: On Tue, 14 Nov 2023, Ville Syrjälä wrote: On Mon, Oct 02, 2023 at 09:38:44PM +0200, maarten.lankho...@linux.intel.com wrote: From: Maarten Lankhorst Now that we can use -EPROBE_DEFER, it's no longer required to spin off the snd_hdac_i915_init into a workqueue. Use the -EPROBE_DEFER mechanism instead, which must be returned in the probe function. This completely broke i915 audio! I also can't see any trace of this stuff ever being posted to intel-gfx so it never went through the CI. Please fix or revert ASAP. Cc: Jani, Suresh Ville, please file a bug at gitlab so we can track this, thanks. I've originally tested this on TGL and DG2, so can you be more specific on what broke? Cheers, ~Maarten Signed-off-by: Maarten Lankhorst Reviewed-by: Kai Vehmanen Reviewed-by: Pierre-Louis Bossart Signed-off-by: Maarten Lankhorst --- sound/pci/hda/hda_intel.c | 54 +++ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e42ad0e816e1..9dad3607596a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2135,6 +2135,33 @@ static int azx_probe(struct pci_dev *pci, pci_set_drvdata(pci, card); +#ifdef CONFIG_SND_HDA_I915 + /* bind with i915 if needed */ + if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT) { + err = snd_hdac_i915_init(azx_bus(chip), false); + if (err < 0) { + /* if the controller is bound only with HDMI/DP +* (for HSW and BDW), we need to abort the probe; +* for other chips, still continue probing as other +* codecs can be on the same link. +*/ + if (HDA_CONTROLLER_IN_GPU(pci)) { + goto out_free; + } else { + /* don't bother any longer */ + chip->driver_caps &= ~AZX_DCAPS_I915_COMPONENT; + } + } + + /* HSW/BDW controllers need this power */ + if (HDA_CONTROLLER_IN_GPU(pci)) + hda->need_i915_power = true; + } +#else + if (HDA_CONTROLLER_IN_GPU(pci)) + dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n"); +#endif + err = register_vga_switcheroo(chip); if (err < 0) { dev_err(card->dev, "Error registering vga_switcheroo client\n"); @@ -2162,11 +2189,6 @@ static int azx_probe(struct pci_dev *pci, } #endif /* CONFIG_SND_HDA_PATCH_LOADER */ -#ifndef CONFIG_SND_HDA_I915 - if (HDA_CONTROLLER_IN_GPU(pci)) - dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n"); -#endif - if (schedule_probe) schedule_delayed_work(>probe_work, 0); @@ -2264,28 +2286,6 @@ static int azx_probe_continue(struct azx *chip) to_hda_bus(bus)->bus_probing = 1; hda->probe_continued = 1; - /* bind with i915 if needed */ - if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT) { - err = snd_hdac_i915_init(bus, true); - if (err < 0) { - /* if the controller is bound only with HDMI/DP -* (for HSW and BDW), we need to abort the probe; -* for other chips, still continue probing as other -* codecs can be on the same link. -*/ - if (HDA_CONTROLLER_IN_GPU(pci)) { - goto out_free; - } else { - /* don't bother any longer */ - chip->driver_caps &= ~AZX_DCAPS_I915_COMPONENT; - } - } - - /* HSW/BDW controllers need this power */ - if (HDA_CONTROLLER_IN_GPU(pci)) - hda->need_i915_power = true; - } - /* Request display power well for the HDA controller or codec. For * Haswell/Broadwell, both the display HDA controller and codec need * this power. For other platforms, like Baytrail/Braswell, only the -- 2.40.1
[Intel-gfx] [PATCH 1/3] drm: Add drm_vblank_work_flush_all().
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_vblank_work.c | 22 ++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index bd481fdd6b870..27c8646a79c8e 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -229,6 +229,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = >vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(>event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + waitqueue_active(>work_wait_queue), + dev->event_lock); + spin_unlock_irq(>event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4ff..e04d436b72973 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- 2.39.2
[Intel-gfx] [PATCH 2/3] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. This patch is slightly reworked by Maarten Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 37 --- drivers/gpu/drm/i915/display/intel_display.c | 3 ++ .../drm/i915/display/intel_display_types.h| 3 ++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index b342fad180ca5..1728ecd5cc782 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -603,6 +603,17 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(>base, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -688,9 +699,14 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); - if (ret) - goto out_free; + if (new_plane_state->uapi.fb != old_plane_state->uapi.fb) { + ret = intel_plane_pin_fb(new_plane_state); + if (ret) + goto out_free; + } else { + /* magic trick */ + swap(new_plane_state->ggtt_vma, old_plane_state->ggtt_vma); + } intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb), ORIGIN_CURSOR_UPDATE); @@ -730,14 +746,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, local_irq_enable(); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->uapi.fb != new_plane_state->uapi.fb) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } out_free: if (new_crtc_state) intel_crtc_destroy_state(>base, _crtc_state->uapi); if (ret) intel_plane_destroy_state(>base, _plane_state->uapi); - else + else if (old_plane_state) intel_plane_destroy_state(>base, _plane_state->uapi); return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3effafcbb411a..9b43810f9a934 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -64,6 +64,7 @@ #include "intel_crt.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" +#include "intel_cursor.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -6883,6 +6884,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) intel_pre_plane_update(state, crtc); intel_crtc_disable_planes(state, crtc); + + drm_vblank_work_flush_all(>base); } /* Only disable port sync and MST slaves */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 926bf9c1a3ede..6d27cfb4f08e7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -709,6 +709,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* for legacy cursor fb unpin */ + struct drm_vblank_work unpin_work; + /* Plane pxp decryption state */ bool decrypt; -- 2.39.2
[Intel-gfx] [PATCH 3/3] drm/i915: Use a different vblank worker for atomic unpin
For the atomic codepath we unpin_work in old_plane_state to unpin the old fb. As this happened after swapping state, this is allowed. Use the unpin_work only as a barrier, and keep doing the actual unpinning in the atomic path. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 18 .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 28 +++ 3 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 06c2455bdd788..6ddb4f4ec79ac 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1164,6 +1164,9 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); /* Should only be called after a successful intel_prepare_plane_fb()! */ + if (old_plane_state->unpin_work.vblank) + drm_vblank_work_flush(_plane_state->unpin_work); + intel_plane_unpin_fb(old_plane_state); } @@ -1176,3 +1179,18 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +/* Completion is enough */ +static void intel_plane_cursor_vblank_work(struct kthread_work *base) +{ } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_plane_cursor_vblank_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e6..5a897cf6fa021 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 1fd068e6e26ca..755c40fd0ac13 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -559,6 +559,19 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_crtc_vblank_evade_scanlines(state, crtc, , , _start); if (min <= 0 || max <= 0) goto irq_disable; @@ -721,6 +734,21 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && + old_plane_state->unpin_work.vblank) { + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + } + } + } + /* * Send VRR Push to terminate Vblank. If we are already in vblank * this has to be done _after_ sampling the frame counter, as -- 2.39.2
[Intel-gfx] [PULL] drm-misc-fixes
Hi Dave, Daniel, drm-misc-next-fixes is empty, have a pull request for drm-misc-fixes. Cheers, ~Maarten drm-misc-fixes-2023-11-08: drm-misc-fixes for v6.7-rc1: - drm-misc-fixes from 2023-11-02 + a single qxl memory leak fix. The following changes since commit 8f5ad367e8b884772945c6c9fb622ac94b7d3e32: accel/ivpu: Extend address range for MMU mmap (2023-10-19 08:01:20 +0200) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-fixes-2023-11-08 for you to fetch changes up to 0e8b9f258baed25f1c5672613699247c76b007b5: drm/qxl: prevent memory leak (2023-11-06 09:37:03 +0100) drm-misc-fixes for v6.7-rc1: - drm-misc-fixes from 2023-11-02 + a single qxl memory leak fix. Christian König (2): drm/amdgpu: ignore duplicate BOs again drm/amdkfd: reserve a fence slot while locking the BO Erik Kurzinger (1): drm/syncobj: fix DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE Karol Wachowski (1): accel/ivpu/37xx: Fix missing VPUIP interrupts Luben Tuikov (1): drm/amdgpu: Remove redundant call to priority_is_valid() Lukasz Majczak (1): drm/dp_mst: Fix NULL deref in get_mst_branch_device_by_guid_helper() Maxime Ripard (1): drm/vc4: tests: Fix UAF in the mock helpers Sui Jingfeng (1): drm/logicvc: Kconfig: select REGMAP and REGMAP_MMIO Zongmin Zhou (1): drm/qxl: prevent memory leak drivers/accel/ivpu/ivpu_hw_37xx.c| 11 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 15 --- drivers/gpu/drm/display/drm_dp_mst_topology.c| 6 +++--- drivers/gpu/drm/drm_syncobj.c| 3 ++- drivers/gpu/drm/logicvc/Kconfig | 2 ++ drivers/gpu/drm/qxl/qxl_display.c| 3 +++ drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c| 2 +- drivers/gpu/drm/vc4/tests/vc4_mock_output.c | 2 +- 10 files changed, 28 insertions(+), 21 deletions(-)
[Intel-gfx] [PATCH] drm/i915: Use drm_atomic_helper_wait_for_fences helper.
From: Maarten Lankhorst The fence api specifies you should wait for fence to completion, not give up after whatever timeout was originally configured. The fences themselves should prevent the timeout from being indefinite. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 1 - drivers/gpu/drm/i915/display/intel_display.c | 23 +-- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 6b3851d77b6d..ef553270c079 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -38,7 +38,6 @@ #include #include -#include "i915_config.h" #include "i915_reg.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 67cfc0eb1af5..28992f368b38 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -48,7 +48,6 @@ #include "g4x_dp.h" #include "g4x_hdmi.h" #include "hsw_ips.h" -#include "i915_config.h" #include "i915_drv.h" #include "i915_reg.h" #include "i915_utils.h" @@ -7053,26 +7052,6 @@ void intel_atomic_helper_free_state_worker(struct work_struct *work) intel_atomic_helper_free_state(dev_priv); } -static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state) -{ - struct drm_i915_private *i915 = to_i915(intel_state->base.dev); - struct drm_plane *plane; - struct drm_plane_state *new_plane_state; - int ret, i; - - for_each_new_plane_in_state(_state->base, plane, new_plane_state, i) { - if (new_plane_state->fence) { - ret = dma_fence_wait_timeout(new_plane_state->fence, false, -i915_fence_timeout(i915)); - if (ret <= 0) - break; - - dma_fence_put(new_plane_state->fence); - new_plane_state->fence = NULL; - } - } -} - static void intel_atomic_cleanup_work(struct work_struct *work) { struct intel_atomic_state *state = @@ -7145,7 +7124,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_wakeref_t wakeref = 0; int i; - intel_atomic_commit_fence_wait(state); + drm_atomic_helper_wait_for_fences(dev, >base, false); drm_atomic_helper_wait_for_dependencies(>base); drm_dp_mst_atomic_wait_for_dependencies(>base); -- 2.40.1
[Intel-gfx] [PULL] drm-misc-next-fixes
Hi Daniel, Dave, Just 2 small ssd130x fixes. Cheers, ~Maarten drm-misc-next-fixes-2023-11-02: drm-misc-next-fixes for v6.7-rc1: - dt binding fix for ssd132x - Initialize ssd130x crtc_state to NULL. The following changes since commit b70438004a14f4d0f9890b3297cd66248728546c: drm/amdgpu: move buffer funcs setting up a level (2023-10-26 16:04:24 -0400) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-fixes-2023-11-02 for you to fetch changes up to 94565e95e247c188fed4d3da1034402f3fb297de: drm/ssd130x: Fix possible uninitialized usage of crtc_state variable (2023-10-30 11:00:27 +0100) drm-misc-next-fixes for v6.7-rc1: - dt binding fix for ssd132x - Initialize ssd130x crtc_state to NULL. Javier Martinez Canillas (2): dt-bindings: display: ssd132x: Remove '-' before compatible enum drm/ssd130x: Fix possible uninitialized usage of crtc_state variable Documentation/devicetree/bindings/display/solomon,ssd132x.yaml | 8 drivers/gpu/drm/solomon/ssd130x.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
[Intel-gfx] [PULL] drm-misc-next
drm-misc-next-2023-10-27: drm-misc-next for v6.7-rc1: drm-misc-next-2023-10-19 + following: UAPI Changes: Cross-subsystem Changes: - Convert fbdev drivers to use fbdev i/o mem helpers. Core Changes: - Use cross-references for macros in docs. - Make drm_client_buffer_addb use addfb2. - Add NV20 and NV30 YUV formats. - Documentation updates for create_dumb ioctl. - CI fixes. - Allow variable number of run-queues in scheduler. Driver Changes: - Rename drm/ast constants. - Make ili9882t its own driver. - Assorted fixes in ivpu, vc4, bridge/synopsis, amdgpu. - Add planar formats to rockchip. The following changes since commit c395c83aafbb9cdbe4230f044d5b8eaf9080c0c5: drm/simpledrm: Fix power domain device link validity check (2023-10-12 10:39:48 +0200) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2023-10-27 for you to fetch changes up to b70438004a14f4d0f9890b3297cd66248728546c: drm/amdgpu: move buffer funcs setting up a level (2023-10-26 16:04:24 -0400) drm-misc-next for v6.7-rc1: drm-misc-next-2023-10-19 + following: UAPI Changes: Cross-subsystem Changes: - Convert fbdev drivers to use fbdev i/o mem helpers. Core Changes: - Use cross-references for macros in docs. - Make drm_client_buffer_addb use addfb2. - Add NV20 and NV30 YUV formats. - Documentation updates for create_dumb ioctl. - CI fixes. - Allow variable number of run-queues in scheduler. Driver Changes: - Rename drm/ast constants. - Make ili9882t its own driver. - Assorted fixes in ivpu, vc4, bridge/synopsis, amdgpu. - Add planar formats to rockchip. Alex Deucher (1): drm/amdgpu: move buffer funcs setting up a level Andy Yan (6): drm/rockchip: remove unused struct in vop2 drm/rockchip: remove NR_LAYERS macro on vop2 drm/rockchip: vop: fix format bpp calculation drm/rockchip: vop2: remove the unsupported format of cluster window drm/rockchip: vop2: Add more supported 10bit formats drm/rockchip: vop2: rename window formats to show window type using them Biju Das (8): drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data() drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info drm: adv7511: Add has_dsi variable to struct adv7511_chip_info drm: adv7511: Add link_config variable to struct adv7511_chip_info drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info Chris Morgan (3): dt-bindings: vendor-prefixes: document Powkiddy dt-bindings: panel: Add Powkiddy RGB30 panel compatible drm/panel: st7703: Add Powkiddy RGB30 Panel Support Cong Yang (3): drm/panel: ili9882t: Break out as separate driver drm/panel: ili9882t: Avoid blurred screen from fast sleep arm64: defconfig: Enable ILITEK_ILI9882T panel Dan Carpenter (1): drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map() Dario Binacchi (1): drm/vc4: fix typo Deepak R Varma (1): accel/ivpu: Delete the TODO file Dmitry Baryshkov (3): drm/bridge: lt9611uxc: fix the race in the error path drm/ci: pick up -external-fixes from the merge target repo drm/ci: force-enable CONFIG_MSM_MMCC_8996 as built-in Frank Oltmanns (1): drm/panel: st7703: Fix timings when entering/exiting sleep Geert Uytterhoeven (1): drm/client: Convert drm_client_buffer_addfb() to drm_mode_addfb2() Helen Koike (11): drm/ci: uprev mesa version: fix container build & crosvm drm/ci: fix DEBIAN_ARCH and get amdgpu probing drm/ci: add helper script update-xfails.py drm/ci: uprev IGT and make sure core_getversion is run drm/ci: clean up xfails (specially flakes list) drm/ci: add subset-1-gfx to LAVA_TAGS and adjust shards drm/ci: increase i915 job timeout to 1h30m drm/ci: export kernel config drm/ci: do not automatically retry on error drm/ci: docs: add step about how to request privileges MAINTAINERS: drm/ci: add entries for xfail files Ian Ray (2): drm/bridge: megachips-stdp-ge-b850v3-fw: switch to drm_do_get_edid() MAINTAINERS: Update entry for megachips-stdp-ge-b850v3-fw Jacek Lawrynowicz (1): accel/ivpu: Add ivpu_bo_vaddr() and ivpu_bo_size() Javier Martinez Canillas (6): drm/ssd130x: Replace .page_height field in device info with a constant drm/ssd130x: Add a controller family id to the device info data drm/ssd130x: Rename commands that are shared across chip families drm/ssd130x: Add support for the SSD132x OLED controller family
[Intel-gfx] [PULL] drm-misc-next
drm-misc-next-2023-10-19: drm-misc-next for v6.7-rc1: UAPI Changes: Cross-subsystem Changes: - Update maintainers entry for megachips STDPx-GE-B850V3-FW. Core Changes: - Add VM_BIND async document. - Dual-license drm_gpuvm to GPL-2.0 OR MIT. Driver Changes: - Assorted small fixes in ivpu, bridge/megachips, ssd130x, st7703, bridge/lt9611uxc, rockchip. - Handle differences between various adv7511 chips better, and improve HPD handling. - Clock fixes for bridge/synopsis dw-mipi-dsi. - Add Powkiddy RGB30 support to st7703. - Add driver and DT support for ssd132x OLED controller to ssd130x. The following changes since commit c395c83aafbb9cdbe4230f044d5b8eaf9080c0c5: drm/simpledrm: Fix power domain device link validity check (2023-10-12 10:39:48 +0200) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2023-10-19 for you to fetch changes up to 2d23e7d6bacb779c4a740dbd5e18978fb075d15e: dt-bindings: display: Add SSD132x OLED controllers (2023-10-18 09:53:33 +0200) drm-misc-next for v6.7-rc1: UAPI Changes: Cross-subsystem Changes: - Update maintainers entry for megachips STDPx-GE-B850V3-FW. Core Changes: - Add VM_BIND async document. - Dual-license drm_gpuvm to GPL-2.0 OR MIT. Driver Changes: - Assorted small fixes in ivpu, bridge/megachips, ssd130x, st7703, bridge/lt9611uxc, rockchip. - Handle differences between various adv7511 chips better, and improve HPD handling. - Clock fixes for bridge/synopsis dw-mipi-dsi. - Add Powkiddy RGB30 support to st7703. - Add driver and DT support for ssd132x OLED controller to ssd130x. Andy Yan (2): drm/rockchip: remove unused struct in vop2 drm/rockchip: remove NR_LAYERS macro on vop2 Biju Das (8): drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data() drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info drm: adv7511: Add has_dsi variable to struct adv7511_chip_info drm: adv7511: Add link_config variable to struct adv7511_chip_info drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info Chris Morgan (3): dt-bindings: vendor-prefixes: document Powkiddy dt-bindings: panel: Add Powkiddy RGB30 panel compatible drm/panel: st7703: Add Powkiddy RGB30 Panel Support Dan Carpenter (1): drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map() Dmitry Baryshkov (1): drm/bridge: lt9611uxc: fix the race in the error path Frank Oltmanns (1): drm/panel: st7703: Fix timings when entering/exiting sleep Ian Ray (2): drm/bridge: megachips-stdp-ge-b850v3-fw: switch to drm_do_get_edid() MAINTAINERS: Update entry for megachips-stdp-ge-b850v3-fw Jacek Lawrynowicz (1): accel/ivpu: Add ivpu_bo_vaddr() and ivpu_bo_size() Javier Martinez Canillas (6): drm/ssd130x: Replace .page_height field in device info with a constant drm/ssd130x: Add a controller family id to the device info data drm/ssd130x: Rename commands that are shared across chip families drm/ssd130x: Add support for the SSD132x OLED controller family dt-bindings: display: Split common Solomon properties in their own schema dt-bindings: display: Add SSD132x OLED controllers Liu Ying (9): drm/bridge: synopsys: dw-mipi-dsi: Add dw_mipi_dsi_get_bridge() helper drm/bridge: synopsys: dw-mipi-dsi: Add input bus format negotiation support drm/bridge: synopsys: dw-mipi-dsi: Force input bus flags drm/bridge: synopsys: dw-mipi-dsi: Add mode fixup support drm/bridge: synopsys: dw-mipi-dsi: Use pixel clock rate to calculate lbcc drm/bridge: synopsys: dw-mipi-dsi: Set minimum lane byte clock cycles for HSA and HBP drm/bridge: synopsys: dw-mipi-dsi: Disable HSTX and LPRX timeout check dt-bindings: display: bridge: Document Freescale i.MX93 MIPI DSI drm/bridge: imx: Add i.MX93 MIPI DSI support Ondrej Jirman (1): drm/panel: st7703: Pick different reset sequence Thomas Hellström (2): Documentation/gpu: Add a VM_BIND async document drm/gpuvm: Dual-licence the drm_gpuvm code GPL-2.0 OR MIT Thomas Zimmermann (1): drm/ssd130x: Fix atomic_check for disabled planes .../display/bridge/fsl,imx93-mipi-dsi.yaml | 115 +++ .../display/panel/rocktech,jh057n00900.yaml| 2 + .../bindings/display/solomon,ssd-common.yaml | 42 + .../bindings/display/solomon,ssd1307fb.yaml| 28 +- .../bindings/display/solomon,ssd132x.yaml | 89 ++
Re: [Intel-gfx] [PATCH] drm/i915/display: Use dma_fence interfaces instead of i915_sw_fence
On 2023-10-18 17:38, Ville Syrjälä wrote: On Mon, Oct 16, 2023 at 11:08:03AM +0300, Jouni Högander wrote: We are preparing for Xe driver. Xe driver doesn't have i915_sw_fence implementation. Lets drop i915_sw_fence usage from display code and use dma_fence interfaces directly. For this purpose stack dma fences from related objects into old and new plane states using drm_gem_plane_helper_prepare_fb. Then wait for these stacked fences during atomic commit. There is no be need for separate GPU reset handling in intel_atomic_commit_fence_wait as the fences are signaled when GPU hang is detected and GPU is being reset. Cc: Ville Syrjälä Cc: Maarten Lankhorst Cc: José Roberto de Souza Signed-off-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_atomic.c | 3 - .../gpu/drm/i915/display/intel_atomic_plane.c | 49 +++- drivers/gpu/drm/i915/display/intel_display.c | 78 ++- .../drm/i915/display/intel_display_types.h| 2 - 4 files changed, 37 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 5d18145da279..ec0d5168b503 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -331,9 +331,6 @@ void intel_atomic_state_free(struct drm_atomic_state *_state) drm_atomic_state_default_release(>base); kfree(state->global_objs); - - i915_sw_fence_fini(>commit_ready); - kfree(state); } diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b1074350616c..d4f9168ec42c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -32,6 +32,7 @@ */ #include +#include #include #include @@ -1035,7 +1036,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, struct intel_atomic_state *state = to_intel_atomic_state(new_plane_state->uapi.state); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - const struct intel_plane_state *old_plane_state = + struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); struct drm_i915_gem_object *obj = intel_fb_obj(new_plane_state->hw.fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(old_plane_state->hw.fb); @@ -1057,56 +1058,30 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * This should only fail upon a hung GPU, in which case we * can safely continue. */ - if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) { - ret = i915_sw_fence_await_reservation(>commit_ready, - old_obj->base.resv, - false, 0, - GFP_KERNEL); + if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state) && + !dma_resv_test_signaled(old_obj->base.resv, + dma_resv_usage_rw(false))) { + ret = drm_gem_plane_helper_prepare_fb(_plane, _plane_state->uapi); This I think is broken. The old plane state and its fence can still be in use by the previous commit, so we cannot mutate it here. Thus we really need to get the implicit fence from the old fb chained into the new plane state's fence. Is it even needed though? If new_plane_state always calls prepare_fb. Cheers, ~Maarten
Re: [Intel-gfx] [PATCH] drm/i915/display: Use dma_fence interfaces instead of i915_sw_fence
On 2023-10-18 17:19, Ville Syrjälä wrote: On Mon, Oct 16, 2023 at 11:08:03AM +0300, Jouni Högander wrote: We are preparing for Xe driver. Xe driver doesn't have i915_sw_fence implementation. Lets drop i915_sw_fence usage from display code and use dma_fence interfaces directly. For this purpose stack dma fences from related objects into old and new plane states using drm_gem_plane_helper_prepare_fb. Then wait for these stacked fences during atomic commit. There is no be need for separate GPU reset handling in intel_atomic_commit_fence_wait as the fences are signaled when GPU hang is detected and GPU is being reset. Cc: Ville Syrjälä Cc: Maarten Lankhorst Cc: José Roberto de Souza Signed-off-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_atomic.c | 3 - .../gpu/drm/i915/display/intel_atomic_plane.c | 49 +++- drivers/gpu/drm/i915/display/intel_display.c | 78 ++- .../drm/i915/display/intel_display_types.h| 2 - 4 files changed, 37 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 5d18145da279..ec0d5168b503 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -331,9 +331,6 @@ void intel_atomic_state_free(struct drm_atomic_state *_state) drm_atomic_state_default_release(>base); kfree(state->global_objs); - - i915_sw_fence_fini(>commit_ready); - kfree(state); } diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b1074350616c..d4f9168ec42c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -32,6 +32,7 @@ */ #include +#include #include #include @@ -1035,7 +1036,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, struct intel_atomic_state *state = to_intel_atomic_state(new_plane_state->uapi.state); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - const struct intel_plane_state *old_plane_state = + struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); struct drm_i915_gem_object *obj = intel_fb_obj(new_plane_state->hw.fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(old_plane_state->hw.fb); @@ -1057,56 +1058,30 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * This should only fail upon a hung GPU, in which case we * can safely continue. */ - if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) { - ret = i915_sw_fence_await_reservation(>commit_ready, - old_obj->base.resv, - false, 0, - GFP_KERNEL); + if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state) && + !dma_resv_test_signaled(old_obj->base.resv, + dma_resv_usage_rw(false))) { + ret = drm_gem_plane_helper_prepare_fb(_plane, _plane_state->uapi); if (ret < 0) return ret; } } - if (new_plane_state->uapi.fence) { /* explicit fencing */ - i915_gem_fence_wait_priority(new_plane_state->uapi.fence, -); - ret = i915_sw_fence_await_dma_fence(>commit_ready, - new_plane_state->uapi.fence, - i915_fence_timeout(dev_priv), - GFP_KERNEL); - if (ret < 0) - return ret; - } - if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); if (ret) return ret; - i915_gem_object_wait_priority(obj, 0, ); - - if (!new_plane_state->uapi.fence) { /* implicit fencing */ - struct dma_resv_iter cursor; - struct dma_fence *fence; + ret = drm_gem_plane_helper_prepare_fb(_plane, _plane_state->uapi); I don't think we can use that as is due to bigjoiner stuff. I think we'd need a slightly lower level variant that takes the fb+fence in explicitly instead of the full plane state. And I suppose we already have a slight bug here where only the master pipe's plane will consult the explicit fence and the rest will take the implicit sync path. Why would bigjoiner fail? If bigjoiner happens, the uapi fb will be fenced at least once. Cheers, ~Maarten
Re: [Intel-gfx] [PATCH] drm/i915/display: Use dma_fence interfaces instead of i915_sw_fence
Hey, Thanks, this version looks a lot better than duplicating drm_gem_plane_helper_prepare_fb functionality. :) Reviewed-by: Maarten Lankhorst On 2023-10-16 10:08, Jouni Högander wrote: We are preparing for Xe driver. Xe driver doesn't have i915_sw_fence implementation. Lets drop i915_sw_fence usage from display code and use dma_fence interfaces directly. For this purpose stack dma fences from related objects into old and new plane states using drm_gem_plane_helper_prepare_fb. Then wait for these stacked fences during atomic commit. There is no be need for separate GPU reset handling in intel_atomic_commit_fence_wait as the fences are signaled when GPU hang is detected and GPU is being reset. Cc: Ville Syrjälä Cc: Maarten Lankhorst Cc: José Roberto de Souza Signed-off-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_atomic.c | 3 - .../gpu/drm/i915/display/intel_atomic_plane.c | 49 +++- drivers/gpu/drm/i915/display/intel_display.c | 78 ++- .../drm/i915/display/intel_display_types.h| 2 - 4 files changed, 37 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 5d18145da279..ec0d5168b503 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -331,9 +331,6 @@ void intel_atomic_state_free(struct drm_atomic_state *_state) drm_atomic_state_default_release(>base); kfree(state->global_objs); - - i915_sw_fence_fini(>commit_ready); - kfree(state); } diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b1074350616c..d4f9168ec42c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -32,6 +32,7 @@ */ #include +#include #include #include @@ -1035,7 +1036,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, struct intel_atomic_state *state = to_intel_atomic_state(new_plane_state->uapi.state); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - const struct intel_plane_state *old_plane_state = + struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); struct drm_i915_gem_object *obj = intel_fb_obj(new_plane_state->hw.fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(old_plane_state->hw.fb); @@ -1057,56 +1058,30 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * This should only fail upon a hung GPU, in which case we * can safely continue. */ - if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) { - ret = i915_sw_fence_await_reservation(>commit_ready, - old_obj->base.resv, - false, 0, - GFP_KERNEL); + if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state) && + !dma_resv_test_signaled(old_obj->base.resv, + dma_resv_usage_rw(false))) { + ret = drm_gem_plane_helper_prepare_fb(_plane, _plane_state->uapi); if (ret < 0) return ret; } } - if (new_plane_state->uapi.fence) { /* explicit fencing */ - i915_gem_fence_wait_priority(new_plane_state->uapi.fence, -); - ret = i915_sw_fence_await_dma_fence(>commit_ready, - new_plane_state->uapi.fence, - i915_fence_timeout(dev_priv), - GFP_KERNEL); - if (ret < 0) - return ret; - } - if (!obj) return 0; - ret = intel_plane_pin_fb(new_plane_state); if (ret) return ret; - i915_gem_object_wait_priority(obj, 0, ); - - if (!new_plane_state->uapi.fence) { /* implicit fencing */ - struct dma_resv_iter cursor; - struct dma_fence *fence; + ret = drm_gem_plane_helper_prepare_fb(_plane, _plane_state->uapi); + if (ret < 0) + goto unpin_fb; - ret = i915_sw_fence_await_reservation(>commit_ready, - obj->base.resv, false, - i915_fence_timeout(dev_priv), - GFP_KERNEL); - i
[Intel-gfx] [PULL] drm-misc-next
drm-misc-next-2023-10-12: drm-misc-next for v6.7-rc1: Contains the previous pull request drm-misc-next-2023-10-06 + following: Cross-subsystem Changes: - Rename fb_pgprot to pgprot_framebuffer and remove file argument/ - Update iosys-map documentation typos. Core Changes: - Assorted fixes to drm/panel. - Add HPD state to drm_connector_oob_hotplug_event(), and implement oob hotplug events in bridge connector. - Replace drm_framebuffer_plane_width/height with calls to drm_format_info_plane_width/height. Driver Changes: - Clock and debug fixes for bridge/samsung-dsim. - More btree -> maple tree conversions. - Assorted bugfixes in rockchip, panel-tpo-tpg110, - Add LTK050H3148W-CTA6 panel support. - Assorted small fixes in host1x, tegra, simpledrm. - Suspend fixes for host1x. The following changes since commit 389af786f92ecdff35883551d54bf4e507ffcccb: Merge tag 'drm-intel-next-2023-09-29' of git://anongit.freedesktop.org/drm/drm-intel into drm-next (2023-10-04 13:55:19 +1000) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2023-10-12 for you to fetch changes up to c395c83aafbb9cdbe4230f044d5b8eaf9080c0c5: drm/simpledrm: Fix power domain device link validity check (2023-10-12 10:39:48 +0200) drm-misc-next for v6.7-rc1: Contains the previous pull request drm-misc-next-2023-10-06 + following: Cross-subsystem Changes: - Rename fb_pgprot to pgprot_framebuffer and remove file argument/ - Update iosys-map documentation typos. Core Changes: - Assorted fixes to drm/panel. - Add HPD state to drm_connector_oob_hotplug_event(), and implement oob hotplug events in bridge connector. - Replace drm_framebuffer_plane_width/height with calls to drm_format_info_plane_width/height. Driver Changes: - Clock and debug fixes for bridge/samsung-dsim. - More btree -> maple tree conversions. - Assorted bugfixes in rockchip, panel-tpo-tpg110, - Add LTK050H3148W-CTA6 panel support. - Assorted small fixes in host1x, tegra, simpledrm. - Suspend fixes for host1x. Adrián Larumbe (6): drm/panfrost: Add cycle count GPU register definitions drm/panfrost: Add fdinfo support GPU load metrics drm/panfrost: Add fdinfo support for memory stats drm/drm_file: Add DRM obj's RSS reporting function for fdinfo drm/panfrost: Implement generic DRM object RSS reporting function Documentation/gpu: fix Panfrost documentation build warnings André Almeida (1): drm/doc: Document DRM device reset expectations Arnd Bergmann (1): drm/nouveau/kms/nv50: hide unused variables Arthur Grillo (2): drm/tests: Add calls to drm_fb_blit() on supported format conversion tests drm/tests: Add new format conversion tests to better cover drm_fb_blit() Bjorn Andersson (1): drm: Add HPD state to drm_connector_oob_hotplug_event() Carlos Eduardo Gallo Filho (2): drm: Remove plane hsub/vsub alignment requirement for core helpers drm: Replace drm_framebuffer plane size functions with its equivalents Chris Morgan (2): dt-bindings: display: newvision,nv3051d: Add Anbernic 351V drm/panel: nv3051d: Add Support for Anbernic 351V Christophe JAILLET (1): drm/rockchip: cdn-dp: Fix some error handling paths in cdn_dp_probe() Danilo Krummrich (1): drm/gpuvm: doc: fix filename references Dmitry Baryshkov (2): drm/bridge_connector: stop filtering events in drm_bridge_connector_hpd_cb() drm/bridge_connector: implement oob_hotplug_event Douglas Anderson (1): MAINTAINERS: Document that the NXP i.MX 8MQ DCSS driver goes thru drm-misc Jani Nikula (3): drm/bridge: use drm_bridge_get_edid() instead of using ->get_edid directly drm/bridge: lt9611uxc: use drm_bridge_get_edid() instead of using ->get_edid directly drm/dp: switch drm_dp_downstream_*() helpers to struct drm_edid Johannes Zink (3): dt-bindings: display: move LVDS data-mapping definition to separate file dt-bindings: display: simple: support non-default data-mapping drm/panel-simple: allow LVDS format override Johnny Liu (1): gpu: host1x: Correct allocated size for contexts Justin Stitt (1): drm/gma500: refactor deprecated strncpy Kees Cook (9): drm/amd/pm: Annotate struct smu10_voltage_dependency_table with __counted_by drm/amdgpu/discovery: Annotate struct ip_hw_instance with __counted_by drm/i915/selftests: Annotate struct perf_series with __counted_by drm/msm/dpu: Annotate struct dpu_hw_intr with __counted_by drm/nouveau/pm: Annotate struct nvkm_perfdom with __counted_by drm/vc4: Annotate struct vc4_perfmon with __counted_by drm/virtio: Annotate struct virtio_gpu_object_array with __counted_by drm/vmwgfx: Annotate struct vmw_surface_dirty with __counted_by drm/v3d: Annotate
[Intel-gfx] [PULL] drm-misc-next
drm-misc-next-2023-10-06: drm-misc-next for v6.7: Cross-subsystem Changes: - drm-misc now matches all drivers to ensure it goes to the correct tree. - Clarify NXP i.MX 8MQ DCSS goes through drm-misc tree in MAINTAINERS. Core Changes: - Assorted small fixes in gpuvm, bridge. - Improve format conversion tests. - Document DRM device reset expectations. - Warn when vblank worker is cancelled. - Allow more accurate reporting of RSS and use it in panfrost. - Use struct drm_edid in drm_dp_downstream helpers. Driver Changes: - Assorted small fixes in gma500, ivpu, nouveau, bridge/lt9611uxc, amdgpu, exynos/dsi. - Convert quite a few drm/bridge drivers to use maple tree register cache. - Add BOE RM692E5 AMOLED, Anbernic 351V panels. - Add fdinfo support for panfrost memor ystat and gpu load metrics, including some documentation updates. - Update drivers variable sized ararys by using __counted_by. - The following changes since commit 78f54469b871db5ba8ea49abd4e5994e97bd525b: drm/nouveau: uvmm: rename 'umgr' to 'base' (2023-09-26 01:58:29 +0200) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2023-10-06 for you to fetch changes up to c1698c73f4aaef2fd406da1c0a92e1c8f7b7780c: drm: exynos: dsi: Convert to platform remove callback returning void (2023-10-06 08:58:44 +0200) drm-misc-next for v6.7: Cross-subsystem Changes: - drm-misc now matches all drivers to ensure it goes to the correct tree. - Clarify NXP i.MX 8MQ DCSS goes through drm-misc tree in MAINTAINERS. Core Changes: - Assorted small fixes in gpuvm, bridge. - Improve format conversion tests. - Document DRM device reset expectations. - Warn when vblank worker is cancelled. - Allow more accurate reporting of RSS and use it in panfrost. - Use struct drm_edid in drm_dp_downstream helpers. Driver Changes: - Assorted small fixes in gma500, ivpu, nouveau, bridge/lt9611uxc, amdgpu, exynos/dsi. - Convert quite a few drm/bridge drivers to use maple tree register cache. - Add BOE RM692E5 AMOLED, Anbernic 351V panels. - Add fdinfo support for panfrost memor ystat and gpu load metrics, including some documentation updates. - Update drivers variable sized ararys by using __counted_by. - Adrián Larumbe (5): drm/panfrost: Add cycle count GPU register definitions drm/panfrost: Add fdinfo support GPU load metrics drm/panfrost: Add fdinfo support for memory stats drm/drm_file: Add DRM obj's RSS reporting function for fdinfo drm/panfrost: Implement generic DRM object RSS reporting function André Almeida (1): drm/doc: Document DRM device reset expectations Arnd Bergmann (1): drm/nouveau/kms/nv50: hide unused variables Arthur Grillo (2): drm/tests: Add calls to drm_fb_blit() on supported format conversion tests drm/tests: Add new format conversion tests to better cover drm_fb_blit() Chris Morgan (2): dt-bindings: display: newvision,nv3051d: Add Anbernic 351V drm/panel: nv3051d: Add Support for Anbernic 351V Danilo Krummrich (1): drm/gpuvm: doc: fix filename references Douglas Anderson (1): MAINTAINERS: Document that the NXP i.MX 8MQ DCSS driver goes thru drm-misc Jani Nikula (3): drm/bridge: use drm_bridge_get_edid() instead of using ->get_edid directly drm/bridge: lt9611uxc: use drm_bridge_get_edid() instead of using ->get_edid directly drm/dp: switch drm_dp_downstream_*() helpers to struct drm_edid Justin Stitt (1): drm/gma500: refactor deprecated strncpy Kees Cook (9): drm/amd/pm: Annotate struct smu10_voltage_dependency_table with __counted_by drm/amdgpu/discovery: Annotate struct ip_hw_instance with __counted_by drm/i915/selftests: Annotate struct perf_series with __counted_by drm/msm/dpu: Annotate struct dpu_hw_intr with __counted_by drm/nouveau/pm: Annotate struct nvkm_perfdom with __counted_by drm/vc4: Annotate struct vc4_perfmon with __counted_by drm/virtio: Annotate struct virtio_gpu_object_array with __counted_by drm/vmwgfx: Annotate struct vmw_surface_dirty with __counted_by drm/v3d: Annotate struct v3d_perfmon with __counted_by Konrad Dybcio (2): dt-bindings: display: panel: Add Raydium RM692E5 drm/panel: Add driver for BOE RM692E5 AMOLED panel Mark Brown (8): drm/bridge: adv7511: Convert to use maple tree register cache drm/bridge: dpc3433: Convert to use maple tree register cache drm/bridge: tc358767: Convert to use maple tree register cache drm/bridge: icn6211: Convert to use maple tree register cache drm/bridge: lt9211: Convert to use maple tree register cache drm/bridge: sn65dsi83: Convert to use maple tree register cache drm/panel: ili9322: Remove redundant volatle_reg() operation drm/panel: ili9322: Convert to
[Intel-gfx] [PATCH 2/2] drm/i915: Use drm_atomic_helper_update_plane for cursor updates
From: Maarten Lankhorst Regular path should be fast enough, even for i915. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 146 +--- 1 file changed, 1 insertion(+), 145 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index b342fad180ca..37c0d3d40e6f 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -603,152 +603,8 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } -static int -intel_legacy_cursor_update(struct drm_plane *_plane, - struct drm_crtc *_crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - u32 src_x, u32 src_y, - u32 src_w, u32 src_h, - struct drm_modeset_acquire_ctx *ctx) -{ - struct intel_plane *plane = to_intel_plane(_plane); - struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct intel_plane_state *old_plane_state = - to_intel_plane_state(plane->base.state); - struct intel_plane_state *new_plane_state; - struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - struct intel_crtc_state *new_crtc_state; - int ret; - - /* -* When crtc is inactive or there is a modeset pending, -* wait for it to complete in the slowpath. -* PSR2 selective fetch also requires the slow path as -* PSR2 plane and transcoder registers can only be updated during -* vblank. -* -* FIXME bigjoiner fastpath would be good -*/ - if (!crtc_state->hw.active || - intel_crtc_needs_modeset(crtc_state) || - intel_crtc_needs_fastset(crtc_state) || - crtc_state->bigjoiner_pipes) - goto slow; - - /* -* Don't do an async update if there is an outstanding commit modifying -* the plane. This prevents our async update's changes from getting -* overridden by a previous synchronous update's state. -*/ - if (old_plane_state->uapi.commit && - !try_wait_for_completion(_plane_state->uapi.commit->hw_done)) - goto slow; - - /* -* If any parameters change that may affect watermarks, -* take the slowpath. Only changing fb or position should be -* in the fastpath. -*/ - if (old_plane_state->uapi.crtc != >base || - old_plane_state->uapi.src_w != src_w || - old_plane_state->uapi.src_h != src_h || - old_plane_state->uapi.crtc_w != crtc_w || - old_plane_state->uapi.crtc_h != crtc_h || - !old_plane_state->uapi.fb != !fb) - goto slow; - - new_plane_state = to_intel_plane_state(intel_plane_duplicate_state(>base)); - if (!new_plane_state) - return -ENOMEM; - - new_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(>base)); - if (!new_crtc_state) { - ret = -ENOMEM; - goto out_free; - } - - drm_atomic_set_fb_for_plane(_plane_state->uapi, fb); - - new_plane_state->uapi.src_x = src_x; - new_plane_state->uapi.src_y = src_y; - new_plane_state->uapi.src_w = src_w; - new_plane_state->uapi.src_h = src_h; - new_plane_state->uapi.crtc_x = crtc_x; - new_plane_state->uapi.crtc_y = crtc_y; - new_plane_state->uapi.crtc_w = crtc_w; - new_plane_state->uapi.crtc_h = crtc_h; - - intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc); - - ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state, - old_plane_state, new_plane_state); - if (ret) - goto out_free; - - ret = intel_plane_pin_fb(new_plane_state); - if (ret) - goto out_free; - - intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb), - ORIGIN_CURSOR_UPDATE); - intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->hw.fb), - to_intel_frontbuffer(new_plane_state->hw.fb), - plane->frontbuffer_bit); - - /* Swap plane state */ - plane->base.state = _plane_state->uapi; - - /* -* We cannot swap crtc_state as it may be in use by an atomic commit or -* page flip that's running simultaneously. If we swap crtc_state and -* destroy the old state, we will cause a use-after-free there. -* -* Only update active_
[Intel-gfx] [PATCH 1/2] drm/i915: Block in cleanup for legacy cursor updates
From: Maarten Lankhorst On cursor updates we should never unpin before the cursor is no longer active. This means that we need to add a delay. The vblank worker may cancel certain updates, so we/ only use it as a barrier to see if a vblank has completed, and then wait for that in the cleanup function. Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_atomic_plane.c | 18 .../gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 29 +++ .../drm/i915/display/intel_display_types.h| 5 4 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b1074350616c..1f2bb8e0c65b 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1153,6 +1153,9 @@ intel_cleanup_plane_fb(struct drm_plane *plane, intel_display_rps_mark_interactive(dev_priv, state, false); /* Should only be called after a successful intel_prepare_plane_fb()! */ + if (old_plane_state->unpin_work.vblank) + drm_vblank_work_flush(_plane_state->unpin_work); + intel_plane_unpin_fb(old_plane_state); } @@ -1165,3 +1168,18 @@ void intel_plane_helper_add(struct intel_plane *plane) { drm_plane_helper_add(>base, _plane_helper_funcs); } + +/* Completion is enough */ +static void intel_plane_cursor_vblank_work(struct kthread_work *base) +{ } + +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state) +{ + if (!old_plane_state->ggtt_vma || + old_plane_state->ggtt_vma == new_plane_state->ggtt_vma) + return; + + drm_vblank_work_init(_plane_state->unpin_work, old_plane_state->uapi.crtc, +intel_plane_cursor_vblank_work); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 191dad0efc8e..5a897cf6fa02 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -66,5 +66,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, +struct intel_plane_state *new_plane_state); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 1fd068e6e26c..20de5f62d492 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -559,7 +559,21 @@ void intel_pipe_update_start(struct intel_atomic_state *state, if (intel_crtc_needs_vblank_work(new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state, *new_plane_state; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, +new_plane_state, i) { + if (old_plane_state->uapi.crtc == >base) + intel_plane_init_cursor_vblank_work(old_plane_state, + new_plane_state); + } + } + intel_crtc_vblank_evade_scanlines(state, crtc, , , _start); + if (min <= 0 || max <= 0) goto irq_disable; @@ -721,6 +735,21 @@ void intel_pipe_update_end(struct intel_atomic_state *state, new_crtc_state->uapi.event = NULL; } + if (state->base.legacy_cursor_update) { + struct intel_plane *plane; + struct intel_plane_state *old_plane_state; + int i; + + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { + if (old_plane_state->uapi.crtc == >base && + old_plane_state->unpin_work.vblank) { + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + } + } + } + /* * Send VRR Push to terminate Vblank. If we are already in vblank * this has to
[Intel-gfx] [PULL] drm-misc-next
drm-misc-next-2023-09-27: drm-misc-next for v6.7-rc1: UAPI Changes: - drm_file owner is now updated during use, in the case of a drm fd opened by the display server for a client, the correct owner is displayed. - Qaic gains support for the QAIC_DETACH_SLICE_BO ioctl to allow bo recycling. Cross-subsystem Changes: - Disable boot logo for au1200fb, mmpfb and unexport logo helpers. Only fbcon should manage display of logo. - Update freescale in MAINTAINERS. - Add some bridge files to bridge in MAINTAINERS. - Update gma500 driver repo in MAINTAINERS to point to drm-misc. Core Changes: - Move size computations to drm buddy allocator. - Make drm_atomic_helper_shutdown(NULL) a nop. - Assorted small fixes in drm_debugfs, DP-MST payload addition error handling. - Fix DRM_BRIDGE_ATTACH_NO_CONNECTOR handling. - Handle bad (h/v)sync_end in EDID by clipping to htotal. - Build GPUVM as a module. Driver Changes: - Simple drivers don't need to cache prepared result. - Call drm_atomic_helper_shutdown() in shutdown/unbind for a whole lot more drm drivers. - Assorted small fixes in amdgpu, ssd130x, bridge/it6621, accel/qaic, nouveau, tc358768. - Add NV12 for komeda writeback. - Add arbitration lost event to synopsis/dw-hdmi-cec. - Speed up s/r in nouveau by not restoring some big bo's. - Assorted nouveau display rework in preparation for GSP-RM, especially related to how the modeset sequence works and the DP sequence in relation to link training. - Update anx7816 panel. - Support NVSYNC and NHSYNC in tegra. - Allow multiple power domains in simple driver. The following changes since commit 15d30b46573d75f5cb58cfacded8ebab9c76a2b0: drm/ssd130x: Use bool for ssd130x_deviceinfo flags (2023-09-10 09:05:47 +0200) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2023-09-27 for you to fetch changes up to 78f54469b871db5ba8ea49abd4e5994e97bd525b: drm/nouveau: uvmm: rename 'umgr' to 'base' (2023-09-26 01:58:29 +0200) drm-misc-next for v6.7-rc1: UAPI Changes: - drm_file owner is now updated during use, in the case of a drm fd opened by the display server for a client, the correct owner is displayed. - Qaic gains support for the QAIC_DETACH_SLICE_BO ioctl to allow bo recycling. Cross-subsystem Changes: - Disable boot logo for au1200fb, mmpfb and unexport logo helpers. Only fbcon should manage display of logo. - Update freescale in MAINTAINERS. - Add some bridge files to bridge in MAINTAINERS. - Update gma500 driver repo in MAINTAINERS to point to drm-misc. Core Changes: - Move size computations to drm buddy allocator. - Make drm_atomic_helper_shutdown(NULL) a nop. - Assorted small fixes in drm_debugfs, DP-MST payload addition error handling. - Fix DRM_BRIDGE_ATTACH_NO_CONNECTOR handling. - Handle bad (h/v)sync_end in EDID by clipping to htotal. - Build GPUVM as a module. Driver Changes: - Simple drivers don't need to cache prepared result. - Call drm_atomic_helper_shutdown() in shutdown/unbind for a whole lot more drm drivers. - Assorted small fixes in amdgpu, ssd130x, bridge/it6621, accel/qaic, nouveau, tc358768. - Add NV12 for komeda writeback. - Add arbitration lost event to synopsis/dw-hdmi-cec. - Speed up s/r in nouveau by not restoring some big bo's. - Assorted nouveau display rework in preparation for GSP-RM, especially related to how the modeset sequence works and the DP sequence in relation to link training. - Update anx7816 panel. - Support NVSYNC and NHSYNC in tegra. - Allow multiple power domains in simple driver. Alicja Michalska (2): dt-bindings: display: anx7814: Add definition for anx7816 drm/bridge/analogix/anx78xx: Add missing definition AngeloGioacchino Del Regno (1): drm/bridge: panel: Fix device link for DRM_BRIDGE_ATTACH_NO_CONNECTOR Arunpravin Paneer Selvam (3): drm/buddy: Improve contiguous memory allocation drm/amdgpu: Move the size computations to drm buddy drm/i915: Move the size computations to drm buddy Ben Skeggs (43): drm/nouveau/devinit/tu102-: remove attempt at loading PreOS drm/nouveau/imem: support allocations not preserved across suspend drm/nouveau/gr/gf100-: lose contents of global ctxbufs across suspend drm/nouveau/mmu/gp100-: always invalidate TLBs at CACHE_LEVEL_ALL drm/nouveau/kms/nv50-: fix mst payload alloc fail crashing evo drm/nouveau/disp: rearrange output methods drm/nouveau/disp: add output detect method drm/nouveau/disp: add output method to fetch edid drm/nouveau/disp: rename internal output acquire/release functions drm/nouveau/disp: shuffle to make upcoming diffs prettier drm/nouveau/disp: add acquire_dac() drm/nouveau/disp: add acquire_sor/pior() drm/nouveau/disp: update SOR routing immediately on acquire()
Re: [Intel-gfx] [PATCH] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
Hey, On 2023-09-01 12:56, Ville Syrjälä wrote: On Fri, Sep 01, 2023 at 12:16:21PM +0200, Maarten Lankhorst wrote: Hey, Den 2023-08-31 kl. 18:26, skrev Ville Syrjala: From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cursor.c | 25 +-- .../drm/i915/display/intel_display_types.h| 3 +++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index b342fad180ca..2bd1a79c6955 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -603,6 +603,16 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(plane_state->uapi.plane, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -730,14 +740,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, local_irq_enable(); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->hw.fb != new_plane_state->hw.fb) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } Maybe check if crtc is active and no modeset is happening? We wouldn't be on this codepath if that wasn't the case. Similar to how the vblank worker is used in other cases. That should hopefully fix the cursor leak test. The leak is likely due to the vblank worker being a bit crazy and sometimes silently cancelling pending works. I fired a new series at trybot that tries to avoid that. I saw the trybot series. Have you tried fixing it to fire off the vblank work immediately before disabling? ~Maarten
[Intel-gfx] [PULL] drm-misc-next
Hi Dave, Daniel, First pull request for next kernel cycle. Cheers, ~Maarten drm-misc-next-2023-09-11-1: drm-misc-next for v6.7-rc1: UAPI Changes: - Nouveau changed to not set NO_PREFETCH flag explicitly. Cross-subsystem Changes: - Update documentation of dma-buf intro and uapi. - fbdev/sbus fixes. - Use initializer macros in a lot of fbdev drivers. - Add Boris Brezillon as Panfrost driver maintainer. - Add Jessica Zhang as drm/panel reviewer. - Make more fbdev drivers use fb_ops helpers for deferred io. - Small hid trailing whitespace fix. - Use fb_ops in hid/picolcd Core Changes: - Assorted small fixes to ttm tests, drm/mst. - Documentation updates to bridge. - Add kunit tests for some drm_fb functions. - Rework drm_debugfs implementation. - Update xe documentation to mark todos as completed. Driver Changes: - Add support to rockchip for rv1126 mipi-dsi and vop. - Assorted small fixes to nouveau, bridge/samsung-dsim, bridge/lvds-codec, loongson, rockchip, panfrost, gma500, repaper, komeda, virtio, ssd130x. - Add support for simple panels Mitsubishi AA084XE01, JDI LPM102A188A, - Documentation updates to accel/ivpu. - Some nouveau scheduling/fence fixes. - Power management related fixes and other fixes to ivpu. - Assorted bridge/it66121 fixes. - Make platform drivers return void in remove() callback. The following changes since commit 2799804ac651da1375ecb9b9a644eba97218df07: drm/ttm: Remove two unused function declarations (2023-08-10 09:12:08 +0200) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-2023-09-11-1 for you to fetch changes up to 15d30b46573d75f5cb58cfacded8ebab9c76a2b0: drm/ssd130x: Use bool for ssd130x_deviceinfo flags (2023-09-10 09:05:47 +0200) drm-misc-next for v6.7-rc1: UAPI Changes: - Nouveau changed to not set NO_PREFETCH flag explicitly. Cross-subsystem Changes: - Update documentation of dma-buf intro and uapi. - fbdev/sbus fixes. - Use initializer macros in a lot of fbdev drivers. - Add Boris Brezillon as Panfrost driver maintainer. - Add Jessica Zhang as drm/panel reviewer. - Make more fbdev drivers use fb_ops helpers for deferred io. - Small hid trailing whitespace fix. - Use fb_ops in hid/picolcd Core Changes: - Assorted small fixes to ttm tests, drm/mst. - Documentation updates to bridge. - Add kunit tests for some drm_fb functions. - Rework drm_debugfs implementation. - Update xe documentation to mark todos as completed. Driver Changes: - Add support to rockchip for rv1126 mipi-dsi and vop. - Assorted small fixes to nouveau, bridge/samsung-dsim, bridge/lvds-codec, loongson, rockchip, panfrost, gma500, repaper, komeda, virtio, ssd130x. - Add support for simple panels Mitsubishi AA084XE01, JDI LPM102A188A, - Documentation updates to accel/ivpu. - Some nouveau scheduling/fence fixes. - Power management related fixes and other fixes to ivpu. - Assorted bridge/it66121 fixes. - Make platform drivers return void in remove() callback. Alexander Stein (1): drm/bridge: lvds-codec: Implement atomic_get_input_bus_fmts for LVDS encoder Arthur Grillo (8): drm/tests: Test default pitch fallback drm/tests: Add KUnit tests for drm_fb_swab() drm/tests: Add KUnit tests for drm_fb_clip_offset() drm/tests: Add KUnit tests for drm_fb_build_fourcc_list() drm/tests: Add multi-plane support to conversion_buf_size() drm/tests: Add KUnit tests for drm_fb_memcpy() drm/debugfs: Add inline to drm_debugfs_dev_init() to suppres -Wunused-function drm/tests: Zero initialize fourccs_out Biju Das (5): drm: bridge: it66121: Extend match support for OF tables drm: bridge: it66121: Simplify probe() drm/bridge/analogix/anx78xx: Drop ID table drm/bridge: Drop conditionals around of_node pointers drm/bridge: Drop CONFIG_OF conditionals around of_node pointers Christian König (5): drm/debugfs: drop debugfs_init() for the render and accel node v2 drm/debugfs: disallow debugfs access when device isn't registered drm/debugfs: rework debugfs directory creation v5 drm/debugfs: remove dev->debugfs_list and debugfs_mutex v2 drm/debugfs: rework drm_debugfs_create_files implementation v2 Daniel Stone (2): doc: dma-buf: Rewrite intro section a little doc: uapi: Add document describing dma-buf semantics Danilo Krummrich (3): drm/nouveau: sched: avoid job races between entities drm/nouveau: uvmm: fix unset region pointer on remap drm/nouveau: uapi: don't pass NO_PREFETCH flag implicitly Dave Airlie (1): nouveau/u_memcpya: use vmemdup_user David Heidelberg (2): drm/panel: JDI LT070ME05000 drop broken link drm/panel: JDI LT070ME05000 simplify with dev_err_probe() Diogo Ivo (2): dt-bindings: display: Add bindings for JDI LPM102A188A
Re: [Intel-gfx] [PATCH] drm/i915: Use vblank worker to unpin old legacy cursor fb safely
Hey, Den 2023-08-31 kl. 18:26, skrev Ville Syrjala: From: Ville Syrjälä The cursor hardware only does sync updates, and thus the hardware will be scanning out from the old fb until the next start of vblank. So in order to make the legacy cursor fastpath actually safe we should not unpin the old fb until we're sure the hardware has ceased accessing it. The simplest approach is to just use a vblank work here to do the delayed unpin. Not 100% sure it's a good idea to put this onto the same high priority vblank worker as eg. our timing critical gamma updates. But let's keep it simple for now, and it we later discover that this is causing problems we can think about adding a lower priority worker for such things. Cc: Maarten Lankhorst Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_cursor.c | 25 +-- .../drm/i915/display/intel_display_types.h| 3 +++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index b342fad180ca..2bd1a79c6955 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -603,6 +603,16 @@ static bool intel_cursor_format_mod_supported(struct drm_plane *_plane, return format == DRM_FORMAT_ARGB; } +static void intel_cursor_unpin_work(struct kthread_work *base) +{ + struct drm_vblank_work *work = to_drm_vblank_work(base); + struct intel_plane_state *plane_state = + container_of(work, typeof(*plane_state), unpin_work); + + intel_plane_unpin_fb(plane_state); + intel_plane_destroy_state(plane_state->uapi.plane, _state->uapi); +} + static int intel_legacy_cursor_update(struct drm_plane *_plane, struct drm_crtc *_crtc, @@ -730,14 +740,25 @@ intel_legacy_cursor_update(struct drm_plane *_plane, local_irq_enable(); - intel_plane_unpin_fb(old_plane_state); + if (old_plane_state->hw.fb != new_plane_state->hw.fb) { + drm_vblank_work_init(_plane_state->unpin_work, >base, +intel_cursor_unpin_work); + + drm_vblank_work_schedule(_plane_state->unpin_work, + drm_crtc_accurate_vblank_count(>base) + 1, +false); + + old_plane_state = NULL; + } else { + intel_plane_unpin_fb(old_plane_state); + } Maybe check if crtc is active and no modeset is happening? Similar to how the vblank worker is used in other cases. That should hopefully fix the cursor leak test. Cheers, ~Maarten
[Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
From: Maarten Lankhorst Abuse the vblank worker to make the changes as small as possible. We need a way to sync flip_done, but if we wait on flip_done, all async tests start failing. Changes since v1: - Prevent null deref when crtc is inactive. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_crtc.c| 28 +--- drivers/gpu/drm/i915/display/intel_crtc.h| 6 +++-- drivers/gpu/drm/i915/display/intel_display.c | 10 --- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index f06b987f5558..be6959c6eb0d 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -389,11 +389,17 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) return ret; } -static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state) +static bool intel_crtc_needs_vblank_work(const struct intel_atomic_state *state, +const struct intel_crtc_state *crtc_state) { - return crtc_state->hw.active && - !intel_crtc_needs_modeset(crtc_state) && - !crtc_state->preload_luts && + if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state)) + return false; + + /* Init for legacy cursor update, so we can sync on teardown */ + if (state->base.legacy_cursor_update) + return true; + + return !crtc_state->preload_luts && intel_crtc_needs_color_update(crtc_state); } @@ -438,7 +444,7 @@ void intel_wait_for_vblank_workers(struct intel_atomic_state *state) int i; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { - if (!intel_crtc_needs_vblank_work(crtc_state)) + if (!intel_crtc_needs_vblank_work(state, crtc_state)) continue; drm_vblank_work_flush(_state->vblank_work); @@ -470,6 +476,7 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) /** * intel_pipe_update_start() - start update of a set of display registers + * @state: the intel atomic state * @new_crtc_state: the new crtc state * * Mark the start of an update to pipe registers that should be updated @@ -480,7 +487,8 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) * until a subsequent call to intel_pipe_update_end(). That is done to * avoid random delays. */ -void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) +void intel_pipe_update_start(struct intel_atomic_state *state, +struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -497,7 +505,7 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) if (new_crtc_state->do_async_flip) return; - if (intel_crtc_needs_vblank_work(new_crtc_state)) + if (intel_crtc_needs_vblank_work(state, new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); if (new_crtc_state->vrr.enable) { @@ -635,13 +643,15 @@ static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) {} /** * intel_pipe_update_end() - end update of a set of display registers + * @state: the intel atomic state * @new_crtc_state: the new crtc state * * Mark the end of an update started with intel_pipe_update_start(). This * re-enables interrupts and verifies the update was actually completed * before a vblank. */ -void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) +void intel_pipe_update_end(struct intel_atomic_state *state, + struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; @@ -669,7 +679,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) * Would be slightly nice to just grab the vblank count and arm the * event outside of the critical section - the spinlock might spin for a * while ... */ - if (intel_crtc_needs_vblank_work(new_crtc_state)) { + if (intel_crtc_needs_vblank_work(state, new_crtc_state)) { drm_vblank_work_schedule(_crtc_state->vblank_work, drm_crtc_accurate_vblank_count(>base) + 1, false); diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index 51a4c8df9e65..ca7f45a454a0 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -36,8 +36,10
[Intel-gfx] [PATCH 1/2] drm/i915: Swap ggtt_vma during legacy cursor update
From: Maarten Lankhorst Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_cursor.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 8ed8a623fa98..b1a77b89585d 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -690,9 +690,8 @@ intel_legacy_cursor_update(struct drm_plane *_plane, if (ret) goto out_free; - ret = intel_plane_pin_fb(new_plane_state); - if (ret) - goto out_free; + /* magic trick! */ + swap(new_plane_state->ggtt_vma, old_plane_state->ggtt_vma); intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb), ORIGIN_CURSOR_UPDATE); -- 2.39.2