From 336c0eaed2bde68b592769e9cd9c12d76d2b4578 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 20 Mar 2025 17:03:55 +0200 Subject: [PATCH 01/16] drm/i915/display: add display specific runtime PM wrappers Add display specific wrappers around the i915 and xe dedicated runtime PM interfaces. There are no conversions here, just the wrappers. Implement with_intel_display_rpm() without needing to provide a local variable, which neatly narrows the scope and hides the type of the wakeref cookie. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/086b312367fa0fbd8de92e9764117aa7ff4a8cc5.1742483007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + .../gpu/drm/i915/display/intel_display_rpm.c | 68 ++++++++++++++++++ .../gpu/drm/i915/display/intel_display_rpm.h | 37 ++++++++++ drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/xe_display_rpm.c | 71 +++++++++++++++++++ 5 files changed, 178 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_display_rpm.c create mode 100644 drivers/gpu/drm/i915/display/intel_display_rpm.h create mode 100644 drivers/gpu/drm/xe/display/xe_display_rpm.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index ed05b131ed3a..c8fc271b33b7 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -247,6 +247,7 @@ i915-y += \ display/intel_display_power_map.o \ display/intel_display_power_well.o \ display/intel_display_reset.o \ + display/intel_display_rpm.o \ display/intel_display_rps.o \ display/intel_display_snapshot.o \ display/intel_display_wa.o \ diff --git a/drivers/gpu/drm/i915/display/intel_display_rpm.c b/drivers/gpu/drm/i915/display/intel_display_rpm.c new file mode 100644 index 000000000000..48da67dd0136 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_rpm.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include "i915_drv.h" +#include "intel_display_rpm.h" +#include "intel_runtime_pm.h" + +static struct intel_runtime_pm *display_to_rpm(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + return &i915->runtime_pm; +} + +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display) +{ + return intel_runtime_pm_get_raw(display_to_rpm(display)); +} + +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_runtime_pm_put_raw(display_to_rpm(display), wakeref); +} + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display) +{ + return intel_runtime_pm_get(display_to_rpm(display)); +} + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display) +{ + return intel_runtime_pm_get_if_in_use(display_to_rpm(display)); +} + +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display) +{ + return intel_runtime_pm_get_noresume(display_to_rpm(display)); +} + +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_runtime_pm_put(display_to_rpm(display), wakeref); +} + +void intel_display_rpm_put_unchecked(struct intel_display *display) +{ + intel_runtime_pm_put_unchecked(display_to_rpm(display)); +} + +bool intel_display_rpm_suspended(struct intel_display *display) +{ + return intel_runtime_pm_suspended(display_to_rpm(display)); +} + +void assert_display_rpm_held(struct intel_display *display) +{ + assert_rpm_wakelock_held(display_to_rpm(display)); +} + +void intel_display_rpm_assert_block(struct intel_display *display) +{ + disable_rpm_wakeref_asserts(display_to_rpm(display)); +} + +void intel_display_rpm_assert_unblock(struct intel_display *display) +{ + enable_rpm_wakeref_asserts(display_to_rpm(display)); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_rpm.h b/drivers/gpu/drm/i915/display/intel_display_rpm.h new file mode 100644 index 000000000000..6ef48515f84b --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_rpm.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __INTEL_DISPLAY_RPM__ +#define __INTEL_DISPLAY_RPM__ + +#include + +struct intel_display; +struct ref_tracker; + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display); +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref); + +#define __with_intel_display_rpm(__display, __wakeref) \ + for (struct ref_tracker *(__wakeref) = intel_display_rpm_get(__display); (__wakeref); \ + intel_display_rpm_put((__display), (__wakeref)), (__wakeref) = NULL) + +#define with_intel_display_rpm(__display) \ + __with_intel_display_rpm((__display), __UNIQUE_ID(wakeref)) + +/* Only for special cases. */ +bool intel_display_rpm_suspended(struct intel_display *display); + +void assert_display_rpm_held(struct intel_display *display); +void intel_display_rpm_assert_block(struct intel_display *display); +void intel_display_rpm_assert_unblock(struct intel_display *display); + +/* Only for display power implementation. */ +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display); +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref); + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display); +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display); +void intel_display_rpm_put_unchecked(struct intel_display *display); + +#endif /* __INTEL_DISPLAY_RPM__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 5ce65ccb3c08..4a99568605bd 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -181,6 +181,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/intel_fbdev_fb.o \ display/xe_display.o \ display/xe_display_misc.o \ + display/xe_display_rpm.o \ display/xe_display_rps.o \ display/xe_display_wa.o \ display/xe_dsb_buffer.o \ diff --git a/drivers/gpu/drm/xe/display/xe_display_rpm.c b/drivers/gpu/drm/xe/display/xe_display_rpm.c new file mode 100644 index 000000000000..1955153aadba --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_display_rpm.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include "intel_display_rpm.h" +#include "xe_device_types.h" +#include "xe_pm.h" + +static struct xe_device *display_to_xe(struct intel_display *display) +{ + return container_of(display, struct xe_device, display); +} + +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display) +{ + return intel_display_rpm_get(display); +} + +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_display_rpm_put(display, wakeref); +} + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display) +{ + return xe_pm_runtime_resume_and_get(display_to_xe(display)) ? INTEL_WAKEREF_DEF : NULL; +} + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display) +{ + return xe_pm_runtime_get_if_in_use(display_to_xe(display)) ? INTEL_WAKEREF_DEF : NULL; +} + +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display) +{ + xe_pm_runtime_get_noresume(display_to_xe(display)); + + return INTEL_WAKEREF_DEF; +} + +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref) +{ + if (wakeref) + xe_pm_runtime_put(display_to_xe(display)); +} + +void intel_display_rpm_put_unchecked(struct intel_display *display) +{ + xe_pm_runtime_put(display_to_xe(display)); +} + +bool intel_display_rpm_suspended(struct intel_display *display) +{ + struct xe_device *xe = display_to_xe(display); + + return pm_runtime_suspended(xe->drm.dev); +} + +void assert_display_rpm_held(struct intel_display *display) +{ + /* FIXME */ +} + +void intel_display_rpm_assert_block(struct intel_display *display) +{ + /* FIXME */ +} + +void intel_display_rpm_assert_unblock(struct intel_display *display) +{ + /* FIXME */ +} -- 2.51.0 From e1de63b84cf0e621e69b0accaed4d5504e01b7ff Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 20 Mar 2025 17:03:56 +0200 Subject: [PATCH 02/16] drm/i915/display: conversions to with_intel_display_rpm() Convert all with_intel_runtime_pm() uses to with_intel_display_rpm(). Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/888566433ca5f31b3fa3c0a192fd495d86c2f201.1742483007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_backlight.c | 5 ++--- drivers/gpu/drm/i915/display/intel_bios.c | 6 +++--- drivers/gpu/drm/i915/display/intel_hdcp.c | 5 ++--- drivers/gpu/drm/i915/display/skl_watermark.c | 9 +++++---- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 178dc6c8de80..4f3fa966c537 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -16,6 +16,7 @@ #include "intel_backlight_regs.h" #include "intel_connector.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp_aux_backlight.h" #include "intel_dsi_dcs_backlight.h" @@ -901,11 +902,9 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); - intel_wakeref_t wakeref; int ret = 0; - with_intel_runtime_pm(&i915->runtime_pm, wakeref) { + with_intel_display_rpm(display) { u32 hw_level; drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index a8d08d7d82b3..fabfcf2caa69 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -37,6 +37,7 @@ #include "i915_drv.h" #include "intel_display.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_gmbus.h" @@ -3115,7 +3116,6 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display { struct drm_i915_private *i915 = to_i915(display->drm); const struct vbt_header *vbt = NULL; - intel_wakeref_t wakeref; vbt = firmware_get_vbt(display, sizep); @@ -3127,11 +3127,11 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display * through MMIO or PCI mapping */ if (!vbt && IS_DGFX(i915)) - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash"); if (!vbt) - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM"); return vbt; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 1bf424a822f3..72a43ef6e4d2 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -22,6 +22,7 @@ #include "intel_de.h" #include "intel_display_power.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_hdcp.h" #include "intel_hdcp_gsc.h" @@ -334,9 +335,7 @@ static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *dig_port, static bool hdcp_key_loadable(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); enum i915_power_well_id id; - intel_wakeref_t wakeref; bool enabled = false; /* @@ -349,7 +348,7 @@ static bool hdcp_key_loadable(struct intel_display *display) id = SKL_DISP_PW_1; /* PG1 (power well #1) needs to be enabled */ - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) enabled = intel_display_power_well_is_enabled(display, id); /* diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 91ab8537347f..a6af5e4ba4d4 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -19,6 +19,7 @@ #include "intel_de.h" #include "intel_display.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fixed.h" @@ -4057,7 +4058,7 @@ static ssize_t skl_watermark_ipc_status_write(struct file *file, { struct seq_file *m = file->private_data; struct drm_i915_private *i915 = m->private; - intel_wakeref_t wakeref; + struct intel_display *display = &i915->display; bool enable; int ret; @@ -4065,11 +4066,11 @@ static ssize_t skl_watermark_ipc_status_write(struct file *file, if (ret < 0) return ret; - with_intel_runtime_pm(&i915->runtime_pm, wakeref) { + with_intel_display_rpm(display) { if (!skl_watermark_ipc_enabled(i915) && enable) - drm_info(&i915->drm, + drm_info(display->drm, "Enabling IPC: WM will be proper only after next commit\n"); - i915->display.wm.ipc_enabled = enable; + display->wm.ipc_enabled = enable; skl_watermark_ipc_update(i915); } -- 2.51.0 From 31630f39e7a5f6186f25e08e502b8d1c775635d3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 20 Mar 2025 17:03:57 +0200 Subject: [PATCH 03/16] drm/i915/display: use display runtime PM interfaces for for atomic state Convert intel_atomic_commit() and intel_atomic_commit_tail() to use display runtime PM interfaces. Also convert the wakeref member type to struct ref_tracker *, which is the same as intel_wakeref_t, but without the typedef. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/2682fa92089ab87429eef4d45f931839f0d32077.1742483007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 12 ++++++------ drivers/gpu/drm/i915/display/intel_display_types.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3afb85fe8536..b852ffe94a10 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -73,6 +73,7 @@ #include "intel_de.h" #include "intel_display_driver.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" @@ -7229,7 +7230,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; @@ -7443,7 +7444,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * toggling overhead at and above 60 FPS. */ intel_display_power_put_async_delay(display, POWER_DOMAIN_DC_OFF, wakeref, 17); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); /* * Defer the cleanup of the old state to a separate worker to not @@ -7515,10 +7516,9 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, { struct intel_display *display = to_intel_display(dev); struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; - state->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + state->wakeref = intel_display_rpm_get(display); /* * The intel_legacy_cursor_update() fast path takes care @@ -7552,7 +7552,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, if (ret) { drm_dbg_atomic(display->drm, "Preparing state failed with %i\n", ret); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); return ret; } @@ -7562,7 +7562,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, if (ret) { drm_atomic_helper_unprepare_planes(dev, &state->base); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 99a6fd2900b9..7d9cc430a6b8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -581,7 +581,7 @@ struct dpll { struct intel_atomic_state { struct drm_atomic_state base; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct __intel_global_objs_state *global_objs; int num_global_objs; -- 2.51.0 From 4d3408328af05a6d9399e14c7505cce0b2f2e3b9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 20 Mar 2025 17:03:58 +0200 Subject: [PATCH 04/16] drm/i915/display: convert to display runtime PM interfaces Convert i915 runtime PM interfaces to display runtime PM interfaces all over the place in display code. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/494d0bd0348e4aa99560f1aed21aaaff31706c44.1742483007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/hsw_ips.c | 8 ++++---- .../drm/i915/display/intel_display_debugfs.c | 17 +++++++---------- .../gpu/drm/i915/display/intel_display_irq.c | 6 +++--- drivers/gpu/drm/i915/display/intel_dmc.c | 9 +++++---- drivers/gpu/drm/i915/display/intel_dp.c | 5 ++--- drivers/gpu/drm/i915/display/intel_dpt.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_dsb.c | 17 +++++++++-------- drivers/gpu/drm/i915/display/intel_fb_pin.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_fbc.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_fbdev.c | 11 +++++++---- drivers/gpu/drm/i915/display/intel_hotplug.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_psr.c | 17 ++++++----------- 12 files changed, 59 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 674a0e5f0858..4307e2ed03d9 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -10,6 +10,7 @@ #include "i915_reg.h" #include "intel_color_regs.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_pcode.h" @@ -344,10 +345,9 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_crtc *crtc = m->private; struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); seq_printf(m, "Enabled by kernel parameter: %s\n", str_yes_no(display->params.enable_ips)); @@ -361,7 +361,7 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) seq_puts(m, "Currently: disabled\n"); } - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index f42b5a69eed5..4c784bb7e14b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -24,6 +24,7 @@ #include "intel_display_debugfs_params.h" #include "intel_display_power.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" @@ -580,13 +581,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) static int i915_display_info(struct seq_file *m, void *unused) { struct intel_display *display = node_to_intel_display(m->private); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); drm_modeset_lock_all(display->drm); @@ -605,7 +605,7 @@ static int i915_display_info(struct seq_file *m, void *unused) drm_modeset_unlock_all(display->drm); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } @@ -690,14 +690,11 @@ static bool intel_lpsp_power_well_enabled(struct intel_display *display, enum i915_power_well_id power_well_id) { - struct drm_i915_private *i915 = to_i915(display->drm); - intel_wakeref_t wakeref; bool is_enabled; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); - is_enabled = intel_display_power_well_is_enabled(display, - power_well_id); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + with_intel_display_rpm(display) + is_enabled = intel_display_power_well_is_enabled(display, + power_well_id); return is_enabled; } diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index d9f9b9f78abb..d2a35e3630b1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -14,6 +14,7 @@ #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_irq.h" +#include "intel_display_rpm.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_dmc_wl.h" @@ -1517,10 +1518,9 @@ void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir) void gen11_display_irq_handler(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); u32 disp_ctl; - disable_rpm_wakeref_asserts(&i915->runtime_pm); + intel_display_rpm_assert_block(display); /* * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ * for the display related bits. @@ -1531,7 +1531,7 @@ void gen11_display_irq_handler(struct intel_display *display) gen8_de_irq_handler(display, disp_ctl); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); - enable_rpm_wakeref_asserts(&i915->runtime_pm); + intel_display_rpm_assert_unblock(display); } static void i915gm_irq_cstate_wa_enable(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index fa6944e55d95..eb6b47ba0870 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -28,6 +28,7 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_step.h" @@ -595,7 +596,7 @@ void intel_dmc_load_program(struct intel_display *display) disable_all_event_handlers(display); - assert_rpm_wakelock_held(&i915->runtime_pm); + assert_display_rpm_held(display); preempt_disable(); @@ -1237,13 +1238,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) struct intel_display *display = m->private; struct drm_i915_private *i915 = to_i915(display->drm); struct intel_dmc *dmc = display_to_dmc(display); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; if (!HAS_DMC(display)) return -ENODEV; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); seq_printf(m, "fw loaded: %s\n", @@ -1299,7 +1300,7 @@ out: intel_de_read(display, DMC_SSP_BASE)); seq_printf(m, "htp: 0x%08x\n", intel_de_read(display, DMC_HTP_SKL)); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7d074770d793..e3821ccfabe3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -62,6 +62,7 @@ #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" @@ -87,7 +88,6 @@ #include "intel_pfit.h" #include "intel_pps.h" #include "intel_psr.h" -#include "intel_runtime_pm.h" #include "intel_quirks.h" #include "intel_tc.h" #include "intel_vdsc.h" @@ -6144,13 +6144,12 @@ enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_dp *intel_dp = &dig_port->dp; u8 dpcd[DP_RECEIVER_CAP_SIZE]; if (dig_port->base.type == INTEL_OUTPUT_EDP && (long_hpd || - intel_runtime_pm_suspended(&i915->runtime_pm) || + intel_display_rpm_suspended(display) || !intel_pps_have_panel_power_or_vdd(intel_dp))) { /* * vdd off can generate a long/short pulse on eDP which diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 0d8ebe38226e..43bd97e4f589 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -9,6 +9,7 @@ #include "gt/gen8_ppgtt.h" #include "i915_drv.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" @@ -127,7 +128,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, struct drm_i915_private *i915 = vm->i915; struct intel_display *display = &i915->display; struct i915_dpt *dpt = i915_vm_to_dpt(vm); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct i915_vma *vma; void __iomem *iomem; struct i915_gem_ww_ctx ww; @@ -137,7 +138,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, if (i915_gem_object_is_stolen(dpt->obj)) pin_flags |= PIN_MAPPABLE; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); atomic_inc(&display->restore.pending_fb_pin); for_i915_gem_ww(&ww, err, true) { @@ -169,7 +170,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, dpt->obj->mm.dirty = true; atomic_dec(&display->restore.pending_fb_pin); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return err ? ERR_PTR(err) : vma; } diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 9fc4003d1579..0ddcdedf5453 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -11,6 +11,7 @@ #include "i915_reg.h" #include "intel_crtc.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dsb.h" #include "intel_dsb_buffer.h" @@ -795,22 +796,22 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, enum intel_dsb_id dsb_id, unsigned int max_cmds) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - intel_wakeref_t wakeref; + struct intel_display *display = to_intel_display(state); + struct ref_tracker *wakeref; struct intel_dsb *dsb; unsigned int size; - if (!HAS_DSB(i915)) + if (!HAS_DSB(display)) return NULL; - if (!i915->display.params.enable_dsb) + if (!display->params.enable_dsb) return NULL; dsb = kzalloc(sizeof(*dsb), GFP_KERNEL); if (!dsb) goto out; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); /* ~1 qword per instruction, full cachelines */ size = ALIGN(max_cmds * 8, CACHELINE_BYTES); @@ -818,7 +819,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, if (!intel_dsb_buffer_create(crtc, &dsb->dsb_buf, size)) goto out_put_rpm; - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); dsb->id = dsb_id; dsb->crtc = crtc; @@ -831,10 +832,10 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, return dsb; out_put_rpm: - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); kfree(dsb); out: - drm_info_once(&i915->drm, + drm_info_once(display->drm, "[CRTC:%d:%s] DSB %d queue setup failed, will fallback to MMIO for display HW programming\n", crtc->base.base.id, crtc->base.name, dsb_id); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index 30ac9b089ad6..c648ab8a93d7 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -12,6 +12,7 @@ #include "i915_drv.h" #include "intel_atomic_plane.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" @@ -117,7 +118,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, struct drm_i915_private *dev_priv = to_i915(dev); struct drm_gem_object *_obj = intel_fb_bo(fb); struct drm_i915_gem_object *obj = to_intel_bo(_obj); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct i915_gem_ww_ctx ww; struct i915_vma *vma; unsigned int pinctl; @@ -136,7 +137,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, * intel_runtime_pm_put(), so it is correct to wrap only the * pin/unpin/fence and not more. */ - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); atomic_inc(&display->restore.pending_fb_pin); @@ -215,7 +216,7 @@ err: vma = ERR_PTR(ret); atomic_dec(&display->restore.pending_fb_pin); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return vma; } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index b6978135e8ad..4f9b4fc526ea 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -55,6 +55,7 @@ #include "intel_cdclk.h" #include "intel_de.h" #include "intel_display_device.h" +#include "intel_display_rpm.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_display_wa.h" @@ -2120,13 +2121,12 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_fbc *fbc = m->private; struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_plane *plane; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; drm_modeset_lock_all(display->drm); - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); mutex_lock(&fbc->lock); if (fbc->active) { @@ -2151,7 +2151,7 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) } mutex_unlock(&fbc->lock); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); drm_modeset_unlock_all(display->drm); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index adc19d5607de..369f46286e95 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -50,6 +50,7 @@ #include "i915_drv.h" #include "i915_vma.h" #include "intel_bo.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fb_pin.h" @@ -213,7 +214,8 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, struct intel_framebuffer *fb = ifbdev->fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); - intel_wakeref_t wakeref; + struct intel_display *display = to_intel_display(dev); + struct ref_tracker *wakeref; struct fb_info *info; struct i915_vma *vma; unsigned long flags = 0; @@ -247,7 +249,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, sizes->fb_height = fb->base.height; } - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); /* Pin the GGTT vma for our access via info->screen_base. * This also validates that any existing fb inherited from the @@ -299,14 +301,15 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, ifbdev->vma = vma; ifbdev->vma_flags = flags; - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; out_unpin: intel_fb_unpin_vma(vma, flags); out_unlock: - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); + return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index fcc3f546cb97..dce9cde03d70 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -30,6 +30,7 @@ #include "i915_irq.h" #include "intel_connector.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_hdcp.h" #include "intel_hotplug.h" @@ -278,10 +279,10 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; enum hpd_pin pin; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); spin_lock_irq(&dev_priv->irq_lock); @@ -309,7 +310,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) spin_unlock_irq(&dev_priv->irq_lock); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } static enum intel_hotplug_state diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 4e938bad808c..50a22cd8d84a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -36,6 +36,7 @@ #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_irq.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" @@ -3728,10 +3729,9 @@ static void intel_psr_print_mode(struct intel_dp *intel_dp, static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; struct intel_psr *psr = &intel_dp->psr; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool enabled; u32 val, psr2_ctl; @@ -3740,7 +3740,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) if (!(psr->sink_support || psr->sink_panel_replay_support)) return 0; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); mutex_lock(&psr->lock); intel_psr_print_mode(intel_dp, m); @@ -3822,7 +3822,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) unlock: mutex_unlock(&psr->lock); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } @@ -3853,9 +3853,7 @@ static int i915_edp_psr_debug_set(void *data, u64 val) { struct intel_display *display = data; - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; - intel_wakeref_t wakeref; int ret = -ENODEV; if (!HAS_PSR(display)) @@ -3866,12 +3864,9 @@ i915_edp_psr_debug_set(void *data, u64 val) drm_dbg_kms(display->drm, "Setting PSR debug to %llx\n", val); - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - // TODO: split to each transcoder's PSR debug state - ret = intel_psr_debug_set(intel_dp, val); - - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + with_intel_display_rpm(display) + ret = intel_psr_debug_set(intel_dp, val); } return ret; -- 2.51.0 From b5de8f445a5f0b9ea1504f89900702d67d2ece2b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 20 Mar 2025 17:03:59 +0200 Subject: [PATCH 05/16] drm/i915/power: convert to display runtime PM interfaces Finish the conversions to display specific runtime PM interfaces in the power code. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/b08a074d466a966b7f0fda9ef35c8ef81d180ebb.1742483007.git.jani.nikula@intel.com --- .../drm/i915/display/intel_display_power.c | 63 ++++++++----------- .../i915/display/intel_display_power_well.c | 4 +- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index f7171e6932dc..adeb4408eb49 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -16,6 +16,7 @@ #include "intel_display_power.h" #include "intel_display_power_map.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_mchbar_regs.h" @@ -204,7 +205,7 @@ static bool __intel_display_power_is_enabled(struct intel_display *display, struct i915_power_well *power_well; bool is_enabled; - if (pm_runtime_suspended(display->drm->dev)) + if (intel_display_rpm_suspended(display)) return false; is_enabled = true; @@ -455,7 +456,6 @@ static bool intel_display_power_grab_async_put_ref(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; bool ret = false; @@ -473,8 +473,8 @@ intel_display_power_grab_async_put_ref(struct intel_display *display, goto out_verify; cancel_async_put_work(power_domains, false); - intel_runtime_pm_put_raw(&dev_priv->runtime_pm, - fetch_and_zero(&power_domains->async_put_wakeref)); + intel_display_rpm_put_raw(display, + fetch_and_zero(&power_domains->async_put_wakeref)); out_verify: verify_async_put_domains_state(power_domains); @@ -512,9 +512,10 @@ __intel_display_power_get_domain(struct intel_display *display, intel_wakeref_t intel_display_power_get(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_wakeref_t wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + struct ref_tracker *wakeref; + + wakeref = intel_display_rpm_get(display); mutex_lock(&power_domains->lock); __intel_display_power_get_domain(display, domain); @@ -539,12 +540,11 @@ intel_wakeref_t intel_display_power_get_if_enabled(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool is_enabled; - wakeref = intel_runtime_pm_get_if_in_use(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get_if_in_use(display); if (!wakeref) return NULL; @@ -560,7 +560,7 @@ intel_display_power_get_if_enabled(struct intel_display *display, mutex_unlock(&power_domains->lock); if (!is_enabled) { - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); wakeref = NULL; } @@ -623,12 +623,10 @@ release_async_put_domains(struct i915_power_domains *power_domains, struct intel_display *display = container_of(power_domains, struct intel_display, power.domains); - struct drm_i915_private *dev_priv = to_i915(display->drm); - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; enum intel_display_power_domain domain; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get_noresume(rpm); + wakeref = intel_display_rpm_get_noresume(display); for_each_power_domain(domain, mask) { /* Clear before put, so put's sanity check is happy. */ @@ -636,7 +634,7 @@ release_async_put_domains(struct i915_power_domains *power_domains, __intel_display_power_put_domain(display, domain); } - intel_runtime_pm_put(rpm, wakeref); + intel_display_rpm_put(display, wakeref); } static void @@ -644,11 +642,10 @@ intel_display_power_put_async_work(struct work_struct *work) { struct intel_display *display = container_of(work, struct intel_display, power.domains.async_put_work.work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; - intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm); - intel_wakeref_t old_work_wakeref = NULL; + struct ref_tracker *new_work_wakeref, *old_work_wakeref = NULL; + + new_work_wakeref = intel_display_rpm_get_raw(display); mutex_lock(&power_domains->lock); @@ -688,9 +685,9 @@ out_verify: mutex_unlock(&power_domains->lock); if (old_work_wakeref) - intel_runtime_pm_put_raw(rpm, old_work_wakeref); + intel_display_rpm_put_raw(display, old_work_wakeref); if (new_work_wakeref) - intel_runtime_pm_put_raw(rpm, new_work_wakeref); + intel_display_rpm_put_raw(display, new_work_wakeref); } /** @@ -711,10 +708,10 @@ void __intel_display_power_put_async(struct intel_display *display, intel_wakeref_t wakeref, int delay_ms) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - struct intel_runtime_pm *rpm = &i915->runtime_pm; - intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm); + struct ref_tracker *work_wakeref; + + work_wakeref = intel_display_rpm_get_raw(display); delay_ms = delay_ms >= 0 ? delay_ms : 100; @@ -746,9 +743,9 @@ out_verify: mutex_unlock(&power_domains->lock); if (work_wakeref) - intel_runtime_pm_put_raw(rpm, work_wakeref); + intel_display_rpm_put_raw(display, work_wakeref); - intel_runtime_pm_put(rpm, wakeref); + intel_display_rpm_put(display, wakeref); } /** @@ -765,7 +762,6 @@ out_verify: */ void intel_display_power_flush_work(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; intel_wakeref_t work_wakeref; @@ -786,7 +782,7 @@ out_verify: mutex_unlock(&power_domains->lock); if (work_wakeref) - intel_runtime_pm_put_raw(&i915->runtime_pm, work_wakeref); + intel_display_rpm_put_raw(display, work_wakeref); } /** @@ -824,10 +820,8 @@ void intel_display_power_put(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - __intel_display_power_put(display, domain); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } #else /** @@ -846,10 +840,8 @@ void intel_display_power_put(struct intel_display *display, void intel_display_power_put_unchecked(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - __intel_display_power_put(display, domain); - intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); + intel_display_rpm_put_unchecked(display); } #endif @@ -1979,7 +1971,6 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) */ void intel_power_domains_driver_remove(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&display->power.domains.init_wakeref); @@ -1993,7 +1984,7 @@ void intel_power_domains_driver_remove(struct intel_display *display) intel_power_domains_verify_state(display); /* Keep the power well enabled, but cancel its rpm wakeref. */ - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } /** diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index b03a95ef64da..751e49b880d6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -13,6 +13,7 @@ #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dkl_phy.h" #include "intel_dkl_phy_regs.h" @@ -812,7 +813,8 @@ static void assert_can_enable_dc5(struct intel_display *display) (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5), "DC5 already programmed to be enabled.\n"); - assert_rpm_wakelock_held(&dev_priv->runtime_pm); + + assert_display_rpm_held(display); assert_dmc_loaded(display); } -- 2.51.0 From f5c3bcd23afb4b2888c8f6eaa608b8a0c70091e4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 20 Mar 2025 17:04:00 +0200 Subject: [PATCH 06/16] drm/xe/compat: remove intel_runtime_pm.h Now that all display code has been converted to display specific runtime PM interfaces, there's no need for the compat header anymore. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/037ed1f38c96715c76514e9eb7069b896ce06ba1.1742483007.git.jani.nikula@intel.com --- .../gpu/drm/xe/compat-i915-headers/i915_drv.h | 1 - .../xe/compat-i915-headers/intel_runtime_pm.h | 76 ------------------- 2 files changed, 77 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h index dfec5108d2c3..f89bd5e3520d 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -13,7 +13,6 @@ #include #include "i915_utils.h" -#include "intel_runtime_pm.h" #include "xe_device.h" /* for xe_device_has_flat_ccs() */ #include "xe_device_types.h" diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h deleted file mode 100644 index 274042bff1be..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h +++ /dev/null @@ -1,76 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef __INTEL_RUNTIME_PM_H__ -#define __INTEL_RUNTIME_PM_H__ - -#include "intel_wakeref.h" -#include "xe_device_types.h" -#include "xe_pm.h" - -#define intel_runtime_pm xe_runtime_pm - -static inline void disable_rpm_wakeref_asserts(void *rpm) -{ -} - -static inline void enable_rpm_wakeref_asserts(void *rpm) -{ -} - -static inline bool -intel_runtime_pm_suspended(struct xe_runtime_pm *pm) -{ - struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - - return pm_runtime_suspended(xe->drm.dev); -} - -static inline intel_wakeref_t intel_runtime_pm_get(struct xe_runtime_pm *pm) -{ - struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - - return xe_pm_runtime_resume_and_get(xe) ? INTEL_WAKEREF_DEF : NULL; -} - -static inline intel_wakeref_t intel_runtime_pm_get_if_in_use(struct xe_runtime_pm *pm) -{ - struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - - return xe_pm_runtime_get_if_in_use(xe) ? INTEL_WAKEREF_DEF : NULL; -} - -static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm *pm) -{ - struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - - xe_pm_runtime_get_noresume(xe); - - return INTEL_WAKEREF_DEF; -} - -static inline void intel_runtime_pm_put_unchecked(struct xe_runtime_pm *pm) -{ - struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - - xe_pm_runtime_put(xe); -} - -static inline void intel_runtime_pm_put(struct xe_runtime_pm *pm, intel_wakeref_t wakeref) -{ - if (wakeref) - intel_runtime_pm_put_unchecked(pm); -} - -#define intel_runtime_pm_get_raw intel_runtime_pm_get -#define intel_runtime_pm_put_raw intel_runtime_pm_put -#define assert_rpm_wakelock_held(x) do { } while (0) -#define assert_rpm_raw_wakeref_held(x) do { } while (0) - -#define with_intel_runtime_pm(rpm, wf) \ - for ((wf) = intel_runtime_pm_get(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) - -#endif -- 2.51.0 From c63d00e388f2240c732bf1c89dc48bc8ff98089d Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Fri, 28 Feb 2025 20:55:32 +0530 Subject: [PATCH 07/16] drm/i915/vdsc: Use the DSC config tables for DSI panels Some DSI panel vendors end up hardcoding PPS params because of which it does not listen to the params sent from the source. We use the default config tables for DSI panels when using DSC 1.1 rather than calculate our own rc parameters. --v2 -Use intel_crtc_has_type [Jani] --v4 -Use a function to check Mipi dsi dsc 1.1 condition [Ankit] -Add documentation for using this condition [Ankit] -Rebase --v5 -Pass only the crtc_state [Jani] -Fixup the comment [Jani] -Check for dsc major version [Jani] -Use co-developed-by tag [Jani] --v6 -Add more definition of the issue and solution in the comment [Ankit] Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13719 Co-developed-by: William Tseng Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250228152531.403026-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 3ed64c17bdff..470c170897e5 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -259,6 +259,15 @@ static int intel_dsc_slice_dimensions_valid(struct intel_crtc_state *pipe_config return 0; } +static bool is_dsi_dsc_1_1(struct intel_crtc_state *crtc_state) +{ + struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; + + return vdsc_cfg->dsc_version_major == 1 && + vdsc_cfg->dsc_version_minor == 1 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI); +} + int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(pipe_config); @@ -317,8 +326,19 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) * From XE_LPD onwards we supports compression bpps in steps of 1 * upto uncompressed bpp-1, hence add calculations for all the rc * parameters + * + * We don't want to calculate all rc parameters when the panel + * is MIPI DSI and it's using DSC 1.1. The reason being that some + * DSI panels vendors have hardcoded PPS params in the VBT causing + * the parameters sent from the source which are derived through + * interpolation to differ from the params the panel expects. + * This causes a noise in the display. + * Furthermore for DSI panels we are currently using bits_per_pixel + * (compressed bpp) hardcoded from VBT, (unlike other encoders where we + * find the optimum compressed bpp) so dont need to rely on interpolation, + * as we can get the required rc parameters from the tables. */ - if (DISPLAY_VER(display) >= 13) { + if (DISPLAY_VER(display) >= 13 && !is_dsi_dsc_1_1(pipe_config)) { calculate_rc_params(vdsc_cfg); } else { if ((compressed_bpp == 8 || -- 2.51.0 From fe8fd8af6de6bc76506f739b9fd1acb1837cfa02 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Sat, 22 Mar 2025 10:13:44 +0530 Subject: [PATCH 08/16] drm/i915/display: Add fixed_rr to crtc_state dump MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add fixed refresh rate mode in crtc_state dump. VRR Timing Generator is running in fixed refresh rate mode when vrr.vmin = vrr.vmax = vrr.flipline. v2: s/fixed_rr/fixed rr for consistency with the other stuff. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250322044345.3827137-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 3 ++- drivers/gpu/drm/i915/display/intel_vrr.c | 1 - drivers/gpu/drm/i915/display/intel_vrr.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 599ddce96371..0f0fad329b89 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -294,8 +294,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", + drm_printf(&p, "vrr: %s, fixed rr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", str_yes_no(pipe_config->vrr.enable), + str_yes_no(intel_vrr_is_fixed_rr(pipe_config)), pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end); diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 622a70e21737..aa65a6933ddb 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -602,7 +602,6 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) intel_vrr_set_fixed_rr_timings(old_crtc_state); } -static bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state) { return crtc_state->vrr.flipline && diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 514822577e8a..65d2b0eead51 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -35,5 +35,6 @@ int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state); int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state); +bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_VRR_H__ */ -- 2.51.0 From 0ead88112bf69da4ee54d3f26e21258f00640865 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Sat, 22 Mar 2025 10:13:45 +0530 Subject: [PATCH 09/16] drm/i915/vrr: Avoid reading vrr.enable based on fixed_rr check MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Currently, vrr.enable is intended only for variable refresh rate timings. At this point, we do not set fixed refresh rate timings, but the GOP can, which creates a problem during the readback of vrr.enable. The GOP enables the VRR timing generator with fixed timings, while the driver only recognizes the VRR timing generator as enabled with variable timings. This discrepancy causes an issue due to the fixed refresh rate check during readback. Since the VRR timing generator is enabled and we do not support fixed timings, the readback should set vrr.enable so that the driver can disable the VRR timing generator. However, the current check does not allow this. Therefore, remove the fixed refresh rate check during readback. Fixes: 27217f9d1856 ("drm/i915/vrr: Track vrr.enable only for variable timing") Cc: Ankit Nautiyal Cc: Ville Syrjälä Cc: Jani Nikula Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250322044345.3827137-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index aa65a6933ddb..6bdcdfed4b9b 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -657,8 +657,7 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) } } - crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE && - !intel_vrr_is_fixed_rr(crtc_state); + crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE; /* * #TODO: For Both VRR and CMRR the flag I915_MODE_FLAG_VRR is set for mode_flags. -- 2.51.0 From 88c1f9a4d36de61f87cc52aac670020b13d1ccaa Mon Sep 17 00:00:00 2001 From: Mohammed Thasleem Date: Fri, 21 Mar 2025 18:07:07 +0530 Subject: [PATCH 10/16] drm/i915/dmc: Create debugfs entry for dc6 counter Starting from MTL we don't have a platform agnostic way to validate DC6 state due to dc6 counter has been removed to validate DC state. The goal is to validate that the display HW can reach the DC6 power state. There is no HW DC6 residency counter (and there wasn't such a counter earlier either), so an alternative way is required. According to the HW team the display driver has programmed everything correctly in order to allow the DC6 power state if the DC5 power state is reached (indicated by the HW DC5 residency counter incrementing) and DC6 is enabled by the driver. Driver could take a snapshot of the DC5 residency counter right after it enables DC6 (dc5_residency_start) and increment the SW DC6 residency counter right before it disables DC6 or when user space reads the DC6 counter. So the driver would update the counter at these two points in the following way: dc6_residency_counter += dc5_current_count - dc5_start_count v2: Update the discription. (Imre) Read dc5 count during dc6 enable and disable then and update dc6 residency counter. (Imre) Remove variable from dmc structure. (Jani) Updated the subject title. v3: Add i915_power_domains lock to updated dc6 count in debugfs. (Imre) Use flags to check dc6 enable/disable states. (Imre) Move the display version check and counter read/update to a helper. (Imre) Resize the variable length. (Rodrigo) Use old dc6 debugfs entry for every platform. (Rodrigo) v4: Remove superfluous whitespace. (Jani) Read DMC registers in intel_dmc.c (Jani) Rename dc6_en_dis to dc6_enabled and change its type to bool. (Jani) Rename update_dc6_count and move it to intel_dmc.c (Jani) Rename dc6_en_dis to start_tracking. (Imre) Have lock for dc6 state read aswelll. (Imre) Keep the existing way print 'DC5 -> DC6 count' along with new 'DC6 Allowed Count' print. (Imre) Add counters in intel_dmc struct. (Imre) Have interface to return dc6 allowed count. (Imre) Rename dc6_count to dc6_allowed_count. (Rodrigo) v5: Rename counters and move in to dc6_allowed structure. (Imre) Order declaration lines in decreasing line length. (Imre) Update start_tacking logic. (Imre) Move get couner inside lock and DISPLAY_VER code to helper. (Imre) v6: Change intel_dmc_get_dc6_allowed_count return type to bool. (Imre) Update debugfs print to better allien with old print. (Imre) Remove braces at if/else for signle line statements. (Imre) v7: Remove in line variable declaration. (Imre) v8: Rebase the changes. Signed-off-by: Mohammed Thasleem Reviewed-by: Imre Deak Signed-off-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20250321123707.287745-1-mohammed.thasleem@intel.com --- .../i915/display/intel_display_power_well.c | 11 +++- drivers/gpu/drm/i915/display/intel_dmc.c | 50 ++++++++++++++++++- drivers/gpu/drm/i915/display/intel_dmc.h | 1 + 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 751e49b880d6..b9b4359751cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -749,8 +749,9 @@ void gen9_sanitize_dc_state(struct intel_display *display) void gen9_set_dc_state(struct intel_display *display, u32 state) { struct i915_power_domains *power_domains = &display->power.domains; - u32 val; + bool dc6_was_enabled, enable_dc6; u32 mask; + u32 val; if (!HAS_DISPLAY(display)) return; @@ -769,11 +770,19 @@ void gen9_set_dc_state(struct intel_display *display, u32 state) drm_err(display->drm, "DC state mismatch (0x%x -> 0x%x)\n", power_domains->dc_state, val & mask); + enable_dc6 = state & DC_STATE_EN_UPTO_DC6; + dc6_was_enabled = val & DC_STATE_EN_UPTO_DC6; + if (!dc6_was_enabled && enable_dc6) + intel_dmc_update_dc6_allowed_count(display, true); + val &= ~mask; val |= state; gen9_write_dc_state(display, val); + if (!enable_dc6 && dc6_was_enabled) + intel_dmc_update_dc6_allowed_count(display, false); + power_domains->dc_state = val & mask; } diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index eb6b47ba0870..98f80a6c63e8 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -29,6 +29,7 @@ #include "i915_reg.h" #include "intel_de.h" #include "intel_display_rpm.h" +#include "intel_display_power_well.h" #include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_step.h" @@ -58,6 +59,10 @@ struct intel_dmc { const char *fw_path; u32 max_fw_size; /* bytes */ u32 version; + struct { + u32 dc5_start; + u32 count; + } dc6_allowed; struct dmc_fw_info { u32 mmio_count; i915_reg_t mmioaddr[20]; @@ -1233,6 +1238,44 @@ void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct DMC_VERSION_MINOR(snapshot->version)); } +void intel_dmc_update_dc6_allowed_count(struct intel_display *display, + bool start_tracking) +{ + struct intel_dmc *dmc = display_to_dmc(display); + u32 dc5_cur_count; + + if (DISPLAY_VER(dmc->display) < 14) + return; + + dc5_cur_count = intel_de_read(dmc->display, DG1_DMC_DEBUG_DC5_COUNT); + + if (!start_tracking) + dmc->dc6_allowed.count += dc5_cur_count - dmc->dc6_allowed.dc5_start; + + dmc->dc6_allowed.dc5_start = dc5_cur_count; +} + +static bool intel_dmc_get_dc6_allowed_count(struct intel_display *display, u32 *count) +{ + struct i915_power_domains *power_domains = &display->power.domains; + struct intel_dmc *dmc = display_to_dmc(display); + bool dc6_enabled; + + if (DISPLAY_VER(display) < 14) + return false; + + mutex_lock(&power_domains->lock); + dc6_enabled = intel_de_read(display, DC_STATE_EN) & + DC_STATE_EN_UPTO_DC6; + if (dc6_enabled) + intel_dmc_update_dc6_allowed_count(display, false); + + *count = dmc->dc6_allowed.count; + mutex_unlock(&power_domains->lock); + + return true; +} + static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_display *display = m->private; @@ -1240,6 +1283,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) struct intel_dmc *dmc = display_to_dmc(display); struct ref_tracker *wakeref; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; + u32 dc6_allowed_count; if (!HAS_DMC(display)) return -ENODEV; @@ -1288,7 +1332,11 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) } seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(display, dc5_reg)); - if (i915_mmio_reg_valid(dc6_reg)) + + if (intel_dmc_get_dc6_allowed_count(display, &dc6_allowed_count)) + seq_printf(m, "DC5 -> DC6 allowed count: %d\n", + dc6_allowed_count); + else if (i915_mmio_reg_valid(dc6_reg)) seq_printf(m, "DC5 -> DC6 count: %d\n", intel_de_read(display, dc6_reg)); diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 44cecef98e73..c78426eb4cd5 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -26,6 +26,7 @@ void intel_dmc_debugfs_register(struct intel_display *display); struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display); void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p); +void intel_dmc_update_dc6_allowed_count(struct intel_display *display, bool start_tracking); void assert_dmc_loaded(struct intel_display *display); -- 2.51.0 From ccdb96cc7186c51045d707503d87cd220c5fed26 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 21 Mar 2025 11:45:28 +0200 Subject: [PATCH 11/16] drm/i915/fbc: keep FBC disabled if selective update is on in xe2lpd MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit FBC was disabled in case PSR2 selective update in display 12 to 14 as part of a wa. From xe2lpd onwards there is a logic to be implemented to decide between FBC and selective update. Until that logic is implemented keep FBC disabled in case selective update is enabled. v1: updated patch description and some explanation and todo Signed-off-by: Vinod Govindapillai Reviewed-by: Jouni Högander Link: https://patchwork.freedesktop.org/patch/msgid/20250321094529.197397-2-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 4f9b4fc526ea..d75e3c7eaa44 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1465,13 +1465,15 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * Recommendation is to keep this combination disabled * Bspec: 50422 HSD: 14010260002 * - * In Xe3, PSR2 selective fetch and FBC dirty rect feature cannot - * coexist. So if PSR2 selective fetch is supported then mark that - * FBC is not supported. - * TODO: Need a logic to decide between PSR2 and FBC Dirty rect + * TODO: Implement a logic to select between PSR2 selective fetch and + * FBC based on Bspec: 68881 in xe2lpd onwards. + * + * As we still see some strange underruns in those platforms while + * disabling PSR2, keep FBC disabled in case of selective update is on + * until the selection logic is implemented. */ - if ((IS_DISPLAY_VER(display, 12, 14) || HAS_FBC_DIRTY_RECT(display)) && - crtc_state->has_sel_update && !crtc_state->has_panel_replay) { + if (DISPLAY_VER(display) >= 12 && crtc_state->has_sel_update && + !crtc_state->has_panel_replay) { plane_state->no_fbc_reason = "PSR2 enabled"; return 0; } -- 2.51.0 From 11938353bfbfaf1acad000bac45adc296748f2f1 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 21 Mar 2025 11:45:29 +0200 Subject: [PATCH 12/16] drm/i915/fbc: update the panel_replay dependency in fbc wa's MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There are two panel_replay scenarios fbc wa need to be aware of, panel replay with and without selective update capability. Panel replay without selective update don't have any fbc wa. So keep the fbc psr1 wa as it is. The current fbc psr2 wa is mainly about selective fetch and we need to apply the fbc wa if selective fetch is on - irrespective of panel replay. Hence we can't exclude panel replay from the fbc psr2 wa. v1: keep panel_replay exclusion in PSR1 case (Jouni) Patch description updated Bspec: 66624, 50442 Signed-off-by: Vinod Govindapillai Reviewed-by: Jouni Högander Link: https://patchwork.freedesktop.org/patch/msgid/20250321094529.197397-3-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index d75e3c7eaa44..ea3123874cbf 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1472,9 +1472,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * disabling PSR2, keep FBC disabled in case of selective update is on * until the selection logic is implemented. */ - if (DISPLAY_VER(display) >= 12 && crtc_state->has_sel_update && - !crtc_state->has_panel_replay) { - plane_state->no_fbc_reason = "PSR2 enabled"; + if (DISPLAY_VER(display) >= 12 && crtc_state->has_sel_update) { + plane_state->no_fbc_reason = "Selective update enabled"; return 0; } -- 2.51.0 From 327e30123cafcb45c0fc5843da0367b90332999d Mon Sep 17 00:00:00 2001 From: Vivek Kasireddy Date: Mon, 24 Mar 2025 10:22:33 -0700 Subject: [PATCH 13/16] drm/i915/xe2hpd: Identify the memory type for SKUs with GDDR + ECC Some SKUs of Xe2_HPD platforms (such as BMG) have GDDR memory type with ECC enabled. We need to identify this scenario and add a new case in xelpdp_get_dram_info() to handle it. In addition, the derating value needs to be adjusted accordingly to compensate for the limited bandwidth. Bspec: 64602 Cc: Matt Roper Fixes: 3adcf970dc7e ("drm/xe/bmg: Drop force_probe requirement") Cc: stable@vger.kernel.org Signed-off-by: Vivek Kasireddy Reviewed-by: Matt Roper Acked-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20250324-tip-v2-1-38397de319f8@intel.com Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/i915/display/intel_bw.c | 12 ++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/soc/intel_dram.c | 4 ++++ drivers/gpu/drm/xe/xe_device_types.h | 1 + 4 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index dc7612658a9d..bb81efec08a0 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -250,6 +250,7 @@ static int icl_get_qgv_points(struct intel_display *display, qi->deinterleave = 4; break; case INTEL_DRAM_GDDR: + case INTEL_DRAM_GDDR_ECC: qi->channel_width = 32; break; default: @@ -404,6 +405,12 @@ static const struct intel_sa_info xe2_hpd_sa_info = { /* Other values not used by simplified algorithm */ }; +static const struct intel_sa_info xe2_hpd_ecc_sa_info = { + .derating = 45, + .deprogbwlimit = 53, + /* Other values not used by simplified algorithm */ +}; + static const struct intel_sa_info xe3lpd_sa_info = { .deburst = 32, .deprogbwlimit = 65, /* GB/s */ @@ -756,11 +763,16 @@ static unsigned int icl_qgv_bw(struct intel_display *display, void intel_bw_init_hw(struct intel_display *display) { + const struct dram_info *dram_info = &to_i915(display->drm)->dram_info; + if (!HAS_DISPLAY(display)) return; if (DISPLAY_VER(display) >= 30) tgl_get_bw_info(display, &xe3lpd_sa_info); + else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx && + dram_info->type == INTEL_DRAM_GDDR_ECC) + xe2_hpd_get_bw_info(display, &xe2_hpd_ecc_sa_info); else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) xe2_hpd_get_bw_info(display, &xe2_hpd_sa_info); else if (DISPLAY_VER(display) >= 14) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ffc346379cc2..54538b6f85df 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -305,6 +305,7 @@ struct drm_i915_private { INTEL_DRAM_DDR5, INTEL_DRAM_LPDDR5, INTEL_DRAM_GDDR, + INTEL_DRAM_GDDR_ECC, } type; u8 num_qgv_points; u8 num_psf_gv_points; diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index 9e310f4099f4..f60eedb0e92c 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -687,6 +687,10 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915) drm_WARN_ON(&i915->drm, !IS_DGFX(i915)); dram_info->type = INTEL_DRAM_GDDR; break; + case 9: + drm_WARN_ON(&i915->drm, !IS_DGFX(i915)); + dram_info->type = INTEL_DRAM_GDDR_ECC; + break; default: MISSING_CASE(val); return -EINVAL; diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 4656305dd45a..0921e957d784 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -575,6 +575,7 @@ struct xe_device { INTEL_DRAM_DDR5, INTEL_DRAM_LPDDR5, INTEL_DRAM_GDDR, + INTEL_DRAM_GDDR_ECC, } type; u8 num_qgv_points; u8 num_psf_gv_points; -- 2.51.0 From 5003720e7d96c2f77c5ae3049aa8958e8074dc44 Mon Sep 17 00:00:00 2001 From: Animesh Manna Date: Mon, 24 Mar 2025 15:38:23 +0530 Subject: [PATCH 14/16] drm/i915/display: Read panel replay source status through PSR2 status register MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit PTL onwards get panel replay status from PSR2 status register instead of SRD status. Signed-off-by: Animesh Manna Reviewed-by: Jouni Högander Link: https://patchwork.freedesktop.org/patch/msgid/20250324100823.3111564-1-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 50a22cd8d84a..708fbcfa9089 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -3635,8 +3635,8 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) const char *status = "unknown"; u32 val, status_val; - if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled || - intel_dp->psr.panel_replay_enabled)) { + if ((intel_dp_is_edp(intel_dp) || DISPLAY_VER(display) >= 30) && + (intel_dp->psr.sel_update_enabled || intel_dp->psr.panel_replay_enabled)) { static const char * const live_status[] = { "IDLE", "CAPTURE", -- 2.51.0 From 77ba0b8562251f44bdc4002813d976dfb3c0a387 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 21 Mar 2025 12:52:45 +0200 Subject: [PATCH 15/16] drm/i915/dsi: convert vlv_dsi.[ch] to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of vlv_dsi.[ch] to struct intel_display. Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/320449f3b58c6eca6fdbb16e4e819cd0e133887a.1742554320.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 4 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 157 +++++++++---------- drivers/gpu/drm/i915/display/vlv_dsi.h | 6 +- 3 files changed, 80 insertions(+), 87 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b852ffe94a10..d7243848fb23 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7670,7 +7670,7 @@ void intel_setup_outputs(struct intel_display *display) intel_bios_for_each_encoder(display, intel_ddi_init); if (display->platform.geminilake || display->platform.broxton) - vlv_dsi_init(dev_priv); + vlv_dsi_init(display); } else if (HAS_PCH_SPLIT(dev_priv)) { int found; @@ -7754,7 +7754,7 @@ void intel_setup_outputs(struct intel_display *display) g4x_hdmi_init(display, CHV_HDMID, PORT_D); } - vlv_dsi_init(dev_priv); + vlv_dsi_init(display); } else if (display->platform.pineview) { intel_lvds_init(dev_priv); intel_crt_init(display); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index af717df83197..6ddf33de85d3 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -251,8 +251,10 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, return 0; } -static void band_gap_reset(struct drm_i915_private *dev_priv) +static void band_gap_reset(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + vlv_flisdsi_get(dev_priv); vlv_flisdsi_write(dev_priv, 0x08, 0x0001); @@ -269,13 +271,13 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_connector *intel_connector = intel_dsi->attached_connector; struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int ret; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; @@ -298,7 +300,7 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, else pipe_config->pipe_bpp = 18; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { /* Enable Frame time stamp based scanline reporting */ pipe_config->mode_flags |= I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; @@ -468,7 +470,7 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder) vlv_flisdsi_put(dev_priv); /* bandgap reset is needed after everytime we do power gate */ - band_gap_reset(dev_priv); + band_gap_reset(display); for_each_dsi_port(port, intel_dsi->ports) { @@ -495,11 +497,11 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder) static void intel_dsi_device_ready(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) glk_dsi_device_ready(encoder); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + else if (display->platform.geminilake || display->platform.broxton) bxt_dsi_device_ready(encoder); else vlv_dsi_device_ready(encoder); @@ -559,23 +561,22 @@ static void glk_dsi_clear_device_ready(struct intel_encoder *encoder) glk_dsi_disable_mipi_io(encoder); } -static i915_reg_t port_ctrl_reg(struct drm_i915_private *i915, enum port port) +static i915_reg_t port_ctrl_reg(struct intel_display *display, enum port port) { - return IS_GEMINILAKE(i915) || IS_BROXTON(i915) ? + return display->platform.geminilake || display->platform.broxton ? BXT_MIPI_PORT_CTRL(port) : VLV_MIPI_PORT_CTRL(port); } static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; drm_dbg_kms(display->drm, "\n"); for_each_dsi_port(port, intel_dsi->ports) { /* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */ - i915_reg_t port_ctrl = IS_BROXTON(dev_priv) ? + i915_reg_t port_ctrl = display->platform.broxton ? BXT_MIPI_PORT_CTRL(port) : VLV_MIPI_PORT_CTRL(PORT_A); intel_de_write(display, MIPI_DEVICE_READY(display, port), @@ -594,7 +595,7 @@ static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder) * On VLV/CHV, wait till Clock lanes are in LP-00 state for MIPI * Port A only. MIPI Port C has no similar bit for checking. */ - if ((IS_BROXTON(dev_priv) || port == PORT_A) && + if ((display->platform.broxton || port == PORT_A) && intel_de_wait_for_clear(display, port_ctrl, AFE_LATCHOUT, 30)) drm_err(display->drm, "DSI LP not going Low\n"); @@ -612,7 +613,6 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; @@ -620,7 +620,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { u32 temp = intel_dsi->pixel_overlap; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { for_each_dsi_port(port, intel_dsi->ports) intel_de_rmw(display, MIPI_CTRL(display, port), BXT_PIXEL_OVERLAP_CNT_MASK, @@ -633,7 +633,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, } for_each_dsi_port(port, intel_dsi->ports) { - i915_reg_t port_ctrl = port_ctrl_reg(dev_priv, port); + i915_reg_t port_ctrl = port_ctrl_reg(display, port); u32 temp; temp = intel_de_read(display, port_ctrl); @@ -644,7 +644,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, if (intel_dsi->ports == (BIT(PORT_A) | BIT(PORT_C))) { temp |= (intel_dsi->dual_link - 1) << DUAL_LINK_MODE_SHIFT; - if (IS_BROXTON(dev_priv)) + if (display->platform.broxton) temp |= LANE_CONFIGURATION_DUAL_LINK_A; else temp |= crtc->pipe ? @@ -664,12 +664,11 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, static void intel_dsi_port_disable(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; for_each_dsi_port(port, intel_dsi->ports) { - i915_reg_t port_ctrl = port_ctrl_reg(dev_priv, port); + i915_reg_t port_ctrl = port_ctrl_reg(display, port); /* de-assert ip_tg_enable signal */ intel_de_rmw(display, port_ctrl, DPI_ENABLE, 0); @@ -730,7 +729,6 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum port port; bool glk_cold_boot = false; @@ -745,7 +743,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, * The BIOS may leave the PLL in a wonky state where it doesn't * lock. It needs to be fully powered down to fix it. */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { bxt_dsi_pll_disable(encoder); bxt_dsi_pll_enable(encoder, pipe_config); } else { @@ -753,7 +751,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, vlv_dsi_pll_enable(encoder, pipe_config); } - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { /* Add MIPI IO reset programming for modeset */ intel_de_rmw(display, BXT_P_CR_GT_DISP_PWRON, 0, MIPIO_RST_CTRL); @@ -762,13 +760,13 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, intel_de_write(display, BXT_P_DSI_REGULATOR_TX_CTRL, 0); } - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { /* Disable DPOunit clock gating, can stall pipe */ - intel_de_rmw(display, DSPCLK_GATE_D(dev_priv), + intel_de_rmw(display, DSPCLK_GATE_D(display), 0, DPOUNIT_CLOCK_GATE_DISABLE); } - if (!IS_GEMINILAKE(dev_priv)) + if (!display->platform.geminilake) intel_dsi_prepare(encoder, pipe_config); /* Give the panel time to power-on and then deassert its reset */ @@ -776,7 +774,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, msleep(intel_dsi->panel_on_delay); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); - if (IS_GEMINILAKE(dev_priv)) { + if (display->platform.geminilake) { glk_cold_boot = glk_dsi_enable_io(encoder); /* Prepare port in cold boot(s3/s4) scenario */ @@ -788,7 +786,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, intel_dsi_device_ready(encoder); /* Prepare port in normal boot scenario */ - if (IS_GEMINILAKE(dev_priv) && !glk_cold_boot) + if (display->platform.geminilake && !glk_cold_boot) intel_dsi_prepare(encoder, pipe_config); /* Send initialization commands in LP mode */ @@ -836,11 +834,11 @@ static void intel_dsi_disable(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - drm_dbg_kms(&i915->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); intel_backlight_disable(old_conn_state); @@ -860,9 +858,9 @@ static void intel_dsi_disable(struct intel_atomic_state *state, static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) glk_dsi_clear_device_ready(encoder); else vlv_dsi_clear_device_ready(encoder); @@ -874,13 +872,12 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; drm_dbg_kms(display->drm, "\n"); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { intel_crtc_vblank_off(old_crtc_state); skl_scaler_disable(old_crtc_state); @@ -907,7 +904,7 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state, /* Transition to LP-00 */ intel_dsi_clear_device_ready(encoder); - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { /* Power down DSI regulator to save power */ intel_de_write(display, BXT_P_DSI_REGULATOR_CFG, STAP_SELECT); intel_de_write(display, BXT_P_DSI_REGULATOR_TX_CTRL, @@ -917,12 +914,12 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state, intel_de_rmw(display, BXT_P_CR_GT_DISP_PWRON, MIPIO_RST_CTRL, 0); } - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { bxt_dsi_pll_disable(encoder); } else { vlv_dsi_pll_disable(encoder); - intel_de_rmw(display, DSPCLK_GATE_D(dev_priv), + intel_de_rmw(display, DSPCLK_GATE_D(display), DPOUNIT_CLOCK_GATE_DISABLE, 0); } @@ -957,13 +954,13 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, * configuration, otherwise accessing DSI registers will hang the * machine. See BSpec North Display Engine registers/MIPI[BXT]. */ - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && !bxt_dsi_pll_is_enabled(dev_priv)) goto out_put_power; /* XXX: this only works for one DSI output */ for_each_dsi_port(port, intel_dsi->ports) { - i915_reg_t port_ctrl = port_ctrl_reg(dev_priv, port); + i915_reg_t port_ctrl = port_ctrl_reg(display, port); bool enabled = intel_de_read(display, port_ctrl) & DPI_ENABLE; /* @@ -971,10 +968,10 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, * bit in port C control register does not get set. As a * workaround, check pipe B conf instead. */ - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && port == PORT_C) enabled = intel_de_read(display, - TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE; + TRANSCONF(display, PIPE_B)) & TRANSCONF_ENABLE; /* Try command mode if video mode not enabled */ if (!enabled) { @@ -989,7 +986,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, if (!(intel_de_read(display, MIPI_DEVICE_READY(display, port)) & DEVICE_READY)) continue; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { u32 tmp = intel_de_read(display, MIPI_CTRL(display, port)); tmp &= BXT_PIPE_SELECT_MASK; tmp >>= BXT_PIPE_SELECT_SHIFT; @@ -1177,15 +1174,15 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, static void intel_dsi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); u32 pclk; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { bxt_dsi_get_pipe_config(encoder, pipe_config); pclk = bxt_dsi_get_pclk(encoder, pipe_config); } else { @@ -1218,7 +1215,6 @@ static void set_dsi_timings(struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); @@ -1253,7 +1249,7 @@ static void set_dsi_timings(struct intel_encoder *encoder, hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); for_each_dsi_port(port, intel_dsi->ports) { - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { /* * Program hdisplay and vdisplay on MIPI transcoder. * This is different from calculated hactive and @@ -1307,7 +1303,6 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; @@ -1327,7 +1322,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, } for_each_dsi_port(port, intel_dsi->ports) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { /* * escape clock divider, 20MHz, shared for A and C. * device ready must be off when doing this! txclkesc? @@ -1342,7 +1337,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, tmp &= ~READ_REQUEST_PRIORITY_MASK; intel_de_write(display, MIPI_CTRL(display, port), tmp | READ_REQUEST_PRIORITY_HIGH); - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { enum pipe pipe = crtc->pipe; intel_de_rmw(display, MIPI_CTRL(display, port), @@ -1377,7 +1372,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, if (intel_dsi->clock_stop) tmp |= CLOCKSTOP; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { tmp |= BXT_DPHY_DEFEATURE_EN; if (!is_cmd_mode(intel_dsi)) tmp |= BXT_DEFEATURE_DPI_FIFO_CTR; @@ -1424,7 +1419,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, intel_de_write(display, MIPI_INIT_COUNT(display, port), txclkesc(intel_dsi->escape_clk_div, 100)); - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && !intel_dsi->dual_link) { /* * BXT spec says write MIPI_INIT_COUNT for @@ -1461,7 +1456,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, intel_de_write(display, MIPI_LP_BYTECLK(display, port), intel_dsi->lp_byte_clk); - if (IS_GEMINILAKE(dev_priv)) { + if (display->platform.geminilake) { intel_de_write(display, MIPI_TLPX_TIME_COUNT(display, port), intel_dsi->lp_byte_clk); /* Shadow of DPHY reg */ @@ -1513,18 +1508,17 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, static void intel_dsi_unprepare(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) return; for_each_dsi_port(port, intel_dsi->ports) { /* Panel commands can be sent when clock is in LP11 */ intel_de_write(display, MIPI_DEVICE_READY(display, port), 0x0); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) bxt_dsi_reset_clocks(encoder, port); else vlv_dsi_reset_clocks(encoder, port); @@ -1596,8 +1590,8 @@ static void vlv_dsi_add_properties(struct intel_connector *connector) static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) { - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); struct intel_connector *connector = intel_dsi->attached_connector; + struct intel_display *display = to_intel_display(connector); struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; u32 tlpx_ns, extra_byte_count, tlpx_ui; u32 ui_num, ui_den; @@ -1645,7 +1639,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) * For GEMINILAKE dphy_param_reg will be programmed in terms of * HS byte clock count for other platform in HS ddr clock count */ - mul = IS_GEMINILAKE(dev_priv) ? 8 : 2; + mul = display->platform.geminilake ? 8 : 2; ths_prepare_ns = max(mipi_config->ths_prepare, mipi_config->tclk_prepare); @@ -1653,7 +1647,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * mul); if (prepare_cnt > PREPARE_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "prepare count too high %u\n", + drm_dbg_kms(display->drm, "prepare count too high %u\n", prepare_cnt); prepare_cnt = PREPARE_CNT_MAX; } @@ -1674,7 +1668,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) exit_zero_cnt += 1; if (exit_zero_cnt > EXIT_ZERO_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "exit zero count too high %u\n", + drm_dbg_kms(display->drm, "exit zero count too high %u\n", exit_zero_cnt); exit_zero_cnt = EXIT_ZERO_CNT_MAX; } @@ -1685,7 +1679,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) * ui_den, ui_num * mul); if (clk_zero_cnt > CLK_ZERO_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "clock zero count too high %u\n", + drm_dbg_kms(display->drm, "clock zero count too high %u\n", clk_zero_cnt); clk_zero_cnt = CLK_ZERO_CNT_MAX; } @@ -1695,7 +1689,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, ui_num * mul); if (trail_cnt > TRAIL_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "trail count too high %u\n", + drm_dbg_kms(display->drm, "trail count too high %u\n", trail_cnt); trail_cnt = TRAIL_CNT_MAX; } @@ -1761,7 +1755,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; @@ -1770,7 +1764,7 @@ int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) * On Valleyview some DSI panels lose (v|h)sync when the clock is lower * than 320000KHz. */ - if (IS_VALLEYVIEW(dev_priv)) + if (display->platform.valleyview) return 320000; /* @@ -1778,7 +1772,7 @@ int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) * picture gets unstable, despite that values are * correct for DSI PLL and DE PLL. */ - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) return 158400; return 0; @@ -1903,9 +1897,8 @@ static const struct dmi_system_id vlv_dsi_dmi_quirk_table[] = { { } }; -void vlv_dsi_init(struct drm_i915_private *dev_priv) +void vlv_dsi_init(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_dsi *intel_dsi; struct intel_encoder *encoder; struct intel_connector *connector; @@ -1914,16 +1907,16 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) enum port port; enum pipe pipe; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); /* There is no detection method for MIPI so rely on VBT */ if (!intel_bios_is_dsi_present(display, &port)) return; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - dev_priv->display.dsi.mmio_base = BXT_MIPI_BASE; + if (display->platform.geminilake || display->platform.broxton) + display->dsi.mmio_base = BXT_MIPI_BASE; else - dev_priv->display.dsi.mmio_base = VLV_MIPI_BASE; + display->dsi.mmio_base = VLV_MIPI_BASE; intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); if (!intel_dsi) @@ -1938,12 +1931,12 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) encoder = &intel_dsi->base; intel_dsi->attached_connector = connector; - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_dsi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port)); encoder->compute_config = intel_dsi_compute_config; encoder->pre_enable = intel_dsi_pre_enable; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) encoder->enable = bxt_dsi_enable; encoder->disable = intel_dsi_disable; encoder->post_disable = intel_dsi_post_disable; @@ -1963,7 +1956,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI * port C. BXT isn't limited like this. */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) encoder->pipe_mask = ~0; else if (port == PORT_A) encoder->pipe_mask = BIT(PIPE_A); @@ -1979,10 +1972,10 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) else intel_dsi->ports = BIT(port); - if (drm_WARN_ON(&dev_priv->drm, connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports)) + if (drm_WARN_ON(display->drm, connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports)) connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports; - if (drm_WARN_ON(&dev_priv->drm, connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports)) + if (drm_WARN_ON(display->drm, connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports)) connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports; /* Create a DSI host (and a device) for each port. */ @@ -1998,18 +1991,18 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) } if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) { - drm_dbg_kms(&dev_priv->drm, "no device found\n"); + drm_dbg_kms(display->drm, "no device found\n"); goto err; } /* Use clock read-back from current hw-state for fastboot */ current_mode = intel_encoder_current_mode(encoder); if (current_mode) { - drm_dbg_kms(&dev_priv->drm, "Calculated pclk %d GOP %d\n", + drm_dbg_kms(display->drm, "Calculated pclk %d GOP %d\n", intel_dsi->pclk, current_mode->clock); if (intel_fuzzy_clock_check(intel_dsi->pclk, current_mode->clock)) { - drm_dbg_kms(&dev_priv->drm, "Using GOP pclk\n"); + drm_dbg_kms(display->drm, "Using GOP pclk\n"); intel_dsi->pclk = current_mode->clock; } @@ -2021,7 +2014,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_dsi_vbt_gpio_init(intel_dsi, intel_dsi_get_hw_state(encoder, &pipe)); - drm_connector_init(&dev_priv->drm, &connector->base, &intel_dsi_connector_funcs, + drm_connector_init(display->drm, &connector->base, &intel_dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); drm_connector_helper_add(&connector->base, &intel_dsi_connector_helper_funcs); @@ -2030,12 +2023,12 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_connector_attach_encoder(connector, encoder); - mutex_lock(&dev_priv->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); intel_panel_add_vbt_lfp_fixed_mode(connector); - mutex_unlock(&dev_priv->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); if (!intel_panel_preferred_fixed_mode(connector)) { - drm_dbg_kms(&dev_priv->drm, "no fixed mode\n"); + drm_dbg_kms(display->drm, "no fixed mode\n"); goto err_cleanup_connector; } diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.h b/drivers/gpu/drm/i915/display/vlv_dsi.h index 277bacfbc551..ff349b5876c2 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.h +++ b/drivers/gpu/drm/i915/display/vlv_dsi.h @@ -7,14 +7,14 @@ #define __VLV_DSI_H__ enum port; -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_dsi; #ifdef I915 void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state); -void vlv_dsi_init(struct drm_i915_private *dev_priv); +void vlv_dsi_init(struct intel_display *display); #else static inline void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port) { @@ -23,7 +23,7 @@ static inline int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) { return 0; } -static inline void vlv_dsi_init(struct drm_i915_private *dev_priv) +static inline void vlv_dsi_init(struct intel_display *display) { } #endif -- 2.51.0 From 767efb276ea80af8a71a8be9cfd8e668d8720a98 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 21 Mar 2025 12:52:46 +0200 Subject: [PATCH 16/16] drm/i915/dsi: convert vlv_dsi_pll.[ch] to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of vlv_dsi_pll.[ch] to struct intel_display. Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/9d34d8b91c6bc8b2dd8e2081194ee496b251bbf3.1742554320.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 3 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 3 +- drivers/gpu/drm/i915/display/vlv_dsi_pll.c | 118 +++++++++---------- drivers/gpu/drm/i915/display/vlv_dsi_pll.h | 5 +- 4 files changed, 63 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d7243848fb23..222bc01d4682 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3834,7 +3834,6 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, struct intel_display_power_domain_set *power_domain_set) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder; enum port port; u32 tmp; @@ -3856,7 +3855,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, * registers/MIPI[BXT]. We can break out here early, since we * need the same DSI PLL to be enabled for both DSI ports. */ - if (!bxt_dsi_pll_is_enabled(dev_priv)) + if (!bxt_dsi_pll_is_enabled(display)) break; /* XXX: this works for video mode only */ diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 6ddf33de85d3..346737f15fa9 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -936,7 +936,6 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); intel_wakeref_t wakeref; enum port port; @@ -955,7 +954,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, * machine. See BSpec North Display Engine registers/MIPI[BXT]. */ if ((display->platform.geminilake || display->platform.broxton) && - !bxt_dsi_pll_is_enabled(dev_priv)) + !bxt_dsi_pll_is_enabled(display)) goto out_put_power; /* XXX: this only works for one DSI output */ diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c index 2ed47e7d1051..7ce924a5ef90 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c @@ -57,7 +57,7 @@ static u32 dsi_clk_from_pclk(u32 pclk, enum mipi_dsi_pixel_format fmt, return dsi_clk_khz; } -static int dsi_calc_mnp(struct drm_i915_private *dev_priv, +static int dsi_calc_mnp(struct intel_display *display, struct intel_crtc_state *config, int target_dsi_clk) { @@ -68,11 +68,11 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, /* target_dsi_clk is expected in kHz */ if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) { - drm_err(&dev_priv->drm, "DSI CLK Out of Range\n"); + drm_err(display->drm, "DSI CLK Out of Range\n"); return -ECHRNG; } - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { ref_clk = 100000; n = 4; m_min = 70; @@ -116,13 +116,13 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, static int vlv_dsi_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); u32 dsi_clock; u32 pll_ctl, pll_div; u32 m = 0, p = 0, n; - int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000; + int refclk = display->platform.cherryview ? 100000 : 25000; int i; pll_ctl = config->dsi_pll.ctrl; @@ -147,7 +147,7 @@ static int vlv_dsi_pclk(struct intel_encoder *encoder, p--; if (!p) { - drm_err(&dev_priv->drm, "wrong P1 divisor\n"); + drm_err(display->drm, "wrong P1 divisor\n"); return 0; } @@ -157,7 +157,7 @@ static int vlv_dsi_pclk(struct intel_encoder *encoder, } if (i == ARRAY_SIZE(lfsr_converts)) { - drm_err(&dev_priv->drm, "wrong m_seed programmed\n"); + drm_err(display->drm, "wrong m_seed programmed\n"); return 0; } @@ -175,16 +175,16 @@ static int vlv_dsi_pclk(struct intel_encoder *encoder, int vlv_dsi_pll_compute(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); int pclk, dsi_clk, ret; dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, intel_dsi->lane_count); - ret = dsi_calc_mnp(dev_priv, config, dsi_clk); + ret = dsi_calc_mnp(display, config, dsi_clk); if (ret) { - drm_dbg_kms(&dev_priv->drm, "dsi_calc_mnp failed\n"); + drm_dbg_kms(display->drm, "dsi_calc_mnp failed\n"); return ret; } @@ -196,7 +196,7 @@ int vlv_dsi_pll_compute(struct intel_encoder *encoder, config->dsi_pll.ctrl |= DSI_PLL_VCO_EN; - drm_dbg_kms(&dev_priv->drm, "dsi pll div %08x, ctrl %08x\n", + drm_dbg_kms(display->drm, "dsi pll div %08x, ctrl %08x\n", config->dsi_pll.div, config->dsi_pll.ctrl); pclk = vlv_dsi_pclk(encoder, config); @@ -213,9 +213,10 @@ int vlv_dsi_pll_compute(struct intel_encoder *encoder, void vlv_dsi_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *config) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); vlv_cck_get(dev_priv); @@ -235,20 +236,21 @@ void vlv_dsi_pll_enable(struct intel_encoder *encoder, DSI_PLL_LOCK, 20)) { vlv_cck_put(dev_priv); - drm_err(&dev_priv->drm, "DSI PLL lock failed\n"); + drm_err(display->drm, "DSI PLL lock failed\n"); return; } vlv_cck_put(dev_priv); - drm_dbg_kms(&dev_priv->drm, "DSI PLL locked\n"); + drm_dbg_kms(display->drm, "DSI PLL locked\n"); } void vlv_dsi_pll_disable(struct intel_encoder *encoder) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 tmp; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); vlv_cck_get(dev_priv); @@ -260,14 +262,14 @@ void vlv_dsi_pll_disable(struct intel_encoder *encoder) vlv_cck_put(dev_priv); } -bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +bool bxt_dsi_pll_is_enabled(struct intel_display *display) { bool enabled; u32 val; u32 mask; mask = BXT_DSI_PLL_DO_ENABLE | BXT_DSI_PLL_LOCKED; - val = intel_de_read(dev_priv, BXT_DSI_PLL_ENABLE); + val = intel_de_read(display, BXT_DSI_PLL_ENABLE); enabled = (val & mask) == mask; if (!enabled) @@ -281,17 +283,17 @@ bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) * times, and since accessing DSI registers with invalid dividers * causes a system hang. */ - val = intel_de_read(dev_priv, BXT_DSI_PLL_CTL); - if (IS_GEMINILAKE(dev_priv)) { + val = intel_de_read(display, BXT_DSI_PLL_CTL); + if (display->platform.geminilake) { if (!(val & BXT_DSIA_16X_MASK)) { - drm_dbg(&dev_priv->drm, - "Invalid PLL divider (%08x)\n", val); + drm_dbg_kms(display->drm, + "Invalid PLL divider (%08x)\n", val); enabled = false; } } else { if (!(val & BXT_DSIA_16X_MASK) || !(val & BXT_DSIC_16X_MASK)) { - drm_dbg(&dev_priv->drm, - "Invalid PLL divider (%08x)\n", val); + drm_dbg_kms(display->drm, + "Invalid PLL divider (%08x)\n", val); enabled = false; } } @@ -301,29 +303,30 @@ bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) void bxt_dsi_pll_disable(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); - intel_de_rmw(dev_priv, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_DO_ENABLE, 0); + intel_de_rmw(display, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_DO_ENABLE, 0); /* * PLL lock should deassert within 200us. * Wait up to 1ms before timing out. */ - if (intel_de_wait_for_clear(dev_priv, BXT_DSI_PLL_ENABLE, + if (intel_de_wait_for_clear(display, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_LOCKED, 1)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Timeout waiting for PLL lock deassertion\n"); } u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 pll_ctl, pll_div; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); vlv_cck_get(dev_priv); pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); @@ -352,14 +355,14 @@ static int bxt_dsi_pclk(struct intel_encoder *encoder, u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 pclk; - config->dsi_pll.ctrl = intel_de_read(dev_priv, BXT_DSI_PLL_CTL); + config->dsi_pll.ctrl = intel_de_read(display, BXT_DSI_PLL_CTL); pclk = bxt_dsi_pclk(encoder, config); - drm_dbg(&dev_priv->drm, "Calculated pclk=%u\n", pclk); + drm_dbg_kms(display->drm, "Calculated pclk=%u\n", pclk); return pclk; } @@ -375,10 +378,9 @@ void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) temp | intel_dsi->escape_clk_div << ESCAPE_CLOCK_DIVIDER_SHIFT); } -static void glk_dsi_program_esc_clock(struct drm_device *dev, - const struct intel_crtc_state *config) +static void glk_dsi_program_esc_clock(struct intel_display *display, + const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(dev); u32 dsi_rate = 0; u32 pll_ratio = 0; u32 ddr_clk = 0; @@ -415,17 +417,16 @@ static void glk_dsi_program_esc_clock(struct drm_device *dev, txesc2_div = min_t(u32, div2_value, 10); - intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV1, + intel_de_write(display, MIPIO_TXESC_CLK_DIV1, (1 << (txesc1_div - 1)) & GLK_TX_ESC_CLK_DIV1_MASK); - intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV2, + intel_de_write(display, MIPIO_TXESC_CLK_DIV2, (1 << (txesc2_div - 1)) & GLK_TX_ESC_CLK_DIV2_MASK); } /* Program BXT Mipi clocks and dividers */ -static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, +static void bxt_dsi_program_clocks(struct intel_display *display, enum port port, const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp; u32 dsi_rate = 0; u32 pll_ratio = 0; @@ -436,7 +437,7 @@ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, u32 mipi_8by3_divider; /* Clear old configurations */ - tmp = intel_de_read(dev_priv, BXT_MIPI_CLOCK_CTL); + tmp = intel_de_read(display, BXT_MIPI_CLOCK_CTL); tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)); tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port)); @@ -472,13 +473,13 @@ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower); tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper); - intel_de_write(dev_priv, BXT_MIPI_CLOCK_CTL, tmp); + intel_de_write(display, BXT_MIPI_CLOCK_CTL, tmp); } int bxt_dsi_pll_compute(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); u8 dsi_ratio, dsi_ratio_min, dsi_ratio_max; u32 dsi_clk; @@ -494,7 +495,7 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, */ dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ); - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { dsi_ratio_min = BXT_DSI_PLL_RATIO_MIN; dsi_ratio_max = BXT_DSI_PLL_RATIO_MAX; } else { @@ -503,11 +504,11 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, } if (dsi_ratio < dsi_ratio_min || dsi_ratio > dsi_ratio_max) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Can't get a suitable ratio from DSI PLL ratios\n"); return -ECHRNG; } else - drm_dbg_kms(&dev_priv->drm, "DSI PLL calculation is Done!!\n"); + drm_dbg_kms(display->drm, "DSI PLL calculation is Done!!\n"); /* * Program DSI ratio and Select MIPIC and MIPIA PLL output as 8x @@ -519,7 +520,7 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, /* As per recommendation from hardware team, * Prog PVD ratio =1 if dsi ratio <= 50 */ - if (IS_BROXTON(dev_priv) && dsi_ratio <= 50) + if (display->platform.broxton && dsi_ratio <= 50) config->dsi_pll.ctrl |= BXT_DSI_PLL_PVD_RATIO_1; pclk = bxt_dsi_pclk(encoder, config); @@ -536,46 +537,45 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, void bxt_dsi_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); /* Configure PLL vales */ - intel_de_write(dev_priv, BXT_DSI_PLL_CTL, config->dsi_pll.ctrl); - intel_de_posting_read(dev_priv, BXT_DSI_PLL_CTL); + intel_de_write(display, BXT_DSI_PLL_CTL, config->dsi_pll.ctrl); + intel_de_posting_read(display, BXT_DSI_PLL_CTL); /* Program TX, RX, Dphy clocks */ - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { for_each_dsi_port(port, intel_dsi->ports) - bxt_dsi_program_clocks(encoder->base.dev, port, config); + bxt_dsi_program_clocks(display, port, config); } else { - glk_dsi_program_esc_clock(encoder->base.dev, config); + glk_dsi_program_esc_clock(display, config); } /* Enable DSI PLL */ - intel_de_rmw(dev_priv, BXT_DSI_PLL_ENABLE, 0, BXT_DSI_PLL_DO_ENABLE); + intel_de_rmw(display, BXT_DSI_PLL_ENABLE, 0, BXT_DSI_PLL_DO_ENABLE); /* Timeout and fail if PLL not locked */ - if (intel_de_wait_for_set(dev_priv, BXT_DSI_PLL_ENABLE, + if (intel_de_wait_for_set(display, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_LOCKED, 1)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Timed out waiting for DSI PLL to lock\n"); return; } - drm_dbg_kms(&dev_priv->drm, "DSI PLL locked\n"); + drm_dbg_kms(display->drm, "DSI PLL locked\n"); } void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 tmp; /* Clear old configurations */ - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { tmp = intel_de_read(display, BXT_MIPI_CLOCK_CTL); tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h index f975660fa609..f26e31a7dd69 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h @@ -9,7 +9,6 @@ #include enum port; -struct drm_i915_private; struct intel_crtc_state; struct intel_display; struct intel_encoder; @@ -33,11 +32,11 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); #ifdef I915 -bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv); +bool bxt_dsi_pll_is_enabled(struct intel_display *display); void assert_dsi_pll_enabled(struct intel_display *display); void assert_dsi_pll_disabled(struct intel_display *display); #else -static inline bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +static inline bool bxt_dsi_pll_is_enabled(struct intel_display *display) { return false; } -- 2.51.0