From cca7eda1c73045d6fb12b3db34f90de65412e742 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 20 Jan 2026 17:45:41 +0200 Subject: drm/{i915, xe}/dsb: move DSB buffer to parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the DSB buffer handling to the display parent interface, making display more independent of i915 and xe driver implementations. Since the DSB parent interface is only called from intel_dsb.c, add the wrappers there with smaller visibility instead of the usual intel_parent.[ch], and using struct intel_dsb as the context parameter for convenience. Unfortunately, memset() being a macro in linux/fortify-string.h, we can't use that as the function pointer name. dsb->memset() would be using the macro and leading to build failures. Therefore, use .fill() for the memset() functionality. v2: s/memset/fill/ Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/df117c862a6d34dae340e4a85c2482b4e29c8884.1768923917.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/intel/display_parent_interface.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index ce946859a3a9..cd091120731c 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -14,6 +14,7 @@ struct drm_gem_object; struct drm_plane_state; struct drm_scanout_buffer; struct i915_vma; +struct intel_dsb_buffer; struct intel_hdcp_gsc_context; struct intel_initial_plane_config; struct intel_panic; @@ -22,6 +23,16 @@ struct ref_tracker; /* Keep struct definitions sorted */ +struct intel_display_dsb_interface { + u32 (*ggtt_offset)(struct intel_dsb_buffer *dsb_buf); + void (*write)(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val); + u32 (*read)(struct intel_dsb_buffer *dsb_buf, u32 idx); + void (*fill)(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size); + struct intel_dsb_buffer *(*create)(struct drm_device *drm, size_t size); + void (*cleanup)(struct intel_dsb_buffer *dsb_buf); + void (*flush_map)(struct intel_dsb_buffer *dsb_buf); +}; + struct intel_display_hdcp_interface { ssize_t (*gsc_msg_send)(struct intel_hdcp_gsc_context *gsc_context, void *msg_in, size_t msg_in_len, @@ -106,6 +117,9 @@ struct intel_display_stolen_interface { * check the optional pointers. */ struct intel_display_parent_interface { + /** @dsb: DSB buffer interface */ + const struct intel_display_dsb_interface *dsb; + /** @hdcp: HDCP GSC interface */ const struct intel_display_hdcp_interface *hdcp; -- cgit v1.2.3 From b3a2a91ae9b48c74e50833242af7d73f8a0ec3a6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Jan 2026 13:29:25 +0200 Subject: drm/{i915, xe}/pcode: move display pcode calls to parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call the parent driver pcode functions through the parent interface function pointers instead of expecting both to have functions of the same name. In i915, add the interface to existing intel_pcode.[ch], while in xe move them to new display/xe_display_pcode.[ch] and build it only for CONFIG_DRM_XE_DISPLAY=y. Do not add separate write and write_timeout calls in the interface. Instead, handle the default 1 ms timeout in the intel_parent.c glue layer. This drops the last intel_pcode.h includes from display, and allows us to remove the corresponding xe compat header. v2: initialize .pcode in i915 Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/20260126112925.2452171-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/hsw_ips.c | 8 ++-- drivers/gpu/drm/i915/display/intel_bw.c | 22 ++++----- drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++----------- drivers/gpu/drm/i915/display/intel_display_power.c | 3 +- .../drm/i915/display/intel_display_power_well.c | 5 +- drivers/gpu/drm/i915/display/intel_dram.c | 6 +-- drivers/gpu/drm/i915/display/intel_hdcp.c | 3 +- drivers/gpu/drm/i915/display/intel_parent.c | 22 +++++++++ drivers/gpu/drm/i915/display/intel_parent.h | 7 +++ drivers/gpu/drm/i915/display/skl_watermark.c | 21 ++++----- drivers/gpu/drm/i915/i915_driver.c | 1 + drivers/gpu/drm/i915/intel_pcode.c | 16 +++++-- drivers/gpu/drm/i915/intel_pcode.h | 9 +--- drivers/gpu/drm/xe/Makefile | 1 + .../gpu/drm/xe/compat-i915-headers/intel_pcode.h | 11 ----- drivers/gpu/drm/xe/display/xe_display.c | 2 + drivers/gpu/drm/xe/display/xe_display_pcode.c | 38 +++++++++++++++ drivers/gpu/drm/xe/display/xe_display_pcode.h | 9 ++++ drivers/gpu/drm/xe/xe_pcode.c | 30 ------------ drivers/gpu/drm/xe/xe_pcode.h | 8 ---- include/drm/intel/display_parent_interface.h | 10 ++++ 21 files changed, 161 insertions(+), 125 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/intel_pcode.h create mode 100644 drivers/gpu/drm/xe/display/xe_display_pcode.c create mode 100644 drivers/gpu/drm/xe/display/xe_display_pcode.h (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 008d339d5c21..0caaea2e64e1 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -14,7 +14,7 @@ #include "intel_display_regs.h" #include "intel_display_rpm.h" #include "intel_display_types.h" -#include "intel_pcode.h" +#include "intel_parent.h" static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) { @@ -39,8 +39,8 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) if (display->platform.broadwell) { drm_WARN_ON(display->drm, - intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, - val | IPS_PCODE_CONTROL)); + intel_parent_pcode_write(display, DISPLAY_IPS_CONTROL, + val | IPS_PCODE_CONTROL)); /* * Quoting Art Runyan: "its not safe to expect any particular * value in IPS_CTL bit 31 after enabling IPS through the @@ -72,7 +72,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state) if (display->platform.broadwell) { drm_WARN_ON(display->drm, - intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 0)); + intel_parent_pcode_write(display, DISPLAY_IPS_CONTROL, 0)); /* * Wait for PCODE to finish disabling IPS. The BSpec specified * 42ms timeout value leads to occasional timeouts so use 100ms diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 4ee3f5172f4e..8d84445c69f1 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -15,7 +15,7 @@ #include "intel_display_utils.h" #include "intel_dram.h" #include "intel_mchbar_regs.h" -#include "intel_pcode.h" +#include "intel_parent.h" #include "intel_uncore.h" #include "skl_watermark.h" @@ -114,9 +114,9 @@ static int icl_pcode_read_qgv_point_info(struct intel_display *display, u16 dclk; int ret; - ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | - ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), - &val, &val2); + ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), + &val, &val2); if (ret) return ret; @@ -141,8 +141,8 @@ static int adls_pcode_read_psf_gv_point_info(struct intel_display *display, int ret; int i; - ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | - ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); + ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); if (ret) return ret; @@ -189,11 +189,11 @@ static int icl_pcode_restrict_qgv_points(struct intel_display *display, return 0; /* bspec says to keep retrying for at least 1 ms */ - ret = intel_pcode_request(display->drm, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, - points_mask, - ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, - ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, - 1); + ret = intel_parent_pcode_request(display, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, + points_mask, + ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, + ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, + 1); if (ret < 0) { drm_err(display->drm, diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 9bfbfbf34dc0..9217050a76e0 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -42,8 +42,8 @@ #include "intel_display_wa.h" #include "intel_dram.h" #include "intel_mchbar_regs.h" +#include "intel_parent.h" #include "intel_pci_config.h" -#include "intel_pcode.h" #include "intel_plane.h" #include "intel_psr.h" #include "intel_step.h" @@ -888,7 +888,7 @@ static void bdw_set_cdclk(struct intel_display *display, "trying to change cdclk frequency with cdclk not enabled\n")) return; - ret = intel_pcode_write(display->drm, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); + ret = intel_parent_pcode_write(display, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); if (ret) { drm_err(display->drm, "failed to inform pcode about cdclk change\n"); @@ -918,8 +918,8 @@ static void bdw_set_cdclk(struct intel_display *display, if (ret) drm_err(display->drm, "Switching back to LCPLL failed\n"); - intel_pcode_write(display->drm, HSW_PCODE_DE_WRITE_FREQ_REQ, - cdclk_config->voltage_level); + intel_parent_pcode_write(display, HSW_PCODE_DE_WRITE_FREQ_REQ, + cdclk_config->voltage_level); intel_de_write(display, CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); @@ -1175,10 +1175,10 @@ static void skl_set_cdclk(struct intel_display *display, drm_WARN_ON_ONCE(display->drm, display->platform.skylake && vco == 8640000); - ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); + ret = intel_parent_pcode_request(display, SKL_PCODE_CDCLK_CONTROL, + SKL_CDCLK_PREPARE_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, 3); if (ret) { drm_err(display->drm, "Failed to inform PCU about cdclk change (%d)\n", ret); @@ -1221,8 +1221,8 @@ static void skl_set_cdclk(struct intel_display *display, intel_de_posting_read(display, CDCLK_CTL); /* inform PCU of the change */ - intel_pcode_write(display->drm, SKL_PCODE_CDCLK_CONTROL, - cdclk_config->voltage_level); + intel_parent_pcode_write(display, SKL_PCODE_CDCLK_CONTROL, + cdclk_config->voltage_level); intel_update_cdclk(display); } @@ -2247,18 +2247,18 @@ static void bxt_set_cdclk(struct intel_display *display, if (DISPLAY_VER(display) >= 14 || display->platform.dg2) ; /* NOOP */ else if (DISPLAY_VER(display) >= 11) - ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); + ret = intel_parent_pcode_request(display, SKL_PCODE_CDCLK_CONTROL, + SKL_CDCLK_PREPARE_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, 3); else /* * BSpec requires us to wait up to 150usec, but that leads to * timeouts; the 2ms used here is based on experiment. */ - ret = intel_pcode_write_timeout(display->drm, - HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x80000000, 2); + ret = intel_parent_pcode_write_timeout(display, + HSW_PCODE_DE_WRITE_FREQ_REQ, + 0x80000000, 2); if (ret) { drm_err(display->drm, @@ -2287,8 +2287,8 @@ static void bxt_set_cdclk(struct intel_display *display, * Display versions 14 and beyond */; else if (DISPLAY_VER(display) >= 11 && !display->platform.dg2) - ret = intel_pcode_write(display->drm, SKL_PCODE_CDCLK_CONTROL, - cdclk_config->voltage_level); + ret = intel_parent_pcode_write(display, SKL_PCODE_CDCLK_CONTROL, + cdclk_config->voltage_level); if (DISPLAY_VER(display) < 11) { /* * The timeout isn't specified, the 2ms used here is based on @@ -2296,9 +2296,9 @@ static void bxt_set_cdclk(struct intel_display *display, * FIXME: Waiting for the request completion could be delayed * until the next PCODE request based on BSpec. */ - ret = intel_pcode_write_timeout(display->drm, - HSW_PCODE_DE_WRITE_FREQ_REQ, - cdclk_config->voltage_level, 2); + ret = intel_parent_pcode_write_timeout(display, + HSW_PCODE_DE_WRITE_FREQ_REQ, + cdclk_config->voltage_level, 2); } if (ret) { drm_err(display->drm, @@ -2598,11 +2598,11 @@ static void intel_pcode_notify(struct intel_display *display, if (pipe_count_update_valid) update_mask |= DISPLAY_TO_PCODE_PIPE_COUNT_VALID; - ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL, - SKL_CDCLK_PREPARE_FOR_CHANGE | - update_mask, - SKL_CDCLK_READY_FOR_CHANGE, - SKL_CDCLK_READY_FOR_CHANGE, 3); + ret = intel_parent_pcode_request(display, SKL_PCODE_CDCLK_CONTROL, + SKL_CDCLK_PREPARE_FOR_CHANGE | + update_mask, + SKL_CDCLK_READY_FOR_CHANGE, + SKL_CDCLK_READY_FOR_CHANGE, 3); if (ret) drm_err(display->drm, "Failed to inform PCU about display config (err %d)\n", diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index d27397f43863..06adf6afbec0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -26,7 +26,6 @@ #include "intel_mchbar_regs.h" #include "intel_parent.h" #include "intel_pch_refclk.h" -#include "intel_pcode.h" #include "intel_pmdemand.h" #include "intel_pps_regs.h" #include "intel_snps_phy.h" @@ -1260,7 +1259,7 @@ static u32 hsw_read_dcomp(struct intel_display *display) static void hsw_write_dcomp(struct intel_display *display, u32 val) { if (display->platform.haswell) { - if (intel_pcode_write(display->drm, GEN6_PCODE_WRITE_D_COMP, val)) + if (intel_parent_pcode_write(display, GEN6_PCODE_WRITE_D_COMP, val)) drm_dbg_kms(display->drm, "Failed to write to D_COMP\n"); } else { intel_de_write(display, D_COMP_BDW, val); 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 68f293c3ac01..6f9bc6f9615e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -27,7 +27,6 @@ #include "intel_dpll.h" #include "intel_hotplug.h" #include "intel_parent.h" -#include "intel_pcode.h" #include "intel_pps.h" #include "intel_psr.h" #include "intel_tc.h" @@ -518,7 +517,7 @@ static void icl_tc_cold_exit(struct intel_display *display) int ret, tries = 0; while (1) { - ret = intel_pcode_write(display->drm, ICL_PCODE_EXIT_TCCOLD, 0); + ret = intel_parent_pcode_write(display, ICL_PCODE_EXIT_TCCOLD, 0); if (ret != -EAGAIN || ++tries == 3) break; msleep(1); @@ -1791,7 +1790,7 @@ tgl_tc_cold_request(struct intel_display *display, bool block) * Spec states that we should timeout the request after 200us * but the function below will timeout after 500us */ - ret = intel_pcode_read(display->drm, TGL_PCODE_TCCOLD, &low_val, &high_val); + ret = intel_parent_pcode_read(display, TGL_PCODE_TCCOLD, &low_val, &high_val); if (ret == 0) { if (block && (low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED)) diff --git a/drivers/gpu/drm/i915/display/intel_dram.c b/drivers/gpu/drm/i915/display/intel_dram.c index 170de304fe96..3b9879714ea9 100644 --- a/drivers/gpu/drm/i915/display/intel_dram.c +++ b/drivers/gpu/drm/i915/display/intel_dram.c @@ -13,7 +13,7 @@ #include "intel_display_utils.h" #include "intel_dram.h" #include "intel_mchbar_regs.h" -#include "intel_pcode.h" +#include "intel_parent.h" #include "intel_uncore.h" #include "vlv_iosf_sb.h" @@ -692,8 +692,8 @@ static int icl_pcode_read_mem_global_info(struct intel_display *display, u32 val = 0; int ret; - ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | - ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, &val, NULL); + ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, &val, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 7114fc405c29..8d3137067bf6 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -33,7 +33,6 @@ #include "intel_hdcp_regs.h" #include "intel_hdcp_shim.h" #include "intel_parent.h" -#include "intel_pcode.h" #include "intel_step.h" #define USE_HDCP_GSC(__display) (DISPLAY_VER(__display) >= 14) @@ -398,7 +397,7 @@ static int intel_hdcp_load_keys(struct intel_display *display) * Mailbox interface. */ if (DISPLAY_VER(display) == 9 && !display->platform.broxton) { - ret = intel_pcode_write(display->drm, SKL_PCODE_LOAD_HDCP_KEYS, 1); + ret = intel_parent_pcode_write(display, SKL_PCODE_LOAD_HDCP_KEYS, 1); if (ret) { drm_err(display->drm, "Failed to initiate HDCP key load (%d)\n", diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index 72ae553f79a4..7f73695a0444 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -92,6 +92,28 @@ void intel_parent_pc8_unblock(struct intel_display *display) display->parent->pc8->unblock(display->drm); } +/* pcode */ +int intel_parent_pcode_read(struct intel_display *display, u32 mbox, u32 *val, u32 *val1) +{ + return display->parent->pcode->read(display->drm, mbox, val, val1); +} + +int intel_parent_pcode_write_timeout(struct intel_display *display, u32 mbox, u32 val, int timeout_ms) +{ + return display->parent->pcode->write(display->drm, mbox, val, timeout_ms); +} + +int intel_parent_pcode_write(struct intel_display *display, u32 mbox, u32 val) +{ + return intel_parent_pcode_write_timeout(display, mbox, val, 1); +} + +int intel_parent_pcode_request(struct intel_display *display, u32 mbox, u32 request, + u32 reply_mask, u32 reply, int timeout_base_ms) +{ + return display->parent->pcode->request(display->drm, mbox, request, reply_mask, reply, timeout_base_ms); +} + /* rps */ bool intel_parent_rps_available(struct intel_display *display) { diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 47cdc14f9aa2..04782bb26b61 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -36,6 +36,13 @@ void intel_parent_panic_finish(struct intel_display *display, struct intel_panic void intel_parent_pc8_block(struct intel_display *display); void intel_parent_pc8_unblock(struct intel_display *display); +/* pcode */ +int intel_parent_pcode_read(struct intel_display *display, u32 mbox, u32 *val, u32 *val1); +int intel_parent_pcode_write_timeout(struct intel_display *display, u32 mbox, u32 val, int timeout_ms); +int intel_parent_pcode_write(struct intel_display *display, u32 mbox, u32 val); +int intel_parent_pcode_request(struct intel_display *display, u32 mbox, u32 request, + u32 reply_mask, u32 reply, int timeout_base_ms); + /* rps */ bool intel_parent_rps_available(struct intel_display *display); void intel_parent_rps_boost_if_not_started(struct intel_display *display, struct dma_fence *fence); diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index a6aab79812e5..b41da10f0f85 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -26,7 +26,7 @@ #include "intel_fb.h" #include "intel_fixed.h" #include "intel_flipq.h" -#include "intel_pcode.h" +#include "intel_parent.h" #include "intel_plane.h" #include "intel_vblank.h" #include "intel_wm.h" @@ -115,9 +115,8 @@ intel_sagv_block_time(struct intel_display *display) u32 val = 0; int ret; - ret = intel_pcode_read(display->drm, - GEN12_PCODE_READ_SAGV_BLOCK_TIME_US, - &val, NULL); + ret = intel_parent_pcode_read(display, GEN12_PCODE_READ_SAGV_BLOCK_TIME_US, + &val, NULL); if (ret) { drm_dbg_kms(display->drm, "Couldn't read SAGV block time!\n"); return 0; @@ -184,8 +183,8 @@ static void skl_sagv_enable(struct intel_display *display) return; drm_dbg_kms(display->drm, "Enabling SAGV\n"); - ret = intel_pcode_write(display->drm, GEN9_PCODE_SAGV_CONTROL, - GEN9_SAGV_ENABLE); + ret = intel_parent_pcode_write(display, GEN9_PCODE_SAGV_CONTROL, + GEN9_SAGV_ENABLE); /* We don't need to wait for SAGV when enabling */ @@ -217,9 +216,9 @@ static void skl_sagv_disable(struct intel_display *display) drm_dbg_kms(display->drm, "Disabling SAGV\n"); /* bspec says to keep retrying for at least 1 ms */ - ret = intel_pcode_request(display->drm, GEN9_PCODE_SAGV_CONTROL, - GEN9_SAGV_DISABLE, - GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED, 1); + ret = intel_parent_pcode_request(display, GEN9_PCODE_SAGV_CONTROL, + GEN9_SAGV_DISABLE, + GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED, 1); /* * Some skl systems, pre-release machines in particular, * don't actually have SAGV. @@ -3283,7 +3282,7 @@ static void skl_read_wm_latency(struct intel_display *display) /* read the first set of memory latencies[0:3] */ val = 0; /* data0 to be programmed to 0 for first set */ - ret = intel_pcode_read(display->drm, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); + ret = intel_parent_pcode_read(display, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); if (ret) { drm_err(display->drm, "SKL Mailbox read error = %d\n", ret); return; @@ -3296,7 +3295,7 @@ static void skl_read_wm_latency(struct intel_display *display) /* read the second set of memory latencies[4:7] */ val = 1; /* data0 to be programmed to 1 for second set */ - ret = intel_pcode_read(display->drm, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); + ret = intel_parent_pcode_read(display, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); if (ret) { drm_err(display->drm, "SKL Mailbox read error = %d\n", ret); return; diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 1e087dfe03d0..f8a1f10d4874 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -771,6 +771,7 @@ static const struct intel_display_parent_interface parent = { .irq = &i915_display_irq_interface, .panic = &i915_display_panic_interface, .pc8 = &i915_display_pc8_interface, + .pcode = &i915_display_pcode_interface, .rpm = &i915_display_rpm_interface, .rps = &i915_display_rps_interface, .stolen = &i915_display_stolen_interface, diff --git a/drivers/gpu/drm/i915/intel_pcode.c b/drivers/gpu/drm/i915/intel_pcode.c index 756652b8ec97..76c5916b28f4 100644 --- a/drivers/gpu/drm/i915/intel_pcode.c +++ b/drivers/gpu/drm/i915/intel_pcode.c @@ -4,6 +4,7 @@ */ #include +#include #include "i915_drv.h" #include "i915_reg.h" @@ -276,26 +277,31 @@ int snb_pcode_write_p(struct intel_uncore *uncore, u32 mbcmd, u32 p1, u32 p2, u3 return err; } -/* Helpers with drm device */ -int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1) +static int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1) { struct drm_i915_private *i915 = to_i915(drm); return snb_pcode_read(&i915->uncore, mbox, val, val1); } -int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms) +static int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms) { struct drm_i915_private *i915 = to_i915(drm); return snb_pcode_write_timeout(&i915->uncore, mbox, val, timeout_ms); } -int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, - u32 reply_mask, u32 reply, int timeout_base_ms) +static int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, + u32 reply_mask, u32 reply, int timeout_base_ms) { struct drm_i915_private *i915 = to_i915(drm); return skl_pcode_request(&i915->uncore, mbox, request, reply_mask, reply, timeout_base_ms); } + +const struct intel_display_pcode_interface i915_display_pcode_interface = { + .read = intel_pcode_read, + .write = intel_pcode_write_timeout, + .request = intel_pcode_request, +}; diff --git a/drivers/gpu/drm/i915/intel_pcode.h b/drivers/gpu/drm/i915/intel_pcode.h index c91a821a88d4..19795ea8172e 100644 --- a/drivers/gpu/drm/i915/intel_pcode.h +++ b/drivers/gpu/drm/i915/intel_pcode.h @@ -27,13 +27,6 @@ int intel_pcode_init(struct intel_uncore *uncore); int snb_pcode_read_p(struct intel_uncore *uncore, u32 mbcmd, u32 p1, u32 p2, u32 *val); int snb_pcode_write_p(struct intel_uncore *uncore, u32 mbcmd, u32 p1, u32 p2, u32 val); -/* Helpers with drm device */ -int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1); -int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms); -#define intel_pcode_write(drm, mbox, val) \ - intel_pcode_write_timeout((drm), (mbox), (val), 1) - -int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, - u32 reply_mask, u32 reply, int timeout_base_ms); +extern const struct intel_display_pcode_interface i915_display_pcode_interface; #endif /* _INTEL_PCODE_H */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index e76224c848d0..999cbf18f3e5 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -209,6 +209,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/intel_fb_bo.o \ display/intel_fbdev_fb.o \ display/xe_display.o \ + display/xe_display_pcode.o \ display/xe_display_rpm.o \ display/xe_display_wa.o \ display/xe_dsb_buffer.o \ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_pcode.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_pcode.h deleted file mode 100644 index 4fcd3bf6b76f..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_pcode.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef __INTEL_PCODE_H__ -#define __INTEL_PCODE_H__ - -#include "xe_pcode.h" - -#endif /* __INTEL_PCODE_H__ */ diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index c640fe3d8490..c8dd3faa9b97 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -35,6 +35,7 @@ #include "intel_hotplug.h" #include "intel_opregion.h" #include "skl_watermark.h" +#include "xe_display_pcode.h" #include "xe_display_rpm.h" #include "xe_dsb_buffer.h" #include "xe_hdcp_gsc.h" @@ -544,6 +545,7 @@ static const struct intel_display_parent_interface parent = { .initial_plane = &xe_display_initial_plane_interface, .irq = &xe_display_irq_interface, .panic = &xe_display_panic_interface, + .pcode = &xe_display_pcode_interface, .rpm = &xe_display_rpm_interface, .stolen = &xe_display_stolen_interface, }; diff --git a/drivers/gpu/drm/xe/display/xe_display_pcode.c b/drivers/gpu/drm/xe/display/xe_display_pcode.c new file mode 100644 index 000000000000..f6820ef7e666 --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_display_pcode.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2026 Intel Corporation */ + +#include + +#include "xe_device.h" +#include "xe_pcode.h" + +static int xe_display_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1) +{ + struct xe_device *xe = to_xe_device(drm); + struct xe_tile *tile = xe_device_get_root_tile(xe); + + return xe_pcode_read(tile, mbox, val, val1); +} + +static int xe_display_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms) +{ + struct xe_device *xe = to_xe_device(drm); + struct xe_tile *tile = xe_device_get_root_tile(xe); + + return xe_pcode_write_timeout(tile, mbox, val, timeout_ms); +} + +static int xe_display_pcode_request(struct drm_device *drm, u32 mbox, u32 request, + u32 reply_mask, u32 reply, int timeout_base_ms) +{ + struct xe_device *xe = to_xe_device(drm); + struct xe_tile *tile = xe_device_get_root_tile(xe); + + return xe_pcode_request(tile, mbox, request, reply_mask, reply, timeout_base_ms); +} + +const struct intel_display_pcode_interface xe_display_pcode_interface = { + .read = xe_display_pcode_read, + .write = xe_display_pcode_write_timeout, + .request = xe_display_pcode_request, +}; diff --git a/drivers/gpu/drm/xe/display/xe_display_pcode.h b/drivers/gpu/drm/xe/display/xe_display_pcode.h new file mode 100644 index 000000000000..58bd2fb7fb79 --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_display_pcode.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2026 Intel Corporation */ + +#ifndef __XE_DISPLAY_PCODE_H__ +#define __XE_DISPLAY_PCODE_H__ + +extern const struct intel_display_pcode_interface xe_display_pcode_interface; + +#endif diff --git a/drivers/gpu/drm/xe/xe_pcode.c b/drivers/gpu/drm/xe/xe_pcode.c index 0d33c14ea0cf..dc66d0c7ee06 100644 --- a/drivers/gpu/drm/xe/xe_pcode.c +++ b/drivers/gpu/drm/xe/xe_pcode.c @@ -348,33 +348,3 @@ int xe_pcode_probe_early(struct xe_device *xe) return xe_pcode_ready(xe, false); } ALLOW_ERROR_INJECTION(xe_pcode_probe_early, ERRNO); /* See xe_pci_probe */ - -/* Helpers with drm device. These should only be called by the display side */ -#if IS_ENABLED(CONFIG_DRM_XE_DISPLAY) - -int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1) -{ - struct xe_device *xe = to_xe_device(drm); - struct xe_tile *tile = xe_device_get_root_tile(xe); - - return xe_pcode_read(tile, mbox, val, val1); -} - -int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms) -{ - struct xe_device *xe = to_xe_device(drm); - struct xe_tile *tile = xe_device_get_root_tile(xe); - - return xe_pcode_write_timeout(tile, mbox, val, timeout_ms); -} - -int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, - u32 reply_mask, u32 reply, int timeout_base_ms) -{ - struct xe_device *xe = to_xe_device(drm); - struct xe_tile *tile = xe_device_get_root_tile(xe); - - return xe_pcode_request(tile, mbox, request, reply_mask, reply, timeout_base_ms); -} - -#endif diff --git a/drivers/gpu/drm/xe/xe_pcode.h b/drivers/gpu/drm/xe/xe_pcode.h index a5584c1c75f9..490e4f269607 100644 --- a/drivers/gpu/drm/xe/xe_pcode.h +++ b/drivers/gpu/drm/xe/xe_pcode.h @@ -34,12 +34,4 @@ int xe_pcode_request(struct xe_tile *tile, u32 mbox, u32 request, | FIELD_PREP(PCODE_MB_PARAM1, param1)\ | FIELD_PREP(PCODE_MB_PARAM2, param2)) -/* Helpers with drm device */ -int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1); -int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms); -#define intel_pcode_write(drm, mbox, val) \ - intel_pcode_write_timeout((drm), (mbox), (val), 1) -int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, - u32 reply_mask, u32 reply, int timeout_base_ms); - #endif diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index cd091120731c..41f4afe7928c 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -66,6 +66,13 @@ struct intel_display_pc8_interface { void (*unblock)(struct drm_device *drm); }; +struct intel_display_pcode_interface { + int (*read)(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1); + int (*write)(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms); + int (*request)(struct drm_device *drm, u32 mbox, u32 request, + u32 reply_mask, u32 reply, int timeout_base_ms); +}; + struct intel_display_rpm_interface { struct ref_tracker *(*get)(const struct drm_device *drm); struct ref_tracker *(*get_raw)(const struct drm_device *drm); @@ -135,6 +142,9 @@ struct intel_display_parent_interface { /** @pc8: PC8 interface. Optional. */ const struct intel_display_pc8_interface *pc8; + /** @pcode: Pcode interface */ + const struct intel_display_pcode_interface *pcode; + /** @rpm: Runtime PM functions */ const struct intel_display_rpm_interface *rpm; -- cgit v1.2.3 From 2a62dc74726b03b76bab4641ee54b88b6eb7a1d5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Feb 2026 16:49:09 +0200 Subject: drm/i915/dpt: move create/destroy to parent interface Move the DPT create/destroy calls to the display parent interface. With this, we can remove the dummy xe implementation. Reviewed-by: Juha-Pekka Heikkila Link: https://patch.msgid.link/9753b21466c668872f468ccff827eab7be034b0c.1772030909.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpt.h | 3 --- drivers/gpu/drm/i915/display/intel_fb.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_parent.c | 17 +++++++++++++++++ drivers/gpu/drm/i915/display/intel_parent.h | 8 ++++++++ drivers/gpu/drm/i915/i915_dpt.c | 11 ++++++++--- drivers/gpu/drm/i915/i915_dpt.h | 9 +++++++++ drivers/gpu/drm/i915/i915_driver.c | 2 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c | 20 -------------------- include/drm/intel/display_parent_interface.h | 9 +++++++++ 9 files changed, 57 insertions(+), 30 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_dpt.h (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h index 79d9bb80941a..e05b3a716310 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.h +++ b/drivers/gpu/drm/i915/display/intel_dpt.h @@ -8,18 +8,15 @@ #include -struct drm_gem_object; struct i915_address_space; struct i915_vma; struct intel_display; -void intel_dpt_destroy(struct i915_address_space *vm); struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned int alignment); void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm); void intel_dpt_suspend(struct intel_display *display); void intel_dpt_resume(struct intel_display *display); -struct i915_address_space *intel_dpt_create(struct drm_gem_object *obj, size_t size); u64 intel_dpt_offset(struct i915_vma *dpt_vma); #endif /* __INTEL_DPT_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 4ee884639ac2..f718eb139d69 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -16,7 +16,6 @@ #include "intel_display_core.h" #include "intel_display_types.h" #include "intel_display_utils.h" -#include "intel_dpt.h" #include "intel_fb.h" #include "intel_fb_bo.h" #include "intel_frontbuffer.h" @@ -2104,12 +2103,13 @@ int intel_plane_compute_gtt(struct intel_plane_state *plane_state) static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) { + struct intel_display *display = to_intel_display(fb->dev); struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); drm_framebuffer_cleanup(fb); if (intel_fb_uses_dpt(fb)) - intel_dpt_destroy(intel_fb->dpt_vm); + intel_parent_dpt_destroy(display, intel_fb->dpt_vm); intel_fb_bo_framebuffer_fini(intel_fb_bo(fb)); @@ -2311,7 +2311,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, if (intel_fb_needs_pot_stride_remap(intel_fb)) size = intel_remapped_info_size(&intel_fb->remapped_view.gtt.remapped); - vm = intel_dpt_create(obj, size); + vm = intel_parent_dpt_create(display, obj, size); if (IS_ERR(vm)) { drm_dbg_kms(display->drm, "failed to create DPT\n"); ret = PTR_ERR(vm); @@ -2331,7 +2331,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, err_free_dpt: if (intel_fb_uses_dpt(fb)) - intel_dpt_destroy(intel_fb->dpt_vm); + intel_parent_dpt_destroy(display, intel_fb->dpt_vm); err_bo_framebuffer_fini: intel_fb_bo_framebuffer_fini(obj); err_frontbuffer_put: diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index 7f73695a0444..c43e3518a139 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -23,6 +23,23 @@ #include "intel_display_core.h" #include "intel_parent.h" +/* dpt */ +struct i915_address_space *intel_parent_dpt_create(struct intel_display *display, + struct drm_gem_object *obj, + size_t size) +{ + if (display->parent->dpt) + return display->parent->dpt->create(obj, size); + + return NULL; +} + +void intel_parent_dpt_destroy(struct intel_display *display, struct i915_address_space *vm) +{ + if (display->parent->dpt) + display->parent->dpt->destroy(vm); +} + /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, struct intel_hdcp_gsc_context *gsc_context, diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 04782bb26b61..88860e471a0d 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -7,12 +7,20 @@ #include struct dma_fence; +struct drm_gem_object; struct drm_scanout_buffer; +struct i915_address_space; struct intel_display; struct intel_hdcp_gsc_context; struct intel_panic; struct intel_stolen_node; +/* dpt */ +struct i915_address_space *intel_parent_dpt_create(struct intel_display *display, + struct drm_gem_object *obj, + size_t size); +void intel_parent_dpt_destroy(struct intel_display *display, struct i915_address_space *vm); + /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, struct intel_hdcp_gsc_context *gsc_context, diff --git a/drivers/gpu/drm/i915/i915_dpt.c b/drivers/gpu/drm/i915/i915_dpt.c index cd98b06d2685..5237d057119e 100644 --- a/drivers/gpu/drm/i915/i915_dpt.c +++ b/drivers/gpu/drm/i915/i915_dpt.c @@ -4,6 +4,7 @@ */ #include +#include #include "display/intel_display_core.h" #include "display/intel_display_rpm.h" @@ -242,8 +243,7 @@ void intel_dpt_suspend(struct intel_display *display) mutex_unlock(&display->drm->mode_config.fb_lock); } -struct i915_address_space * -intel_dpt_create(struct drm_gem_object *obj, size_t size) +static struct i915_address_space *i915_dpt_create(struct drm_gem_object *obj, size_t size) { struct drm_i915_private *i915 = to_i915(obj->dev); struct drm_i915_gem_object *dpt_obj; @@ -308,7 +308,7 @@ intel_dpt_create(struct drm_gem_object *obj, size_t size) return &dpt->vm; } -void intel_dpt_destroy(struct i915_address_space *vm) +static void i915_dpt_destroy(struct i915_address_space *vm) { struct i915_dpt *dpt = i915_vm_to_dpt(vm); @@ -320,3 +320,8 @@ u64 intel_dpt_offset(struct i915_vma *dpt_vma) { return i915_vma_offset(dpt_vma); } + +const struct intel_display_dpt_interface i915_display_dpt_interface = { + .create = i915_dpt_create, + .destroy = i915_dpt_destroy, +}; diff --git a/drivers/gpu/drm/i915/i915_dpt.h b/drivers/gpu/drm/i915/i915_dpt.h new file mode 100644 index 000000000000..494cd4af3bcd --- /dev/null +++ b/drivers/gpu/drm/i915/i915_dpt.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2026 Intel Corporation */ + +#ifndef __I915_DPT_H__ +#define __I915_DPT_H__ + +extern const struct intel_display_dpt_interface i915_display_dpt_interface; + +#endif /* __I915_DPT_H__ */ diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 6d8fbf845bc2..31a608ccab00 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -91,6 +91,7 @@ #include "i915_debugfs.h" #include "i915_display_pc8.h" +#include "i915_dpt.h" #include "i915_driver.h" #include "i915_drm_client.h" #include "i915_drv.h" @@ -761,6 +762,7 @@ static bool vgpu_active(struct drm_device *drm) } static const struct intel_display_parent_interface parent = { + .dpt = &i915_display_dpt_interface, .dsb = &i915_display_dsb_interface, .hdcp = &i915_display_hdcp_interface, .initial_plane = &i915_display_initial_plane_interface, diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 36eb6c0b9d76..4cb37717d3b4 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -8,7 +8,6 @@ #include "i915_vma.h" #include "intel_display_core.h" #include "intel_display_types.h" -#include "intel_dpt.h" #include "intel_fb.h" #include "intel_fb_pin.h" #include "intel_fbdev.h" @@ -452,25 +451,6 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) old_plane_state->ggtt_vma = NULL; } -/* - * For Xe introduce dummy intel_dpt_create which just return NULL, - * intel_dpt_destroy which does nothing, and fake intel_dpt_ofsset returning 0; - */ -struct i915_address_space *intel_dpt_create(struct drm_gem_object *obj, size_t size) -{ - return NULL; -} - -void intel_dpt_destroy(struct i915_address_space *vm) -{ - return; -} - -u64 intel_dpt_offset(struct i915_vma *dpt_vma) -{ - return 0; -} - void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map) { *map = vma->bo->vmap; diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 41f4afe7928c..48abbe187d61 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -13,6 +13,7 @@ struct drm_framebuffer; struct drm_gem_object; struct drm_plane_state; struct drm_scanout_buffer; +struct i915_address_space; struct i915_vma; struct intel_dsb_buffer; struct intel_hdcp_gsc_context; @@ -23,6 +24,11 @@ struct ref_tracker; /* Keep struct definitions sorted */ +struct intel_display_dpt_interface { + struct i915_address_space *(*create)(struct drm_gem_object *obj, size_t size); + void (*destroy)(struct i915_address_space *vm); +}; + struct intel_display_dsb_interface { u32 (*ggtt_offset)(struct intel_dsb_buffer *dsb_buf); void (*write)(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val); @@ -124,6 +130,9 @@ struct intel_display_stolen_interface { * check the optional pointers. */ struct intel_display_parent_interface { + /** @dsb: DPT interface. Optional. */ + const struct intel_display_dpt_interface *dpt; + /** @dsb: DSB buffer interface */ const struct intel_display_dsb_interface *dsb; -- cgit v1.2.3 From 3834ea7499ca2c88e0f67bb6929668f78bb67127 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Feb 2026 16:49:10 +0200 Subject: drm/i915/dpt: move suspend/resume to parent interface Add per-vm DPT suspend/resume calls to the display parent interface, and lift the generic code away from i915 specific code. Reviewed-by: Juha-Pekka Heikkila Link: https://patch.msgid.link/080945a49559ec1f5183ad409e1526736e828d90.1772030909.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpt.h | 3 -- drivers/gpu/drm/i915/display/intel_dpt_common.c | 59 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dpt_common.h | 3 ++ drivers/gpu/drm/i915/display/intel_parent.c | 12 +++++ drivers/gpu/drm/i915/display/intel_parent.h | 2 + drivers/gpu/drm/i915/i915_dpt.c | 72 +++++-------------------- drivers/gpu/drm/i915/i915_driver.c | 2 +- include/drm/intel/display_parent_interface.h | 2 + 8 files changed, 91 insertions(+), 64 deletions(-) (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h index e05b3a716310..0482af43e946 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.h +++ b/drivers/gpu/drm/i915/display/intel_dpt.h @@ -10,13 +10,10 @@ struct i915_address_space; struct i915_vma; -struct intel_display; struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned int alignment); void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm); -void intel_dpt_suspend(struct intel_display *display); -void intel_dpt_resume(struct intel_display *display); u64 intel_dpt_offset(struct i915_vma *dpt_vma); #endif /* __INTEL_DPT_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dpt_common.c b/drivers/gpu/drm/i915/display/intel_dpt_common.c index 5eb88d51dba1..6551318b037b 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt_common.c +++ b/drivers/gpu/drm/i915/display/intel_dpt_common.c @@ -7,6 +7,7 @@ #include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_dpt_common.h" +#include "intel_parent.h" #include "skl_universal_plane_regs.h" void intel_dpt_configure(struct intel_crtc *crtc) @@ -33,3 +34,61 @@ void intel_dpt_configure(struct intel_crtc *crtc) CHICKEN_MISC_DISABLE_DPT); } } + +/** + * intel_dpt_suspend - suspend the memory mapping for all DPT FBs during system suspend + * @display: display device instance + * + * Suspend the memory mapping during system suspend for all framebuffers which + * are mapped to HW via a GGTT->DPT page table. + * + * This function must be called before the mappings in GGTT are suspended calling + * i915_ggtt_suspend(). + */ +void intel_dpt_suspend(struct intel_display *display) +{ + struct drm_framebuffer *drm_fb; + + if (!HAS_DISPLAY(display)) + return; + + mutex_lock(&display->drm->mode_config.fb_lock); + + drm_for_each_fb(drm_fb, display->drm) { + struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); + + if (fb->dpt_vm) + intel_parent_dpt_suspend(display, fb->dpt_vm); + } + + mutex_unlock(&display->drm->mode_config.fb_lock); +} + +/** + * intel_dpt_resume - restore the memory mapping for all DPT FBs during system resume + * @display: display device instance + * + * Restore the memory mapping during system resume for all framebuffers which + * are mapped to HW via a GGTT->DPT page table. The content of these page + * tables are not stored in the hibernation image during S4 and S3RST->S4 + * transitions, so here we reprogram the PTE entries in those tables. + * + * This function must be called after the mappings in GGTT have been restored calling + * i915_ggtt_resume(). + */ +void intel_dpt_resume(struct intel_display *display) +{ + struct drm_framebuffer *drm_fb; + + if (!HAS_DISPLAY(display)) + return; + + mutex_lock(&display->drm->mode_config.fb_lock); + drm_for_each_fb(drm_fb, display->drm) { + struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); + + if (fb->dpt_vm) + intel_parent_dpt_resume(display, fb->dpt_vm); + } + mutex_unlock(&display->drm->mode_config.fb_lock); +} diff --git a/drivers/gpu/drm/i915/display/intel_dpt_common.h b/drivers/gpu/drm/i915/display/intel_dpt_common.h index 6d7de405126a..11bd495693b2 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt_common.h +++ b/drivers/gpu/drm/i915/display/intel_dpt_common.h @@ -7,7 +7,10 @@ #define __INTEL_DPT_COMMON_H__ struct intel_crtc; +struct intel_display; void intel_dpt_configure(struct intel_crtc *crtc); +void intel_dpt_suspend(struct intel_display *display); +void intel_dpt_resume(struct intel_display *display); #endif /* __INTEL_DPT_COMMON_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index c43e3518a139..a79ea775bde2 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -40,6 +40,18 @@ void intel_parent_dpt_destroy(struct intel_display *display, struct i915_address display->parent->dpt->destroy(vm); } +void intel_parent_dpt_suspend(struct intel_display *display, struct i915_address_space *vm) +{ + if (display->parent->dpt) + display->parent->dpt->suspend(vm); +} + +void intel_parent_dpt_resume(struct intel_display *display, struct i915_address_space *vm) +{ + if (display->parent->dpt) + display->parent->dpt->resume(vm); +} + /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, struct intel_hdcp_gsc_context *gsc_context, diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 88860e471a0d..be577ce10c21 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -20,6 +20,8 @@ struct i915_address_space *intel_parent_dpt_create(struct intel_display *display struct drm_gem_object *obj, size_t size); void intel_parent_dpt_destroy(struct intel_display *display, struct i915_address_space *vm); +void intel_parent_dpt_suspend(struct intel_display *display, struct i915_address_space *vm); +void intel_parent_dpt_resume(struct intel_display *display, struct i915_address_space *vm); /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/i915_dpt.c b/drivers/gpu/drm/i915/i915_dpt.c index 5237d057119e..635127ee5505 100644 --- a/drivers/gpu/drm/i915/i915_dpt.c +++ b/drivers/gpu/drm/i915/i915_dpt.c @@ -8,9 +8,7 @@ #include "display/intel_display_core.h" #include "display/intel_display_rpm.h" -#include "display/intel_display_types.h" #include "display/intel_dpt.h" -#include "display/intel_fb.h" #include "gem/i915_gem_domain.h" #include "gem/i915_gem_internal.h" #include "gem/i915_gem_lmem.h" @@ -185,64 +183,6 @@ void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm) i915_vma_put(dpt->vma); } -/** - * intel_dpt_resume - restore the memory mapping for all DPT FBs during system resume - * @display: display device instance - * - * Restore the memory mapping during system resume for all framebuffers which - * are mapped to HW via a GGTT->DPT page table. The content of these page - * tables are not stored in the hibernation image during S4 and S3RST->S4 - * transitions, so here we reprogram the PTE entries in those tables. - * - * This function must be called after the mappings in GGTT have been restored calling - * i915_ggtt_resume(). - */ -void intel_dpt_resume(struct intel_display *display) -{ - struct drm_framebuffer *drm_fb; - - if (!HAS_DISPLAY(display)) - return; - - mutex_lock(&display->drm->mode_config.fb_lock); - drm_for_each_fb(drm_fb, display->drm) { - struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); - - if (fb->dpt_vm) - i915_ggtt_resume_vm(fb->dpt_vm, true); - } - mutex_unlock(&display->drm->mode_config.fb_lock); -} - -/** - * intel_dpt_suspend - suspend the memory mapping for all DPT FBs during system suspend - * @display: display device instance - * - * Suspend the memory mapping during system suspend for all framebuffers which - * are mapped to HW via a GGTT->DPT page table. - * - * This function must be called before the mappings in GGTT are suspended calling - * i915_ggtt_suspend(). - */ -void intel_dpt_suspend(struct intel_display *display) -{ - struct drm_framebuffer *drm_fb; - - if (!HAS_DISPLAY(display)) - return; - - mutex_lock(&display->drm->mode_config.fb_lock); - - drm_for_each_fb(drm_fb, display->drm) { - struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); - - if (fb->dpt_vm) - i915_ggtt_suspend_vm(fb->dpt_vm, true); - } - - mutex_unlock(&display->drm->mode_config.fb_lock); -} - static struct i915_address_space *i915_dpt_create(struct drm_gem_object *obj, size_t size) { struct drm_i915_private *i915 = to_i915(obj->dev); @@ -316,6 +256,16 @@ static void i915_dpt_destroy(struct i915_address_space *vm) i915_vm_put(&dpt->vm); } +static void i915_dpt_suspend(struct i915_address_space *vm) +{ + i915_ggtt_suspend_vm(vm, true); +} + +static void i915_dpt_resume(struct i915_address_space *vm) +{ + i915_ggtt_resume_vm(vm, true); +} + u64 intel_dpt_offset(struct i915_vma *dpt_vma) { return i915_vma_offset(dpt_vma); @@ -324,4 +274,6 @@ u64 intel_dpt_offset(struct i915_vma *dpt_vma) const struct intel_display_dpt_interface i915_display_dpt_interface = { .create = i915_dpt_create, .destroy = i915_dpt_destroy, + .suspend = i915_dpt_suspend, + .resume = i915_dpt_resume, }; diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 31a608ccab00..570626f8a554 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -59,7 +59,7 @@ #include "display/intel_display_power.h" #include "display/intel_dmc.h" #include "display/intel_dp.h" -#include "display/intel_dpt.h" +#include "display/intel_dpt_common.h" #include "display/intel_dram.h" #include "display/intel_encoder.h" #include "display/intel_fbdev.h" diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 48abbe187d61..2af4d6e99fd0 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -27,6 +27,8 @@ struct ref_tracker; struct intel_display_dpt_interface { struct i915_address_space *(*create)(struct drm_gem_object *obj, size_t size); void (*destroy)(struct i915_address_space *vm); + void (*suspend)(struct i915_address_space *vm); + void (*resume)(struct i915_address_space *vm); }; struct intel_display_dsb_interface { -- cgit v1.2.3 From 4226479f912e829ffba3993438ebc64dac90ae18 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Feb 2026 16:49:16 +0200 Subject: drm/i915/dpt: pass opaque struct intel_dpt around instead of i915_address_space struct i915_address_space is used in an opaque fashion in the display parent interface, but it's just one include away from being non-opaque. And anyway the name is rather specific. Switch to using the struct intel_dpt instead, which embeds struct i915_address_space anyway. With the definition hidden in i915_dpt.c, this can't be accidentally made non-opaque, and the type seems rather more generic anyway. We do have to add a new helper i915_dpt_to_vm(), as there's one case in intel_fb_pin_to_dpt() that requires direct access to struct i915_address_space. But this just underlines the point about opacity. Reviewed-by: Juha-Pekka Heikkila Link: https://patch.msgid.link/daa39178c0b0305b010564952d691f06e3cd63ca.1772030909.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/display/intel_dpt.c | 8 +++--- drivers/gpu/drm/i915/display/intel_fb.c | 14 +++++----- drivers/gpu/drm/i915/display/intel_fb_pin.c | 11 ++++---- drivers/gpu/drm/i915/display/intel_parent.c | 17 ++++++------ drivers/gpu/drm/i915/display/intel_parent.h | 13 +++++----- drivers/gpu/drm/i915/i915_dpt.c | 30 +++++++++++----------- drivers/gpu/drm/i915/i915_dpt.h | 6 +++-- include/drm/intel/display_parent_interface.h | 10 ++++---- 9 files changed, 56 insertions(+), 55 deletions(-) (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index e8e4af03a6a6..8a2b37c7bccf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -145,7 +145,7 @@ struct intel_framebuffer { struct intel_fb_view remapped_view; }; - struct i915_address_space *dpt_vm; + struct intel_dpt *dpt; unsigned int min_alignment; unsigned int vtd_guard; diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index dffd500d378e..145dc9511116 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -57,8 +57,8 @@ void intel_dpt_suspend(struct intel_display *display) drm_for_each_fb(drm_fb, display->drm) { struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); - if (fb->dpt_vm) - intel_parent_dpt_suspend(display, fb->dpt_vm); + if (fb->dpt) + intel_parent_dpt_suspend(display, fb->dpt); } mutex_unlock(&display->drm->mode_config.fb_lock); @@ -87,8 +87,8 @@ void intel_dpt_resume(struct intel_display *display) drm_for_each_fb(drm_fb, display->drm) { struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); - if (fb->dpt_vm) - intel_parent_dpt_resume(display, fb->dpt_vm); + if (fb->dpt) + intel_parent_dpt_resume(display, fb->dpt); } mutex_unlock(&display->drm->mode_config.fb_lock); } diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index f718eb139d69..6be07d8a7e81 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2109,7 +2109,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) drm_framebuffer_cleanup(fb); if (intel_fb_uses_dpt(fb)) - intel_parent_dpt_destroy(display, intel_fb->dpt_vm); + intel_parent_dpt_destroy(display, intel_fb->dpt); intel_fb_bo_framebuffer_fini(intel_fb_bo(fb)); @@ -2305,20 +2305,20 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, if (intel_fb_uses_dpt(fb)) { struct drm_gem_object *obj = intel_fb_bo(&intel_fb->base); - struct i915_address_space *vm; + struct intel_dpt *dpt; size_t size = 0; if (intel_fb_needs_pot_stride_remap(intel_fb)) size = intel_remapped_info_size(&intel_fb->remapped_view.gtt.remapped); - vm = intel_parent_dpt_create(display, obj, size); - if (IS_ERR(vm)) { + dpt = intel_parent_dpt_create(display, obj, size); + if (IS_ERR(dpt)) { drm_dbg_kms(display->drm, "failed to create DPT\n"); - ret = PTR_ERR(vm); + ret = PTR_ERR(dpt); goto err_frontbuffer_put; } - intel_fb->dpt_vm = vm; + intel_fb->dpt = dpt; } ret = drm_framebuffer_init(display->drm, fb, &intel_fb_funcs); @@ -2331,7 +2331,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, err_free_dpt: if (intel_fb_uses_dpt(fb)) - intel_parent_dpt_destroy(display, intel_fb->dpt_vm); + intel_parent_dpt_destroy(display, intel_fb->dpt); err_bo_framebuffer_fini: intel_fb_bo_framebuffer_fini(obj); err_frontbuffer_put: diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index d2e4200f2cef..738d77a1468a 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -27,13 +27,14 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, const struct i915_gtt_view *view, unsigned int alignment, unsigned long *out_flags, - struct i915_address_space *vm) + struct intel_dpt *dpt) { struct drm_device *dev = fb->dev; struct intel_display *display = to_intel_display(dev); 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); + struct i915_address_space *vm = i915_dpt_to_vm(dpt); struct i915_gem_ww_ctx ww; struct i915_vma *vma; int ret; @@ -284,7 +285,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state, } else { unsigned int alignment = intel_plane_fb_min_alignment(plane_state); - vma = i915_dpt_pin_to_ggtt(fb->dpt_vm, alignment / 512); + vma = i915_dpt_pin_to_ggtt(fb->dpt, alignment / 512); if (IS_ERR(vma)) return PTR_ERR(vma); @@ -292,9 +293,9 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state, vma = intel_fb_pin_to_dpt(&fb->base, &plane_state->view.gtt, alignment, &plane_state->flags, - fb->dpt_vm); + fb->dpt); if (IS_ERR(vma)) { - i915_dpt_unpin_from_ggtt(fb->dpt_vm); + i915_dpt_unpin_from_ggtt(fb->dpt); plane_state->ggtt_vma = NULL; return PTR_ERR(vma); } @@ -346,7 +347,7 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) vma = fetch_and_zero(&old_plane_state->ggtt_vma); if (vma) - i915_dpt_unpin_from_ggtt(fb->dpt_vm); + i915_dpt_unpin_from_ggtt(fb->dpt); } } diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index a79ea775bde2..7044632ef3fc 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -24,9 +24,8 @@ #include "intel_parent.h" /* dpt */ -struct i915_address_space *intel_parent_dpt_create(struct intel_display *display, - struct drm_gem_object *obj, - size_t size) +struct intel_dpt *intel_parent_dpt_create(struct intel_display *display, + struct drm_gem_object *obj, size_t size) { if (display->parent->dpt) return display->parent->dpt->create(obj, size); @@ -34,22 +33,22 @@ struct i915_address_space *intel_parent_dpt_create(struct intel_display *display return NULL; } -void intel_parent_dpt_destroy(struct intel_display *display, struct i915_address_space *vm) +void intel_parent_dpt_destroy(struct intel_display *display, struct intel_dpt *dpt) { if (display->parent->dpt) - display->parent->dpt->destroy(vm); + display->parent->dpt->destroy(dpt); } -void intel_parent_dpt_suspend(struct intel_display *display, struct i915_address_space *vm) +void intel_parent_dpt_suspend(struct intel_display *display, struct intel_dpt *dpt) { if (display->parent->dpt) - display->parent->dpt->suspend(vm); + display->parent->dpt->suspend(dpt); } -void intel_parent_dpt_resume(struct intel_display *display, struct i915_address_space *vm) +void intel_parent_dpt_resume(struct intel_display *display, struct intel_dpt *dpt) { if (display->parent->dpt) - display->parent->dpt->resume(vm); + display->parent->dpt->resume(dpt); } /* hdcp */ diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index be577ce10c21..002234e81ce6 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -9,19 +9,18 @@ struct dma_fence; struct drm_gem_object; struct drm_scanout_buffer; -struct i915_address_space; struct intel_display; +struct intel_dpt; struct intel_hdcp_gsc_context; struct intel_panic; struct intel_stolen_node; /* dpt */ -struct i915_address_space *intel_parent_dpt_create(struct intel_display *display, - struct drm_gem_object *obj, - size_t size); -void intel_parent_dpt_destroy(struct intel_display *display, struct i915_address_space *vm); -void intel_parent_dpt_suspend(struct intel_display *display, struct i915_address_space *vm); -void intel_parent_dpt_resume(struct intel_display *display, struct i915_address_space *vm); +struct intel_dpt *intel_parent_dpt_create(struct intel_display *display, + struct drm_gem_object *obj, size_t size); +void intel_parent_dpt_destroy(struct intel_display *display, struct intel_dpt *dpt); +void intel_parent_dpt_suspend(struct intel_display *display, struct intel_dpt *dpt); +void intel_parent_dpt_resume(struct intel_display *display, struct intel_dpt *dpt); /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/i915_dpt.c b/drivers/gpu/drm/i915/i915_dpt.c index baf45d70c152..9f47bb563c85 100644 --- a/drivers/gpu/drm/i915/i915_dpt.c +++ b/drivers/gpu/drm/i915/i915_dpt.c @@ -33,6 +33,11 @@ i915_vm_to_dpt(struct i915_address_space *vm) return container_of(vm, struct intel_dpt, vm); } +struct i915_address_space *i915_dpt_to_vm(struct intel_dpt *dpt) +{ + return &dpt->vm; +} + static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) { writeq(pte, addr); @@ -121,11 +126,10 @@ static void dpt_cleanup(struct i915_address_space *vm) i915_gem_object_put(dpt->obj); } -struct i915_vma *i915_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned int alignment) +struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignment) { - struct drm_i915_private *i915 = vm->i915; + struct drm_i915_private *i915 = dpt->vm.i915; struct intel_display *display = i915->display; - struct intel_dpt *dpt = i915_vm_to_dpt(vm); struct ref_tracker *wakeref; struct i915_vma *vma; void __iomem *iomem; @@ -173,15 +177,13 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned in return err ? ERR_PTR(err) : vma; } -void i915_dpt_unpin_from_ggtt(struct i915_address_space *vm) +void i915_dpt_unpin_from_ggtt(struct intel_dpt *dpt) { - struct intel_dpt *dpt = i915_vm_to_dpt(vm); - i915_vma_unpin_iomap(dpt->vma); i915_vma_put(dpt->vma); } -static struct i915_address_space *i915_dpt_create(struct drm_gem_object *obj, size_t size) +static struct intel_dpt *i915_dpt_create(struct drm_gem_object *obj, size_t size) { struct drm_i915_private *i915 = to_i915(obj->dev); struct drm_i915_gem_object *dpt_obj; @@ -243,25 +245,23 @@ static struct i915_address_space *i915_dpt_create(struct drm_gem_object *obj, si dpt->obj = dpt_obj; dpt->obj->is_dpt = true; - return &dpt->vm; + return dpt; } -static void i915_dpt_destroy(struct i915_address_space *vm) +static void i915_dpt_destroy(struct intel_dpt *dpt) { - struct intel_dpt *dpt = i915_vm_to_dpt(vm); - dpt->obj->is_dpt = false; i915_vm_put(&dpt->vm); } -static void i915_dpt_suspend(struct i915_address_space *vm) +static void i915_dpt_suspend(struct intel_dpt *dpt) { - i915_ggtt_suspend_vm(vm, true); + i915_ggtt_suspend_vm(&dpt->vm, true); } -static void i915_dpt_resume(struct i915_address_space *vm) +static void i915_dpt_resume(struct intel_dpt *dpt) { - i915_ggtt_resume_vm(vm, true); + i915_ggtt_resume_vm(&dpt->vm, true); } u64 i915_dpt_offset(struct i915_vma *dpt_vma) diff --git a/drivers/gpu/drm/i915/i915_dpt.h b/drivers/gpu/drm/i915/i915_dpt.h index 3b76e9760600..08dbe444fe18 100644 --- a/drivers/gpu/drm/i915/i915_dpt.h +++ b/drivers/gpu/drm/i915/i915_dpt.h @@ -8,9 +8,11 @@ struct i915_address_space; struct i915_vma; +struct intel_dpt; -struct i915_vma *i915_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned int alignment); -void i915_dpt_unpin_from_ggtt(struct i915_address_space *vm); +struct i915_address_space *i915_dpt_to_vm(struct intel_dpt *dpt); +struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignment); +void i915_dpt_unpin_from_ggtt(struct intel_dpt *dpt); u64 i915_dpt_offset(struct i915_vma *dpt_vma); extern const struct intel_display_dpt_interface i915_display_dpt_interface; diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 2af4d6e99fd0..50da825ec06c 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -13,8 +13,8 @@ struct drm_framebuffer; struct drm_gem_object; struct drm_plane_state; struct drm_scanout_buffer; -struct i915_address_space; struct i915_vma; +struct intel_dpt; struct intel_dsb_buffer; struct intel_hdcp_gsc_context; struct intel_initial_plane_config; @@ -25,10 +25,10 @@ struct ref_tracker; /* Keep struct definitions sorted */ struct intel_display_dpt_interface { - struct i915_address_space *(*create)(struct drm_gem_object *obj, size_t size); - void (*destroy)(struct i915_address_space *vm); - void (*suspend)(struct i915_address_space *vm); - void (*resume)(struct i915_address_space *vm); + struct intel_dpt *(*create)(struct drm_gem_object *obj, size_t size); + void (*destroy)(struct intel_dpt *dpt); + void (*suspend)(struct intel_dpt *dpt); + void (*resume)(struct intel_dpt *dpt); }; struct intel_display_dsb_interface { -- cgit v1.2.3 From e3f33adfa3a3be16ef59ed849fbbd10e966e98b0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 26 Feb 2026 15:01:50 +0200 Subject: drm/i915/overlay: Convert overlay to parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the direct i915_overlay_*() calls from the display side to go over a new parent interface instead. v2: Correctly handle the ERR_PTR returned by i915_overlay_obj_lookup() (Jani) v3: Rebase due to the NULL check in intel_overlay_cleanup() Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260226130150.16816-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_overlay.c | 36 ++++++------- drivers/gpu/drm/i915/display/intel_overlay.h | 30 ----------- drivers/gpu/drm/i915/display/intel_parent.c | 76 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_parent.h | 25 +++++++++ drivers/gpu/drm/i915/i915_driver.c | 2 + drivers/gpu/drm/i915/i915_overlay.c | 57 +++++++++++++-------- drivers/gpu/drm/i915/i915_overlay.h | 34 +------------ drivers/gpu/drm/xe/Makefile | 1 + include/drm/intel/display_parent_interface.h | 33 ++++++++++++ 9 files changed, 193 insertions(+), 101 deletions(-) (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 497bd4ec2224..12a325ceae6f 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -30,13 +30,13 @@ #include #include -#include "i915_overlay.h" #include "intel_color_regs.h" #include "intel_de.h" #include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_frontbuffer.h" #include "intel_overlay.h" +#include "intel_parent.h" #include "intel_pfit_regs.h" /* Limits for overlay size. According to intel doc, the real limits are: @@ -199,7 +199,7 @@ void intel_overlay_reset(struct intel_display *display) overlay->old_yscale = 0; overlay->crtc = NULL; - i915_overlay_reset(display->drm); + intel_parent_overlay_reset(display); } static int packed_depth_bytes(u32 format) @@ -477,19 +477,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, drm_WARN_ON(display->drm, !drm_modeset_is_locked(&display->drm->mode_config.connection_mutex)); - ret = i915_overlay_release_old_vid(display->drm); + ret = intel_parent_overlay_release_old_vid(display); if (ret != 0) return ret; atomic_inc(&display->restore.pending_fb_pin); - vma = i915_overlay_pin_fb(display->drm, obj, &offset); + vma = intel_parent_overlay_pin_fb(display, obj, &offset); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto out_pin_section; } - if (!i915_overlay_is_active(display->drm)) { + if (!intel_parent_overlay_is_active(display)) { const struct intel_crtc_state *crtc_state = overlay->crtc->config; u32 oconfig = 0; @@ -505,7 +505,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, OCONF_PIPE_A : OCONF_PIPE_B; iowrite32(oconfig, ®s->OCONFIG); - ret = i915_overlay_on(display->drm, INTEL_FRONTBUFFER_OVERLAY(pipe)); + ret = intel_parent_overlay_on(display, INTEL_FRONTBUFFER_OVERLAY(pipe)); if (ret != 0) goto out_unpin; } @@ -563,14 +563,14 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (tmp & (1 << 17)) drm_dbg(display->drm, "overlay underrun, DOVSTA: %x\n", tmp); - ret = i915_overlay_continue(display->drm, vma, scale_changed); + ret = intel_parent_overlay_continue(display, vma, scale_changed); if (ret) goto out_unpin; return 0; out_unpin: - i915_overlay_unpin_fb(display->drm, vma); + intel_parent_overlay_unpin_fb(display, vma); out_pin_section: atomic_dec(&display->restore.pending_fb_pin); @@ -585,14 +585,14 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) drm_WARN_ON(display->drm, !drm_modeset_is_locked(&display->drm->mode_config.connection_mutex)); - ret = i915_overlay_recover_from_interrupt(display->drm); + ret = intel_parent_overlay_recover_from_interrupt(display); if (ret != 0) return ret; - if (!i915_overlay_is_active(display->drm)) + if (!intel_parent_overlay_is_active(display)) return 0; - ret = i915_overlay_release_old_vid(display->drm); + ret = intel_parent_overlay_release_old_vid(display); if (ret != 0) return ret; @@ -601,7 +601,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) overlay->crtc->overlay = NULL; overlay->crtc = NULL; - return i915_overlay_off(display->drm); + return intel_parent_overlay_off(display); } static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, @@ -822,13 +822,13 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, return -ENOENT; crtc = to_intel_crtc(drmmode_crtc); - obj = i915_overlay_obj_lookup(dev, file_priv, params->bo_handle); + obj = intel_parent_overlay_obj_lookup(display, file_priv, params->bo_handle); if (IS_ERR(obj)) return PTR_ERR(obj); drm_modeset_lock_all(dev); - ret = i915_overlay_recover_from_interrupt(dev); + ret = intel_parent_overlay_recover_from_interrupt(display); if (ret != 0) goto out_unlock; @@ -998,7 +998,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, if (DISPLAY_VER(display) == 2) goto out_unlock; - if (i915_overlay_is_active(display->drm)) { + if (intel_parent_overlay_is_active(display)) { ret = -EBUSY; goto out_unlock; } @@ -1036,8 +1036,8 @@ void intel_overlay_setup(struct intel_display *display) if (!overlay) return; - regs = i915_overlay_setup(display->drm, - OVERLAY_NEEDS_PHYSICAL(display)); + regs = intel_parent_overlay_setup(display, + OVERLAY_NEEDS_PHYSICAL(display)); if (IS_ERR(regs)) goto out_free; @@ -1071,7 +1071,7 @@ void intel_overlay_cleanup(struct intel_display *display) if (!display->overlay) return; - i915_overlay_cleanup(display->drm); + intel_parent_overlay_cleanup(display); kfree(display->overlay); display->overlay = NULL; diff --git a/drivers/gpu/drm/i915/display/intel_overlay.h b/drivers/gpu/drm/i915/display/intel_overlay.h index 4ef6882b9acb..a4291d6dd528 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.h +++ b/drivers/gpu/drm/i915/display/intel_overlay.h @@ -14,7 +14,6 @@ struct drm_printer; struct intel_display; struct intel_overlay; -#ifdef I915 void intel_overlay_setup(struct intel_display *display); bool intel_overlay_available(struct intel_display *display); void intel_overlay_cleanup(struct intel_display *display); @@ -24,34 +23,5 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void intel_overlay_reset(struct intel_display *display); -#else -static inline void intel_overlay_setup(struct intel_display *display) -{ -} -static inline bool intel_overlay_available(struct intel_display *display) -{ - return false; -} -static inline void intel_overlay_cleanup(struct intel_display *display) -{ -} -static inline int intel_overlay_switch_off(struct intel_overlay *overlay) -{ - return 0; -} -static inline int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return 0; -} -static inline int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return 0; -} -static inline void intel_overlay_reset(struct intel_display *display) -{ -} -#endif #endif /* __INTEL_OVERLAY_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index 7044632ef3fc..89f78ca1cd15 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -87,6 +87,82 @@ void intel_parent_irq_synchronize(struct intel_display *display) display->parent->irq->synchronize(display->drm); } +/* overlay */ +bool intel_parent_overlay_is_active(struct intel_display *display) +{ + return display->parent->overlay->is_active(display->drm); +} + +int intel_parent_overlay_on(struct intel_display *display, + u32 frontbuffer_bits) +{ + return display->parent->overlay->overlay_on(display->drm, + frontbuffer_bits); +} + +int intel_parent_overlay_continue(struct intel_display *display, + struct i915_vma *vma, + bool load_polyphase_filter) +{ + return display->parent->overlay->overlay_continue(display->drm, vma, + load_polyphase_filter); +} + +int intel_parent_overlay_off(struct intel_display *display) +{ + return display->parent->overlay->overlay_off(display->drm); +} + +int intel_parent_overlay_recover_from_interrupt(struct intel_display *display) +{ + return display->parent->overlay->recover_from_interrupt(display->drm); +} + +int intel_parent_overlay_release_old_vid(struct intel_display *display) +{ + return display->parent->overlay->release_old_vid(display->drm); +} + +void intel_parent_overlay_reset(struct intel_display *display) +{ + display->parent->overlay->reset(display->drm); +} + +struct i915_vma *intel_parent_overlay_pin_fb(struct intel_display *display, + struct drm_gem_object *obj, + u32 *offset) +{ + return display->parent->overlay->pin_fb(display->drm, obj, offset); +} + +void intel_parent_overlay_unpin_fb(struct intel_display *display, + struct i915_vma *vma) +{ + return display->parent->overlay->unpin_fb(display->drm, vma); +} + +struct drm_gem_object *intel_parent_overlay_obj_lookup(struct intel_display *display, + struct drm_file *filp, + u32 handle) +{ + return display->parent->overlay->obj_lookup(display->drm, + filp, handle); +} + +void __iomem *intel_parent_overlay_setup(struct intel_display *display, + bool needs_physical) +{ + if (drm_WARN_ON_ONCE(display->drm, !display->parent->overlay)) + return ERR_PTR(-ENODEV); + + return display->parent->overlay->setup(display->drm, needs_physical); +} + +void intel_parent_overlay_cleanup(struct intel_display *display) +{ + display->parent->overlay->cleanup(display->drm); +} + /* panic */ struct intel_panic *intel_parent_panic_alloc(struct intel_display *display) { diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 002234e81ce6..2317482ef072 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -7,8 +7,10 @@ #include struct dma_fence; +struct drm_file; struct drm_gem_object; struct drm_scanout_buffer; +struct i915_vma; struct intel_display; struct intel_dpt; struct intel_hdcp_gsc_context; @@ -36,6 +38,29 @@ void intel_parent_hdcp_gsc_context_free(struct intel_display *display, bool intel_parent_irq_enabled(struct intel_display *display); void intel_parent_irq_synchronize(struct intel_display *display); +/* overlay */ +bool intel_parent_overlay_is_active(struct intel_display *display); +int intel_parent_overlay_on(struct intel_display *display, + u32 frontbuffer_bits); +int intel_parent_overlay_continue(struct intel_display *display, + struct i915_vma *vma, + bool load_polyphase_filter); +int intel_parent_overlay_off(struct intel_display *display); +int intel_parent_overlay_recover_from_interrupt(struct intel_display *display); +int intel_parent_overlay_release_old_vid(struct intel_display *display); +void intel_parent_overlay_reset(struct intel_display *display); +struct i915_vma *intel_parent_overlay_pin_fb(struct intel_display *display, + struct drm_gem_object *obj, + u32 *offset); +void intel_parent_overlay_unpin_fb(struct intel_display *display, + struct i915_vma *vma); +struct drm_gem_object *intel_parent_overlay_obj_lookup(struct intel_display *display, + struct drm_file *filp, + u32 handle); +void __iomem *intel_parent_overlay_setup(struct intel_display *display, + bool needs_physical); +void intel_parent_overlay_cleanup(struct intel_display *display); + /* panic */ struct intel_panic *intel_parent_panic_alloc(struct intel_display *display); int intel_parent_panic_setup(struct intel_display *display, struct intel_panic *panic, struct drm_scanout_buffer *sb); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 31a608ccab00..5f77e891604d 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -107,6 +107,7 @@ #include "i915_ioctl.h" #include "i915_irq.h" #include "i915_memcpy.h" +#include "i915_overlay.h" #include "i915_panic.h" #include "i915_perf.h" #include "i915_query.h" @@ -767,6 +768,7 @@ static const struct intel_display_parent_interface parent = { .hdcp = &i915_display_hdcp_interface, .initial_plane = &i915_display_initial_plane_interface, .irq = &i915_display_irq_interface, + .overlay = &i915_display_overlay_interface, .panic = &i915_display_panic_interface, .pc8 = &i915_display_pc8_interface, .pcode = &i915_display_pcode_interface, diff --git a/drivers/gpu/drm/i915/i915_overlay.c b/drivers/gpu/drm/i915/i915_overlay.c index 61869747c6bb..28518dbb5b8e 100644 --- a/drivers/gpu/drm/i915/i915_overlay.c +++ b/drivers/gpu/drm/i915/i915_overlay.c @@ -5,6 +5,7 @@ #include +#include #include #include "gem/i915_gem_internal.h" @@ -88,7 +89,7 @@ alloc_request(struct i915_overlay *overlay, void (*fn)(struct i915_overlay *)) return rq; } -bool i915_overlay_is_active(struct drm_device *drm) +static bool i915_overlay_is_active(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -97,8 +98,8 @@ bool i915_overlay_is_active(struct drm_device *drm) } /* overlay needs to be disable in OCMD reg */ -int i915_overlay_on(struct drm_device *drm, - u32 frontbuffer_bits) +static int i915_overlay_on(struct drm_device *drm, + u32 frontbuffer_bits) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -159,9 +160,9 @@ static void i915_overlay_flip_prepare(struct i915_overlay *overlay, } /* overlay needs to be enabled in OCMD reg */ -int i915_overlay_continue(struct drm_device *drm, - struct i915_vma *vma, - bool load_polyphase_filter) +static int i915_overlay_continue(struct drm_device *drm, + struct i915_vma *vma, + bool load_polyphase_filter) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -210,7 +211,8 @@ static void i915_overlay_release_old_vma(struct i915_overlay *overlay) i915_vma_put(vma); } -static void i915_overlay_release_old_vid_tail(struct i915_overlay *overlay) +static void +i915_overlay_release_old_vid_tail(struct i915_overlay *overlay) { i915_overlay_release_old_vma(overlay); } @@ -237,7 +239,7 @@ static void i915_overlay_last_flip_retire(struct i915_active *active) } /* overlay needs to be disabled in OCMD reg */ -int i915_overlay_off(struct drm_device *drm) +static int i915_overlay_off(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -286,7 +288,7 @@ int i915_overlay_off(struct drm_device *drm) * Recover from an interruption due to a signal. * We have to be careful not to repeat work forever an make forward progress. */ -int i915_overlay_recover_from_interrupt(struct drm_device *drm) +static int i915_overlay_recover_from_interrupt(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -299,7 +301,7 @@ int i915_overlay_recover_from_interrupt(struct drm_device *drm) * Needs to be called before the overlay register are changed * via intel_overlay_(un)map_regs. */ -int i915_overlay_release_old_vid(struct drm_device *drm) +static int i915_overlay_release_old_vid(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -337,7 +339,7 @@ int i915_overlay_release_old_vid(struct drm_device *drm) return i915_active_wait(&overlay->last_flip); } -void i915_overlay_reset(struct drm_device *drm) +static void i915_overlay_reset(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay = i915->overlay; @@ -348,9 +350,9 @@ void i915_overlay_reset(struct drm_device *drm) overlay->frontbuffer_bits = 0; } -struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm, - struct drm_gem_object *obj, - u32 *offset) +static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm, + struct drm_gem_object *obj, + u32 *offset) { struct drm_i915_gem_object *new_bo = to_intel_bo(obj); struct i915_gem_ww_ctx ww; @@ -379,13 +381,13 @@ retry: return vma; } -void i915_overlay_unpin_fb(struct drm_device *drm, - struct i915_vma *vma) +static void i915_overlay_unpin_fb(struct drm_device *drm, + struct i915_vma *vma) { i915_vma_unpin(vma); } -struct drm_gem_object * +static struct drm_gem_object * i915_overlay_obj_lookup(struct drm_device *drm, struct drm_file *file_priv, u32 handle) @@ -444,8 +446,8 @@ err_put_bo: return err; } -void __iomem *i915_overlay_setup(struct drm_device *drm, - bool needs_physical) +static void __iomem *i915_overlay_setup(struct drm_device *drm, + bool needs_physical) { struct drm_i915_private *i915 = to_i915(drm); struct intel_engine_cs *engine; @@ -477,7 +479,7 @@ void __iomem *i915_overlay_setup(struct drm_device *drm, return overlay->regs; } -void i915_overlay_cleanup(struct drm_device *drm) +static void i915_overlay_cleanup(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); struct i915_overlay *overlay; @@ -498,3 +500,18 @@ void i915_overlay_cleanup(struct drm_device *drm) kfree(overlay); } + +const struct intel_display_overlay_interface i915_display_overlay_interface = { + .is_active = i915_overlay_is_active, + .overlay_on = i915_overlay_on, + .overlay_continue = i915_overlay_continue, + .overlay_off = i915_overlay_off, + .recover_from_interrupt = i915_overlay_recover_from_interrupt, + .release_old_vid = i915_overlay_release_old_vid, + .reset = i915_overlay_reset, + .obj_lookup = i915_overlay_obj_lookup, + .pin_fb = i915_overlay_pin_fb, + .unpin_fb = i915_overlay_unpin_fb, + .setup = i915_overlay_setup, + .cleanup = i915_overlay_cleanup, +}; diff --git a/drivers/gpu/drm/i915/i915_overlay.h b/drivers/gpu/drm/i915/i915_overlay.h index f553de2abeaa..f8053eb8d189 100644 --- a/drivers/gpu/drm/i915/i915_overlay.h +++ b/drivers/gpu/drm/i915/i915_overlay.h @@ -6,38 +6,6 @@ #ifndef __I915_OVERLAY_H__ #define __I915_OVERLAY_H__ -#include - -struct drm_device; -struct drm_file; -struct drm_gem_object; -struct i915_vma; - -bool i915_overlay_is_active(struct drm_device *drm); -int i915_overlay_on(struct drm_device *drm, - u32 frontbuffer_bits); -int i915_overlay_continue(struct drm_device *drm, - struct i915_vma *vma, - bool load_polyphase_filter); -int i915_overlay_off(struct drm_device *drm); -int i915_overlay_recover_from_interrupt(struct drm_device *drm); -int i915_overlay_release_old_vid(struct drm_device *drm); - -void i915_overlay_reset(struct drm_device *drm); - -struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm, - struct drm_gem_object *obj, - u32 *offset); -void i915_overlay_unpin_fb(struct drm_device *drm, - struct i915_vma *vma); - -struct drm_gem_object * -i915_overlay_obj_lookup(struct drm_device *drm, - struct drm_file *file_priv, - u32 handle); - -void __iomem *i915_overlay_setup(struct drm_device *drm, - bool needs_physical); -void i915_overlay_cleanup(struct drm_device *drm); +extern const struct intel_display_overlay_interface i915_display_overlay_interface; #endif /* __I915_OVERLAY_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index a630466b3d72..c4fb9f13371a 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -303,6 +303,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_modeset_lock.o \ i915-display/intel_modeset_setup.o \ i915-display/intel_modeset_verify.o \ + i915-display/intel_overlay.o \ i915-display/intel_panel.o \ i915-display/intel_parent.o \ i915-display/intel_pch.o \ diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 50da825ec06c..b4b0f58ae3ee 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -9,6 +9,7 @@ struct dma_fence; struct drm_crtc; struct drm_device; +struct drm_file; struct drm_framebuffer; struct drm_gem_object; struct drm_plane_state; @@ -63,6 +64,35 @@ struct intel_display_irq_interface { void (*synchronize)(struct drm_device *drm); }; +struct intel_display_overlay_interface { + bool (*is_active)(struct drm_device *drm); + + int (*overlay_on)(struct drm_device *drm, + u32 frontbuffer_bits); + int (*overlay_continue)(struct drm_device *drm, + struct i915_vma *vma, + bool load_polyphase_filter); + int (*overlay_off)(struct drm_device *drm); + int (*recover_from_interrupt)(struct drm_device *drm); + int (*release_old_vid)(struct drm_device *drm); + + void (*reset)(struct drm_device *drm); + + struct i915_vma *(*pin_fb)(struct drm_device *drm, + struct drm_gem_object *obj, + u32 *offset); + void (*unpin_fb)(struct drm_device *drm, + struct i915_vma *vma); + + struct drm_gem_object *(*obj_lookup)(struct drm_device *drm, + struct drm_file *filp, + u32 handle); + + void __iomem *(*setup)(struct drm_device *drm, + bool needs_physical); + void (*cleanup)(struct drm_device *drm); +}; + struct intel_display_panic_interface { struct intel_panic *(*alloc)(void); int (*setup)(struct intel_panic *panic, struct drm_scanout_buffer *sb); @@ -150,6 +180,9 @@ struct intel_display_parent_interface { /** @panic: Panic interface */ const struct intel_display_panic_interface *panic; + /** @overlay: Overlay. Optional. */ + const struct intel_display_overlay_interface *overlay; + /** @pc8: PC8 interface. Optional. */ const struct intel_display_pc8_interface *pc8; -- cgit v1.2.3 From dc5f903b3ab6675721c8aa943d5cd0cb5ca2f5c8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 27 Feb 2026 19:17:12 +0200 Subject: drm/i915: add VMA to parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's unclear what the direction of the VMA abstraction in the parent interface should be, but convert i915_vma_fence_id() to parent interface for starters. This paves the way for making struct i915_vma opaque towards display. Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/036f4b2d20cc1b0a7ab814beb5bb914c53b6eb53.1772212579.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fbc.c | 5 ++--- drivers/gpu/drm/i915/display/intel_parent.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_parent.h | 3 +++ drivers/gpu/drm/i915/i915_driver.c | 1 + drivers/gpu/drm/i915/i915_vma.c | 10 ++++++++++ drivers/gpu/drm/i915/i915_vma.h | 7 ++----- drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h | 2 -- include/drm/intel/display_parent_interface.h | 7 +++++++ 8 files changed, 34 insertions(+), 10 deletions(-) (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 91de38379282..3e9b3e532499 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -45,7 +45,6 @@ #include #include -#include "i915_vma.h" #include "i9xx_plane_regs.h" #include "intel_de.h" #include "intel_display_device.h" @@ -1463,7 +1462,7 @@ static void intel_fbc_update_state(struct intel_atomic_state *state, !intel_fbc_has_fences(display)); if (plane_state->flags & PLANE_HAS_FENCE) - fbc_state->fence_id = i915_vma_fence_id(plane_state->ggtt_vma); + fbc_state->fence_id = intel_parent_vma_fence_id(display, plane_state->ggtt_vma); else fbc_state->fence_id = -1; @@ -1490,7 +1489,7 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state) */ return DISPLAY_VER(display) >= 9 || (plane_state->flags & PLANE_HAS_FENCE && - i915_vma_fence_id(plane_state->ggtt_vma) != -1); + intel_parent_vma_fence_id(display, plane_state->ggtt_vma) != -1); } static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state) diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index 89f78ca1cd15..0c5962cb2f6d 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -317,6 +317,15 @@ void intel_parent_stolen_node_free(struct intel_display *display, const struct i display->parent->stolen->node_free(node); } +/* vma */ +int intel_parent_vma_fence_id(struct intel_display *display, const struct i915_vma *vma) +{ + if (!display->parent->vma) + return -1; + + return display->parent->vma->fence_id(vma); +} + /* generic */ void intel_parent_fence_priority_display(struct intel_display *display, struct dma_fence *fence) { diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 2317482ef072..6e7d09133aee 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -102,6 +102,9 @@ u64 intel_parent_stolen_node_size(struct intel_display *display, const struct in struct intel_stolen_node *intel_parent_stolen_node_alloc(struct intel_display *display); void intel_parent_stolen_node_free(struct intel_display *display, const struct intel_stolen_node *node); +/* vma */ +int intel_parent_vma_fence_id(struct intel_display *display, const struct i915_vma *vma); + /* generic */ bool intel_parent_has_auxccs(struct intel_display *display); bool intel_parent_has_fenced_regions(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 5f77e891604d..18f912043f90 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -775,6 +775,7 @@ static const struct intel_display_parent_interface parent = { .rpm = &i915_display_rpm_interface, .rps = &i915_display_rps_interface, .stolen = &i915_display_stolen_interface, + .vma = &i915_display_vma_interface, .fence_priority_display = fence_priority_display, .has_auxccs = has_auxccs, diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index afc192d9931b..6a3a4d4244dc 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -27,6 +27,7 @@ #include #include +#include #include "display/intel_fb.h" #include "display/intel_frontbuffer.h" @@ -2332,3 +2333,12 @@ int __init i915_vma_module_init(void) return 0; } + +static int i915_vma_fence_id(const struct i915_vma *vma) +{ + return vma->fence ? vma->fence->id : -1; +} + +const struct intel_display_vma_interface i915_display_vma_interface = { + .fence_id = i915_vma_fence_id, +}; diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 8054047840aa..fa2d9b429db6 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -404,11 +404,6 @@ i915_vma_unpin_fence(struct i915_vma *vma) __i915_vma_unpin_fence(vma); } -static inline int i915_vma_fence_id(const struct i915_vma *vma) -{ - return vma->fence ? vma->fence->id : -1; -} - void i915_vma_parked(struct intel_gt *gt); static inline bool i915_vma_is_scanout(const struct i915_vma *vma) @@ -481,4 +476,6 @@ int i915_vma_module_init(void); I915_SELFTEST_DECLARE(int i915_vma_get_pages(struct i915_vma *vma)); I915_SELFTEST_DECLARE(void i915_vma_put_pages(struct i915_vma *vma)); +extern const struct intel_display_vma_interface i915_display_vma_interface; + #endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h index c4b5adaaa99a..da1d97b48fee 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h @@ -26,8 +26,6 @@ struct i915_vma { struct xe_ggtt_node *node; }; -#define i915_vma_fence_id(vma) -1 - static inline u32 i915_ggtt_offset(const struct i915_vma *vma) { return xe_ggtt_node_addr(vma->node); diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index b4b0f58ae3ee..d02ab7cc1c92 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -149,6 +149,10 @@ struct intel_display_stolen_interface { void (*node_free)(const struct intel_stolen_node *node); }; +struct intel_display_vma_interface { + int (*fence_id)(const struct i915_vma *vma); +}; + /** * struct intel_display_parent_interface - services parent driver provides to display * @@ -198,6 +202,9 @@ struct intel_display_parent_interface { /** @stolen: Stolen memory. */ const struct intel_display_stolen_interface *stolen; + /** @vma: VMA interface. Optional. */ + const struct intel_display_vma_interface *vma; + /* Generic independent functions */ struct { /** @fence_priority_display: Set display priority. Optional. */ -- cgit v1.2.3 From 6a3e5eb3c51dbd01ca46c2c40a67bea1dd845cdb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 2 Mar 2026 20:17:36 +0200 Subject: drm/intel: fix @dpt kernel-doc for parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the copy-paste fail. Reviewed-by: Jouni Högander Link: https://patch.msgid.link/0209e128312520ca1c6a0c39f9dfb0184125322a.1772475391.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/intel/display_parent_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index d02ab7cc1c92..6a88c8640683 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -166,7 +166,7 @@ struct intel_display_vma_interface { * check the optional pointers. */ struct intel_display_parent_interface { - /** @dsb: DPT interface. Optional. */ + /** @dpt: DPT interface. Optional. */ const struct intel_display_dpt_interface *dpt; /** @dsb: DSB buffer interface */ -- cgit v1.2.3 From 2cca25160d159e6351e3273b088db0b4f359ef6a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 2 Mar 2026 20:17:37 +0200 Subject: drm/{i915, xe}/frontbuffer: move frontbuffer handling to parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the get/put/ref/flush_for_display calls to the display parent interface. For i915, move the hooks next to the other i915 core frontbuffer code in i915_gem_object_frontbuffer.c. For xe, add new file xe_frontbuffer.c for the same. Note: The intel_frontbuffer_flush() calls from i915_gem_object_frontbuffer.c will partially route back to i915 core via the parent interface. This is less than stellar. Reviewed-by: Jouni Högander Link: https://patch.msgid.link/f69b967ed82bbcfd60ffa77ba197b26a1399f09f.1772475391.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_bo.c | 36 ----------- drivers/gpu/drm/i915/display/intel_bo.h | 5 -- drivers/gpu/drm/i915/display/intel_frontbuffer.c | 12 ++-- drivers/gpu/drm/i915/display/intel_parent.c | 21 +++++++ drivers/gpu/drm/i915/display/intel_parent.h | 7 +++ .../gpu/drm/i915/gem/i915_gem_object_frontbuffer.c | 45 ++++++++++++++ .../gpu/drm/i915/gem/i915_gem_object_frontbuffer.h | 2 + drivers/gpu/drm/i915/i915_driver.c | 2 + drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/intel_bo.c | 56 ----------------- drivers/gpu/drm/xe/display/xe_display.c | 2 + drivers/gpu/drm/xe/display/xe_frontbuffer.c | 71 ++++++++++++++++++++++ drivers/gpu/drm/xe/display/xe_frontbuffer.h | 9 +++ include/drm/intel/display_parent_interface.h | 11 ++++ 14 files changed, 178 insertions(+), 102 deletions(-) create mode 100644 drivers/gpu/drm/xe/display/xe_frontbuffer.c create mode 100644 drivers/gpu/drm/xe/display/xe_frontbuffer.h (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index 8f372b33d48b..2b6eaec351d8 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -45,42 +45,6 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size); } -struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *_obj) -{ - struct drm_i915_gem_object *obj = to_intel_bo(_obj); - struct i915_frontbuffer *front; - - front = i915_gem_object_frontbuffer_get(obj); - if (!front) - return NULL; - - return &front->base; -} - -void intel_bo_frontbuffer_ref(struct intel_frontbuffer *_front) -{ - struct i915_frontbuffer *front = - container_of(_front, typeof(*front), base); - - i915_gem_object_frontbuffer_ref(front); -} - -void intel_bo_frontbuffer_put(struct intel_frontbuffer *_front) -{ - struct i915_frontbuffer *front = - container_of(_front, typeof(*front), base); - - return i915_gem_object_frontbuffer_put(front); -} - -void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *_front) -{ - struct i915_frontbuffer *front = - container_of(_front, typeof(*front), base); - - i915_gem_object_flush_if_display(front->obj); -} - void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) { i915_debugfs_describe_obj(m, to_intel_bo(obj)); diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index 516a3836a6bc..40390ed92ceb 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -20,11 +20,6 @@ int intel_bo_key_check(struct drm_gem_object *obj); int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size); -struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj); -void intel_bo_frontbuffer_ref(struct intel_frontbuffer *front); -void intel_bo_frontbuffer_put(struct intel_frontbuffer *front); -void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front); - void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj); #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 03c4978fa5ec..a355dc064528 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -58,13 +58,13 @@ #include #include -#include "intel_bo.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_drrs.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_parent.h" #include "intel_psr.h" #include "intel_tdf.h" @@ -150,7 +150,7 @@ void __intel_fb_flush(struct intel_frontbuffer *front, struct intel_display *display = front->display; if (origin == ORIGIN_DIRTYFB) - intel_bo_frontbuffer_flush_for_display(front); + intel_parent_frontbuffer_flush_for_display(display, front); if (origin == ORIGIN_CS) { spin_lock(&display->fb_tracking.lock); @@ -166,7 +166,7 @@ void __intel_fb_flush(struct intel_frontbuffer *front, static void intel_frontbuffer_ref(struct intel_frontbuffer *front) { - intel_bo_frontbuffer_ref(front); + intel_parent_frontbuffer_ref(front->display, front); } static void intel_frontbuffer_flush_work(struct work_struct *work) @@ -209,12 +209,14 @@ void intel_frontbuffer_fini(struct intel_frontbuffer *front) struct intel_frontbuffer *intel_frontbuffer_get(struct drm_gem_object *obj) { - return intel_bo_frontbuffer_get(obj); + struct intel_display *display = to_intel_display(obj->dev); + + return intel_parent_frontbuffer_get(display, obj); } void intel_frontbuffer_put(struct intel_frontbuffer *front) { - intel_bo_frontbuffer_put(front); + intel_parent_frontbuffer_put(front->display, front); } /** diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index 0c5962cb2f6d..2e3bad2b3e6b 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -51,6 +51,27 @@ void intel_parent_dpt_resume(struct intel_display *display, struct intel_dpt *dp display->parent->dpt->resume(dpt); } +/* frontbuffer */ +struct intel_frontbuffer *intel_parent_frontbuffer_get(struct intel_display *display, struct drm_gem_object *obj) +{ + return display->parent->frontbuffer->get(obj); +} + +void intel_parent_frontbuffer_ref(struct intel_display *display, struct intel_frontbuffer *front) +{ + display->parent->frontbuffer->ref(front); +} + +void intel_parent_frontbuffer_put(struct intel_display *display, struct intel_frontbuffer *front) +{ + display->parent->frontbuffer->put(front); +} + +void intel_parent_frontbuffer_flush_for_display(struct intel_display *display, struct intel_frontbuffer *front) +{ + display->parent->frontbuffer->flush_for_display(front); +} + /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, struct intel_hdcp_gsc_context *gsc_context, diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 6e7d09133aee..2013e5ed5aa9 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -13,6 +13,7 @@ struct drm_scanout_buffer; struct i915_vma; struct intel_display; struct intel_dpt; +struct intel_frontbuffer; struct intel_hdcp_gsc_context; struct intel_panic; struct intel_stolen_node; @@ -24,6 +25,12 @@ void intel_parent_dpt_destroy(struct intel_display *display, struct intel_dpt *d void intel_parent_dpt_suspend(struct intel_display *display, struct intel_dpt *dpt); void intel_parent_dpt_resume(struct intel_display *display, struct intel_dpt *dpt); +/* frontbuffer */ +struct intel_frontbuffer *intel_parent_frontbuffer_get(struct intel_display *display, struct drm_gem_object *obj); +void intel_parent_frontbuffer_ref(struct intel_display *display, struct intel_frontbuffer *front); +void intel_parent_frontbuffer_put(struct intel_display *display, struct intel_frontbuffer *front); +void intel_parent_frontbuffer_flush_for_display(struct intel_display *display, struct intel_frontbuffer *front); + /* hdcp */ ssize_t intel_parent_hdcp_gsc_msg_send(struct intel_display *display, struct intel_hdcp_gsc_context *gsc_context, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c index cf0b66eaf11b..f885c4fb1326 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT /* Copyright © 2025 Intel Corporation */ +#include + #include "i915_drv.h" #include "i915_gem_object_frontbuffer.h" @@ -125,3 +127,46 @@ void __i915_gem_object_frontbuffer_invalidate(struct drm_i915_gem_object *obj, i915_gem_object_frontbuffer_put(front); } } + +static struct intel_frontbuffer *i915_frontbuffer_get(struct drm_gem_object *_obj) +{ + struct drm_i915_gem_object *obj = to_intel_bo(_obj); + struct i915_frontbuffer *front; + + front = i915_gem_object_frontbuffer_get(obj); + if (!front) + return NULL; + + return &front->base; +} + +static void i915_frontbuffer_ref(struct intel_frontbuffer *_front) +{ + struct i915_frontbuffer *front = + container_of(_front, typeof(*front), base); + + i915_gem_object_frontbuffer_ref(front); +} + +static void i915_frontbuffer_put(struct intel_frontbuffer *_front) +{ + struct i915_frontbuffer *front = + container_of(_front, typeof(*front), base); + + return i915_gem_object_frontbuffer_put(front); +} + +static void i915_frontbuffer_flush_for_display(struct intel_frontbuffer *_front) +{ + struct i915_frontbuffer *front = + container_of(_front, typeof(*front), base); + + i915_gem_object_flush_if_display(front->obj); +} + +const struct intel_display_frontbuffer_interface i915_display_frontbuffer_interface = { + .get = i915_frontbuffer_get, + .ref = i915_frontbuffer_ref, + .put = i915_frontbuffer_put, + .flush_for_display = i915_frontbuffer_flush_for_display, +}; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h b/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h index 46124048a59f..9c6d91f21c19 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h @@ -91,4 +91,6 @@ i915_gem_object_frontbuffer_lookup(const struct drm_i915_gem_object *obj) return front; } +extern const struct intel_display_frontbuffer_interface i915_display_frontbuffer_interface; + #endif diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 79ded07b5db5..7a8c59a8c865 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -78,6 +78,7 @@ #include "gem/i915_gem_dmabuf.h" #include "gem/i915_gem_ioctls.h" #include "gem/i915_gem_mman.h" +#include "gem/i915_gem_object_frontbuffer.h" #include "gem/i915_gem_pm.h" #include "gt/intel_gt.h" #include "gt/intel_gt_pm.h" @@ -766,6 +767,7 @@ static bool vgpu_active(struct drm_device *drm) static const struct intel_display_parent_interface parent = { .dpt = &i915_display_dpt_interface, .dsb = &i915_display_dsb_interface, + .frontbuffer = &i915_display_frontbuffer_interface, .hdcp = &i915_display_hdcp_interface, .initial_plane = &i915_display_initial_plane_interface, .irq = &i915_display_irq_interface, diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index c4fb9f13371a..7c5bb6e8fb8d 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -218,6 +218,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/xe_display_wa.o \ display/xe_dsb_buffer.o \ display/xe_fb_pin.o \ + display/xe_frontbuffer.o \ display/xe_hdcp_gsc.o \ display/xe_initial_plane.o \ display/xe_panic.o \ diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 05d5e5c0a0de..fa1f2c796b81 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -47,62 +47,6 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i return xe_bo_read(bo, offset, dst, size); } -struct xe_frontbuffer { - struct intel_frontbuffer base; - struct drm_gem_object *obj; - struct kref ref; -}; - -struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj) -{ - struct xe_frontbuffer *front; - - front = kmalloc_obj(*front); - if (!front) - return NULL; - - intel_frontbuffer_init(&front->base, obj->dev); - - kref_init(&front->ref); - - drm_gem_object_get(obj); - front->obj = obj; - - return &front->base; -} - -void intel_bo_frontbuffer_ref(struct intel_frontbuffer *_front) -{ - struct xe_frontbuffer *front = - container_of(_front, typeof(*front), base); - - kref_get(&front->ref); -} - -static void frontbuffer_release(struct kref *ref) -{ - struct xe_frontbuffer *front = - container_of(ref, typeof(*front), ref); - - intel_frontbuffer_fini(&front->base); - - drm_gem_object_put(front->obj); - - kfree(front); -} - -void intel_bo_frontbuffer_put(struct intel_frontbuffer *_front) -{ - struct xe_frontbuffer *front = - container_of(_front, typeof(*front), base); - - kref_put(&front->ref, frontbuffer_release); -} - -void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front) -{ -} - void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) { /* FIXME */ diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index c8dd3faa9b97..f1e1889a52d3 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -38,6 +38,7 @@ #include "xe_display_pcode.h" #include "xe_display_rpm.h" #include "xe_dsb_buffer.h" +#include "xe_frontbuffer.h" #include "xe_hdcp_gsc.h" #include "xe_initial_plane.h" #include "xe_module.h" @@ -541,6 +542,7 @@ static const struct intel_display_irq_interface xe_display_irq_interface = { static const struct intel_display_parent_interface parent = { .dsb = &xe_display_dsb_interface, + .frontbuffer = &xe_display_frontbuffer_interface, .hdcp = &xe_display_hdcp_interface, .initial_plane = &xe_display_initial_plane_interface, .irq = &xe_display_irq_interface, diff --git a/drivers/gpu/drm/xe/display/xe_frontbuffer.c b/drivers/gpu/drm/xe/display/xe_frontbuffer.c new file mode 100644 index 000000000000..113fc017ee94 --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_frontbuffer.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2026 Intel Corporation */ + +#include +#include + +#include "intel_frontbuffer.h" +#include "xe_frontbuffer.h" + +struct xe_frontbuffer { + struct intel_frontbuffer base; + struct drm_gem_object *obj; + struct kref ref; +}; + +static struct intel_frontbuffer *xe_frontbuffer_get(struct drm_gem_object *obj) +{ + struct xe_frontbuffer *front; + + front = kmalloc_obj(*front); + if (!front) + return NULL; + + intel_frontbuffer_init(&front->base, obj->dev); + + kref_init(&front->ref); + + drm_gem_object_get(obj); + front->obj = obj; + + return &front->base; +} + +static void xe_frontbuffer_ref(struct intel_frontbuffer *_front) +{ + struct xe_frontbuffer *front = + container_of(_front, typeof(*front), base); + + kref_get(&front->ref); +} + +static void frontbuffer_release(struct kref *ref) +{ + struct xe_frontbuffer *front = + container_of(ref, typeof(*front), ref); + + intel_frontbuffer_fini(&front->base); + + drm_gem_object_put(front->obj); + + kfree(front); +} + +static void xe_frontbuffer_put(struct intel_frontbuffer *_front) +{ + struct xe_frontbuffer *front = + container_of(_front, typeof(*front), base); + + kref_put(&front->ref, frontbuffer_release); +} + +static void xe_frontbuffer_flush_for_display(struct intel_frontbuffer *front) +{ +} + +const struct intel_display_frontbuffer_interface xe_display_frontbuffer_interface = { + .get = xe_frontbuffer_get, + .ref = xe_frontbuffer_ref, + .put = xe_frontbuffer_put, + .flush_for_display = xe_frontbuffer_flush_for_display, +}; diff --git a/drivers/gpu/drm/xe/display/xe_frontbuffer.h b/drivers/gpu/drm/xe/display/xe_frontbuffer.h new file mode 100644 index 000000000000..6b4f59b42ade --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_frontbuffer.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2026 Intel Corporation */ + +#ifndef _XE_FRONTBUFFER_H_ +#define _XE_FRONTBUFFER_H_ + +extern const struct intel_display_frontbuffer_interface xe_display_frontbuffer_interface; + +#endif diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 6a88c8640683..c044472b9400 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -17,6 +17,7 @@ struct drm_scanout_buffer; struct i915_vma; struct intel_dpt; struct intel_dsb_buffer; +struct intel_frontbuffer; struct intel_hdcp_gsc_context; struct intel_initial_plane_config; struct intel_panic; @@ -42,6 +43,13 @@ struct intel_display_dsb_interface { void (*flush_map)(struct intel_dsb_buffer *dsb_buf); }; +struct intel_display_frontbuffer_interface { + struct intel_frontbuffer *(*get)(struct drm_gem_object *obj); + void (*ref)(struct intel_frontbuffer *front); + void (*put)(struct intel_frontbuffer *front); + void (*flush_for_display)(struct intel_frontbuffer *front); +}; + struct intel_display_hdcp_interface { ssize_t (*gsc_msg_send)(struct intel_hdcp_gsc_context *gsc_context, void *msg_in, size_t msg_in_len, @@ -172,6 +180,9 @@ struct intel_display_parent_interface { /** @dsb: DSB buffer interface */ const struct intel_display_dsb_interface *dsb; + /** @frontbuffer: Frontbuffer interface */ + const struct intel_display_frontbuffer_interface *frontbuffer; + /** @hdcp: HDCP GSC interface */ const struct intel_display_hdcp_interface *hdcp; -- cgit v1.2.3 From 37a6ed2c284b594470e5512df3528abb50b9815e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 11 Mar 2026 16:18:16 +0200 Subject: drm/{i915, xe}/bo: move display bo calls to parent interface Continue i915 and xe separation from display by moving the bo calls to the display parent interface. Instead of adding all these functions to intel_parent.[ch], reuse the now vacated intel_bo.[ch], and avoid mass renames to calls of these functions. This is similar to intel_display_rpm.[ch]. Make many of the hooks optional to avoid having to implement dummy functions in xe. Indeed now we can remove many of the existing dummy functions. Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/7899eef2ccf0cd603df69099df065226a0df917b.1773238670.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_bo.c | 66 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_bo.c | 32 +++++++++----- drivers/gpu/drm/i915/i915_bo.h | 9 ++++ drivers/gpu/drm/i915/i915_driver.c | 2 + drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/xe_display.c | 2 + drivers/gpu/drm/xe/display/xe_display_bo.c | 45 +++++-------------- drivers/gpu/drm/xe/display/xe_display_bo.h | 9 ++++ include/drm/intel/display_parent_interface.h | 16 +++++++ 10 files changed, 138 insertions(+), 45 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_bo.c create mode 100644 drivers/gpu/drm/i915/i915_bo.h create mode 100644 drivers/gpu/drm/xe/display/xe_display_bo.h (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 52a82608b8b1..425933fb26a5 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -240,6 +240,7 @@ i915-y += \ display/intel_atomic.o \ display/intel_audio.o \ display/intel_bios.o \ + display/intel_bo.o \ display/intel_bw.o \ display/intel_casf.o \ display/intel_cdclk.o \ diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c new file mode 100644 index 000000000000..e356ab4e0640 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2026 Intel Corporation */ + +#include +#include + +#include "intel_bo.h" +#include "intel_display_core.h" +#include "intel_display_types.h" + +bool intel_bo_is_tiled(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->is_tiled && display->parent->bo->is_tiled(obj); +} + +bool intel_bo_is_userptr(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->is_userptr && display->parent->bo->is_userptr(obj); +} + +bool intel_bo_is_shmem(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->is_shmem && display->parent->bo->is_shmem(obj); +} + +bool intel_bo_is_protected(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->is_protected(obj); +} + +int intel_bo_key_check(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->key_check(obj); +} + +int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->fb_mmap(obj, vma); +} + +int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->read_from_page(obj, offset, dst, size); +} + +void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + if (display->parent->bo->describe) + display->parent->bo->describe(m, obj); +} diff --git a/drivers/gpu/drm/i915/i915_bo.c b/drivers/gpu/drm/i915/i915_bo.c index 21a4533ba341..04fc0e3b7ef6 100644 --- a/drivers/gpu/drm/i915/i915_bo.c +++ b/drivers/gpu/drm/i915/i915_bo.c @@ -2,51 +2,63 @@ /* Copyright © 2024 Intel Corporation */ #include - -#include "display/intel_bo.h" +#include #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" #include "gem/i915_gem_object_frontbuffer.h" #include "pxp/intel_pxp.h" + +#include "i915_bo.h" #include "i915_debugfs.h" -bool intel_bo_is_tiled(struct drm_gem_object *obj) +static bool i915_bo_is_tiled(struct drm_gem_object *obj) { return i915_gem_object_is_tiled(to_intel_bo(obj)); } -bool intel_bo_is_userptr(struct drm_gem_object *obj) +static bool i915_bo_is_userptr(struct drm_gem_object *obj) { return i915_gem_object_is_userptr(to_intel_bo(obj)); } -bool intel_bo_is_shmem(struct drm_gem_object *obj) +static bool i915_bo_is_shmem(struct drm_gem_object *obj) { return i915_gem_object_is_shmem(to_intel_bo(obj)); } -bool intel_bo_is_protected(struct drm_gem_object *obj) +static bool i915_bo_is_protected(struct drm_gem_object *obj) { return i915_gem_object_is_protected(to_intel_bo(obj)); } -int intel_bo_key_check(struct drm_gem_object *obj) +static int i915_bo_key_check(struct drm_gem_object *obj) { return intel_pxp_key_check(obj, false); } -int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +static int i915_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { return i915_gem_fb_mmap(to_intel_bo(obj), vma); } -int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size) +static int i915_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size) { return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size); } -void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) +static void i915_bo_describe(struct seq_file *m, struct drm_gem_object *obj) { i915_debugfs_describe_obj(m, to_intel_bo(obj)); } + +const struct intel_display_bo_interface i915_display_bo_interface = { + .is_tiled = i915_bo_is_tiled, + .is_userptr = i915_bo_is_userptr, + .is_shmem = i915_bo_is_shmem, + .is_protected = i915_bo_is_protected, + .key_check = i915_bo_key_check, + .fb_mmap = i915_bo_fb_mmap, + .read_from_page = i915_bo_read_from_page, + .describe = i915_bo_describe, +}; diff --git a/drivers/gpu/drm/i915/i915_bo.h b/drivers/gpu/drm/i915/i915_bo.h new file mode 100644 index 000000000000..57255d052dd9 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_bo.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2026 Intel Corporation */ + +#ifndef __I915_BO_H__ +#define __I915_BO_H__ + +extern const struct intel_display_bo_interface i915_display_bo_interface; + +#endif /* __I915_BO_H__ */ diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 7a8c59a8c865..385a634c3ed0 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -90,6 +90,7 @@ #include "pxp/intel_pxp_debugfs.h" #include "pxp/intel_pxp_pm.h" +#include "i915_bo.h" #include "i915_debugfs.h" #include "i915_display_pc8.h" #include "i915_dpt.h" @@ -765,6 +766,7 @@ static bool vgpu_active(struct drm_device *drm) } static const struct intel_display_parent_interface parent = { + .bo = &i915_display_bo_interface, .dpt = &i915_display_dpt_interface, .dsb = &i915_display_dsb_interface, .frontbuffer = &i915_display_frontbuffer_interface, diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index ac8c1f2cb7f9..10b4ed30f843 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -233,6 +233,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_audio.o \ i915-display/intel_backlight.o \ i915-display/intel_bios.o \ + i915-display/intel_bo.o \ i915-display/intel_bw.o \ i915-display/intel_casf.o \ i915-display/intel_cdclk.o \ diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index f1e1889a52d3..49b6f98e7391 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -35,6 +35,7 @@ #include "intel_hotplug.h" #include "intel_opregion.h" #include "skl_watermark.h" +#include "xe_display_bo.h" #include "xe_display_pcode.h" #include "xe_display_rpm.h" #include "xe_dsb_buffer.h" @@ -541,6 +542,7 @@ static const struct intel_display_irq_interface xe_display_irq_interface = { }; static const struct intel_display_parent_interface parent = { + .bo = &xe_display_bo_interface, .dsb = &xe_display_dsb_interface, .frontbuffer = &xe_display_frontbuffer_interface, .hdcp = &xe_display_hdcp_interface, diff --git a/drivers/gpu/drm/xe/display/xe_display_bo.c b/drivers/gpu/drm/xe/display/xe_display_bo.c index fa1f2c796b81..a53ba3f247ec 100644 --- a/drivers/gpu/drm/xe/display/xe_display_bo.c +++ b/drivers/gpu/drm/xe/display/xe_display_bo.c @@ -2,52 +2,27 @@ /* Copyright © 2024 Intel Corporation */ #include +#include -#include "intel_bo.h" -#include "intel_frontbuffer.h" #include "xe_bo.h" +#include "xe_display_bo.h" #include "xe_pxp.h" -bool intel_bo_is_tiled(struct drm_gem_object *obj) -{ - /* legacy tiling is unused */ - return false; -} - -bool intel_bo_is_userptr(struct drm_gem_object *obj) -{ - /* xe does not have userptr bos */ - return false; -} - -bool intel_bo_is_shmem(struct drm_gem_object *obj) -{ - return false; -} - -bool intel_bo_is_protected(struct drm_gem_object *obj) +static bool xe_display_bo_is_protected(struct drm_gem_object *obj) { return xe_bo_is_protected(gem_to_xe_bo(obj)); } -int intel_bo_key_check(struct drm_gem_object *obj) -{ - return xe_pxp_obj_key_check(obj); -} - -int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) -{ - return drm_gem_prime_mmap(obj, vma); -} - -int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size) +static int xe_display_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size) { struct xe_bo *bo = gem_to_xe_bo(obj); return xe_bo_read(bo, offset, dst, size); } -void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) -{ - /* FIXME */ -} +const struct intel_display_bo_interface xe_display_bo_interface = { + .is_protected = xe_display_bo_is_protected, + .key_check = xe_pxp_obj_key_check, + .fb_mmap = drm_gem_prime_mmap, + .read_from_page = xe_display_bo_read_from_page, +}; diff --git a/drivers/gpu/drm/xe/display/xe_display_bo.h b/drivers/gpu/drm/xe/display/xe_display_bo.h new file mode 100644 index 000000000000..6879c104b0b1 --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_display_bo.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2026 Intel Corporation */ + +#ifndef __XE_DISPLAY_BO_H__ +#define __XE_DISPLAY_BO_H__ + +extern const struct intel_display_bo_interface xe_display_bo_interface; + +#endif diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index c044472b9400..2b53d12b0e0a 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -23,9 +23,22 @@ struct intel_initial_plane_config; struct intel_panic; struct intel_stolen_node; struct ref_tracker; +struct seq_file; +struct vm_area_struct; /* Keep struct definitions sorted */ +struct intel_display_bo_interface { + bool (*is_tiled)(struct drm_gem_object *obj); /* Optional */ + bool (*is_userptr)(struct drm_gem_object *obj); /* Optional */ + bool (*is_shmem)(struct drm_gem_object *obj); /* Optional */ + bool (*is_protected)(struct drm_gem_object *obj); + int (*key_check)(struct drm_gem_object *obj); + int (*fb_mmap)(struct drm_gem_object *obj, struct vm_area_struct *vma); + int (*read_from_page)(struct drm_gem_object *obj, u64 offset, void *dst, int size); + void (*describe)(struct seq_file *m, struct drm_gem_object *obj); /* Optional */ +}; + struct intel_display_dpt_interface { struct intel_dpt *(*create)(struct drm_gem_object *obj, size_t size); void (*destroy)(struct intel_dpt *dpt); @@ -174,6 +187,9 @@ struct intel_display_vma_interface { * check the optional pointers. */ struct intel_display_parent_interface { + /** @bo: BO interface */ + const struct intel_display_bo_interface *bo; + /** @dpt: DPT interface. Optional. */ const struct intel_display_dpt_interface *dpt; -- cgit v1.2.3 From 9876394f64a7c166964e003585806473ad6f532b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 11 Mar 2026 16:18:18 +0200 Subject: drm/{i915,xe}: move framebuffer bo to parent interface Add .framebuffer_init, .framebuffer_fini and .framebuffer_lookup to the bo parent interface. While they're about framebuffers, they're specifically about framebuffer objects, so the bo interface is a good enough fit, and there's no need to add another interface struct. Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/848d32a44bf844cba3d66e44ba9f20bea4a8352d.1773238670.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 1 - drivers/gpu/drm/i915/display/intel_bo.c | 21 ++++++ drivers/gpu/drm/i915/display/intel_bo.h | 9 +++ drivers/gpu/drm/i915/display/intel_fb.c | 12 ++-- drivers/gpu/drm/i915/display/intel_fb_bo.c | 99 ---------------------------- drivers/gpu/drm/i915/display/intel_fb_bo.h | 25 ------- drivers/gpu/drm/i915/i915_bo.c | 92 ++++++++++++++++++++++++++ drivers/gpu/drm/xe/Makefile | 1 - drivers/gpu/drm/xe/display/intel_fb_bo.c | 91 ------------------------- drivers/gpu/drm/xe/display/xe_display_bo.c | 84 +++++++++++++++++++++++ include/drm/intel/display_parent_interface.h | 6 ++ 11 files changed, 218 insertions(+), 223 deletions(-) delete mode 100644 drivers/gpu/drm/i915/display/intel_fb_bo.c delete mode 100644 drivers/gpu/drm/i915/display/intel_fb_bo.h delete mode 100644 drivers/gpu/drm/xe/display/intel_fb_bo.c (limited to 'include/drm/intel/display_parent_interface.h') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 425933fb26a5..be976a90c5a6 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -278,7 +278,6 @@ i915-y += \ display/intel_drrs.o \ display/intel_dsb.o \ display/intel_fb.o \ - display/intel_fb_bo.o \ display/intel_fb_pin.o \ display/intel_fbc.o \ display/intel_fdi.o \ diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index e356ab4e0640..3b82d38a0504 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -64,3 +64,24 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) if (display->parent->bo->describe) display->parent->bo->describe(m, obj); } + +int intel_bo_framebuffer_init(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->framebuffer_init(obj, mode_cmd); +} + +void intel_bo_framebuffer_fini(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + display->parent->bo->framebuffer_fini(obj); +} + +struct drm_gem_object *intel_bo_framebuffer_lookup(struct intel_display *display, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *user_mode_cmd) +{ + return display->parent->bo->framebuffer_lookup(display->drm, filp, user_mode_cmd); +} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index 40390ed92ceb..aec188c706c2 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -6,8 +6,11 @@ #include +struct drm_file; struct drm_gem_object; +struct drm_mode_fb_cmd2; struct drm_scanout_buffer; +struct intel_display; struct intel_framebuffer; struct seq_file; struct vm_area_struct; @@ -22,4 +25,10 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj); +void intel_bo_framebuffer_fini(struct drm_gem_object *obj); +int intel_bo_framebuffer_init(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); +struct drm_gem_object *intel_bo_framebuffer_lookup(struct intel_display *display, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *user_mode_cmd); + #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 49c6ca9d94c6..5768619f840f 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -17,7 +17,6 @@ #include "intel_display_types.h" #include "intel_display_utils.h" #include "intel_fb.h" -#include "intel_fb_bo.h" #include "intel_frontbuffer.h" #include "intel_parent.h" #include "intel_plane.h" @@ -2111,7 +2110,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) if (intel_fb_uses_dpt(fb)) intel_parent_dpt_destroy(display, intel_fb->dpt); - intel_fb_bo_framebuffer_fini(intel_fb_bo(fb)); + intel_bo_framebuffer_fini(intel_fb_bo(fb)); intel_parent_frontbuffer_put(display, intel_fb->frontbuffer); @@ -2222,7 +2221,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, /* * intel_parent_frontbuffer_get() must be done before - * intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race. + * intel_bo_framebuffer_init() to avoid set_tiling vs. addfb race. */ intel_fb->frontbuffer = intel_parent_frontbuffer_get(display, obj); if (!intel_fb->frontbuffer) { @@ -2230,7 +2229,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, goto err_free_panic; } - ret = intel_fb_bo_framebuffer_init(obj, mode_cmd); + ret = intel_bo_framebuffer_init(obj, mode_cmd); if (ret) goto err_frontbuffer_put; @@ -2333,7 +2332,7 @@ err_free_dpt: if (intel_fb_uses_dpt(fb)) intel_parent_dpt_destroy(display, intel_fb->dpt); err_bo_framebuffer_fini: - intel_fb_bo_framebuffer_fini(obj); + intel_bo_framebuffer_fini(obj); err_frontbuffer_put: intel_parent_frontbuffer_put(display, intel_fb->frontbuffer); err_free_panic: @@ -2348,11 +2347,12 @@ intel_user_framebuffer_create(struct drm_device *dev, const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *user_mode_cmd) { + struct intel_display *display = to_intel_display(dev); struct drm_framebuffer *fb; struct drm_gem_object *obj; struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; - obj = intel_fb_bo_lookup_valid_bo(dev, filp, &mode_cmd); + obj = intel_bo_framebuffer_lookup(display, filp, &mode_cmd); if (IS_ERR(obj)) return ERR_CAST(obj); diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c deleted file mode 100644 index a4d49ef450d9..000000000000 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.c +++ /dev/null @@ -1,99 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2021 Intel Corporation - */ - -#include -#include - -#include "gem/i915_gem_object.h" - -#include "i915_drv.h" -#include "intel_fb.h" -#include "intel_fb_bo.h" - -void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj) -{ - /* Nothing to do for i915 */ -} - -int intel_fb_bo_framebuffer_init(struct drm_gem_object *_obj, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_i915_gem_object *obj = to_intel_bo(_obj); - struct drm_i915_private *i915 = to_i915(obj->base.dev); - unsigned int tiling, stride; - - i915_gem_object_lock(obj, NULL); - tiling = i915_gem_object_get_tiling(obj); - stride = i915_gem_object_get_stride(obj); - i915_gem_object_unlock(obj); - - if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { - /* - * If there's a fence, enforce that - * the fb modifier and tiling mode match. - */ - if (tiling != I915_TILING_NONE && - tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { - drm_dbg_kms(&i915->drm, - "tiling_mode doesn't match fb modifier\n"); - return -EINVAL; - } - } else { - if (tiling == I915_TILING_X) { - mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; - } else if (tiling == I915_TILING_Y) { - drm_dbg_kms(&i915->drm, - "No Y tiling for legacy addfb\n"); - return -EINVAL; - } - } - - /* - * gen2/3 display engine uses the fence if present, - * so the tiling mode must match the fb modifier exactly. - */ - if (GRAPHICS_VER(i915) < 4 && - tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { - drm_dbg_kms(&i915->drm, - "tiling_mode must match fb modifier exactly on gen2/3\n"); - return -EINVAL; - } - - /* - * If there's a fence, enforce that - * the fb pitch and fence stride match. - */ - if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { - drm_dbg_kms(&i915->drm, - "pitch (%d) must match tiling stride (%d)\n", - mode_cmd->pitches[0], stride); - return -EINVAL; - } - - return 0; -} - -struct drm_gem_object * -intel_fb_bo_lookup_valid_bo(struct drm_device *drm, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_i915_private *i915 = to_i915(drm); - struct drm_i915_gem_object *obj; - - obj = i915_gem_object_lookup(filp, mode_cmd->handles[0]); - if (!obj) - return ERR_PTR(-ENOENT); - - /* object is backed with LMEM for discrete */ - if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM_0)) { - /* object is "remote", not in local memory */ - i915_gem_object_put(obj); - drm_dbg_kms(&i915->drm, "framebuffer must reside in local memory\n"); - return ERR_PTR(-EREMOTE); - } - - return intel_bo_to_drm_bo(obj); -} diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.h b/drivers/gpu/drm/i915/display/intel_fb_bo.h deleted file mode 100644 index d775773c6c03..000000000000 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2021 Intel Corporation - */ - -#ifndef __INTEL_FB_BO_H__ -#define __INTEL_FB_BO_H__ - -struct drm_device; -struct drm_file; -struct drm_framebuffer; -struct drm_gem_object; -struct drm_mode_fb_cmd2; - -void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj); - -int intel_fb_bo_framebuffer_init(struct drm_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd); - -struct drm_gem_object * -intel_fb_bo_lookup_valid_bo(struct drm_device *drm, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *user_mode_cmd); - -#endif diff --git a/drivers/gpu/drm/i915/i915_bo.c b/drivers/gpu/drm/i915/i915_bo.c index 04fc0e3b7ef6..1789f7cab05c 100644 --- a/drivers/gpu/drm/i915/i915_bo.c +++ b/drivers/gpu/drm/i915/i915_bo.c @@ -2,8 +2,10 @@ /* Copyright © 2024 Intel Corporation */ #include +#include #include +#include "display/intel_fb.h" #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" #include "gem/i915_gem_object_frontbuffer.h" @@ -11,6 +13,7 @@ #include "i915_bo.h" #include "i915_debugfs.h" +#include "i915_drv.h" static bool i915_bo_is_tiled(struct drm_gem_object *obj) { @@ -52,6 +55,92 @@ static void i915_bo_describe(struct seq_file *m, struct drm_gem_object *obj) i915_debugfs_describe_obj(m, to_intel_bo(obj)); } +static int i915_bo_framebuffer_init(struct drm_gem_object *_obj, + struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct drm_i915_gem_object *obj = to_intel_bo(_obj); + struct drm_i915_private *i915 = to_i915(obj->base.dev); + unsigned int tiling, stride; + + i915_gem_object_lock(obj, NULL); + tiling = i915_gem_object_get_tiling(obj); + stride = i915_gem_object_get_stride(obj); + i915_gem_object_unlock(obj); + + if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { + /* + * If there's a fence, enforce that + * the fb modifier and tiling mode match. + */ + if (tiling != I915_TILING_NONE && + tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { + drm_dbg_kms(&i915->drm, + "tiling_mode doesn't match fb modifier\n"); + return -EINVAL; + } + } else { + if (tiling == I915_TILING_X) { + mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; + } else if (tiling == I915_TILING_Y) { + drm_dbg_kms(&i915->drm, + "No Y tiling for legacy addfb\n"); + return -EINVAL; + } + } + + /* + * gen2/3 display engine uses the fence if present, + * so the tiling mode must match the fb modifier exactly. + */ + if (GRAPHICS_VER(i915) < 4 && + tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { + drm_dbg_kms(&i915->drm, + "tiling_mode must match fb modifier exactly on gen2/3\n"); + return -EINVAL; + } + + /* + * If there's a fence, enforce that + * the fb pitch and fence stride match. + */ + if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { + drm_dbg_kms(&i915->drm, + "pitch (%d) must match tiling stride (%d)\n", + mode_cmd->pitches[0], stride); + return -EINVAL; + } + + return 0; +} + +static void i915_bo_framebuffer_fini(struct drm_gem_object *obj) +{ + /* Nothing to do for i915 */ +} + +static struct drm_gem_object * +i915_bo_framebuffer_lookup(struct drm_device *drm, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct drm_i915_private *i915 = to_i915(drm); + struct drm_i915_gem_object *obj; + + obj = i915_gem_object_lookup(filp, mode_cmd->handles[0]); + if (!obj) + return ERR_PTR(-ENOENT); + + /* object is backed with LMEM for discrete */ + if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM_0)) { + /* object is "remote", not in local memory */ + i915_gem_object_put(obj); + drm_dbg_kms(&i915->drm, "framebuffer must reside in local memory\n"); + return ERR_PTR(-EREMOTE); + } + + return intel_bo_to_drm_bo(obj); +} + const struct intel_display_bo_interface i915_display_bo_interface = { .is_tiled = i915_bo_is_tiled, .is_userptr = i915_bo_is_userptr, @@ -61,4 +150,7 @@ const struct intel_display_bo_interface i915_display_bo_interface = { .fb_mmap = i915_bo_fb_mmap, .read_from_page = i915_bo_read_from_page, .describe = i915_bo_describe, + .framebuffer_init = i915_bo_framebuffer_init, + .framebuffer_fini = i915_bo_framebuffer_fini, + .framebuffer_lookup = i915_bo_framebuffer_lookup, }; diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 10b4ed30f843..468599492af1 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -209,7 +209,6 @@ $(obj)/i915-display/%.o: $(srctree)/drivers/gpu/drm/i915/display/%.c FORCE # Display code specific to xe xe-$(CONFIG_DRM_XE_DISPLAY) += \ - display/intel_fb_bo.o \ display/intel_fbdev_fb.o \ display/xe_display.o \ display/xe_display_bo.o \ diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c deleted file mode 100644 index db8b1a27b4de..000000000000 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.c +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2021 Intel Corporation - */ - -#include -#include - -#include "intel_display_types.h" -#include "intel_fb.h" -#include "intel_fb_bo.h" -#include "xe_bo.h" - -void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj) -{ - struct xe_bo *bo = gem_to_xe_bo(obj); - - if (bo->flags & XE_BO_FLAG_PINNED) { - /* Unpin our kernel fb first */ - xe_bo_lock(bo, false); - xe_bo_unpin(bo); - xe_bo_unlock(bo); - } - xe_bo_put(bo); -} - -int intel_fb_bo_framebuffer_init(struct drm_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct xe_bo *bo = gem_to_xe_bo(obj); - struct xe_device *xe = to_xe_device(bo->ttm.base.dev); - int ret; - - /* - * Some modifiers require physical alignment of 64KiB VRAM pages; - * require that the BO in those cases is created correctly. - */ - if (XE_IOCTL_DBG(xe, intel_fb_needs_64k_phys(mode_cmd->modifier[0]) && - !(bo->flags & XE_BO_FLAG_NEEDS_64K))) - return -EINVAL; - - xe_bo_get(bo); - - ret = ttm_bo_reserve(&bo->ttm, true, false, NULL); - if (ret) - goto err; - - if (!(bo->flags & XE_BO_FLAG_SCANOUT)) { - /* - * XE_BO_FLAG_SCANOUT should ideally be set at creation, or is - * automatically set when creating FB. We cannot change caching - * mode when the bo is VM_BINDed, so we can only set - * coherency with display when unbound. - */ - if (XE_IOCTL_DBG(xe, xe_bo_is_vm_bound(bo))) { - ttm_bo_unreserve(&bo->ttm); - ret = -EINVAL; - goto err; - } - bo->flags |= XE_BO_FLAG_SCANOUT; - } - ttm_bo_unreserve(&bo->ttm); - return 0; - -err: - xe_bo_put(bo); - return ret; -} - -struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_device *drm, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct xe_device *xe = to_xe_device(drm); - struct xe_bo *bo; - struct drm_gem_object *gem = drm_gem_object_lookup(filp, mode_cmd->handles[0]); - - if (!gem) - return ERR_PTR(-ENOENT); - - bo = gem_to_xe_bo(gem); - /* Require vram placement or dma-buf import */ - if (IS_DGFX(xe) && - !xe_bo_can_migrate(bo, XE_PL_VRAM0) && - bo->ttm.type != ttm_bo_type_sg) { - drm_gem_object_put(gem); - return ERR_PTR(-EREMOTE); - } - - return gem; -} diff --git a/drivers/gpu/drm/xe/display/xe_display_bo.c b/drivers/gpu/drm/xe/display/xe_display_bo.c index a53ba3f247ec..a689f71e7b14 100644 --- a/drivers/gpu/drm/xe/display/xe_display_bo.c +++ b/drivers/gpu/drm/xe/display/xe_display_bo.c @@ -4,6 +4,7 @@ #include #include +#include "intel_fb.h" #include "xe_bo.h" #include "xe_display_bo.h" #include "xe_pxp.h" @@ -20,9 +21,92 @@ static int xe_display_bo_read_from_page(struct drm_gem_object *obj, u64 offset, return xe_bo_read(bo, offset, dst, size); } +static int xe_display_bo_framebuffer_init(struct drm_gem_object *obj, + struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct xe_bo *bo = gem_to_xe_bo(obj); + struct xe_device *xe = to_xe_device(bo->ttm.base.dev); + int ret; + + /* + * Some modifiers require physical alignment of 64KiB VRAM pages; + * require that the BO in those cases is created correctly. + */ + if (XE_IOCTL_DBG(xe, intel_fb_needs_64k_phys(mode_cmd->modifier[0]) && + !(bo->flags & XE_BO_FLAG_NEEDS_64K))) + return -EINVAL; + + xe_bo_get(bo); + + ret = ttm_bo_reserve(&bo->ttm, true, false, NULL); + if (ret) + goto err; + + if (!(bo->flags & XE_BO_FLAG_SCANOUT)) { + /* + * XE_BO_FLAG_SCANOUT should ideally be set at creation, or is + * automatically set when creating FB. We cannot change caching + * mode when the bo is VM_BINDed, so we can only set + * coherency with display when unbound. + */ + if (XE_IOCTL_DBG(xe, xe_bo_is_vm_bound(bo))) { + ttm_bo_unreserve(&bo->ttm); + ret = -EINVAL; + goto err; + } + bo->flags |= XE_BO_FLAG_SCANOUT; + } + ttm_bo_unreserve(&bo->ttm); + return 0; + +err: + xe_bo_put(bo); + return ret; +} + +static void xe_display_bo_framebuffer_fini(struct drm_gem_object *obj) +{ + struct xe_bo *bo = gem_to_xe_bo(obj); + + if (bo->flags & XE_BO_FLAG_PINNED) { + /* Unpin our kernel fb first */ + xe_bo_lock(bo, false); + xe_bo_unpin(bo); + xe_bo_unlock(bo); + } + xe_bo_put(bo); +} + +static struct drm_gem_object * +xe_display_bo_framebuffer_lookup(struct drm_device *drm, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct xe_device *xe = to_xe_device(drm); + struct xe_bo *bo; + struct drm_gem_object *gem = drm_gem_object_lookup(filp, mode_cmd->handles[0]); + + if (!gem) + return ERR_PTR(-ENOENT); + + bo = gem_to_xe_bo(gem); + /* Require vram placement or dma-buf import */ + if (IS_DGFX(xe) && + !xe_bo_can_migrate(bo, XE_PL_VRAM0) && + bo->ttm.type != ttm_bo_type_sg) { + drm_gem_object_put(gem); + return ERR_PTR(-EREMOTE); + } + + return gem; +} + const struct intel_display_bo_interface xe_display_bo_interface = { .is_protected = xe_display_bo_is_protected, .key_check = xe_pxp_obj_key_check, .fb_mmap = drm_gem_prime_mmap, .read_from_page = xe_display_bo_read_from_page, + .framebuffer_init = xe_display_bo_framebuffer_init, + .framebuffer_fini = xe_display_bo_framebuffer_fini, + .framebuffer_lookup = xe_display_bo_framebuffer_lookup, }; diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 2b53d12b0e0a..97ec94a2e749 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -12,6 +12,7 @@ struct drm_device; struct drm_file; struct drm_framebuffer; struct drm_gem_object; +struct drm_mode_fb_cmd2; struct drm_plane_state; struct drm_scanout_buffer; struct i915_vma; @@ -37,6 +38,11 @@ struct intel_display_bo_interface { int (*fb_mmap)(struct drm_gem_object *obj, struct vm_area_struct *vma); int (*read_from_page)(struct drm_gem_object *obj, u64 offset, void *dst, int size); void (*describe)(struct seq_file *m, struct drm_gem_object *obj); /* Optional */ + int (*framebuffer_init)(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); + void (*framebuffer_fini)(struct drm_gem_object *obj); + struct drm_gem_object *(*framebuffer_lookup)(struct drm_device *drm, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *user_mode_cmd); }; struct intel_display_dpt_interface { -- cgit v1.2.3