From 32620e176443bf23ec81bfe8f177c6721a904864 Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane Date: Mon, 22 Sep 2025 20:33:15 +0530 Subject: drm/pcids: Split PTL pciids group to make wcl subplatform To form the WCL platform as a subplatform of PTL in definition, WCL pci ids are splited into saparate group from PTL. So update the pciidlist struct to cover all the pci ids. v2: - Squash wcl description in single patch for display and xe.(jani,gustavo) Signed-off-by: Dnyaneshwar Bhadane Reviewed-by: Gustavo Sousa Signed-off-by: Suraj Kandpal Link: https://lore.kernel.org/r/20250922150317.2334680-2-dnyaneshwar.bhadane@intel.com --- include/drm/intel/pciids.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index da6301a6fcea..69d4ae92d822 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -877,7 +877,10 @@ MACRO__(0xB08F, ## __VA_ARGS__), \ MACRO__(0xB090, ## __VA_ARGS__), \ MACRO__(0xB0A0, ## __VA_ARGS__), \ - MACRO__(0xB0B0, ## __VA_ARGS__), \ + MACRO__(0xB0B0, ## __VA_ARGS__) + +/* WCL */ +#define INTEL_WCL_IDS(MACRO__, ...) \ MACRO__(0xFD80, ## __VA_ARGS__), \ MACRO__(0xFD81, ## __VA_ARGS__) -- cgit v1.2.3 From 97825e1c6de7315cba9acb6c1371f1a87dedd904 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 26 Sep 2025 14:10:32 +0300 Subject: drm/{i915,xe}: driver agnostic drm to display pointer chase The display driver needs to get from the struct drm_device pointer to the struct intel_display pointer. Currently, this depends on knowledge of the struct drm_i915_private and struct xe_device definitions, but we'd like to hide those definitions from display. Require the struct drm_device and struct intel_display * members within struct drm_i915_private and struct xe_device to be placed next to each other, to be able to figure out the display pointer without knowledge of the structures. Use a generic dummy device structure to define the relative offsets of the drm and display members, and add static assertions to ensure this holds for both i915 and xe. Use the dummy structure to do the pointer chase from struct drm_device * to struct intel_display *. This requires moving the display member in struct xe_device after the drm member. Cc: Lucas De Marchi Cc: Rodrigo Vivi Cc: Ville Syrjala Suggested-by: Simona Vetter Reviewed-by: Lucas De Marchi Link: https://lore.kernel.org/r/20250926111032.1188876-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_conversion.c | 20 +++++++---- drivers/gpu/drm/i915/i915_driver.c | 4 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/xe/display/xe_display.c | 4 +++ drivers/gpu/drm/xe/xe_device_types.h | 7 ++-- include/drm/intel/display_member.h | 42 ++++++++++++++++++++++ 6 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 include/drm/intel/display_member.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/display/intel_display_conversion.c b/drivers/gpu/drm/i915/display/intel_display_conversion.c index d56065f22655..9a47aa38cf82 100644 --- a/drivers/gpu/drm/i915/display/intel_display_conversion.c +++ b/drivers/gpu/drm/i915/display/intel_display_conversion.c @@ -1,15 +1,21 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ -#include "i915_drv.h" -#include "intel_display_conversion.h" +#include -static struct intel_display *__i915_to_display(struct drm_i915_private *i915) -{ - return i915->display; -} +#include "intel_display_conversion.h" struct intel_display *__drm_to_display(struct drm_device *drm) { - return __i915_to_display(to_i915(drm)); + /* + * Note: This relies on both struct drm_i915_private and struct + * xe_device having the struct drm_device and struct intel_display * + * members at the same relative offsets, as defined by struct + * __intel_generic_device. + * + * See also INTEL_DISPLAY_MEMBER_STATIC_ASSERT(). + */ + struct __intel_generic_device *d = container_of(drm, struct __intel_generic_device, drm); + + return d->display; } diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 95165e45de74..b46cb54ef5dc 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "display/i9xx_display_sr.h" #include "display/intel_bw.h" @@ -737,6 +738,9 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) "DRM_I915_DEBUG_RUNTIME_PM enabled\n"); } +/* Ensure drm and display members are placed properly. */ +INTEL_DISPLAY_MEMBER_STATIC_ASSERT(struct drm_i915_private, drm, display); + static struct drm_i915_private * i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 03e497d2081e..6e159bb8ad2f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -174,6 +174,7 @@ struct i915_selftest_stash { struct drm_i915_private { struct drm_device drm; + /* display device data, must be placed after drm device member */ struct intel_display *display; /* FIXME: Device release actions should all be moved to drmm_ */ diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 19e691fccf8c..5f4044e63185 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "soc/intel_dram.h" @@ -35,6 +36,9 @@ #include "skl_watermark.h" #include "xe_module.h" +/* Ensure drm and display members are placed properly. */ +INTEL_DISPLAY_MEMBER_STATIC_ASSERT(struct xe_device, drm, display); + /* Xe device functions */ /** diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index a6c361db11d9..53264b2bb832 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -217,6 +217,11 @@ struct xe_device { /** @drm: drm device */ struct drm_device drm; +#if IS_ENABLED(CONFIG_DRM_XE_DISPLAY) + /** @display: display device data, must be placed after drm device member */ + struct intel_display *display; +#endif + /** @devcoredump: device coredump */ struct xe_devcoredump devcoredump; @@ -617,8 +622,6 @@ struct xe_device { * drm_i915_private during build. After cleanup these should go away, * migrating to the right sub-structs */ - struct intel_display *display; - const struct dram_info *dram_info; /* diff --git a/include/drm/intel/display_member.h b/include/drm/intel/display_member.h new file mode 100644 index 000000000000..0319ea560b60 --- /dev/null +++ b/include/drm/intel/display_member.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __DRM_INTEL_DISPLAY_H__ +#define __DRM_INTEL_DISPLAY_H__ + +#include +#include +#include + +#include + +struct intel_display; + +/* + * A dummy device struct to define the relative offsets of drm and display + * members. With the members identically placed in struct drm_i915_private and + * struct xe_device, this allows figuring out the struct intel_display pointer + * without the definition of either driver specific structure. + */ +struct __intel_generic_device { + struct drm_device drm; + struct intel_display *display; +}; + +/** + * INTEL_DISPLAY_MEMBER_STATIC_ASSERT() - ensure correct placing of drm and display members + * @type: The struct to check + * @drm_member: Name of the struct drm_device member + * @display_member: Name of the struct intel_display * member. + * + * Use this static assert macro to ensure the struct drm_i915_private and struct + * xe_device struct drm_device and struct intel_display * members are at the + * same relative offsets. + */ +#define INTEL_DISPLAY_MEMBER_STATIC_ASSERT(type, drm_member, display_member) \ + static_assert( \ + offsetof(struct __intel_generic_device, display) - offsetof(struct __intel_generic_device, drm) == \ + offsetof(type, display_member) - offsetof(type, drm_member), \ + __stringify(type) " " __stringify(drm_member) " and " __stringify(display_member) " members at invalid offsets") + +#endif -- cgit v1.2.3 From fcf6bddebfe03574041d7bb5f7e3f18e6b46a426 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 30 Sep 2025 21:24:45 +0300 Subject: drm/dp: Add quirk for Synaptics DSC throughput link-bpp limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some Synaptics MST branch devices have a problem decompressing a stream with a compressed link-bpp higher than 12, if the pixel clock is higher than ~50 % of the maximum throughput capability reported by the branch device. The screen remains blank, or for some - mostly black content - gets enabled, but may stil have jitter artifacts. At least the following docking stations are affected, based on testing both with any Intel devices or the UCD-500 reference device as a source: - DELL WD19DCS, DELL WD19TB3, DELL WD22TB4 - ThinkPad 40AN - HP G2 At least the following docking stations are free from this problem, based on tests with a source/sink/mode etc. configuration matching the test cases used above: - DELL Dual Charge HD22Q, DELL WD25TB5 - ThinkPad 40B0 - Anker 565 All the affected devices have an older version of the Synaptics MST branch device (Panamera), whereas all the non-affected docking stations have a newer branch device (at least Synaptics Panamera with a higher HW revision number and Synaptics Cayenne models). Add the required quirk entries accordingly. The quirk will be handled by the i915/xe drivers in a follow-up change. The latest firmware version of the Synaptics branch device for all the affected devices tested above is 5.7 (as reported at DPCD address 0x50a/0x50b). For the DELL devices this corresponds to the latest 01.00.14.01.A03 firmware package version of the docking station. v2: - Document the DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT enum. - Describe the quirk in more detail in the dpcd_quirk_list. v3: - s/Panarema/Panamera in the commit log. Cc: dri-devel@lists.freedesktop.org Reported-by: Vidya Srinivas Reported-and-tested-by: Swati Sharma Reviewed-by: Ville Syrjälä Acked-by: Maarten Lankhorst Signed-off-by: Imre Deak Link: https://lore.kernel.org/r/20250930182450.563016-2-imre.deak@intel.com --- drivers/gpu/drm/display/drm_dp_helper.c | 4 ++++ include/drm/display/drm_dp_helper.h | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 4aaeae4fa03c..4cbcb685f562 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -2543,6 +2543,10 @@ static const struct dpcd_quirk dpcd_quirk_list[] = { { OUI(0x00, 0x0C, 0xE7), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) }, /* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low DP_MAX_LINK_RATE */ { OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) }, + /* Synaptics Panamera supports only a compressed bpp of 12 above 50% of its max DSC pixel throughput */ + { OUI(0x90, 0xCC, 0x24), DEVICE_ID('S', 'Y', 'N', 'A', 0x53, 0x22), true, BIT(DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT) }, + { OUI(0x90, 0xCC, 0x24), DEVICE_ID('S', 'Y', 'N', 'A', 0x53, 0x31), true, BIT(DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT) }, + { OUI(0x90, 0xCC, 0x24), DEVICE_ID('S', 'Y', 'N', 'A', 0x53, 0x33), true, BIT(DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT) }, }; #undef OUI diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 87caa4f1fdb8..558f5ce924ac 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -820,6 +820,15 @@ enum drm_dp_quirk { * requires enabling DSC. */ DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC, + /** + * @DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT: + * + * The device doesn't support DSC decompression at the maximum DSC + * pixel throughput and compressed bpp it indicates via its DPCD DSC + * capabilities. The compressed bpp must be limited above a device + * specific DSC pixel throughput. + */ + DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT, }; /** -- cgit v1.2.3 From 1f95871207db4439a3116e9a86f5b5658a5157c4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 30 Sep 2025 21:24:46 +0300 Subject: drm/dp: Add helpers to query the branch DSC max throughput/line-width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helpers to query the DP DSC sink device's per-slice throughput as well as a DSC branch device's overall throughput and line-width capabilities. v2 (Ville): - Rename pixel_clock to peak_pixel_rate, document what the value means in case of MST tiled displays. - Fix name of drm_dp_dsc_branch_max_slice_throughput() to drm_dp_dsc_sink_max_slice_throughput(). v3: - Fix the DSC branch device minimum valid line width value from 2560 to 5120 pixels. - Fix drm_dp_dsc_sink_max_slice_throughput()'s pixel_clock parameter name to peak_pixel_rate in header file. - Add handling for throughput mode 0 granular delta, defined by DP Standard v2.1a. v4: - Remove the default switch case in drm_dp_dsc_sink_max_slice_throughput(), which is unreachable in the current code. (Ville) Cc: dri-devel@lists.freedesktop.org Suggested-by: Ville Syrjälä Reported-and-tested-by: Swati Sharma Reviewed-by: Ville Syrjälä Reviewed-by: Dmitry Baryshkov Acked-by: Maarten Lankhorst Signed-off-by: Imre Deak Link: https://lore.kernel.org/r/20250930182450.563016-3-imre.deak@intel.com --- drivers/gpu/drm/display/drm_dp_helper.c | 152 ++++++++++++++++++++++++++++++++ include/drm/display/drm_dp.h | 3 + include/drm/display/drm_dp_helper.h | 5 ++ 3 files changed, 160 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 4cbcb685f562..1ebed7c41b0d 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -2836,6 +2836,158 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_S } EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs); +/* + * See DP Standard v2.1a 2.8.4 Minimum Slices/Display, Table 2-159 and + * Appendix L.1 Derivation of Slice Count Requirements. + */ +static int dsc_sink_min_slice_throughput(int peak_pixel_rate) +{ + if (peak_pixel_rate >= 4800000) + return 600000; + else if (peak_pixel_rate >= 2700000) + return 400000; + else + return 340000; +} + +/** + * drm_dp_dsc_sink_max_slice_throughput() - Get a DSC sink's maximum pixel throughput per slice + * @dsc_dpcd: DSC sink's capabilities from DPCD + * @peak_pixel_rate: Cumulative peak pixel rate in kHz + * @is_rgb_yuv444: The mode is either RGB or YUV444 + * + * Return the DSC sink device's maximum pixel throughput per slice, based on + * the device's @dsc_dpcd capabilities, the @peak_pixel_rate of the transferred + * stream(s) and whether the output format @is_rgb_yuv444 or yuv422/yuv420. + * + * Note that @peak_pixel_rate is the total pixel rate transferred to the same + * DSC/display sink. For instance to calculate a tile's slice count of an MST + * multi-tiled display sink (not considering here the required + * rounding/alignment of slice count):: + * + * @peak_pixel_rate = tile_pixel_rate * tile_count + * total_slice_count = @peak_pixel_rate / drm_dp_dsc_sink_max_slice_throughput(@peak_pixel_rate) + * tile_slice_count = total_slice_count / tile_count + * + * Returns: + * The maximum pixel throughput per slice supported by the DSC sink device + * in kPixels/sec. + */ +int drm_dp_dsc_sink_max_slice_throughput(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], + int peak_pixel_rate, bool is_rgb_yuv444) +{ + int throughput; + int delta = 0; + int base; + + throughput = dsc_dpcd[DP_DSC_PEAK_THROUGHPUT - DP_DSC_SUPPORT]; + + if (is_rgb_yuv444) { + throughput = (throughput & DP_DSC_THROUGHPUT_MODE_0_MASK) >> + DP_DSC_THROUGHPUT_MODE_0_SHIFT; + + delta = ((dsc_dpcd[DP_DSC_RC_BUF_BLK_SIZE - DP_DSC_SUPPORT]) & + DP_DSC_THROUGHPUT_MODE_0_DELTA_MASK) >> + DP_DSC_THROUGHPUT_MODE_0_DELTA_SHIFT; /* in units of 2 MPixels/sec */ + delta *= 2000; + } else { + throughput = (throughput & DP_DSC_THROUGHPUT_MODE_1_MASK) >> + DP_DSC_THROUGHPUT_MODE_1_SHIFT; + } + + switch (throughput) { + case 0: + return dsc_sink_min_slice_throughput(peak_pixel_rate); + case 1: + base = 340000; + break; + case 2 ... 14: + base = 400000 + 50000 * (throughput - 2); + break; + case 15: + base = 170000; + break; + } + + return base + delta; +} +EXPORT_SYMBOL(drm_dp_dsc_sink_max_slice_throughput); + +static u8 dsc_branch_dpcd_cap(const u8 dpcd[DP_DSC_BRANCH_CAP_SIZE], int reg) +{ + return dpcd[reg - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0]; +} + +/** + * drm_dp_dsc_branch_max_overall_throughput() - Branch device's max overall DSC pixel throughput + * @dsc_branch_dpcd: DSC branch capabilities from DPCD + * @is_rgb_yuv444: The mode is either RGB or YUV444 + * + * Return the branch device's maximum overall DSC pixel throughput, based on + * the device's DPCD DSC branch capabilities, and whether the output + * format @is_rgb_yuv444 or yuv422/yuv420. + * + * Returns: + * - 0: The maximum overall throughput capability is not indicated by + * the device separately and it must be determined from the per-slice + * max throughput (see @drm_dp_dsc_branch_slice_max_throughput()) + * and the maximum slice count supported by the device. + * - > 0: The maximum overall DSC pixel throughput supported by the branch + * device in kPixels/sec. + */ +int drm_dp_dsc_branch_max_overall_throughput(const u8 dsc_branch_dpcd[DP_DSC_BRANCH_CAP_SIZE], + bool is_rgb_yuv444) +{ + int throughput; + + if (is_rgb_yuv444) + throughput = dsc_branch_dpcd_cap(dsc_branch_dpcd, + DP_DSC_BRANCH_OVERALL_THROUGHPUT_0); + else + throughput = dsc_branch_dpcd_cap(dsc_branch_dpcd, + DP_DSC_BRANCH_OVERALL_THROUGHPUT_1); + + switch (throughput) { + case 0: + return 0; + case 1: + return 680000; + default: + return 600000 + 50000 * throughput; + } +} +EXPORT_SYMBOL(drm_dp_dsc_branch_max_overall_throughput); + +/** + * drm_dp_dsc_branch_max_line_width() - Branch device's max DSC line width + * @dsc_branch_dpcd: DSC branch capabilities from DPCD + * + * Return the branch device's maximum overall DSC line width, based on + * the device's @dsc_branch_dpcd capabilities. + * + * Returns: + * - 0: The maximum line width is not indicated by the device + * separately and it must be determined from the maximum + * slice count and slice-width supported by the device. + * - %-EINVAL: The device indicates an invalid maximum line width + * (< 5120 pixels). + * - >= 5120: The maximum line width in pixels. + */ +int drm_dp_dsc_branch_max_line_width(const u8 dsc_branch_dpcd[DP_DSC_BRANCH_CAP_SIZE]) +{ + int line_width = dsc_branch_dpcd_cap(dsc_branch_dpcd, DP_DSC_BRANCH_MAX_LINE_WIDTH); + + switch (line_width) { + case 0: + return 0; + case 1 ... 15: + return -EINVAL; + default: + return line_width * 320; + } +} +EXPORT_SYMBOL(drm_dp_dsc_branch_max_line_width); + static int drm_dp_read_lttpr_regs(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE], int address, u8 *buf, int buf_size) diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 811e9238a77c..600bca40249b 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -257,6 +257,8 @@ # define DP_DSC_RC_BUF_BLK_SIZE_4 0x1 # define DP_DSC_RC_BUF_BLK_SIZE_16 0x2 # define DP_DSC_RC_BUF_BLK_SIZE_64 0x3 +# define DP_DSC_THROUGHPUT_MODE_0_DELTA_SHIFT 3 /* DP 2.1a, in units of 2 MPixels/sec */ +# define DP_DSC_THROUGHPUT_MODE_0_DELTA_MASK (0x1f << DP_DSC_THROUGHPUT_MODE_0_DELTA_SHIFT) #define DP_DSC_RC_BUF_SIZE 0x063 @@ -1683,6 +1685,7 @@ enum drm_dp_phy { #define DP_BRANCH_OUI_HEADER_SIZE 0xc #define DP_RECEIVER_CAP_SIZE 0xf #define DP_DSC_RECEIVER_CAP_SIZE 0x10 /* DSC Capabilities 0x60 through 0x6F */ +#define DP_DSC_BRANCH_CAP_SIZE 3 #define EDP_PSR_RECEIVER_CAP_SIZE 2 #define EDP_DISPLAY_CTL_CAP_SIZE 5 #define DP_LTTPR_COMMON_CAP_SIZE 8 diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 558f5ce924ac..fc02eb888be8 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -203,6 +203,11 @@ u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]); int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE], u8 dsc_bpc[3]); +int drm_dp_dsc_sink_max_slice_throughput(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], + int peak_pixel_rate, bool is_rgb_yuv444); +int drm_dp_dsc_branch_max_overall_throughput(const u8 dsc_branch_dpcd[DP_DSC_BRANCH_CAP_SIZE], + bool is_rgb_yuv444); +int drm_dp_dsc_branch_max_line_width(const u8 dsc_branch_dpcd[DP_DSC_BRANCH_CAP_SIZE]); static inline bool drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) -- cgit v1.2.3 From 5e0de2dfbc1bddbd47fbcc9dabb4917000b0ca27 Mon Sep 17 00:00:00 2001 From: Balasubramani Vivekanandan Date: Tue, 21 Oct 2025 22:17:33 -0700 Subject: drm/xe/cri: Add CRI platform definition Add platform definition and PCI IDs for Crescent Island. Other platforms use INTEL_VGA_DEVICE since they have a PCI_BASE_CLASS_DISPLAY class. This is not the case for CRI, so just match on devid, which should be sufficient. Signed-off-by: Balasubramani Vivekanandan Reviewed-by: Shekhar Chauhan Link: https://lore.kernel.org/r/20251021-cri-v1-1-bf11e61d9f49@intel.com Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/xe/xe_pci.c | 15 +++++++++++++++ drivers/gpu/drm/xe/xe_platform_types.h | 1 + include/drm/intel/pciids.h | 4 ++++ 3 files changed, 20 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index ece45157fd31..6e59642e7820 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -400,6 +400,20 @@ static const struct xe_device_desc nvls_desc = { .vm_max_level = 4, }; +static const struct xe_device_desc cri_desc = { + DGFX_FEATURES, + PLATFORM(CRESCENTISLAND), + .dma_mask_size = 52, + .has_display = false, + .has_flat_ccs = false, + .has_mbx_power_limits = true, + .has_sriov = true, + .max_gt_per_tile = 2, + .require_force_probe = true, + .va_bits = 57, + .vm_max_level = 4, +}; + #undef PLATFORM __diag_pop(); @@ -427,6 +441,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_BMG_IDS(INTEL_VGA_DEVICE, &bmg_desc), INTEL_PTL_IDS(INTEL_VGA_DEVICE, &ptl_desc), INTEL_NVLS_IDS(INTEL_VGA_DEVICE, &nvls_desc), + INTEL_CRI_IDS(INTEL_PCI_DEVICE, &cri_desc), { } }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/gpu/drm/xe/xe_platform_types.h b/drivers/gpu/drm/xe/xe_platform_types.h index 78286285c249..f516dbddfd88 100644 --- a/drivers/gpu/drm/xe/xe_platform_types.h +++ b/drivers/gpu/drm/xe/xe_platform_types.h @@ -25,6 +25,7 @@ enum xe_platform { XE_BATTLEMAGE, XE_PANTHERLAKE, XE_NOVALAKE_S, + XE_CRESCENTISLAND, }; enum xe_subplatform { diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index 9f095a99d6c9..6e53fb4cdd37 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -893,4 +893,8 @@ MACRO__(0xD744, ## __VA_ARGS__), \ MACRO__(0xD745, ## __VA_ARGS__) +/* CRI */ +#define INTEL_CRI_IDS(MACRO__, ...) \ + MACRO__(0x674C, ## __VA_ARGS__) + #endif /* __PCIIDS_H__ */ -- cgit v1.2.3 From d1ac2573f0085a5aab6f5d4cfa7b2818d703e5fe Mon Sep 17 00:00:00 2001 From: Nemesa Garg Date: Tue, 28 Oct 2025 17:37:37 +0530 Subject: drm/drm_crtc: Introduce sharpness strength property Introduce a new crtc property "SHARPNESS_STRENGTH" that allows the user to set the intensity so as to get the sharpness effect. The value of this property can be set from 0-255. It is useful in scenario when the output is blurry and user want to sharpen the pixels. User can increase/decrease the sharpness level depending on the content displayed. v2: Rename crtc property variable [Arun] Add modeset detail in uapi doc[Uma] v3: Fix build issue v4: Modify the subject line[Ankit] Signed-off-by: Nemesa Garg Reviewed-by: Ankit Nautiyal Tested-by: Adarsh G M Acked-by: Simona Vetter Link: https://invent.kde.org/plasma/kwin/-/merge_requests/7689 Link: https://patch.msgid.link/20251028120747.3027332-2-ankit.k.nautiyal@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++++ drivers/gpu/drm/drm_crtc.c | 35 +++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 18 ++++++++++++++++++ 3 files changed, 57 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 85dbdaa4a2e2..b2cb5ae5a139 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -419,6 +419,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, set_out_fence_for_crtc(state->state, crtc, fence_ptr); } else if (property == crtc->scaling_filter_property) { state->scaling_filter = val; + } else if (property == crtc->sharpness_strength_property) { + state->sharpness_strength = val; } else if (crtc->funcs->atomic_set_property) { return crtc->funcs->atomic_set_property(crtc, state, property, val); } else { @@ -456,6 +458,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = 0; else if (property == crtc->scaling_filter_property) *val = state->scaling_filter; + else if (property == crtc->sharpness_strength_property) + *val = state->sharpness_strength; else if (crtc->funcs->atomic_get_property) return crtc->funcs->atomic_get_property(crtc, state, property, val); else { diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 46655339003d..a7797d260f1e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -229,6 +229,25 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc) * Driver's default scaling filter * Nearest Neighbor: * Nearest Neighbor scaling filter + * SHARPNESS_STRENGTH: + * Atomic property for setting the sharpness strength/intensity by userspace. + * + * The value of this property is set as an integer value ranging + * from 0 - 255 where: + * + * 0: Sharpness feature is disabled(default value). + * + * 1: Minimum sharpness. + * + * 255: Maximum sharpness. + * + * User can gradually increase or decrease the sharpness level and can + * set the optimum value depending on content. + * This value will be passed to kernel through the UAPI. + * The setting of this property does not require modeset. + * The sharpness effect takes place post blending on the final composed output. + * If the feature is disabled, the content remains same without any sharpening effect + * and when this feature is applied, it enhances the clarity of the content. */ __printf(6, 0) @@ -940,6 +959,22 @@ int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, } EXPORT_SYMBOL(drm_crtc_create_scaling_filter_property); +int drm_crtc_create_sharpness_strength_property(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_property *prop = + drm_property_create_range(dev, 0, "SHARPNESS_STRENGTH", 0, 255); + + if (!prop) + return -ENOMEM; + + crtc->sharpness_strength_property = prop; + drm_object_attach_property(&crtc->base, prop, 0); + + return 0; +} +EXPORT_SYMBOL(drm_crtc_create_sharpness_strength_property); + /** * drm_crtc_in_clone_mode - check if the given CRTC state is in clone mode * diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index caa56e039da2..bcdbde681986 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -317,6 +317,17 @@ struct drm_crtc_state { */ enum drm_scaling_filter scaling_filter; + /** + * @sharpness_strength: + * + * Used by the user to set the sharpness intensity. + * The value ranges from 0-255. + * Default value is 0 which disable the sharpness feature. + * Any value greater than 0 enables sharpening with the + * specified strength. + */ + u8 sharpness_strength; + /** * @event: * @@ -1088,6 +1099,12 @@ struct drm_crtc { */ struct drm_property *scaling_filter_property; + /** + * @sharpness_strength_property: property to apply + * the intensity of the sharpness requested. + */ + struct drm_property *sharpness_strength_property; + /** * @state: * @@ -1324,4 +1341,5 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, unsigned int supported_filters); bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state); +int drm_crtc_create_sharpness_strength_property(struct drm_crtc *crtc); #endif /* __DRM_CRTC_H__ */ -- cgit v1.2.3 From b3c8fa0d9c2650ab9bdc7ccc980a6826c4f9021d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Oct 2025 22:28:31 +0200 Subject: drm/{i915, xe}/display: pass parent interface to display probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's gradually start calling i915 and xe parent, or core, drivers from display via function pointers passed at display probe. Going forward, the struct intel_display_parent_interface is expected to include const pointers to sub-structs by functionality, for example: struct intel_display_rpm { struct ref_tracker *(*get)(struct drm_device *drm); /* ... */ }; struct intel_display_parent_interface { /* ... */ const struct intel_display_rpm *rpm; }; This is a baby step towards not building display as part of both i915 and xe drivers, but rather making it an independent driver interfacing with the two. v3: useless include additions dropped v2: unrelated include removal dropped Cc: Jouni Högander Cc: Lucas De Marchi Cc: Rodrigo Vivi Cc: Ville Syrjälä Signed-off-by: Jani Nikula Signed-off-by: Jouni Högander Link: https://patch.msgid.link/20251030202836.1815680-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display_core.h | 4 ++++ .../gpu/drm/i915/display/intel_display_device.c | 5 ++++- .../gpu/drm/i915/display/intel_display_device.h | 4 +++- drivers/gpu/drm/i915/i915_driver.c | 11 ++++++++- drivers/gpu/drm/i915/i915_driver.h | 2 ++ drivers/gpu/drm/i915/selftests/mock_gem_device.c | 4 +++- drivers/gpu/drm/xe/display/xe_display.c | 6 ++++- include/drm/intel/display_parent_interface.h | 26 ++++++++++++++++++++++ 8 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 include/drm/intel/display_parent_interface.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 32664098b407..893279be8409 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -41,6 +41,7 @@ struct intel_cdclk_vals; struct intel_color_funcs; struct intel_crtc; struct intel_crtc_state; +struct intel_display_parent_interface; struct intel_dmc; struct intel_dpll_global_funcs; struct intel_dpll_mgr; @@ -291,6 +292,9 @@ struct intel_display { /* Intel PCH: where the south display engine lives */ enum intel_pch pch_type; + /* Parent, or core, driver functions exposed to display */ + const struct intel_display_parent_interface *parent; + /* Display functions */ struct { /* Top level crtc-ish functions */ diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index f3f1f25b0f38..328447a5e5e8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1647,7 +1647,8 @@ static void display_platforms_or(struct intel_display_platforms *dst, bitmap_or(dst->bitmap, dst->bitmap, src->bitmap, display_platforms_num_bits()); } -struct intel_display *intel_display_device_probe(struct pci_dev *pdev) +struct intel_display *intel_display_device_probe(struct pci_dev *pdev, + const struct intel_display_parent_interface *parent) { struct intel_display *display; const struct intel_display_device_info *info; @@ -1663,6 +1664,8 @@ struct intel_display *intel_display_device_probe(struct pci_dev *pdev) /* Add drm device backpointer as early as possible. */ display->drm = pci_get_drvdata(pdev); + display->parent = parent; + intel_display_params_copy(&display->params); if (has_no_display(pdev)) { diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index ece66c8c4ce6..b559ef43d547 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -13,6 +13,7 @@ struct drm_printer; struct intel_display; +struct intel_display_parent_interface; struct pci_dev; /* @@ -313,7 +314,8 @@ struct intel_display_device_info { bool intel_display_device_present(struct intel_display *display); bool intel_display_device_enabled(struct intel_display *display); -struct intel_display *intel_display_device_probe(struct pci_dev *pdev); +struct intel_display *intel_display_device_probe(struct pci_dev *pdev, + const struct intel_display_parent_interface *parent); void intel_display_device_remove(struct intel_display *display); void intel_display_device_info_runtime_init(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index b46cb54ef5dc..18ff10c63e98 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "display/i9xx_display_sr.h" #include "display/intel_bw.h" @@ -738,6 +739,14 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) "DRM_I915_DEBUG_RUNTIME_PM enabled\n"); } +static const struct intel_display_parent_interface parent = { +}; + +const struct intel_display_parent_interface *i915_driver_parent_interface(void) +{ + return &parent; +} + /* Ensure drm and display members are placed properly. */ INTEL_DISPLAY_MEMBER_STATIC_ASSERT(struct drm_i915_private, drm, display); @@ -762,7 +771,7 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) /* Set up device info and initial runtime info. */ intel_device_info_driver_create(i915, pdev->device, match_info); - display = intel_display_device_probe(pdev); + display = intel_display_device_probe(pdev, &parent); if (IS_ERR(display)) return ERR_CAST(display); diff --git a/drivers/gpu/drm/i915/i915_driver.h b/drivers/gpu/drm/i915/i915_driver.h index 1e95ecb2a163..9551519ab429 100644 --- a/drivers/gpu/drm/i915/i915_driver.h +++ b/drivers/gpu/drm/i915/i915_driver.h @@ -12,6 +12,7 @@ struct pci_dev; struct pci_device_id; struct drm_i915_private; struct drm_printer; +struct intel_display_parent_interface; #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" @@ -24,6 +25,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915); int i915_driver_resume_switcheroo(struct drm_i915_private *i915); int i915_driver_suspend_switcheroo(struct drm_i915_private *i915, pm_message_t state); +const struct intel_display_parent_interface *i915_driver_parent_interface(void); void i915_print_iommu_status(struct drm_i915_private *i915, struct drm_printer *p); diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index fb8751bd5df0..b59626c4994c 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -33,6 +33,7 @@ #include "gt/intel_gt.h" #include "gt/intel_gt_requests.h" #include "gt/mock_engine.h" +#include "i915_driver.h" #include "intel_memory_region.h" #include "intel_region_ttm.h" @@ -183,7 +184,8 @@ struct drm_i915_private *mock_gem_device(void) /* Set up device info and initial runtime info. */ intel_device_info_driver_create(i915, pdev->device, &mock_info); - display = intel_display_device_probe(pdev); + /* FIXME: Can we run selftests using a mock device without display? */ + display = intel_display_device_probe(pdev, i915_driver_parent_interface()); if (IS_ERR(display)) goto err_device; diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 5f4044e63185..074341645960 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "soc/intel_dram.h" @@ -515,6 +516,9 @@ static void display_device_remove(struct drm_device *dev, void *arg) intel_display_device_remove(display); } +static const struct intel_display_parent_interface parent = { +}; + /** * xe_display_probe - probe display and create display struct * @xe: XE device instance @@ -535,7 +539,7 @@ int xe_display_probe(struct xe_device *xe) if (!xe->info.probe_display) goto no_display; - display = intel_display_device_probe(pdev); + display = intel_display_device_probe(pdev, &parent); if (IS_ERR(display)) return PTR_ERR(display); diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h new file mode 100644 index 000000000000..28c976815327 --- /dev/null +++ b/include/drm/intel/display_parent_interface.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation x*/ + +#ifndef __DISPLAY_PARENT_INTERFACE_H__ +#define __DISPLAY_PARENT_INTERFACE_H__ + +#include + +struct drm_device; + +/** + * struct intel_display_parent_interface - services parent driver provides to display + * + * The parent, or core, driver provides a pointer to this structure to display + * driver when calling intel_display_device_probe(). The display driver uses it + * to access services provided by the parent driver. The structure may contain + * sub-struct pointers to group function pointers by functionality. + * + * All function and sub-struct pointers must be initialized and callable unless + * explicitly marked as "optional" below. The display driver will only NULL + * check the optional pointers. + */ +struct intel_display_parent_interface { +}; + +#endif -- cgit v1.2.3 From 1914d6861b594dde7cbb359ab1ba43f2e3a82f91 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Thu, 30 Oct 2025 22:28:32 +0200 Subject: drm/{i915, xe}/display: Add display runtime pm parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have differing implementations for display runtime pm in i915 and xe drivers. Add struct of function pointers into display_parent_interface which will contain used implementation of runtime pm. v2: - add _interface suffix to rpm function pointer struct - add struct ref_tracker forward declaration - use kernel-doc comments Reviewed-by: Jani Nikula Signed-off-by: Jouni Högander Link: https://patch.msgid.link/20251030202836.1815680-3-jouni.hogander@intel.com --- include/drm/intel/display_parent_interface.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 28c976815327..26bedc360044 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -7,6 +7,23 @@ #include struct drm_device; +struct ref_tracker; + +struct intel_display_rpm_interface { + struct ref_tracker *(*get)(const struct drm_device *drm); + struct ref_tracker *(*get_raw)(const struct drm_device *drm); + struct ref_tracker *(*get_if_in_use)(const struct drm_device *drm); + struct ref_tracker *(*get_noresume)(const struct drm_device *drm); + + void (*put)(const struct drm_device *drm, struct ref_tracker *wakeref); + void (*put_raw)(const struct drm_device *drm, struct ref_tracker *wakeref); + void (*put_unchecked)(const struct drm_device *drm); + + bool (*suspended)(const struct drm_device *drm); + void (*assert_held)(const struct drm_device *drm); + void (*assert_block)(const struct drm_device *drm); + void (*assert_unblock)(const struct drm_device *drm); +}; /** * struct intel_display_parent_interface - services parent driver provides to display @@ -21,6 +38,8 @@ struct drm_device; * check the optional pointers. */ struct intel_display_parent_interface { + /** @rpm: Runtime PM functions */ + const struct intel_display_rpm_interface *rpm; }; #endif -- cgit v1.2.3