Add struct intel_display_rps_interface to the display parent interface, and call the RPS functions through it. The RPS interface is optional, but we expect it to be set for ILK.
Signed-off-by: Jani Nikula <[email protected]> --- .../gpu/drm/i915/display/intel_display_rps.c | 33 +++++++++--------- drivers/gpu/drm/i915/gt/intel_rps.c | 34 +++++++++++++++++++ drivers/gpu/drm/i915/gt/intel_rps.h | 2 ++ drivers/gpu/drm/i915/i915_driver.c | 2 ++ include/drm/intel/display_parent_interface.h | 10 ++++++ 5 files changed, 65 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_rps.c b/drivers/gpu/drm/i915/display/intel_display_rps.c index b6720f7c09d9..27714b75d32d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_rps.c +++ b/drivers/gpu/drm/i915/display/intel_display_rps.c @@ -3,12 +3,14 @@ * Copyright © 2023 Intel Corporation */ +#include <linux/dma-fence.h> + #include <drm/drm_crtc.h> #include <drm/drm_vblank.h> +#include <drm/intel/display_parent_interface.h> -#include "gt/intel_rps.h" -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_request.h" #include "intel_display_core.h" #include "intel_display_irq.h" #include "intel_display_rps.h" @@ -25,15 +27,10 @@ static int do_rps_boost(struct wait_queue_entry *_wait, unsigned mode, int sync, void *key) { struct wait_rps_boost *wait = container_of(_wait, typeof(*wait), wait); - struct i915_request *rq = to_request(wait->fence); - - /* - * If we missed the vblank, but the request is already running it - * is reasonable to assume that it will complete before the next - * vblank without our intervention, so leave RPS alone. - */ - if (!i915_request_started(rq)) - intel_rps_boost(rq); + struct intel_display *display = to_intel_display(wait->crtc->dev); + + display->parent->rps->boost(wait->fence); + dma_fence_put(wait->fence); drm_crtc_vblank_put(wait->crtc); @@ -49,6 +46,9 @@ void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, struct intel_display *display = to_intel_display(crtc->dev); struct wait_rps_boost *wait; + if (!display->parent->rps) + return; + if (!dma_fence_is_i915(fence)) return; @@ -77,12 +77,14 @@ void intel_display_rps_mark_interactive(struct intel_display *display, struct intel_atomic_state *state, bool interactive) { - struct drm_i915_private *i915 = to_i915(display->drm); + if (!display->parent->rps) + return; if (state->rps_interactive == interactive) return; - intel_rps_mark_interactive(&to_gt(i915)->rps, interactive); + display->parent->rps->mark_interactive(display->drm, interactive); + state->rps_interactive = interactive; } @@ -102,7 +104,6 @@ void ilk_display_rps_disable(struct intel_display *display) void ilk_display_rps_irq_handler(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - gen5_rps_irq_handler(&to_gt(i915)->rps); + /* We expect these to be non-NULL when running on ILK */ + display->parent->rps->ilk_irq_handler(display->drm); } diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index b01c837ab646..61d746bda462 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -6,6 +6,7 @@ #include <linux/string_helpers.h> #include <drm/intel/i915_drm.h> +#include <drm/intel/display_parent_interface.h> #include "display/intel_display_rps.h" #include "display/vlv_clock.h" @@ -2914,6 +2915,39 @@ bool i915_gpu_turbo_disable(void) } EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); +static void boost(struct dma_fence *fence) +{ + struct i915_request *rq = to_request(fence); + + /* + * If we missed the vblank, but the request is already running it + * is reasonable to assume that it will complete before the next + * vblank without our intervention, so leave RPS alone. + */ + if (!i915_request_started(rq)) + intel_rps_boost(rq); +} + +static void mark_interactive(struct drm_device *drm, bool interactive) +{ + struct drm_i915_private *i915 = to_i915(drm); + + intel_rps_mark_interactive(&to_gt(i915)->rps, interactive); +} + +static void ilk_irq_handler(struct drm_device *drm) +{ + struct drm_i915_private *i915 = to_i915(drm); + + gen5_rps_irq_handler(&to_gt(i915)->rps); +} + +const struct intel_display_rps_interface i915_display_rps_interface = { + .boost = boost, + .mark_interactive = mark_interactive, + .ilk_irq_handler = ilk_irq_handler, +}; + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftest_rps.c" #include "selftest_slpc.c" diff --git a/drivers/gpu/drm/i915/gt/intel_rps.h b/drivers/gpu/drm/i915/gt/intel_rps.h index 92fb01f5a452..5dbcebd7d4a5 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.h +++ b/drivers/gpu/drm/i915/gt/intel_rps.h @@ -128,4 +128,6 @@ static inline void intel_rps_clear_timer(struct intel_rps *rps) clear_bit(INTEL_RPS_TIMER, &rps->flags); } +extern const struct intel_display_rps_interface i915_display_rps_interface; + #endif /* INTEL_RPS_H */ diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index c97b76771917..75dfab10f44a 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -81,6 +81,7 @@ #include "gt/intel_gt_pm.h" #include "gt/intel_gt_print.h" #include "gt/intel_rc6.h" +#include "gt/intel_rps.h" #include "pxp/intel_pxp.h" #include "pxp/intel_pxp_debugfs.h" @@ -741,6 +742,7 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) static const struct intel_display_parent_interface parent = { .rpm = &i915_display_rpm_interface, + .rps = &i915_display_rps_interface, }; const struct intel_display_parent_interface *i915_driver_parent_interface(void) diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 26bedc360044..8920404545be 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -6,6 +6,7 @@ #include <linux/types.h> +struct dma_fence; struct drm_device; struct ref_tracker; @@ -25,6 +26,12 @@ struct intel_display_rpm_interface { void (*assert_unblock)(const struct drm_device *drm); }; +struct intel_display_rps_interface { + void (*boost)(struct dma_fence *fence); + void (*mark_interactive)(struct drm_device *drm, bool interactive); + void (*ilk_irq_handler)(struct drm_device *drm); +}; + /** * struct intel_display_parent_interface - services parent driver provides to display * @@ -40,6 +47,9 @@ struct intel_display_rpm_interface { struct intel_display_parent_interface { /** @rpm: Runtime PM functions */ const struct intel_display_rpm_interface *rpm; + + /** @rpm: RPS functions. Optional. */ + const struct intel_display_rps_interface *rps; }; #endif -- 2.47.3
