From 7cd1049a33caf1199b18424a0b6165cf22f8e963 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 3 Sep 2024 10:55:58 +0800 Subject: [PATCH 001/205] drm/i915/hdmi: convert comma to semicolon Replace a comma between expression statements by a semicolon. Signed-off-by: Chen Ni Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240903025558.493977-1-nichen@iscas.ac.cn Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index cd9ee171e0df..f2dce9896a48 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1310,8 +1310,8 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, memcpy(&write_buf[1], buffer, size); msg.addr = DRM_HDCP_DDC_ADDR; - msg.flags = 0, - msg.len = size + 1, + msg.flags = 0; + msg.len = size + 1; msg.buf = write_buf; ret = i2c_transfer(ddc, &msg, 1); From c4d37c54c3739530f8585ccf064fb712913f8375 Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Mon, 2 Sep 2024 10:40:21 +0300 Subject: [PATCH 002/205] drm/i915/display: Fix BMG CCS modifiers Let I915_FORMAT_MOD_4_TILED_BMG_CCS show up as supported modifier Fixes: 97c6efb36497 ("drm/i915/display: Plane capability for 64k phys alignment") Signed-off-by: Juha-Pekka Heikkila Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20240902074021.459480-1-juhapekka.heikkila@gmail.com Signed-off-by: Maarten Lankhorst,,, --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 9452cad41d07..17d4c880ecc4 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2453,6 +2453,9 @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915, if (gen12_plane_has_mc_ccs(i915, plane_id)) caps |= INTEL_PLANE_CAP_CCS_MC; + if (DISPLAY_VER(i915) >= 14 && IS_DGFX(i915)) + caps |= INTEL_PLANE_CAP_NEED64K_PHYS; + return caps; } From 4e66f73ee08ccb723258524e32420d721d4e3d6b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Aug 2024 19:31:14 +0300 Subject: [PATCH 003/205] drm/i915/wm: move struct intel_watermark_params to i9xx_wm.c The definition is only used within i9xx_wm.c, hide it there. Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d7408290c909eb67fc7a935469a3c6287b58587d.1724689818.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/i9xx_wm.c | 8 ++++++++ drivers/gpu/drm/i915/display/intel_display_types.h | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 15cda57fbc91..4e7ca5277bf1 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -14,6 +14,14 @@ #include "skl_watermark.h" #include "vlv_sideband.h" +struct intel_watermark_params { + u16 fifo_size; + u16 max_wm; + u8 default_wm; + u8 guard_size; + u8 cacheline_size; +}; + /* used in computing the new watermarks state */ struct intel_wm_config { unsigned int num_pipes_active; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index f29e5dc3db91..fdaefb765f12 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1601,14 +1601,6 @@ struct intel_plane { void (*disable_flip_done)(struct intel_plane *plane); }; -struct intel_watermark_params { - u16 fifo_size; - u16 max_wm; - u8 default_wm; - u8 guard_size; - u8 cacheline_size; -}; - #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base) #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) #define to_intel_connector(x) container_of(x, struct intel_connector, base) From c0e08c2028f7d57644a5154d5aaca54625710a75 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Aug 2024 19:31:15 +0300 Subject: [PATCH 004/205] drm/i915/hdcp: split out intel_hdcp_shim.h for struct intel_hdcp_shim There are only a handful of files that need the struct intel_hdcp_shim definition. Move it to a new file intel_hdcp_shim.h and include where needed. Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8dc62bed1f4c827730f66f91a18e1cf0712df123.1724689818.git.jani.nikula@intel.com --- .../drm/i915/display/intel_display_types.h | 125 +--------------- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 1 + drivers/gpu/drm/i915/display/intel_hdcp.c | 1 + .../gpu/drm/i915/display/intel_hdcp_shim.h | 137 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_hdmi.c | 1 + 5 files changed, 142 insertions(+), 123 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_hdcp_shim.h diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index fdaefb765f12..2da6bbe95420 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -59,9 +59,10 @@ struct drm_printer; struct __intel_global_objs_state; +struct intel_connector; struct intel_ddi_buf_trans; struct intel_fbc; -struct intel_connector; +struct intel_hdcp_shim; struct intel_tc_port; /* @@ -430,128 +431,6 @@ struct intel_panel { struct intel_digital_port; -enum check_link_response { - HDCP_LINK_PROTECTED = 0, - HDCP_TOPOLOGY_CHANGE, - HDCP_LINK_INTEGRITY_FAILURE, - HDCP_REAUTH_REQUEST -}; - -/* - * This structure serves as a translation layer between the generic HDCP code - * and the bus-specific code. What that means is that HDCP over HDMI differs - * from HDCP over DP, so to account for these differences, we need to - * communicate with the receiver through this shim. - * - * For completeness, the 2 buses differ in the following ways: - * - DP AUX vs. DDC - * HDCP registers on the receiver are set via DP AUX for DP, and - * they are set via DDC for HDMI. - * - Receiver register offsets - * The offsets of the registers are different for DP vs. HDMI - * - Receiver register masks/offsets - * For instance, the ready bit for the KSV fifo is in a different - * place on DP vs HDMI - * - Receiver register names - * Seriously. In the DP spec, the 16-bit register containing - * downstream information is called BINFO, on HDMI it's called - * BSTATUS. To confuse matters further, DP has a BSTATUS register - * with a completely different definition. - * - KSV FIFO - * On HDMI, the ksv fifo is read all at once, whereas on DP it must - * be read 3 keys at a time - * - Aksv output - * Since Aksv is hidden in hardware, there's different procedures - * to send it over DP AUX vs DDC - */ -struct intel_hdcp_shim { - /* Outputs the transmitter's An and Aksv values to the receiver. */ - int (*write_an_aksv)(struct intel_digital_port *dig_port, u8 *an); - - /* Reads the receiver's key selection vector */ - int (*read_bksv)(struct intel_digital_port *dig_port, u8 *bksv); - - /* - * Reads BINFO from DP receivers and BSTATUS from HDMI receivers. The - * definitions are the same in the respective specs, but the names are - * different. Call it BSTATUS since that's the name the HDMI spec - * uses and it was there first. - */ - int (*read_bstatus)(struct intel_digital_port *dig_port, - u8 *bstatus); - - /* Determines whether a repeater is present downstream */ - int (*repeater_present)(struct intel_digital_port *dig_port, - bool *repeater_present); - - /* Reads the receiver's Ri' value */ - int (*read_ri_prime)(struct intel_digital_port *dig_port, u8 *ri); - - /* Determines if the receiver's KSV FIFO is ready for consumption */ - int (*read_ksv_ready)(struct intel_digital_port *dig_port, - bool *ksv_ready); - - /* Reads the ksv fifo for num_downstream devices */ - int (*read_ksv_fifo)(struct intel_digital_port *dig_port, - int num_downstream, u8 *ksv_fifo); - - /* Reads a 32-bit part of V' from the receiver */ - int (*read_v_prime_part)(struct intel_digital_port *dig_port, - int i, u32 *part); - - /* Enables HDCP signalling on the port */ - int (*toggle_signalling)(struct intel_digital_port *dig_port, - enum transcoder cpu_transcoder, - bool enable); - - /* Enable/Disable stream encryption on DP MST Transport Link */ - int (*stream_encryption)(struct intel_connector *connector, - bool enable); - - /* Ensures the link is still protected */ - bool (*check_link)(struct intel_digital_port *dig_port, - struct intel_connector *connector); - - /* Detects panel's hdcp capability. This is optional for HDMI. */ - int (*hdcp_get_capability)(struct intel_digital_port *dig_port, - bool *hdcp_capable); - - /* HDCP adaptation(DP/HDMI) required on the port */ - enum hdcp_wired_protocol protocol; - - /* Detects whether sink is HDCP2.2 capable */ - int (*hdcp_2_2_get_capability)(struct intel_connector *connector, - bool *capable); - - /* Write HDCP2.2 messages */ - int (*write_2_2_msg)(struct intel_connector *connector, - void *buf, size_t size); - - /* Read HDCP2.2 messages */ - int (*read_2_2_msg)(struct intel_connector *connector, - u8 msg_id, void *buf, size_t size); - - /* - * Implementation of DP HDCP2.2 Errata for the communication of stream - * type to Receivers. In DP HDCP2.2 Stream type is one of the input to - * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI. - */ - int (*config_stream_type)(struct intel_connector *connector, - bool is_repeater, u8 type); - - /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */ - int (*stream_2_2_encryption)(struct intel_connector *connector, - bool enable); - - /* HDCP2.2 Link Integrity Check */ - int (*check_2_2_link)(struct intel_digital_port *dig_port, - struct intel_connector *connector); - - /* HDCP remote sink cap */ - int (*get_remote_hdcp_capability)(struct intel_connector *connector, - bool *hdcp_capable, bool *hdcp2_capable); -}; - struct intel_hdcp { const struct intel_hdcp_shim *shim; /* Mutex for hdcp state of the connector */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 3425b3643143..dce645a07cdb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -19,6 +19,7 @@ #include "intel_dp_hdcp.h" #include "intel_hdcp.h" #include "intel_hdcp_regs.h" +#include "intel_hdcp_shim.h" static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder) { diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 6980b98792c2..ebec03bc88e9 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -25,6 +25,7 @@ #include "intel_hdcp.h" #include "intel_hdcp_gsc.h" #include "intel_hdcp_regs.h" +#include "intel_hdcp_shim.h" #include "intel_pcode.h" #define KEY_LOAD_TRIES 5 diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_shim.h b/drivers/gpu/drm/i915/display/intel_hdcp_shim.h new file mode 100644 index 000000000000..abf9ae2f4ada --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_hdcp_shim.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2024 Intel Corporation */ + +#ifndef __INTEL_HDCP_SHIM_H__ +#define __INTEL_HDCP_SHIM_H__ + +#include + +#include + +enum transcoder; +struct intel_connector; +struct intel_digital_port; + +enum check_link_response { + HDCP_LINK_PROTECTED = 0, + HDCP_TOPOLOGY_CHANGE, + HDCP_LINK_INTEGRITY_FAILURE, + HDCP_REAUTH_REQUEST +}; + +/* + * This structure serves as a translation layer between the generic HDCP code + * and the bus-specific code. What that means is that HDCP over HDMI differs + * from HDCP over DP, so to account for these differences, we need to + * communicate with the receiver through this shim. + * + * For completeness, the 2 buses differ in the following ways: + * - DP AUX vs. DDC + * HDCP registers on the receiver are set via DP AUX for DP, and + * they are set via DDC for HDMI. + * - Receiver register offsets + * The offsets of the registers are different for DP vs. HDMI + * - Receiver register masks/offsets + * For instance, the ready bit for the KSV fifo is in a different + * place on DP vs HDMI + * - Receiver register names + * Seriously. In the DP spec, the 16-bit register containing + * downstream information is called BINFO, on HDMI it's called + * BSTATUS. To confuse matters further, DP has a BSTATUS register + * with a completely different definition. + * - KSV FIFO + * On HDMI, the ksv fifo is read all at once, whereas on DP it must + * be read 3 keys at a time + * - Aksv output + * Since Aksv is hidden in hardware, there's different procedures + * to send it over DP AUX vs DDC + */ +struct intel_hdcp_shim { + /* Outputs the transmitter's An and Aksv values to the receiver. */ + int (*write_an_aksv)(struct intel_digital_port *dig_port, u8 *an); + + /* Reads the receiver's key selection vector */ + int (*read_bksv)(struct intel_digital_port *dig_port, u8 *bksv); + + /* + * Reads BINFO from DP receivers and BSTATUS from HDMI receivers. The + * definitions are the same in the respective specs, but the names are + * different. Call it BSTATUS since that's the name the HDMI spec + * uses and it was there first. + */ + int (*read_bstatus)(struct intel_digital_port *dig_port, + u8 *bstatus); + + /* Determines whether a repeater is present downstream */ + int (*repeater_present)(struct intel_digital_port *dig_port, + bool *repeater_present); + + /* Reads the receiver's Ri' value */ + int (*read_ri_prime)(struct intel_digital_port *dig_port, u8 *ri); + + /* Determines if the receiver's KSV FIFO is ready for consumption */ + int (*read_ksv_ready)(struct intel_digital_port *dig_port, + bool *ksv_ready); + + /* Reads the ksv fifo for num_downstream devices */ + int (*read_ksv_fifo)(struct intel_digital_port *dig_port, + int num_downstream, u8 *ksv_fifo); + + /* Reads a 32-bit part of V' from the receiver */ + int (*read_v_prime_part)(struct intel_digital_port *dig_port, + int i, u32 *part); + + /* Enables HDCP signalling on the port */ + int (*toggle_signalling)(struct intel_digital_port *dig_port, + enum transcoder cpu_transcoder, + bool enable); + + /* Enable/Disable stream encryption on DP MST Transport Link */ + int (*stream_encryption)(struct intel_connector *connector, + bool enable); + + /* Ensures the link is still protected */ + bool (*check_link)(struct intel_digital_port *dig_port, + struct intel_connector *connector); + + /* Detects panel's hdcp capability. This is optional for HDMI. */ + int (*hdcp_get_capability)(struct intel_digital_port *dig_port, + bool *hdcp_capable); + + /* HDCP adaptation(DP/HDMI) required on the port */ + enum hdcp_wired_protocol protocol; + + /* Detects whether sink is HDCP2.2 capable */ + int (*hdcp_2_2_get_capability)(struct intel_connector *connector, + bool *capable); + + /* Write HDCP2.2 messages */ + int (*write_2_2_msg)(struct intel_connector *connector, + void *buf, size_t size); + + /* Read HDCP2.2 messages */ + int (*read_2_2_msg)(struct intel_connector *connector, + u8 msg_id, void *buf, size_t size); + + /* + * Implementation of DP HDCP2.2 Errata for the communication of stream + * type to Receivers. In DP HDCP2.2 Stream type is one of the input to + * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI. + */ + int (*config_stream_type)(struct intel_connector *connector, + bool is_repeater, u8 type); + + /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */ + int (*stream_2_2_encryption)(struct intel_connector *connector, + bool enable); + + /* HDCP2.2 Link Integrity Check */ + int (*check_2_2_link)(struct intel_digital_port *dig_port, + struct intel_connector *connector); + + /* HDCP remote sink cap */ + int (*get_remote_hdcp_capability)(struct intel_connector *connector, + bool *hdcp_capable, bool *hdcp2_capable); +}; + +#endif /* __INTEL_HDCP_SHIM_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index f2dce9896a48..e44b68f153d4 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -55,6 +55,7 @@ #include "intel_gmbus.h" #include "intel_hdcp.h" #include "intel_hdcp_regs.h" +#include "intel_hdcp_shim.h" #include "intel_hdmi.h" #include "intel_lspcon.h" #include "intel_panel.h" From 11d0613af7c565fe9836505f1c860185f0f2137f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Aug 2024 19:31:16 +0300 Subject: [PATCH 005/205] drm/i915/display: include drm/drm_probe_helper.h where needed Stop including drm/drm_probe_helper.h in intel_display_types.h and only include it where needed. Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/88f565495763d0f31a84f31059ab3b01af9bf2b9.1724689818.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 1 + drivers/gpu/drm/i915/display/intel_display_types.h | 1 - drivers/gpu/drm/i915/display/intel_dvo.c | 1 + drivers/gpu/drm/i915/display/intel_hdmi.c | 1 + drivers/gpu/drm/i915/display/intel_hotplug.c | 2 ++ drivers/gpu/drm/i915/display/intel_lvds.c | 1 + drivers/gpu/drm/i915/display/intel_sdvo.c | 1 + drivers/gpu/drm/i915/display/intel_tv.c | 1 + drivers/gpu/drm/i915/display/vlv_dsi.c | 1 + drivers/gpu/drm/xe/display/xe_display.c | 1 + 10 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 293efc1f841d..87a27d91d15d 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "i915_reg.h" #include "icl_dsi.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 2da6bbe95420..bbd0e1da6b49 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index 12e7628cbecf..9508ceae0d84 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index e44b68f153d4..15316c0272a8 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "g4x_hdmi.h" diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index d9ec349f3c8c..2617c5f63a07 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -23,6 +23,8 @@ #include +#include + #include "i915_drv.h" #include "i915_irq.h" #include "intel_display_power.h" diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index fb4ed9f7855b..1734b12ddf5e 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 7cc519b402e9..b83bf813677d 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 581844d1db9a..e40aff490486 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index d21f3fb39706..f19660064525 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 78a884ddd499..50e62f82313e 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -10,6 +10,7 @@ #include #include +#include #include #include "soc/intel_dram.h" From 5cc6529767981a1ec3557e0247d4bd2645c701e8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Aug 2024 19:31:17 +0300 Subject: [PATCH 006/205] drm/i915/display: include drm/drm_vblank.h where needed Stop including drm/drm_vblank.h in intel_display_types.h and only include it where needed. Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0cdb855398ff21e520ef8839b9d00ded40b85fd0.1724689818.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 1 + drivers/gpu/drm/i915/display/intel_cursor.c | 1 + drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/i915/display/intel_display_irq.c | 2 ++ drivers/gpu/drm/i915/display/intel_display_types.h | 1 - drivers/gpu/drm/i915/display/intel_modeset_setup.c | 1 + drivers/gpu/drm/i915/display/intel_vblank.c | 2 ++ 7 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 1b578cad2813..4218f746691e 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "i915_vgpu.h" diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 9ad53e1cbbd0..805e0af21a45 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "i915_reg.h" #include "intel_atomic.h" diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b4ef4d59da1a..a734dbf937d0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_object.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 73369847ed66..52d31f736b7f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -3,6 +3,8 @@ * Copyright © 2023 Intel Corporation */ +#include + #include "gt/intel_rps.h" #include "i915_drv.h" #include "i915_irq.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index bbd0e1da6b49..5a6c3be5a909 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 72694dde3c22..c2c3b3037938 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -8,6 +8,7 @@ #include #include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 0b7f2134e441..d18b8292be49 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -3,6 +3,8 @@ * Copyright © 2022-2023 Intel Corporation */ +#include + #include "i915_drv.h" #include "i915_reg.h" #include "intel_color.h" From ae19ba915eb7260ba8532c00ffece6b46460c547 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 27 Aug 2024 13:45:21 +0300 Subject: [PATCH 007/205] drm/i915/display: include media/cec-notifier.h and linux/debugfs.h where needed Use a forward declaration for struct cec_notifier instead of including media/cec-notifier.h in intel_display_types.h, and only include it where needed. Also realize that a lot of places depend on including linux/debugfs.h via intel_display_types.h -> media/cec-notifier.h -> media/cec.h, and include that too where needed. v2: hsw_ips.c also needs debugfs.h (kernel test robot) Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240827104521.4151471-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/hsw_ips.c | 2 ++ drivers/gpu/drm/i915/display/intel_alpm.c | 2 ++ drivers/gpu/drm/i915/display/intel_bios.c | 1 + drivers/gpu/drm/i915/display/intel_cdclk.c | 1 + drivers/gpu/drm/i915/display/intel_display_debugfs.c | 1 + drivers/gpu/drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 ++ drivers/gpu/drm/i915/display/intel_drrs.c | 2 ++ drivers/gpu/drm/i915/display/intel_fbc.c | 1 + drivers/gpu/drm/i915/display/intel_hdmi.c | 2 ++ drivers/gpu/drm/i915/display/intel_hotplug.c | 1 + drivers/gpu/drm/i915/display/intel_opregion.c | 1 + drivers/gpu/drm/i915/display/intel_pps.c | 2 ++ drivers/gpu/drm/i915/display/intel_psr.c | 2 ++ drivers/gpu/drm/i915/display/intel_wm.c | 2 ++ drivers/gpu/drm/i915/display/skl_watermark.c | 2 ++ 16 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 611a7d6ef80c..c571c6e76d4a 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -3,6 +3,8 @@ * Copyright © 2022 Intel Corporation */ +#include + #include "hsw_ips.h" #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index 186cf4833f71..31c068f393b7 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.c +++ b/drivers/gpu/drm/i915/display/intel_alpm.c @@ -3,6 +3,8 @@ * Copyright 2024, Intel Corporation. */ +#include + #include "intel_alpm.h" #include "intel_crtc.h" #include "intel_de.h" diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index d49435af62c7..cd32c9cd38a9 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -25,6 +25,7 @@ * */ +#include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index aa3ba66c5307..d6031419e32b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index f5f618199d39..30a0a1d7f6f1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -3,6 +3,7 @@ * Copyright © 2020 Intel Corporation */ +#include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 5a6c3be5a909..4b8b7a86d02c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -43,7 +43,6 @@ #include #include #include -#include #include "gem/i915_gem_object_types.h" /* for to_intel_bo() */ #include "i915_vma.h" @@ -55,6 +54,7 @@ #include "intel_dpll_mgr.h" #include "intel_wm_types.h" +struct cec_notifier; struct drm_printer; struct __intel_global_objs_state; struct intel_connector; diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 40bedc31d6bf..f45797c1a205 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -21,6 +21,8 @@ * IN THE SOFTWARE. */ +#include + #include #include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index 3ca29afa5422..bb39eb96e812 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -3,6 +3,8 @@ * Copyright © 2021 Intel Corporation */ +#include + #include "i915_drv.h" #include "i915_reg.h" #include "intel_atomic.h" diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 52b79bacef4d..b53b38c2f19f 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -38,6 +38,7 @@ * forcibly disable it to allow proper screen updates. */ +#include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 15316c0272a8..869fa00f7ef2 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -41,6 +41,8 @@ #include #include +#include + #include "g4x_hdmi.h" #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 2617c5f63a07..a013b0e0ef54 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -21,6 +21,7 @@ * IN THE SOFTWARE. */ +#include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index ff11836459de..0eaa6cd6fe80 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -26,6 +26,7 @@ */ #include +#include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index feddc30e3375..cdbac9f5a14c 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -3,6 +3,8 @@ * Copyright © 2020 Intel Corporation */ +#include + #include "g4x_dp.h" #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 1f83b3b67ea6..b30fa067ce6e 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -21,6 +21,8 @@ * DEALINGS IN THE SOFTWARE. */ +#include + #include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c index 82c4933ad507..462917bc488f 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.c +++ b/drivers/gpu/drm/i915/display/intel_wm.c @@ -3,6 +3,8 @@ * Copyright © 2023 Intel Corporation */ +#include + #include "i915_drv.h" #include "i9xx_wm.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 045c7cac166b..e955e399b390 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3,6 +3,8 @@ * Copyright © 2022 Intel Corporation */ +#include + #include #include "i915_drv.h" From 9af06d09470893bdde239fdd90bfd3568903695b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Aug 2024 19:31:19 +0300 Subject: [PATCH 008/205] drm/i915/fb: hide the guts of intel_fb_obj() Use a proper function in intel_fb.[ch] for intel_fb_obj() to be able to drop the gem/i915_gem_object_types.h from intel_display_types.h. Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c5ff0d355911903809ba366403192243c05d3427.1724689818.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/i9xx_wm.c | 1 + drivers/gpu/drm/i915/display/intel_atomic_plane.c | 1 + drivers/gpu/drm/i915/display/intel_display_debugfs.c | 3 ++- drivers/gpu/drm/i915/display/intel_display_types.h | 3 --- drivers/gpu/drm/i915/display/intel_fb.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_fb.h | 2 ++ drivers/gpu/drm/i915/display/intel_fbdev.c | 1 + drivers/gpu/drm/i915/display/intel_frontbuffer.c | 1 + 8 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 4e7ca5277bf1..cdaf6dfb824e 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -9,6 +9,7 @@ #include "intel_atomic.h" #include "intel_display.h" #include "intel_display_trace.h" +#include "intel_fb.h" #include "intel_mchbar_regs.h" #include "intel_wm.h" #include "skl_watermark.h" diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index e979786aa5cf..c9978bbd42a9 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -39,6 +39,7 @@ #include #include +#include "gem/i915_gem_object_types.h" #include "i915_config.h" #include "i9xx_plane_regs.h" #include "intel_atomic_plane.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 30a0a1d7f6f1..830b9eb60976 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -16,8 +16,8 @@ #include "i915_reg.h" #include "intel_alpm.h" #include "intel_crtc.h" -#include "intel_de.h" #include "intel_crtc_state_dump.h" +#include "intel_de.h" #include "intel_display_debugfs.h" #include "intel_display_debugfs_params.h" #include "intel_display_power.h" @@ -28,6 +28,7 @@ #include "intel_dp_link_training.h" #include "intel_dp_mst.h" #include "intel_drrs.h" +#include "intel_fb.h" #include "intel_fbc.h" #include "intel_fbdev.h" #include "intel_hdcp.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 4b8b7a86d02c..7cda490b231d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -44,7 +44,6 @@ #include #include -#include "gem/i915_gem_object_types.h" /* for to_intel_bo() */ #include "i915_vma.h" #include "i915_vma_types.h" #include "intel_bios.h" @@ -1491,8 +1490,6 @@ struct intel_plane { #define to_intel_framebuffer(fb) \ container_of_const((fb), struct intel_framebuffer, base) -#define intel_fb_obj(x) ((x) ? to_intel_bo((x)->obj[0]) : NULL) - struct intel_hdmi { i915_reg_t hdmi_reg; struct { diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 5be7bb43e2e0..d2ff21e98545 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -10,6 +10,7 @@ #include #include "gem/i915_gem_object.h" +#include "gem/i915_gem_object_types.h" #include "i915_drv.h" #include "intel_atomic_plane.h" #include "intel_display.h" @@ -2119,3 +2120,8 @@ intel_framebuffer_create(struct drm_i915_gem_object *obj, kfree(intel_fb); return ERR_PTR(ret); } + +struct drm_i915_gem_object *intel_fb_obj(const struct drm_framebuffer *fb) +{ + return fb ? to_intel_bo(fb->obj[0]) : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 10de437e8ef8..068f3aee99aa 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -96,4 +96,6 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb); unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier); +struct drm_i915_gem_object *intel_fb_obj(const struct drm_framebuffer *fb); + #endif /* __INTEL_FB_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 49a1ac4f5491..56bf8641459b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -45,6 +45,7 @@ #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" +#include "gem/i915_gem_object_types.h" #include "i915_drv.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index af4576dee92a..3c44a44cb8da 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -56,6 +56,7 @@ */ #include "gem/i915_gem_object_frontbuffer.h" +#include "gem/i915_gem_object_types.h" #include "i915_active.h" #include "i915_drv.h" #include "intel_display_trace.h" From 0fd1bf3ee4f8b7b82fd126ab1055e08b55fc9b4b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 26 Aug 2024 19:31:20 +0300 Subject: [PATCH 009/205] drm/i915/display: drop extra includes from intel_display_types.h Drop some unnecessary includes from intel_display_types.h. Reviewed-by: Luca Coelho Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/bf61599a9cafd9c674a23296eca305fcbf6f44c1.1724689818.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 7cda490b231d..733de5edcfdb 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -26,10 +26,8 @@ #ifndef __INTEL_DISPLAY_TYPES_H__ #define __INTEL_DISPLAY_TYPES_H__ -#include #include #include -#include #include #include @@ -38,7 +36,6 @@ #include #include #include -#include #include #include #include From fc9cb46bdca8747aedd86ce304caaddac6df07fd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Sep 2024 12:51:32 +0300 Subject: [PATCH 010/205] drm/i915/pciids: use designated initializers in INTEL_VGA_DEVICE() With IGT no longer using INTEL_VGA_DEVICE(), we can make it kernel specific and use designated initializers. Ditto for INTEL_QUANTA_VGA_DEVICE(). Remove the superfluous comments while at it. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/ce15f8f2a6b672155f9728c8e6a5f49d33fafd24.1725443418.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/intel/i915_pciids.h | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h index 2bf03ebfcf73..6a78df5687c5 100644 --- a/include/drm/intel/i915_pciids.h +++ b/include/drm/intel/i915_pciids.h @@ -25,27 +25,20 @@ #ifndef _I915_PCIIDS_H #define _I915_PCIIDS_H -/* - * A pci_device_id struct { - * __u32 vendor, device; - * __u32 subvendor, subdevice; - * __u32 class, class_mask; - * kernel_ulong_t driver_data; - * }; - * Don't use C99 here because "class" is reserved and we want to - * give userspace flexibility. - */ -#define INTEL_VGA_DEVICE(id, info) { \ - 0x8086, id, \ - ~0, ~0, \ - 0x030000, 0xff0000, \ - (unsigned long) info } +#ifdef __KERNEL__ +#define INTEL_VGA_DEVICE(_id, _info) { \ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, (_id)), \ + .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, \ + .driver_data = (kernel_ulong_t)(_info), \ +} -#define INTEL_QUANTA_VGA_DEVICE(info) { \ - 0x8086, 0x16a, \ - 0x152d, 0x8990, \ - 0x030000, 0xff0000, \ - (unsigned long) info } +#define INTEL_QUANTA_VGA_DEVICE(_info) { \ + .vendor = PCI_VENDOR_ID_INTEL, .device = 0x16a, \ + .subvendor = 0x152d, .subdevice = 0x8990, \ + .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16, \ + .driver_data = (kernel_ulong_t)(_info), \ +} +#endif #define INTEL_I810_IDS(MACRO__, ...) \ MACRO__(0x7121, ## __VA_ARGS__), /* I810 */ \ From a37c68dd80f9951bb48aa44094fce130197ce3a4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Sep 2024 12:51:33 +0300 Subject: [PATCH 011/205] drm/i915/pciids: separate ARL and MTL PCI IDs Avoid including PCI IDs for one platform to the PCI IDs of another. It's more clear to deal with them completely separately at the PCI ID macro level. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/b70af19ea017a76af4678d0a4ee8332253ee1f3b.1725443418.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_device.c | 1 + drivers/gpu/drm/i915/i915_pci.c | 1 + include/drm/intel/i915_pciids.h | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 1b46ba985580..408c76852495 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1318,6 +1318,7 @@ static const struct { INTEL_RPLU_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc), INTEL_RPLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc), INTEL_DG2_IDS(INTEL_DISPLAY_DEVICE, &dg2_desc), + INTEL_ARL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc), INTEL_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc), INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc), INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc), diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index d37bb3a704d0..617f411feb8c 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -870,6 +870,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &adl_p_info), INTEL_DG2_IDS(INTEL_VGA_DEVICE, &dg2_info), INTEL_ATS_M_IDS(INTEL_VGA_DEVICE, &ats_m_info), + INTEL_ARL_IDS(INTEL_VGA_DEVICE, &mtl_info), INTEL_MTL_IDS(INTEL_VGA_DEVICE, &mtl_info), {} }; diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h index 6a78df5687c5..cbb12fdbcb7f 100644 --- a/include/drm/intel/i915_pciids.h +++ b/include/drm/intel/i915_pciids.h @@ -764,15 +764,15 @@ INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \ INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) -/* MTL */ +/* ARL */ #define INTEL_ARL_IDS(MACRO__, ...) \ MACRO__(0x7D41, ## __VA_ARGS__), \ MACRO__(0x7D51, ## __VA_ARGS__), \ MACRO__(0x7D67, ## __VA_ARGS__), \ MACRO__(0x7DD1, ## __VA_ARGS__) +/* MTL */ #define INTEL_MTL_IDS(MACRO__, ...) \ - INTEL_ARL_IDS(MACRO__, ## __VA_ARGS__), \ MACRO__(0x7D40, ## __VA_ARGS__), \ MACRO__(0x7D45, ## __VA_ARGS__), \ MACRO__(0x7D55, ## __VA_ARGS__), \ From 138d2bda4eafc40066d913222e90a443764dc535 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Sep 2024 16:06:32 +0300 Subject: [PATCH 012/205] drm/i915/display: pass display to intel_crtc_for_pipe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the intel_crtc_for_pipe() struct drm_i915_private parameter to struct intel_display. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240904130633.3831492-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_wm.c | 15 ++++++++++----- .../gpu/drm/i915/display/intel_atomic_plane.c | 4 ++-- drivers/gpu/drm/i915/display/intel_cdclk.c | 6 ++++-- drivers/gpu/drm/i915/display/intel_crt.c | 3 ++- drivers/gpu/drm/i915/display/intel_crtc.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_crtc.h | 3 ++- drivers/gpu/drm/i915/display/intel_display.c | 17 ++++++++++------- .../gpu/drm/i915/display/intel_display_driver.c | 3 ++- .../gpu/drm/i915/display/intel_display_irq.c | 9 ++++++--- .../gpu/drm/i915/display/intel_display_trace.h | 15 ++++++++++----- drivers/gpu/drm/i915/display/intel_dpll.c | 3 ++- drivers/gpu/drm/i915/display/intel_dsb.c | 2 +- drivers/gpu/drm/i915/display/intel_fbc.c | 3 +-- drivers/gpu/drm/i915/display/intel_fdi.c | 10 ++++++---- .../gpu/drm/i915/display/intel_fifo_underrun.c | 15 ++++++++++----- drivers/gpu/drm/i915/display/intel_link_bw.c | 3 +-- .../gpu/drm/i915/display/intel_modeset_setup.c | 12 ++++++++---- .../gpu/drm/i915/display/intel_sprite_uapi.c | 3 ++- drivers/gpu/drm/i915/display/skl_watermark.c | 7 ++++--- 19 files changed, 87 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index cdaf6dfb824e..8442d75e5c28 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -724,10 +724,11 @@ static unsigned int g4x_tlb_miss_wa(int fifo_size, int width, int cpp) static void g4x_write_wm_values(struct drm_i915_private *dev_priv, const struct g4x_wm_values *wm) { + struct intel_display *display = &dev_priv->display; enum pipe pipe; for_each_pipe(dev_priv, pipe) - trace_g4x_wm(intel_crtc_for_pipe(dev_priv, pipe), wm); + trace_g4x_wm(intel_crtc_for_pipe(display, pipe), wm); intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), FW_WM(wm->sr.plane, SR) | @@ -756,10 +757,11 @@ static void g4x_write_wm_values(struct drm_i915_private *dev_priv, static void vlv_write_wm_values(struct drm_i915_private *dev_priv, const struct vlv_wm_values *wm) { + struct intel_display *display = &dev_priv->display; enum pipe pipe; for_each_pipe(dev_priv, pipe) { - trace_vlv_wm(intel_crtc_for_pipe(dev_priv, pipe), wm); + trace_vlv_wm(intel_crtc_for_pipe(display, pipe), wm); intel_uncore_write(&dev_priv->uncore, VLV_DDL(pipe), (wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) | @@ -2097,12 +2099,13 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) static struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915, enum i9xx_plane_id i9xx_plane) { + struct intel_display *display = &i915->display; struct intel_plane *plane; for_each_intel_plane(&i915->drm, plane) { if (plane->id == PLANE_PRIMARY && plane->i9xx_plane == i9xx_plane) - return intel_crtc_for_pipe(i915, plane->pipe); + return intel_crtc_for_pipe(display, plane->pipe); } return NULL; @@ -3725,6 +3728,7 @@ static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_plane *plane; struct intel_crtc *crtc; @@ -3732,7 +3736,7 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) for_each_intel_plane(&dev_priv->drm, plane) { struct intel_crtc *crtc = - intel_crtc_for_pipe(dev_priv, plane->pipe); + intel_crtc_for_pipe(display, plane->pipe); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane_state *plane_state = @@ -3880,6 +3884,7 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_plane *plane; struct intel_crtc *crtc; @@ -3887,7 +3892,7 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) for_each_intel_plane(&dev_priv->drm, plane) { struct intel_crtc *crtc = - intel_crtc_for_pipe(dev_priv, plane->pipe); + intel_crtc_for_pipe(display, plane->pipe); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane_state *plane_state = diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index c9978bbd42a9..928d985f9985 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -711,13 +711,13 @@ intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id) int intel_plane_atomic_check(struct intel_atomic_state *state, struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_plane_state *new_plane_state = intel_atomic_get_new_plane_state(state, plane); const struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); const struct intel_plane_state *new_primary_crtc_plane_state; - struct intel_crtc *crtc = intel_crtc_for_pipe(i915, plane->pipe); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index d6031419e32b..66964c7d2a2c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2039,6 +2039,7 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct intel_display *display = &dev_priv->display; int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; @@ -2064,7 +2065,7 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, intel_de_write(dev_priv, CDCLK_CTL, bxt_cdclk_ctl(dev_priv, cdclk_config, pipe)); if (pipe != INVALID_PIPE) - intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe)); + intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe)); } static void bxt_set_cdclk(struct drm_i915_private *dev_priv, @@ -3263,6 +3264,7 @@ static bool intel_cdclk_need_serialize(struct drm_i915_private *i915, int intel_modeset_calc_cdclk(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_cdclk_state *old_cdclk_state; struct intel_cdclk_state *new_cdclk_state; @@ -3309,7 +3311,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) struct intel_crtc_state *crtc_state; pipe = ilog2(new_cdclk_state->active_pipes); - crtc = intel_crtc_for_pipe(dev_priv, pipe); + crtc = intel_crtc_for_pipe(display, pipe); crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); if (IS_ERR(crtc_state)) diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 835c8b844494..fd78adbaadbe 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -694,6 +694,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) static enum drm_connector_status intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe) { + struct intel_display *display = to_intel_display(&crt->base); struct drm_device *dev = crt->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = (enum transcoder)pipe; @@ -734,7 +735,7 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe) TRANSCONF(dev_priv, cpu_transcoder)); /* Wait for next Vblank to substitue * border color for Color info */ - intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe)); + intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe)); st00 = intel_de_read8(dev_priv, _VGA_MSR_WRITE); status = ((st00 & (1 << 4)) != 0) ? connector_status_connected : diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 4218f746691e..aed3853952be 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -49,12 +49,12 @@ struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915) return to_intel_crtc(drm_crtc_from_index(&i915->drm, 0)); } -struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915, +struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display, enum pipe pipe) { struct intel_crtc *crtc; - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { if (crtc->pipe == pipe) return crtc; } @@ -70,7 +70,8 @@ void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc) void intel_wait_for_vblank_if_active(struct drm_i915_private *i915, enum pipe pipe) { - struct intel_crtc *crtc = intel_crtc_for_pipe(i915, pipe); + struct intel_display *display = &i915->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); if (crtc->active) intel_crtc_wait_for_next_vblank(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index b615b7ab5ccd..0de8c772df2e 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -15,6 +15,7 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; /* * FIXME: We should instead only take spinlocks once for the entire update @@ -43,7 +44,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_wait_for_vblank_workers(struct intel_atomic_state *state); struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915); -struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915, +struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display, enum pipe pipe); void intel_wait_for_vblank_if_active(struct drm_i915_private *i915, enum pipe pipe); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a734dbf937d0..b4ec9bf12aa7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -292,10 +292,10 @@ u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state) struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (intel_crtc_is_joiner_secondary(crtc_state)) - return intel_crtc_for_pipe(i915, joiner_primary_pipe(crtc_state)); + return intel_crtc_for_pipe(display, joiner_primary_pipe(crtc_state)); else return to_intel_crtc(crtc_state->uapi.crtc); } @@ -1678,6 +1678,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta static void hsw_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -1777,7 +1778,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, hsw_workaround_pipe = pipe_crtc_state->hsw_workaround_pipe; if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) { struct intel_crtc *wa_crtc = - intel_crtc_for_pipe(dev_priv, hsw_workaround_pipe); + intel_crtc_for_pipe(display, hsw_workaround_pipe); intel_crtc_wait_for_next_vblank(wa_crtc); intel_crtc_wait_for_next_vblank(wa_crtc); @@ -3987,7 +3988,7 @@ int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config) struct drm_display_mode * intel_encoder_current_mode(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc_state *crtc_state; struct drm_display_mode *mode; struct intel_crtc *crtc; @@ -3996,7 +3997,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder) if (!encoder->get_hw_state(encoder, &pipe)) return NULL; - crtc = intel_crtc_for_pipe(dev_priv, pipe); + crtc = intel_crtc_for_pipe(display, pipe); mode = kzalloc(sizeof(*mode), GFP_KERNEL); if (!mode) @@ -8258,7 +8259,8 @@ int intel_initial_commit(struct drm_device *dev) void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); enum transcoder cpu_transcoder = (enum transcoder)pipe; /* 640x480@60Hz, ~25175 kHz */ struct dpll clock = { @@ -8339,7 +8341,8 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); drm_dbg_kms(&dev_priv->drm, "disabling pipe %c due to force quirk\n", pipe_name(pipe)); diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 069426d9260b..e7670774ecd0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -168,10 +168,11 @@ static void intel_mode_config_cleanup(struct drm_i915_private *i915) static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_plane *plane; for_each_intel_plane(&dev_priv->drm, plane) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, + struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); plane->base.possible_crtcs = drm_crtc_mask(&crtc->base); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 52d31f736b7f..9c68c681eee3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -29,7 +29,8 @@ static void intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); drm_crtc_handle_vblank(&crtc->base); } @@ -307,7 +308,8 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, u32 crc2, u32 crc3, u32 crc4) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; u32 crcs[5] = { crc0, crc1, crc2, crc3, crc4 }; @@ -346,7 +348,8 @@ display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, static void flip_done_handler(struct drm_i915_private *i915, enum pipe pipe) { - struct intel_crtc *crtc = intel_crtc_for_pipe(i915, pipe); + struct intel_display *display = &i915->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); spin_lock(&i915->drm.event_lock); diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index c734ef1fba3c..7176eefaf505 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -141,7 +141,8 @@ TRACE_EVENT(intel_cpu_fifo_underrun, ), TP_fast_assign( - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); __assign_str(dev); __entry->pipe = pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); @@ -165,8 +166,9 @@ TRACE_EVENT(intel_pch_fifo_underrun, ), TP_fast_assign( + struct intel_display *display = &dev_priv->display; enum pipe pipe = pch_transcoder; - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); __assign_str(dev); __entry->pipe = pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); @@ -458,7 +460,8 @@ TRACE_EVENT(intel_fbc_activate, ), TP_fast_assign( - struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), + struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); __assign_str(dev); __assign_str(name); @@ -485,7 +488,8 @@ TRACE_EVENT(intel_fbc_deactivate, ), TP_fast_assign( - struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), + struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); __assign_str(dev); __assign_str(name); @@ -512,7 +516,8 @@ TRACE_EVENT(intel_fbc_nuke, ), TP_fast_assign( - struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), + struct intel_display *display = to_intel_display(plane->base.dev); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); __assign_str(dev); __assign_str(name); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 340dfce480b8..bc72d1c0cb41 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -2212,7 +2212,8 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, const struct dpll *dpll) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); struct intel_crtc_state *crtc_state; crtc_state = intel_crtc_state_alloc(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index da24e041d269..c39bae1be89e 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -763,7 +763,7 @@ void intel_dsb_cleanup(struct intel_dsb *dsb) void intel_dsb_irq_handler(struct intel_display *display, enum pipe pipe, enum intel_dsb_id dsb_id) { - struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(display->drm), pipe); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); u32 tmp, errors; tmp = intel_de_read_fw(display, DSB_INTERRUPT(pipe, dsb_id)); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index b53b38c2f19f..2e0863093cff 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1793,7 +1793,6 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work) { struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work); struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); mutex_lock(&fbc->lock); @@ -1806,7 +1805,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work) intel_fbc_deactivate(fbc, "FIFO underrun"); if (!fbc->flip_pending) - intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(i915, fbc->state.plane->pipe)); + intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, fbc->state.plane->pipe)); __intel_fbc_disable(fbc); out: mutex_unlock(&fbc->lock); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 222cd0e1a2bc..0168894e9cd1 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -137,6 +137,7 @@ void intel_fdi_link_train(struct intel_crtc *crtc, */ int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state; const struct intel_crtc_state *new_crtc_state; @@ -145,7 +146,7 @@ int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state) if (!IS_IVYBRIDGE(i915) || INTEL_NUM_PIPES(i915) != 3) return 0; - crtc = intel_crtc_for_pipe(i915, PIPE_C); + crtc = intel_crtc_for_pipe(display, PIPE_C); new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!new_crtc_state) return 0; @@ -157,7 +158,7 @@ int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state) if (!old_crtc_state->fdi_lanes) return 0; - crtc = intel_crtc_for_pipe(i915, PIPE_B); + crtc = intel_crtc_for_pipe(display, PIPE_B); new_crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); if (IS_ERR(new_crtc_state)) return PTR_ERR(new_crtc_state); @@ -184,6 +185,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, struct intel_crtc_state *pipe_config, enum pipe *pipe_to_reduce) { + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); struct drm_atomic_state *state = pipe_config->uapi.state; struct intel_crtc *other_crtc; @@ -223,7 +225,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, if (pipe_config->fdi_lanes <= 2) return 0; - other_crtc = intel_crtc_for_pipe(dev_priv, PIPE_C); + other_crtc = intel_crtc_for_pipe(display, PIPE_C); other_crtc_state = intel_atomic_get_crtc_state(state, other_crtc); if (IS_ERR(other_crtc_state)) @@ -244,7 +246,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, return -EINVAL; } - other_crtc = intel_crtc_for_pipe(dev_priv, PIPE_B); + other_crtc = intel_crtc_for_pipe(display, PIPE_B); other_crtc_state = intel_atomic_get_crtc_state(state, other_crtc); if (IS_ERR(other_crtc_state)) diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index 8949fbb1cc60..4ffbaf44c21b 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -57,6 +57,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) { + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; enum pipe pipe; @@ -64,7 +65,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) lockdep_assert_held(&dev_priv->irq_lock); for_each_pipe(dev_priv, pipe) { - crtc = intel_crtc_for_pipe(dev_priv, pipe); + crtc = intel_crtc_for_pipe(display, pipe); if (crtc->cpu_fifo_underrun_disabled) return false; @@ -75,6 +76,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) static bool cpt_can_enable_serr_int(struct drm_device *dev) { + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; struct intel_crtc *crtc; @@ -82,7 +84,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) lockdep_assert_held(&dev_priv->irq_lock); for_each_pipe(dev_priv, pipe) { - crtc = intel_crtc_for_pipe(dev_priv, pipe); + crtc = intel_crtc_for_pipe(display, pipe); if (crtc->pch_fifo_underrun_disabled) return false; @@ -282,8 +284,9 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable) { + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); bool old; lockdep_assert_held(&dev_priv->irq_lock); @@ -351,8 +354,9 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum pipe pch_transcoder, bool enable) { + struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = - intel_crtc_for_pipe(dev_priv, pch_transcoder); + intel_crtc_for_pipe(display, pch_transcoder); unsigned long flags; bool old; @@ -395,7 +399,8 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + struct intel_display *display = &dev_priv->display; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); u32 underruns = 0; /* We may be called too early in init, thanks BIOS! */ diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c index e7a9b860fac6..c87cd1d16d0a 100644 --- a/drivers/gpu/drm/i915/display/intel_link_bw.c +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c @@ -26,7 +26,6 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state, struct intel_link_bw_limits *limits) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); enum pipe pipe; limits->force_fec_pipes = 0; @@ -34,7 +33,7 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state, for_each_pipe(display, pipe) { const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, - intel_crtc_for_pipe(i915, pipe)); + intel_crtc_for_pipe(display, pipe)); if (state->base.duplicated && crtc_state) { limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16; diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index c2c3b3037938..1f57549fce00 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -222,6 +222,7 @@ static u8 get_transcoder_pipes(struct drm_i915_private *i915, static void get_portsync_pipes(struct intel_crtc *crtc, u8 *master_pipe_mask, u8 *slave_pipes_mask) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -244,7 +245,7 @@ static void get_portsync_pipes(struct intel_crtc *crtc, *master_pipe_mask = get_transcoder_pipes(i915, BIT(master_transcoder)); drm_WARN_ON(&i915->drm, !is_power_of_2(*master_pipe_mask)); - master_crtc = intel_crtc_for_pipe(i915, ffs(*master_pipe_mask) - 1); + master_crtc = intel_crtc_for_pipe(display, ffs(*master_pipe_mask) - 1); master_crtc_state = to_intel_crtc_state(master_crtc->base.state); *slave_pipes_mask = get_transcoder_pipes(i915, master_crtc_state->sync_mode_slaves_mask); } @@ -376,6 +377,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state static void intel_sanitize_plane_mapping(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_crtc *crtc; if (DISPLAY_VER(i915) >= 4) @@ -397,7 +399,7 @@ intel_sanitize_plane_mapping(struct drm_i915_private *i915) "[PLANE:%d:%s] attached to the wrong pipe, disabling plane\n", plane->base.base.id, plane->base.name); - plane_crtc = intel_crtc_for_pipe(i915, pipe); + plane_crtc = intel_crtc_for_pipe(display, pipe); intel_plane_disable_noatomic(plane_crtc, plane); } } @@ -663,6 +665,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) /* FIXME read out full plane state for all planes */ static void readout_plane_state(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_plane *plane; struct intel_crtc *crtc; @@ -675,7 +678,7 @@ static void readout_plane_state(struct drm_i915_private *i915) visible = plane->get_hw_state(plane, &pipe); - crtc = intel_crtc_for_pipe(i915, pipe); + crtc = intel_crtc_for_pipe(display, pipe); crtc_state = to_intel_crtc_state(crtc->base.state); intel_set_plane_visible(crtc_state, plane_state, visible); @@ -696,6 +699,7 @@ static void readout_plane_state(struct drm_i915_private *i915) static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(i915->display.cdclk.obj.state); struct intel_dbuf_state *dbuf_state = @@ -744,7 +748,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) pipe = 0; if (encoder->get_hw_state(encoder, &pipe)) { - crtc = intel_crtc_for_pipe(i915, pipe); + crtc = intel_crtc_for_pipe(display, pipe); crtc_state = to_intel_crtc_state(crtc->base.state); encoder->base.crtc = &crtc->base; diff --git a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c index 4853c4806004..1d0b84b464c1 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c +++ b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c @@ -42,6 +42,7 @@ static void intel_plane_set_ckey(struct intel_plane_state *plane_state, int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); struct drm_intel_sprite_colorkey *set = data; struct drm_plane *plane; @@ -100,7 +101,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, */ if (!ret && has_dst_key_in_primary_plane(dev_priv)) { struct intel_crtc *crtc = - intel_crtc_for_pipe(dev_priv, + intel_crtc_for_pipe(display, to_intel_plane(plane)->pipe); plane_state = drm_atomic_get_plane_state(state, diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index e955e399b390..29835b638495 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3600,6 +3600,7 @@ static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state, const struct intel_dbuf_state *dbuf_state) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *i915 = to_i915(state->base.dev); enum pipe pipe = ffs(dbuf_state->active_pipes) - 1; const struct intel_crtc_state *new_crtc_state; @@ -3608,7 +3609,7 @@ static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state, drm_WARN_ON(&i915->drm, !dbuf_state->joined_mbus); drm_WARN_ON(&i915->drm, !is_power_of_2(dbuf_state->active_pipes)); - crtc = intel_crtc_for_pipe(i915, pipe); + crtc = intel_crtc_for_pipe(display, pipe); new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (new_crtc_state && !intel_crtc_needs_modeset(new_crtc_state)) @@ -3670,7 +3671,7 @@ void intel_dbuf_mbus_pre_ddb_update(struct intel_atomic_state *state) void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_dbuf_state *new_dbuf_state = intel_atomic_get_new_dbuf_state(state); const struct intel_dbuf_state *old_dbuf_state = @@ -3689,7 +3690,7 @@ void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state) intel_dbuf_mbus_join_update(state, pipe); if (pipe != INVALID_PIPE) { - struct intel_crtc *crtc = intel_crtc_for_pipe(i915, pipe); + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); intel_crtc_wait_for_next_vblank(crtc); } From 307fa415771fab32b99965395819c67cbca6efa0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Sep 2024 16:06:33 +0300 Subject: [PATCH 013/205] drm/i915/display: convert intel_display_trace.h to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Going forward, struct intel_display shall replace struct drm_i915_private as the main display device data pointer type. Convert intel_display_trace.h to struct intel_display. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240904130633.3831492-2-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_wm.c | 3 +- .../drm/i915/display/intel_display_trace.h | 44 +++++++++---------- .../drm/i915/display/intel_fifo_underrun.c | 15 ++++--- .../gpu/drm/i915/display/intel_frontbuffer.c | 4 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 8442d75e5c28..5b21604312fd 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -145,6 +145,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) { + struct intel_display *display = &dev_priv->display; bool was_enabled; u32 val; @@ -186,7 +187,7 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl return false; } - trace_intel_memory_cxsr(dev_priv, was_enabled, enable); + trace_intel_memory_cxsr(display, was_enabled, enable); drm_dbg_kms(&dev_priv->drm, "memory self-refresh is %s (was %s)\n", str_enabled_disabled(enable), diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 7176eefaf505..fc28d34b5eef 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -18,7 +18,7 @@ #include "intel_display_types.h" #include "intel_vblank.h" -#define __dev_name_i915(i915) dev_name((i915)->drm.dev) +#define __dev_name_display(display) dev_name((display)->drm->dev) #define __dev_name_kms(obj) dev_name((obj)->base.dev->dev) TRACE_EVENT(intel_pipe_enable, @@ -32,10 +32,10 @@ TRACE_EVENT(intel_pipe_enable, __field(enum pipe, pipe) ), TP_fast_assign( - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc *it__; __assign_str(dev); - for_each_intel_crtc(&dev_priv->drm, it__) { + for_each_intel_crtc(display->drm, it__) { __entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__); __entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__); } @@ -61,10 +61,10 @@ TRACE_EVENT(intel_pipe_disable, ), TP_fast_assign( - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc *it__; __assign_str(dev); - for_each_intel_crtc(&dev_priv->drm, it__) { + for_each_intel_crtc(display->drm, it__) { __entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__); __entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__); } @@ -130,18 +130,17 @@ TRACE_EVENT(intel_pipe_crc, ); TRACE_EVENT(intel_cpu_fifo_underrun, - TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pipe), - TP_ARGS(dev_priv, pipe), + TP_PROTO(struct intel_display *display, enum pipe pipe), + TP_ARGS(display, pipe), TP_STRUCT__entry( - __string(dev, __dev_name_i915(dev_priv)) + __string(dev, __dev_name_display(display)) __field(enum pipe, pipe) __field(u32, frame) __field(u32, scanline) ), TP_fast_assign( - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); __assign_str(dev); __entry->pipe = pipe; @@ -155,18 +154,17 @@ TRACE_EVENT(intel_cpu_fifo_underrun, ); TRACE_EVENT(intel_pch_fifo_underrun, - TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pch_transcoder), - TP_ARGS(dev_priv, pch_transcoder), + TP_PROTO(struct intel_display *display, enum pipe pch_transcoder), + TP_ARGS(display, pch_transcoder), TP_STRUCT__entry( - __string(dev, __dev_name_i915(dev_priv)) + __string(dev, __dev_name_display(display)) __field(enum pipe, pipe) __field(u32, frame) __field(u32, scanline) ), TP_fast_assign( - struct intel_display *display = &dev_priv->display; enum pipe pipe = pch_transcoder; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); __assign_str(dev); @@ -181,11 +179,11 @@ TRACE_EVENT(intel_pch_fifo_underrun, ); TRACE_EVENT(intel_memory_cxsr, - TP_PROTO(struct drm_i915_private *dev_priv, bool old, bool new), - TP_ARGS(dev_priv, old, new), + TP_PROTO(struct intel_display *display, bool old, bool new), + TP_ARGS(display, old, new), TP_STRUCT__entry( - __string(dev, __dev_name_i915(dev_priv)) + __string(dev, __dev_name_display(display)) __array(u32, frame, 3) __array(u32, scanline, 3) __field(bool, old) @@ -195,7 +193,7 @@ TRACE_EVENT(intel_memory_cxsr, TP_fast_assign( struct intel_crtc *crtc; __assign_str(dev); - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { __entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc); __entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc); } @@ -657,12 +655,12 @@ TRACE_EVENT(intel_pipe_update_end, ); TRACE_EVENT(intel_frontbuffer_invalidate, - TP_PROTO(struct drm_i915_private *i915, + TP_PROTO(struct intel_display *display, unsigned int frontbuffer_bits, unsigned int origin), - TP_ARGS(i915, frontbuffer_bits, origin), + TP_ARGS(display, frontbuffer_bits, origin), TP_STRUCT__entry( - __string(dev, __dev_name_i915(i915)) + __string(dev, __dev_name_display(display)) __field(unsigned int, frontbuffer_bits) __field(unsigned int, origin) ), @@ -678,12 +676,12 @@ TRACE_EVENT(intel_frontbuffer_invalidate, ); TRACE_EVENT(intel_frontbuffer_flush, - TP_PROTO(struct drm_i915_private *i915, + TP_PROTO(struct intel_display *display, unsigned int frontbuffer_bits, unsigned int origin), - TP_ARGS(i915, frontbuffer_bits, origin), + TP_ARGS(display, frontbuffer_bits, origin), TP_STRUCT__entry( - __string(dev, __dev_name_i915(i915)) + __string(dev, __dev_name_display(display)) __field(unsigned int, frontbuffer_bits) __field(unsigned int, origin) ), diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index 4ffbaf44c21b..745ce22afb89 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -95,6 +95,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); i915_reg_t reg = PIPESTAT(dev_priv, crtc->pipe); u32 enable_mask; @@ -108,7 +109,7 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) intel_de_write(dev_priv, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); intel_de_posting_read(dev_priv, reg); - trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe); + trace_intel_cpu_fifo_underrun(display, crtc->pipe); drm_err(&dev_priv->drm, "pipe %c underrun\n", pipe_name(crtc->pipe)); } @@ -149,6 +150,7 @@ static void ilk_set_fifo_underrun_reporting(struct drm_device *dev, static void ivb_check_fifo_underruns(struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 err_int = intel_de_read(dev_priv, GEN7_ERR_INT); @@ -161,7 +163,7 @@ static void ivb_check_fifo_underruns(struct intel_crtc *crtc) intel_de_write(dev_priv, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); intel_de_posting_read(dev_priv, GEN7_ERR_INT); - trace_intel_cpu_fifo_underrun(dev_priv, pipe); + trace_intel_cpu_fifo_underrun(display, pipe); drm_err(&dev_priv->drm, "fifo underrun on pipe %c\n", pipe_name(pipe)); } @@ -237,6 +239,7 @@ static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pch_transcoder = crtc->pipe; u32 serr_int = intel_de_read(dev_priv, SERR_INT); @@ -250,7 +253,7 @@ static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc) SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); intel_de_posting_read(dev_priv, SERR_INT); - trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder); + trace_intel_pch_fifo_underrun(display, pch_transcoder); drm_err(&dev_priv->drm, "pch fifo underrun on pch transcoder %c\n", pipe_name(pch_transcoder)); } @@ -432,7 +435,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, } if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) { - trace_intel_cpu_fifo_underrun(dev_priv, pipe); + trace_intel_cpu_fifo_underrun(display, pipe); if (DISPLAY_VER(dev_priv) >= 11) drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun: %s%s%s%s\n", @@ -460,9 +463,11 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, enum pipe pch_transcoder) { + struct intel_display *display = &dev_priv->display; + if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, false)) { - trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder); + trace_intel_pch_fifo_underrun(display, pch_transcoder); drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n", pipe_name(pch_transcoder)); } diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 3c44a44cb8da..e56d596485c3 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -94,7 +94,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915, if (!frontbuffer_bits) return; - trace_intel_frontbuffer_flush(i915, frontbuffer_bits, origin); + trace_intel_frontbuffer_flush(display, frontbuffer_bits, origin); might_sleep(); intel_td_flush(i915); @@ -184,7 +184,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, spin_unlock(&i915->display.fb_tracking.lock); } - trace_intel_frontbuffer_invalidate(i915, frontbuffer_bits, origin); + trace_intel_frontbuffer_invalidate(display, frontbuffer_bits, origin); might_sleep(); intel_psr_invalidate(display, frontbuffer_bits, origin); From c96c834836478b3a202551074321509c2a9607a7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Sep 2024 17:52:18 +0300 Subject: [PATCH 014/205] drm/i915: use IS_ENABLED() instead of defined() on config options Prefer IS_ENABLED() instead of defined() for checking whether a kconfig option is enabled. Reviewed-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240904145218.3902145-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_irq.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_tunnel.h | 2 +- drivers/gpu/drm/i915/gem/i915_gem_pm.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_huc.c | 2 +- drivers/gpu/drm/i915/i915_trace.h | 2 +- drivers/gpu/drm/i915/i915_utils.h | 2 +- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 9c68c681eee3..8f13f148c73e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -301,7 +301,7 @@ void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv) spin_unlock_irq(&dev_priv->irq_lock); } -#if defined(CONFIG_DEBUG_FS) +#if IS_ENABLED(CONFIG_DEBUG_FS) static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe, u32 crc0, u32 crc1, diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h index a0c00b7d3303..e9314cf25a19 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h @@ -20,7 +20,7 @@ struct intel_dp; struct intel_encoder; struct intel_link_bw_limits; -#if defined(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915) +#if IS_ENABLED(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915) int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx); void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c index 3b27218aabe2..900c08337942 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c @@ -13,7 +13,7 @@ #include "i915_driver.h" #include "i915_drv.h" -#if defined(CONFIG_X86) +#if IS_ENABLED(CONFIG_X86) #include #else #define wbinvd_on_all_cpus() \ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c index 23f54c84cbab..fe53e8eccf4b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c @@ -145,7 +145,7 @@ static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, bool * an end user should hit the timeout is in case of extreme thermal throttling. * And a system that is that hot during boot is probably dead anyway! */ -#if defined(CONFIG_DRM_I915_DEBUG_GEM) +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) #define GUC_LOAD_RETRY_LIMIT 20 #else #define GUC_LOAD_RETRY_LIMIT 3 diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index bf16351c9349..222c95f62156 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -14,7 +14,7 @@ #include "intel_guc_log.h" #include "intel_guc_print.h" -#if defined(CONFIG_DRM_I915_DEBUG_GUC) +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC) #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M #define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_16M #define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c index 2d9152eb7282..d7ac31c3254c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -455,7 +455,7 @@ static const char *auth_mode_string(struct intel_huc *huc, * an end user should hit the timeout is in case of extreme thermal throttling. * And a system that is that hot during boot is probably dead anyway! */ -#if defined(CONFIG_DRM_I915_DEBUG_GEM) +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) #define HUC_LOAD_RETRY_LIMIT 20 #else #define HUC_LOAD_RETRY_LIMIT 3 diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index ce1cbee1b39d..09d89bdf82f4 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -322,7 +322,7 @@ DEFINE_EVENT(i915_request, i915_request_add, TP_ARGS(rq) ); -#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) +#if IS_ENABLED(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) DEFINE_EVENT(i915_request, i915_request_guc_submit, TP_PROTO(struct i915_request *rq), TP_ARGS(rq) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 71bdc89bd621..609214231ffc 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -270,7 +270,7 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms) #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000) /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */ -#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG) && IS_ENABLED(CONFIG_PREEMPT_COUNT) # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) #else # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0) diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 91794ca17a58..70f3d7bf47d0 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -137,7 +137,7 @@ static const struct intel_device_info mock_info = { struct drm_i915_private *mock_gem_device(void) { -#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU) +#if IS_ENABLED(CONFIG_IOMMU_API) && IS_ENABLED(CONFIG_INTEL_IOMMU) static struct dev_iommu fake_iommu = { .priv = (void *)-1 }; #endif struct drm_i915_private *i915; @@ -153,7 +153,7 @@ struct drm_i915_private *mock_gem_device(void) dev_set_name(&pdev->dev, "mock"); dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); -#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU) +#if IS_ENABLED(CONFIG_IOMMU_API) && IS_ENABLED(CONFIG_INTEL_IOMMU) /* HACK to disable iommu for the fake device; force identity mapping */ pdev->dev.iommu = &fake_iommu; #endif From f5d2a0e464b117b99d16e92e21f2a234a3a4076e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Sep 2024 15:53:01 +0300 Subject: [PATCH 015/205] drm/i915/display: use to_intel_display() global state macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert intel_atomic_get_{old,new}_cdclk_state() and intel_atomic_get_{old,new}_dbuf_state() to use to_intel_display() instead of to_i915(). Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240904125301.3813721-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_cdclk.h | 4 ++-- drivers/gpu/drm/i915/display/skl_watermark.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index cfdcdec07a4d..1fe445a3a30b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -88,9 +88,9 @@ intel_atomic_get_cdclk_state(struct intel_atomic_state *state); container_of_const((global_state), struct intel_cdclk_state, base) #define intel_atomic_get_old_cdclk_state(state) \ - to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj)) + to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->cdclk.obj)) #define intel_atomic_get_new_cdclk_state(state) \ - to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj)) + to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->cdclk.obj)) int intel_cdclk_init(struct drm_i915_private *dev_priv); void intel_cdclk_debugfs_register(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h index 78b121941237..e73baec94873 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.h +++ b/drivers/gpu/drm/i915/display/skl_watermark.h @@ -73,9 +73,9 @@ intel_atomic_get_dbuf_state(struct intel_atomic_state *state); container_of_const((global_state), struct intel_dbuf_state, base) #define intel_atomic_get_old_dbuf_state(state) \ - to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.dbuf.obj)) + to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) #define intel_atomic_get_new_dbuf_state(state) \ - to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->display.dbuf.obj)) + to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) int intel_dbuf_init(struct drm_i915_private *i915); int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, From 54df34c5a2439b481f066476e67bfa21a0a640e5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 5 Sep 2024 14:25:19 +0300 Subject: [PATCH 016/205] drm/i915/bios: fix printk format width s/0x04%x/0x%04x/ to use 0 prefixed width 4 instead of printing 04 verbatim. Fixes: 51f5748179d4 ("drm/i915/bios: create fake child devices on missing VBT") Cc: stable@vger.kernel.org # v5.13+ Reviewed-by: Vandita Kulkarni Link: https://patchwork.freedesktop.org/patch/msgid/20240905112519.4186408-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index cd32c9cd38a9..daa4b9535123 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2949,7 +2949,7 @@ init_vbt_missing_defaults(struct intel_display *display) list_add_tail(&devdata->node, &display->vbt.display_devices); drm_dbg_kms(display->drm, - "Generating default VBT child device with type 0x04%x on port %c\n", + "Generating default VBT child device with type 0x%04x on port %c\n", child->device_type, port_name(port)); } From d04d2348f5aa891a677424a88c690ae47cb05c6f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 9 Sep 2024 16:56:27 +0300 Subject: [PATCH 017/205] drm/i915/dp: Dump the LTTPR PHY descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dump the descriptor of the detected LTTPRs in non-transparent mode to help the debugging related to LTTPRs easier. v2: Use drm_dp_dump_lttpr_desc() instead of the driver specific equivalent. v3: Add empty line between license and header section. (Ankit) v4: Don't include drm_dp_helper.h twice. (Jani) Cc: Jani Nikula Reviewed-by: Ville Syrjälä # v1 Reviewed-by: Ankit Nautiyal Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240909135627.2926906-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index f45797c1a205..abe7b9c035d2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -210,8 +210,10 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd); - for (i = 0; i < lttpr_count; i++) + for (i = 0; i < lttpr_count; i++) { intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i)); + drm_dp_dump_lttpr_desc(&intel_dp->aux, DP_PHY_LTTPR(i)); + } return lttpr_count; } From 12f01766537a44104b1a43bfa5b16fccadad4aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 6 Sep 2024 10:00:30 +0300 Subject: [PATCH 018/205] drm/i915/display: Handle MST connector in intel_attached_dp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Connector->encoder might be null for MST connector. Take this into account in intel_attached_dp. Signed-off-by: Jouni Högander Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240906070033.289015-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 733de5edcfdb..000ab373c887 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1913,7 +1913,10 @@ static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder) static inline struct intel_dp *intel_attached_dp(struct intel_connector *connector) { - return enc_to_intel_dp(intel_attached_encoder(connector)); + if (connector->mst_port) + return connector->mst_port; + else + return enc_to_intel_dp(intel_attached_encoder(connector)); } static inline bool intel_encoder_is_dp(struct intel_encoder *encoder) From 414c4eb5d706e717ae5901852d3a4096d8a07f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 6 Sep 2024 10:00:31 +0300 Subject: [PATCH 019/205] drm/i915/display: Use intel_attached_dp instead of local implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Link training code contains local "connector to intel_dp" implementation. This was added due to missing MST handling in intel_attached_dp. Missing MST support is now fixed in intel_attached_dp. We can now change link training code to use that instead of local intel_connector_to_intel_dp. Signed-off-by: Jouni Högander Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240906070033.289015-3-jouni.hogander@intel.com --- .../drm/i915/display/intel_dp_link_training.c | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index abe7b9c035d2..397cc4ebae52 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1681,19 +1681,11 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp, lt_dbg(intel_dp, DP_PHY_DPRX, "DP2.0 SDP CRC16 for 128b/132b enabled\n"); } -static struct intel_dp *intel_connector_to_intel_dp(struct intel_connector *connector) -{ - if (connector->mst_port) - return connector->mst_port; - else - return enc_to_intel_dp(intel_attached_encoder(connector)); -} - static int i915_dp_force_link_rate_show(struct seq_file *m, void *data) { struct intel_connector *connector = to_intel_connector(m->private); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int current_rate = -1; int force_rate; int err; @@ -1764,7 +1756,7 @@ static ssize_t i915_dp_force_link_rate_write(struct file *file, struct seq_file *m = file->private_data; struct intel_connector *connector = to_intel_connector(m->private); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int rate; int err; @@ -1791,7 +1783,7 @@ static int i915_dp_force_lane_count_show(struct seq_file *m, void *data) { struct intel_connector *connector = to_intel_connector(m->private); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int current_lane_count = -1; int force_lane_count; int err; @@ -1866,7 +1858,7 @@ static ssize_t i915_dp_force_lane_count_write(struct file *file, struct seq_file *m = file->private_data; struct intel_connector *connector = to_intel_connector(m->private); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int lane_count; int err; @@ -1893,7 +1885,7 @@ static int i915_dp_max_link_rate_show(void *data, u64 *val) { struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -1912,7 +1904,7 @@ static int i915_dp_max_lane_count_show(void *data, u64 *val) { struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -1931,7 +1923,7 @@ static int i915_dp_force_link_training_failure_show(void *data, u64 *val) { struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -1949,7 +1941,7 @@ static int i915_dp_force_link_training_failure_write(void *data, u64 val) { struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; if (val > 2) @@ -1973,7 +1965,7 @@ static int i915_dp_force_link_retrain_show(void *data, u64 *val) { struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -1991,7 +1983,7 @@ static int i915_dp_force_link_retrain_write(void *data, u64 val) { struct intel_connector *connector = to_intel_connector(data); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); @@ -2014,7 +2006,7 @@ static int i915_dp_link_retrain_disabled_show(struct seq_file *m, void *data) { struct intel_connector *connector = to_intel_connector(m->private); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); int err; err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); From 91463d74b1318d3513bc06f9da179517505057a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 6 Sep 2024 10:00:32 +0300 Subject: [PATCH 020/205] drm/i915/psr: Add connector debugfs files for MST connector as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Connector debugfs files are currently not add for MST connector. We can now add them as we have taken into account possibility to have NULL in connector->encoder in intel_attached_dp. v2: remove TODO comment Signed-off-by: Jouni Högander Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240906070033.289015-4-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index b30fa067ce6e..581c409ce730 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -3840,10 +3840,8 @@ void intel_psr_connector_debugfs_add(struct intel_connector *connector) struct drm_i915_private *i915 = to_i915(connector->base.dev); struct dentry *root = connector->base.debugfs_entry; - /* TODO: Add support for MST connectors as well. */ - if ((connector->base.connector_type != DRM_MODE_CONNECTOR_eDP && - connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) || - connector->mst_port) + if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP && + connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) return; debugfs_create_file("i915_psr_sink_status", 0444, root, From a2d98feb4b0013ef4f9db0d8f642a8ac1f5ecbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 6 Sep 2024 10:00:33 +0300 Subject: [PATCH 021/205] drm/i915/psr: Do not wait for PSR being idle on on Panel Replay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We do not have ALPM on DP Panel Replay. Due to this SRD_STATUS[SRD State] doesn't change from SRDENT_ON after Panel Replay is enabled until it gets disabled. On eDP Panel Replay DEEP_SLEEP is not reached. _psr2_ready_for_pipe_update_locked is waiting DEEP_SLEEP bit getting reset. Take these into account in Panel Replay code by not waiting PSR getting idle after enabling VBI. Fixes: 29fb595d4875 ("drm/i915/psr: Panel replay uses SRD_STATUS to track it's status") Cc: Animesh Manna Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20240906070033.289015-5-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 581c409ce730..1a4ef231a53c 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2786,13 +2786,6 @@ static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp) EDP_PSR_STATUS_STATE_MASK, 50); } -static int _panel_replay_ready_for_pipe_update_locked(struct intel_dp *intel_dp) -{ - return intel_dp_is_edp(intel_dp) ? - _psr2_ready_for_pipe_update_locked(intel_dp) : - _psr1_ready_for_pipe_update_locked(intel_dp); -} - /** * intel_psr_wait_for_idle_locked - wait for PSR be ready for a pipe update * @new_crtc_state: new CRTC state @@ -2815,12 +2808,10 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat lockdep_assert_held(&intel_dp->psr.lock); - if (!intel_dp->psr.enabled) + if (!intel_dp->psr.enabled || intel_dp->psr.panel_replay_enabled) continue; - if (intel_dp->psr.panel_replay_enabled) - ret = _panel_replay_ready_for_pipe_update_locked(intel_dp); - else if (intel_dp->psr.sel_update_enabled) + if (intel_dp->psr.sel_update_enabled) ret = _psr2_ready_for_pipe_update_locked(intel_dp); else ret = _psr1_ready_for_pipe_update_locked(intel_dp); From 25dd5e9801cc001d7af8a1b191a2398adfc02c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 6 Sep 2024 17:33:01 +0300 Subject: [PATCH 022/205] drm/i915/cdclk: Add missing braces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodingStyle says when one branch of an if ladder is braced then all of them should be. Make it so. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240906143306.15937-2-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_cdclk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 66964c7d2a2c..9d870d15d888 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2053,8 +2053,9 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, dg2_cdclk_squash_program(dev_priv, 0); icl_cdclk_pll_update(dev_priv, vco); - } else + } else { bxt_cdclk_pll_update(dev_priv, vco); + } if (HAS_CDCLK_SQUASH(dev_priv)) { u16 waveform = cdclk_squash_waveform(dev_priv, cdclk); From d34927acff915017504c2fb9563c3eec1ef39a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 6 Sep 2024 17:33:02 +0300 Subject: [PATCH 023/205] drm/i915/cdclk: Convert CDCLK code to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the CDCLK code to use it (as much as possible at this stage). v2: Add local 'display' variable to __intel_display_device_info_runtime_init() (Jani) Simplify the to_intel_display(crtc_state) stuff (Jani) Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240906143306.15937-3-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_cdclk.c | 1167 +++++++++-------- drivers/gpu/drm/i915/display/intel_cdclk.h | 24 +- .../drm/i915/display/intel_display_debugfs.c | 2 +- .../drm/i915/display/intel_display_device.c | 3 +- .../drm/i915/display/intel_display_driver.c | 17 +- .../drm/i915/display/intel_display_power.c | 35 +- .../i915/display/intel_display_power_well.c | 9 +- drivers/gpu/drm/i915/display/skl_watermark.c | 3 +- 8 files changed, 657 insertions(+), 603 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 9d870d15d888..fa1c2012b10c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -113,81 +113,81 @@ */ struct intel_cdclk_funcs { - void (*get_cdclk)(struct drm_i915_private *i915, + void (*get_cdclk)(struct intel_display *display, struct intel_cdclk_config *cdclk_config); - void (*set_cdclk)(struct drm_i915_private *i915, + void (*set_cdclk)(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe); int (*modeset_calc_cdclk)(struct intel_atomic_state *state); u8 (*calc_voltage_level)(int cdclk); }; -void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, +void intel_cdclk_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - dev_priv->display.funcs.cdclk->get_cdclk(dev_priv, cdclk_config); + display->funcs.cdclk->get_cdclk(display, cdclk_config); } -static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv, +static void intel_cdclk_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { - dev_priv->display.funcs.cdclk->set_cdclk(dev_priv, cdclk_config, pipe); + display->funcs.cdclk->set_cdclk(display, cdclk_config, pipe); } static int intel_cdclk_modeset_calc_cdclk(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(state); + return display->funcs.cdclk->modeset_calc_cdclk(state); } -static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv, +static u8 intel_cdclk_calc_voltage_level(struct intel_display *display, int cdclk) { - return dev_priv->display.funcs.cdclk->calc_voltage_level(cdclk); + return display->funcs.cdclk->calc_voltage_level(cdclk); } -static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv, +static void fixed_133mhz_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { cdclk_config->cdclk = 133333; } -static void fixed_200mhz_get_cdclk(struct drm_i915_private *dev_priv, +static void fixed_200mhz_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { cdclk_config->cdclk = 200000; } -static void fixed_266mhz_get_cdclk(struct drm_i915_private *dev_priv, +static void fixed_266mhz_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { cdclk_config->cdclk = 266667; } -static void fixed_333mhz_get_cdclk(struct drm_i915_private *dev_priv, +static void fixed_333mhz_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { cdclk_config->cdclk = 333333; } -static void fixed_400mhz_get_cdclk(struct drm_i915_private *dev_priv, +static void fixed_400mhz_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { cdclk_config->cdclk = 400000; } -static void fixed_450mhz_get_cdclk(struct drm_i915_private *dev_priv, +static void fixed_450mhz_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { cdclk_config->cdclk = 450000; } -static void i85x_get_cdclk(struct drm_i915_private *dev_priv, +static void i85x_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); u16 hpllcc = 0; /* @@ -226,10 +226,10 @@ static void i85x_get_cdclk(struct drm_i915_private *dev_priv, } } -static void i915gm_get_cdclk(struct drm_i915_private *dev_priv, +static void i915gm_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); u16 gcfgc = 0; pci_read_config_word(pdev, GCFGC, &gcfgc); @@ -250,10 +250,10 @@ static void i915gm_get_cdclk(struct drm_i915_private *dev_priv, } } -static void i945gm_get_cdclk(struct drm_i915_private *dev_priv, +static void i945gm_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); u16 gcfgc = 0; pci_read_config_word(pdev, GCFGC, &gcfgc); @@ -274,7 +274,7 @@ static void i945gm_get_cdclk(struct drm_i915_private *dev_priv, } } -static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv) +static unsigned int intel_hpll_vco(struct intel_display *display) { static const unsigned int blb_vco[8] = { [0] = 3200000, @@ -313,6 +313,7 @@ static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv) [4] = 2666667, [5] = 4266667, }; + struct drm_i915_private *dev_priv = to_i915(display->drm); const unsigned int *vco_table; unsigned int vco; u8 tmp = 0; @@ -331,23 +332,23 @@ static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv) else return 0; - tmp = intel_de_read(dev_priv, + tmp = intel_de_read(display, IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO); vco = vco_table[tmp & 0x7]; if (vco == 0) - drm_err(&dev_priv->drm, "Bad HPLL VCO (HPLLVCO=0x%02x)\n", + drm_err(display->drm, "Bad HPLL VCO (HPLLVCO=0x%02x)\n", tmp); else - drm_dbg_kms(&dev_priv->drm, "HPLL VCO %u kHz\n", vco); + drm_dbg_kms(display->drm, "HPLL VCO %u kHz\n", vco); return vco; } -static void g33_get_cdclk(struct drm_i915_private *dev_priv, +static void g33_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); static const u8 div_3200[] = { 12, 10, 8, 7, 5, 16 }; static const u8 div_4000[] = { 14, 12, 10, 8, 6, 20 }; static const u8 div_4800[] = { 20, 14, 12, 10, 8, 24 }; @@ -356,7 +357,7 @@ static void g33_get_cdclk(struct drm_i915_private *dev_priv, unsigned int cdclk_sel; u16 tmp = 0; - cdclk_config->vco = intel_hpll_vco(dev_priv); + cdclk_config->vco = intel_hpll_vco(display); pci_read_config_word(pdev, GCFGC, &tmp); @@ -387,16 +388,16 @@ static void g33_get_cdclk(struct drm_i915_private *dev_priv, return; fail: - drm_err(&dev_priv->drm, + drm_err(display->drm, "Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n", cdclk_config->vco, tmp); cdclk_config->cdclk = 190476; } -static void pnv_get_cdclk(struct drm_i915_private *dev_priv, +static void pnv_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); u16 gcfgc = 0; pci_read_config_word(pdev, GCFGC, &gcfgc); @@ -415,7 +416,7 @@ static void pnv_get_cdclk(struct drm_i915_private *dev_priv, cdclk_config->cdclk = 200000; break; default: - drm_err(&dev_priv->drm, + drm_err(display->drm, "Unknown pnv display core clock 0x%04x\n", gcfgc); fallthrough; case GC_DISPLAY_CLOCK_133_MHZ_PNV: @@ -427,10 +428,10 @@ static void pnv_get_cdclk(struct drm_i915_private *dev_priv, } } -static void i965gm_get_cdclk(struct drm_i915_private *dev_priv, +static void i965gm_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); static const u8 div_3200[] = { 16, 10, 8 }; static const u8 div_4000[] = { 20, 12, 10 }; static const u8 div_5333[] = { 24, 16, 14 }; @@ -438,7 +439,7 @@ static void i965gm_get_cdclk(struct drm_i915_private *dev_priv, unsigned int cdclk_sel; u16 tmp = 0; - cdclk_config->vco = intel_hpll_vco(dev_priv); + cdclk_config->vco = intel_hpll_vco(display); pci_read_config_word(pdev, GCFGC, &tmp); @@ -466,20 +467,20 @@ static void i965gm_get_cdclk(struct drm_i915_private *dev_priv, return; fail: - drm_err(&dev_priv->drm, + drm_err(display->drm, "Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n", cdclk_config->vco, tmp); cdclk_config->cdclk = 200000; } -static void gm45_get_cdclk(struct drm_i915_private *dev_priv, +static void gm45_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); unsigned int cdclk_sel; u16 tmp = 0; - cdclk_config->vco = intel_hpll_vco(dev_priv); + cdclk_config->vco = intel_hpll_vco(display); pci_read_config_word(pdev, GCFGC, &tmp); @@ -495,7 +496,7 @@ static void gm45_get_cdclk(struct drm_i915_private *dev_priv, cdclk_config->cdclk = cdclk_sel ? 320000 : 228571; break; default: - drm_err(&dev_priv->drm, + drm_err(display->drm, "Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n", cdclk_config->vco, tmp); cdclk_config->cdclk = 222222; @@ -503,15 +504,16 @@ static void gm45_get_cdclk(struct drm_i915_private *dev_priv, } } -static void hsw_get_cdclk(struct drm_i915_private *dev_priv, +static void hsw_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL); + struct drm_i915_private *dev_priv = to_i915(display->drm); + u32 lcpll = intel_de_read(display, LCPLL_CTL); u32 freq = lcpll & LCPLL_CLK_FREQ_MASK; if (lcpll & LCPLL_CD_SOURCE_FCLK) cdclk_config->cdclk = 800000; - else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT) + else if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT) cdclk_config->cdclk = 450000; else if (freq == LCPLL_CLK_FREQ_450) cdclk_config->cdclk = 450000; @@ -521,8 +523,9 @@ static void hsw_get_cdclk(struct drm_i915_private *dev_priv, cdclk_config->cdclk = 540000; } -static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) +static int vlv_calc_cdclk(struct intel_display *display, int min_cdclk) { + struct drm_i915_private *dev_priv = to_i915(display->drm); int freq_320 = (dev_priv->hpll_freq << 1) % 320000 != 0 ? 333333 : 320000; @@ -541,8 +544,10 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) return 200000; } -static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk) +static u8 vlv_calc_voltage_level(struct intel_display *display, int cdclk) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + if (IS_VALLEYVIEW(dev_priv)) { if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */ return 2; @@ -560,9 +565,10 @@ static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk) } } -static void vlv_get_cdclk(struct drm_i915_private *dev_priv, +static void vlv_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; vlv_iosf_sb_get(dev_priv, @@ -586,8 +592,9 @@ static void vlv_get_cdclk(struct drm_i915_private *dev_priv, DSPFREQGUAR_SHIFT_CHV; } -static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) +static void vlv_program_pfi_credits(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); unsigned int credits, default_credits; if (IS_CHERRYVIEW(dev_priv)) @@ -595,7 +602,7 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) else default_credits = PFI_CREDIT(8); - if (dev_priv->display.cdclk.hw.cdclk >= dev_priv->czclk_freq) { + if (display->cdclk.hw.cdclk >= dev_priv->czclk_freq) { /* CHV suggested value is 31 or 63 */ if (IS_CHERRYVIEW(dev_priv)) credits = PFI_CREDIT_63; @@ -609,24 +616,25 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) * WA - write default credits before re-programming * FIXME: should we also set the resend bit here? */ - intel_de_write(dev_priv, GCI_CONTROL, + intel_de_write(display, GCI_CONTROL, VGA_FAST_MODE_DISABLE | default_credits); - intel_de_write(dev_priv, GCI_CONTROL, + intel_de_write(display, GCI_CONTROL, VGA_FAST_MODE_DISABLE | credits | PFI_CREDIT_RESEND); /* * FIXME is this guaranteed to clear * immediately or should we poll for it? */ - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, GCI_CONTROL) & PFI_CREDIT_RESEND); + drm_WARN_ON(display->drm, + intel_de_read(display, GCI_CONTROL) & PFI_CREDIT_RESEND); } -static void vlv_set_cdclk(struct drm_i915_private *dev_priv, +static void vlv_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); int cdclk = cdclk_config->cdclk; u32 val, cmd = cdclk_config->voltage_level; intel_wakeref_t wakeref; @@ -663,7 +671,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) & DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT), 50)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "timed out waiting for CDclk change\n"); } @@ -682,7 +690,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) & CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT), 50)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "timed out waiting for CDclk change\n"); } @@ -705,17 +713,18 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, BIT(VLV_IOSF_SB_BUNIT) | BIT(VLV_IOSF_SB_PUNIT)); - intel_update_cdclk(dev_priv); + intel_update_cdclk(display); - vlv_program_pfi_credits(dev_priv); + vlv_program_pfi_credits(display); intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref); } -static void chv_set_cdclk(struct drm_i915_private *dev_priv, +static void chv_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); int cdclk = cdclk_config->cdclk; u32 val, cmd = cdclk_config->voltage_level; intel_wakeref_t wakeref; @@ -747,15 +756,15 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) & DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV), 50)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "timed out waiting for CDclk change\n"); } vlv_punit_put(dev_priv); - intel_update_cdclk(dev_priv); + intel_update_cdclk(display); - vlv_program_pfi_credits(dev_priv); + vlv_program_pfi_credits(display); intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref); } @@ -787,15 +796,15 @@ static u8 bdw_calc_voltage_level(int cdclk) } } -static void bdw_get_cdclk(struct drm_i915_private *dev_priv, +static void bdw_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL); + u32 lcpll = intel_de_read(display, LCPLL_CTL); u32 freq = lcpll & LCPLL_CLK_FREQ_MASK; if (lcpll & LCPLL_CD_SOURCE_FCLK) cdclk_config->cdclk = 800000; - else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT) + else if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT) cdclk_config->cdclk = 450000; else if (freq == LCPLL_CLK_FREQ_450) cdclk_config->cdclk = 450000; @@ -831,15 +840,16 @@ static u32 bdw_cdclk_freq_sel(int cdclk) } } -static void bdw_set_cdclk(struct drm_i915_private *dev_priv, +static void bdw_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); int cdclk = cdclk_config->cdclk; int ret; - if (drm_WARN(&dev_priv->drm, - (intel_de_read(dev_priv, LCPLL_CTL) & + if (drm_WARN(display->drm, + (intel_de_read(display, LCPLL_CTL) & (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK | LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE | LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW | @@ -849,39 +859,39 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, ret = snb_pcode_write(&dev_priv->uncore, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); if (ret) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "failed to inform pcode about cdclk change\n"); return; } - intel_de_rmw(dev_priv, LCPLL_CTL, + intel_de_rmw(display, LCPLL_CTL, 0, LCPLL_CD_SOURCE_FCLK); /* * According to the spec, it should be enough to poll for this 1 us. * However, extensive testing shows that this can take longer. */ - if (wait_for_us(intel_de_read(dev_priv, LCPLL_CTL) & + if (wait_for_us(intel_de_read(display, LCPLL_CTL) & LCPLL_CD_SOURCE_FCLK_DONE, 100)) - drm_err(&dev_priv->drm, "Switching to FCLK failed\n"); + drm_err(display->drm, "Switching to FCLK failed\n"); - intel_de_rmw(dev_priv, LCPLL_CTL, + intel_de_rmw(display, LCPLL_CTL, LCPLL_CLK_FREQ_MASK, bdw_cdclk_freq_sel(cdclk)); - intel_de_rmw(dev_priv, LCPLL_CTL, + intel_de_rmw(display, LCPLL_CTL, LCPLL_CD_SOURCE_FCLK, 0); - if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) & + if (wait_for_us((intel_de_read(display, LCPLL_CTL) & LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) - drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n"); + drm_err(display->drm, "Switching back to LCPLL failed\n"); snb_pcode_write(&dev_priv->uncore, HSW_PCODE_DE_WRITE_FREQ_REQ, cdclk_config->voltage_level); - intel_de_write(dev_priv, CDCLK_FREQ, + intel_de_write(display, CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); - intel_update_cdclk(dev_priv); + intel_update_cdclk(display); } static int skl_calc_cdclk(int min_cdclk, int vco) @@ -919,7 +929,7 @@ static u8 skl_calc_voltage_level(int cdclk) return 0; } -static void skl_dpll0_update(struct drm_i915_private *dev_priv, +static void skl_dpll0_update(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { u32 val; @@ -927,16 +937,16 @@ static void skl_dpll0_update(struct drm_i915_private *dev_priv, cdclk_config->ref = 24000; cdclk_config->vco = 0; - val = intel_de_read(dev_priv, LCPLL1_CTL); + val = intel_de_read(display, LCPLL1_CTL); if ((val & LCPLL_PLL_ENABLE) == 0) return; - if (drm_WARN_ON(&dev_priv->drm, (val & LCPLL_PLL_LOCK) == 0)) + if (drm_WARN_ON(display->drm, (val & LCPLL_PLL_LOCK) == 0)) return; - val = intel_de_read(dev_priv, DPLL_CTRL1); + val = intel_de_read(display, DPLL_CTRL1); - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, (val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) | DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) != @@ -960,19 +970,19 @@ static void skl_dpll0_update(struct drm_i915_private *dev_priv, } } -static void skl_get_cdclk(struct drm_i915_private *dev_priv, +static void skl_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { u32 cdctl; - skl_dpll0_update(dev_priv, cdclk_config); + skl_dpll0_update(display, cdclk_config); cdclk_config->cdclk = cdclk_config->bypass = cdclk_config->ref; if (cdclk_config->vco == 0) goto out; - cdctl = intel_de_read(dev_priv, CDCLK_CTL); + cdctl = intel_de_read(display, CDCLK_CTL); if (cdclk_config->vco == 8640000) { switch (cdctl & CDCLK_FREQ_SEL_MASK) { @@ -1027,19 +1037,19 @@ static int skl_cdclk_decimal(int cdclk) return DIV_ROUND_CLOSEST(cdclk - 1000, 500); } -static void skl_set_preferred_cdclk_vco(struct drm_i915_private *i915, int vco) +static void skl_set_preferred_cdclk_vco(struct intel_display *display, int vco) { - bool changed = i915->display.cdclk.skl_preferred_vco_freq != vco; + bool changed = display->cdclk.skl_preferred_vco_freq != vco; - i915->display.cdclk.skl_preferred_vco_freq = vco; + display->cdclk.skl_preferred_vco_freq = vco; if (changed) - intel_update_max_cdclk(i915); + intel_update_max_cdclk(display); } -static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco) +static u32 skl_dpll0_link_rate(struct intel_display *display, int vco) { - drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000); + drm_WARN_ON(display->drm, vco != 8100000 && vco != 8640000); /* * We always enable DPLL0 with the lowest link rate possible, but still @@ -1056,47 +1066,47 @@ static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco) return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0); } -static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco) +static void skl_dpll0_enable(struct intel_display *display, int vco) { - intel_de_rmw(dev_priv, DPLL_CTRL1, + intel_de_rmw(display, DPLL_CTRL1, DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) | DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0), DPLL_CTRL1_OVERRIDE(SKL_DPLL0) | - skl_dpll0_link_rate(dev_priv, vco)); - intel_de_posting_read(dev_priv, DPLL_CTRL1); + skl_dpll0_link_rate(display, vco)); + intel_de_posting_read(display, DPLL_CTRL1); - intel_de_rmw(dev_priv, LCPLL1_CTL, + intel_de_rmw(display, LCPLL1_CTL, 0, LCPLL_PLL_ENABLE); - if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5)) - drm_err(&dev_priv->drm, "DPLL0 not locked\n"); + if (intel_de_wait_for_set(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 5)) + drm_err(display->drm, "DPLL0 not locked\n"); - dev_priv->display.cdclk.hw.vco = vco; + display->cdclk.hw.vco = vco; /* We'll want to keep using the current vco from now on. */ - skl_set_preferred_cdclk_vco(dev_priv, vco); + skl_set_preferred_cdclk_vco(display, vco); } -static void skl_dpll0_disable(struct drm_i915_private *dev_priv) +static void skl_dpll0_disable(struct intel_display *display) { - intel_de_rmw(dev_priv, LCPLL1_CTL, + intel_de_rmw(display, LCPLL1_CTL, LCPLL_PLL_ENABLE, 0); - if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1)) - drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n"); + if (intel_de_wait_for_clear(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 1)) + drm_err(display->drm, "Couldn't disable DPLL0\n"); - dev_priv->display.cdclk.hw.vco = 0; + display->cdclk.hw.vco = 0; } -static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv, +static u32 skl_cdclk_freq_sel(struct intel_display *display, int cdclk, int vco) { switch (cdclk) { default: - drm_WARN_ON(&dev_priv->drm, - cdclk != dev_priv->display.cdclk.hw.bypass); - drm_WARN_ON(&dev_priv->drm, vco != 0); + drm_WARN_ON(display->drm, + cdclk != display->cdclk.hw.bypass); + drm_WARN_ON(display->drm, vco != 0); fallthrough; case 308571: case 337500: @@ -1112,10 +1122,11 @@ static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv, } } -static void skl_set_cdclk(struct drm_i915_private *dev_priv, +static void skl_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u32 freq_select, cdclk_ctl; @@ -1129,7 +1140,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, * use the corresponding VCO freq as that always leads to using the * minimum 308MHz CDCLK. */ - drm_WARN_ON_ONCE(&dev_priv->drm, + drm_WARN_ON_ONCE(display->drm, IS_SKYLAKE(dev_priv) && vco == 8640000); ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, @@ -1137,54 +1148,54 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, SKL_CDCLK_READY_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, 3); if (ret) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to inform PCU about cdclk change (%d)\n", ret); return; } - freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco); + freq_select = skl_cdclk_freq_sel(display, cdclk, vco); - if (dev_priv->display.cdclk.hw.vco != 0 && - dev_priv->display.cdclk.hw.vco != vco) - skl_dpll0_disable(dev_priv); + if (display->cdclk.hw.vco != 0 && + display->cdclk.hw.vco != vco) + skl_dpll0_disable(display); - cdclk_ctl = intel_de_read(dev_priv, CDCLK_CTL); + cdclk_ctl = intel_de_read(display, CDCLK_CTL); - if (dev_priv->display.cdclk.hw.vco != vco) { + if (display->cdclk.hw.vco != vco) { /* Wa Display #1183: skl,kbl,cfl */ cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK); cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk); - intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl); + intel_de_write(display, CDCLK_CTL, cdclk_ctl); } /* Wa Display #1183: skl,kbl,cfl */ cdclk_ctl |= CDCLK_DIVMUX_CD_OVERRIDE; - intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl); - intel_de_posting_read(dev_priv, CDCLK_CTL); + intel_de_write(display, CDCLK_CTL, cdclk_ctl); + intel_de_posting_read(display, CDCLK_CTL); - if (dev_priv->display.cdclk.hw.vco != vco) - skl_dpll0_enable(dev_priv, vco); + if (display->cdclk.hw.vco != vco) + skl_dpll0_enable(display, vco); /* Wa Display #1183: skl,kbl,cfl */ cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK); - intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl); + intel_de_write(display, CDCLK_CTL, cdclk_ctl); cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk); - intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl); + intel_de_write(display, CDCLK_CTL, cdclk_ctl); /* Wa Display #1183: skl,kbl,cfl */ cdclk_ctl &= ~CDCLK_DIVMUX_CD_OVERRIDE; - intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl); - intel_de_posting_read(dev_priv, CDCLK_CTL); + intel_de_write(display, CDCLK_CTL, cdclk_ctl); + intel_de_posting_read(display, CDCLK_CTL); /* inform PCU of the change */ snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, cdclk_config->voltage_level); - intel_update_cdclk(dev_priv); + intel_update_cdclk(display); } -static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) +static void skl_sanitize_cdclk(struct intel_display *display) { u32 cdctl, expected; @@ -1193,15 +1204,15 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) * There is SWF18 scratchpad register defined which is set by the * pre-os which can be used by the OS drivers to check the status */ - if ((intel_de_read(dev_priv, SWF_ILK(0x18)) & 0x00FFFFFF) == 0) + if ((intel_de_read(display, SWF_ILK(0x18)) & 0x00FFFFFF) == 0) goto sanitize; - intel_update_cdclk(dev_priv); - intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK"); + intel_update_cdclk(display); + intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); /* Is PLL enabled and locked ? */ - if (dev_priv->display.cdclk.hw.vco == 0 || - dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass) + if (display->cdclk.hw.vco == 0 || + display->cdclk.hw.cdclk == display->cdclk.hw.bypass) goto sanitize; /* DPLL okay; verify the cdclock @@ -1210,60 +1221,60 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) * decimal part is programmed wrong from BIOS where pre-os does not * enable display. Verify the same as well. */ - cdctl = intel_de_read(dev_priv, CDCLK_CTL); + cdctl = intel_de_read(display, CDCLK_CTL); expected = (cdctl & CDCLK_FREQ_SEL_MASK) | - skl_cdclk_decimal(dev_priv->display.cdclk.hw.cdclk); + skl_cdclk_decimal(display->cdclk.hw.cdclk); if (cdctl == expected) /* All well; nothing to sanitize */ return; sanitize: - drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n"); + drm_dbg_kms(display->drm, "Sanitizing cdclk programmed by pre-os\n"); /* force cdclk programming */ - dev_priv->display.cdclk.hw.cdclk = 0; + display->cdclk.hw.cdclk = 0; /* force full PLL disable + enable */ - dev_priv->display.cdclk.hw.vco = ~0; + display->cdclk.hw.vco = ~0; } -static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv) +static void skl_cdclk_init_hw(struct intel_display *display) { struct intel_cdclk_config cdclk_config; - skl_sanitize_cdclk(dev_priv); + skl_sanitize_cdclk(display); - if (dev_priv->display.cdclk.hw.cdclk != 0 && - dev_priv->display.cdclk.hw.vco != 0) { + if (display->cdclk.hw.cdclk != 0 && + display->cdclk.hw.vco != 0) { /* * Use the current vco as our initial * guess as to what the preferred vco is. */ - if (dev_priv->display.cdclk.skl_preferred_vco_freq == 0) - skl_set_preferred_cdclk_vco(dev_priv, - dev_priv->display.cdclk.hw.vco); + if (display->cdclk.skl_preferred_vco_freq == 0) + skl_set_preferred_cdclk_vco(display, + display->cdclk.hw.vco); return; } - cdclk_config = dev_priv->display.cdclk.hw; + cdclk_config = display->cdclk.hw; - cdclk_config.vco = dev_priv->display.cdclk.skl_preferred_vco_freq; + cdclk_config.vco = display->cdclk.skl_preferred_vco_freq; if (cdclk_config.vco == 0) cdclk_config.vco = 8100000; cdclk_config.cdclk = skl_calc_cdclk(0, cdclk_config.vco); cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk); - skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE); + skl_set_cdclk(display, &cdclk_config, INVALID_PIPE); } -static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv) +static void skl_cdclk_uninit_hw(struct intel_display *display) { - struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw; + struct intel_cdclk_config cdclk_config = display->cdclk.hw; cdclk_config.cdclk = cdclk_config.bypass; cdclk_config.vco = 0; cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk); - skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE); + skl_set_cdclk(display, &cdclk_config, INVALID_PIPE); } struct intel_cdclk_vals { @@ -1471,37 +1482,37 @@ static int cdclk_divider(int cdclk, int vco, u16 waveform) cdclk * cdclk_squash_len); } -static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) +static int bxt_calc_cdclk(struct intel_display *display, int min_cdclk) { - const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; + const struct intel_cdclk_vals *table = display->cdclk.table; int i; for (i = 0; table[i].refclk; i++) - if (table[i].refclk == dev_priv->display.cdclk.hw.ref && + if (table[i].refclk == display->cdclk.hw.ref && table[i].cdclk >= min_cdclk) return table[i].cdclk; - drm_WARN(&dev_priv->drm, 1, + drm_WARN(display->drm, 1, "Cannot satisfy minimum cdclk %d with refclk %u\n", - min_cdclk, dev_priv->display.cdclk.hw.ref); + min_cdclk, display->cdclk.hw.ref); return 0; } -static int bxt_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) +static int bxt_calc_cdclk_pll_vco(struct intel_display *display, int cdclk) { - const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; + const struct intel_cdclk_vals *table = display->cdclk.table; int i; - if (cdclk == dev_priv->display.cdclk.hw.bypass) + if (cdclk == display->cdclk.hw.bypass) return 0; for (i = 0; table[i].refclk; i++) - if (table[i].refclk == dev_priv->display.cdclk.hw.ref && + if (table[i].refclk == display->cdclk.hw.ref && table[i].cdclk == cdclk) - return dev_priv->display.cdclk.hw.ref * table[i].ratio; + return display->cdclk.hw.ref * table[i].ratio; - drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n", - cdclk, dev_priv->display.cdclk.hw.ref); + drm_WARN(display->drm, 1, "cdclk %d not valid for refclk %u\n", + cdclk, display->cdclk.hw.ref); return 0; } @@ -1583,10 +1594,10 @@ static u8 rplu_calc_voltage_level(int cdclk) rplu_voltage_level_max_cdclk); } -static void icl_readout_refclk(struct drm_i915_private *dev_priv, +static void icl_readout_refclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - u32 dssm = intel_de_read(dev_priv, SKL_DSSM) & ICL_DSSM_CDCLK_PLL_REFCLK_MASK; + u32 dssm = intel_de_read(display, SKL_DSSM) & ICL_DSSM_CDCLK_PLL_REFCLK_MASK; switch (dssm) { default: @@ -1604,19 +1615,20 @@ static void icl_readout_refclk(struct drm_i915_private *dev_priv, } } -static void bxt_de_pll_readout(struct drm_i915_private *dev_priv, +static void bxt_de_pll_readout(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val, ratio; if (IS_DG2(dev_priv)) cdclk_config->ref = 38400; - else if (DISPLAY_VER(dev_priv) >= 11) - icl_readout_refclk(dev_priv, cdclk_config); + else if (DISPLAY_VER(display) >= 11) + icl_readout_refclk(display, cdclk_config); else cdclk_config->ref = 19200; - val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE); + val = intel_de_read(display, BXT_DE_PLL_ENABLE); if ((val & BXT_DE_PLL_PLL_ENABLE) == 0 || (val & BXT_DE_PLL_LOCK) == 0) { /* @@ -1631,26 +1643,26 @@ static void bxt_de_pll_readout(struct drm_i915_private *dev_priv, * DISPLAY_VER >= 11 have the ratio directly in the PLL enable register, * gen9lp had it in a separate PLL control register. */ - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) ratio = val & ICL_CDCLK_PLL_RATIO_MASK; else - ratio = intel_de_read(dev_priv, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK; + ratio = intel_de_read(display, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK; cdclk_config->vco = ratio * cdclk_config->ref; } -static void bxt_get_cdclk(struct drm_i915_private *dev_priv, +static void bxt_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { u32 squash_ctl = 0; u32 divider; int div; - bxt_de_pll_readout(dev_priv, cdclk_config); + bxt_de_pll_readout(display, cdclk_config); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) cdclk_config->bypass = cdclk_config->ref / 2; - else if (DISPLAY_VER(dev_priv) >= 11) + else if (DISPLAY_VER(display) >= 11) cdclk_config->bypass = 50000; else cdclk_config->bypass = cdclk_config->ref; @@ -1660,7 +1672,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, goto out; } - divider = intel_de_read(dev_priv, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; + divider = intel_de_read(display, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; switch (divider) { case BXT_CDCLK_CD2X_DIV_SEL_1: @@ -1680,8 +1692,8 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_SQUASH(dev_priv)) - squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL); + if (HAS_CDCLK_SQUASH(display)) + squash_ctl = intel_de_read(display, CDCLK_SQUASH_CTL); if (squash_ctl & CDCLK_SQUASH_ENABLE) { u16 waveform; @@ -1697,107 +1709,107 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, } out: - if (DISPLAY_VER(dev_priv) >= 20) - cdclk_config->joined_mbus = intel_de_read(dev_priv, MBUS_CTL) & MBUS_JOIN; + if (DISPLAY_VER(display) >= 20) + cdclk_config->joined_mbus = intel_de_read(display, MBUS_CTL) & MBUS_JOIN; /* * Can't read this out :( Let's assume it's * at least what the CDCLK frequency requires. */ cdclk_config->voltage_level = - intel_cdclk_calc_voltage_level(dev_priv, cdclk_config->cdclk); + intel_cdclk_calc_voltage_level(display, cdclk_config->cdclk); } -static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) +static void bxt_de_pll_disable(struct intel_display *display) { - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, 0); + intel_de_write(display, BXT_DE_PLL_ENABLE, 0); /* Timeout 200us */ - if (intel_de_wait_for_clear(dev_priv, + if (intel_de_wait_for_clear(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1)) - drm_err(&dev_priv->drm, "timeout waiting for DE PLL unlock\n"); + drm_err(display->drm, "timeout waiting for DE PLL unlock\n"); - dev_priv->display.cdclk.hw.vco = 0; + display->cdclk.hw.vco = 0; } -static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco) +static void bxt_de_pll_enable(struct intel_display *display, int vco) { - int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref); + int ratio = DIV_ROUND_CLOSEST(vco, display->cdclk.hw.ref); - intel_de_rmw(dev_priv, BXT_DE_PLL_CTL, + intel_de_rmw(display, BXT_DE_PLL_CTL, BXT_DE_PLL_RATIO_MASK, BXT_DE_PLL_RATIO(ratio)); - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE); + intel_de_write(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE); /* Timeout 200us */ - if (intel_de_wait_for_set(dev_priv, + if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1)) - drm_err(&dev_priv->drm, "timeout waiting for DE PLL lock\n"); + drm_err(display->drm, "timeout waiting for DE PLL lock\n"); - dev_priv->display.cdclk.hw.vco = vco; + display->cdclk.hw.vco = vco; } -static void icl_cdclk_pll_disable(struct drm_i915_private *dev_priv) +static void icl_cdclk_pll_disable(struct intel_display *display) { - intel_de_rmw(dev_priv, BXT_DE_PLL_ENABLE, + intel_de_rmw(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE, 0); /* Timeout 200us */ - if (intel_de_wait_for_clear(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1)) - drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL unlock\n"); + if (intel_de_wait_for_clear(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1)) + drm_err(display->drm, "timeout waiting for CDCLK PLL unlock\n"); - dev_priv->display.cdclk.hw.vco = 0; + display->cdclk.hw.vco = 0; } -static void icl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco) +static void icl_cdclk_pll_enable(struct intel_display *display, int vco) { - int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref); + int ratio = DIV_ROUND_CLOSEST(vco, display->cdclk.hw.ref); u32 val; val = ICL_CDCLK_PLL_RATIO(ratio); - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); + intel_de_write(display, BXT_DE_PLL_ENABLE, val); val |= BXT_DE_PLL_PLL_ENABLE; - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); + intel_de_write(display, BXT_DE_PLL_ENABLE, val); /* Timeout 200us */ - if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1)) - drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL lock\n"); + if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1)) + drm_err(display->drm, "timeout waiting for CDCLK PLL lock\n"); - dev_priv->display.cdclk.hw.vco = vco; + display->cdclk.hw.vco = vco; } -static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco) +static void adlp_cdclk_pll_crawl(struct intel_display *display, int vco) { - int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref); + int ratio = DIV_ROUND_CLOSEST(vco, display->cdclk.hw.ref); u32 val; /* Write PLL ratio without disabling */ val = ICL_CDCLK_PLL_RATIO(ratio) | BXT_DE_PLL_PLL_ENABLE; - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); + intel_de_write(display, BXT_DE_PLL_ENABLE, val); /* Submit freq change request */ val |= BXT_DE_PLL_FREQ_REQ; - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); + intel_de_write(display, BXT_DE_PLL_ENABLE, val); /* Timeout 200us */ - if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, + if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1)) - drm_err(&dev_priv->drm, "timeout waiting for FREQ change request ack\n"); + drm_err(display->drm, "timeout waiting for FREQ change request ack\n"); val &= ~BXT_DE_PLL_FREQ_REQ; - intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); + intel_de_write(display, BXT_DE_PLL_ENABLE, val); - dev_priv->display.cdclk.hw.vco = vco; + display->cdclk.hw.vco = vco; } -static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +static u32 bxt_cdclk_cd2x_pipe(struct intel_display *display, enum pipe pipe) { - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { if (pipe == INVALID_PIPE) return TGL_CDCLK_CD2X_PIPE_NONE; else return TGL_CDCLK_CD2X_PIPE(pipe); - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { if (pipe == INVALID_PIPE) return ICL_CDCLK_CD2X_PIPE_NONE; else @@ -1810,15 +1822,15 @@ static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe } } -static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv, +static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display, int cdclk, int vco, u16 waveform) { /* cdclk = vco / 2 / div{1,1.5,2,4} */ switch (cdclk_divider(cdclk, vco, waveform)) { default: - drm_WARN_ON(&dev_priv->drm, - cdclk != dev_priv->display.cdclk.hw.bypass); - drm_WARN_ON(&dev_priv->drm, vco != 0); + drm_WARN_ON(display->drm, + cdclk != display->cdclk.hw.bypass); + drm_WARN_ON(display->drm, vco != 0); fallthrough; case 2: return BXT_CDCLK_CD2X_DIV_SEL_1; @@ -1831,47 +1843,47 @@ static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv, } } -static u16 cdclk_squash_waveform(struct drm_i915_private *dev_priv, +static u16 cdclk_squash_waveform(struct intel_display *display, int cdclk) { - const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table; + const struct intel_cdclk_vals *table = display->cdclk.table; int i; - if (cdclk == dev_priv->display.cdclk.hw.bypass) + if (cdclk == display->cdclk.hw.bypass) return 0; for (i = 0; table[i].refclk; i++) - if (table[i].refclk == dev_priv->display.cdclk.hw.ref && + if (table[i].refclk == display->cdclk.hw.ref && table[i].cdclk == cdclk) return table[i].waveform; - drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n", - cdclk, dev_priv->display.cdclk.hw.ref); + drm_WARN(display->drm, 1, "cdclk %d not valid for refclk %u\n", + cdclk, display->cdclk.hw.ref); return 0xffff; } -static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco) +static void icl_cdclk_pll_update(struct intel_display *display, int vco) { - if (i915->display.cdclk.hw.vco != 0 && - i915->display.cdclk.hw.vco != vco) - icl_cdclk_pll_disable(i915); + if (display->cdclk.hw.vco != 0 && + display->cdclk.hw.vco != vco) + icl_cdclk_pll_disable(display); - if (i915->display.cdclk.hw.vco != vco) - icl_cdclk_pll_enable(i915, vco); + if (display->cdclk.hw.vco != vco) + icl_cdclk_pll_enable(display, vco); } -static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco) +static void bxt_cdclk_pll_update(struct intel_display *display, int vco) { - if (i915->display.cdclk.hw.vco != 0 && - i915->display.cdclk.hw.vco != vco) - bxt_de_pll_disable(i915); + if (display->cdclk.hw.vco != 0 && + display->cdclk.hw.vco != vco) + bxt_de_pll_disable(display); - if (i915->display.cdclk.hw.vco != vco) - bxt_de_pll_enable(i915, vco); + if (display->cdclk.hw.vco != vco) + bxt_de_pll_enable(display, vco); } -static void dg2_cdclk_squash_program(struct drm_i915_private *i915, +static void dg2_cdclk_squash_program(struct intel_display *display, u16 waveform) { u32 squash_ctl = 0; @@ -1880,7 +1892,7 @@ static void dg2_cdclk_squash_program(struct drm_i915_private *i915, squash_ctl = CDCLK_SQUASH_ENABLE | CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl); + intel_de_write(display, CDCLK_SQUASH_CTL, squash_ctl); } static bool cdclk_pll_is_unknown(unsigned int vco) @@ -1893,38 +1905,40 @@ static bool cdclk_pll_is_unknown(unsigned int vco) return vco == ~0; } -static bool mdclk_source_is_cdclk_pll(struct drm_i915_private *i915) +static bool mdclk_source_is_cdclk_pll(struct intel_display *display) { - return DISPLAY_VER(i915) >= 20; + return DISPLAY_VER(display) >= 20; } -static u32 xe2lpd_mdclk_source_sel(struct drm_i915_private *i915) +static u32 xe2lpd_mdclk_source_sel(struct intel_display *display) { - if (mdclk_source_is_cdclk_pll(i915)) + if (mdclk_source_is_cdclk_pll(display)) return MDCLK_SOURCE_SEL_CDCLK_PLL; return MDCLK_SOURCE_SEL_CD2XCLK; } -int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915, +int intel_mdclk_cdclk_ratio(struct intel_display *display, const struct intel_cdclk_config *cdclk_config) { - if (mdclk_source_is_cdclk_pll(i915)) + if (mdclk_source_is_cdclk_pll(display)) return DIV_ROUND_UP(cdclk_config->vco, cdclk_config->cdclk); /* Otherwise, source for MDCLK is CD2XCLK. */ return 2; } -static void xe2lpd_mdclk_cdclk_ratio_program(struct drm_i915_private *i915, +static void xe2lpd_mdclk_cdclk_ratio_program(struct intel_display *display, const struct intel_cdclk_config *cdclk_config) { + struct drm_i915_private *i915 = to_i915(display->drm); + intel_dbuf_mdclk_cdclk_ratio_update(i915, - intel_mdclk_cdclk_ratio(i915, cdclk_config), + intel_mdclk_cdclk_ratio(display, cdclk_config), cdclk_config->joined_mbus); } -static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915, +static bool cdclk_compute_crawl_and_squash_midpoint(struct intel_display *display, const struct intel_cdclk_config *old_cdclk_config, const struct intel_cdclk_config *new_cdclk_config, struct intel_cdclk_config *mid_cdclk_config) @@ -1937,11 +1951,11 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91 return false; /* Return if both Squash and Crawl are not present */ - if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + if (!HAS_CDCLK_CRAWL(display) || !HAS_CDCLK_SQUASH(display)) return false; - old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk); - new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk); + old_waveform = cdclk_squash_waveform(display, old_cdclk_config->cdclk); + new_waveform = cdclk_squash_waveform(display, new_cdclk_config->cdclk); /* Return if Squash only or Crawl only is the desired action */ if (old_cdclk_config->vco == 0 || new_cdclk_config->vco == 0 || @@ -1958,7 +1972,7 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91 * Should not happen currently. We might need more midpoint * transitions if we need to also change the cd2x divider. */ - if (drm_WARN_ON(&i915->drm, old_div != new_div)) + if (drm_WARN_ON(display->drm, old_div != new_div)) return false; *mid_cdclk_config = *new_cdclk_config; @@ -1987,37 +2001,40 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91 /* make sure the mid clock came out sane */ - drm_WARN_ON(&i915->drm, mid_cdclk_config->cdclk < + drm_WARN_ON(display->drm, mid_cdclk_config->cdclk < min(old_cdclk_config->cdclk, new_cdclk_config->cdclk)); - drm_WARN_ON(&i915->drm, mid_cdclk_config->cdclk > - i915->display.cdclk.max_cdclk_freq); - drm_WARN_ON(&i915->drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) != + drm_WARN_ON(display->drm, mid_cdclk_config->cdclk > + display->cdclk.max_cdclk_freq); + drm_WARN_ON(display->drm, cdclk_squash_waveform(display, mid_cdclk_config->cdclk) != mid_waveform); return true; } -static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv) +static bool pll_enable_wa_needed(struct intel_display *display) { - return (DISPLAY_VER_FULL(dev_priv) == IP_VER(20, 0) || - DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 0) || + struct drm_i915_private *dev_priv = to_i915(display->drm); + + return (DISPLAY_VER_FULL(display) == IP_VER(20, 0) || + DISPLAY_VER_FULL(display) == IP_VER(14, 0) || IS_DG2(dev_priv)) && - dev_priv->display.cdclk.hw.vco > 0; + display->cdclk.hw.vco > 0; } -static u32 bxt_cdclk_ctl(struct drm_i915_private *i915, +static u32 bxt_cdclk_ctl(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct drm_i915_private *i915 = to_i915(display->drm); int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; u16 waveform; u32 val; - waveform = cdclk_squash_waveform(i915, cdclk); + waveform = cdclk_squash_waveform(display, cdclk); - val = bxt_cdclk_cd2x_div_sel(i915, cdclk, vco, waveform) | - bxt_cdclk_cd2x_pipe(i915, pipe); + val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform) | + bxt_cdclk_cd2x_pipe(display, pipe); /* * Disable SSA Precharge when CD clock frequency < 500 MHz, @@ -2027,52 +2044,52 @@ static u32 bxt_cdclk_ctl(struct drm_i915_private *i915, cdclk >= 500000) val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; - if (DISPLAY_VER(i915) >= 20) - val |= xe2lpd_mdclk_source_sel(i915); + if (DISPLAY_VER(display) >= 20) + val |= xe2lpd_mdclk_source_sel(display); else val |= skl_cdclk_decimal(cdclk); return val; } -static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, +static void _bxt_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 && - !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) { - if (dev_priv->display.cdclk.hw.vco != vco) - adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { + if (HAS_CDCLK_CRAWL(display) && display->cdclk.hw.vco > 0 && vco > 0 && + !cdclk_pll_is_unknown(display->cdclk.hw.vco)) { + if (display->cdclk.hw.vco != vco) + adlp_cdclk_pll_crawl(display, vco); + } else if (DISPLAY_VER(display) >= 11) { /* wa_15010685871: dg2, mtl */ - if (pll_enable_wa_needed(dev_priv)) - dg2_cdclk_squash_program(dev_priv, 0); + if (pll_enable_wa_needed(display)) + dg2_cdclk_squash_program(display, 0); - icl_cdclk_pll_update(dev_priv, vco); + icl_cdclk_pll_update(display, vco); } else { - bxt_cdclk_pll_update(dev_priv, vco); + bxt_cdclk_pll_update(display, vco); } - if (HAS_CDCLK_SQUASH(dev_priv)) { - u16 waveform = cdclk_squash_waveform(dev_priv, cdclk); + if (HAS_CDCLK_SQUASH(display)) { + u16 waveform = cdclk_squash_waveform(display, cdclk); - dg2_cdclk_squash_program(dev_priv, waveform); + dg2_cdclk_squash_program(display, waveform); } - intel_de_write(dev_priv, CDCLK_CTL, bxt_cdclk_ctl(dev_priv, cdclk_config, pipe)); + intel_de_write(display, CDCLK_CTL, bxt_cdclk_ctl(display, cdclk_config, pipe)); if (pipe != INVALID_PIPE) intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe)); } -static void bxt_set_cdclk(struct drm_i915_private *dev_priv, +static void bxt_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_cdclk_config mid_cdclk_config; int cdclk = cdclk_config->cdclk; int ret = 0; @@ -2083,9 +2100,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, * mailbox communication, skip * this step. */ - if (DISPLAY_VER(dev_priv) >= 14 || IS_DG2(dev_priv)) + if (DISPLAY_VER(display) >= 14 || IS_DG2(dev_priv)) /* NOOP */; - else if (DISPLAY_VER(dev_priv) >= 11) + else if (DISPLAY_VER(display) >= 11) ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, SKL_CDCLK_PREPARE_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, @@ -2100,35 +2117,35 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, 0x80000000, 150, 2); if (ret) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to inform PCU about cdclk change (err %d, freq %d)\n", ret, cdclk); return; } - if (DISPLAY_VER(dev_priv) >= 20 && cdclk < dev_priv->display.cdclk.hw.cdclk) - xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config); + if (DISPLAY_VER(display) >= 20 && cdclk < display->cdclk.hw.cdclk) + xe2lpd_mdclk_cdclk_ratio_program(display, cdclk_config); - if (cdclk_compute_crawl_and_squash_midpoint(dev_priv, &dev_priv->display.cdclk.hw, + if (cdclk_compute_crawl_and_squash_midpoint(display, &display->cdclk.hw, cdclk_config, &mid_cdclk_config)) { - _bxt_set_cdclk(dev_priv, &mid_cdclk_config, pipe); - _bxt_set_cdclk(dev_priv, cdclk_config, pipe); + _bxt_set_cdclk(display, &mid_cdclk_config, pipe); + _bxt_set_cdclk(display, cdclk_config, pipe); } else { - _bxt_set_cdclk(dev_priv, cdclk_config, pipe); + _bxt_set_cdclk(display, cdclk_config, pipe); } - if (DISPLAY_VER(dev_priv) >= 20 && cdclk > dev_priv->display.cdclk.hw.cdclk) - xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config); + if (DISPLAY_VER(display) >= 20 && cdclk > display->cdclk.hw.cdclk) + xe2lpd_mdclk_cdclk_ratio_program(display, cdclk_config); - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) /* * NOOP - No Pcode communication needed for * Display versions 14 and beyond */; - else if (DISPLAY_VER(dev_priv) >= 11 && !IS_DG2(dev_priv)) + else if (DISPLAY_VER(display) >= 11 && !IS_DG2(dev_priv)) ret = snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, cdclk_config->voltage_level); - if (DISPLAY_VER(dev_priv) < 11) { + if (DISPLAY_VER(display) < 11) { /* * The timeout isn't specified, the 2ms used here is based on * experiment. @@ -2141,42 +2158,42 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, 150, 2); } if (ret) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "PCode CDCLK freq set failed, (err %d, freq %d)\n", ret, cdclk); return; } - intel_update_cdclk(dev_priv); + intel_update_cdclk(display); - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) /* * Can't read out the voltage level :( * Let's just assume everything is as expected. */ - dev_priv->display.cdclk.hw.voltage_level = cdclk_config->voltage_level; + display->cdclk.hw.voltage_level = cdclk_config->voltage_level; } -static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) +static void bxt_sanitize_cdclk(struct intel_display *display) { u32 cdctl, expected; int cdclk, vco; - intel_update_cdclk(dev_priv); - intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK"); + intel_update_cdclk(display); + intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); - if (dev_priv->display.cdclk.hw.vco == 0 || - dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass) + if (display->cdclk.hw.vco == 0 || + display->cdclk.hw.cdclk == display->cdclk.hw.bypass) goto sanitize; /* Make sure this is a legal cdclk value for the platform */ - cdclk = bxt_calc_cdclk(dev_priv, dev_priv->display.cdclk.hw.cdclk); - if (cdclk != dev_priv->display.cdclk.hw.cdclk) + cdclk = bxt_calc_cdclk(display, display->cdclk.hw.cdclk); + if (cdclk != display->cdclk.hw.cdclk) goto sanitize; /* Make sure the VCO is correct for the cdclk */ - vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk); - if (vco != dev_priv->display.cdclk.hw.vco) + vco = bxt_calc_cdclk_pll_vco(display, cdclk); + if (vco != display->cdclk.hw.vco) goto sanitize; /* @@ -2184,129 +2201,133 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) * set reserved MBZ bits in CDCLK_CTL at least during exiting from S4, * so sanitize this register. */ - cdctl = intel_de_read(dev_priv, CDCLK_CTL); - expected = bxt_cdclk_ctl(dev_priv, &dev_priv->display.cdclk.hw, INVALID_PIPE); + cdctl = intel_de_read(display, CDCLK_CTL); + expected = bxt_cdclk_ctl(display, &display->cdclk.hw, INVALID_PIPE); /* * Let's ignore the pipe field, since BIOS could have configured the * dividers both synching to an active pipe, or asynchronously * (PIPE_NONE). */ - cdctl &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE); - expected &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE); + cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE); + expected &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE); if (cdctl == expected) /* All well; nothing to sanitize */ return; sanitize: - drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n"); + drm_dbg_kms(display->drm, "Sanitizing cdclk programmed by pre-os\n"); /* force cdclk programming */ - dev_priv->display.cdclk.hw.cdclk = 0; + display->cdclk.hw.cdclk = 0; /* force full PLL disable + enable */ - dev_priv->display.cdclk.hw.vco = ~0; + display->cdclk.hw.vco = ~0; } -static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv) +static void bxt_cdclk_init_hw(struct intel_display *display) { struct intel_cdclk_config cdclk_config; - bxt_sanitize_cdclk(dev_priv); + bxt_sanitize_cdclk(display); - if (dev_priv->display.cdclk.hw.cdclk != 0 && - dev_priv->display.cdclk.hw.vco != 0) + if (display->cdclk.hw.cdclk != 0 && + display->cdclk.hw.vco != 0) return; - cdclk_config = dev_priv->display.cdclk.hw; + cdclk_config = display->cdclk.hw; /* * FIXME: * - The initial CDCLK needs to be read from VBT. * Need to make this change after VBT has changes for BXT. */ - cdclk_config.cdclk = bxt_calc_cdclk(dev_priv, 0); - cdclk_config.vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk_config.cdclk); + cdclk_config.cdclk = bxt_calc_cdclk(display, 0); + cdclk_config.vco = bxt_calc_cdclk_pll_vco(display, cdclk_config.cdclk); cdclk_config.voltage_level = - intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk); + intel_cdclk_calc_voltage_level(display, cdclk_config.cdclk); - bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE); + bxt_set_cdclk(display, &cdclk_config, INVALID_PIPE); } -static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv) +static void bxt_cdclk_uninit_hw(struct intel_display *display) { - struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw; + struct intel_cdclk_config cdclk_config = display->cdclk.hw; cdclk_config.cdclk = cdclk_config.bypass; cdclk_config.vco = 0; cdclk_config.voltage_level = - intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk); + intel_cdclk_calc_voltage_level(display, cdclk_config.cdclk); - bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE); + bxt_set_cdclk(display, &cdclk_config, INVALID_PIPE); } /** * intel_cdclk_init_hw - Initialize CDCLK hardware - * @i915: i915 device + * @display: display instance * - * Initialize CDCLK. This consists mainly of initializing dev_priv->display.cdclk.hw and + * Initialize CDCLK. This consists mainly of initializing display->cdclk.hw and * sanitizing the state of the hardware if needed. This is generally done only * during the display core initialization sequence, after which the DMC will * take care of turning CDCLK off/on as needed. */ -void intel_cdclk_init_hw(struct drm_i915_private *i915) +void intel_cdclk_init_hw(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915)) - bxt_cdclk_init_hw(i915); - else if (DISPLAY_VER(i915) == 9) - skl_cdclk_init_hw(i915); + struct drm_i915_private *i915 = to_i915(display->drm); + + if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915)) + bxt_cdclk_init_hw(display); + else if (DISPLAY_VER(display) == 9) + skl_cdclk_init_hw(display); } /** * intel_cdclk_uninit_hw - Uninitialize CDCLK hardware - * @i915: i915 device + * @display: display instance * * Uninitialize CDCLK. This is done only during the display core * uninitialization sequence. */ -void intel_cdclk_uninit_hw(struct drm_i915_private *i915) +void intel_cdclk_uninit_hw(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915)) - bxt_cdclk_uninit_hw(i915); - else if (DISPLAY_VER(i915) == 9) - skl_cdclk_uninit_hw(i915); + struct drm_i915_private *i915 = to_i915(display->drm); + + if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915)) + bxt_cdclk_uninit_hw(display); + else if (DISPLAY_VER(display) == 9) + skl_cdclk_uninit_hw(display); } -static bool intel_cdclk_can_crawl_and_squash(struct drm_i915_private *i915, +static bool intel_cdclk_can_crawl_and_squash(struct intel_display *display, const struct intel_cdclk_config *a, const struct intel_cdclk_config *b) { u16 old_waveform; u16 new_waveform; - drm_WARN_ON(&i915->drm, cdclk_pll_is_unknown(a->vco)); + drm_WARN_ON(display->drm, cdclk_pll_is_unknown(a->vco)); if (a->vco == 0 || b->vco == 0) return false; - if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915)) + if (!HAS_CDCLK_CRAWL(display) || !HAS_CDCLK_SQUASH(display)) return false; - old_waveform = cdclk_squash_waveform(i915, a->cdclk); - new_waveform = cdclk_squash_waveform(i915, b->cdclk); + old_waveform = cdclk_squash_waveform(display, a->cdclk); + new_waveform = cdclk_squash_waveform(display, b->cdclk); return a->vco != b->vco && old_waveform != new_waveform; } -static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, +static bool intel_cdclk_can_crawl(struct intel_display *display, const struct intel_cdclk_config *a, const struct intel_cdclk_config *b) { int a_div, b_div; - if (!HAS_CDCLK_CRAWL(dev_priv)) + if (!HAS_CDCLK_CRAWL(display)) return false; /* @@ -2322,7 +2343,7 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv, a->ref == b->ref; } -static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, +static bool intel_cdclk_can_squash(struct intel_display *display, const struct intel_cdclk_config *a, const struct intel_cdclk_config *b) { @@ -2332,7 +2353,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (!HAS_CDCLK_SQUASH(dev_priv)) + if (!HAS_CDCLK_SQUASH(display)) return false; return a->cdclk != b->cdclk && @@ -2361,7 +2382,7 @@ bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a, /** * intel_cdclk_can_cd2x_update - Determine if changing between the two CDCLK * configurations requires only a cd2x divider update - * @dev_priv: i915 device + * @display: display instance * @a: first CDCLK configuration * @b: second CDCLK configuration * @@ -2369,12 +2390,14 @@ bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a, * True if changing between the two CDCLK configurations * can be done with just a cd2x divider update, false if not. */ -static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, +static bool intel_cdclk_can_cd2x_update(struct intel_display *display, const struct intel_cdclk_config *a, const struct intel_cdclk_config *b) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + /* Older hw doesn't have the capability */ - if (DISPLAY_VER(dev_priv) < 10 && !IS_BROXTON(dev_priv)) + if (DISPLAY_VER(display) < 10 && !IS_BROXTON(dev_priv)) return false; /* @@ -2383,7 +2406,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv, * the moment all platforms with squasher use a fixed cd2x * divider. */ - if (HAS_CDCLK_SQUASH(dev_priv)) + if (HAS_CDCLK_SQUASH(display)) return false; return a->cdclk != b->cdclk && @@ -2407,23 +2430,24 @@ static bool intel_cdclk_changed(const struct intel_cdclk_config *a, a->voltage_level != b->voltage_level; } -void intel_cdclk_dump_config(struct drm_i915_private *i915, +void intel_cdclk_dump_config(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, const char *context) { - drm_dbg_kms(&i915->drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n", + drm_dbg_kms(display->drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n", context, cdclk_config->cdclk, cdclk_config->vco, cdclk_config->ref, cdclk_config->bypass, cdclk_config->voltage_level); } -static void intel_pcode_notify(struct drm_i915_private *i915, +static void intel_pcode_notify(struct intel_display *display, u8 voltage_level, u8 active_pipe_count, u16 cdclk, bool cdclk_update_valid, bool pipe_count_update_valid) { + struct drm_i915_private *i915 = to_i915(display->drm); int ret; u32 update_mask = 0; @@ -2444,26 +2468,27 @@ static void intel_pcode_notify(struct drm_i915_private *i915, SKL_CDCLK_READY_FOR_CHANGE, SKL_CDCLK_READY_FOR_CHANGE, 3); if (ret) - drm_err(&i915->drm, + drm_err(display->drm, "Failed to inform PCU about display config (err %d)\n", ret); } -static void intel_set_cdclk(struct drm_i915_private *dev_priv, +static void intel_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe, const char *context) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; - if (!intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config)) + if (!intel_cdclk_changed(&display->cdclk.hw, cdclk_config)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->display.funcs.cdclk->set_cdclk)) + if (drm_WARN_ON_ONCE(display->drm, !display->funcs.cdclk->set_cdclk)) return; - intel_cdclk_dump_config(dev_priv, cdclk_config, context); + intel_cdclk_dump_config(display, cdclk_config, context); - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { + for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_psr_pause(intel_dp); @@ -2476,24 +2501,24 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, * functions use cdclk. Not all platforms/ports do, * but we'll lock them all for simplicity. */ - mutex_lock(&dev_priv->display.gmbus.mutex); - for_each_intel_dp(&dev_priv->drm, encoder) { + mutex_lock(&display->gmbus.mutex); + for_each_intel_dp(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); mutex_lock_nest_lock(&intel_dp->aux.hw_mutex, - &dev_priv->display.gmbus.mutex); + &display->gmbus.mutex); } - intel_cdclk_set_cdclk(dev_priv, cdclk_config, pipe); + intel_cdclk_set_cdclk(display, cdclk_config, pipe); - for_each_intel_dp(&dev_priv->drm, encoder) { + for_each_intel_dp(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); mutex_unlock(&intel_dp->aux.hw_mutex); } - mutex_unlock(&dev_priv->display.gmbus.mutex); + mutex_unlock(&display->gmbus.mutex); - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { + for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_psr_resume(intel_dp); @@ -2501,17 +2526,17 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, intel_audio_cdclk_change_post(dev_priv); - if (drm_WARN(&dev_priv->drm, - intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config), + if (drm_WARN(display->drm, + intel_cdclk_changed(&display->cdclk.hw, cdclk_config), "cdclk state doesn't match!\n")) { - intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "[hw state]"); - intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]"); + intel_cdclk_dump_config(display, &display->cdclk.hw, "[hw state]"); + intel_cdclk_dump_config(display, cdclk_config, "[sw state]"); } } static void intel_cdclk_pcode_pre_notify(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = @@ -2550,13 +2575,13 @@ static void intel_cdclk_pcode_pre_notify(struct intel_atomic_state *state) if (update_pipe_count) num_active_pipes = hweight8(new_cdclk_state->active_pipes); - intel_pcode_notify(i915, voltage_level, num_active_pipes, cdclk, + intel_pcode_notify(display, voltage_level, num_active_pipes, cdclk, change_cdclk, update_pipe_count); } static void intel_cdclk_pcode_post_notify(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_cdclk_state *new_cdclk_state = intel_atomic_get_new_cdclk_state(state); const struct intel_cdclk_state *old_cdclk_state = @@ -2587,7 +2612,7 @@ static void intel_cdclk_pcode_post_notify(struct intel_atomic_state *state) if (update_pipe_count) num_active_pipes = hweight8(new_cdclk_state->active_pipes); - intel_pcode_notify(i915, voltage_level, num_active_pipes, cdclk, + intel_pcode_notify(display, voltage_level, num_active_pipes, cdclk, update_cdclk, update_pipe_count); } @@ -2612,7 +2637,8 @@ bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state) void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = @@ -2649,9 +2675,9 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state) */ cdclk_config.joined_mbus = old_cdclk_state->actual.joined_mbus; - drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed); + drm_WARN_ON(display->drm, !new_cdclk_state->base.changed); - intel_set_cdclk(i915, &cdclk_config, pipe, + intel_set_cdclk(display, &cdclk_config, pipe, "Pre changing CDCLK to"); } @@ -2665,7 +2691,8 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state) void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_cdclk_state *old_cdclk_state = intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = @@ -2685,20 +2712,21 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state) else pipe = INVALID_PIPE; - drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed); + drm_WARN_ON(display->drm, !new_cdclk_state->base.changed); - intel_set_cdclk(i915, &new_cdclk_state->actual, pipe, + intel_set_cdclk(display, &new_cdclk_state->actual, pipe, "Post changing CDCLK to"); } static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); + struct drm_i915_private *dev_priv = to_i915(display->drm); int pixel_rate = crtc_state->pixel_rate; - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) return DIV_ROUND_UP(pixel_rate, 2); - else if (DISPLAY_VER(dev_priv) == 9 || + else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) return pixel_rate; else if (IS_CHERRYVIEW(dev_priv)) @@ -2712,11 +2740,11 @@ static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state) static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_plane *plane; int min_cdclk = 0; - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) + for_each_intel_plane_on_crtc(display->drm, crtc, plane) min_cdclk = max(crtc_state->min_cdclk[plane->id], min_cdclk); return min_cdclk; @@ -2725,7 +2753,7 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state) static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); int min_cdclk = 0; @@ -2754,7 +2782,7 @@ static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) * Since PPC = 2 with bigjoiner * => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits */ - int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24; + int bigjoiner_interface_bits = DISPLAY_VER(display) >= 14 ? 36 : 24; int min_cdclk_bj = (fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) * pixel_clock) / (2 * bigjoiner_interface_bits); @@ -2767,8 +2795,8 @@ static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = - to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); + struct drm_i915_private *dev_priv = to_i915(display->drm); int min_cdclk; if (!crtc_state->hw.enable) @@ -2789,10 +2817,10 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) crtc_state->has_audio && crtc_state->port_clock >= 540000 && crtc_state->lane_count == 4) { - if (DISPLAY_VER(dev_priv) == 10) { + if (DISPLAY_VER(display) == 10) { /* Display WA #1145: glk */ min_cdclk = max(316800, min_cdclk); - } else if (DISPLAY_VER(dev_priv) == 9 || IS_BROADWELL(dev_priv)) { + } else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv)) { /* Display WA #1144: skl,bxt */ min_cdclk = max(432000, min_cdclk); } @@ -2802,7 +2830,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) * According to BSpec, "The CD clock frequency must be at least twice * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default. */ - if (crtc_state->has_audio && DISPLAY_VER(dev_priv) >= 9) + if (crtc_state->has_audio && DISPLAY_VER(display) >= 9) min_cdclk = max(2 * 96000, min_cdclk); /* @@ -2844,7 +2872,8 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) static int intel_compute_min_cdclk(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); const struct intel_bw_state *bw_state; @@ -2887,7 +2916,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state) min_cdclk = max(cdclk_state->force_min_cdclk, cdclk_state->bw_min_cdclk); - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk); /* @@ -2902,10 +2931,10 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state) !is_power_of_2(cdclk_state->active_pipes)) min_cdclk = max(2 * 96000, min_cdclk); - if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) { - drm_dbg_kms(&dev_priv->drm, + if (min_cdclk > display->cdclk.max_cdclk_freq) { + drm_dbg_kms(display->drm, "required cdclk (%d kHz) exceeds max (%d kHz)\n", - min_cdclk, dev_priv->display.cdclk.max_cdclk_freq); + min_cdclk, display->cdclk.max_cdclk_freq); return -EINVAL; } @@ -2927,7 +2956,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state) */ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); struct intel_crtc *crtc; @@ -2955,7 +2984,7 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state) } min_voltage_level = 0; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) min_voltage_level = max(cdclk_state->min_voltage_level[pipe], min_voltage_level); @@ -2964,7 +2993,7 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state) static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); int min_cdclk, cdclk; @@ -2973,18 +3002,18 @@ static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state) if (min_cdclk < 0) return min_cdclk; - cdclk = vlv_calc_cdclk(dev_priv, min_cdclk); + cdclk = vlv_calc_cdclk(display, min_cdclk); cdclk_state->logical.cdclk = cdclk; cdclk_state->logical.voltage_level = - vlv_calc_voltage_level(dev_priv, cdclk); + vlv_calc_voltage_level(display, cdclk); if (!cdclk_state->active_pipes) { - cdclk = vlv_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk); + cdclk = vlv_calc_cdclk(display, cdclk_state->force_min_cdclk); cdclk_state->actual.cdclk = cdclk; cdclk_state->actual.voltage_level = - vlv_calc_voltage_level(dev_priv, cdclk); + vlv_calc_voltage_level(display, cdclk); } else { cdclk_state->actual = cdclk_state->logical; } @@ -3023,7 +3052,7 @@ static int bdw_modeset_calc_cdclk(struct intel_atomic_state *state) static int skl_dpll0_vco(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); struct intel_crtc *crtc; @@ -3032,7 +3061,7 @@ static int skl_dpll0_vco(struct intel_atomic_state *state) vco = cdclk_state->logical.vco; if (!vco) - vco = dev_priv->display.cdclk.skl_preferred_vco_freq; + vco = display->cdclk.skl_preferred_vco_freq; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { if (!crtc_state->hw.enable) @@ -3094,7 +3123,7 @@ static int skl_modeset_calc_cdclk(struct intel_atomic_state *state) static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); int min_cdclk, min_voltage_level, cdclk, vco; @@ -3107,23 +3136,23 @@ static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state) if (min_voltage_level < 0) return min_voltage_level; - cdclk = bxt_calc_cdclk(dev_priv, min_cdclk); - vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk); + cdclk = bxt_calc_cdclk(display, min_cdclk); + vco = bxt_calc_cdclk_pll_vco(display, cdclk); cdclk_state->logical.vco = vco; cdclk_state->logical.cdclk = cdclk; cdclk_state->logical.voltage_level = max_t(int, min_voltage_level, - intel_cdclk_calc_voltage_level(dev_priv, cdclk)); + intel_cdclk_calc_voltage_level(display, cdclk)); if (!cdclk_state->active_pipes) { - cdclk = bxt_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk); - vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk); + cdclk = bxt_calc_cdclk(display, cdclk_state->force_min_cdclk); + vco = bxt_calc_cdclk_pll_vco(display, cdclk); cdclk_state->actual.vco = vco; cdclk_state->actual.cdclk = cdclk; cdclk_state->actual.voltage_level = - intel_cdclk_calc_voltage_level(dev_priv, cdclk); + intel_cdclk_calc_voltage_level(display, cdclk); } else { cdclk_state->actual = cdclk_state->logical; } @@ -3175,10 +3204,10 @@ static const struct intel_global_state_funcs intel_cdclk_funcs = { struct intel_cdclk_state * intel_atomic_get_cdclk_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *cdclk_state; - cdclk_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.cdclk.obj); + cdclk_state = intel_atomic_get_global_obj_state(state, &display->cdclk.obj); if (IS_ERR(cdclk_state)) return ERR_CAST(cdclk_state); @@ -3234,24 +3263,26 @@ int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joi return intel_atomic_lock_global_state(&cdclk_state->base); } -int intel_cdclk_init(struct drm_i915_private *dev_priv) +int intel_cdclk_init(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_cdclk_state *cdclk_state; cdclk_state = kzalloc(sizeof(*cdclk_state), GFP_KERNEL); if (!cdclk_state) return -ENOMEM; - intel_atomic_global_obj_init(dev_priv, &dev_priv->display.cdclk.obj, + intel_atomic_global_obj_init(dev_priv, &display->cdclk.obj, &cdclk_state->base, &intel_cdclk_funcs); return 0; } -static bool intel_cdclk_need_serialize(struct drm_i915_private *i915, +static bool intel_cdclk_need_serialize(struct intel_display *display, const struct intel_cdclk_state *old_cdclk_state, const struct intel_cdclk_state *new_cdclk_state) { + struct drm_i915_private *i915 = to_i915(display->drm); bool power_well_cnt_changed = hweight8(old_cdclk_state->active_pipes) != hweight8(new_cdclk_state->active_pipes); bool cdclk_changed = intel_cdclk_changed(&old_cdclk_state->actual, @@ -3266,7 +3297,6 @@ static bool intel_cdclk_need_serialize(struct drm_i915_private *i915, int intel_modeset_calc_cdclk(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_cdclk_state *old_cdclk_state; struct intel_cdclk_state *new_cdclk_state; enum pipe pipe = INVALID_PIPE; @@ -3285,7 +3315,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) if (ret) return ret; - if (intel_cdclk_need_serialize(dev_priv, old_cdclk_state, new_cdclk_state)) { + if (intel_cdclk_need_serialize(display, old_cdclk_state, new_cdclk_state)) { /* * Also serialize commits across all crtcs * if the actual hw needs to be poked. @@ -3305,7 +3335,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) } if (is_power_of_2(new_cdclk_state->active_pipes) && - intel_cdclk_can_cd2x_update(dev_priv, + intel_cdclk_can_cd2x_update(display, &old_cdclk_state->actual, &new_cdclk_state->actual)) { struct intel_crtc *crtc; @@ -3322,25 +3352,25 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) pipe = INVALID_PIPE; } - if (intel_cdclk_can_crawl_and_squash(dev_priv, + if (intel_cdclk_can_crawl_and_squash(display, &old_cdclk_state->actual, &new_cdclk_state->actual)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Can change cdclk via crawling and squashing\n"); - } else if (intel_cdclk_can_squash(dev_priv, + } else if (intel_cdclk_can_squash(display, &old_cdclk_state->actual, &new_cdclk_state->actual)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Can change cdclk via squashing\n"); - } else if (intel_cdclk_can_crawl(dev_priv, + } else if (intel_cdclk_can_crawl(display, &old_cdclk_state->actual, &new_cdclk_state->actual)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Can change cdclk via crawling\n"); } else if (pipe != INVALID_PIPE) { new_cdclk_state->pipe = pipe; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Can change cdclk cd2x divider with pipe %c active\n", pipe_name(pipe)); } else if (intel_cdclk_clock_changed(&old_cdclk_state->actual, @@ -3352,24 +3382,24 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) new_cdclk_state->disable_pipes = true; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Modeset required for cdclk change\n"); } - if (intel_mdclk_cdclk_ratio(dev_priv, &old_cdclk_state->actual) != - intel_mdclk_cdclk_ratio(dev_priv, &new_cdclk_state->actual)) { - int ratio = intel_mdclk_cdclk_ratio(dev_priv, &new_cdclk_state->actual); + if (intel_mdclk_cdclk_ratio(display, &old_cdclk_state->actual) != + intel_mdclk_cdclk_ratio(display, &new_cdclk_state->actual)) { + int ratio = intel_mdclk_cdclk_ratio(display, &new_cdclk_state->actual); ret = intel_dbuf_state_set_mdclk_cdclk_ratio(state, ratio); if (ret) return ret; } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "New cdclk calculated to be logical %u kHz, actual %u kHz\n", new_cdclk_state->logical.cdclk, new_cdclk_state->actual.cdclk); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "New voltage level calculated to be logical %u, actual %u\n", new_cdclk_state->logical.voltage_level, new_cdclk_state->actual.voltage_level); @@ -3377,18 +3407,19 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) return 0; } -static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) +static int intel_compute_max_dotclk(struct intel_display *display) { - int max_cdclk_freq = dev_priv->display.cdclk.max_cdclk_freq; + struct drm_i915_private *dev_priv = to_i915(display->drm); + int max_cdclk_freq = display->cdclk.max_cdclk_freq; - if (DISPLAY_VER(dev_priv) >= 10) + if (DISPLAY_VER(display) >= 10) return 2 * max_cdclk_freq; - else if (DISPLAY_VER(dev_priv) == 9 || + else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) return max_cdclk_freq; else if (IS_CHERRYVIEW(dev_priv)) return max_cdclk_freq*95/100; - else if (DISPLAY_VER(dev_priv) < 4) + else if (DISPLAY_VER(display) < 4) return 2*max_cdclk_freq*90/100; else return max_cdclk_freq*90/100; @@ -3396,34 +3427,36 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) /** * intel_update_max_cdclk - Determine the maximum support CDCLK frequency - * @dev_priv: i915 device + * @display: display instance * * Determine the maximum CDCLK frequency the platform supports, and also * derive the maximum dot clock frequency the maximum CDCLK frequency * allows. */ -void intel_update_max_cdclk(struct drm_i915_private *dev_priv) +void intel_update_max_cdclk(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { - if (dev_priv->display.cdclk.hw.ref == 24000) - dev_priv->display.cdclk.max_cdclk_freq = 552000; + if (display->cdclk.hw.ref == 24000) + display->cdclk.max_cdclk_freq = 552000; else - dev_priv->display.cdclk.max_cdclk_freq = 556800; - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->display.cdclk.hw.ref == 24000) - dev_priv->display.cdclk.max_cdclk_freq = 648000; + display->cdclk.max_cdclk_freq = 556800; + } else if (DISPLAY_VER(display) >= 11) { + if (display->cdclk.hw.ref == 24000) + display->cdclk.max_cdclk_freq = 648000; else - dev_priv->display.cdclk.max_cdclk_freq = 652800; + display->cdclk.max_cdclk_freq = 652800; } else if (IS_GEMINILAKE(dev_priv)) { - dev_priv->display.cdclk.max_cdclk_freq = 316800; + display->cdclk.max_cdclk_freq = 316800; } else if (IS_BROXTON(dev_priv)) { - dev_priv->display.cdclk.max_cdclk_freq = 624000; - } else if (DISPLAY_VER(dev_priv) == 9) { - u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; + display->cdclk.max_cdclk_freq = 624000; + } else if (DISPLAY_VER(display) == 9) { + u32 limit = intel_de_read(display, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; int max_cdclk, vco; - vco = dev_priv->display.cdclk.skl_preferred_vco_freq; - drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000); + vco = display->cdclk.skl_preferred_vco_freq; + drm_WARN_ON(display->drm, vco != 8100000 && vco != 8640000); /* * Use the lower (vco 8640) cdclk values as a @@ -3439,7 +3472,7 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv) else max_cdclk = 308571; - dev_priv->display.cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco); + display->cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco); } else if (IS_BROADWELL(dev_priv)) { /* * FIXME with extra cooling we can allow @@ -3447,41 +3480,43 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv) * How can we know if extra cooling is * available? PCI ID, VTB, something else? */ - if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT) - dev_priv->display.cdclk.max_cdclk_freq = 450000; + if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT) + display->cdclk.max_cdclk_freq = 450000; else if (IS_BROADWELL_ULX(dev_priv)) - dev_priv->display.cdclk.max_cdclk_freq = 450000; + display->cdclk.max_cdclk_freq = 450000; else if (IS_BROADWELL_ULT(dev_priv)) - dev_priv->display.cdclk.max_cdclk_freq = 540000; + display->cdclk.max_cdclk_freq = 540000; else - dev_priv->display.cdclk.max_cdclk_freq = 675000; + display->cdclk.max_cdclk_freq = 675000; } else if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.cdclk.max_cdclk_freq = 320000; + display->cdclk.max_cdclk_freq = 320000; } else if (IS_VALLEYVIEW(dev_priv)) { - dev_priv->display.cdclk.max_cdclk_freq = 400000; + display->cdclk.max_cdclk_freq = 400000; } else { /* otherwise assume cdclk is fixed */ - dev_priv->display.cdclk.max_cdclk_freq = dev_priv->display.cdclk.hw.cdclk; + display->cdclk.max_cdclk_freq = display->cdclk.hw.cdclk; } - dev_priv->display.cdclk.max_dotclk_freq = intel_compute_max_dotclk(dev_priv); + display->cdclk.max_dotclk_freq = intel_compute_max_dotclk(display); - drm_dbg(&dev_priv->drm, "Max CD clock rate: %d kHz\n", - dev_priv->display.cdclk.max_cdclk_freq); + drm_dbg(display->drm, "Max CD clock rate: %d kHz\n", + display->cdclk.max_cdclk_freq); - drm_dbg(&dev_priv->drm, "Max dotclock rate: %d kHz\n", - dev_priv->display.cdclk.max_dotclk_freq); + drm_dbg(display->drm, "Max dotclock rate: %d kHz\n", + display->cdclk.max_dotclk_freq); } /** * intel_update_cdclk - Determine the current CDCLK frequency - * @dev_priv: i915 device + * @display: display instance * * Determine the current CDCLK frequency. */ -void intel_update_cdclk(struct drm_i915_private *dev_priv) +void intel_update_cdclk(struct intel_display *display) { - intel_cdclk_get_cdclk(dev_priv, &dev_priv->display.cdclk.hw); + struct drm_i915_private *dev_priv = to_i915(display->drm); + + intel_cdclk_get_cdclk(display, &display->cdclk.hw); /* * 9:0 CMBUS [sic] CDCLK frequency (cdfreq): @@ -3490,28 +3525,29 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv) * generate GMBus clock. This will vary with the cdclk freq. */ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - intel_de_write(dev_priv, GMBUSFREQ_VLV, - DIV_ROUND_UP(dev_priv->display.cdclk.hw.cdclk, 1000)); + intel_de_write(display, GMBUSFREQ_VLV, + DIV_ROUND_UP(display->cdclk.hw.cdclk, 1000)); } -static int dg1_rawclk(struct drm_i915_private *dev_priv) +static int dg1_rawclk(struct intel_display *display) { /* * DG1 always uses a 38.4 MHz rawclk. The bspec tells us * "Program Numerator=2, Denominator=4, Divider=37 decimal." */ - intel_de_write(dev_priv, PCH_RAWCLK_FREQ, + intel_de_write(display, PCH_RAWCLK_FREQ, CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2)); return 38400; } -static int cnp_rawclk(struct drm_i915_private *dev_priv) +static int cnp_rawclk(struct intel_display *display) { - u32 rawclk; + struct drm_i915_private *dev_priv = to_i915(display->drm); int divider, fraction; + u32 rawclk; - if (intel_de_read(dev_priv, SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) { + if (intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) { /* 24 MHz */ divider = 24000; fraction = 0; @@ -3531,37 +3567,42 @@ static int cnp_rawclk(struct drm_i915_private *dev_priv) rawclk |= ICP_RAWCLK_NUM(numerator); } - intel_de_write(dev_priv, PCH_RAWCLK_FREQ, rawclk); + intel_de_write(display, PCH_RAWCLK_FREQ, rawclk); return divider + fraction; } -static int pch_rawclk(struct drm_i915_private *dev_priv) +static int pch_rawclk(struct intel_display *display) { - return (intel_de_read(dev_priv, PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000; + return (intel_de_read(display, PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000; } -static int vlv_hrawclk(struct drm_i915_private *dev_priv) +static int vlv_hrawclk(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + /* RAWCLK_FREQ_VLV register updated from power well code */ return vlv_get_cck_clock_hpll(dev_priv, "hrawclk", CCK_DISPLAY_REF_CLOCK_CONTROL); } -static int i9xx_hrawclk(struct drm_i915_private *i915) +static int i9xx_hrawclk(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); + /* hrawclock is 1/4 the FSB frequency */ return DIV_ROUND_CLOSEST(i9xx_fsb_freq(i915), 4); } /** * intel_read_rawclk - Determine the current RAWCLK frequency - * @dev_priv: i915 device + * @display: display instance * * Determine the current RAWCLK frequency. RAWCLK is a fixed * frequency clock so this needs to done only once. */ -u32 intel_read_rawclk(struct drm_i915_private *dev_priv) +u32 intel_read_rawclk(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 freq; if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL) @@ -3572,15 +3613,15 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) */ freq = 38400; else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) - freq = dg1_rawclk(dev_priv); + freq = dg1_rawclk(display); else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) - freq = cnp_rawclk(dev_priv); + freq = cnp_rawclk(display); else if (HAS_PCH_SPLIT(dev_priv)) - freq = pch_rawclk(dev_priv); + freq = pch_rawclk(display); else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - freq = vlv_hrawclk(dev_priv); - else if (DISPLAY_VER(dev_priv) >= 3) - freq = i9xx_hrawclk(dev_priv); + freq = vlv_hrawclk(display); + else if (DISPLAY_VER(display) >= 3) + freq = i9xx_hrawclk(display); else /* no rawclk on other platforms, or no need to know it */ return 0; @@ -3590,23 +3631,23 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) static int i915_cdclk_info_show(struct seq_file *m, void *unused) { - struct drm_i915_private *i915 = m->private; + struct intel_display *display = m->private; - seq_printf(m, "Current CD clock frequency: %d kHz\n", i915->display.cdclk.hw.cdclk); - seq_printf(m, "Max CD clock frequency: %d kHz\n", i915->display.cdclk.max_cdclk_freq); - seq_printf(m, "Max pixel clock frequency: %d kHz\n", i915->display.cdclk.max_dotclk_freq); + seq_printf(m, "Current CD clock frequency: %d kHz\n", display->cdclk.hw.cdclk); + seq_printf(m, "Max CD clock frequency: %d kHz\n", display->cdclk.max_cdclk_freq); + seq_printf(m, "Max pixel clock frequency: %d kHz\n", display->cdclk.max_dotclk_freq); return 0; } DEFINE_SHOW_ATTRIBUTE(i915_cdclk_info); -void intel_cdclk_debugfs_register(struct drm_i915_private *i915) +void intel_cdclk_debugfs_register(struct intel_display *display) { - struct drm_minor *minor = i915->drm.primary; + struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_cdclk_info", 0444, minor->debugfs_root, - i915, &i915_cdclk_info_fops); + display, &i915_cdclk_info_fops); } static const struct intel_cdclk_funcs rplu_cdclk_funcs = { @@ -3747,97 +3788,99 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { /** * intel_init_cdclk_hooks - Initialize CDCLK related modesetting hooks - * @dev_priv: i915 device + * @display: display instance */ -void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) +void intel_init_cdclk_hooks(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 20) { - dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs; - dev_priv->display.cdclk.table = xe2lpd_cdclk_table; - } else if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1)) { - dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs; - dev_priv->display.cdclk.table = xe2hpd_cdclk_table; - } else if (DISPLAY_VER(dev_priv) >= 14) { - dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs; - dev_priv->display.cdclk.table = mtl_cdclk_table; + struct drm_i915_private *dev_priv = to_i915(display->drm); + + if (DISPLAY_VER(display) >= 20) { + display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.table = xe2lpd_cdclk_table; + } else if (DISPLAY_VER_FULL(display) >= IP_VER(14, 1)) { + display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.table = xe2hpd_cdclk_table; + } else if (DISPLAY_VER(display) >= 14) { + display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.table = mtl_cdclk_table; } else if (IS_DG2(dev_priv)) { - dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs; - dev_priv->display.cdclk.table = dg2_cdclk_table; + display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { /* Wa_22011320316:adl-p[a0] */ if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { - dev_priv->display.cdclk.table = adlp_a_step_cdclk_table; - dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.table = adlp_a_step_cdclk_table; + display->funcs.cdclk = &tgl_cdclk_funcs; } else if (IS_RAPTORLAKE_U(dev_priv)) { - dev_priv->display.cdclk.table = rplu_cdclk_table; - dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.table = rplu_cdclk_table; + display->funcs.cdclk = &rplu_cdclk_funcs; } else { - dev_priv->display.cdclk.table = adlp_cdclk_table; - dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.table = adlp_cdclk_table; + display->funcs.cdclk = &tgl_cdclk_funcs; } } else if (IS_ROCKETLAKE(dev_priv)) { - dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs; - dev_priv->display.cdclk.table = rkl_cdclk_table; - } else if (DISPLAY_VER(dev_priv) >= 12) { - dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs; - dev_priv->display.cdclk.table = icl_cdclk_table; + display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.table = rkl_cdclk_table; + } else if (DISPLAY_VER(display) >= 12) { + display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.table = icl_cdclk_table; } else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { - dev_priv->display.funcs.cdclk = &ehl_cdclk_funcs; - dev_priv->display.cdclk.table = icl_cdclk_table; - } else if (DISPLAY_VER(dev_priv) >= 11) { - dev_priv->display.funcs.cdclk = &icl_cdclk_funcs; - dev_priv->display.cdclk.table = icl_cdclk_table; + display->funcs.cdclk = &ehl_cdclk_funcs; + display->cdclk.table = icl_cdclk_table; + } else if (DISPLAY_VER(display) >= 11) { + display->funcs.cdclk = &icl_cdclk_funcs; + display->cdclk.table = icl_cdclk_table; } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { - dev_priv->display.funcs.cdclk = &bxt_cdclk_funcs; + display->funcs.cdclk = &bxt_cdclk_funcs; if (IS_GEMINILAKE(dev_priv)) - dev_priv->display.cdclk.table = glk_cdclk_table; + display->cdclk.table = glk_cdclk_table; else - dev_priv->display.cdclk.table = bxt_cdclk_table; - } else if (DISPLAY_VER(dev_priv) == 9) { - dev_priv->display.funcs.cdclk = &skl_cdclk_funcs; + display->cdclk.table = bxt_cdclk_table; + } else if (DISPLAY_VER(display) == 9) { + display->funcs.cdclk = &skl_cdclk_funcs; } else if (IS_BROADWELL(dev_priv)) { - dev_priv->display.funcs.cdclk = &bdw_cdclk_funcs; + display->funcs.cdclk = &bdw_cdclk_funcs; } else if (IS_HASWELL(dev_priv)) { - dev_priv->display.funcs.cdclk = &hsw_cdclk_funcs; + display->funcs.cdclk = &hsw_cdclk_funcs; } else if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.funcs.cdclk = &chv_cdclk_funcs; + display->funcs.cdclk = &chv_cdclk_funcs; } else if (IS_VALLEYVIEW(dev_priv)) { - dev_priv->display.funcs.cdclk = &vlv_cdclk_funcs; + display->funcs.cdclk = &vlv_cdclk_funcs; } else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) { - dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs; + display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; } else if (IS_IRONLAKE(dev_priv)) { - dev_priv->display.funcs.cdclk = &ilk_cdclk_funcs; + display->funcs.cdclk = &ilk_cdclk_funcs; } else if (IS_GM45(dev_priv)) { - dev_priv->display.funcs.cdclk = &gm45_cdclk_funcs; + display->funcs.cdclk = &gm45_cdclk_funcs; } else if (IS_G45(dev_priv)) { - dev_priv->display.funcs.cdclk = &g33_cdclk_funcs; + display->funcs.cdclk = &g33_cdclk_funcs; } else if (IS_I965GM(dev_priv)) { - dev_priv->display.funcs.cdclk = &i965gm_cdclk_funcs; + display->funcs.cdclk = &i965gm_cdclk_funcs; } else if (IS_I965G(dev_priv)) { - dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs; + display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; } else if (IS_PINEVIEW(dev_priv)) { - dev_priv->display.funcs.cdclk = &pnv_cdclk_funcs; + display->funcs.cdclk = &pnv_cdclk_funcs; } else if (IS_G33(dev_priv)) { - dev_priv->display.funcs.cdclk = &g33_cdclk_funcs; + display->funcs.cdclk = &g33_cdclk_funcs; } else if (IS_I945GM(dev_priv)) { - dev_priv->display.funcs.cdclk = &i945gm_cdclk_funcs; + display->funcs.cdclk = &i945gm_cdclk_funcs; } else if (IS_I945G(dev_priv)) { - dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs; + display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; } else if (IS_I915GM(dev_priv)) { - dev_priv->display.funcs.cdclk = &i915gm_cdclk_funcs; + display->funcs.cdclk = &i915gm_cdclk_funcs; } else if (IS_I915G(dev_priv)) { - dev_priv->display.funcs.cdclk = &i915g_cdclk_funcs; + display->funcs.cdclk = &i915g_cdclk_funcs; } else if (IS_I865G(dev_priv)) { - dev_priv->display.funcs.cdclk = &i865g_cdclk_funcs; + display->funcs.cdclk = &i865g_cdclk_funcs; } else if (IS_I85X(dev_priv)) { - dev_priv->display.funcs.cdclk = &i85x_cdclk_funcs; + display->funcs.cdclk = &i85x_cdclk_funcs; } else if (IS_I845G(dev_priv)) { - dev_priv->display.funcs.cdclk = &i845g_cdclk_funcs; + display->funcs.cdclk = &i845g_cdclk_funcs; } else if (IS_I830(dev_priv)) { - dev_priv->display.funcs.cdclk = &i830_cdclk_funcs; + display->funcs.cdclk = &i830_cdclk_funcs; } - if (drm_WARN(&dev_priv->drm, !dev_priv->display.funcs.cdclk, + if (drm_WARN(display->drm, !display->funcs.cdclk, "Unknown platform. Assuming i830\n")) - dev_priv->display.funcs.cdclk = &i830_cdclk_funcs; + display->funcs.cdclk = &i830_cdclk_funcs; } diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index 1fe445a3a30b..6b0e7a41eba3 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -11,9 +11,9 @@ #include "intel_display_limits.h" #include "intel_global_state.h" -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc_state; +struct intel_display; struct intel_cdclk_config { unsigned int cdclk, vco, ref, bypass; @@ -59,24 +59,24 @@ struct intel_cdclk_state { }; int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); -void intel_cdclk_init_hw(struct drm_i915_private *i915); -void intel_cdclk_uninit_hw(struct drm_i915_private *i915); -void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); -void intel_update_max_cdclk(struct drm_i915_private *dev_priv); -void intel_update_cdclk(struct drm_i915_private *dev_priv); -u32 intel_read_rawclk(struct drm_i915_private *dev_priv); +void intel_cdclk_init_hw(struct intel_display *display); +void intel_cdclk_uninit_hw(struct intel_display *display); +void intel_init_cdclk_hooks(struct intel_display *display); +void intel_update_max_cdclk(struct intel_display *display); +void intel_update_cdclk(struct intel_display *display); +u32 intel_read_rawclk(struct intel_display *display); bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a, const struct intel_cdclk_config *b); -int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915, +int intel_mdclk_cdclk_ratio(struct intel_display *display, const struct intel_cdclk_config *cdclk_config); bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state); void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state); void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state); -void intel_cdclk_dump_config(struct drm_i915_private *i915, +void intel_cdclk_dump_config(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, const char *context); int intel_modeset_calc_cdclk(struct intel_atomic_state *state); -void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, +void intel_cdclk_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config); int intel_cdclk_atomic_check(struct intel_atomic_state *state, bool *need_cdclk_calc); @@ -92,7 +92,7 @@ intel_atomic_get_cdclk_state(struct intel_atomic_state *state); #define intel_atomic_get_new_cdclk_state(state) \ to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->cdclk.obj)) -int intel_cdclk_init(struct drm_i915_private *dev_priv); -void intel_cdclk_debugfs_register(struct drm_i915_private *i915); +int intel_cdclk_init(struct intel_display *display); +void intel_cdclk_debugfs_register(struct intel_display *display); #endif /* __INTEL_CDCLK_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 830b9eb60976..c1bef34d1ffd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1068,7 +1068,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) minor->debugfs_root, minor); intel_bios_debugfs_register(display); - intel_cdclk_debugfs_register(i915); + intel_cdclk_debugfs_register(display); intel_dmc_debugfs_register(i915); intel_fbc_debugfs_register(display); intel_hpd_debugfs_register(i915); diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 408c76852495..f33062322c66 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1532,6 +1532,7 @@ void intel_display_device_remove(struct drm_i915_private *i915) static void __intel_display_device_info_runtime_init(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915); enum pipe pipe; @@ -1678,7 +1679,7 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9 } } - display_runtime->rawclk_freq = intel_read_rawclk(i915); + display_runtime->rawclk_freq = intel_read_rawclk(display); drm_dbg_kms(&i915->drm, "rawclk rate: %d kHz\n", display_runtime->rawclk_freq); return; diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index e7670774ecd0..434e52f450ff 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -82,16 +82,17 @@ bool intel_display_driver_probe_defer(struct pci_dev *pdev) void intel_display_driver_init_hw(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_cdclk_state *cdclk_state; if (!HAS_DISPLAY(i915)) return; - cdclk_state = to_intel_cdclk_state(i915->display.cdclk.obj.state); + cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state); - intel_update_cdclk(i915); - intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK"); - cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw; + intel_update_cdclk(display); + intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); + cdclk_state->logical = cdclk_state->actual = display->cdclk.hw; intel_display_wa_apply(i915); } @@ -194,7 +195,7 @@ void intel_display_driver_early_probe(struct drm_i915_private *i915) intel_display_irq_init(i915); intel_dkl_phy_init(i915); intel_color_init_hooks(i915); - intel_init_cdclk_hooks(i915); + intel_init_cdclk_hooks(&i915->display); intel_audio_hooks_init(i915); intel_dpll_init_clock_hook(i915); intel_init_display_hooks(i915); @@ -244,7 +245,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) intel_mode_config_init(i915); - ret = intel_cdclk_init(i915); + ret = intel_cdclk_init(display); if (ret) goto cleanup_vga_client_pw_domain_dmc; @@ -451,8 +452,8 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915) intel_display_driver_init_hw(i915); intel_dpll_update_ref_clks(i915); - if (i915->display.cdclk.max_cdclk_freq == 0) - intel_update_max_cdclk(i915); + if (display->cdclk.max_cdclk_freq == 0) + intel_update_max_cdclk(display); intel_hti_init(display); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index ef2fdbf97346..eb3e2a56af1d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1300,6 +1300,7 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv, */ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; u32 val; val = intel_de_read(dev_priv, LCPLL_CTL); @@ -1343,8 +1344,8 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); - intel_update_cdclk(dev_priv); - intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK"); + intel_update_cdclk(display); + intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); } /* @@ -1416,7 +1417,8 @@ static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv, static void skl_display_core_init(struct drm_i915_private *dev_priv, bool resume) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -1438,7 +1440,7 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, mutex_unlock(&power_domains->lock); - intel_cdclk_init_hw(dev_priv); + intel_cdclk_init_hw(display); gen9_dbuf_enable(dev_priv); @@ -1448,7 +1450,8 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, static void skl_display_core_uninit(struct drm_i915_private *dev_priv) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; if (!HAS_DISPLAY(dev_priv)) @@ -1459,7 +1462,7 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv) gen9_dbuf_disable(dev_priv); - intel_cdclk_uninit_hw(dev_priv); + intel_cdclk_uninit_hw(display); /* The spec doesn't call for removing the reset handshake flag */ /* disable PG1 and Misc I/O */ @@ -1482,7 +1485,8 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv) static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -1506,7 +1510,7 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume mutex_unlock(&power_domains->lock); - intel_cdclk_init_hw(dev_priv); + intel_cdclk_init_hw(display); gen9_dbuf_enable(dev_priv); @@ -1516,7 +1520,8 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume static void bxt_display_core_uninit(struct drm_i915_private *dev_priv) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; if (!HAS_DISPLAY(dev_priv)) @@ -1527,7 +1532,7 @@ static void bxt_display_core_uninit(struct drm_i915_private *dev_priv) gen9_dbuf_disable(dev_priv); - intel_cdclk_uninit_hw(dev_priv); + intel_cdclk_uninit_hw(display); /* The spec doesn't call for removing the reset handshake flag */ @@ -1623,7 +1628,8 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv) static void icl_display_core_init(struct drm_i915_private *dev_priv, bool resume) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -1657,7 +1663,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, HOLD_PHY_PG1_LATCH | HOLD_PHY_CLKREQ_PG1_LATCH, 0); /* 4. Enable CDCLK. */ - intel_cdclk_init_hw(dev_priv); + intel_cdclk_init_hw(display); if (DISPLAY_VER(dev_priv) >= 12) gen12_dbuf_slices_config(dev_priv); @@ -1704,7 +1710,8 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, static void icl_display_core_uninit(struct drm_i915_private *dev_priv) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; if (!HAS_DISPLAY(dev_priv)) @@ -1719,7 +1726,7 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv) gen9_dbuf_disable(dev_priv); /* 3. Disable CD clock */ - intel_cdclk_uninit_hw(dev_priv); + intel_cdclk_uninit_hw(display); if (DISPLAY_VER(dev_priv) == 14) intel_de_rmw(dev_priv, DC_STATE_EN, 0, 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 46e9eff12c23..7b40a5b88214 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -967,7 +967,8 @@ static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv) void gen9_disable_dc_states(struct drm_i915_private *dev_priv) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; struct intel_cdclk_config cdclk_config = {}; if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) { @@ -982,10 +983,10 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv) intel_dmc_wl_disable(&dev_priv->display); - intel_cdclk_get_cdclk(dev_priv, &cdclk_config); + intel_cdclk_get_cdclk(display, &cdclk_config); /* Can't read out voltage_level so can't use intel_cdclk_changed() */ - drm_WARN_ON(&dev_priv->drm, - intel_cdclk_clock_changed(&dev_priv->display.cdclk.hw, + drm_WARN_ON(display->drm, + intel_cdclk_clock_changed(&display->cdclk.hw, &cdclk_config)); gen9_assert_dbuf_enabled(dev_priv); diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 29835b638495..6e1f04d5ef47 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2973,6 +2973,7 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, static void skl_wm_get_hw_state(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(i915->display.dbuf.obj.state); struct intel_crtc *crtc; @@ -2980,7 +2981,7 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915) if (HAS_MBUS_JOINING(i915)) dbuf_state->joined_mbus = intel_de_read(i915, MBUS_CTL) & MBUS_JOIN; - dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(i915, &i915->display.cdclk.hw); + dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw); for_each_intel_crtc(&i915->drm, crtc) { struct intel_crtc_state *crtc_state = From 08648ad9b725a648146dc37e0a568be945631038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 6 Sep 2024 17:33:03 +0300 Subject: [PATCH 024/205] drm/i915/power: Convert low level DC state code to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the lower level DC state code to use it (as much as possible at this stage). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240906143306.15937-4-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi --- .../drm/i915/display/intel_display_power.c | 41 ++-- .../i915/display/intel_display_power_well.c | 199 ++++++++++-------- .../i915/display/intel_display_power_well.h | 15 +- 3 files changed, 139 insertions(+), 116 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index eb3e2a56af1d..86ac494ed33b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1421,7 +1421,7 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + gen9_set_dc_state(display, DC_STATE_DISABLE); /* enable PCH reset handshake */ intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); @@ -1457,7 +1457,7 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; - gen9_disable_dc_states(dev_priv); + gen9_disable_dc_states(display); /* TODO: disable DMC program */ gen9_dbuf_disable(dev_priv); @@ -1489,7 +1489,7 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + gen9_set_dc_state(display, DC_STATE_DISABLE); /* * NDE_RSTWRN_OPT RST PCH Handshake En must always be 0b on BXT @@ -1527,7 +1527,7 @@ static void bxt_display_core_uninit(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; - gen9_disable_dc_states(dev_priv); + gen9_disable_dc_states(display); /* TODO: disable DMC program */ gen9_dbuf_disable(dev_priv); @@ -1632,7 +1632,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + gen9_set_dc_state(display, DC_STATE_DISABLE); /* Wa_14011294188:ehl,jsl,tgl,rkl,adl-s */ if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && @@ -1717,7 +1717,7 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; - gen9_disable_dc_states(dev_priv); + gen9_disable_dc_states(display); intel_dmc_disable_program(dev_priv); /* 1. Disable all display engine functions -> aready done */ @@ -2232,9 +2232,11 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915) void intel_display_power_suspend_late(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; + if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { - bxt_enable_dc9(i915); + bxt_enable_dc9(display); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_enable_pc8(i915); } @@ -2246,10 +2248,12 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915) void intel_display_power_resume_early(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; + if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { - gen9_sanitize_dc_state(i915); - bxt_disable_dc9(i915); + gen9_sanitize_dc_state(display); + bxt_disable_dc9(display); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_disable_pc8(i915); } @@ -2261,12 +2265,14 @@ void intel_display_power_resume_early(struct drm_i915_private *i915) void intel_display_power_suspend(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; + if (DISPLAY_VER(i915) >= 11) { icl_display_core_uninit(i915); - bxt_enable_dc9(i915); + bxt_enable_dc9(display); } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { bxt_display_core_uninit(i915); - bxt_enable_dc9(i915); + bxt_enable_dc9(display); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_enable_pc8(i915); } @@ -2274,23 +2280,24 @@ void intel_display_power_suspend(struct drm_i915_private *i915) void intel_display_power_resume(struct drm_i915_private *i915) { - struct i915_power_domains *power_domains = &i915->display.power.domains; + struct intel_display *display = &i915->display; + struct i915_power_domains *power_domains = &display->power.domains; if (DISPLAY_VER(i915) >= 11) { - bxt_disable_dc9(i915); + bxt_disable_dc9(display); icl_display_core_init(i915, true); if (intel_dmc_has_payload(i915)) { if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC6) - skl_enable_dc6(i915); + skl_enable_dc6(display); else if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5) - gen9_enable_dc5(i915); + gen9_enable_dc5(display); } } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { - bxt_disable_dc9(i915); + bxt_disable_dc9(display); bxt_display_core_init(i915, true); if (intel_dmc_has_payload(i915) && (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5)) - gen9_enable_dc5(i915); + gen9_enable_dc5(display); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_disable_pc8(i915); } 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 7b40a5b88214..1f0084ca6248 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -601,20 +601,22 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, return (val & mask) == mask; } -static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) +static void assert_can_enable_dc9(struct intel_display *display) { - drm_WARN_ONCE(&dev_priv->drm, - (intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_DC9), + struct drm_i915_private *dev_priv = to_i915(display->drm); + + drm_WARN_ONCE(display->drm, + (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_DC9), "DC9 already programmed to be enabled.\n"); - drm_WARN_ONCE(&dev_priv->drm, - intel_de_read(dev_priv, DC_STATE_EN) & + drm_WARN_ONCE(display->drm, + intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, "DC5 still not disabled to enable DC9.\n"); - drm_WARN_ONCE(&dev_priv->drm, - intel_de_read(dev_priv, HSW_PWR_WELL_CTL2) & + drm_WARN_ONCE(display->drm, + intel_de_read(display, HSW_PWR_WELL_CTL2) & HSW_PWR_WELL_CTL_REQ(SKL_PW_CTL_IDX_PW_2), "Power well 2 on.\n"); - drm_WARN_ONCE(&dev_priv->drm, intel_irqs_enabled(dev_priv), + drm_WARN_ONCE(display->drm, intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); /* @@ -626,12 +628,14 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) */ } -static void assert_can_disable_dc9(struct drm_i915_private *dev_priv) +static void assert_can_disable_dc9(struct intel_display *display) { - drm_WARN_ONCE(&dev_priv->drm, intel_irqs_enabled(dev_priv), + struct drm_i915_private *dev_priv = to_i915(display->drm); + + drm_WARN_ONCE(display->drm, intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); - drm_WARN_ONCE(&dev_priv->drm, - intel_de_read(dev_priv, DC_STATE_EN) & + drm_WARN_ONCE(display->drm, + intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, "DC5 still not disabled.\n"); @@ -644,14 +648,14 @@ static void assert_can_disable_dc9(struct drm_i915_private *dev_priv) */ } -static void gen9_write_dc_state(struct drm_i915_private *dev_priv, +static void gen9_write_dc_state(struct intel_display *display, u32 state) { int rewrites = 0; int rereads = 0; u32 v; - intel_de_write(dev_priv, DC_STATE_EN, state); + intel_de_write(display, DC_STATE_EN, state); /* It has been observed that disabling the dc6 state sometimes * doesn't stick and dmc keeps returning old value. Make sure @@ -659,10 +663,10 @@ static void gen9_write_dc_state(struct drm_i915_private *dev_priv, * we are confident that state is exactly what we want. */ do { - v = intel_de_read(dev_priv, DC_STATE_EN); + v = intel_de_read(display, DC_STATE_EN); if (v != state) { - intel_de_write(dev_priv, DC_STATE_EN, state); + intel_de_write(display, DC_STATE_EN, state); rewrites++; rereads = 0; } else if (rereads++ > 5) { @@ -672,27 +676,28 @@ static void gen9_write_dc_state(struct drm_i915_private *dev_priv, } while (rewrites < 100); if (v != state) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Writing dc state to 0x%x failed, now 0x%x\n", state, v); /* Most of the times we need one retry, avoid spam */ if (rewrites > 1) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Rewrote dc state to 0x%x %d times\n", state, rewrites); } -static u32 gen9_dc_mask(struct drm_i915_private *dev_priv) +static u32 gen9_dc_mask(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 mask; mask = DC_STATE_EN_UPTO_DC5; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9; - else if (DISPLAY_VER(dev_priv) == 11) + else if (DISPLAY_VER(display) == 11) mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9; else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) mask |= DC_STATE_EN_DC9; @@ -702,17 +707,17 @@ static u32 gen9_dc_mask(struct drm_i915_private *dev_priv) return mask; } -void gen9_sanitize_dc_state(struct drm_i915_private *i915) +void gen9_sanitize_dc_state(struct intel_display *display) { - struct i915_power_domains *power_domains = &i915->display.power.domains; + struct i915_power_domains *power_domains = &display->power.domains; u32 val; - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; - val = intel_de_read(i915, DC_STATE_EN) & gen9_dc_mask(i915); + val = intel_de_read(display, DC_STATE_EN) & gen9_dc_mask(display); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Resetting DC state tracking from %02x to %02x\n", power_domains->dc_state, val); power_domains->dc_state = val; @@ -720,7 +725,7 @@ void gen9_sanitize_dc_state(struct drm_i915_private *i915) /** * gen9_set_dc_state - set target display C power state - * @dev_priv: i915 device instance + * @display: display instance * @state: target DC power state * - DC_STATE_DISABLE * - DC_STATE_EN_UPTO_DC5 @@ -741,70 +746,71 @@ void gen9_sanitize_dc_state(struct drm_i915_private *i915) * back on and register state is restored. This is guaranteed by the MMIO write * to DC_STATE_EN blocking until the state is restored. */ -void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state) +void gen9_set_dc_state(struct intel_display *display, u32 state) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct i915_power_domains *power_domains = &display->power.domains; u32 val; u32 mask; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, + if (drm_WARN_ON_ONCE(display->drm, state & ~power_domains->allowed_dc_mask)) state &= power_domains->allowed_dc_mask; - val = intel_de_read(dev_priv, DC_STATE_EN); - mask = gen9_dc_mask(dev_priv); - drm_dbg_kms(&dev_priv->drm, "Setting DC state from %02x to %02x\n", + val = intel_de_read(display, DC_STATE_EN); + mask = gen9_dc_mask(display); + drm_dbg_kms(display->drm, "Setting DC state from %02x to %02x\n", val & mask, state); /* Check if DMC is ignoring our DC state requests */ if ((val & mask) != power_domains->dc_state) - drm_err(&dev_priv->drm, "DC state mismatch (0x%x -> 0x%x)\n", + drm_err(display->drm, "DC state mismatch (0x%x -> 0x%x)\n", power_domains->dc_state, val & mask); val &= ~mask; val |= state; - gen9_write_dc_state(dev_priv, val); + gen9_write_dc_state(display, val); power_domains->dc_state = val & mask; } -static void tgl_enable_dc3co(struct drm_i915_private *dev_priv) +static void tgl_enable_dc3co(struct intel_display *display) { - drm_dbg_kms(&dev_priv->drm, "Enabling DC3CO\n"); - gen9_set_dc_state(dev_priv, DC_STATE_EN_DC3CO); + drm_dbg_kms(display->drm, "Enabling DC3CO\n"); + gen9_set_dc_state(display, DC_STATE_EN_DC3CO); } -static void tgl_disable_dc3co(struct drm_i915_private *dev_priv) +static void tgl_disable_dc3co(struct intel_display *display) { - drm_dbg_kms(&dev_priv->drm, "Disabling DC3CO\n"); - intel_de_rmw(dev_priv, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0); - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + drm_dbg_kms(display->drm, "Disabling DC3CO\n"); + intel_de_rmw(display, DC_STATE_EN, DC_STATE_DC3CO_STATUS, 0); + gen9_set_dc_state(display, DC_STATE_DISABLE); /* * Delay of 200us DC3CO Exit time B.Spec 49196 */ usleep_range(200, 210); } -static void assert_can_enable_dc5(struct drm_i915_private *dev_priv) +static void assert_can_enable_dc5(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); enum i915_power_well_id high_pg; /* Power wells at this level and above must be disabled for DC5 entry */ - if (DISPLAY_VER(dev_priv) == 12) + if (DISPLAY_VER(display) == 12) high_pg = ICL_DISP_PW_3; else high_pg = SKL_DISP_PW_2; - drm_WARN_ONCE(&dev_priv->drm, + drm_WARN_ONCE(display->drm, intel_display_power_well_is_enabled(dev_priv, high_pg), "Power wells above platform's DC5 limit still enabled.\n"); - drm_WARN_ONCE(&dev_priv->drm, - (intel_de_read(dev_priv, DC_STATE_EN) & + drm_WARN_ONCE(display->drm, + (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5), "DC5 already programmed to be enabled.\n"); assert_rpm_wakelock_held(&dev_priv->runtime_pm); @@ -812,60 +818,66 @@ static void assert_can_enable_dc5(struct drm_i915_private *dev_priv) assert_dmc_loaded(dev_priv); } -void gen9_enable_dc5(struct drm_i915_private *dev_priv) +void gen9_enable_dc5(struct intel_display *display) { - assert_can_enable_dc5(dev_priv); + struct drm_i915_private *dev_priv = to_i915(display->drm); - drm_dbg_kms(&dev_priv->drm, "Enabling DC5\n"); + assert_can_enable_dc5(display); + + drm_dbg_kms(display->drm, "Enabling DC5\n"); /* Wa Display #1183: skl,kbl,cfl */ - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) - intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, + if (DISPLAY_VER(display) == 9 && !IS_BROXTON(dev_priv)) + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, 0, SKL_SELECT_ALTERNATE_DC_EXIT); - intel_dmc_wl_enable(&dev_priv->display); + intel_dmc_wl_enable(display); - gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5); + gen9_set_dc_state(display, DC_STATE_EN_UPTO_DC5); } -static void assert_can_enable_dc6(struct drm_i915_private *dev_priv) +static void assert_can_enable_dc6(struct intel_display *display) { - drm_WARN_ONCE(&dev_priv->drm, - (intel_de_read(dev_priv, UTIL_PIN_CTL) & + struct drm_i915_private *dev_priv = to_i915(display->drm); + + drm_WARN_ONCE(display->drm, + (intel_de_read(display, UTIL_PIN_CTL) & (UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) == (UTIL_PIN_ENABLE | UTIL_PIN_MODE_PWM), "Utility pin enabled in PWM mode\n"); - drm_WARN_ONCE(&dev_priv->drm, - (intel_de_read(dev_priv, DC_STATE_EN) & + drm_WARN_ONCE(display->drm, + (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC6), "DC6 already programmed to be enabled.\n"); assert_dmc_loaded(dev_priv); } -void skl_enable_dc6(struct drm_i915_private *dev_priv) +void skl_enable_dc6(struct intel_display *display) { - assert_can_enable_dc6(dev_priv); + struct drm_i915_private *dev_priv = to_i915(display->drm); - drm_dbg_kms(&dev_priv->drm, "Enabling DC6\n"); + assert_can_enable_dc6(display); + + drm_dbg_kms(display->drm, "Enabling DC6\n"); /* Wa Display #1183: skl,kbl,cfl */ - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) - intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, + if (DISPLAY_VER(display) == 9 && !IS_BROXTON(dev_priv)) + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, 0, SKL_SELECT_ALTERNATE_DC_EXIT); - intel_dmc_wl_enable(&dev_priv->display); + intel_dmc_wl_enable(display); - gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); + gen9_set_dc_state(display, DC_STATE_EN_UPTO_DC6); } -void bxt_enable_dc9(struct drm_i915_private *dev_priv) +void bxt_enable_dc9(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); - assert_can_enable_dc9(dev_priv); + assert_can_enable_dc9(display); - drm_dbg_kms(&dev_priv->drm, "Enabling DC9\n"); + drm_dbg_kms(display->drm, "Enabling DC9\n"); /* * Power sequencer reset is not needed on * platforms with South Display Engine on PCH, @@ -873,18 +885,16 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv) */ if (!HAS_PCH_SPLIT(dev_priv)) intel_pps_reset_all(display); - gen9_set_dc_state(dev_priv, DC_STATE_EN_DC9); + gen9_set_dc_state(display, DC_STATE_EN_DC9); } -void bxt_disable_dc9(struct drm_i915_private *dev_priv) +void bxt_disable_dc9(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + assert_can_disable_dc9(display); - assert_can_disable_dc9(dev_priv); + drm_dbg_kms(display->drm, "Disabling DC9\n"); - drm_dbg_kms(&dev_priv->drm, "Disabling DC9\n"); - - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + gen9_set_dc_state(display, DC_STATE_DISABLE); intel_pps_unlock_regs_wa(display); } @@ -949,8 +959,10 @@ static void bxt_verify_dpio_phy_power_wells(struct drm_i915_private *dev_priv) static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - return ((intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_DC3CO) == 0 && - (intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0); + struct intel_display *display = &dev_priv->display; + + return ((intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_DC3CO) == 0 && + (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0); } static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv) @@ -965,23 +977,23 @@ static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv) enabled_dbuf_slices); } -void gen9_disable_dc_states(struct drm_i915_private *dev_priv) +void gen9_disable_dc_states(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_cdclk_config cdclk_config = {}; if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) { - tgl_disable_dc3co(dev_priv); + tgl_disable_dc3co(display); return; } - gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); + gen9_set_dc_state(display, DC_STATE_DISABLE); - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - intel_dmc_wl_disable(&dev_priv->display); + intel_dmc_wl_disable(display); intel_cdclk_get_cdclk(display, &cdclk_config); /* Can't read out voltage_level so can't use intel_cdclk_changed() */ @@ -994,7 +1006,7 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) bxt_verify_dpio_phy_power_wells(dev_priv); - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) /* * DMC retains HW context only for port A, the other combo * PHY's HW context for port B is lost after DC transitions, @@ -1006,26 +1018,29 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv) static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - gen9_disable_dc_states(dev_priv); + struct intel_display *display = &dev_priv->display; + + gen9_disable_dc_states(display); } static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + struct intel_display *display = &dev_priv->display; + struct i915_power_domains *power_domains = &display->power.domains; if (!intel_dmc_has_payload(dev_priv)) return; switch (power_domains->target_dc_state) { case DC_STATE_EN_DC3CO: - tgl_enable_dc3co(dev_priv); + tgl_enable_dc3co(display); break; case DC_STATE_EN_UPTO_DC6: - skl_enable_dc6(dev_priv); + skl_enable_dc6(display); break; case DC_STATE_EN_UPTO_DC5: - gen9_enable_dc5(dev_priv); + gen9_enable_dc5(display); break; } } diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.h b/drivers/gpu/drm/i915/display/intel_display_power_well.h index 9357a9a73c06..93559f7c6100 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.h +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.h @@ -12,6 +12,7 @@ struct drm_i915_private; struct i915_power_well_ops; +struct intel_display; struct intel_encoder; #define for_each_power_well(__dev_priv, __power_well) \ @@ -154,13 +155,13 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder, bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, enum dpio_channel ch, bool override); -void gen9_enable_dc5(struct drm_i915_private *dev_priv); -void skl_enable_dc6(struct drm_i915_private *dev_priv); -void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv); -void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state); -void gen9_disable_dc_states(struct drm_i915_private *dev_priv); -void bxt_enable_dc9(struct drm_i915_private *dev_priv); -void bxt_disable_dc9(struct drm_i915_private *dev_priv); +void gen9_enable_dc5(struct intel_display *display); +void skl_enable_dc6(struct intel_display *display); +void gen9_sanitize_dc_state(struct intel_display *display); +void gen9_set_dc_state(struct intel_display *display, u32 state); +void gen9_disable_dc_states(struct intel_display *display); +void bxt_enable_dc9(struct intel_display *display); +void bxt_disable_dc9(struct intel_display *display); extern const struct i915_power_well_ops i9xx_always_on_power_well_ops; extern const struct i915_power_well_ops chv_pipe_power_well_ops; From 4b6e05c43b7542e9baaf70a0064b9198fe495fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 6 Sep 2024 17:33:04 +0300 Subject: [PATCH 025/205] drm/i915/vga: Convert VGA code to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the VGA code to use it (as much as possible at this stage). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240906143306.15937-5-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi --- .../drm/i915/display/intel_display_driver.c | 11 ++--- .../i915/display/intel_display_power_well.c | 6 ++- drivers/gpu/drm/i915/display/intel_vga.c | 45 ++++++++++--------- drivers/gpu/drm/i915/display/intel_vga.h | 14 +++--- drivers/gpu/drm/i915/i915_suspend.c | 3 +- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 434e52f450ff..f8da72af2107 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -221,7 +221,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) intel_bios_init(display); - ret = intel_vga_register(i915); + ret = intel_vga_register(display); if (ret) goto cleanup_bios; @@ -275,7 +275,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) intel_dmc_fini(i915); intel_power_domains_driver_remove(i915); cleanup_vga: - intel_vga_unregister(i915); + intel_vga_unregister(display); cleanup_bios: intel_bios_driver_remove(display); @@ -458,7 +458,7 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915) intel_hti_init(display); /* Just disable it once at startup */ - intel_vga_disable(i915); + intel_vga_disable(display); intel_setup_outputs(i915); ret = intel_dp_tunnel_mgr_init(display); @@ -625,7 +625,7 @@ void intel_display_driver_remove_nogem(struct drm_i915_private *i915) intel_power_domains_driver_remove(i915); - intel_vga_unregister(i915); + intel_vga_unregister(display); intel_bios_driver_remove(display); } @@ -683,12 +683,13 @@ __intel_display_driver_resume(struct drm_i915_private *i915, struct drm_atomic_state *state, struct drm_modeset_acquire_ctx *ctx) { + struct intel_display *display = &i915->display; struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; int ret, i; intel_modeset_setup_hw_state(i915, ctx); - intel_vga_redisable(i915); + intel_vga_redisable(display); if (!state) return 0; 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 1f0084ca6248..a5d9b17e03a2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -187,8 +187,10 @@ int intel_power_well_refcount(struct i915_power_well *power_well) static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv, u8 irq_pipe_mask, bool has_vga) { + struct intel_display *display = &dev_priv->display; + if (has_vga) - intel_vga_reset_io_mem(dev_priv); + intel_vga_reset_io_mem(display); if (irq_pipe_mask) gen8_irq_power_well_post_enable(dev_priv, irq_pipe_mask); @@ -1248,7 +1250,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv) intel_crt_reset(&encoder->base); } - intel_vga_redisable_power_on(dev_priv); + intel_vga_redisable_power_on(display); intel_pps_unlock_regs_wa(display); } diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c index 0b5916c15307..2c76a0176a35 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.c +++ b/drivers/gpu/drm/i915/display/intel_vga.c @@ -14,24 +14,26 @@ #include "intel_de.h" #include "intel_vga.h" -static i915_reg_t intel_vga_cntrl_reg(struct drm_i915_private *i915) +static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); + if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) return VLV_VGACNTRL; - else if (DISPLAY_VER(i915) >= 5) + else if (DISPLAY_VER(display) >= 5) return CPU_VGACNTRL; else return VGACNTRL; } /* Disable the VGA plane that we never use */ -void intel_vga_disable(struct drm_i915_private *dev_priv) +void intel_vga_disable(struct intel_display *display) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); + i915_reg_t vga_reg = intel_vga_cntrl_reg(display); u8 sr1; - if (intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE) + if (intel_de_read(display, vga_reg) & VGA_DISP_DISABLE) return; /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ @@ -42,23 +44,24 @@ void intel_vga_disable(struct drm_i915_private *dev_priv) vga_put(pdev, VGA_RSRC_LEGACY_IO); udelay(300); - intel_de_write(dev_priv, vga_reg, VGA_DISP_DISABLE); - intel_de_posting_read(dev_priv, vga_reg); + intel_de_write(display, vga_reg, VGA_DISP_DISABLE); + intel_de_posting_read(display, vga_reg); } -void intel_vga_redisable_power_on(struct drm_i915_private *dev_priv) +void intel_vga_redisable_power_on(struct intel_display *display) { - i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv); + i915_reg_t vga_reg = intel_vga_cntrl_reg(display); - if (!(intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)) { - drm_dbg_kms(&dev_priv->drm, + if (!(intel_de_read(display, vga_reg) & VGA_DISP_DISABLE)) { + drm_dbg_kms(display->drm, "Something enabled VGA plane, disabling it\n"); - intel_vga_disable(dev_priv); + intel_vga_disable(display); } } -void intel_vga_redisable(struct drm_i915_private *i915) +void intel_vga_redisable(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref; /* @@ -74,14 +77,14 @@ void intel_vga_redisable(struct drm_i915_private *i915) if (!wakeref) return; - intel_vga_redisable_power_on(i915); + intel_vga_redisable_power_on(display); intel_display_power_put(i915, POWER_DOMAIN_VGA, wakeref); } -void intel_vga_reset_io_mem(struct drm_i915_private *i915) +void intel_vga_reset_io_mem(struct intel_display *display) { - struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); /* * After we re-enable the power well, if we touch VGA register 0x3d5 @@ -98,10 +101,10 @@ void intel_vga_reset_io_mem(struct drm_i915_private *i915) vga_put(pdev, VGA_RSRC_LEGACY_IO); } -int intel_vga_register(struct drm_i915_private *i915) +int intel_vga_register(struct intel_display *display) { - struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); int ret; /* @@ -119,9 +122,9 @@ int intel_vga_register(struct drm_i915_private *i915) return 0; } -void intel_vga_unregister(struct drm_i915_private *i915) +void intel_vga_unregister(struct intel_display *display) { - struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); vga_client_unregister(pdev); } diff --git a/drivers/gpu/drm/i915/display/intel_vga.h b/drivers/gpu/drm/i915/display/intel_vga.h index ba5b55b917f0..824dfc32a199 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.h +++ b/drivers/gpu/drm/i915/display/intel_vga.h @@ -6,13 +6,13 @@ #ifndef __INTEL_VGA_H__ #define __INTEL_VGA_H__ -struct drm_i915_private; +struct intel_display; -void intel_vga_reset_io_mem(struct drm_i915_private *i915); -void intel_vga_disable(struct drm_i915_private *i915); -void intel_vga_redisable(struct drm_i915_private *i915); -void intel_vga_redisable_power_on(struct drm_i915_private *i915); -int intel_vga_register(struct drm_i915_private *i915); -void intel_vga_unregister(struct drm_i915_private *i915); +void intel_vga_reset_io_mem(struct intel_display *display); +void intel_vga_disable(struct intel_display *display); +void intel_vga_redisable(struct intel_display *display); +void intel_vga_redisable_power_on(struct intel_display *display); +int intel_vga_register(struct intel_display *display); +void intel_vga_unregister(struct intel_display *display); #endif /* __INTEL_VGA_H__ */ diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index f8373a461f17..9d3d9b983032 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -118,6 +118,7 @@ void i915_save_display(struct drm_i915_private *dev_priv) void i915_restore_display(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); if (!HAS_DISPLAY(dev_priv)) @@ -134,7 +135,7 @@ void i915_restore_display(struct drm_i915_private *dev_priv) intel_de_write(dev_priv, DSPARB(dev_priv), dev_priv->regfile.saveDSPARB); - intel_vga_redisable(dev_priv); + intel_vga_redisable(display); intel_gmbus_reset(dev_priv); } From e9a114778d1f1a547c33cac99f1d8464598a3956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 6 Sep 2024 17:33:05 +0300 Subject: [PATCH 026/205] drm/i915/power: Convert "i830 power well" code to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the "i830 power well" code to use it (as much as possible at this stage). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240906143306.15937-6-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_display.c | 79 +++++++++---------- drivers/gpu/drm/i915/display/intel_display.h | 5 +- .../i915/display/intel_display_power_well.c | 22 ++++-- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b4ec9bf12aa7..0ec78b06ca80 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2226,9 +2226,10 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) static void i9xx_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; /* @@ -2267,7 +2268,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, /* clock the pipe down to 640x480@60 to potentially save power */ if (IS_I830(dev_priv)) - i830_enable_pipe(dev_priv, pipe); + i830_enable_pipe(display, pipe); } void intel_encoder_destroy(struct drm_encoder *encoder) @@ -8257,9 +8258,8 @@ int intel_initial_commit(struct drm_device *dev) return ret; } -void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +void i830_enable_pipe(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); enum transcoder cpu_transcoder = (enum transcoder)pipe; /* 640x480@60Hz, ~25175 kHz */ @@ -8273,10 +8273,10 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) u32 dpll, fp; int i; - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, i9xx_calc_dpll_params(48000, &clock) != 25154); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "enabling pipe %c due to force quirk (vco=%d dot=%d)\n", pipe_name(pipe), clock.vco, clock.dot); @@ -8288,35 +8288,35 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) PLL_REF_INPUT_DREFCLK | DPLL_VCO_ENABLE; - intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_HTOTAL(display, cpu_transcoder), HACTIVE(640 - 1) | HTOTAL(800 - 1)); - intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_HBLANK(display, cpu_transcoder), HBLANK_START(640 - 1) | HBLANK_END(800 - 1)); - intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_HSYNC(display, cpu_transcoder), HSYNC_START(656 - 1) | HSYNC_END(752 - 1)); - intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(480 - 1) | VTOTAL(525 - 1)); - intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VBLANK(display, cpu_transcoder), VBLANK_START(480 - 1) | VBLANK_END(525 - 1)); - intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VSYNC(display, cpu_transcoder), VSYNC_START(490 - 1) | VSYNC_END(492 - 1)); - intel_de_write(dev_priv, PIPESRC(dev_priv, pipe), + intel_de_write(display, PIPESRC(display, pipe), PIPESRC_WIDTH(640 - 1) | PIPESRC_HEIGHT(480 - 1)); - intel_de_write(dev_priv, FP0(pipe), fp); - intel_de_write(dev_priv, FP1(pipe), fp); + intel_de_write(display, FP0(pipe), fp); + intel_de_write(display, FP1(pipe), fp); /* * Apparently we need to have VGA mode enabled prior to changing * the P1/P2 dividers. Otherwise the DPLL will keep using the old * dividers, even though the register value does change. */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), dpll & ~DPLL_VGA_MODE_DIS); - intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll); + intel_de_write(display, DPLL(display, pipe), dpll); /* Wait for the clocks to stabilize. */ - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); /* The pixel multiplier can only be updated once the @@ -8324,47 +8324,46 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) * * So write it again. */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll); + intel_de_write(display, DPLL(display, pipe), dpll); /* We do this three times for luck */ for (i = 0; i < 3 ; i++) { - intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), dpll); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); /* wait for warmup */ } - intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), TRANSCONF_ENABLE); - intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe)); + intel_de_write(display, TRANSCONF(display, pipe), TRANSCONF_ENABLE); + intel_de_posting_read(display, TRANSCONF(display, pipe)); intel_wait_for_pipe_scanline_moving(crtc); } -void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +void i830_disable_pipe(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); - drm_dbg_kms(&dev_priv->drm, "disabling pipe %c due to force quirk\n", + drm_dbg_kms(display->drm, "disabling pipe %c due to force quirk\n", pipe_name(pipe)); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_A)) & DISP_ENABLE); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_B)) & DISP_ENABLE); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_C)) & DISP_ENABLE); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & MCURSOR_MODE_MASK); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_B)) & MCURSOR_MODE_MASK); + drm_WARN_ON(display->drm, + intel_de_read(display, DSPCNTR(display, PLANE_A)) & DISP_ENABLE); + drm_WARN_ON(display->drm, + intel_de_read(display, DSPCNTR(display, PLANE_B)) & DISP_ENABLE); + drm_WARN_ON(display->drm, + intel_de_read(display, DSPCNTR(display, PLANE_C)) & DISP_ENABLE); + drm_WARN_ON(display->drm, + intel_de_read(display, CURCNTR(display, PIPE_A)) & MCURSOR_MODE_MASK); + drm_WARN_ON(display->drm, + intel_de_read(display, CURCNTR(display, PIPE_B)) & MCURSOR_MODE_MASK); - intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), 0); - intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe)); + intel_de_write(display, TRANSCONF(display, pipe), 0); + intel_de_posting_read(display, TRANSCONF(display, pipe)); intel_wait_for_pipe_scanline_stopped(crtc); - intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), DPLL_VGA_MODE_DIS); + intel_de_posting_read(display, DPLL(display, pipe)); } void intel_hpd_poll_fini(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index b21d9578d5db..7ca26e5cb20e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -52,6 +52,7 @@ struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_digital_port; +struct intel_display; struct intel_dp; struct intel_encoder; struct intel_initial_plane_config; @@ -437,8 +438,8 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state); void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state); void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state); void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state); -void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); -void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); +void i830_enable_pipe(struct intel_display *display, enum pipe pipe); +void i830_disable_pipe(struct intel_display *display, enum pipe pipe); int vlv_get_hpll_vco(struct drm_i915_private *dev_priv); int vlv_get_cck_clock(struct drm_i915_private *dev_priv, const char *name, u32 reg, int ref_freq); 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 a5d9b17e03a2..9f275a6674a1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -1066,24 +1066,30 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, static void i830_pipes_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE) == 0) - i830_enable_pipe(dev_priv, PIPE_A); - if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE) == 0) - i830_enable_pipe(dev_priv, PIPE_B); + struct intel_display *display = &dev_priv->display; + + if ((intel_de_read(display, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE) == 0) + i830_enable_pipe(display, PIPE_A); + if ((intel_de_read(display, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE) == 0) + i830_enable_pipe(display, PIPE_B); } static void i830_pipes_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - i830_disable_pipe(dev_priv, PIPE_B); - i830_disable_pipe(dev_priv, PIPE_A); + struct intel_display *display = &dev_priv->display; + + i830_disable_pipe(display, PIPE_B); + i830_disable_pipe(display, PIPE_A); } static bool i830_pipes_power_well_enabled(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - return intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE && - intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE; + struct intel_display *display = &dev_priv->display; + + return intel_de_read(display, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE && + intel_de_read(display, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE; } static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv, From 5c30cfa295ccbfa93368486acc94ca01b4887a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 6 Sep 2024 17:33:06 +0300 Subject: [PATCH 027/205] drm/i915/dmc: Convert DMC code to intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct intel_display will replace struct drm_i915_private as the main thing for display code. Convert the DMC code to use it (as much as possible at this stage). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240906143306.15937-7-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_display.c | 7 +- .../drm/i915/display/intel_display_debugfs.c | 2 +- .../drm/i915/display/intel_display_driver.c | 6 +- .../drm/i915/display/intel_display_power.c | 17 +- .../i915/display/intel_display_power_well.c | 8 +- drivers/gpu/drm/i915/display/intel_dmc.c | 391 +++++++++--------- drivers/gpu/drm/i915/display/intel_dmc.h | 26 +- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 4 +- .../drm/i915/display/intel_modeset_setup.c | 3 +- drivers/gpu/drm/i915/i915_driver.c | 6 +- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/xe/display/xe_display.c | 4 +- 12 files changed, 243 insertions(+), 233 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 0ec78b06ca80..fdf244a32b24 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1690,7 +1690,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, intel_crtc_joined_pipe_mask(new_crtc_state)) - intel_dmc_enable_pipe(dev_priv, pipe_crtc->pipe); + intel_dmc_enable_pipe(display, pipe_crtc->pipe); intel_encoders_pre_pll_enable(state, crtc); @@ -1843,9 +1843,10 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, static void hsw_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); + struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_crtc *pipe_crtc; /* @@ -1867,7 +1868,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc, intel_crtc_joined_pipe_mask(old_crtc_state)) - intel_dmc_disable_pipe(i915, pipe_crtc->pipe); + intel_dmc_disable_pipe(display, pipe_crtc->pipe); } static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index c1bef34d1ffd..b75361e95e97 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1069,7 +1069,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) intel_bios_debugfs_register(display); intel_cdclk_debugfs_register(display); - intel_dmc_debugfs_register(i915); + intel_dmc_debugfs_register(display); intel_fbc_debugfs_register(display); intel_hpd_debugfs_register(i915); intel_opregion_debugfs_register(display); diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index f8da72af2107..c106fb2dd20b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -237,7 +237,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) if (!HAS_DISPLAY(i915)) return 0; - intel_dmc_init(i915); + intel_dmc_init(display); i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | @@ -272,7 +272,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915) return 0; cleanup_vga_client_pw_domain_dmc: - intel_dmc_fini(i915); + intel_dmc_fini(display); intel_power_domains_driver_remove(i915); cleanup_vga: intel_vga_unregister(display); @@ -621,7 +621,7 @@ void intel_display_driver_remove_nogem(struct drm_i915_private *i915) { struct intel_display *display = &i915->display; - intel_dmc_fini(i915); + intel_dmc_fini(display); intel_power_domains_driver_remove(i915); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 86ac494ed33b..ecabb674644b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1445,7 +1445,7 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, gen9_dbuf_enable(dev_priv); if (resume) - intel_dmc_load_program(dev_priv); + intel_dmc_load_program(display); } static void skl_display_core_uninit(struct drm_i915_private *dev_priv) @@ -1515,7 +1515,7 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume gen9_dbuf_enable(dev_priv); if (resume) - intel_dmc_load_program(dev_priv); + intel_dmc_load_program(display); } static void bxt_display_core_uninit(struct drm_i915_private *dev_priv) @@ -1687,7 +1687,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, intel_de_rmw(dev_priv, CHICKEN_MISC_2, BMG_DARB_HALF_BLK_END_BURST, 1); if (resume) - intel_dmc_load_program(dev_priv); + intel_dmc_load_program(display); /* Wa_14011508470:tgl,dg1,rkl,adl-s,adl-p,dg2 */ if (IS_DISPLAY_VER_FULL(dev_priv, IP_VER(12, 0), IP_VER(13, 0))) @@ -1718,7 +1718,7 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv) return; gen9_disable_dc_states(display); - intel_dmc_disable_program(dev_priv); + intel_dmc_disable_program(display); /* 1. Disable all display engine functions -> aready done */ @@ -2073,7 +2073,8 @@ void intel_power_domains_disable(struct drm_i915_private *i915) */ void intel_power_domains_suspend(struct drm_i915_private *i915, bool s2idle) { - struct i915_power_domains *power_domains = &i915->display.power.domains; + struct intel_display *display = &i915->display; + struct i915_power_domains *power_domains = &display->power.domains; intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&power_domains->init_wakeref); @@ -2087,7 +2088,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915, bool s2idle) * that would be blocked if the firmware was inactive. */ if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC9) && s2idle && - intel_dmc_has_payload(i915)) { + intel_dmc_has_payload(display)) { intel_display_power_flush_work(i915); intel_power_domains_verify_state(i915); return; @@ -2286,7 +2287,7 @@ void intel_display_power_resume(struct drm_i915_private *i915) if (DISPLAY_VER(i915) >= 11) { bxt_disable_dc9(display); icl_display_core_init(i915, true); - if (intel_dmc_has_payload(i915)) { + if (intel_dmc_has_payload(display)) { if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC6) skl_enable_dc6(display); else if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5) @@ -2295,7 +2296,7 @@ void intel_display_power_resume(struct drm_i915_private *i915) } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { bxt_disable_dc9(display); bxt_display_core_init(i915, true); - if (intel_dmc_has_payload(i915) && + if (intel_dmc_has_payload(display) && (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5)) gen9_enable_dc5(display); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { 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 9f275a6674a1..1898aff50ac4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -817,7 +817,7 @@ static void assert_can_enable_dc5(struct intel_display *display) "DC5 already programmed to be enabled.\n"); assert_rpm_wakelock_held(&dev_priv->runtime_pm); - assert_dmc_loaded(dev_priv); + assert_dmc_loaded(display); } void gen9_enable_dc5(struct intel_display *display) @@ -840,8 +840,6 @@ void gen9_enable_dc5(struct intel_display *display) static void assert_can_enable_dc6(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - drm_WARN_ONCE(display->drm, (intel_de_read(display, UTIL_PIN_CTL) & (UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) == @@ -852,7 +850,7 @@ static void assert_can_enable_dc6(struct intel_display *display) DC_STATE_EN_UPTO_DC6), "DC6 already programmed to be enabled.\n"); - assert_dmc_loaded(dev_priv); + assert_dmc_loaded(display); } void skl_enable_dc6(struct intel_display *display) @@ -1031,7 +1029,7 @@ static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, struct intel_display *display = &dev_priv->display; struct i915_power_domains *power_domains = &display->power.domains; - if (!intel_dmc_has_payload(dev_priv)) + if (!intel_dmc_has_payload(display)) return; switch (power_domains->target_dc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 7c756d5ba2a2..bbac6bfd1752 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -52,7 +52,7 @@ enum intel_dmc_id { }; struct intel_dmc { - struct drm_i915_private *i915; + struct intel_display *display; struct work_struct work; const char *fw_path; u32 max_fw_size; /* bytes */ @@ -70,21 +70,21 @@ struct intel_dmc { }; /* Note: This may be NULL. */ -static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915) +static struct intel_dmc *display_to_dmc(struct intel_display *display) { - return i915->display.dmc.dmc; + return display->dmc.dmc; } -static const char *dmc_firmware_param(struct drm_i915_private *i915) +static const char *dmc_firmware_param(struct intel_display *display) { - const char *p = i915->display.params.dmc_firmware_path; + const char *p = display->params.dmc_firmware_path; return p && *p ? p : NULL; } -static bool dmc_firmware_param_disabled(struct drm_i915_private *i915) +static bool dmc_firmware_param_disabled(struct intel_display *display) { - const char *p = dmc_firmware_param(i915); + const char *p = dmc_firmware_param(display); /* Magic path to indicate disabled */ return p && !strcmp(p, "/dev/null"); @@ -162,18 +162,19 @@ MODULE_FIRMWARE(SKL_DMC_PATH); #define BXT_DMC_MAX_FW_SIZE 0x3000 MODULE_FIRMWARE(BXT_DMC_PATH); -static const char *dmc_firmware_default(struct drm_i915_private *i915, u32 *size) +static const char *dmc_firmware_default(struct intel_display *display, u32 *size) { + struct drm_i915_private *i915 = to_i915(display->drm); const char *fw_path = NULL; u32 max_fw_size = 0; - if (DISPLAY_VER_FULL(i915) == IP_VER(20, 0)) { + if (DISPLAY_VER_FULL(display) == IP_VER(20, 0)) { fw_path = XE2LPD_DMC_PATH; max_fw_size = XE2LPD_DMC_MAX_FW_SIZE; - } else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 1)) { + } else if (DISPLAY_VER_FULL(display) == IP_VER(14, 1)) { fw_path = BMG_DMC_PATH; max_fw_size = XELPDP_DMC_MAX_FW_SIZE; - } else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) { + } else if (DISPLAY_VER_FULL(display) == IP_VER(14, 0)) { fw_path = MTL_DMC_PATH; max_fw_size = XELPDP_DMC_MAX_FW_SIZE; } else if (IS_DG2(i915)) { @@ -194,7 +195,7 @@ static const char *dmc_firmware_default(struct drm_i915_private *i915, u32 *size } else if (IS_TIGERLAKE(i915)) { fw_path = TGL_DMC_PATH; max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (DISPLAY_VER(i915) == 11) { + } else if (DISPLAY_VER(display) == 11) { fw_path = ICL_DMC_PATH; max_fw_size = ICL_DMC_MAX_FW_SIZE; } else if (IS_GEMINILAKE(i915)) { @@ -375,70 +376,70 @@ static bool is_valid_dmc_id(enum intel_dmc_id dmc_id) return dmc_id >= DMC_FW_MAIN && dmc_id < DMC_FW_MAX; } -static bool has_dmc_id_fw(struct drm_i915_private *i915, enum intel_dmc_id dmc_id) +static bool has_dmc_id_fw(struct intel_display *display, enum intel_dmc_id dmc_id) { - struct intel_dmc *dmc = i915_to_dmc(i915); + struct intel_dmc *dmc = display_to_dmc(display); return dmc && dmc->dmc_info[dmc_id].payload; } -bool intel_dmc_has_payload(struct drm_i915_private *i915) +bool intel_dmc_has_payload(struct intel_display *display) { - return has_dmc_id_fw(i915, DMC_FW_MAIN); + return has_dmc_id_fw(display, DMC_FW_MAIN); } static const struct stepping_info * -intel_get_stepping_info(struct drm_i915_private *i915, +intel_get_stepping_info(struct intel_display *display, struct stepping_info *si) { - const char *step_name = intel_step_name(INTEL_DISPLAY_STEP(i915)); + const char *step_name = intel_step_name(INTEL_DISPLAY_STEP(display)); si->stepping = step_name[0]; si->substepping = step_name[1]; return si; } -static void gen9_set_dc_state_debugmask(struct drm_i915_private *i915) +static void gen9_set_dc_state_debugmask(struct intel_display *display) { /* The below bit doesn't need to be cleared ever afterwards */ - intel_de_rmw(i915, DC_STATE_DEBUG, 0, + intel_de_rmw(display, DC_STATE_DEBUG, 0, DC_STATE_DEBUG_MASK_CORES | DC_STATE_DEBUG_MASK_MEMORY_UP); - intel_de_posting_read(i915, DC_STATE_DEBUG); + intel_de_posting_read(display, DC_STATE_DEBUG); } -static void disable_event_handler(struct drm_i915_private *i915, +static void disable_event_handler(struct intel_display *display, i915_reg_t ctl_reg, i915_reg_t htp_reg) { - intel_de_write(i915, ctl_reg, + intel_de_write(display, ctl_reg, REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, DMC_EVT_CTL_TYPE_EDGE_0_1) | REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK, DMC_EVT_CTL_EVENT_ID_FALSE)); - intel_de_write(i915, htp_reg, 0); + intel_de_write(display, htp_reg, 0); } -static void disable_all_event_handlers(struct drm_i915_private *i915) +static void disable_all_event_handlers(struct intel_display *display) { enum intel_dmc_id dmc_id; /* TODO: disable the event handlers on pre-GEN12 platforms as well */ - if (DISPLAY_VER(i915) < 12) + if (DISPLAY_VER(display) < 12) return; for_each_dmc_id(dmc_id) { int handler; - if (!has_dmc_id_fw(i915, dmc_id)) + if (!has_dmc_id_fw(display, dmc_id)) continue; for (handler = 0; handler < DMC_EVENT_HANDLER_COUNT_GEN12; handler++) - disable_event_handler(i915, - DMC_EVT_CTL(i915, dmc_id, handler), - DMC_EVT_HTP(i915, dmc_id, handler)); + disable_event_handler(display, + DMC_EVT_CTL(display, dmc_id, handler), + DMC_EVT_HTP(display, dmc_id, handler)); } } -static void adlp_pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) +static void adlp_pipedmc_clock_gating_wa(struct intel_display *display, bool enable) { enum pipe pipe; @@ -451,84 +452,86 @@ static void adlp_pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool ena */ if (enable) for (pipe = PIPE_A; pipe <= PIPE_D; pipe++) - intel_de_rmw(i915, CLKGATE_DIS_PSL_EXT(pipe), + intel_de_rmw(display, CLKGATE_DIS_PSL_EXT(pipe), 0, PIPEDMC_GATING_DIS); else for (pipe = PIPE_C; pipe <= PIPE_D; pipe++) - intel_de_rmw(i915, CLKGATE_DIS_PSL_EXT(pipe), + intel_de_rmw(display, CLKGATE_DIS_PSL_EXT(pipe), PIPEDMC_GATING_DIS, 0); } -static void mtl_pipedmc_clock_gating_wa(struct drm_i915_private *i915) +static void mtl_pipedmc_clock_gating_wa(struct intel_display *display) { /* * Wa_16015201720 * The WA requires clock gating to be disabled all the time * for pipe A and B. */ - intel_de_rmw(i915, GEN9_CLKGATE_DIS_0, 0, + intel_de_rmw(display, GEN9_CLKGATE_DIS_0, 0, MTL_PIPEDMC_GATING_DIS_A | MTL_PIPEDMC_GATING_DIS_B); } -static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) +static void pipedmc_clock_gating_wa(struct intel_display *display, bool enable) { - if (DISPLAY_VER(i915) >= 14 && enable) - mtl_pipedmc_clock_gating_wa(i915); - else if (DISPLAY_VER(i915) == 13) - adlp_pipedmc_clock_gating_wa(i915, enable); + if (DISPLAY_VER(display) >= 14 && enable) + mtl_pipedmc_clock_gating_wa(display); + else if (DISPLAY_VER(display) == 13) + adlp_pipedmc_clock_gating_wa(display, enable); } -void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe) +void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe) { enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); - if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(i915, dmc_id)) + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) return; - if (DISPLAY_VER(i915) >= 14) - intel_de_rmw(i915, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe)); + if (DISPLAY_VER(display) >= 14) + intel_de_rmw(display, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe)); else - intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE); + intel_de_rmw(display, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE); } -void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe) +void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe) { enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); - if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(i915, dmc_id)) + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) return; - if (DISPLAY_VER(i915) >= 14) - intel_de_rmw(i915, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0); + if (DISPLAY_VER(display) >= 14) + intel_de_rmw(display, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0); else - intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); + intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); } -static bool is_dmc_evt_ctl_reg(struct drm_i915_private *i915, +static bool is_dmc_evt_ctl_reg(struct intel_display *display, enum intel_dmc_id dmc_id, i915_reg_t reg) { u32 offset = i915_mmio_reg_offset(reg); - u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(i915, dmc_id, 0)); - u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(i915, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); + u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0)); + u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); return offset >= start && offset < end; } -static bool is_dmc_evt_htp_reg(struct drm_i915_private *i915, +static bool is_dmc_evt_htp_reg(struct intel_display *display, enum intel_dmc_id dmc_id, i915_reg_t reg) { u32 offset = i915_mmio_reg_offset(reg); - u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(i915, dmc_id, 0)); - u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(i915, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); + u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0)); + u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); return offset >= start && offset < end; } -static bool disable_dmc_evt(struct drm_i915_private *i915, +static bool disable_dmc_evt(struct intel_display *display, enum intel_dmc_id dmc_id, i915_reg_t reg, u32 data) { - if (!is_dmc_evt_ctl_reg(i915, dmc_id, reg)) + struct drm_i915_private *i915 = to_i915(display->drm); + + if (!is_dmc_evt_ctl_reg(display, dmc_id, reg)) return false; /* keep all pipe DMC events disabled by default */ @@ -548,11 +551,11 @@ static bool disable_dmc_evt(struct drm_i915_private *i915, return false; } -static u32 dmc_mmiodata(struct drm_i915_private *i915, +static u32 dmc_mmiodata(struct intel_display *display, struct intel_dmc *dmc, enum intel_dmc_id dmc_id, int i) { - if (disable_dmc_evt(i915, dmc_id, + if (disable_dmc_evt(display, dmc_id, dmc->dmc_info[dmc_id].mmioaddr[i], dmc->dmc_info[dmc_id].mmiodata[i])) return REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, @@ -565,25 +568,26 @@ static u32 dmc_mmiodata(struct drm_i915_private *i915, /** * intel_dmc_load_program() - write the firmware from memory to register. - * @i915: i915 drm device. + * @display: display instance * * DMC firmware is read from a .bin file and kept in internal memory one time. * Everytime display comes back from low power state this function is called to * copy the firmware from internal memory to registers. */ -void intel_dmc_load_program(struct drm_i915_private *i915) +void intel_dmc_load_program(struct intel_display *display) { - struct i915_power_domains *power_domains = &i915->display.power.domains; - struct intel_dmc *dmc = i915_to_dmc(i915); + struct drm_i915_private *i915 __maybe_unused = to_i915(display->drm); + struct i915_power_domains *power_domains = &display->power.domains; + struct intel_dmc *dmc = display_to_dmc(display); enum intel_dmc_id dmc_id; u32 i; - if (!intel_dmc_has_payload(i915)) + if (!intel_dmc_has_payload(display)) return; - pipedmc_clock_gating_wa(i915, true); + pipedmc_clock_gating_wa(display, true); - disable_all_event_handlers(i915); + disable_all_event_handlers(display); assert_rpm_wakelock_held(&i915->runtime_pm); @@ -591,7 +595,7 @@ void intel_dmc_load_program(struct drm_i915_private *i915) for_each_dmc_id(dmc_id) { for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { - intel_de_write_fw(i915, + intel_de_write_fw(display, DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), dmc->dmc_info[dmc_id].payload[i]); } @@ -601,48 +605,48 @@ void intel_dmc_load_program(struct drm_i915_private *i915) for_each_dmc_id(dmc_id) { for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { - intel_de_write(i915, dmc->dmc_info[dmc_id].mmioaddr[i], - dmc_mmiodata(i915, dmc, dmc_id, i)); + intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i], + dmc_mmiodata(display, dmc, dmc_id, i)); } } power_domains->dc_state = 0; - gen9_set_dc_state_debugmask(i915); + gen9_set_dc_state_debugmask(display); - pipedmc_clock_gating_wa(i915, false); + pipedmc_clock_gating_wa(display, false); } /** * intel_dmc_disable_program() - disable the firmware - * @i915: i915 drm device + * @display: display instance * * Disable all event handlers in the firmware, making sure the firmware is * inactive after the display is uninitialized. */ -void intel_dmc_disable_program(struct drm_i915_private *i915) +void intel_dmc_disable_program(struct intel_display *display) { - if (!intel_dmc_has_payload(i915)) + if (!intel_dmc_has_payload(display)) return; - pipedmc_clock_gating_wa(i915, true); - disable_all_event_handlers(i915); - pipedmc_clock_gating_wa(i915, false); + pipedmc_clock_gating_wa(display, true); + disable_all_event_handlers(display); + pipedmc_clock_gating_wa(display, false); - intel_dmc_wl_disable(&i915->display); + intel_dmc_wl_disable(display); } -void assert_dmc_loaded(struct drm_i915_private *i915) +void assert_dmc_loaded(struct intel_display *display) { - struct intel_dmc *dmc = i915_to_dmc(i915); + struct intel_dmc *dmc = display_to_dmc(display); - drm_WARN_ONCE(&i915->drm, !dmc, "DMC not initialized\n"); - drm_WARN_ONCE(&i915->drm, dmc && - !intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), + drm_WARN_ONCE(display->drm, !dmc, "DMC not initialized\n"); + drm_WARN_ONCE(display->drm, dmc && + !intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), "DMC program storage start is NULL\n"); - drm_WARN_ONCE(&i915->drm, !intel_de_read(i915, DMC_SSP_BASE), + drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_SSP_BASE), "DMC SSP Base Not fine\n"); - drm_WARN_ONCE(&i915->drm, !intel_de_read(i915, DMC_HTP_SKL), + drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_HTP_SKL), "DMC HTP Not fine\n"); } @@ -673,7 +677,7 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, const struct stepping_info *si, u8 package_ver) { - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; enum intel_dmc_id dmc_id; unsigned int i; @@ -681,7 +685,7 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, dmc_id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id; if (!is_valid_dmc_id(dmc_id)) { - drm_dbg(&i915->drm, "Unsupported firmware id: %u\n", dmc_id); + drm_dbg(display->drm, "Unsupported firmware id: %u\n", dmc_id); continue; } @@ -703,7 +707,7 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, u32 mmio_count, int header_ver, enum intel_dmc_id dmc_id) { - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; u32 start_range, end_range; int i; @@ -713,14 +717,14 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, } else if (dmc_id == DMC_FW_MAIN) { start_range = TGL_MAIN_MMIO_START; end_range = TGL_MAIN_MMIO_END; - } else if (DISPLAY_VER(i915) >= 13) { + } else if (DISPLAY_VER(display) >= 13) { start_range = ADLP_PIPE_MMIO_START; end_range = ADLP_PIPE_MMIO_END; - } else if (DISPLAY_VER(i915) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { start_range = TGL_PIPE_MMIO_START(dmc_id); end_range = TGL_PIPE_MMIO_END(dmc_id); } else { - drm_warn(&i915->drm, "Unknown mmio range for sanity check"); + drm_warn(display->drm, "Unknown mmio range for sanity check"); return false; } @@ -736,7 +740,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, enum intel_dmc_id dmc_id) { - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id]; unsigned int header_len_bytes, dmc_header_size, payload_size, i; const u32 *mmioaddr, *mmiodata; @@ -784,39 +788,39 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, start_mmioaddr = DMC_V1_MMIO_START_RANGE; dmc_header_size = sizeof(*v1); } else { - drm_err(&i915->drm, "Unknown DMC fw header version: %u\n", + drm_err(display->drm, "Unknown DMC fw header version: %u\n", dmc_header->header_ver); return 0; } if (header_len_bytes != dmc_header_size) { - drm_err(&i915->drm, "DMC firmware has wrong dmc header length " + drm_err(display->drm, "DMC firmware has wrong dmc header length " "(%u bytes)\n", header_len_bytes); return 0; } /* Cache the dmc header info. */ if (mmio_count > mmio_count_max) { - drm_err(&i915->drm, "DMC firmware has wrong mmio count %u\n", mmio_count); + drm_err(display->drm, "DMC firmware has wrong mmio count %u\n", mmio_count); return 0; } if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, dmc_header->header_ver, dmc_id)) { - drm_err(&i915->drm, "DMC firmware has Wrong MMIO Addresses\n"); + drm_err(display->drm, "DMC firmware has Wrong MMIO Addresses\n"); return 0; } - drm_dbg_kms(&i915->drm, "DMC %d:\n", dmc_id); + drm_dbg_kms(display->drm, "DMC %d:\n", dmc_id); for (i = 0; i < mmio_count; i++) { dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); dmc_info->mmiodata[i] = mmiodata[i]; - drm_dbg_kms(&i915->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n", + drm_dbg_kms(display->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n", i, mmioaddr[i], mmiodata[i], - is_dmc_evt_ctl_reg(i915, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" : - is_dmc_evt_htp_reg(i915, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "", - disable_dmc_evt(i915, dmc_id, dmc_info->mmioaddr[i], + is_dmc_evt_ctl_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" : + is_dmc_evt_htp_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "", + disable_dmc_evt(display, dmc_id, dmc_info->mmioaddr[i], dmc_info->mmiodata[i]) ? " (disabling)" : ""); } dmc_info->mmio_count = mmio_count; @@ -830,7 +834,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, goto error_truncated; if (payload_size > dmc->max_fw_size) { - drm_err(&i915->drm, "DMC FW too big (%u bytes)\n", payload_size); + drm_err(display->drm, "DMC FW too big (%u bytes)\n", payload_size); return 0; } dmc_info->dmc_fw_size = dmc_header->fw_size; @@ -845,7 +849,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, return header_len_bytes + payload_size; error_truncated: - drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); + drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); return 0; } @@ -855,7 +859,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc, const struct stepping_info *si, size_t rem_size) { - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; u32 package_size = sizeof(struct intel_package_header); u32 num_entries, max_entries; const struct intel_fw_info *fw_info; @@ -868,7 +872,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc, } else if (package_header->header_ver == 2) { max_entries = PACKAGE_V2_MAX_FW_INFO_ENTRIES; } else { - drm_err(&i915->drm, "DMC firmware has unknown header version %u\n", + drm_err(display->drm, "DMC firmware has unknown header version %u\n", package_header->header_ver); return 0; } @@ -882,7 +886,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc, goto error_truncated; if (package_header->header_len * 4 != package_size) { - drm_err(&i915->drm, "DMC firmware has wrong package header length " + drm_err(display->drm, "DMC firmware has wrong package header length " "(%u bytes)\n", package_size); return 0; } @@ -900,7 +904,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc, return package_size; error_truncated: - drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); + drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); return 0; } @@ -909,16 +913,16 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc, struct intel_css_header *css_header, size_t rem_size) { - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; if (rem_size < sizeof(struct intel_css_header)) { - drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); + drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); return 0; } if (sizeof(struct intel_css_header) != (css_header->header_len * 4)) { - drm_err(&i915->drm, "DMC firmware has wrong CSS header length " + drm_err(display->drm, "DMC firmware has wrong CSS header length " "(%u bytes)\n", (css_header->header_len * 4)); return 0; @@ -931,12 +935,12 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc, static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) { - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; struct intel_css_header *css_header; struct intel_package_header *package_header; struct intel_dmc_header_base *dmc_header; struct stepping_info display_info = { '*', '*'}; - const struct stepping_info *si = intel_get_stepping_info(i915, &display_info); + const struct stepping_info *si = intel_get_stepping_info(display, &display_info); enum intel_dmc_id dmc_id; u32 readcount = 0; u32 r, offset; @@ -966,7 +970,7 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4; if (offset > fw->size) { - drm_err(&i915->drm, "Reading beyond the fw_size\n"); + drm_err(display->drm, "Reading beyond the fw_size\n"); continue; } @@ -974,30 +978,35 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, dmc_id); } - if (!intel_dmc_has_payload(i915)) { - drm_err(&i915->drm, "DMC firmware main program not found\n"); + if (!intel_dmc_has_payload(display)) { + drm_err(display->drm, "DMC firmware main program not found\n"); return -ENOENT; } return 0; } -static void intel_dmc_runtime_pm_get(struct drm_i915_private *i915) +static void intel_dmc_runtime_pm_get(struct intel_display *display) { - drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref); - i915->display.dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); + struct drm_i915_private *i915 = to_i915(display->drm); + + drm_WARN_ON(display->drm, display->dmc.wakeref); + display->dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); } -static void intel_dmc_runtime_pm_put(struct drm_i915_private *i915) +static void intel_dmc_runtime_pm_put(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref __maybe_unused = - fetch_and_zero(&i915->display.dmc.wakeref); + fetch_and_zero(&display->dmc.wakeref); intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); } -static const char *dmc_fallback_path(struct drm_i915_private *i915) +static const char *dmc_fallback_path(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); + if (IS_ALDERLAKE_P(i915)) return ADLP_DMC_FALLBACK_PATH; @@ -1007,45 +1016,45 @@ static const char *dmc_fallback_path(struct drm_i915_private *i915) static void dmc_load_work_fn(struct work_struct *work) { struct intel_dmc *dmc = container_of(work, typeof(*dmc), work); - struct drm_i915_private *i915 = dmc->i915; + struct intel_display *display = dmc->display; const struct firmware *fw = NULL; const char *fallback_path; int err; - err = request_firmware(&fw, dmc->fw_path, i915->drm.dev); + err = request_firmware(&fw, dmc->fw_path, display->drm->dev); - if (err == -ENOENT && !dmc_firmware_param(i915)) { - fallback_path = dmc_fallback_path(i915); + if (err == -ENOENT && !dmc_firmware_param(display)) { + fallback_path = dmc_fallback_path(display); if (fallback_path) { - drm_dbg_kms(&i915->drm, "%s not found, falling back to %s\n", + drm_dbg_kms(display->drm, "%s not found, falling back to %s\n", dmc->fw_path, fallback_path); - err = request_firmware(&fw, fallback_path, i915->drm.dev); + err = request_firmware(&fw, fallback_path, display->drm->dev); if (err == 0) dmc->fw_path = fallback_path; } } if (err) { - drm_notice(&i915->drm, + drm_notice(display->drm, "Failed to load DMC firmware %s (%pe). Disabling runtime power management.\n", dmc->fw_path, ERR_PTR(err)); - drm_notice(&i915->drm, "DMC firmware homepage: %s", + drm_notice(display->drm, "DMC firmware homepage: %s", INTEL_DMC_FIRMWARE_URL); return; } err = parse_dmc_fw(dmc, fw); if (err) { - drm_notice(&i915->drm, + drm_notice(display->drm, "Failed to parse DMC firmware %s (%pe). Disabling runtime power management.\n", dmc->fw_path, ERR_PTR(err)); goto out; } - intel_dmc_load_program(i915); - intel_dmc_runtime_pm_put(i915); + intel_dmc_load_program(display); + intel_dmc_runtime_pm_put(display); - drm_info(&i915->drm, "Finished loading DMC firmware %s (v%u.%u)\n", + drm_info(display->drm, "Finished loading DMC firmware %s (v%u.%u)\n", dmc->fw_path, DMC_VERSION_MAJOR(dmc->version), DMC_VERSION_MINOR(dmc->version)); @@ -1055,16 +1064,17 @@ static void dmc_load_work_fn(struct work_struct *work) /** * intel_dmc_init() - initialize the firmware loading. - * @i915: i915 drm device. + * @display: display instance * * This function is called at the time of loading the display driver to read * firmware from a .bin file and copied into a internal memory. */ -void intel_dmc_init(struct drm_i915_private *i915) +void intel_dmc_init(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_dmc *dmc; - if (!HAS_DMC(i915)) + if (!HAS_DMC(display)) return; /* @@ -1075,35 +1085,35 @@ void intel_dmc_init(struct drm_i915_private *i915) * suspend as runtime suspend *requires* a working DMC for whatever * reason. */ - intel_dmc_runtime_pm_get(i915); + intel_dmc_runtime_pm_get(display); dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); if (!dmc) return; - dmc->i915 = i915; + dmc->display = display; INIT_WORK(&dmc->work, dmc_load_work_fn); - dmc->fw_path = dmc_firmware_default(i915, &dmc->max_fw_size); + dmc->fw_path = dmc_firmware_default(display, &dmc->max_fw_size); - if (dmc_firmware_param_disabled(i915)) { - drm_info(&i915->drm, "Disabling DMC firmware and runtime PM\n"); + if (dmc_firmware_param_disabled(display)) { + drm_info(display->drm, "Disabling DMC firmware and runtime PM\n"); goto out; } - if (dmc_firmware_param(i915)) - dmc->fw_path = dmc_firmware_param(i915); + if (dmc_firmware_param(display)) + dmc->fw_path = dmc_firmware_param(display); if (!dmc->fw_path) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "No known DMC firmware for platform, disabling runtime PM\n"); goto out; } - i915->display.dmc.dmc = dmc; + display->dmc.dmc = dmc; - drm_dbg_kms(&i915->drm, "Loading %s\n", dmc->fw_path); + drm_dbg_kms(display->drm, "Loading %s\n", dmc->fw_path); queue_work(i915->unordered_wq, &dmc->work); return; @@ -1114,87 +1124,87 @@ void intel_dmc_init(struct drm_i915_private *i915) /** * intel_dmc_suspend() - prepare DMC firmware before system suspend - * @i915: i915 drm device + * @display: display instance * * Prepare the DMC firmware before entering system suspend. This includes * flushing pending work items and releasing any resources acquired during * init. */ -void intel_dmc_suspend(struct drm_i915_private *i915) +void intel_dmc_suspend(struct intel_display *display) { - struct intel_dmc *dmc = i915_to_dmc(i915); + struct intel_dmc *dmc = display_to_dmc(display); - if (!HAS_DMC(i915)) + if (!HAS_DMC(display)) return; if (dmc) flush_work(&dmc->work); - intel_dmc_wl_disable(&i915->display); + intel_dmc_wl_disable(display); /* Drop the reference held in case DMC isn't loaded. */ - if (!intel_dmc_has_payload(i915)) - intel_dmc_runtime_pm_put(i915); + if (!intel_dmc_has_payload(display)) + intel_dmc_runtime_pm_put(display); } /** * intel_dmc_resume() - init DMC firmware during system resume - * @i915: i915 drm device + * @display: display instance * * Reinitialize the DMC firmware during system resume, reacquiring any * resources released in intel_dmc_suspend(). */ -void intel_dmc_resume(struct drm_i915_private *i915) +void intel_dmc_resume(struct intel_display *display) { - if (!HAS_DMC(i915)) + if (!HAS_DMC(display)) return; /* * Reacquire the reference to keep RPM disabled in case DMC isn't * loaded. */ - if (!intel_dmc_has_payload(i915)) - intel_dmc_runtime_pm_get(i915); + if (!intel_dmc_has_payload(display)) + intel_dmc_runtime_pm_get(display); } /** * intel_dmc_fini() - unload the DMC firmware. - * @i915: i915 drm device. + * @display: display instance * * Firmmware unloading includes freeing the internal memory and reset the * firmware loading status. */ -void intel_dmc_fini(struct drm_i915_private *i915) +void intel_dmc_fini(struct intel_display *display) { - struct intel_dmc *dmc = i915_to_dmc(i915); + struct intel_dmc *dmc = display_to_dmc(display); enum intel_dmc_id dmc_id; - if (!HAS_DMC(i915)) + if (!HAS_DMC(display)) return; - intel_dmc_suspend(i915); - drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref); + intel_dmc_suspend(display); + drm_WARN_ON(display->drm, display->dmc.wakeref); if (dmc) { for_each_dmc_id(dmc_id) kfree(dmc->dmc_info[dmc_id].payload); kfree(dmc); - i915->display.dmc.dmc = NULL; + display->dmc.dmc = NULL; } } void intel_dmc_print_error_state(struct drm_printer *p, - struct drm_i915_private *i915) + struct intel_display *display) { - struct intel_dmc *dmc = i915_to_dmc(i915); + struct intel_dmc *dmc = display_to_dmc(display); - if (!HAS_DMC(i915)) + if (!HAS_DMC(display)) return; drm_printf(p, "DMC initialized: %s\n", str_yes_no(dmc)); drm_printf(p, "DMC loaded: %s\n", - str_yes_no(intel_dmc_has_payload(i915))); + str_yes_no(intel_dmc_has_payload(display))); if (dmc) drm_printf(p, "DMC fw version: %d.%d\n", DMC_VERSION_MAJOR(dmc->version), @@ -1203,40 +1213,41 @@ void intel_dmc_print_error_state(struct drm_printer *p, static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) { - struct drm_i915_private *i915 = m->private; - struct intel_dmc *dmc = i915_to_dmc(i915); + struct intel_display *display = m->private; + struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_dmc *dmc = display_to_dmc(display); intel_wakeref_t wakeref; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; - if (!HAS_DMC(i915)) + if (!HAS_DMC(display)) return -ENODEV; wakeref = intel_runtime_pm_get(&i915->runtime_pm); seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); seq_printf(m, "fw loaded: %s\n", - str_yes_no(intel_dmc_has_payload(i915))); + str_yes_no(intel_dmc_has_payload(display))); seq_printf(m, "path: %s\n", dmc ? dmc->fw_path : "N/A"); seq_printf(m, "Pipe A fw needed: %s\n", - str_yes_no(DISPLAY_VER(i915) >= 12)); + str_yes_no(DISPLAY_VER(display) >= 12)); seq_printf(m, "Pipe A fw loaded: %s\n", - str_yes_no(has_dmc_id_fw(i915, DMC_FW_PIPEA))); + str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEA))); seq_printf(m, "Pipe B fw needed: %s\n", str_yes_no(IS_ALDERLAKE_P(i915) || - DISPLAY_VER(i915) >= 14)); + DISPLAY_VER(display) >= 14)); seq_printf(m, "Pipe B fw loaded: %s\n", - str_yes_no(has_dmc_id_fw(i915, DMC_FW_PIPEB))); + str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEB))); - if (!intel_dmc_has_payload(i915)) + if (!intel_dmc_has_payload(display)) goto out; seq_printf(m, "version: %d.%d\n", DMC_VERSION_MAJOR(dmc->version), DMC_VERSION_MINOR(dmc->version)); - if (DISPLAY_VER(i915) >= 12) { + if (DISPLAY_VER(display) >= 12) { i915_reg_t dc3co_reg; - if (IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) { + if (IS_DGFX(i915) || DISPLAY_VER(display) >= 14) { dc3co_reg = DG1_DMC_DEBUG3; dc5_reg = DG1_DMC_DEBUG_DC5_COUNT; } else { @@ -1246,7 +1257,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) } seq_printf(m, "DC3CO count: %d\n", - intel_de_read(i915, dc3co_reg)); + intel_de_read(display, dc3co_reg)); } else { dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT : SKL_DMC_DC3_DC5_COUNT; @@ -1254,18 +1265,18 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) dc6_reg = SKL_DMC_DC5_DC6_COUNT; } - seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(i915, dc5_reg)); + seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(display, dc5_reg)); if (i915_mmio_reg_valid(dc6_reg)) seq_printf(m, "DC5 -> DC6 count: %d\n", - intel_de_read(i915, dc6_reg)); + intel_de_read(display, dc6_reg)); seq_printf(m, "program base: 0x%08x\n", - intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0))); + intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0))); out: seq_printf(m, "ssp base: 0x%08x\n", - intel_de_read(i915, DMC_SSP_BASE)); - seq_printf(m, "htp: 0x%08x\n", intel_de_read(i915, DMC_HTP_SKL)); + intel_de_read(display, DMC_SSP_BASE)); + seq_printf(m, "htp: 0x%08x\n", intel_de_read(display, DMC_HTP_SKL)); intel_runtime_pm_put(&i915->runtime_pm, wakeref); @@ -1274,10 +1285,10 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) DEFINE_SHOW_ATTRIBUTE(intel_dmc_debugfs_status); -void intel_dmc_debugfs_register(struct drm_i915_private *i915) +void intel_dmc_debugfs_register(struct intel_display *display) { - struct drm_minor *minor = i915->drm.primary; + struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_dmc_info", 0444, minor->debugfs_root, - i915, &intel_dmc_debugfs_status_fops); + display, &intel_dmc_debugfs_status_fops); } diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 54cff6002e31..2ead2ec1f820 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -9,22 +9,22 @@ #include enum pipe; -struct drm_i915_private; struct drm_printer; +struct intel_display; -void intel_dmc_init(struct drm_i915_private *i915); -void intel_dmc_load_program(struct drm_i915_private *i915); -void intel_dmc_disable_program(struct drm_i915_private *i915); -void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe); -void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe); -void intel_dmc_fini(struct drm_i915_private *i915); -void intel_dmc_suspend(struct drm_i915_private *i915); -void intel_dmc_resume(struct drm_i915_private *i915); -bool intel_dmc_has_payload(struct drm_i915_private *i915); -void intel_dmc_debugfs_register(struct drm_i915_private *i915); +void intel_dmc_init(struct intel_display *display); +void intel_dmc_load_program(struct intel_display *display); +void intel_dmc_disable_program(struct intel_display *display); +void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe); +void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe); +void intel_dmc_fini(struct intel_display *display); +void intel_dmc_suspend(struct intel_display *display); +void intel_dmc_resume(struct intel_display *display); +bool intel_dmc_has_payload(struct intel_display *display); +void intel_dmc_debugfs_register(struct intel_display *display); void intel_dmc_print_error_state(struct drm_printer *p, - struct drm_i915_private *i915); + struct intel_display *display); -void assert_dmc_loaded(struct drm_i915_private *i915); +void assert_dmc_loaded(struct intel_display *display); #endif /* __INTEL_DMC_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index d9864b9cc429..5634ff07269d 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -109,10 +109,8 @@ static bool intel_dmc_wl_check_range(u32 address) static bool __intel_dmc_wl_supported(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) < 20 || - !intel_dmc_has_payload(i915) || + !intel_dmc_has_payload(display) || !display->params.enable_dmc_wl) return false; diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 1f57549fce00..bcc5cf137a88 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -960,6 +960,7 @@ static void intel_early_display_was(struct drm_i915_private *i915) void intel_modeset_setup_hw_state(struct drm_i915_private *i915, struct drm_modeset_acquire_ctx *ctx) { + struct intel_display *display = &i915->display; struct intel_encoder *encoder; struct intel_crtc *crtc; intel_wakeref_t wakeref; @@ -987,7 +988,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, drm_crtc_vblank_reset(&crtc->base); if (crtc_state->hw.active) { - intel_dmc_enable_pipe(i915, crtc->pipe); + intel_dmc_enable_pipe(display, crtc->pipe); intel_crtc_vblank_on(crtc_state); } } diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index fe905d65ddf7..943e938040c0 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -959,7 +959,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_encoder_suspend_all(&i915->display); intel_encoder_shutdown_all(&i915->display); - intel_dmc_suspend(i915); + intel_dmc_suspend(&i915->display); i915_gem_suspend(i915); @@ -1054,7 +1054,7 @@ static int i915_drm_suspend(struct drm_device *dev) dev_priv->suspend_count++; - intel_dmc_suspend(dev_priv); + intel_dmc_suspend(display); enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); @@ -1164,7 +1164,7 @@ static int i915_drm_resume(struct drm_device *dev) /* Must be called after GGTT is resumed. */ intel_dpt_resume(dev_priv); - intel_dmc_resume(dev_priv); + intel_dmc_resume(display); i915_restore_display(dev_priv); intel_pps_unlock_regs_wa(display); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 6469b9bcf2ec..b455fa441609 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -875,7 +875,7 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m, err_printf(m, "IOMMU enabled?: %d\n", error->iommu); - intel_dmc_print_error_state(&p, m->i915); + intel_dmc_print_error_state(&p, &m->i915->display); err_printf(m, "RPM wakelock: %s\n", str_yes_no(error->wakelock)); err_printf(m, "PM suspended: %s\n", str_yes_no(error->suspended)); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index c0e9aa7a274f..10d707e05d6e 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -353,7 +353,7 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime) intel_opregion_suspend(display, s2idle ? PCI_D1 : PCI_D3cold); - intel_dmc_suspend(xe); + intel_dmc_suspend(display); } void xe_display_pm_suspend_late(struct xe_device *xe) @@ -395,7 +395,7 @@ void xe_display_pm_resume(struct xe_device *xe, bool runtime) if (!xe->info.probe_display) return; - intel_dmc_resume(xe); + intel_dmc_resume(display); if (has_display(xe)) drm_mode_config_reset(&xe->drm); From d3944104251f71b274ce1ceeba79f4039110de8a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:45 +0300 Subject: [PATCH 028/205] drm/i915/reg: fix transcoder timing register style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/fcd7c5114f707da8018c65fbb44a70dbdceec37f.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_psr_regs.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 51 ++++++++++--------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h index 642bb15fb547..945fdc750a03 100644 --- a/drivers/gpu/drm/i915/display/intel_psr_regs.h +++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h @@ -9,6 +9,7 @@ #include "intel_display_reg_defs.h" #include "intel_dp_aux_regs.h" +#define _TRANS_EXITLINE_A 0x60018 #define TRANS_EXITLINE(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_EXITLINE_A) #define EXITLINE_ENABLE REG_BIT(31) #define EXITLINE_MASK REG_GENMASK(12, 0) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 41f4350a7c6c..7a6ca695bb6a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1071,56 +1071,72 @@ /* Pipe/transcoder A timing regs */ #define _TRANS_HTOTAL_A 0x60000 +#define _TRANS_HTOTAL_B 0x61000 +#define TRANS_HTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HTOTAL_A) #define HTOTAL_MASK REG_GENMASK(31, 16) #define HTOTAL(htotal) REG_FIELD_PREP(HTOTAL_MASK, (htotal)) #define HACTIVE_MASK REG_GENMASK(15, 0) #define HACTIVE(hdisplay) REG_FIELD_PREP(HACTIVE_MASK, (hdisplay)) + #define _TRANS_HBLANK_A 0x60004 +#define _TRANS_HBLANK_B 0x61004 +#define TRANS_HBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HBLANK_A) #define HBLANK_END_MASK REG_GENMASK(31, 16) #define HBLANK_END(hblank_end) REG_FIELD_PREP(HBLANK_END_MASK, (hblank_end)) #define HBLANK_START_MASK REG_GENMASK(15, 0) #define HBLANK_START(hblank_start) REG_FIELD_PREP(HBLANK_START_MASK, (hblank_start)) + #define _TRANS_HSYNC_A 0x60008 +#define _TRANS_HSYNC_B 0x61008 +#define TRANS_HSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HSYNC_A) #define HSYNC_END_MASK REG_GENMASK(31, 16) #define HSYNC_END(hsync_end) REG_FIELD_PREP(HSYNC_END_MASK, (hsync_end)) #define HSYNC_START_MASK REG_GENMASK(15, 0) #define HSYNC_START(hsync_start) REG_FIELD_PREP(HSYNC_START_MASK, (hsync_start)) + #define _TRANS_VTOTAL_A 0x6000c +#define _TRANS_VTOTAL_B 0x6100c +#define TRANS_VTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VTOTAL_A) #define VTOTAL_MASK REG_GENMASK(31, 16) #define VTOTAL(vtotal) REG_FIELD_PREP(VTOTAL_MASK, (vtotal)) #define VACTIVE_MASK REG_GENMASK(15, 0) #define VACTIVE(vdisplay) REG_FIELD_PREP(VACTIVE_MASK, (vdisplay)) + #define _TRANS_VBLANK_A 0x60010 +#define _TRANS_VBLANK_B 0x61010 +#define TRANS_VBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VBLANK_A) #define VBLANK_END_MASK REG_GENMASK(31, 16) #define VBLANK_END(vblank_end) REG_FIELD_PREP(VBLANK_END_MASK, (vblank_end)) #define VBLANK_START_MASK REG_GENMASK(15, 0) #define VBLANK_START(vblank_start) REG_FIELD_PREP(VBLANK_START_MASK, (vblank_start)) + #define _TRANS_VSYNC_A 0x60014 +#define _TRANS_VSYNC_B 0x61014 +#define TRANS_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNC_A) #define VSYNC_END_MASK REG_GENMASK(31, 16) #define VSYNC_END(vsync_end) REG_FIELD_PREP(VSYNC_END_MASK, (vsync_end)) #define VSYNC_START_MASK REG_GENMASK(15, 0) #define VSYNC_START(vsync_start) REG_FIELD_PREP(VSYNC_START_MASK, (vsync_start)) -#define _TRANS_EXITLINE_A 0x60018 + #define _PIPEASRC 0x6001c +#define _PIPEBSRC 0x6101c +#define PIPESRC(dev_priv, pipe) _MMIO_TRANS2(dev_priv, (pipe), _PIPEASRC) #define PIPESRC_WIDTH_MASK REG_GENMASK(31, 16) #define PIPESRC_WIDTH(w) REG_FIELD_PREP(PIPESRC_WIDTH_MASK, (w)) #define PIPESRC_HEIGHT_MASK REG_GENMASK(15, 0) #define PIPESRC_HEIGHT(h) REG_FIELD_PREP(PIPESRC_HEIGHT_MASK, (h)) -#define _BCLRPAT_A 0x60020 -#define _TRANS_VSYNCSHIFT_A 0x60028 -#define _TRANS_MULT_A 0x6002c -/* Pipe/transcoder B timing regs */ -#define _TRANS_HTOTAL_B 0x61000 -#define _TRANS_HBLANK_B 0x61004 -#define _TRANS_HSYNC_B 0x61008 -#define _TRANS_VTOTAL_B 0x6100c -#define _TRANS_VBLANK_B 0x61010 -#define _TRANS_VSYNC_B 0x61014 -#define _PIPEBSRC 0x6101c +#define _BCLRPAT_A 0x60020 #define _BCLRPAT_B 0x61020 +#define BCLRPAT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _BCLRPAT_A) + +#define _TRANS_VSYNCSHIFT_A 0x60028 #define _TRANS_VSYNCSHIFT_B 0x61028 +#define TRANS_VSYNCSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNCSHIFT_A) + +#define _TRANS_MULT_A 0x6002c #define _TRANS_MULT_B 0x6102c +#define TRANS_MULT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A) /* DSI 0 timing regs */ #define _TRANS_HTOTAL_DSI0 0x6b000 @@ -1136,17 +1152,6 @@ #define _TRANS_VSYNC_DSI1 0x6b814 #define _TRANS_VSYNCSHIFT_DSI1 0x6b828 -#define TRANS_HTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HTOTAL_A) -#define TRANS_HBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HBLANK_A) -#define TRANS_HSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HSYNC_A) -#define TRANS_VTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VTOTAL_A) -#define TRANS_VBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VBLANK_A) -#define TRANS_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNC_A) -#define BCLRPAT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _BCLRPAT_A) -#define TRANS_VSYNCSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNCSHIFT_A) -#define PIPESRC(dev_priv, pipe) _MMIO_TRANS2(dev_priv, (pipe), _PIPEASRC) -#define TRANS_MULT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A) - /* VGA port control */ #define ADPA _MMIO(0x61100) #define PCH_ADPA _MMIO(0xe1100) From 2575db5092aaaa8702950f5fffae4932e0470d48 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:46 +0300 Subject: [PATCH 029/205] drm/i915/reg: fix g4x pipe data/link m/n register style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/f55960ce8cdcf654e5de19274c7b67b3d3497550.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7a6ca695bb6a..a1f86b32efac 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1554,16 +1554,16 @@ */ #define _PIPEA_DATA_M_G4X 0x70050 #define _PIPEB_DATA_M_G4X 0x71050 - +#define PIPE_DATA_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X) /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ #define TU_SIZE_MASK REG_GENMASK(30, 25) #define TU_SIZE(x) REG_FIELD_PREP(TU_SIZE_MASK, (x) - 1) /* default size 64 */ - #define DATA_LINK_M_N_MASK REG_GENMASK(23, 0) #define DATA_LINK_N_MAX (0x800000) #define _PIPEA_DATA_N_G4X 0x70054 #define _PIPEB_DATA_N_G4X 0x71054 +#define PIPE_DATA_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X) /* * Computing Link M and N values for the Display Port link @@ -1575,15 +1575,12 @@ * The Link value is transmitted in the Main Stream * Attributes and VB-ID. */ - #define _PIPEA_LINK_M_G4X 0x70060 #define _PIPEB_LINK_M_G4X 0x71060 +#define PIPE_LINK_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X) + #define _PIPEA_LINK_N_G4X 0x70064 #define _PIPEB_LINK_N_G4X 0x71064 - -#define PIPE_DATA_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X) -#define PIPE_DATA_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X) -#define PIPE_LINK_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X) #define PIPE_LINK_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X) /* Pipe A */ From 2ac6a84b042eb26a55b7c7b499629524789cb8af Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:47 +0300 Subject: [PATCH 030/205] drm/i915/reg: fix pipe conf, stat etc. register style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/4360912222c8c0516d84253c3a05ef1cf421da01.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a1f86b32efac..591a6dc9c3bc 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1585,9 +1585,12 @@ /* Pipe A */ #define _PIPEADSL 0x70000 +#define PIPEDSL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEADSL) #define PIPEDSL_CURR_FIELD REG_BIT(31) /* ctg+ */ #define PIPEDSL_LINE_MASK REG_GENMASK(19, 0) + #define _TRANSACONF 0x70008 +#define TRANSCONF(dev_priv, trans) _MMIO_PIPE2(dev_priv, (trans), _TRANSACONF) #define TRANSCONF_ENABLE REG_BIT(31) #define TRANSCONF_DOUBLE_WIDE REG_BIT(30) /* pre-i965 */ #define TRANSCONF_STATE_ENABLE REG_BIT(30) /* i965+ */ @@ -1647,6 +1650,7 @@ #define TRANSCONF_PIXEL_COUNT_SCALING_X4 1 #define _PIPEASTAT 0x70024 +#define PIPESTAT(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEASTAT) #define PIPE_FIFO_UNDERRUN_STATUS (1UL << 31) #define SPRITE1_FLIP_DONE_INT_EN_VLV (1UL << 30) #define PIPE_CRC_ERROR_ENABLE (1UL << 29) @@ -1693,15 +1697,8 @@ #define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1) #define PIPE_HBLANK_INT_STATUS (1UL << 0) #define PIPE_OVERLAY_UPDATED_STATUS (1UL << 0) - -#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000 -#define PIPESTAT_INT_STATUS_MASK 0x0000ffff - -#define TRANSCONF(dev_priv, trans) _MMIO_PIPE2(dev_priv, (trans), _TRANSACONF) -#define PIPEDSL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEADSL) -#define PIPEFRAME(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEHIGH) -#define PIPEFRAMEPIXEL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEPIXEL) -#define PIPESTAT(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEASTAT) +#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000 +#define PIPESTAT_INT_STATUS_MASK 0x0000ffff #define _PIPE_ARB_CTL_A 0x70028 /* icl+ */ #define PIPE_ARB_CTL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPE_ARB_CTL_A) @@ -1709,6 +1706,7 @@ #define _PIPE_MISC_A 0x70030 #define _PIPE_MISC_B 0x71030 +#define PIPE_MISC(pipe) _MMIO_PIPE(pipe, _PIPE_MISC_A, _PIPE_MISC_B) #define PIPE_MISC_YUV420_ENABLE REG_BIT(27) /* glk+ */ #define PIPE_MISC_YUV420_MODE_FULL_BLEND REG_BIT(26) /* glk+ */ #define PIPE_MISC_HDR_MODE_PRECISION REG_BIT(23) /* icl+ */ @@ -1736,16 +1734,15 @@ #define PIPE_MISC_DITHER_TYPE_ST1 REG_FIELD_PREP(PIPE_MISC_DITHER_TYPE_MASK, 1) #define PIPE_MISC_DITHER_TYPE_ST2 REG_FIELD_PREP(PIPE_MISC_DITHER_TYPE_MASK, 2) #define PIPE_MISC_DITHER_TYPE_TEMP REG_FIELD_PREP(PIPE_MISC_DITHER_TYPE_MASK, 3) -#define PIPE_MISC(pipe) _MMIO_PIPE(pipe, _PIPE_MISC_A, _PIPE_MISC_B) #define _PIPE_MISC2_A 0x7002C #define _PIPE_MISC2_B 0x7102C +#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B) #define PIPE_MISC2_BUBBLE_COUNTER_MASK REG_GENMASK(31, 24) #define PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN REG_FIELD_PREP(PIPE_MISC2_BUBBLE_COUNTER_MASK, 80) #define PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS REG_FIELD_PREP(PIPE_MISC2_BUBBLE_COUNTER_MASK, 20) #define PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK REG_GENMASK(2, 0) /* tgl+ */ #define PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id) REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id)) -#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B) #define _ICL_PIPE_A_STATUS 0x70058 #define ICL_PIPESTATUS(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _ICL_PIPE_A_STATUS) @@ -2068,33 +2065,38 @@ * frame = (high1 << 8) | low1; */ #define _PIPEAFRAMEHIGH 0x70040 +#define PIPEFRAME(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEHIGH) #define PIPE_FRAME_HIGH_MASK 0x0000ffff #define PIPE_FRAME_HIGH_SHIFT 0 + #define _PIPEAFRAMEPIXEL 0x70044 +#define PIPEFRAMEPIXEL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEPIXEL) #define PIPE_FRAME_LOW_MASK 0xff000000 #define PIPE_FRAME_LOW_SHIFT 24 #define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_SHIFT 0 + /* GM45+ just has to be different */ #define _PIPEA_FRMCOUNT_G4X 0x70040 -#define _PIPEA_FLIPCOUNT_G4X 0x70044 #define PIPE_FRMCOUNT_G4X(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FRMCOUNT_G4X) + +#define _PIPEA_FLIPCOUNT_G4X 0x70044 #define PIPE_FLIPCOUNT_G4X(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FLIPCOUNT_G4X) /* CHV pipe B blender */ #define _CHV_BLEND_A 0x60a00 +#define CHV_BLEND(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_BLEND_A) #define CHV_BLEND_MASK REG_GENMASK(31, 30) #define CHV_BLEND_LEGACY REG_FIELD_PREP(CHV_BLEND_MASK, 0) #define CHV_BLEND_ANDROID REG_FIELD_PREP(CHV_BLEND_MASK, 1) #define CHV_BLEND_MPO REG_FIELD_PREP(CHV_BLEND_MASK, 2) + #define _CHV_CANVAS_A 0x60a04 +#define CHV_CANVAS(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_CANVAS_A) #define CHV_CANVAS_RED_MASK REG_GENMASK(29, 20) #define CHV_CANVAS_GREEN_MASK REG_GENMASK(19, 10) #define CHV_CANVAS_BLUE_MASK REG_GENMASK(9, 0) -#define CHV_BLEND(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_BLEND_A) -#define CHV_CANVAS(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_CANVAS_A) - /* Display/Sprite base address macros */ #define DISP_BASEADDR_MASK (0xfffff000) #define I915_LO_DISPBASE(val) ((val) & ~DISP_BASEADDR_MASK) From 7bb46e03e1e483f7002f52f474405e6561591763 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:48 +0300 Subject: [PATCH 031/205] drm/i915/reg: fix pipe data/link m/n register style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/99fb1c8aabb7646ca2565db0b969cf15d9103318.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 39 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 591a6dc9c3bc..9ece696baae8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2160,32 +2160,35 @@ # define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11) #define _PIPEA_DATA_M1 0x60030 -#define _PIPEA_DATA_N1 0x60034 -#define _PIPEA_DATA_M2 0x60038 -#define _PIPEA_DATA_N2 0x6003c -#define _PIPEA_LINK_M1 0x60040 -#define _PIPEA_LINK_N1 0x60044 -#define _PIPEA_LINK_M2 0x60048 -#define _PIPEA_LINK_N2 0x6004c - -/* PIPEB timing regs are same start from 0x61000 */ - #define _PIPEB_DATA_M1 0x61030 -#define _PIPEB_DATA_N1 0x61034 -#define _PIPEB_DATA_M2 0x61038 -#define _PIPEB_DATA_N2 0x6103c -#define _PIPEB_LINK_M1 0x61040 -#define _PIPEB_LINK_N1 0x61044 -#define _PIPEB_LINK_M2 0x61048 -#define _PIPEB_LINK_N2 0x6104c - #define PIPE_DATA_M1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M1) + +#define _PIPEA_DATA_N1 0x60034 +#define _PIPEB_DATA_N1 0x61034 #define PIPE_DATA_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N1) + +#define _PIPEA_DATA_M2 0x60038 +#define _PIPEB_DATA_M2 0x61038 #define PIPE_DATA_M2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M2) + +#define _PIPEA_DATA_N2 0x6003c +#define _PIPEB_DATA_N2 0x6103c #define PIPE_DATA_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N2) + +#define _PIPEA_LINK_M1 0x60040 +#define _PIPEB_LINK_M1 0x61040 #define PIPE_LINK_M1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M1) + +#define _PIPEA_LINK_N1 0x60044 +#define _PIPEB_LINK_N1 0x61044 #define PIPE_LINK_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N1) + +#define _PIPEA_LINK_M2 0x60048 +#define _PIPEB_LINK_M2 0x61048 #define PIPE_LINK_M2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M2) + +#define _PIPEA_LINK_N2 0x6004c +#define _PIPEB_LINK_N2 0x6104c #define PIPE_LINK_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N2) /* CPU panel fitter */ From 01c1305820462ef1e996c95a11183c0d907717a9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:49 +0300 Subject: [PATCH 032/205] drm/i915/reg: fix SKL scaler register style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/0c6188d7afe688b43734ee4ef5f2c403f805bd48.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 64 ++++++++++++++++----------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9ece696baae8..2f09145b9791 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2229,11 +2229,15 @@ /* * Skylake scalers */ +#define _ID(id, a, b) _PICK_EVEN(id, a, b) #define _PS_1A_CTRL 0x68180 #define _PS_2A_CTRL 0x68280 #define _PS_1B_CTRL 0x68980 #define _PS_2B_CTRL 0x68A80 #define _PS_1C_CTRL 0x69180 +#define SKL_PS_CTRL(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_1A_CTRL, _PS_2A_CTRL), \ + _ID(id, _PS_1B_CTRL, _PS_2B_CTRL)) #define PS_SCALER_EN REG_BIT(31) #define PS_SCALER_TYPE_MASK REG_BIT(30) /* icl+ */ #define PS_SCALER_TYPE_NON_LINEAR REG_FIELD_PREP(PS_SCALER_TYPE_MASK, 0) @@ -2286,6 +2290,9 @@ #define _PS_PWR_GATE_1B 0x68960 #define _PS_PWR_GATE_2B 0x68A60 #define _PS_PWR_GATE_1C 0x69160 +#define SKL_PS_PWR_GATE(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_PWR_GATE_1A, _PS_PWR_GATE_2A), \ + _ID(id, _PS_PWR_GATE_1B, _PS_PWR_GATE_2B)) #define PS_PWR_GATE_DIS_OVERRIDE REG_BIT(31) #define PS_PWR_GATE_SETTLING_TIME_MASK REG_GENMASK(4, 3) #define PS_PWR_GATE_SETTLING_TIME_32 REG_FIELD_PREP(PS_PWR_GATE_SETTLING_TIME_MASK, 0) @@ -2303,6 +2310,9 @@ #define _PS_WIN_POS_1B 0x68970 #define _PS_WIN_POS_2B 0x68A70 #define _PS_WIN_POS_1C 0x69170 +#define SKL_PS_WIN_POS(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_WIN_POS_1A, _PS_WIN_POS_2A), \ + _ID(id, _PS_WIN_POS_1B, _PS_WIN_POS_2B)) #define PS_WIN_XPOS_MASK REG_GENMASK(31, 16) #define PS_WIN_XPOS(x) REG_FIELD_PREP(PS_WIN_XPOS_MASK, (x)) #define PS_WIN_YPOS_MASK REG_GENMASK(15, 0) @@ -2313,6 +2323,9 @@ #define _PS_WIN_SZ_1B 0x68974 #define _PS_WIN_SZ_2B 0x68A74 #define _PS_WIN_SZ_1C 0x69174 +#define SKL_PS_WIN_SZ(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_WIN_SZ_1A, _PS_WIN_SZ_2A), \ + _ID(id, _PS_WIN_SZ_1B, _PS_WIN_SZ_2B)) #define PS_WIN_XSIZE_MASK REG_GENMASK(31, 16) #define PS_WIN_XSIZE(w) REG_FIELD_PREP(PS_WIN_XSIZE_MASK, (w)) #define PS_WIN_YSIZE_MASK REG_GENMASK(15, 0) @@ -2323,18 +2336,27 @@ #define _PS_VSCALE_1B 0x68984 #define _PS_VSCALE_2B 0x68A84 #define _PS_VSCALE_1C 0x69184 +#define SKL_PS_VSCALE(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_VSCALE_1A, _PS_VSCALE_2A), \ + _ID(id, _PS_VSCALE_1B, _PS_VSCALE_2B)) #define _PS_HSCALE_1A 0x68190 #define _PS_HSCALE_2A 0x68290 #define _PS_HSCALE_1B 0x68990 #define _PS_HSCALE_2B 0x68A90 #define _PS_HSCALE_1C 0x69190 +#define SKL_PS_HSCALE(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_HSCALE_1A, _PS_HSCALE_2A), \ + _ID(id, _PS_HSCALE_1B, _PS_HSCALE_2B)) #define _PS_VPHASE_1A 0x68188 #define _PS_VPHASE_2A 0x68288 #define _PS_VPHASE_1B 0x68988 #define _PS_VPHASE_2B 0x68A88 #define _PS_VPHASE_1C 0x69188 +#define SKL_PS_VPHASE(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_VPHASE_1A, _PS_VPHASE_2A), \ + _ID(id, _PS_VPHASE_1B, _PS_VPHASE_2B)) #define PS_Y_PHASE_MASK REG_GENMASK(31, 16) #define PS_Y_PHASE(x) REG_FIELD_PREP(PS_Y_PHASE_MASK, (x)) #define PS_UV_RGB_PHASE_MASK REG_GENMASK(15, 0) @@ -2347,56 +2369,32 @@ #define _PS_HPHASE_1B 0x68994 #define _PS_HPHASE_2B 0x68A94 #define _PS_HPHASE_1C 0x69194 +#define SKL_PS_HPHASE(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_HPHASE_1A, _PS_HPHASE_2A), \ + _ID(id, _PS_HPHASE_1B, _PS_HPHASE_2B)) #define _PS_ECC_STAT_1A 0x681D0 #define _PS_ECC_STAT_2A 0x682D0 #define _PS_ECC_STAT_1B 0x689D0 #define _PS_ECC_STAT_2B 0x68AD0 #define _PS_ECC_STAT_1C 0x691D0 +#define SKL_PS_ECC_STAT(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \ + _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)) #define _PS_COEF_SET0_INDEX_1A 0x68198 #define _PS_COEF_SET0_INDEX_2A 0x68298 #define _PS_COEF_SET0_INDEX_1B 0x68998 #define _PS_COEF_SET0_INDEX_2B 0x68A98 +#define GLK_PS_COEF_INDEX_SET(pipe, id, set) _MMIO_PIPE(pipe, \ + _ID(id, _PS_COEF_SET0_INDEX_1A, _PS_COEF_SET0_INDEX_2A) + (set) * 8, \ + _ID(id, _PS_COEF_SET0_INDEX_1B, _PS_COEF_SET0_INDEX_2B) + (set) * 8) #define PS_COEF_INDEX_AUTO_INC REG_BIT(10) #define _PS_COEF_SET0_DATA_1A 0x6819C #define _PS_COEF_SET0_DATA_2A 0x6829C #define _PS_COEF_SET0_DATA_1B 0x6899C #define _PS_COEF_SET0_DATA_2B 0x68A9C - -#define _ID(id, a, b) _PICK_EVEN(id, a, b) -#define SKL_PS_CTRL(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_1A_CTRL, _PS_2A_CTRL), \ - _ID(id, _PS_1B_CTRL, _PS_2B_CTRL)) -#define SKL_PS_PWR_GATE(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_PWR_GATE_1A, _PS_PWR_GATE_2A), \ - _ID(id, _PS_PWR_GATE_1B, _PS_PWR_GATE_2B)) -#define SKL_PS_WIN_POS(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_WIN_POS_1A, _PS_WIN_POS_2A), \ - _ID(id, _PS_WIN_POS_1B, _PS_WIN_POS_2B)) -#define SKL_PS_WIN_SZ(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_WIN_SZ_1A, _PS_WIN_SZ_2A), \ - _ID(id, _PS_WIN_SZ_1B, _PS_WIN_SZ_2B)) -#define SKL_PS_VSCALE(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_VSCALE_1A, _PS_VSCALE_2A), \ - _ID(id, _PS_VSCALE_1B, _PS_VSCALE_2B)) -#define SKL_PS_HSCALE(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_HSCALE_1A, _PS_HSCALE_2A), \ - _ID(id, _PS_HSCALE_1B, _PS_HSCALE_2B)) -#define SKL_PS_VPHASE(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_VPHASE_1A, _PS_VPHASE_2A), \ - _ID(id, _PS_VPHASE_1B, _PS_VPHASE_2B)) -#define SKL_PS_HPHASE(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_HPHASE_1A, _PS_HPHASE_2A), \ - _ID(id, _PS_HPHASE_1B, _PS_HPHASE_2B)) -#define SKL_PS_ECC_STAT(pipe, id) _MMIO_PIPE(pipe, \ - _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \ - _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)) -#define GLK_PS_COEF_INDEX_SET(pipe, id, set) _MMIO_PIPE(pipe, \ - _ID(id, _PS_COEF_SET0_INDEX_1A, _PS_COEF_SET0_INDEX_2A) + (set) * 8, \ - _ID(id, _PS_COEF_SET0_INDEX_1B, _PS_COEF_SET0_INDEX_2B) + (set) * 8) - #define GLK_PS_COEF_DATA_SET(pipe, id, set) _MMIO_PIPE(pipe, \ _ID(id, _PS_COEF_SET0_DATA_1A, _PS_COEF_SET0_DATA_2A) + (set) * 8, \ _ID(id, _PS_COEF_SET0_DATA_1B, _PS_COEF_SET0_DATA_2B) + (set) * 8) From 869b3653fe58e80d3753924153be85d6783ba009 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:50 +0300 Subject: [PATCH 033/205] drm/i915/reg: fix PCH transcoder timing indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/f56e48a927692cec382e292602e0fa68e37f3b93.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2f09145b9791..1eede96a5415 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3292,13 +3292,13 @@ #define HSW_STEREO_3D_CTL(dev_priv, trans) _MMIO_PIPE2(dev_priv, trans, _HSW_STEREO_3D_CTL_A) -#define _PCH_TRANS_HTOTAL_B 0xe1000 -#define _PCH_TRANS_HBLANK_B 0xe1004 -#define _PCH_TRANS_HSYNC_B 0xe1008 -#define _PCH_TRANS_VTOTAL_B 0xe100c -#define _PCH_TRANS_VBLANK_B 0xe1010 -#define _PCH_TRANS_VSYNC_B 0xe1014 -#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028 +#define _PCH_TRANS_HTOTAL_B 0xe1000 +#define _PCH_TRANS_HBLANK_B 0xe1004 +#define _PCH_TRANS_HSYNC_B 0xe1008 +#define _PCH_TRANS_VTOTAL_B 0xe100c +#define _PCH_TRANS_VBLANK_B 0xe1010 +#define _PCH_TRANS_VSYNC_B 0xe1014 +#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028 #define PCH_TRANS_HTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B) #define PCH_TRANS_HBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B) From 6f369b78f9af845fc5c1028be6ae208d038992ba Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:51 +0300 Subject: [PATCH 034/205] drm/i915/reg: fix PCH transcoder timing and data/link m/n style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. v2: Rebase with the indentation fixed (Ville) Reviewed-by: Ville Syrjälä # v1 Link: https://patchwork.freedesktop.org/patch/msgid/90b1145453050797d3030bc2e5e24da18f34bdda.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 77 ++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1eede96a5415..b617de6b6928 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3160,33 +3160,76 @@ /* transcoder */ #define _PCH_TRANS_HTOTAL_A 0xe0000 +#define _PCH_TRANS_HTOTAL_B 0xe1000 +#define PCH_TRANS_HTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B) #define TRANS_HTOTAL_SHIFT 16 #define TRANS_HACTIVE_SHIFT 0 + #define _PCH_TRANS_HBLANK_A 0xe0004 +#define _PCH_TRANS_HBLANK_B 0xe1004 +#define PCH_TRANS_HBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B) #define TRANS_HBLANK_END_SHIFT 16 #define TRANS_HBLANK_START_SHIFT 0 + #define _PCH_TRANS_HSYNC_A 0xe0008 +#define _PCH_TRANS_HSYNC_B 0xe1008 +#define PCH_TRANS_HSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B) #define TRANS_HSYNC_END_SHIFT 16 #define TRANS_HSYNC_START_SHIFT 0 + #define _PCH_TRANS_VTOTAL_A 0xe000c +#define _PCH_TRANS_VTOTAL_B 0xe100c +#define PCH_TRANS_VTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B) #define TRANS_VTOTAL_SHIFT 16 #define TRANS_VACTIVE_SHIFT 0 + #define _PCH_TRANS_VBLANK_A 0xe0010 +#define _PCH_TRANS_VBLANK_B 0xe1010 +#define PCH_TRANS_VBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B) #define TRANS_VBLANK_END_SHIFT 16 #define TRANS_VBLANK_START_SHIFT 0 + #define _PCH_TRANS_VSYNC_A 0xe0014 +#define _PCH_TRANS_VSYNC_B 0xe1014 +#define PCH_TRANS_VSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B) #define TRANS_VSYNC_END_SHIFT 16 #define TRANS_VSYNC_START_SHIFT 0 + #define _PCH_TRANS_VSYNCSHIFT_A 0xe0028 +#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028 +#define PCH_TRANS_VSYNCSHIFT(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, _PCH_TRANS_VSYNCSHIFT_B) #define _PCH_TRANSA_DATA_M1 0xe0030 +#define _PCH_TRANSB_DATA_M1 0xe1030 +#define PCH_TRANS_DATA_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1) + #define _PCH_TRANSA_DATA_N1 0xe0034 +#define _PCH_TRANSB_DATA_N1 0xe1034 +#define PCH_TRANS_DATA_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1) + #define _PCH_TRANSA_DATA_M2 0xe0038 +#define _PCH_TRANSB_DATA_M2 0xe1038 +#define PCH_TRANS_DATA_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2) + #define _PCH_TRANSA_DATA_N2 0xe003c +#define _PCH_TRANSB_DATA_N2 0xe103c +#define PCH_TRANS_DATA_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2) + #define _PCH_TRANSA_LINK_M1 0xe0040 +#define _PCH_TRANSB_LINK_M1 0xe1040 +#define PCH_TRANS_LINK_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1) + #define _PCH_TRANSA_LINK_N1 0xe0044 +#define _PCH_TRANSB_LINK_N1 0xe1044 +#define PCH_TRANS_LINK_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1) + #define _PCH_TRANSA_LINK_M2 0xe0048 +#define _PCH_TRANSB_LINK_M2 0xe1048 +#define PCH_TRANS_LINK_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2) + #define _PCH_TRANSA_LINK_N2 0xe004c +#define _PCH_TRANSB_LINK_N2 0xe104c +#define PCH_TRANS_LINK_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2) /* Per-transcoder DIP controls (PCH) */ #define _VIDEO_DIP_CTL_A 0xe0200 @@ -3292,40 +3335,6 @@ #define HSW_STEREO_3D_CTL(dev_priv, trans) _MMIO_PIPE2(dev_priv, trans, _HSW_STEREO_3D_CTL_A) -#define _PCH_TRANS_HTOTAL_B 0xe1000 -#define _PCH_TRANS_HBLANK_B 0xe1004 -#define _PCH_TRANS_HSYNC_B 0xe1008 -#define _PCH_TRANS_VTOTAL_B 0xe100c -#define _PCH_TRANS_VBLANK_B 0xe1010 -#define _PCH_TRANS_VSYNC_B 0xe1014 -#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028 - -#define PCH_TRANS_HTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B) -#define PCH_TRANS_HBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B) -#define PCH_TRANS_HSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B) -#define PCH_TRANS_VTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B) -#define PCH_TRANS_VBLANK(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B) -#define PCH_TRANS_VSYNC(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B) -#define PCH_TRANS_VSYNCSHIFT(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, _PCH_TRANS_VSYNCSHIFT_B) - -#define _PCH_TRANSB_DATA_M1 0xe1030 -#define _PCH_TRANSB_DATA_N1 0xe1034 -#define _PCH_TRANSB_DATA_M2 0xe1038 -#define _PCH_TRANSB_DATA_N2 0xe103c -#define _PCH_TRANSB_LINK_M1 0xe1040 -#define _PCH_TRANSB_LINK_N1 0xe1044 -#define _PCH_TRANSB_LINK_M2 0xe1048 -#define _PCH_TRANSB_LINK_N2 0xe104c - -#define PCH_TRANS_DATA_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1) -#define PCH_TRANS_DATA_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1) -#define PCH_TRANS_DATA_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2) -#define PCH_TRANS_DATA_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2) -#define PCH_TRANS_LINK_M1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1) -#define PCH_TRANS_LINK_N1(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1) -#define PCH_TRANS_LINK_M2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2) -#define PCH_TRANS_LINK_N2(pipe) _MMIO_PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2) - #define _PCH_TRANSACONF 0xf0008 #define _PCH_TRANSBCONF 0xf1008 #define PCH_TRANSCONF(pipe) _MMIO_PIPE(pipe, _PCH_TRANSACONF, _PCH_TRANSBCONF) From c9e2071fd74f8179030b7ddb539c9618b54d09f7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:52 +0300 Subject: [PATCH 035/205] drm/i915/reg: fix DIP CTL register style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/fdc607b716cf86b8bc88c15a43bc7088c5aab05f.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 82 ++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b617de6b6928..489a88b133d6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3233,20 +3233,20 @@ /* Per-transcoder DIP controls (PCH) */ #define _VIDEO_DIP_CTL_A 0xe0200 +#define _VIDEO_DIP_CTL_B 0xe1200 +#define TVIDEO_DIP_CTL(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B) + #define _VIDEO_DIP_DATA_A 0xe0208 +#define _VIDEO_DIP_DATA_B 0xe1208 +#define TVIDEO_DIP_DATA(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B) + #define _VIDEO_DIP_GCP_A 0xe0210 +#define _VIDEO_DIP_GCP_B 0xe1210 +#define TVIDEO_DIP_GCP(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B) #define GCP_COLOR_INDICATION (1 << 2) #define GCP_DEFAULT_PHASE_ENABLE (1 << 1) #define GCP_AV_MUTE (1 << 0) -#define _VIDEO_DIP_CTL_B 0xe1200 -#define _VIDEO_DIP_DATA_B 0xe1208 -#define _VIDEO_DIP_GCP_B 0xe1210 - -#define TVIDEO_DIP_CTL(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B) -#define TVIDEO_DIP_DATA(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B) -#define TVIDEO_DIP_GCP(pipe) _MMIO_PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B) - /* Per-transcoder DIP controls (VLV) */ #define _VLV_VIDEO_DIP_CTL_A 0x60200 #define _VLV_VIDEO_DIP_CTL_B 0x61170 @@ -3273,36 +3273,54 @@ _CHV_VIDEO_DIP_GDCP_PAYLOAD_C) /* Haswell DIP controls */ - #define _HSW_VIDEO_DIP_CTL_A 0x60200 -#define _HSW_VIDEO_DIP_AVI_DATA_A 0x60220 -#define _HSW_VIDEO_DIP_VS_DATA_A 0x60260 -#define _HSW_VIDEO_DIP_SPD_DATA_A 0x602A0 -#define _HSW_VIDEO_DIP_GMP_DATA_A 0x602E0 -#define _HSW_VIDEO_DIP_VSC_DATA_A 0x60320 -#define _ADL_VIDEO_DIP_AS_DATA_A 0x60484 -#define _GLK_VIDEO_DIP_DRM_DATA_A 0x60440 -#define _HSW_VIDEO_DIP_AVI_ECC_A 0x60240 -#define _HSW_VIDEO_DIP_VS_ECC_A 0x60280 -#define _HSW_VIDEO_DIP_SPD_ECC_A 0x602C0 -#define _HSW_VIDEO_DIP_GMP_ECC_A 0x60300 -#define _HSW_VIDEO_DIP_VSC_ECC_A 0x60344 -#define _HSW_VIDEO_DIP_GCP_A 0x60210 - #define _HSW_VIDEO_DIP_CTL_B 0x61200 +#define HSW_TVIDEO_DIP_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_CTL_A) + +#define _HSW_VIDEO_DIP_AVI_DATA_A 0x60220 #define _HSW_VIDEO_DIP_AVI_DATA_B 0x61220 +#define HSW_TVIDEO_DIP_AVI_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4) + +#define _HSW_VIDEO_DIP_VS_DATA_A 0x60260 #define _HSW_VIDEO_DIP_VS_DATA_B 0x61260 +#define HSW_TVIDEO_DIP_VS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4) + +#define _HSW_VIDEO_DIP_SPD_DATA_A 0x602A0 #define _HSW_VIDEO_DIP_SPD_DATA_B 0x612A0 +#define HSW_TVIDEO_DIP_SPD_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4) + +#define _HSW_VIDEO_DIP_GMP_DATA_A 0x602E0 #define _HSW_VIDEO_DIP_GMP_DATA_B 0x612E0 +#define HSW_TVIDEO_DIP_GMP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4) + +#define _HSW_VIDEO_DIP_VSC_DATA_A 0x60320 #define _HSW_VIDEO_DIP_VSC_DATA_B 0x61320 +#define HSW_TVIDEO_DIP_VSC_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4) + +/*ADLP and later: */ +#define _ADL_VIDEO_DIP_AS_DATA_A 0x60484 #define _ADL_VIDEO_DIP_AS_DATA_B 0x61484 +#define ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans,\ + _ADL_VIDEO_DIP_AS_DATA_A + (i) * 4) + +#define _GLK_VIDEO_DIP_DRM_DATA_A 0x60440 #define _GLK_VIDEO_DIP_DRM_DATA_B 0x61440 +#define GLK_TVIDEO_DIP_DRM_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4) + +#define _HSW_VIDEO_DIP_AVI_ECC_A 0x60240 #define _HSW_VIDEO_DIP_BVI_ECC_B 0x61240 +#define _HSW_VIDEO_DIP_VS_ECC_A 0x60280 #define _HSW_VIDEO_DIP_VS_ECC_B 0x61280 +#define _HSW_VIDEO_DIP_SPD_ECC_A 0x602C0 #define _HSW_VIDEO_DIP_SPD_ECC_B 0x612C0 +#define _HSW_VIDEO_DIP_GMP_ECC_A 0x60300 #define _HSW_VIDEO_DIP_GMP_ECC_B 0x61300 +#define _HSW_VIDEO_DIP_VSC_ECC_A 0x60344 #define _HSW_VIDEO_DIP_VSC_ECC_B 0x61344 + +#define _HSW_VIDEO_DIP_GCP_A 0x60210 #define _HSW_VIDEO_DIP_GCP_B 0x61210 +#define HSW_TVIDEO_DIP_GCP(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GCP_A) /* Icelake PPS_DATA and _ECC DIP Registers. * These are available for transcoders B,C and eDP. @@ -3312,28 +3330,16 @@ #define _ICL_VIDEO_DIP_PPS_DATA_A 0x60350 #define _ICL_VIDEO_DIP_PPS_DATA_B 0x61350 +#define ICL_VIDEO_DIP_PPS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4) + #define _ICL_VIDEO_DIP_PPS_ECC_A 0x603D4 #define _ICL_VIDEO_DIP_PPS_ECC_B 0x613D4 - -#define HSW_TVIDEO_DIP_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_CTL_A) -#define HSW_TVIDEO_DIP_GCP(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GCP_A) -#define HSW_TVIDEO_DIP_AVI_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4) -#define HSW_TVIDEO_DIP_VS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4) -#define HSW_TVIDEO_DIP_SPD_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4) -#define HSW_TVIDEO_DIP_GMP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4) -#define HSW_TVIDEO_DIP_VSC_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4) -#define GLK_TVIDEO_DIP_DRM_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4) -#define ICL_VIDEO_DIP_PPS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4) #define ICL_VIDEO_DIP_PPS_ECC(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_ECC_A + (i) * 4) -/*ADLP and later: */ -#define ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans,\ - _ADL_VIDEO_DIP_AS_DATA_A + (i) * 4) #define _HSW_STEREO_3D_CTL_A 0x70020 -#define S3D_ENABLE (1 << 31) #define _HSW_STEREO_3D_CTL_B 0x71020 - #define HSW_STEREO_3D_CTL(dev_priv, trans) _MMIO_PIPE2(dev_priv, trans, _HSW_STEREO_3D_CTL_A) +#define S3D_ENABLE (1 << 31) #define _PCH_TRANSACONF 0xf0008 #define _PCH_TRANSBCONF 0xf1008 From 4fd452ea3b02c15fcdcd2e346c6cacf6013d5b05 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:53 +0300 Subject: [PATCH 036/205] drm/i915/reg: fix small register style issues here and there MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to the style described at the top of i915_reg.h. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/0bbb79008bb83bc56669a1e969978769539d6c62.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 489a88b133d6..70864cf96102 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2195,6 +2195,7 @@ /* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */ #define _PFA_CTL_1 0x68080 #define _PFB_CTL_1 0x68880 +#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1) #define PF_ENABLE REG_BIT(31) #define PF_PIPE_SEL_MASK_IVB REG_GENMASK(30, 29) /* ivb/hsw */ #define PF_PIPE_SEL_IVB(pipe) REG_FIELD_PREP(PF_PIPE_SEL_MASK_IVB, (pipe)) @@ -2203,27 +2204,29 @@ #define PF_FILTER_MED_3x3 REG_FIELD_PREP(PF_FILTER_MASK, 1) #define PF_FILTER_EDGE_ENHANCE REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 2) #define PF_FILTER_EDGE_SOFTEN REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 3) + #define _PFA_WIN_SZ 0x68074 #define _PFB_WIN_SZ 0x68874 +#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ) #define PF_WIN_XSIZE_MASK REG_GENMASK(31, 16) #define PF_WIN_XSIZE(w) REG_FIELD_PREP(PF_WIN_XSIZE_MASK, (w)) #define PF_WIN_YSIZE_MASK REG_GENMASK(15, 0) #define PF_WIN_YSIZE(h) REG_FIELD_PREP(PF_WIN_YSIZE_MASK, (h)) + #define _PFA_WIN_POS 0x68070 #define _PFB_WIN_POS 0x68870 +#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS) #define PF_WIN_XPOS_MASK REG_GENMASK(31, 16) #define PF_WIN_XPOS(x) REG_FIELD_PREP(PF_WIN_XPOS_MASK, (x)) #define PF_WIN_YPOS_MASK REG_GENMASK(15, 0) #define PF_WIN_YPOS(y) REG_FIELD_PREP(PF_WIN_YPOS_MASK, (y)) + #define _PFA_VSCALE 0x68084 #define _PFB_VSCALE 0x68884 +#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE) + #define _PFA_HSCALE 0x68090 #define _PFB_HSCALE 0x68890 - -#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1) -#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ) -#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS) -#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE) #define PF_HSCALE(pipe) _MMIO_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE) /* @@ -3103,11 +3106,12 @@ #define PCH_DPLL(pll) _MMIO((pll) == 0 ? _PCH_DPLL_A : _PCH_DPLL_B) #define _PCH_FPA0 0xc6040 -#define FP_CB_TUNE (0x3 << 22) -#define _PCH_FPA1 0xc6044 #define _PCH_FPB0 0xc6048 -#define _PCH_FPB1 0xc604c #define PCH_FP0(pll) _MMIO((pll) == 0 ? _PCH_FPA0 : _PCH_FPB0) +#define FP_CB_TUNE (0x3 << 22) + +#define _PCH_FPA1 0xc6044 +#define _PCH_FPB1 0xc604c #define PCH_FP1(pll) _MMIO((pll) == 0 ? _PCH_FPA1 : _PCH_FPB1) #define PCH_DPLL_TEST _MMIO(0xc606c) @@ -4145,6 +4149,7 @@ enum skl_power_gate { #define _DPLL1_CFGCR1 0x6C040 #define _DPLL2_CFGCR1 0x6C048 #define _DPLL3_CFGCR1 0x6C050 +#define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1) #define DPLL_CFGCR1_FREQ_ENABLE (1 << 31) #define DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff << 9) #define DPLL_CFGCR1_DCO_FRACTION(x) ((x) << 9) @@ -4153,6 +4158,7 @@ enum skl_power_gate { #define _DPLL1_CFGCR2 0x6C044 #define _DPLL2_CFGCR2 0x6C04C #define _DPLL3_CFGCR2 0x6C054 +#define DPLL_CFGCR2(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2) #define DPLL_CFGCR2_QDIV_RATIO_MASK (0xff << 8) #define DPLL_CFGCR2_QDIV_RATIO(x) ((x) << 8) #define DPLL_CFGCR2_QDIV_MODE(x) ((x) << 7) @@ -4171,9 +4177,6 @@ enum skl_power_gate { #define DPLL_CFGCR2_PDIV_7_INVALID (5 << 2) #define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3) -#define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1) -#define DPLL_CFGCR2(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2) - /* ICL Clocks */ #define ICL_DPCLKA_CFGCR0 _MMIO(0x164280) #define ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy) (1 << _PICK(phy, 10, 11, 24, 4, 5)) From 5d66a870c818a8fb242b1b98e4fb7a7dd278b156 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:54 +0300 Subject: [PATCH 037/205] drm/i915/reg: remove unused DSI register macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not needed. Remove. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/2a8633038c0bd6ca06236558a609e021b30514f4.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 70864cf96102..6dbaaca1ab4c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1138,20 +1138,6 @@ #define _TRANS_MULT_B 0x6102c #define TRANS_MULT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A) -/* DSI 0 timing regs */ -#define _TRANS_HTOTAL_DSI0 0x6b000 -#define _TRANS_HSYNC_DSI0 0x6b008 -#define _TRANS_VTOTAL_DSI0 0x6b00c -#define _TRANS_VSYNC_DSI0 0x6b014 -#define _TRANS_VSYNCSHIFT_DSI0 0x6b028 - -/* DSI 1 timing regs */ -#define _TRANS_HTOTAL_DSI1 0x6b800 -#define _TRANS_HSYNC_DSI1 0x6b808 -#define _TRANS_VTOTAL_DSI1 0x6b80c -#define _TRANS_VSYNC_DSI1 0x6b814 -#define _TRANS_VSYNCSHIFT_DSI1 0x6b828 - /* VGA port control */ #define ADPA _MMIO(0x61100) #define PCH_ADPA _MMIO(0xe1100) @@ -2118,11 +2104,6 @@ #define SWF3(dev_priv, i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x72414 + (i) * 4) #define SWF_ILK(i) _MMIO(0x4F000 + (i) * 4) -/* ICL DSI 0 and 1 */ -#define _PIPEDSI0CONF 0x7b008 -#define _PIPEDSI1CONF 0x7b808 - - /* VBIOS regs */ #define VGACNTRL _MMIO(0x71400) # define VGA_DISP_DISABLE (1 << 31) From 1d256052ac3bc058993b77031338b24932e9844d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 10 Sep 2024 16:28:55 +0300 Subject: [PATCH 038/205] drm/i915/reg: remove superfluous whitespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up some whitespace. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1223c6c7ff59f541453a38f8f5e2df9eb3526573.1725974820.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6dbaaca1ab4c..7396fc630e29 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1142,7 +1142,6 @@ #define ADPA _MMIO(0x61100) #define PCH_ADPA _MMIO(0xe1100) #define VLV_ADPA _MMIO(VLV_DISPLAY_BASE + 0x61100) - #define ADPA_DAC_ENABLE (1 << 31) #define ADPA_DAC_DISABLE 0 #define ADPA_PIPE_SEL_SHIFT 30 @@ -1186,7 +1185,6 @@ #define ADPA_DPMS_STANDBY (2 << 10) #define ADPA_DPMS_OFF (3 << 10) - /* Hotplug control (945+ only) */ #define PORT_HOTPLUG_EN(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61110) #define PORTB_HOTPLUG_INT_EN (1 << 29) @@ -1437,11 +1435,9 @@ #define DP_B _MMIO(0x64100) #define DP_C _MMIO(0x64200) #define DP_D _MMIO(0x64300) - #define VLV_DP_B _MMIO(VLV_DISPLAY_BASE + 0x64100) #define VLV_DP_C _MMIO(VLV_DISPLAY_BASE + 0x64200) #define CHV_DP_D _MMIO(VLV_DISPLAY_BASE + 0x64300) - #define DP_PORT_EN (1 << 31) #define DP_PIPE_SEL_SHIFT 30 #define DP_PIPE_SEL_MASK (1 << 30) @@ -4250,7 +4246,6 @@ enum skl_power_gate { /* ADL-P Type C PLL */ #define PORTTC1_PLL_ENABLE 0x46038 #define PORTTC2_PLL_ENABLE 0x46040 - #define ADLP_PORTTC_PLL_ENABLE(tc_port) _MMIO_PORT((tc_port), \ PORTTC1_PLL_ENABLE, \ PORTTC2_PLL_ENABLE) From 9c2338ac4543e0fab3a1e0f9f025591e0f0d9f8f Mon Sep 17 00:00:00 2001 From: Arun R Murthy Date: Tue, 27 Aug 2024 13:42:05 +0530 Subject: [PATCH 039/205] drm/i915/display: BMG supports UHBR13.5 UHBR20 is not supported by battlemage and the maximum link rate supported is UHBR13.5 v2: Replace IS_DGFX with IS_BATTLEMAGE (Jani) HSD: 16023263677 Signed-off-by: Arun R Murthy Reviewed-by: Mika Kahola Fixes: 98b1c87a5e51 ("drm/i915/xe2hpd: Set maximum DP rate to UHBR13.5") Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240827081205.136569-1-arun.r.murthy@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a1fcedfd404b..b1b512e258ab 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -531,6 +531,10 @@ static void intel_dp_set_source_rates(struct intel_dp *intel_dp) { /* The values must be in increasing order */ + static const int bmg_rates[] = { + 162000, 216000, 243000, 270000, 324000, 432000, 540000, 675000, + 810000, 1000000, 1350000, + }; static const int mtl_rates[] = { 162000, 216000, 243000, 270000, 324000, 432000, 540000, 675000, 810000, 1000000, 2000000, @@ -561,8 +565,13 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) intel_dp->source_rates || intel_dp->num_source_rates); if (DISPLAY_VER(dev_priv) >= 14) { - source_rates = mtl_rates; - size = ARRAY_SIZE(mtl_rates); + if (IS_BATTLEMAGE(dev_priv)) { + source_rates = bmg_rates; + size = ARRAY_SIZE(bmg_rates); + } else { + source_rates = mtl_rates; + size = ARRAY_SIZE(mtl_rates); + } max_rate = mtl_max_source_rate(intel_dp); } else if (DISPLAY_VER(dev_priv) >= 11) { source_rates = icl_rates; From 26c85e7f40f9aed4f5f04dcb0ea0bce5d44f6f54 Mon Sep 17 00:00:00 2001 From: Chaitanya Kumar Borah Date: Thu, 22 Aug 2024 11:44:48 +0530 Subject: [PATCH 040/205] drm/i915: Do not explicilty enable FEC in DP_TP_CTL for UHBR rates In case of UHBR rates, we do not need to explicitly enable FEC by writing to DP_TP_CTL register. For MST use-cases, intel_dp_mst_find_vcpi_slots_for_bpp() takes care of setting fec_enable to false. However, it gets overwritten in intel_dp_dsc_compute_config(). This change keeps fec_enable false across MST and SST use-cases for UHBR rates. While at it, add a comment explaining why we don't enable FEC in eDP v1.5. v2: Correct logic to cater to SST use-cases (Jani) Signed-off-by: Chaitanya Kumar Borah Reviewed-by: Imre Deak Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240822061448.4085693-1-chaitanya.kumar.borah@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b1b512e258ab..cb0f6db5f8e7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2310,9 +2310,15 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, &pipe_config->hw.adjusted_mode; int ret; + /* + * Though eDP v1.5 supports FEC with DSC, unlike DP, it is optional. + * Since, FEC is a bandwidth overhead, continue to not enable it for + * eDP. Until, there is a good reason to do so. + */ pipe_config->fec_enable = pipe_config->fec_enable || (!intel_dp_is_edp(intel_dp) && - intel_dp_supports_fec(intel_dp, connector, pipe_config)); + intel_dp_supports_fec(intel_dp, connector, pipe_config) && + !intel_dp_is_uhbr(pipe_config)); if (!intel_dp_supports_dsc(connector, pipe_config)) return -EINVAL; From e35bf8f6a0ff06ceeff15bb032351cd5d006f92b Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 11 Sep 2024 14:35:39 +0530 Subject: [PATCH 041/205] drm/i915/hdcp: Move to using intel_display in intel_hdcp Move to using intel_display wherever possible in intel_hdcp.c as a part of code refactor. --v2 -Move intel_display to the first line wherever possible [Jani] -use the closest reference when using to_intel_display [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240911090540.643155-2-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hdcp.c | 685 +++++++++--------- drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 9 +- drivers/gpu/drm/i915/display/intel_hdcp_gsc.h | 5 +- .../drm/i915/display/intel_hdcp_gsc_message.h | 3 +- drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 7 +- 5 files changed, 361 insertions(+), 348 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index ebec03bc88e9..b964af7425cf 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -36,20 +36,20 @@ static void intel_hdcp_disable_hdcp_line_rekeying(struct intel_encoder *encoder, struct intel_hdcp *hdcp) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); /* Here we assume HDMI is in TMDS mode of operation */ if (encoder->type != INTEL_OUTPUT_HDMI) return; - if (DISPLAY_VER(dev_priv) >= 14) { - if (IS_DISPLAY_VER_STEP(dev_priv, IP_VER(14, 0), STEP_D0, STEP_FOREVER)) - intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder), + if (DISPLAY_VER(display) >= 14) { + if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_D0, STEP_FOREVER)) + intel_de_rmw(display, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder), 0, HDCP_LINE_REKEY_DISABLE); - else if (IS_DISPLAY_VER_STEP(dev_priv, IP_VER(14, 1), STEP_B0, STEP_FOREVER) || - IS_DISPLAY_VER_STEP(dev_priv, IP_VER(20, 0), STEP_B0, STEP_FOREVER)) - intel_de_rmw(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, hdcp->cpu_transcoder), + else if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 1), STEP_B0, STEP_FOREVER) || + IS_DISPLAY_VER_STEP(display, IP_VER(20, 0), STEP_B0, STEP_FOREVER)) + intel_de_rmw(display, + TRANS_DDI_FUNC_CTL(display, hdcp->cpu_transcoder), 0, TRANS_DDI_HDCP_LINE_REKEY_DISABLE); } } @@ -96,10 +96,10 @@ static int intel_hdcp_required_content_stream(struct intel_atomic_state *state, struct intel_digital_port *dig_port) { + struct intel_display *display = to_intel_display(state); struct drm_connector_list_iter conn_iter; struct intel_digital_port *conn_dig_port; struct intel_connector *connector; - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct hdcp_port_data *data = &dig_port->hdcp_port_data; bool enforce_type0 = false; int k; @@ -112,7 +112,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state, if (!dig_port->hdcp_mst_type1_capable) enforce_type0 = true; - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { if (connector->base.status == connector_status_disconnected) continue; @@ -134,7 +134,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state, } drm_connector_list_iter_end(&conn_iter); - if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k == 0)) + if (drm_WARN_ON(display->drm, data->k > INTEL_NUM_PIPES(display) || data->k == 0)) return -EINVAL; /* @@ -182,7 +182,7 @@ static int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port, const struct intel_hdcp_shim *shim, u8 *bksv) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); int ret, i, tries = 2; /* HDCP spec states that we must retry the bksv if it is invalid */ @@ -194,7 +194,7 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port, break; } if (i == tries) { - drm_dbg_kms(&i915->drm, "Bksv is invalid\n"); + drm_dbg_kms(display->drm, "Bksv is invalid\n"); return -ENODEV; } @@ -233,7 +233,7 @@ bool intel_hdcp_get_capability(struct intel_connector *connector) */ static bool intel_hdcp2_prerequisite(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_hdcp *hdcp = &connector->hdcp; /* I915 support for HDCP2.2 */ @@ -241,18 +241,18 @@ static bool intel_hdcp2_prerequisite(struct intel_connector *connector) return false; /* If MTL+ make sure gsc is loaded and proxy is setup */ - if (intel_hdcp_gsc_cs_required(i915)) { - if (!intel_hdcp_gsc_check_status(i915)) + if (intel_hdcp_gsc_cs_required(display)) { + if (!intel_hdcp_gsc_check_status(display)) return false; } /* MEI/GSC interface is solid depending on which is used */ - mutex_lock(&i915->display.hdcp.hdcp_mutex); - if (!i915->display.hdcp.comp_added || !i915->display.hdcp.arbiter) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_lock(&display->hdcp.hdcp_mutex); + if (!display->hdcp.comp_added || !display->hdcp.arbiter) { + mutex_unlock(&display->hdcp.hdcp_mutex); return false; } - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return true; } @@ -288,19 +288,19 @@ void intel_hdcp_get_remote_capability(struct intel_connector *connector, *hdcp2_capable = false; } -static bool intel_hdcp_in_use(struct drm_i915_private *i915, +static bool intel_hdcp_in_use(struct intel_display *display, enum transcoder cpu_transcoder, enum port port) { - return intel_de_read(i915, - HDCP_STATUS(i915, cpu_transcoder, port)) & + return intel_de_read(display, + HDCP_STATUS(display, cpu_transcoder, port)) & HDCP_STATUS_ENC; } -static bool intel_hdcp2_in_use(struct drm_i915_private *i915, +static bool intel_hdcp2_in_use(struct intel_display *display, enum transcoder cpu_transcoder, enum port port) { - return intel_de_read(i915, - HDCP2_STATUS(i915, cpu_transcoder, port)) & + return intel_de_read(display, + HDCP2_STATUS(display, cpu_transcoder, port)) & LINK_ENCRYPTION_STATUS; } @@ -325,8 +325,9 @@ static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *dig_port, return 0; } -static bool hdcp_key_loadable(struct drm_i915_private *i915) +static bool hdcp_key_loadable(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); enum i915_power_well_id id; intel_wakeref_t wakeref; bool enabled = false; @@ -353,19 +354,20 @@ static bool hdcp_key_loadable(struct drm_i915_private *i915) return enabled; } -static void intel_hdcp_clear_keys(struct drm_i915_private *i915) +static void intel_hdcp_clear_keys(struct intel_display *display) { - intel_de_write(i915, HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER); - intel_de_write(i915, HDCP_KEY_STATUS, + intel_de_write(display, HDCP_KEY_CONF, HDCP_CLEAR_KEYS_TRIGGER); + intel_de_write(display, HDCP_KEY_STATUS, HDCP_KEY_LOAD_DONE | HDCP_KEY_LOAD_STATUS | HDCP_FUSE_IN_PROGRESS | HDCP_FUSE_ERROR | HDCP_FUSE_DONE); } -static int intel_hdcp_load_keys(struct drm_i915_private *i915) +static int intel_hdcp_load_keys(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); int ret; u32 val; - val = intel_de_read(i915, HDCP_KEY_STATUS); + val = intel_de_read(display, HDCP_KEY_STATUS); if ((val & HDCP_KEY_LOAD_DONE) && (val & HDCP_KEY_LOAD_STATUS)) return 0; @@ -374,7 +376,7 @@ static int intel_hdcp_load_keys(struct drm_i915_private *i915) * out of reset. So if Key is not already loaded, its an error state. */ if (IS_HASWELL(i915) || IS_BROADWELL(i915)) - if (!(intel_de_read(i915, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE)) + if (!(intel_de_read(display, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE)) return -ENXIO; /* @@ -385,20 +387,20 @@ static int intel_hdcp_load_keys(struct drm_i915_private *i915) * process from other platforms. These platforms use the GT Driver * Mailbox interface. */ - if (DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915)) { + if (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)) { ret = snb_pcode_write(&i915->uncore, SKL_PCODE_LOAD_HDCP_KEYS, 1); if (ret) { - drm_err(&i915->drm, + drm_err(display->drm, "Failed to initiate HDCP key load (%d)\n", ret); return ret; } } else { - intel_de_write(i915, HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER); + intel_de_write(display, HDCP_KEY_CONF, HDCP_KEY_LOAD_TRIGGER); } /* Wait for the keys to load (500us) */ - ret = intel_de_wait_custom(i915, HDCP_KEY_STATUS, + ret = intel_de_wait_custom(display, HDCP_KEY_STATUS, HDCP_KEY_LOAD_DONE, HDCP_KEY_LOAD_DONE, 10, 1, &val); if (ret) @@ -407,27 +409,27 @@ static int intel_hdcp_load_keys(struct drm_i915_private *i915) return -ENXIO; /* Send Aksv over to PCH display for use in authentication */ - intel_de_write(i915, HDCP_KEY_CONF, HDCP_AKSV_SEND_TRIGGER); + intel_de_write(display, HDCP_KEY_CONF, HDCP_AKSV_SEND_TRIGGER); return 0; } /* Returns updated SHA-1 index */ -static int intel_write_sha_text(struct drm_i915_private *i915, u32 sha_text) +static int intel_write_sha_text(struct intel_display *display, u32 sha_text) { - intel_de_write(i915, HDCP_SHA_TEXT, sha_text); - if (intel_de_wait_for_set(i915, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) { - drm_err(&i915->drm, "Timed out waiting for SHA1 ready\n"); + intel_de_write(display, HDCP_SHA_TEXT, sha_text); + if (intel_de_wait_for_set(display, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) { + drm_err(display->drm, "Timed out waiting for SHA1 ready\n"); return -ETIMEDOUT; } return 0; } static -u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915, +u32 intel_hdcp_get_repeater_ctl(struct intel_display *display, enum transcoder cpu_transcoder, enum port port) { - if (DISPLAY_VER(i915) >= 12) { + if (DISPLAY_VER(display) >= 12) { switch (cpu_transcoder) { case TRANSCODER_A: return HDCP_TRANSA_REP_PRESENT | @@ -442,7 +444,7 @@ u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915, return HDCP_TRANSD_REP_PRESENT | HDCP_TRANSD_SHA1_M0; default: - drm_err(&i915->drm, "Unknown transcoder %d\n", + drm_err(display->drm, "Unknown transcoder %d\n", cpu_transcoder); return 0; } @@ -460,7 +462,7 @@ u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *i915, case PORT_E: return HDCP_DDIE_REP_PRESENT | HDCP_DDIE_SHA1_M0; default: - drm_err(&i915->drm, "Unknown port %d\n", port); + drm_err(display->drm, "Unknown port %d\n", port); return 0; } } @@ -470,8 +472,8 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, const struct intel_hdcp_shim *shim, u8 *ksv_fifo, u8 num_downstream, u8 *bstatus) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder; enum port port = dig_port->base.port; u32 vprime, sha_text, sha_leftovers, rep_ctl; @@ -482,7 +484,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, ret = shim->read_v_prime_part(dig_port, i, &vprime); if (ret) return ret; - intel_de_write(i915, HDCP_SHA_V_PRIME(i), vprime); + intel_de_write(display, HDCP_SHA_V_PRIME(i), vprime); } /* @@ -498,8 +500,8 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, sha_idx = 0; sha_text = 0; sha_leftovers = 0; - rep_ctl = intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, port); - intel_de_write(i915, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); + rep_ctl = intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port); + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); for (i = 0; i < num_downstream; i++) { unsigned int sha_empty; u8 *ksv = &ksv_fifo[i * DRM_HDCP_KSV_LEN]; @@ -511,14 +513,14 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, sha_text |= ksv[j] << off; } - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; /* Programming guide writes this every 64 bytes */ sha_idx += sizeof(sha_text); if (!(sha_idx % 64)) - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); /* Store the leftover bytes from the ksv in sha_text */ @@ -535,7 +537,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, if (sizeof(sha_text) > sha_leftovers) continue; - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; sha_leftovers = 0; @@ -551,73 +553,73 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, */ if (sha_leftovers == 0) { /* Write 16 bits of text, 16 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_16); - ret = intel_write_sha_text(i915, + ret = intel_write_sha_text(display, bstatus[0] << 8 | bstatus[1]); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 32 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_0); - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 16 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_16); - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); } else if (sha_leftovers == 1) { /* Write 24 bits of text, 8 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_24); sha_text |= bstatus[0] << 16 | bstatus[1] << 8; /* Only 24-bits of data, must be in the LSB */ sha_text = (sha_text & 0xffffff00) >> 8; - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 32 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_0); - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 24 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8); - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); } else if (sha_leftovers == 2) { /* Write 32 bits of text */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); sha_text |= bstatus[0] << 8 | bstatus[1]; - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 64 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_0); for (i = 0; i < 2; i++) { - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); @@ -627,56 +629,56 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, * Terminate the SHA-1 stream by hand. For the other leftover * cases this is appended by the hardware. */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); sha_text = DRM_HDCP_SHA1_TERMINATOR << 24; - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; sha_idx += sizeof(sha_text); } else if (sha_leftovers == 3) { /* Write 32 bits of text (filled from LSB) */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); sha_text |= bstatus[0]; - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 8 bits of text (filled from LSB), 24 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8); - ret = intel_write_sha_text(i915, bstatus[1]); + ret = intel_write_sha_text(display, bstatus[1]); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 32 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_0); - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); /* Write 8 bits of M0 */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_24); - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); } else { - drm_dbg_kms(&i915->drm, "Invalid number of leftovers %d\n", + drm_dbg_kms(display->drm, "Invalid number of leftovers %d\n", sha_leftovers); return -EINVAL; } - intel_de_write(i915, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); /* Fill up to 64-4 bytes with zeros (leave the last write for length) */ while ((sha_idx % 64) < (64 - sizeof(sha_text))) { - ret = intel_write_sha_text(i915, 0); + ret = intel_write_sha_text(display, 0); if (ret < 0) return ret; sha_idx += sizeof(sha_text); @@ -688,20 +690,20 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, * - 10 bytes for BINFO/BSTATUS(2), M0(8) */ sha_text = (num_downstream * 5 + 10) * 8; - ret = intel_write_sha_text(i915, sha_text); + ret = intel_write_sha_text(display, sha_text); if (ret < 0) return ret; /* Tell the HW we're done with the hash and wait for it to ACK */ - intel_de_write(i915, HDCP_REP_CTL, + intel_de_write(display, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_COMPLETE_HASH); - if (intel_de_wait_for_set(i915, HDCP_REP_CTL, + if (intel_de_wait_for_set(display, HDCP_REP_CTL, HDCP_SHA1_COMPLETE, 1)) { - drm_err(&i915->drm, "Timed out waiting for SHA1 complete\n"); + drm_err(display->drm, "Timed out waiting for SHA1 complete\n"); return -ETIMEDOUT; } - if (!(intel_de_read(i915, HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) { - drm_dbg_kms(&i915->drm, "SHA-1 mismatch, HDCP failed\n"); + if (!(intel_de_read(display, HDCP_REP_CTL) & HDCP_SHA1_V_MATCH)) { + drm_dbg_kms(display->drm, "SHA-1 mismatch, HDCP failed\n"); return -ENXIO; } @@ -712,15 +714,15 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, static int intel_hdcp_auth_downstream(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct intel_hdcp_shim *shim = connector->hdcp.shim; u8 bstatus[2], num_downstream, *ksv_fifo; int ret, i, tries = 3; ret = intel_hdcp_poll_ksv_fifo(dig_port, shim); if (ret) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "KSV list failed to become ready (%d)\n", ret); return ret; } @@ -731,7 +733,7 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) || DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) { - drm_dbg_kms(&i915->drm, "Max Topology Limit Exceeded\n"); + drm_dbg_kms(display->drm, "Max Topology Limit Exceeded\n"); return -EPERM; } @@ -744,14 +746,14 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) */ num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]); if (num_downstream == 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Repeater with zero downstream devices\n"); return -EINVAL; } ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL); if (!ksv_fifo) { - drm_dbg_kms(&i915->drm, "Out of mem: ksv_fifo\n"); + drm_dbg_kms(display->drm, "Out of mem: ksv_fifo\n"); return -ENOMEM; } @@ -759,9 +761,9 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) if (ret) goto err; - if (drm_hdcp_check_ksvs_revoked(&i915->drm, ksv_fifo, + if (drm_hdcp_check_ksvs_revoked(display->drm, ksv_fifo, num_downstream) > 0) { - drm_err(&i915->drm, "Revoked Ksv(s) in ksv_fifo\n"); + drm_err(display->drm, "Revoked Ksv(s) in ksv_fifo\n"); ret = -EPERM; goto err; } @@ -779,12 +781,12 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) } if (i == tries) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "V Prime validation failed.(%d)\n", ret); goto err; } - drm_dbg_kms(&i915->drm, "HDCP is enabled (%d downstream devices)\n", + drm_dbg_kms(display->drm, "HDCP is enabled (%d downstream devices)\n", num_downstream); ret = 0; err: @@ -795,8 +797,8 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) /* Implements Part 1 of the HDCP authorization procedure */ static int intel_hdcp_auth(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; const struct intel_hdcp_shim *shim = hdcp->shim; enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder; @@ -828,7 +830,7 @@ static int intel_hdcp_auth(struct intel_connector *connector) if (ret) return ret; if (!hdcp_capable) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Panel is not HDCP capable\n"); return -EINVAL; } @@ -836,24 +838,24 @@ static int intel_hdcp_auth(struct intel_connector *connector) /* Initialize An with 2 random values and acquire it */ for (i = 0; i < 2; i++) - intel_de_write(i915, - HDCP_ANINIT(i915, cpu_transcoder, port), + intel_de_write(display, + HDCP_ANINIT(display, cpu_transcoder, port), get_random_u32()); - intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port), + intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port), HDCP_CONF_CAPTURE_AN); /* Wait for An to be acquired */ - if (intel_de_wait_for_set(i915, - HDCP_STATUS(i915, cpu_transcoder, port), + if (intel_de_wait_for_set(display, + HDCP_STATUS(display, cpu_transcoder, port), HDCP_STATUS_AN_READY, 1)) { - drm_err(&i915->drm, "Timed out waiting for An\n"); + drm_err(display->drm, "Timed out waiting for An\n"); return -ETIMEDOUT; } - an.reg[0] = intel_de_read(i915, - HDCP_ANLO(i915, cpu_transcoder, port)); - an.reg[1] = intel_de_read(i915, - HDCP_ANHI(i915, cpu_transcoder, port)); + an.reg[0] = intel_de_read(display, + HDCP_ANLO(display, cpu_transcoder, port)); + an.reg[1] = intel_de_read(display, + HDCP_ANHI(display, cpu_transcoder, port)); ret = shim->write_an_aksv(dig_port, an.shim); if (ret) return ret; @@ -866,34 +868,34 @@ static int intel_hdcp_auth(struct intel_connector *connector) if (ret < 0) return ret; - if (drm_hdcp_check_ksvs_revoked(&i915->drm, bksv.shim, 1) > 0) { - drm_err(&i915->drm, "BKSV is revoked\n"); + if (drm_hdcp_check_ksvs_revoked(display->drm, bksv.shim, 1) > 0) { + drm_err(display->drm, "BKSV is revoked\n"); return -EPERM; } - intel_de_write(i915, HDCP_BKSVLO(i915, cpu_transcoder, port), + intel_de_write(display, HDCP_BKSVLO(display, cpu_transcoder, port), bksv.reg[0]); - intel_de_write(i915, HDCP_BKSVHI(i915, cpu_transcoder, port), + intel_de_write(display, HDCP_BKSVHI(display, cpu_transcoder, port), bksv.reg[1]); ret = shim->repeater_present(dig_port, &repeater_present); if (ret) return ret; if (repeater_present) - intel_de_write(i915, HDCP_REP_CTL, - intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, port)); + intel_de_write(display, HDCP_REP_CTL, + intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port)); ret = shim->toggle_signalling(dig_port, cpu_transcoder, true); if (ret) return ret; - intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port), + intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port), HDCP_CONF_AUTH_AND_ENC); /* Wait for R0 ready */ - if (wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) & + if (wait_for(intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) & (HDCP_STATUS_R0_READY | HDCP_STATUS_ENC), 1)) { - drm_err(&i915->drm, "Timed out waiting for R0 ready\n"); + drm_err(display->drm, "Timed out waiting for R0 ready\n"); return -ETIMEDOUT; } @@ -919,30 +921,30 @@ static int intel_hdcp_auth(struct intel_connector *connector) ret = shim->read_ri_prime(dig_port, ri.shim); if (ret) return ret; - intel_de_write(i915, - HDCP_RPRIME(i915, cpu_transcoder, port), + intel_de_write(display, + HDCP_RPRIME(display, cpu_transcoder, port), ri.reg); /* Wait for Ri prime match */ - if (!wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) & + if (!wait_for(intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) & (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) break; } if (i == tries) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Timed out waiting for Ri prime match (%x)\n", - intel_de_read(i915, - HDCP_STATUS(i915, cpu_transcoder, port))); + intel_de_read(display, + HDCP_STATUS(display, cpu_transcoder, port))); return -ETIMEDOUT; } /* Wait for encryption confirmation */ - if (intel_de_wait_for_set(i915, - HDCP_STATUS(i915, cpu_transcoder, port), + if (intel_de_wait_for_set(display, + HDCP_STATUS(display, cpu_transcoder, port), HDCP_STATUS_ENC, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { - drm_err(&i915->drm, "Timed out waiting for encryption\n"); + drm_err(display->drm, "Timed out waiting for encryption\n"); return -ETIMEDOUT; } @@ -950,42 +952,42 @@ static int intel_hdcp_auth(struct intel_connector *connector) if (shim->stream_encryption) { ret = shim->stream_encryption(connector, true); if (ret) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 1.4 stream enc\n", connector->base.base.id, connector->base.name); return ret; } - drm_dbg_kms(&i915->drm, "HDCP 1.4 transcoder: %s stream encrypted\n", + drm_dbg_kms(display->drm, "HDCP 1.4 transcoder: %s stream encrypted\n", transcoder_name(hdcp->stream_transcoder)); } if (repeater_present) return intel_hdcp_auth_downstream(connector); - drm_dbg_kms(&i915->drm, "HDCP is enabled (no repeater present)\n"); + drm_dbg_kms(display->drm, "HDCP is enabled (no repeater present)\n"); return 0; } static int _intel_hdcp_disable(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; enum port port = dig_port->base.port; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; u32 repeater_ctl; int ret; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP is being disabled...\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP is being disabled...\n", connector->base.base.id, connector->base.name); if (hdcp->shim->stream_encryption) { ret = hdcp->shim->stream_encryption(connector, false); if (ret) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 1.4 stream enc\n", connector->base.base.id, connector->base.name); return ret; } - drm_dbg_kms(&i915->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n", + drm_dbg_kms(display->drm, "HDCP 1.4 transcoder: %s stream encryption disabled\n", transcoder_name(hdcp->stream_transcoder)); /* * If there are other connectors on this port using HDCP, @@ -997,51 +999,51 @@ static int _intel_hdcp_disable(struct intel_connector *connector) } hdcp->hdcp_encrypted = false; - intel_de_write(i915, HDCP_CONF(i915, cpu_transcoder, port), 0); - if (intel_de_wait_for_clear(i915, - HDCP_STATUS(i915, cpu_transcoder, port), + intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port), 0); + if (intel_de_wait_for_clear(display, + HDCP_STATUS(display, cpu_transcoder, port), ~0, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { - drm_err(&i915->drm, + drm_err(display->drm, "Failed to disable HDCP, timeout clearing status\n"); return -ETIMEDOUT; } - repeater_ctl = intel_hdcp_get_repeater_ctl(i915, cpu_transcoder, + repeater_ctl = intel_hdcp_get_repeater_ctl(display, cpu_transcoder, port); - intel_de_rmw(i915, HDCP_REP_CTL, repeater_ctl, 0); + intel_de_rmw(display, HDCP_REP_CTL, repeater_ctl, 0); ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder, false); if (ret) { - drm_err(&i915->drm, "Failed to disable HDCP signalling\n"); + drm_err(display->drm, "Failed to disable HDCP signalling\n"); return ret; } - drm_dbg_kms(&i915->drm, "HDCP is disabled\n"); + drm_dbg_kms(display->drm, "HDCP is disabled\n"); return 0; } static int intel_hdcp1_enable(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_hdcp *hdcp = &connector->hdcp; int i, ret, tries = 3; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP is being enabled...\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP is being enabled...\n", connector->base.base.id, connector->base.name); - if (!hdcp_key_loadable(i915)) { - drm_err(&i915->drm, "HDCP key Load is not possible\n"); + if (!hdcp_key_loadable(display)) { + drm_err(display->drm, "HDCP key Load is not possible\n"); return -ENXIO; } for (i = 0; i < KEY_LOAD_TRIES; i++) { - ret = intel_hdcp_load_keys(i915); + ret = intel_hdcp_load_keys(display); if (!ret) break; - intel_hdcp_clear_keys(i915); + intel_hdcp_clear_keys(display); } if (ret) { - drm_err(&i915->drm, "Could not load HDCP keys, (%d)\n", + drm_err(display->drm, "Could not load HDCP keys, (%d)\n", ret); return ret; } @@ -1054,13 +1056,13 @@ static int intel_hdcp1_enable(struct intel_connector *connector) return 0; } - drm_dbg_kms(&i915->drm, "HDCP Auth failure (%d)\n", ret); + drm_dbg_kms(display->drm, "HDCP Auth failure (%d)\n", ret); /* Ensuring HDCP encryption and signalling are stopped. */ _intel_hdcp_disable(connector); } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "HDCP authentication failed (%d tries/%d)\n", tries, ret); return ret; } @@ -1073,20 +1075,20 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp) static void intel_hdcp_update_value(struct intel_connector *connector, u64 value, bool update_property) { - struct drm_device *dev = connector->base.dev; + struct intel_display *display = to_intel_display(connector); + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; - struct drm_i915_private *i915 = to_i915(connector->base.dev); - drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex)); + drm_WARN_ON(display->drm, !mutex_is_locked(&hdcp->mutex)); if (hdcp->value == value) return; - drm_WARN_ON(dev, !mutex_is_locked(&dig_port->hdcp_mutex)); + drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp_mutex)); if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) { - if (!drm_WARN_ON(dev, dig_port->num_hdcp_streams == 0)) + if (!drm_WARN_ON(display->drm, dig_port->num_hdcp_streams == 0)) dig_port->num_hdcp_streams--; } else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) { dig_port->num_hdcp_streams++; @@ -1102,8 +1104,8 @@ static void intel_hdcp_update_value(struct intel_connector *connector, /* Implements Part 3 of the HDCP authorization procedure */ static int intel_hdcp_check_link(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; enum port port = dig_port->base.port; enum transcoder cpu_transcoder; @@ -1121,12 +1123,12 @@ static int intel_hdcp_check_link(struct intel_connector *connector) goto out; } - if (drm_WARN_ON(&i915->drm, - !intel_hdcp_in_use(i915, cpu_transcoder, port))) { - drm_err(&i915->drm, + if (drm_WARN_ON(display->drm, + !intel_hdcp_in_use(display, cpu_transcoder, port))) { + drm_err(display->drm, "[CONNECTOR:%d:%s] HDCP link stopped encryption,%x\n", connector->base.base.id, connector->base.name, - intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port))); + intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port))); ret = -ENXIO; intel_hdcp_update_value(connector, DRM_MODE_CONTENT_PROTECTION_DESIRED, @@ -1142,13 +1144,13 @@ static int intel_hdcp_check_link(struct intel_connector *connector) goto out; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP link failed, retrying authentication\n", connector->base.base.id, connector->base.name); ret = _intel_hdcp_disable(connector); if (ret) { - drm_err(&i915->drm, "Failed to disable hdcp (%d)\n", ret); + drm_err(display->drm, "Failed to disable hdcp (%d)\n", ret); intel_hdcp_update_value(connector, DRM_MODE_CONTENT_PROTECTION_DESIRED, true); @@ -1169,9 +1171,9 @@ static void intel_hdcp_prop_work(struct work_struct *work) struct intel_hdcp *hdcp = container_of(work, struct intel_hdcp, prop_work); struct intel_connector *connector = intel_hdcp_to_connector(hdcp); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); - drm_modeset_lock(&i915->drm.mode_config.connection_mutex, NULL); + drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); mutex_lock(&hdcp->mutex); /* @@ -1184,7 +1186,7 @@ static void intel_hdcp_prop_work(struct work_struct *work) hdcp->value); mutex_unlock(&hdcp->mutex); - drm_modeset_unlock(&i915->drm.mode_config.connection_mutex); + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); drm_connector_put(&connector->base); } @@ -1199,25 +1201,25 @@ static int hdcp2_prepare_ake_init(struct intel_connector *connector, struct hdcp2_ake_init *ake_data) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->initiate_hdcp2_session(arbiter->hdcp_dev, data, ake_data); if (ret) - drm_dbg_kms(&i915->drm, "Prepare_ake_init failed. %d\n", + drm_dbg_kms(display->drm, "Prepare_ake_init failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1229,17 +1231,17 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector, struct hdcp2_ake_no_stored_km *ek_pub_km, size_t *msg_sz) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } @@ -1247,9 +1249,9 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector, rx_cert, paired, ek_pub_km, msg_sz); if (ret < 0) - drm_dbg_kms(&i915->drm, "Verify rx_cert failed. %d\n", + drm_dbg_kms(display->drm, "Verify rx_cert failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1257,24 +1259,24 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector, static int hdcp2_verify_hprime(struct intel_connector *connector, struct hdcp2_ake_send_hprime *rx_hprime) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->verify_hprime(arbiter->hdcp_dev, data, rx_hprime); if (ret < 0) - drm_dbg_kms(&i915->drm, "Verify hprime failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + drm_dbg_kms(display->drm, "Verify hprime failed. %d\n", ret); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1283,25 +1285,25 @@ static int hdcp2_store_pairing_info(struct intel_connector *connector, struct hdcp2_ake_send_pairing_info *pairing_info) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->store_pairing_info(arbiter->hdcp_dev, data, pairing_info); if (ret < 0) - drm_dbg_kms(&i915->drm, "Store pairing info failed. %d\n", + drm_dbg_kms(display->drm, "Store pairing info failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1310,25 +1312,25 @@ static int hdcp2_prepare_lc_init(struct intel_connector *connector, struct hdcp2_lc_init *lc_init) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->initiate_locality_check(arbiter->hdcp_dev, data, lc_init); if (ret < 0) - drm_dbg_kms(&i915->drm, "Prepare lc_init failed. %d\n", + drm_dbg_kms(display->drm, "Prepare lc_init failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1337,25 +1339,25 @@ static int hdcp2_verify_lprime(struct intel_connector *connector, struct hdcp2_lc_send_lprime *rx_lprime) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->verify_lprime(arbiter->hdcp_dev, data, rx_lprime); if (ret < 0) - drm_dbg_kms(&i915->drm, "Verify L_Prime failed. %d\n", + drm_dbg_kms(display->drm, "Verify L_Prime failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1363,25 +1365,25 @@ hdcp2_verify_lprime(struct intel_connector *connector, static int hdcp2_prepare_skey(struct intel_connector *connector, struct hdcp2_ske_send_eks *ske_data) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->get_session_key(arbiter->hdcp_dev, data, ske_data); if (ret < 0) - drm_dbg_kms(&i915->drm, "Get session key failed. %d\n", + drm_dbg_kms(display->drm, "Get session key failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1392,17 +1394,17 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector, *rep_topology, struct hdcp2_rep_send_ack *rep_send_ack) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } @@ -1411,9 +1413,9 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector, rep_topology, rep_send_ack); if (ret < 0) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Verify rep topology failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1422,71 +1424,71 @@ static int hdcp2_verify_mprime(struct intel_connector *connector, struct hdcp2_rep_stream_ready *stream_ready) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->verify_mprime(arbiter->hdcp_dev, data, stream_ready); if (ret < 0) - drm_dbg_kms(&i915->drm, "Verify mprime failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + drm_dbg_kms(display->drm, "Verify mprime failed. %d\n", ret); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } static int hdcp2_authenticate_port(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->enable_hdcp_authentication(arbiter->hdcp_dev, data); if (ret < 0) - drm_dbg_kms(&i915->drm, "Enable hdcp auth failed. %d\n", + drm_dbg_kms(display->drm, "Enable hdcp auth failed. %d\n", ret); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } static int hdcp2_close_session(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct i915_hdcp_arbiter *arbiter; int ret; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - arbiter = i915->display.hdcp.arbiter; + mutex_lock(&display->hdcp.hdcp_mutex); + arbiter = display->hdcp.arbiter; if (!arbiter || !arbiter->ops) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return -EINVAL; } ret = arbiter->ops->close_hdcp_session(arbiter->hdcp_dev, &dig_port->hdcp_port_data); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } @@ -1499,7 +1501,7 @@ static int hdcp2_deauthenticate_port(struct intel_connector *connector) /* Authentication flow starts from here */ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_hdcp *hdcp = &connector->hdcp; union { struct hdcp2_ake_init ake_init; @@ -1531,16 +1533,16 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) return ret; if (msgs.send_cert.rx_caps[0] != HDCP_2_2_RX_CAPS_VERSION_VAL) { - drm_dbg_kms(&i915->drm, "cert.rx_caps dont claim HDCP2.2\n"); + drm_dbg_kms(display->drm, "cert.rx_caps dont claim HDCP2.2\n"); return -EINVAL; } hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]); - if (drm_hdcp_check_ksvs_revoked(&i915->drm, + if (drm_hdcp_check_ksvs_revoked(display->drm, msgs.send_cert.cert_rx.receiver_id, 1) > 0) { - drm_err(&i915->drm, "Receiver ID is revoked\n"); + drm_err(display->drm, "Receiver ID is revoked\n"); return -EPERM; } @@ -1691,8 +1693,8 @@ int _hdcp2_propagate_stream_management_info(struct intel_connector *connector) static int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; union { struct hdcp2_rep_send_receiverid_list recvid_list; @@ -1712,7 +1714,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) if (HDCP_2_2_MAX_CASCADE_EXCEEDED(rx_info[1]) || HDCP_2_2_MAX_DEVS_EXCEEDED(rx_info[1])) { - drm_dbg_kms(&i915->drm, "Topology Max Size Exceeded\n"); + drm_dbg_kms(display->drm, "Topology Max Size Exceeded\n"); return -EINVAL; } @@ -1725,7 +1727,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) !HDCP_2_2_HDCP_2_0_REP_CONNECTED(rx_info[1]); if (!dig_port->hdcp_mst_type1_capable && hdcp->content_type) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "HDCP1.x or 2.0 Legacy Device Downstream\n"); return -EINVAL; } @@ -1735,23 +1737,23 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v); if (!hdcp->hdcp2_encrypted && seq_num_v) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Non zero Seq_num_v at first RecvId_List msg\n"); return -EINVAL; } if (seq_num_v < hdcp->seq_num_v) { /* Roll over of the seq_num_v from repeater. Reauthenticate. */ - drm_dbg_kms(&i915->drm, "Seq_num_v roll over.\n"); + drm_dbg_kms(display->drm, "Seq_num_v roll over.\n"); return -EINVAL; } device_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 | HDCP_2_2_DEV_COUNT_LO(rx_info[1])); - if (drm_hdcp_check_ksvs_revoked(&i915->drm, + if (drm_hdcp_check_ksvs_revoked(display->drm, msgs.recvid_list.receiver_ids, device_cnt) > 0) { - drm_err(&i915->drm, "Revoked receiver ID(s) is in list\n"); + drm_err(display->drm, "Revoked receiver ID(s) is in list\n"); return -EPERM; } @@ -1772,27 +1774,27 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) static int hdcp2_authenticate_sink(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_hdcp *hdcp = &connector->hdcp; const struct intel_hdcp_shim *shim = hdcp->shim; int ret; ret = hdcp2_authentication_key_exchange(connector); if (ret < 0) { - drm_dbg_kms(&i915->drm, "AKE Failed. Err : %d\n", ret); + drm_dbg_kms(display->drm, "AKE Failed. Err : %d\n", ret); return ret; } ret = hdcp2_locality_check(connector); if (ret < 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Locality Check failed. Err : %d\n", ret); return ret; } ret = hdcp2_session_key_exchange(connector); if (ret < 0) { - drm_dbg_kms(&i915->drm, "SKE Failed. Err : %d\n", ret); + drm_dbg_kms(display->drm, "SKE Failed. Err : %d\n", ret); return ret; } @@ -1807,7 +1809,7 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector) if (hdcp->is_repeater) { ret = hdcp2_authenticate_repeater_topology(connector); if (ret < 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Repeater Auth Failed. Err: %d\n", ret); return ret; } @@ -1818,17 +1820,17 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector) static int hdcp2_enable_stream_encryption(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct intel_hdcp *hdcp = &connector->hdcp; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; enum port port = dig_port->base.port; int ret = 0; - if (!(intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) & + if (!(intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) & LINK_ENCRYPTION_STATUS)) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] HDCP 2.2 Link is not encrypted\n", connector->base.base.id, connector->base.name); ret = -EPERM; goto link_recover; @@ -1837,11 +1839,11 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector) if (hdcp->shim->stream_2_2_encryption) { ret = hdcp->shim->stream_2_2_encryption(connector, true); if (ret) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to enable HDCP 2.2 stream enc\n", connector->base.base.id, connector->base.name); return ret; } - drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encrypted\n", + drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encrypted\n", transcoder_name(hdcp->stream_transcoder)); } @@ -1849,7 +1851,7 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector) link_recover: if (hdcp2_deauthenticate_port(connector) < 0) - drm_dbg_kms(&i915->drm, "Port deauth failed.\n"); + drm_dbg_kms(display->drm, "Port deauth failed.\n"); dig_port->hdcp_auth_status = false; data->k = 0; @@ -1859,35 +1861,35 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector) static int hdcp2_enable_encryption(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; enum port port = dig_port->base.port; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; int ret; - drm_WARN_ON(&i915->drm, - intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) & + drm_WARN_ON(display->drm, + intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) & LINK_ENCRYPTION_STATUS); if (hdcp->shim->toggle_signalling) { ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder, true); if (ret) { - drm_err(&i915->drm, + drm_err(display->drm, "Failed to enable HDCP signalling. %d\n", ret); return ret; } } - if (intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) & + if (intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) & LINK_AUTH_STATUS) /* Link is Authenticated. Now set for Encryption */ - intel_de_rmw(i915, HDCP2_CTL(i915, cpu_transcoder, port), + intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port), 0, CTL_LINK_ENCRYPTION_REQ); - ret = intel_de_wait_for_set(i915, - HDCP2_STATUS(i915, cpu_transcoder, + ret = intel_de_wait_for_set(display, + HDCP2_STATUS(display, cpu_transcoder, port), LINK_ENCRYPTION_STATUS, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); @@ -1898,32 +1900,33 @@ static int hdcp2_enable_encryption(struct intel_connector *connector) static int hdcp2_disable_encryption(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; enum port port = dig_port->base.port; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; int ret; - drm_WARN_ON(&i915->drm, !(intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port)) & - LINK_ENCRYPTION_STATUS)); + drm_WARN_ON(display->drm, + !(intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port)) & + LINK_ENCRYPTION_STATUS)); - intel_de_rmw(i915, HDCP2_CTL(i915, cpu_transcoder, port), + intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port), CTL_LINK_ENCRYPTION_REQ, 0); - ret = intel_de_wait_for_clear(i915, - HDCP2_STATUS(i915, cpu_transcoder, + ret = intel_de_wait_for_clear(display, + HDCP2_STATUS(display, cpu_transcoder, port), LINK_ENCRYPTION_STATUS, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); if (ret == -ETIMEDOUT) - drm_dbg_kms(&i915->drm, "Disable Encryption Timedout"); + drm_dbg_kms(display->drm, "Disable Encryption Timedout"); if (hdcp->shim->toggle_signalling) { ret = hdcp->shim->toggle_signalling(dig_port, cpu_transcoder, false); if (ret) { - drm_err(&i915->drm, + drm_err(display->drm, "Failed to disable HDCP signalling. %d\n", ret); return ret; @@ -1936,7 +1939,7 @@ static int hdcp2_disable_encryption(struct intel_connector *connector) static int hdcp2_propagate_stream_management_info(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); int i, tries = 3, ret; if (!connector->hdcp.is_repeater) @@ -1949,12 +1952,12 @@ hdcp2_propagate_stream_management_info(struct intel_connector *connector) /* Lets restart the auth incase of seq_num_m roll over */ if (connector->hdcp.seq_num_m > HDCP_2_2_SEQ_NUM_MAX) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "seq_num_m roll over.(%d)\n", ret); break; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "HDCP2 stream management %d of %d Failed.(%d)\n", i + 1, tries, ret); } @@ -1965,8 +1968,8 @@ hdcp2_propagate_stream_management_info(struct intel_connector *connector) static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); int ret = 0, i, tries = 3; for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) { @@ -1974,7 +1977,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, if (!ret) { ret = intel_hdcp_prepare_streams(state, connector); if (ret) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Prepare stream failed.(%d)\n", ret); break; @@ -1982,7 +1985,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, ret = hdcp2_propagate_stream_management_info(connector); if (ret) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Stream management failed.(%d)\n", ret); break; @@ -1991,15 +1994,15 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, ret = hdcp2_authenticate_port(connector); if (!ret) break; - drm_dbg_kms(&i915->drm, "HDCP2 port auth failed.(%d)\n", + drm_dbg_kms(display->drm, "HDCP2 port auth failed.(%d)\n", ret); } /* Clearing the mei hdcp session */ - drm_dbg_kms(&i915->drm, "HDCP2.2 Auth %d of %d Failed.(%d)\n", + drm_dbg_kms(display->drm, "HDCP2.2 Auth %d of %d Failed.(%d)\n", i + 1, tries, ret); if (hdcp2_deauthenticate_port(connector) < 0) - drm_dbg_kms(&i915->drm, "Port deauth failed.\n"); + drm_dbg_kms(display->drm, "Port deauth failed.\n"); } if (!ret && !dig_port->hdcp_auth_status) { @@ -2010,10 +2013,10 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, msleep(HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN); ret = hdcp2_enable_encryption(connector); if (ret < 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Encryption Enable Failed.(%d)\n", ret); if (hdcp2_deauthenticate_port(connector) < 0) - drm_dbg_kms(&i915->drm, "Port deauth failed.\n"); + drm_dbg_kms(display->drm, "Port deauth failed.\n"); } } @@ -2026,11 +2029,11 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, static int _intel_hdcp2_enable(struct intel_atomic_state *state, struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_hdcp *hdcp = &connector->hdcp; int ret; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being enabled. Type: %d\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being enabled. Type: %d\n", connector->base.base.id, connector->base.name, hdcp->content_type); @@ -2038,12 +2041,12 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state, ret = hdcp2_authenticate_and_encrypt(state, connector); if (ret) { - drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n", + drm_dbg_kms(display->drm, "HDCP2 Type%d Enabling Failed. (%d)\n", hdcp->content_type, ret); return ret; } - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is enabled. Type %d\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is enabled. Type %d\n", connector->base.base.id, connector->base.name, hdcp->content_type); @@ -2054,23 +2057,23 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state, static int _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct intel_hdcp *hdcp = &connector->hdcp; int ret; - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being Disabled\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 is being Disabled\n", connector->base.base.id, connector->base.name); if (hdcp->shim->stream_2_2_encryption) { ret = hdcp->shim->stream_2_2_encryption(connector, false); if (ret) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable HDCP 2.2 stream enc\n", connector->base.base.id, connector->base.name); return ret; } - drm_dbg_kms(&i915->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n", + drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n", transcoder_name(hdcp->stream_transcoder)); if (dig_port->num_hdcp_streams > 0 && !hdcp2_link_recovery) @@ -2080,7 +2083,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery ret = hdcp2_disable_encryption(connector); if (hdcp2_deauthenticate_port(connector) < 0) - drm_dbg_kms(&i915->drm, "Port deauth failed.\n"); + drm_dbg_kms(display->drm, "Port deauth failed.\n"); connector->hdcp.hdcp2_encrypted = false; dig_port->hdcp_auth_status = false; @@ -2092,8 +2095,8 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery /* Implements the Link Integrity Check for HDCP2.2 */ static int intel_hdcp2_check_link(struct intel_connector *connector) { + struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_hdcp *hdcp = &connector->hdcp; enum port port = dig_port->base.port; enum transcoder cpu_transcoder; @@ -2110,11 +2113,11 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) goto out; } - if (drm_WARN_ON(&i915->drm, - !intel_hdcp2_in_use(i915, cpu_transcoder, port))) { - drm_err(&i915->drm, + if (drm_WARN_ON(display->drm, + !intel_hdcp2_in_use(display, cpu_transcoder, port))) { + drm_err(display->drm, "HDCP2.2 link stopped the encryption, %x\n", - intel_de_read(i915, HDCP2_STATUS(i915, cpu_transcoder, port))); + intel_de_read(display, HDCP2_STATUS(display, cpu_transcoder, port))); ret = -ENXIO; _intel_hdcp2_disable(connector, true); intel_hdcp_update_value(connector, @@ -2137,17 +2140,17 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) goto out; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "HDCP2.2 Downstream topology change\n"); } else { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] HDCP2.2 link failed, retrying auth\n", connector->base.base.id, connector->base.name); } ret = _intel_hdcp2_disable(connector, true); if (ret) { - drm_err(&i915->drm, + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to disable hdcp2.2 (%d)\n", connector->base.base.id, connector->base.name, ret); intel_hdcp_update_value(connector, @@ -2169,7 +2172,8 @@ static void intel_hdcp_check_work(struct work_struct *work) struct intel_hdcp, check_work); struct intel_connector *connector = intel_hdcp_to_connector(hdcp); - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); + struct drm_i915_private *i915 = to_i915(display->drm); if (drm_connector_is_unregistered(&connector->base)) return; @@ -2186,13 +2190,12 @@ static int i915_hdcp_component_bind(struct device *drv_kdev, struct device *mei_kdev, void *data) { struct intel_display *display = to_intel_display(drv_kdev); - struct drm_i915_private *i915 = to_i915(display->drm); - drm_dbg(&i915->drm, "I915 HDCP comp bind\n"); - mutex_lock(&i915->display.hdcp.hdcp_mutex); - i915->display.hdcp.arbiter = (struct i915_hdcp_arbiter *)data; - i915->display.hdcp.arbiter->hdcp_dev = mei_kdev; - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + drm_dbg(display->drm, "I915 HDCP comp bind\n"); + mutex_lock(&display->hdcp.hdcp_mutex); + display->hdcp.arbiter = (struct i915_hdcp_arbiter *)data; + display->hdcp.arbiter->hdcp_dev = mei_kdev; + mutex_unlock(&display->hdcp.hdcp_mutex); return 0; } @@ -2201,12 +2204,11 @@ static void i915_hdcp_component_unbind(struct device *drv_kdev, struct device *mei_kdev, void *data) { struct intel_display *display = to_intel_display(drv_kdev); - struct drm_i915_private *i915 = to_i915(display->drm); - drm_dbg(&i915->drm, "I915 HDCP comp unbind\n"); - mutex_lock(&i915->display.hdcp.hdcp_mutex); - i915->display.hdcp.arbiter = NULL; - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + drm_dbg(display->drm, "I915 HDCP comp unbind\n"); + mutex_lock(&display->hdcp.hdcp_mutex); + display->hdcp.arbiter = NULL; + mutex_unlock(&display->hdcp.hdcp_mutex); } static const struct component_ops i915_hdcp_ops = { @@ -2240,11 +2242,11 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, struct intel_digital_port *dig_port, const struct intel_hdcp_shim *shim) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct hdcp_port_data *data = &dig_port->hdcp_port_data; enum port port = dig_port->base.port; - if (DISPLAY_VER(i915) < 12) + if (DISPLAY_VER(display) < 12) data->hdcp_ddi = intel_get_hdcp_ddi_index(port); else /* @@ -2264,11 +2266,11 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, data->protocol = (u8)shim->protocol; if (!data->streams) - data->streams = kcalloc(INTEL_NUM_PIPES(i915), + data->streams = kcalloc(INTEL_NUM_PIPES(display), sizeof(struct hdcp2_streamid_type), GFP_KERNEL); if (!data->streams) { - drm_err(&i915->drm, "Out of Memory\n"); + drm_err(display->drm, "Out of Memory\n"); return -ENOMEM; } @@ -2277,13 +2279,15 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, static bool is_hdcp2_supported(struct drm_i915_private *i915) { - if (intel_hdcp_gsc_cs_required(i915)) + struct intel_display *display = to_intel_display(&i915->drm); + + if (intel_hdcp_gsc_cs_required(display)) return true; if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP)) return false; - return (DISPLAY_VER(i915) >= 10 || + return (DISPLAY_VER(display) >= 10 || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)); @@ -2291,28 +2295,29 @@ static bool is_hdcp2_supported(struct drm_i915_private *i915) void intel_hdcp_component_init(struct drm_i915_private *i915) { + struct intel_display *display = to_intel_display(&i915->drm); int ret; if (!is_hdcp2_supported(i915)) return; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - drm_WARN_ON(&i915->drm, i915->display.hdcp.comp_added); + mutex_lock(&display->hdcp.hdcp_mutex); + drm_WARN_ON(display->drm, display->hdcp.comp_added); - i915->display.hdcp.comp_added = true; - mutex_unlock(&i915->display.hdcp.hdcp_mutex); - if (intel_hdcp_gsc_cs_required(i915)) + display->hdcp.comp_added = true; + mutex_unlock(&display->hdcp.hdcp_mutex); + if (intel_hdcp_gsc_cs_required(display)) ret = intel_hdcp_gsc_init(i915); else - ret = component_add_typed(i915->drm.dev, &i915_hdcp_ops, + ret = component_add_typed(display->drm->dev, &i915_hdcp_ops, I915_COMPONENT_HDCP); if (ret < 0) { - drm_dbg_kms(&i915->drm, "Failed at fw component add(%d)\n", + drm_dbg_kms(display->drm, "Failed at fw component add(%d)\n", ret); - mutex_lock(&i915->display.hdcp.hdcp_mutex); - i915->display.hdcp.comp_added = false; - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_lock(&display->hdcp.hdcp_mutex); + display->hdcp.comp_added = false; + mutex_unlock(&display->hdcp.hdcp_mutex); return; } } @@ -2321,13 +2326,13 @@ static void intel_hdcp2_init(struct intel_connector *connector, struct intel_digital_port *dig_port, const struct intel_hdcp_shim *shim) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_hdcp *hdcp = &connector->hdcp; int ret; ret = initialize_hdcp_port_data(connector, dig_port, shim); if (ret) { - drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n"); + drm_dbg_kms(display->drm, "Mei hdcp data init failed\n"); return; } @@ -2371,7 +2376,8 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); @@ -2383,14 +2389,14 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, return -ENOENT; if (!connector->encoder) { - drm_err(&i915->drm, "[CONNECTOR:%d:%s] encoder is not initialized\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] encoder is not initialized\n", connector->base.base.id, connector->base.name); return -ENODEV; } mutex_lock(&hdcp->mutex); mutex_lock(&dig_port->hdcp_mutex); - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); hdcp->content_type = (u8)conn_state->hdcp_content_type; @@ -2552,19 +2558,21 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, void intel_hdcp_component_fini(struct drm_i915_private *i915) { - mutex_lock(&i915->display.hdcp.hdcp_mutex); - if (!i915->display.hdcp.comp_added) { - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + struct intel_display *display = to_intel_display(&i915->drm); + + mutex_lock(&display->hdcp.hdcp_mutex); + if (!display->hdcp.comp_added) { + mutex_unlock(&display->hdcp.hdcp_mutex); return; } - i915->display.hdcp.comp_added = false; - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + display->hdcp.comp_added = false; + mutex_unlock(&display->hdcp.hdcp_mutex); - if (intel_hdcp_gsc_cs_required(i915)) + if (intel_hdcp_gsc_cs_required(display)) intel_hdcp_gsc_fini(i915); else - component_del(i915->drm.dev, &i915_hdcp_ops); + component_del(display->drm->dev, &i915_hdcp_ops); } void intel_hdcp_cleanup(struct intel_connector *connector) @@ -2654,7 +2662,8 @@ void intel_hdcp_atomic_check(struct drm_connector *connector, void intel_hdcp_handle_cp_irq(struct intel_connector *connector) { struct intel_hdcp *hdcp = &connector->hdcp; - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); + struct drm_i915_private *i915 = to_i915(display->drm); if (!hdcp->shim) return; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c index 16afeb8a3a8d..dc5cc1d54c85 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c @@ -19,18 +19,19 @@ struct intel_hdcp_gsc_message { void *hdcp_cmd_out; }; -bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915) +bool intel_hdcp_gsc_cs_required(struct intel_display *display) { - return DISPLAY_VER(i915) >= 14; + return DISPLAY_VER(display) >= 14; } -bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915) +bool intel_hdcp_gsc_check_status(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_gt *gt = i915->media_gt; struct intel_gsc_uc *gsc = gt ? >->uc.gsc : NULL; if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "GSC components required for HDCP2.2 are not ready\n"); return false; } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h index 5f610df61cc9..b6aabd855478 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h @@ -10,14 +10,15 @@ #include struct drm_i915_private; +struct intel_display; struct intel_hdcp_gsc_message; -bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915); +bool intel_hdcp_gsc_cs_required(struct intel_display *display); ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, size_t msg_in_len, u8 *msg_out, size_t msg_out_len); int intel_hdcp_gsc_init(struct drm_i915_private *i915); void intel_hdcp_gsc_fini(struct drm_i915_private *i915); -bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915); +bool intel_hdcp_gsc_check_status(struct intel_display *display); #endif /* __INTEL_HDCP_GCS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h index ce199d6f6232..2d597f27e931 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h @@ -22,11 +22,12 @@ struct hdcp2_ske_send_eks; struct hdcp2_rep_send_receiverid_list; struct hdcp2_rep_send_ack; struct hdcp2_rep_stream_ready; +struct intel_display; ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, size_t msg_in_len, u8 *msg_out, size_t msg_out_len); -bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915); +bool intel_hdcp_gsc_check_status(struct intel_display *display); int intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, struct hdcp2_ake_init *ake_data); diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c index 6619a40aed15..5badf90b26de 100644 --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c @@ -30,13 +30,14 @@ struct intel_hdcp_gsc_message { #define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header) -bool intel_hdcp_gsc_cs_required(struct xe_device *xe) +bool intel_hdcp_gsc_cs_required(struct intel_display *display) { - return DISPLAY_VER(xe) >= 14; + return DISPLAY_VER(display) >= 14; } -bool intel_hdcp_gsc_check_status(struct xe_device *xe) +bool intel_hdcp_gsc_check_status(struct intel_display *display) { + struct xe_device *xe = to_xe_device(display->drm); struct xe_tile *tile = xe_device_get_root_tile(xe); struct xe_gt *gt = tile->media_gt; struct xe_gsc *gsc = >->uc.gsc; From c8d4ef71397c35f950b58388c27a9c0466eb6d7f Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Wed, 11 Sep 2024 14:35:40 +0530 Subject: [PATCH 042/205] drm/i915/hdcp: Use intel_display in hdcp_gsc Use intel_display structure instead of drm_i915_private wherever possible in hdcp_gsc related files. --v2 -make intel_hdcp_gsc_hdcp2_init accept intel_display [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240911090540.643155-3-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hdcp.c | 4 +- drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 31 ++++++------- drivers/gpu/drm/i915/display/intel_hdcp_gsc.h | 4 +- .../drm/i915/display/intel_hdcp_gsc_message.c | 44 +++++++++---------- drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 37 ++++++++-------- 5 files changed, 61 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index b964af7425cf..2afa92321b08 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2307,7 +2307,7 @@ void intel_hdcp_component_init(struct drm_i915_private *i915) display->hdcp.comp_added = true; mutex_unlock(&display->hdcp.hdcp_mutex); if (intel_hdcp_gsc_cs_required(display)) - ret = intel_hdcp_gsc_init(i915); + ret = intel_hdcp_gsc_init(display); else ret = component_add_typed(display->drm->dev, &i915_hdcp_ops, I915_COMPONENT_HDCP); @@ -2570,7 +2570,7 @@ void intel_hdcp_component_fini(struct drm_i915_private *i915) mutex_unlock(&display->hdcp.hdcp_mutex); if (intel_hdcp_gsc_cs_required(display)) - intel_hdcp_gsc_fini(i915); + intel_hdcp_gsc_fini(display); else component_del(display->drm->dev, &i915_hdcp_ops); } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c index dc5cc1d54c85..55965844d829 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c @@ -107,8 +107,9 @@ static const struct i915_hdcp_ops gsc_hdcp_ops = { .close_hdcp_session = intel_hdcp_gsc_close_session, }; -static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915) +static int intel_hdcp_gsc_hdcp2_init(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hdcp_gsc_message *hdcp_message; int ret; @@ -121,19 +122,19 @@ static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915) * NOTE: No need to lock the comp mutex here as it is already * going to be taken before this function called */ - i915->display.hdcp.hdcp_message = hdcp_message; + display->hdcp.hdcp_message = hdcp_message; ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message); if (ret) - drm_err(&i915->drm, "Could not initialize hdcp_message\n"); + drm_err(display->drm, "Could not initialize hdcp_message\n"); return ret; } -static void intel_hdcp_gsc_free_message(struct drm_i915_private *i915) +static void intel_hdcp_gsc_free_message(struct intel_display *display) { struct intel_hdcp_gsc_message *hdcp_message = - i915->display.hdcp.hdcp_message; + display->hdcp.hdcp_message; hdcp_message->hdcp_cmd_in = NULL; hdcp_message->hdcp_cmd_out = NULL; @@ -141,7 +142,7 @@ static void intel_hdcp_gsc_free_message(struct drm_i915_private *i915) kfree(hdcp_message); } -int intel_hdcp_gsc_init(struct drm_i915_private *i915) +int intel_hdcp_gsc_init(struct intel_display *display) { struct i915_hdcp_arbiter *data; int ret; @@ -150,20 +151,20 @@ int intel_hdcp_gsc_init(struct drm_i915_private *i915) if (!data) return -ENOMEM; - mutex_lock(&i915->display.hdcp.hdcp_mutex); - i915->display.hdcp.arbiter = data; - i915->display.hdcp.arbiter->hdcp_dev = i915->drm.dev; - i915->display.hdcp.arbiter->ops = &gsc_hdcp_ops; - ret = intel_hdcp_gsc_hdcp2_init(i915); - mutex_unlock(&i915->display.hdcp.hdcp_mutex); + mutex_lock(&display->hdcp.hdcp_mutex); + display->hdcp.arbiter = data; + display->hdcp.arbiter->hdcp_dev = display->drm->dev; + display->hdcp.arbiter->ops = &gsc_hdcp_ops; + ret = intel_hdcp_gsc_hdcp2_init(display); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } -void intel_hdcp_gsc_fini(struct drm_i915_private *i915) +void intel_hdcp_gsc_fini(struct intel_display *display) { - intel_hdcp_gsc_free_message(i915); - kfree(i915->display.hdcp.arbiter); + intel_hdcp_gsc_free_message(display); + kfree(display->hdcp.arbiter); } static int intel_gsc_send_sync(struct drm_i915_private *i915, diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h index b6aabd855478..5695a5e4f609 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h @@ -17,8 +17,8 @@ bool intel_hdcp_gsc_cs_required(struct intel_display *display); ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, size_t msg_in_len, u8 *msg_out, size_t msg_out_len); -int intel_hdcp_gsc_init(struct drm_i915_private *i915); -void intel_hdcp_gsc_fini(struct drm_i915_private *i915); +int intel_hdcp_gsc_init(struct intel_display *display); +void intel_hdcp_gsc_fini(struct intel_display *display); bool intel_hdcp_gsc_check_status(struct intel_display *display); #endif /* __INTEL_HDCP_GCS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c index 35bdb532bbb3..129104fa9b16 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c @@ -46,12 +46,12 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, (u8 *)&session_init_out, sizeof(session_init_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", WIRED_INITIATE_HDCP2_SESSION, session_init_out.header.status); return -EIO; @@ -108,12 +108,12 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, (u8 *)&verify_rxcert_out, sizeof(verify_rxcert_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte); return byte; } if (verify_rxcert_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", WIRED_VERIFY_RECEIVER_CERT, verify_rxcert_out.header.status); return -EIO; @@ -171,12 +171,12 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, (u8 *)&send_hprime_out, sizeof(send_hprime_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (send_hprime_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status); return -EIO; } @@ -222,12 +222,12 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat (u8 *)&pairing_info_out, sizeof(pairing_info_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (pairing_info_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. Status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. Status: 0x%X\n", WIRED_AKE_SEND_PAIRING_INFO, pairing_info_out.header.status); return -EIO; @@ -269,12 +269,12 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev, byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&lc_init_in, sizeof(lc_init_in), (u8 *)&lc_init_out, sizeof(lc_init_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (lc_init_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. status: 0x%X\n", WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status); return -EIO; } @@ -323,12 +323,12 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, (u8 *)&verify_lprime_out, sizeof(verify_lprime_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (verify_lprime_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", WIRED_VALIDATE_LOCALITY, verify_lprime_out.header.status); return -EIO; @@ -369,12 +369,12 @@ int intel_hdcp_gsc_get_session_key(struct device *dev, byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&get_skey_in, sizeof(get_skey_in), (u8 *)&get_skey_out, sizeof(get_skey_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (get_skey_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", WIRED_GET_SESSION_KEY, get_skey_out.header.status); return -EIO; } @@ -435,12 +435,12 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, (u8 *)&verify_repeater_out, sizeof(verify_repeater_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (verify_repeater_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", WIRED_VERIFY_REPEATER, verify_repeater_out.header.status); return -EIO; @@ -504,12 +504,12 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev, sizeof(verify_mprime_out)); kfree(verify_mprime_in); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (verify_mprime_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", WIRED_REPEATER_AUTH_STREAM_REQ, verify_mprime_out.header.status); return -EIO; @@ -552,12 +552,12 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev, (u8 *)&enable_auth_out, sizeof(enable_auth_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (enable_auth_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", WIRED_ENABLE_AUTH, enable_auth_out.header.status); return -EIO; } @@ -599,12 +599,12 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data) (u8 *)&session_close_out, sizeof(session_close_out)); if (byte < 0) { - drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); + drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; } if (session_close_out.header.status != FW_HDCP_STATUS_SUCCESS) { - drm_dbg_kms(&i915->drm, "Session Close Failed. status: 0x%X\n", + drm_dbg_kms(display->drm, "Session Close Failed. status: 0x%X\n", session_close_out.header.status); return -EIO; } diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c index 5badf90b26de..231677129a35 100644 --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c @@ -67,9 +67,10 @@ bool intel_hdcp_gsc_check_status(struct intel_display *display) } /*This function helps allocate memory for the command that we will send to gsc cs */ -static int intel_hdcp_gsc_initialize_message(struct xe_device *xe, +static int intel_hdcp_gsc_initialize_message(struct intel_display *display, struct intel_hdcp_gsc_message *hdcp_message) { + struct xe_device *xe = to_xe_device(display->drm); struct xe_bo *bo = NULL; u64 cmd_in, cmd_out; int ret = 0; @@ -81,7 +82,7 @@ static int intel_hdcp_gsc_initialize_message(struct xe_device *xe, XE_BO_FLAG_GGTT); if (IS_ERR(bo)) { - drm_err(&xe->drm, "Failed to allocate bo for HDCP streaming command!\n"); + drm_err(display->drm, "Failed to allocate bo for HDCP streaming command!\n"); ret = PTR_ERR(bo); goto out; } @@ -97,7 +98,7 @@ static int intel_hdcp_gsc_initialize_message(struct xe_device *xe, return ret; } -static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe) +static int intel_hdcp_gsc_hdcp2_init(struct intel_display *display) { struct intel_hdcp_gsc_message *hdcp_message; int ret; @@ -111,14 +112,14 @@ static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe) * NOTE: No need to lock the comp mutex here as it is already * going to be taken before this function called */ - ret = intel_hdcp_gsc_initialize_message(xe, hdcp_message); + ret = intel_hdcp_gsc_initialize_message(display, hdcp_message); if (ret) { - drm_err(&xe->drm, "Could not initialize hdcp_message\n"); + drm_err(display->drm, "Could not initialize hdcp_message\n"); kfree(hdcp_message); return ret; } - xe->display.hdcp.hdcp_message = hdcp_message; + display->hdcp.hdcp_message = hdcp_message; return ret; } @@ -138,7 +139,7 @@ static const struct i915_hdcp_ops gsc_hdcp_ops = { .close_hdcp_session = intel_hdcp_gsc_close_session, }; -int intel_hdcp_gsc_init(struct xe_device *xe) +int intel_hdcp_gsc_init(struct intel_display *display) { struct i915_hdcp_arbiter *data; int ret; @@ -147,33 +148,33 @@ int intel_hdcp_gsc_init(struct xe_device *xe) if (!data) return -ENOMEM; - mutex_lock(&xe->display.hdcp.hdcp_mutex); - xe->display.hdcp.arbiter = data; - xe->display.hdcp.arbiter->hdcp_dev = xe->drm.dev; - xe->display.hdcp.arbiter->ops = &gsc_hdcp_ops; - ret = intel_hdcp_gsc_hdcp2_init(xe); + mutex_lock(&display->hdcp.hdcp_mutex); + display->hdcp.arbiter = data; + display->hdcp.arbiter->hdcp_dev = display->drm->dev; + display->hdcp.arbiter->ops = &gsc_hdcp_ops; + ret = intel_hdcp_gsc_hdcp2_init(display); if (ret) kfree(data); - mutex_unlock(&xe->display.hdcp.hdcp_mutex); + mutex_unlock(&display->hdcp.hdcp_mutex); return ret; } -void intel_hdcp_gsc_fini(struct xe_device *xe) +void intel_hdcp_gsc_fini(struct intel_display *display) { struct intel_hdcp_gsc_message *hdcp_message = - xe->display.hdcp.hdcp_message; - struct i915_hdcp_arbiter *arb = xe->display.hdcp.arbiter; + display->hdcp.hdcp_message; + struct i915_hdcp_arbiter *arb = display->hdcp.arbiter; if (hdcp_message) { xe_bo_unpin_map_no_vm(hdcp_message->hdcp_bo); kfree(hdcp_message); - xe->display.hdcp.hdcp_message = NULL; + display->hdcp.hdcp_message = NULL; } kfree(arb); - xe->display.hdcp.arbiter = NULL; + display->hdcp.arbiter = NULL; } static int xe_gsc_send_sync(struct xe_device *xe, From 47382485baa781b68622d94faa3473c9a235f23e Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 12 Sep 2024 06:55:44 +0530 Subject: [PATCH 043/205] drm/xe/display: Do not suspend resume dp mst during runtime Remove intel_dp_mst_suspend/resume from runtime suspend resume sequences. It is incorrect as it depends on AUX transfers which itself depend on the device being runtime resumed. This is also why we see a lock_dep splat here. <4> [76.011119] kworker/4:2/192 is trying to acquire lock: <4> [76.011122] ffff8881120b3210 (&mgr->lock#2){+.+.}-{3:3}, at: drm_dp_mst_topology_mgr_suspend+0x33/0xd0 [drm_display_helper] <4> [76.011142] but task is already holding lock: <4> [76.011144] ffffffffa0bc3420 (xe_pm_runtime_lockdep_map){+.+.}-{0:0}, at: xe_pm_runtime_suspend+0x51/0x3f0 [xe] <4> [76.011223] which lock already depends on the new lock. <4> [76.011226] the existing dependency chain (in reverse order) is: <4> [76.011229] -> #2 (xe_pm_runtime_lockdep_map){+.+.}-{0:0}: <4> [76.011233] pm_runtime_lockdep_prime+0x2f/0x50 [xe] <4> [76.011306] xe_pm_runtime_resume_and_get+0x29/0x90 [xe] <4> [76.011377] intel_display_power_get+0x24/0x70 [xe] <4> [76.011466] intel_digital_port_connected_locked+0x4c/0xf0 [xe] <4> [76.011551] intel_dp_aux_xfer+0xb8/0x7c0 [xe] <4> [76.011633] intel_dp_aux_transfer+0x166/0x2e0 [xe] <4> [76.011715] drm_dp_dpcd_access+0x87/0x150 [drm_display_helper] <4> [76.011726] drm_dp_dpcd_probe+0x3d/0xf0 [drm_display_helper] <4> [76.011737] drm_dp_dpcd_read+0xdd/0x130 [drm_display_helper] <4> [76.011747] intel_dp_get_colorimetry_status+0x3a/0x70 [xe] <4> [76.011886] intel_dp_init_connector+0x4ff/0x1030 [xe] <4> [76.011969] intel_ddi_init+0xc5b/0x1030 [xe] <4> [76.012058] intel_bios_for_each_encoder+0x36/0x60 [xe] <4> [76.012145] intel_setup_outputs+0x201/0x460 [xe] <4> [76.012233] intel_display_driver_probe_nogem+0x155/0x1e0 [xe] <4> [76.012320] xe_display_init_noaccel+0x27/0x70 [xe] Signed-off-by: Suraj Kandpal Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20240912012545.702032-2-suraj.kandpal@intel.com --- drivers/gpu/drm/xe/display/xe_display.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 10d707e05d6e..cdfc87bd78bc 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -342,7 +342,8 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime) xe_display_flush_cleanup_work(xe); - intel_dp_mst_suspend(xe); + if (!runtime) + intel_dp_mst_suspend(xe); intel_hpd_cancel_work(xe); @@ -407,7 +408,9 @@ void xe_display_pm_resume(struct xe_device *xe, bool runtime) intel_display_driver_resume_access(xe); /* MST sideband requires HPD interrupts enabled */ - intel_dp_mst_resume(xe); + if (!runtime) + intel_dp_mst_resume(xe); + if (!runtime && has_display(xe)) { intel_display_driver_resume(xe); drm_kms_helper_poll_enable(&xe->drm); From 5422d30957570b0f0283f8ad4d0dd45637c11db7 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 12 Sep 2024 06:55:45 +0530 Subject: [PATCH 044/205] drm/xe/display: Do not do intel_fbdev_set_suspend during runtime Do not do intel_fbdev_set_suspend during runtime_suspend/resume functions. This cause a big circular lock_dep splat. kworker/0:4/198 is trying to acquire lock: <4> [77.185594] ffffffff83398500 (console_lock){+.+.}-{0:0}, at: intel_fbdev_set_suspend+0x169/0x1f0 [xe] <4> [77.185947] but task is already holding lock: <4> [77.185949] ffffffffa09e9460 (xe_pm_runtime_lockdep_map){+.+.}-{0:0}, at: xe_pm_runtime_suspend+0x51/0x3f0 [xe] <4> [77.186262] which lock already depends on the new lock. <4> [77.186264] the existing dependency chain (in reverse order) is: <4> [77.186266] -> #2 (xe_pm_runtime_lockdep_map){+.+.}-{0:0}: <4> [77.186276] pm_runtime_lockdep_prime+0x2f/0x50 [xe] <4> [77.186572] xe_pm_runtime_resume_and_get+0x29/0x90 [xe] <4> [77.186867] intelfb_create+0x150/0x390 [xe] <4> [77.187197] __drm_fb_helper_initial_config_and_unlock+0x31c/0x5e0 [drm_kms_helper] <4> [77.187243] drm_fb_helper_initial_config+0x3d/0x50 [drm_kms_helper] <4> [77.187274] intel_fbdev_client_hotplug+0xb1/0x140 [xe] <4> [77.187603] drm_client_register+0x87/0xd0 [drm] <4> [77.187704] intel_fbdev_setup+0x51c/0x640 [xe] <4> [77.188033] intel_display_driver_register+0xb7/0xf0 [xe] <4> [77.188438] xe_display_register+0x21/0x40 [xe] <4> [77.188809] xe_device_probe+0xa8d/0xbf0 [xe] <4> [77.189035] xe_pci_probe+0x333/0x5b0 [xe] <4> [77.189330] local_pci_probe+0x48/0xb0 <4> [77.189341] pci_device_probe+0xc8/0x280 <4> [77.189351] really_probe+0xf8/0x390 <4> [77.189362] __driver_probe_device+0x8a/0x170 <4> [77.189373] driver_probe_device+0x23/0xb0 Signed-off-by: Suraj Kandpal Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20240912012545.702032-3-suraj.kandpal@intel.com --- drivers/gpu/drm/xe/display/xe_display.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index cdfc87bd78bc..b1730b581656 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -333,7 +333,9 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime) * properly. */ intel_power_domains_disable(xe); - intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true); + if (!runtime) + intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true); + if (!runtime && has_display(xe)) { drm_kms_helper_poll_disable(&xe->drm); intel_display_driver_disable_user_access(xe); @@ -420,7 +422,8 @@ void xe_display_pm_resume(struct xe_device *xe, bool runtime) intel_opregion_resume(display); - intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false); + if (!runtime) + intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false); intel_power_domains_enable(xe); } From 8d8c3ceb79efe2e49315984a3d4f0a3d4e687d28 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 Sep 2024 17:34:11 +0300 Subject: [PATCH 045/205] drm/i915: dump display parameters captured in error state, not current intel_display_params_dump() prints the current display parameters, not the ones captured during error capture. It's not likely the params get changed in between, but make it pedantically correct anyway. Pass in the parameters and driver name to intel_display_params_dump(). Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/b437a5db768f0cb34377a9e4669c2b37fc7c7c29.1726151571.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_params.c | 8 +++++--- drivers/gpu/drm/i915/display/intel_display_params.h | 5 ++--- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c index 1a45d300b6f0..024de8abcb1a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.c +++ b/drivers/gpu/drm/i915/display/intel_display_params.c @@ -173,14 +173,16 @@ static void _param_print_charp(struct drm_printer *p, const char *driver_name, /** * intel_display_params_dump - dump intel display modparams - * @display: display device + * @params: display params + * @driver_name: driver name to use for printing * @p: the &drm_printer * * Pretty printer for i915 modparams. */ -void intel_display_params_dump(struct intel_display *display, struct drm_printer *p) +void intel_display_params_dump(const struct intel_display_params *params, + const char *driver_name, struct drm_printer *p) { -#define PRINT(T, x, ...) _param_print(p, display->drm->driver->name, #x, display->params.x); +#define PRINT(T, x, ...) _param_print(p, driver_name, #x, params->x); INTEL_DISPLAY_PARAMS_FOR_EACH(PRINT); #undef PRINT } diff --git a/drivers/gpu/drm/i915/display/intel_display_params.h b/drivers/gpu/drm/i915/display/intel_display_params.h index da8dc943234b..dcb6face936a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.h +++ b/drivers/gpu/drm/i915/display/intel_display_params.h @@ -9,7 +9,6 @@ #include struct drm_printer; -struct intel_display; /* * Invoke param, a function-like macro, for each intel display param, with @@ -56,8 +55,8 @@ struct intel_display_params { }; #undef MEMBER -void intel_display_params_dump(struct intel_display *display, - struct drm_printer *p); +void intel_display_params_dump(const struct intel_display_params *params, + const char *driver_name, struct drm_printer *p); void intel_display_params_copy(struct intel_display_params *dest); void intel_display_params_free(struct intel_display_params *params); diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f969f585d07b..246fece628d6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -78,7 +78,7 @@ static int i915_capabilities(struct seq_file *m, void *data) kernel_param_lock(THIS_MODULE); i915_params_dump(&i915->params, &p); - intel_display_params_dump(display, &p); + intel_display_params_dump(&display->params, display->drm->driver->name, &p); kernel_param_unlock(THIS_MODULE); return 0; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index b455fa441609..4baee1aa74dc 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -663,7 +663,7 @@ static void err_print_params(struct drm_i915_error_state_buf *m, struct intel_display *display = &m->i915->display; i915_params_dump(params, &p); - intel_display_params_dump(display, &p); + intel_display_params_dump(&display->params, display->drm->driver->name, &p); } static void err_print_pciid(struct drm_i915_error_state_buf *m, From 6843cd85430054735b2178dcabee39bc57a4eebf Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 Sep 2024 17:34:12 +0300 Subject: [PATCH 046/205] drm/i915/display: add intel_display_snapshot abstraction The error state capture still handles display info at a too detailed level. Start abstracting the whole display snapshot capture and printing at a higher level. Move overlay to display snapshot first. Use the same nomenclature and style as in xe devcoredump, in preparation for perhaps some day bolting the snapshots there as well. v3: Fix build harder for CONFIG_DRM_I915_CAPTURE_ERROR=n v2: Fix build for CONFIG_DRM_I915_CAPTURE_ERROR=n (kernel test robot) Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/ba6a36759600c2d35405c41a0fc9d69f676df77d.1726151571.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/display/intel_display_snapshot.c | 42 +++++++++++++++++++ .../drm/i915/display/intel_display_snapshot.h | 16 +++++++ drivers/gpu/drm/i915/display/intel_overlay.c | 16 ++++--- drivers/gpu/drm/i915/display/intel_overlay.h | 25 +++++++---- drivers/gpu/drm/i915/i915_gpu_error.c | 12 +++--- drivers/gpu/drm/i915/i915_gpu_error.h | 6 +-- 7 files changed, 94 insertions(+), 24 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_display_snapshot.c create mode 100644 drivers/gpu/drm/i915/display/intel_display_snapshot.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index c63fa2133ccb..9fcd9e09bc0b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -242,6 +242,7 @@ i915-y += \ display/intel_display_power_well.o \ display/intel_display_reset.o \ display/intel_display_rps.o \ + display/intel_display_snapshot.o \ display/intel_display_wa.o \ display/intel_dmc.o \ display/intel_dmc_wl.o \ diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.c b/drivers/gpu/drm/i915/display/intel_display_snapshot.c new file mode 100644 index 000000000000..78b019dcd41d --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2024 Intel Corporation */ + +#include + +#include "intel_display_snapshot.h" +#include "intel_overlay.h" + +struct intel_display_snapshot { + struct intel_overlay_snapshot *overlay; +}; + +struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display) +{ + struct intel_display_snapshot *snapshot; + + snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + if (!snapshot) + return NULL; + + snapshot->overlay = intel_overlay_snapshot_capture(display); + + return snapshot; +} + +void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot, + struct drm_printer *p) +{ + if (!snapshot) + return; + + intel_overlay_snapshot_print(snapshot->overlay, p); +} + +void intel_display_snapshot_free(struct intel_display_snapshot *snapshot) +{ + if (!snapshot) + return; + + kfree(snapshot->overlay); + kfree(snapshot); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.h b/drivers/gpu/drm/i915/display/intel_display_snapshot.h new file mode 100644 index 000000000000..7ed27cdea644 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2024 Intel Corporation */ + +#ifndef __INTEL_DISPLAY_SNAPSHOT_H__ +#define __INTEL_DISPLAY_SNAPSHOT_H__ + +struct drm_printer; +struct intel_display; +struct intel_display_snapshot; + +struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display); +void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot, + struct drm_printer *p); +void intel_display_snapshot_free(struct intel_display_snapshot *snapshot); + +#endif /* __INTEL_DISPLAY_SNAPSHOT_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 06b1122ec13e..b89541458765 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -1457,18 +1457,19 @@ void intel_overlay_cleanup(struct drm_i915_private *dev_priv) #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) -struct intel_overlay_error_state { +struct intel_overlay_snapshot { struct overlay_registers regs; unsigned long base; u32 dovsta; u32 isr; }; -struct intel_overlay_error_state * -intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) +struct intel_overlay_snapshot * +intel_overlay_snapshot_capture(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_overlay *overlay = dev_priv->display.overlay; - struct intel_overlay_error_state *error; + struct intel_overlay_snapshot *error; if (!overlay || !overlay->active) return NULL; @@ -1487,9 +1488,12 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) } void -intel_overlay_print_error_state(struct drm_printer *p, - struct intel_overlay_error_state *error) +intel_overlay_snapshot_print(const struct intel_overlay_snapshot *error, + struct drm_printer *p) { + if (!error) + return; + drm_printf(p, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", error->dovsta, error->isr); drm_printf(p, " Register file at 0x%08lx:\n", error->base); diff --git a/drivers/gpu/drm/i915/display/intel_overlay.h b/drivers/gpu/drm/i915/display/intel_overlay.h index f28a09c062d0..eafac24d1de8 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.h +++ b/drivers/gpu/drm/i915/display/intel_overlay.h @@ -6,12 +6,15 @@ #ifndef __INTEL_OVERLAY_H__ #define __INTEL_OVERLAY_H__ +#include + struct drm_device; struct drm_file; struct drm_i915_private; struct drm_printer; +struct intel_display; struct intel_overlay; -struct intel_overlay_error_state; +struct intel_overlay_snapshot; #ifdef I915 void intel_overlay_setup(struct drm_i915_private *dev_priv); @@ -22,10 +25,6 @@ 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 drm_i915_private *dev_priv); -struct intel_overlay_error_state * -intel_overlay_capture_error_state(struct drm_i915_private *dev_priv); -void intel_overlay_print_error_state(struct drm_printer *p, - struct intel_overlay_error_state *error); #else static inline void intel_overlay_setup(struct drm_i915_private *dev_priv) { @@ -50,13 +49,21 @@ static inline int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, static inline void intel_overlay_reset(struct drm_i915_private *dev_priv) { } -static inline struct intel_overlay_error_state * -intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) +#endif + +#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) && defined(I915) +struct intel_overlay_snapshot * +intel_overlay_snapshot_capture(struct intel_display *display); +void intel_overlay_snapshot_print(const struct intel_overlay_snapshot *error, + struct drm_printer *p); +#else +static inline struct intel_overlay_snapshot * +intel_overlay_snapshot_capture(struct intel_display *display) { return NULL; } -static inline void intel_overlay_print_error_state(struct drm_printer *p, - struct intel_overlay_error_state *error) +static inline void intel_overlay_snapshot_print(const struct intel_overlay_snapshot *error, + struct drm_printer *p) { } #endif diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 4baee1aa74dc..c4402d7cc1cd 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -40,8 +40,8 @@ #include #include +#include "display/intel_display_snapshot.h" #include "display/intel_dmc.h" -#include "display/intel_overlay.h" #include "gem/i915_gem_context.h" #include "gem/i915_gem_lmem.h" @@ -905,11 +905,10 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m, err_print_gt_info(m, error->gt); } - if (error->overlay) - intel_overlay_print_error_state(&p, error->overlay); - err_print_capabilities(m, error); err_print_params(m, &error->params); + + intel_display_snapshot_print(error->display_snapshot, &p); } static int err_print_to_sgl(struct i915_gpu_coredump *error) @@ -1077,7 +1076,7 @@ void __i915_gpu_coredump_free(struct kref *error_ref) cleanup_gt(gt); } - kfree(error->overlay); + intel_display_snapshot_free(error->display_snapshot); cleanup_params(error); @@ -2097,6 +2096,7 @@ static struct i915_gpu_coredump * __i915_gpu_coredump(struct intel_gt *gt, intel_engine_mask_t engine_mask, u32 dump_flags) { struct drm_i915_private *i915 = gt->i915; + struct intel_display *display = &i915->display; struct i915_gpu_coredump *error; /* Check if GPU capture has been disabled */ @@ -2138,7 +2138,7 @@ __i915_gpu_coredump(struct intel_gt *gt, intel_engine_mask_t engine_mask, u32 du error->simulated |= error->gt->simulated; } - error->overlay = intel_overlay_capture_error_state(i915); + error->display_snapshot = intel_display_snapshot_capture(display); return error; } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h index 7c255bb1c319..1a11942d7800 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.h +++ b/drivers/gpu/drm/i915/i915_gpu_error.h @@ -31,7 +31,7 @@ struct drm_i915_private; struct i915_vma_compress; struct intel_engine_capture_vma; -struct intel_overlay_error_state; +struct intel_display_snapshot; struct i915_vma_coredump { struct i915_vma_coredump *next; @@ -218,9 +218,9 @@ struct i915_gpu_coredump { struct i915_params params; struct intel_display_params display_params; - struct intel_overlay_error_state *overlay; - struct scatterlist *sgl, *fit; + + struct intel_display_snapshot *display_snapshot; }; struct i915_gpu_error { From 6304e052df2111f25bfedcaf999ac8571a275f2a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 Sep 2024 17:34:13 +0300 Subject: [PATCH 047/205] drm/i915/display: move device info and params handling to snapshot Snapshot display device and runtime info as well as display parameters in display snapshot. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/5aa52749d6adce6d9c85cb8d8395bbf4db0e76a2.1726151571.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_snapshot.c | 25 +++++++++++++++++++ drivers/gpu/drm/i915/i915_gpu_error.c | 10 -------- drivers/gpu/drm/i915/i915_gpu_error.h | 5 ---- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.c b/drivers/gpu/drm/i915/display/intel_display_snapshot.c index 78b019dcd41d..a61ff0f81397 100644 --- a/drivers/gpu/drm/i915/display/intel_display_snapshot.c +++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.c @@ -3,10 +3,18 @@ #include +#include "i915_drv.h" +#include "intel_display_device.h" +#include "intel_display_params.h" #include "intel_display_snapshot.h" #include "intel_overlay.h" struct intel_display_snapshot { + struct intel_display *display; + + struct intel_display_device_info info; + struct intel_display_runtime_info runtime_info; + struct intel_display_params params; struct intel_overlay_snapshot *overlay; }; @@ -18,6 +26,14 @@ struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_displ if (!snapshot) return NULL; + snapshot->display = display; + + memcpy(&snapshot->info, DISPLAY_INFO(display), sizeof(snapshot->info)); + memcpy(&snapshot->runtime_info, DISPLAY_RUNTIME_INFO(display), + sizeof(snapshot->runtime_info)); + + intel_display_params_copy(&snapshot->params); + snapshot->overlay = intel_overlay_snapshot_capture(display); return snapshot; @@ -26,9 +42,16 @@ struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_displ void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot, struct drm_printer *p) { + struct intel_display *display; + if (!snapshot) return; + display = snapshot->display; + + intel_display_device_info_print(&snapshot->info, &snapshot->runtime_info, p); + intel_display_params_dump(&snapshot->params, display->drm->driver->name, p); + intel_overlay_snapshot_print(snapshot->overlay, p); } @@ -37,6 +60,8 @@ void intel_display_snapshot_free(struct intel_display_snapshot *snapshot) if (!snapshot) return; + intel_display_params_free(&snapshot->params); + kfree(snapshot->overlay); kfree(snapshot); } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index c4402d7cc1cd..a84d2fa735b0 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -651,8 +651,6 @@ static void err_print_capabilities(struct drm_i915_error_state_buf *m, struct drm_printer p = i915_error_printer(m); intel_device_info_print(&error->device_info, &error->runtime_info, &p); - intel_display_device_info_print(&error->display_device_info, - &error->display_runtime_info, &p); intel_driver_caps_print(&error->driver_caps, &p); } @@ -660,10 +658,8 @@ static void err_print_params(struct drm_i915_error_state_buf *m, const struct i915_params *params) { struct drm_printer p = i915_error_printer(m); - struct intel_display *display = &m->i915->display; i915_params_dump(params, &p); - intel_display_params_dump(&display->params, display->drm->driver->name, &p); } static void err_print_pciid(struct drm_i915_error_state_buf *m, @@ -1031,7 +1027,6 @@ static void i915_vma_coredump_free(struct i915_vma_coredump *vma) static void cleanup_params(struct i915_gpu_coredump *error) { i915_params_free(&error->params); - intel_display_params_free(&error->display_params); } static void cleanup_uc(struct intel_uc_coredump *uc) @@ -1992,17 +1987,12 @@ static void capture_gen(struct i915_gpu_coredump *error) error->suspend_count = i915->suspend_count; i915_params_copy(&error->params, &i915->params); - intel_display_params_copy(&error->display_params); memcpy(&error->device_info, INTEL_INFO(i915), sizeof(error->device_info)); memcpy(&error->runtime_info, RUNTIME_INFO(i915), sizeof(error->runtime_info)); - memcpy(&error->display_device_info, DISPLAY_INFO(i915), - sizeof(error->display_device_info)); - memcpy(&error->display_runtime_info, DISPLAY_RUNTIME_INFO(i915), - sizeof(error->display_runtime_info)); error->driver_caps = i915->caps; } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h index 1a11942d7800..78a8928562a9 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.h +++ b/drivers/gpu/drm/i915/i915_gpu_error.h @@ -14,8 +14,6 @@ #include -#include "display/intel_display_device.h" -#include "display/intel_display_params.h" #include "gt/intel_engine.h" #include "gt/intel_engine_types.h" #include "gt/intel_gt_types.h" @@ -212,11 +210,8 @@ struct i915_gpu_coredump { struct intel_device_info device_info; struct intel_runtime_info runtime_info; - struct intel_display_device_info display_device_info; - struct intel_display_runtime_info display_runtime_info; struct intel_driver_caps driver_caps; struct i915_params params; - struct intel_display_params display_params; struct scatterlist *sgl, *fit; From 8967549f99aaf6a2652ded122a2b15cd6bf895b1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 Sep 2024 17:34:14 +0300 Subject: [PATCH 048/205] drm/i915/display: move dmc snapshotting to new display snapshot Convert dmc error state printing to new snapshot capture/print division. v2: Rebase Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/9116319e7faceeed7695ee35e56fe001ddf94e11.1726151571.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_snapshot.c | 5 +++ drivers/gpu/drm/i915/display/intel_dmc.c | 38 +++++++++++++++---- drivers/gpu/drm/i915/display/intel_dmc.h | 6 ++- drivers/gpu/drm/i915/i915_gpu_error.c | 3 -- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.c b/drivers/gpu/drm/i915/display/intel_display_snapshot.c index a61ff0f81397..030c4f873da1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_snapshot.c +++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.c @@ -7,6 +7,7 @@ #include "intel_display_device.h" #include "intel_display_params.h" #include "intel_display_snapshot.h" +#include "intel_dmc.h" #include "intel_overlay.h" struct intel_display_snapshot { @@ -16,6 +17,7 @@ struct intel_display_snapshot { struct intel_display_runtime_info runtime_info; struct intel_display_params params; struct intel_overlay_snapshot *overlay; + struct intel_dmc_snapshot *dmc; }; struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display) @@ -35,6 +37,7 @@ struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_displ intel_display_params_copy(&snapshot->params); snapshot->overlay = intel_overlay_snapshot_capture(display); + snapshot->dmc = intel_dmc_snapshot_capture(display); return snapshot; } @@ -53,6 +56,7 @@ void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot, intel_display_params_dump(&snapshot->params, display->drm->driver->name, p); intel_overlay_snapshot_print(snapshot->overlay, p); + intel_dmc_snapshot_print(snapshot->dmc, p); } void intel_display_snapshot_free(struct intel_display_snapshot *snapshot) @@ -63,5 +67,6 @@ void intel_display_snapshot_free(struct intel_display_snapshot *snapshot) intel_display_params_free(&snapshot->params); kfree(snapshot->overlay); + kfree(snapshot->dmc); kfree(snapshot); } diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index bbac6bfd1752..48bbbf8f312c 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -1194,21 +1194,43 @@ void intel_dmc_fini(struct intel_display *display) } } -void intel_dmc_print_error_state(struct drm_printer *p, - struct intel_display *display) +struct intel_dmc_snapshot { + bool initialized; + bool loaded; + u32 version; +}; + +struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display) { struct intel_dmc *dmc = display_to_dmc(display); + struct intel_dmc_snapshot *snapshot; if (!HAS_DMC(display)) + return NULL; + + snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + if (!snapshot) + return NULL; + + snapshot->initialized = dmc; + snapshot->loaded = intel_dmc_has_payload(display); + if (dmc) + snapshot->version = dmc->version; + + return snapshot; +} + +void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p) +{ + if (!snapshot) return; - drm_printf(p, "DMC initialized: %s\n", str_yes_no(dmc)); - drm_printf(p, "DMC loaded: %s\n", - str_yes_no(intel_dmc_has_payload(display))); - if (dmc) + drm_printf(p, "DMC initialized: %s\n", str_yes_no(snapshot->initialized)); + drm_printf(p, "DMC loaded: %s\n", str_yes_no(snapshot->loaded)); + if (snapshot->initialized) drm_printf(p, "DMC fw version: %d.%d\n", - DMC_VERSION_MAJOR(dmc->version), - DMC_VERSION_MINOR(dmc->version)); + DMC_VERSION_MAJOR(snapshot->version), + DMC_VERSION_MINOR(snapshot->version)); } static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 2ead2ec1f820..44cecef98e73 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -11,6 +11,7 @@ enum pipe; struct drm_printer; struct intel_display; +struct intel_dmc_snapshot; void intel_dmc_init(struct intel_display *display); void intel_dmc_load_program(struct intel_display *display); @@ -22,8 +23,9 @@ void intel_dmc_suspend(struct intel_display *display); void intel_dmc_resume(struct intel_display *display); bool intel_dmc_has_payload(struct intel_display *display); void intel_dmc_debugfs_register(struct intel_display *display); -void intel_dmc_print_error_state(struct drm_printer *p, - struct intel_display *display); + +struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display); +void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p); void assert_dmc_loaded(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a84d2fa735b0..135ded17334e 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -41,7 +41,6 @@ #include #include "display/intel_display_snapshot.h" -#include "display/intel_dmc.h" #include "gem/i915_gem_context.h" #include "gem/i915_gem_lmem.h" @@ -871,8 +870,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m, err_printf(m, "IOMMU enabled?: %d\n", error->iommu); - intel_dmc_print_error_state(&p, &m->i915->display); - err_printf(m, "RPM wakelock: %s\n", str_yes_no(error->wakelock)); err_printf(m, "PM suspended: %s\n", str_yes_no(error->suspended)); From 0f47fed5c30f178e2db3222597abbba23ff3b6ff Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Tue, 10 Sep 2024 16:22:42 +0530 Subject: [PATCH 049/205] drm/i915/hwmon: expose package temperature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add hwmon support for temp1_input attribute, which will expose package temperature in millidegree Celsius. With this in place we can monitor package temperature using lm-sensors tool. $ sensors i915-pci-0300 Adapter: PCI adapter in0: 990.00 mV fan1: 1260 RPM temp1: +45.0°C power1: N/A (max = 35.00 W) energy1: 12.62 kJ v2: Use switch case (Anshuman) v3: Comment adjustment (Riana) Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/11276 Signed-off-by: Raag Jadav Reviewed-by: Anshuman Gupta Reviewed-by: Andi Shyti Reviewed-by: Riana Tauro Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240910105242.3357276-1-raag.jadav@intel.com --- .../ABI/testing/sysfs-driver-intel-i915-hwmon | 8 ++++ drivers/gpu/drm/i915/i915_hwmon.c | 40 +++++++++++++++++++ drivers/gpu/drm/i915/intel_mchbar_regs.h | 4 ++ 3 files changed, 52 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon index be4141a7522f..a885e5316d02 100644 --- a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon +++ b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon @@ -83,3 +83,11 @@ Contact: intel-gfx@lists.freedesktop.org Description: RO. Fan speed of device in RPM. Only supported for particular Intel i915 graphics platforms. + +What: /sys/bus/pci/drivers/i915/.../hwmon/hwmon/temp1_input +Date: November 2024 +KernelVersion: 6.12 +Contact: intel-gfx@lists.freedesktop.org +Description: RO. GPU package temperature in millidegree Celsius. + + Only supported for particular Intel i915 graphics platforms. diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c index 17d30f6b84b0..7dfe1784153f 100644 --- a/drivers/gpu/drm/i915/i915_hwmon.c +++ b/drivers/gpu/drm/i915/i915_hwmon.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_hwmon.h" @@ -32,6 +33,7 @@ struct hwm_reg { i915_reg_t gt_perf_status; + i915_reg_t pkg_temp; i915_reg_t pkg_power_sku_unit; i915_reg_t pkg_power_sku; i915_reg_t pkg_rapl_limit; @@ -280,6 +282,7 @@ static const struct attribute_group *hwm_groups[] = { }; static const struct hwmon_channel_info * const hwm_info[] = { + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), HWMON_CHANNEL_INFO(in, HWMON_I_INPUT), HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_CRIT), HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT), @@ -310,6 +313,37 @@ static int hwm_pcode_write_i1(struct drm_i915_private *i915, u32 uval) POWER_SETUP_SUBCOMMAND_WRITE_I1, 0, uval); } +static umode_t +hwm_temp_is_visible(const struct hwm_drvdata *ddat, u32 attr) +{ + struct i915_hwmon *hwmon = ddat->hwmon; + + if (attr == hwmon_temp_input && i915_mmio_reg_valid(hwmon->rg.pkg_temp)) + return 0444; + + return 0; +} + +static int +hwm_temp_read(struct hwm_drvdata *ddat, u32 attr, long *val) +{ + struct i915_hwmon *hwmon = ddat->hwmon; + intel_wakeref_t wakeref; + u32 reg_val; + + switch (attr) { + case hwmon_temp_input: + with_intel_runtime_pm(ddat->uncore->rpm, wakeref) + reg_val = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_temp); + + /* HW register value is in degrees Celsius, convert to millidegrees. */ + *val = REG_FIELD_GET(TEMP_MASK, reg_val) * MILLIDEGREE_PER_DEGREE; + return 0; + default: + return -EOPNOTSUPP; + } +} + static umode_t hwm_in_is_visible(const struct hwm_drvdata *ddat, u32 attr) { @@ -692,6 +726,8 @@ hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type, struct hwm_drvdata *ddat = (struct hwm_drvdata *)drvdata; switch (type) { + case hwmon_temp: + return hwm_temp_is_visible(ddat, attr); case hwmon_in: return hwm_in_is_visible(ddat, attr); case hwmon_power: @@ -714,6 +750,8 @@ hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, struct hwm_drvdata *ddat = dev_get_drvdata(dev); switch (type) { + case hwmon_temp: + return hwm_temp_read(ddat, attr, val); case hwmon_in: return hwm_in_read(ddat, attr, val); case hwmon_power: @@ -810,6 +848,7 @@ hwm_get_preregistration_info(struct drm_i915_private *i915) hwmon->rg.gt_perf_status = GEN12_RPSTAT1; if (IS_DG1(i915) || IS_DG2(i915)) { + hwmon->rg.pkg_temp = PCU_PACKAGE_TEMPERATURE; hwmon->rg.pkg_power_sku_unit = PCU_PACKAGE_POWER_SKU_UNIT; hwmon->rg.pkg_power_sku = PCU_PACKAGE_POWER_SKU; hwmon->rg.pkg_rapl_limit = PCU_PACKAGE_RAPL_LIMIT; @@ -817,6 +856,7 @@ hwm_get_preregistration_info(struct drm_i915_private *i915) hwmon->rg.energy_status_tile = INVALID_MMIO_REG; hwmon->rg.fan_speed = PCU_PWM_FAN_SPEED; } else { + hwmon->rg.pkg_temp = INVALID_MMIO_REG; hwmon->rg.pkg_power_sku_unit = INVALID_MMIO_REG; hwmon->rg.pkg_power_sku = INVALID_MMIO_REG; hwmon->rg.pkg_rapl_limit = INVALID_MMIO_REG; diff --git a/drivers/gpu/drm/i915/intel_mchbar_regs.h b/drivers/gpu/drm/i915/intel_mchbar_regs.h index 73900c098d59..dc2477179c3e 100644 --- a/drivers/gpu/drm/i915/intel_mchbar_regs.h +++ b/drivers/gpu/drm/i915/intel_mchbar_regs.h @@ -207,6 +207,10 @@ #define PCU_PACKAGE_ENERGY_STATUS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x593c) #define GEN6_GT_PERF_STATUS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5948) + +#define PCU_PACKAGE_TEMPERATURE _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5978) +#define TEMP_MASK REG_GENMASK(7, 0) + #define GEN6_RP_STATE_LIMITS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5994) #define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998) #define RP0_CAP_MASK REG_GENMASK(7, 0) From f7c2ed9d4ce80a2570c492825de239dc8b500f2e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 10 Sep 2024 14:18:47 +0300 Subject: [PATCH 050/205] drm/i915/dp: Fix AUX IO power enabling for eDP PSR Panel Self Refresh on eDP requires the AUX IO power to be enabled whenever the output (main link) is enabled. This is required by the AUX_PHY_WAKE/ML_PHY_LOCK signaling initiated by the HW automatically to re-enable the main link after it got disabled in power saving states (see eDP v1.4b, sections 5.1, 6.1.3.3.1.1). The Panel Replay mode on non-eDP outputs on the other hand is only supported by keeping the main link active, thus not requiring the above AUX_PHY_WAKE/ML_PHY_LOCK signaling (eDP v1.4b, section 6.1.3.3.1.2). Thus enabling the AUX IO power for this case is not required either. Based on the above enable the AUX IO power only for eDP/PSR outputs. Bspec: 49274, 53370 v2: - Add a TODO comment to adjust the requirement for AUX IO based on whether the ALPM/main-link off mode gets enabled. (Rodrigo) Cc: Animesh Manna Fixes: b8cf5b5d266e ("drm/i915/panelreplay: Initializaton and compute config for panel replay") Reviewed-by: Rodrigo Vivi Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240910111847.2995725-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_psr.h | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 00fbe9f8c03a..b1c294236cc8 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -916,7 +916,7 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port, * instead of a specific AUX_IO_ reference without powering up any * extra wells. */ - if (intel_encoder_can_psr(&dig_port->base)) + if (intel_psr_needs_aux_io_power(&dig_port->base, crtc_state)) return intel_display_power_aux_io_domain(i915, dig_port->aux_ch); else if (DISPLAY_VER(i915) < 14 && (intel_crtc_has_dp_encoder(crtc_state) || diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 1a4ef231a53c..4f29ac32ff85 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -205,6 +205,25 @@ bool intel_encoder_can_psr(struct intel_encoder *encoder) return false; } +bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + /* + * For PSR/PR modes only eDP requires the AUX IO power to be enabled whenever + * the output is enabled. For non-eDP outputs the main link is always + * on, hence it doesn't require the HW initiated AUX wake-up signaling used + * for eDP. + * + * TODO: + * - Consider leaving AUX IO disabled for eDP / PR as well, in case + * the ALPM with main-link off mode is not enabled. + * - Leave AUX IO enabled for DP / PR, once support for ALPM with + * main-link off mode is added for it and this mode gets enabled. + */ + return intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && + intel_encoder_can_psr(encoder); +} + static bool psr_global_enabled(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 4e09c10908e4..6eb5f15f674f 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -25,6 +25,8 @@ struct intel_plane_state; (intel_dp)->psr.source_panel_replay_support) bool intel_encoder_can_psr(struct intel_encoder *encoder); +bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); void intel_psr_init_dpcd(struct intel_dp *intel_dp); void intel_psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); From 26fee9e09be346e93a2fc4126cac244de498ec5a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 12 Sep 2024 18:59:31 +0530 Subject: [PATCH 051/205] drm/i915/display: Check whether platform supports joiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add macros to check if platform supports bigjoiner/uncompressed joiner. Replace the existing DISPLAY_VER checks with these. Additionally use it before readout for joiner stuff, where its missing. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240912132931.1320686-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 9 ++++++--- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 2 +- drivers/gpu/drm/i915/display/intel_display_device.h | 2 ++ drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index fdf244a32b24..d4a371edfcdd 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1712,7 +1712,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_dsc_enable(pipe_crtc_state); - if (DISPLAY_VER(dev_priv) >= 13) + if (HAS_UNCOMPRESSED_JOINER(dev_priv)) intel_uncompressed_joiner_enable(pipe_crtc_state); intel_set_pipe_src_size(pipe_crtc_state); @@ -3546,6 +3546,9 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, *primary_pipes = 0; *secondary_pipes = 0; + if (!HAS_BIGJOINER(dev_priv)) + return; + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, joiner_pipes(dev_priv)) { enum intel_display_power_domain power_domain; @@ -3565,7 +3568,7 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, *secondary_pipes |= BIT(pipe); } - if (DISPLAY_VER(dev_priv) < 13) + if (!HAS_UNCOMPRESSED_JOINER(dev_priv)) continue; power_domain = POWER_DOMAIN_PIPE(pipe); @@ -7966,7 +7969,7 @@ static int max_dotclock(struct drm_i915_private *i915) int max_dotclock = i915->display.cdclk.max_dotclk_freq; /* icl+ might use joiner */ - if (DISPLAY_VER(i915) >= 11) + if (HAS_BIGJOINER(i915)) max_dotclock *= 2; return max_dotclock; diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index b75361e95e97..8caacdd624bd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1550,7 +1550,7 @@ void intel_connector_debugfs_add(struct intel_connector *connector) connector, &i915_dsc_fractional_bpp_fops); } - if (DISPLAY_VER(i915) >= 11 && + if (HAS_BIGJOINER(i915) && (connector_type == DRM_MODE_CONNECTOR_DisplayPort || connector_type == DRM_MODE_CONNECTOR_eDP)) { debugfs_create_bool("i915_bigjoiner_force_enable", 0644, root, diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index dfb0c8bf5ca2..5306bbd13e59 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -118,6 +118,7 @@ enum intel_display_subplatform { #define HAS_4TILE(i915) (IS_DG2(i915) || DISPLAY_VER(i915) >= 14) #define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5) +#define HAS_BIGJOINER(i915) (DISPLAY_VER(i915) >= 11) #define HAS_CDCLK_CRAWL(i915) (DISPLAY_INFO(i915)->has_cdclk_crawl) #define HAS_CDCLK_SQUASH(i915) (DISPLAY_INFO(i915)->has_cdclk_squash) #define HAS_CUR_FBC(i915) (!HAS_GMCH(i915) && IS_DISPLAY_VER(i915, 7, 13)) @@ -152,6 +153,7 @@ enum intel_display_subplatform { #define HAS_SAGV(i915) (DISPLAY_VER(i915) >= 9 && !IS_LP(i915)) #define HAS_TRANSCODER(i915, trans) ((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \ BIT(trans)) != 0) +#define HAS_UNCOMPRESSED_JOINER(i915) (DISPLAY_VER(i915) >= 13) #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11) #define HAS_AS_SDP(i915) (DISPLAY_VER(i915) >= 13) #define HAS_CMRR(i915) (DISPLAY_VER(i915) >= 20) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index cb0f6db5f8e7..c53eb8e165de 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2520,7 +2520,7 @@ bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner) * limitation. DG2 onwards pipe joiner can be enabled without * compression. */ - return DISPLAY_VER(i915) < 13 && use_joiner; + return !HAS_UNCOMPRESSED_JOINER(i915) && use_joiner; } static int From 0b5d9e3061f182cc9994edb2c896c9279949889d Mon Sep 17 00:00:00 2001 From: Yuesong Li Date: Fri, 23 Aug 2024 10:36:12 +0800 Subject: [PATCH 052/205] drm/i915/dp: Remove double assignment in intel_dp_compute_as_sdp() cocci report a double assignment warning. 'as_sdp->duration_incr_ms' was assigned twice in intel_dp_compute_as_sdp(). Signed-off-by: Yuesong Li Reviewed-by: Jani Nikula Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240823023612.3027849-1-liyuesong@vivo.com --- drivers/gpu/drm/i915/display/intel_dp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c53eb8e165de..dd281eb7c4bf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2748,7 +2748,6 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC; as_sdp->length = 0x9; as_sdp->duration_incr_ms = 0; - as_sdp->duration_incr_ms = 0; if (crtc_state->cmrr.enable) { as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED; From b0035fee1f753b85111457b454caa8d744d44c3f Mon Sep 17 00:00:00 2001 From: Shen Lichuan Date: Fri, 13 Sep 2024 10:16:12 +0800 Subject: [PATCH 053/205] drm/i915/gvt: Correct multiple typos in comments Fixed some spelling errors, the details are as follows: -in the code comments: addess->address trasitions->transitions furture->future unsubmited->unsubmitted Signed-off-by: Shen Lichuan Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240913021612.41948-1-shenlichuan@vivo.com --- drivers/gpu/drm/i915/gvt/gtt.c | 2 +- drivers/gpu/drm/i915/gvt/opregion.c | 2 +- drivers/gpu/drm/i915/gvt/page_track.c | 2 +- drivers/gpu/drm/i915/gvt/scheduler.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 58cca4906f41..1bce1493b86f 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1190,7 +1190,7 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ppgtt_set_shadow_entry(spt, se, index); return 0; err: - /* Cancel the existing addess mappings of DMA addr. */ + /* Cancel the existing address mappings of DMA addr. */ for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { gvt_vdbg_mm("invalidate 4K entry\n"); ppgtt_invalidate_pte(sub_spt, &sub_se); diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c index 908f910420c2..509f9ccae3a9 100644 --- a/drivers/gpu/drm/i915/gvt/opregion.c +++ b/drivers/gpu/drm/i915/gvt/opregion.c @@ -439,7 +439,7 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci) gvt_vgpu_err("requesting SMI service\n"); return 0; } - /* ignore non 0->1 trasitions */ + /* ignore non 0->1 transitions */ if ((vgpu_cfg_space(vgpu)[INTEL_GVT_PCI_SWSCI] & SWSCI_SCI_TRIGGER) || !(swsci & SWSCI_SCI_TRIGGER)) { diff --git a/drivers/gpu/drm/i915/gvt/page_track.c b/drivers/gpu/drm/i915/gvt/page_track.c index 60a65435556d..20c3cd807488 100644 --- a/drivers/gpu/drm/i915/gvt/page_track.c +++ b/drivers/gpu/drm/i915/gvt/page_track.c @@ -167,7 +167,7 @@ int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa, return -ENXIO; if (unlikely(vgpu->failsafe)) { - /* Remove write protection to prevent furture traps. */ + /* Remove write protection to prevent future traps. */ intel_gvt_page_track_remove(vgpu, gpa >> PAGE_SHIFT); } else { ret = page_track->handler(page_track, gpa, data, bytes); diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index a5c8005ec484..23f2cc397ec9 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -1052,7 +1052,7 @@ void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu, struct intel_vgpu_workload *pos, *n; intel_engine_mask_t tmp; - /* free the unsubmited workloads in the queues. */ + /* free the unsubmitted workloads in the queues. */ for_each_engine_masked(engine, vgpu->gvt->gt, engine_mask, tmp) { list_for_each_entry_safe(pos, n, &s->workload_q_head[engine->id], list) { From cb9c2913de481dd02de19023fceabf0814fc9515 Mon Sep 17 00:00:00 2001 From: Yan Zhen Date: Fri, 13 Sep 2024 14:17:27 +0800 Subject: [PATCH 054/205] drm/i915/display: fix typo in the comment Correctly spelled comments make it easier for the reader to understand the code. Replace 'platformas' with 'platforms' in the comment & replace 'prefere' with 'prefer' in the comment & replace 'corresponsding' with 'corresponding' in the comment & replace 'harizontal' with 'horizontal' in the comment. Signed-off-by: Yan Zhen Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240913061727.170198-1-yanzhen@vivo.com --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll.c | 2 +- drivers/gpu/drm/i915/display/intel_lvds.c | 2 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 8caacdd624bd..86403a9318b0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -426,7 +426,7 @@ static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc) int num_scalers = crtc->num_scalers; int i; - /* Not all platformas have a scaler */ + /* Not all platforms have a scaler */ if (num_scalers) { seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d scaling_filter=%d", num_scalers, diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index bc72d1c0cb41..38e34b72bc4e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -780,7 +780,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, max_n = limit->n.max; /* based on hardware requirement, prefer smaller n to precision */ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { - /* based on hardware requirement, prefere larger m1,m2 */ + /* based on hardware requirement, prefer larger m1,m2 */ for (clock.m1 = limit->m1.max; clock.m1 >= limit->m1.min; clock.m1--) { for (clock.m2 = limit->m2.max; diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 1734b12ddf5e..5f753ee743c6 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -264,7 +264,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, temp |= LVDS_PIPE_SEL(pipe); } - /* set the corresponsding LVDS_BORDER bit */ + /* set the corresponding LVDS_BORDER bit */ temp &= ~LVDS_BORDER_ENABLE; temp |= crtc_state->gmch_pfit.lvds_border_bits; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index f19660064525..32d15bd9a358 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -1072,7 +1072,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, hsync = intel_de_read(display, MIPI_HSYNC_PADDING_COUNT(display, port)); hbp = intel_de_read(display, MIPI_HBP_COUNT(display, port)); - /* harizontal values are in terms of high speed byte clock */ + /* horizontal values are in terms of high speed byte clock */ hfp = pixels_from_txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio); hsync = pixels_from_txbyteclkhs(hsync, bpp, lane_count, From 7e046d747fb5f9a22e35a04cac60fa6612ffc7b3 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 12 Sep 2024 13:25:37 -0400 Subject: [PATCH 055/205] drm/i915/irq: Remove duplicated irq_enabled variable Let's kill this legacy iand almost unused rq_enabled version in favor of the real one that is checked at intel_irqs_enabled(). The commit 'ac1723c16b66 ("drm/i915: Track IRQ state in local device state")' shows that this was a legacy DRM level irq_enabled information that got removed. But the driver one already existed under a different name. Cc: Jani Nikula Reviewed-by: Jonathan Cavitt Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240912172539.418957-1-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_irq.c | 8 ++------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 39f6614a0a99..aa3000349116 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -343,8 +343,6 @@ struct drm_i915_private { struct intel_pxp *pxp; - bool irq_enabled; - struct i915_pmu pmu; /* The TTM device structure. */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2321de48d169..9f1a6f692dd1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1406,14 +1406,12 @@ int intel_irq_install(struct drm_i915_private *dev_priv) */ dev_priv->runtime_pm.irqs_enabled = true; - dev_priv->irq_enabled = true; - intel_irq_reset(dev_priv); ret = request_irq(irq, intel_irq_handler(dev_priv), IRQF_SHARED, DRIVER_NAME, dev_priv); if (ret < 0) { - dev_priv->irq_enabled = false; + dev_priv->runtime_pm.irqs_enabled = false; return ret; } @@ -1439,11 +1437,9 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) * intel_display_driver_remove() calling us out of sequence. * Would be nice if it didn't do that... */ - if (!dev_priv->irq_enabled) + if (!dev_priv->runtime_pm.irqs_enabled) return; - dev_priv->irq_enabled = false; - intel_irq_reset(dev_priv); free_irq(irq, dev_priv); From acc7a9b2b96123fe27c73ac637d8da58ddc09904 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 12 Sep 2024 13:25:38 -0400 Subject: [PATCH 056/205] drm/i915/irq: Move irqs_enabled out of runtime_pm This information is used in many places and it doesn't have anything to do with runtime_pm directly. Let's move it to the driver, where it belongs. Reviewed-by: Jonathan Cavitt Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240912172539.418957-2-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 14 +++++++------- drivers/gpu/drm/i915/intel_runtime_pm.h | 1 - 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aa3000349116..def3ca135406 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -234,6 +234,7 @@ struct drm_i915_private { /* protects the irq masks */ spinlock_t irq_lock; + bool irqs_enabled; /* Sideband mailbox protection */ struct mutex sb_lock; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9f1a6f692dd1..2c0fdb5e05a6 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1404,14 +1404,14 @@ int intel_irq_install(struct drm_i915_private *dev_priv) * interrupts as enabled _before_ actually enabling them to avoid * special cases in our ordering checks. */ - dev_priv->runtime_pm.irqs_enabled = true; + dev_priv->irqs_enabled = true; intel_irq_reset(dev_priv); ret = request_irq(irq, intel_irq_handler(dev_priv), IRQF_SHARED, DRIVER_NAME, dev_priv); if (ret < 0) { - dev_priv->runtime_pm.irqs_enabled = false; + dev_priv->irqs_enabled = false; return ret; } @@ -1437,7 +1437,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) * intel_display_driver_remove() calling us out of sequence. * Would be nice if it didn't do that... */ - if (!dev_priv->runtime_pm.irqs_enabled) + if (!dev_priv->irqs_enabled) return; intel_irq_reset(dev_priv); @@ -1445,7 +1445,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) free_irq(irq, dev_priv); intel_hpd_cancel_work(dev_priv); - dev_priv->runtime_pm.irqs_enabled = false; + dev_priv->irqs_enabled = false; } /** @@ -1458,7 +1458,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) { intel_irq_reset(dev_priv); - dev_priv->runtime_pm.irqs_enabled = false; + dev_priv->irqs_enabled = false; intel_synchronize_irq(dev_priv); } @@ -1471,14 +1471,14 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) { - dev_priv->runtime_pm.irqs_enabled = true; + dev_priv->irqs_enabled = true; intel_irq_reset(dev_priv); intel_irq_postinstall(dev_priv); } bool intel_irqs_enabled(struct drm_i915_private *dev_priv) { - return dev_priv->runtime_pm.irqs_enabled; + return dev_priv->irqs_enabled; } void intel_synchronize_irq(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index de3579d399e1..796a2dcb307e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -42,7 +42,6 @@ struct intel_runtime_pm { atomic_t wakeref_count; struct device *kdev; /* points to i915->drm.dev */ bool available; - bool irqs_enabled; bool no_wakeref_tracking; /* From 3de5774cb8c0638aee9d5f0431561666515a3875 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 12 Sep 2024 13:25:39 -0400 Subject: [PATCH 057/205] drm/i915/irq: Rename suspend/resume functions Although these functions are used in runtime_pm, they are not exclusively used there, so remove the misleading prefix. Reviewed-by: Jonathan Cavitt Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20240912172539.418957-3-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/intel_reset.c | 4 ++-- drivers/gpu/drm/i915/i915_driver.c | 12 +++++------ drivers/gpu/drm/i915/i915_irq.c | 30 +++++++++++++-------------- drivers/gpu/drm/i915/i915_irq.h | 4 ++-- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 8f1ea95471ef..f42f21632306 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1233,7 +1233,7 @@ void intel_gt_reset(struct intel_gt *gt, } if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) - intel_runtime_pm_disable_interrupts(gt->i915); + intel_irq_suspend(gt->i915); if (do_reset(gt, stalled_mask)) { gt_err(gt, "Failed to reset chip\n"); @@ -1241,7 +1241,7 @@ void intel_gt_reset(struct intel_gt *gt, } if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) - intel_runtime_pm_enable_interrupts(gt->i915); + intel_irq_resume(gt->i915); intel_overlay_reset(gt->i915); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 943e938040c0..f82aa313f854 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -950,7 +950,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_dp_mst_suspend(i915); - intel_runtime_pm_disable_interrupts(i915); + intel_irq_suspend(i915); intel_hpd_cancel_work(i915); if (HAS_DISPLAY(i915)) @@ -1035,7 +1035,7 @@ static int i915_drm_suspend(struct drm_device *dev) intel_dp_mst_suspend(dev_priv); - intel_runtime_pm_disable_interrupts(dev_priv); + intel_irq_suspend(dev_priv); intel_hpd_cancel_work(dev_priv); if (HAS_DISPLAY(dev_priv)) @@ -1181,7 +1181,7 @@ static int i915_drm_resume(struct drm_device *dev) * Modeset enabling in intel_display_driver_init_hw() also needs working * interrupts. */ - intel_runtime_pm_enable_interrupts(dev_priv); + intel_irq_resume(dev_priv); if (HAS_DISPLAY(dev_priv)) drm_mode_config_reset(dev); @@ -1481,7 +1481,7 @@ static int intel_runtime_suspend(struct device *kdev) for_each_gt(gt, dev_priv, i) intel_gt_runtime_suspend(gt); - intel_runtime_pm_disable_interrupts(dev_priv); + intel_irq_suspend(dev_priv); for_each_gt(gt, dev_priv, i) intel_uncore_suspend(gt->uncore); @@ -1494,7 +1494,7 @@ static int intel_runtime_suspend(struct device *kdev) "Runtime suspend failed, disabling it (%d)\n", ret); intel_uncore_runtime_resume(&dev_priv->uncore); - intel_runtime_pm_enable_interrupts(dev_priv); + intel_irq_resume(dev_priv); for_each_gt(gt, dev_priv, i) intel_gt_runtime_resume(gt); @@ -1587,7 +1587,7 @@ static int intel_runtime_resume(struct device *kdev) for_each_gt(gt, dev_priv, i) intel_uncore_runtime_resume(gt->uncore); - intel_runtime_pm_enable_interrupts(dev_priv); + intel_irq_resume(dev_priv); /* * No point of rolling back things in case of an error, as the best diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2c0fdb5e05a6..d42997fdee65 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1449,31 +1449,29 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) } /** - * intel_runtime_pm_disable_interrupts - runtime interrupt disabling - * @dev_priv: i915 device instance + * intel_irq_suspend - Suspend interrupts + * @i915: i915 device instance * - * This function is used to disable interrupts at runtime, both in the runtime - * pm and the system suspend/resume code. + * This function is used to disable interrupts at runtime. */ -void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) +void intel_irq_suspend(struct drm_i915_private *i915) { - intel_irq_reset(dev_priv); - dev_priv->irqs_enabled = false; - intel_synchronize_irq(dev_priv); + intel_irq_reset(i915); + i915->irqs_enabled = false; + intel_synchronize_irq(i915); } /** - * intel_runtime_pm_enable_interrupts - runtime interrupt enabling - * @dev_priv: i915 device instance + * intel_irq_resume - Resume interrupts + * @i915: i915 device instance * - * This function is used to enable interrupts at runtime, both in the runtime - * pm and the system suspend/resume code. + * This function is used to enable interrupts at runtime. */ -void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) +void intel_irq_resume(struct drm_i915_private *i915) { - dev_priv->irqs_enabled = true; - intel_irq_reset(dev_priv); - intel_irq_postinstall(dev_priv); + i915->irqs_enabled = true; + intel_irq_reset(i915); + intel_irq_postinstall(i915); } bool intel_irqs_enabled(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h index e665a1b007dc..cde4cac5eca2 100644 --- a/drivers/gpu/drm/i915/i915_irq.h +++ b/drivers/gpu/drm/i915/i915_irq.h @@ -34,8 +34,8 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv); void gen6_rps_reset_ei(struct drm_i915_private *dev_priv); u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915, u32 mask); -void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); -void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); +void intel_irq_suspend(struct drm_i915_private *i915); +void intel_irq_resume(struct drm_i915_private *i915); bool intel_irqs_enabled(struct drm_i915_private *dev_priv); void intel_synchronize_irq(struct drm_i915_private *i915); void intel_synchronize_hardirq(struct drm_i915_private *i915); From 367941734f299ce03aa2ea3d5238374394736f35 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Sep 2024 16:54:38 +0300 Subject: [PATCH 058/205] drm/i915: move intel_get_pipe_from_crtc_id_ioctl to intel_crtc.c Reduce the size of and dependencies on intel_display.[ch], and move intel_get_pipe_from_crtc_id_ioctl() to intel_crtc.[ch]. Rename to intel_crtc_get_pipe_from_crtc_id_ioctl() while at it. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/edcf4477e6f38cc1f36a8afc0d09fd98544803ab.1726235647.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_crtc.c | 17 +++++++++++++++++ drivers/gpu/drm/i915/display/intel_crtc.h | 4 ++++ drivers/gpu/drm/i915/display/intel_display.c | 17 ----------------- drivers/gpu/drm/i915/display/intel_display.h | 3 --- drivers/gpu/drm/i915/i915_driver.c | 4 ++-- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index aed3853952be..f95d169fc324 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -389,6 +389,23 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) return ret; } +int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; + struct drm_crtc *drm_crtc; + struct intel_crtc *crtc; + + drm_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id); + if (!drm_crtc) + return -ENOENT; + + crtc = to_intel_crtc(drm_crtc); + pipe_from_crtc_id->pipe = crtc->pipe; + + return 0; +} + static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state) { return crtc_state->hw.active && diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index 0de8c772df2e..a58ecd11bba2 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -10,7 +10,9 @@ enum i9xx_plane_id; enum pipe; +struct drm_device; struct drm_display_mode; +struct drm_file; struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; @@ -32,6 +34,8 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state); u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state); int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe); +int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc); void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d4a371edfcdd..426074afef43 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7709,23 +7709,6 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } -int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; - struct drm_crtc *drmmode_crtc; - struct intel_crtc *crtc; - - drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id); - if (!drmmode_crtc) - return -ENOENT; - - crtc = to_intel_crtc(drmmode_crtc); - pipe_from_crtc_id->pipe = crtc->pipe; - - return 0; -} - static u32 intel_encoder_possible_clones(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 7ca26e5cb20e..d10608526eee 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -471,9 +471,6 @@ bool intel_encoder_is_snps(struct intel_encoder *encoder); bool intel_encoder_is_tc(struct intel_encoder *encoder); enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder); -int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - int ilk_get_lanes_required(int target_clock, int link_bw, int bpp); void vlv_wait_port_ready(struct drm_i915_private *dev_priv, struct intel_digital_port *dig_port, diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index f82aa313f854..3bf6482b60b0 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -48,8 +48,8 @@ #include "display/intel_acpi.h" #include "display/intel_bw.h" #include "display/intel_cdclk.h" +#include "display/intel_crtc.h" #include "display/intel_display_driver.h" -#include "display/intel_display.h" #include "display/intel_dmc.h" #include "display/intel_dp.h" #include "display/intel_dpt.h" @@ -1724,7 +1724,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id_ioctl, 0), + DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_crtc_get_pipe_from_crtc_id_ioctl, 0), DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER), DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER), From cb1c998401529466ae16b0a6a81d8d297375917e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Sep 2024 16:54:39 +0300 Subject: [PATCH 059/205] drm/i915/display: move enum i9xx_plane_id to intel_display_limits.h Move enum i9xx_plane_id from intel_display.h to intel_display_limits.h to be able to reduce dependencies on intel_display.h. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/1e8f9768f2d638dfa1fc72f80f0d7391c4a48bbb.1726235647.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.h | 10 ---------- drivers/gpu/drm/i915/display/intel_display_limits.h | 10 ++++++++++ drivers/gpu/drm/i915/gvt/cmd_parser.c | 1 - 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index d10608526eee..4bdb48084cab 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -95,16 +95,6 @@ static inline bool transcoder_is_dsi(enum transcoder transcoder) return transcoder == TRANSCODER_DSI_A || transcoder == TRANSCODER_DSI_C; } -/* - * Global legacy plane identifier. Valid only for primary/sprite - * planes on pre-g4x, and only for primary planes on g4x-bdw. - */ -enum i9xx_plane_id { - PLANE_A, - PLANE_B, - PLANE_C, -}; - #define plane_name(p) ((p) + 'A') #define for_each_plane_id_on_crtc(__crtc, __p) \ diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.h b/drivers/gpu/drm/i915/display/intel_display_limits.h index c4775c99dc83..f0fa27e365ab 100644 --- a/drivers/gpu/drm/i915/display/intel_display_limits.h +++ b/drivers/gpu/drm/i915/display/intel_display_limits.h @@ -49,6 +49,16 @@ enum transcoder { I915_MAX_TRANSCODERS }; +/* + * Global legacy plane identifier. Valid only for primary/sprite + * planes on pre-g4x, and only for primary planes on g4x-bdw. + */ +enum i9xx_plane_id { + PLANE_A, + PLANE_B, + PLANE_C, +}; + /* * Per-pipe plane identifier. * I915_MAX_PLANES in the enum below is the maximum (across all platforms) diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 2f4c9c66b40b..81d67a46cd9e 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -50,7 +50,6 @@ #include "trace.h" #include "display/i9xx_plane_regs.h" -#include "display/intel_display.h" #include "display/intel_sprite_regs.h" #include "gem/i915_gem_context.h" #include "gem/i915_gem_pm.h" From 7ab8f42b8c4c142ccc05864966b0d3538ed47ff6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 16 Sep 2024 16:47:20 +0300 Subject: [PATCH 060/205] drm/i915: add i9xx_display_irq_reset() Add common i9xx_display_irq_reset() for display 2-4. The check for I915_HAS_HOTPLUG() covers all the alternatives. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20240916134720.501725-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_irq.c | 13 ++++++++++++- drivers/gpu/drm/i915/display/intel_display_irq.h | 2 +- drivers/gpu/drm/i915/i915_irq.c | 15 +++------------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 8f13f148c73e..b830756124c3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -405,7 +405,7 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, res1, res2); } -void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) +static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) { enum pipe pipe; @@ -1466,6 +1466,17 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv) dev_priv->irq_mask = ~0u; } +void i9xx_display_irq_reset(struct drm_i915_private *i915) +{ + if (I915_HAS_HOTPLUG(i915)) { + i915_hotplug_interrupt_update(i915, 0xffffffff, 0); + intel_uncore_rmw(&i915->uncore, + PORT_HOTPLUG_STAT(i915), 0, 0); + } + + i9xx_pipestat_irq_reset(i915); +} + void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 2a090dd6abd7..093e356a2894 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -54,6 +54,7 @@ void gen11_display_irq_handler(struct drm_i915_private *i915); u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl); void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir); +void i9xx_display_irq_reset(struct drm_i915_private *i915); void vlv_display_irq_reset(struct drm_i915_private *i915); void gen8_display_irq_reset(struct drm_i915_private *i915); void gen11_display_irq_reset(struct drm_i915_private *i915); @@ -68,7 +69,6 @@ u32 i915_pipestat_enable_mask(struct drm_i915_private *i915, enum pipe pipe); void i915_enable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); void i915_disable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); void i915_enable_asle_pipestat(struct drm_i915_private *i915); -void i9xx_pipestat_irq_reset(struct drm_i915_private *i915); void i9xx_pipestat_irq_ack(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d42997fdee65..723d1334fdbb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -849,7 +849,7 @@ static void i8xx_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; - i9xx_pipestat_irq_reset(dev_priv); + i9xx_display_irq_reset(dev_priv); gen2_irq_reset(uncore); dev_priv->irq_mask = ~0u; @@ -1037,13 +1037,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; - if (I915_HAS_HOTPLUG(dev_priv)) { - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - intel_uncore_rmw(&dev_priv->uncore, - PORT_HOTPLUG_STAT(dev_priv), 0, 0); - } - - i9xx_pipestat_irq_reset(dev_priv); + i9xx_display_irq_reset(dev_priv); GEN3_IRQ_RESET(uncore, GEN2_); dev_priv->irq_mask = ~0u; @@ -1148,10 +1142,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; - i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT(dev_priv), 0, 0); - - i9xx_pipestat_irq_reset(dev_priv); + i9xx_display_irq_reset(dev_priv); GEN3_IRQ_RESET(uncore, GEN2_); dev_priv->irq_mask = ~0u; From 0b7e9ddb9ab2965025a809b3299394e3151ed75f Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 16 Sep 2024 12:19:37 -0400 Subject: [PATCH 061/205] drm/i915/irq: Uninstall should be called just once There shouldn't be any path where the irq uninstall is called twice nowadays. So, remove the FIXME commend and change the check to a WARN. Suggested-by: Jani Nikula Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240916161937.537334-1-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_irq.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 723d1334fdbb..a784803f709a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1422,13 +1422,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) { int irq = to_pci_dev(dev_priv->drm.dev)->irq; - /* - * FIXME we can get called twice during driver probe - * error handling as well as during driver remove due to - * intel_display_driver_remove() calling us out of sequence. - * Would be nice if it didn't do that... - */ - if (!dev_priv->irqs_enabled) + if (drm_WARN_ON(&dev_priv->drm, !dev_priv->irqs_enabled)) return; intel_irq_reset(dev_priv); From eb920fbbb4c84ffe60124412754491f397640d1f Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 16 Sep 2024 15:58:33 +0530 Subject: [PATCH 062/205] drm/i915/display: Simplify intel_joiner_num_pipes and its usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently intel_joiner_num_pipes is used to get num of pipes wrt num of pipes joined. Simplify this by returning 1 when no joiner is used and update the checks for no joiner case. v2: Rename the function to intel_crtc_num_joined_pipes and use helper intel_crtc_joined_pipe_mask. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916102836.2149012-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 426074afef43..da79a4522530 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -278,9 +278,9 @@ bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state) crtc->pipe == joiner_primary_pipe(crtc_state); } -static int intel_joiner_num_pipes(const struct intel_crtc_state *crtc_state) +static int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state) { - return hweight8(crtc_state->joiner_pipes); + return hweight8(intel_crtc_joined_pipe_mask(crtc_state)); } u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state) @@ -2347,9 +2347,9 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state) static void intel_joiner_adjust_timings(const struct intel_crtc_state *crtc_state, struct drm_display_mode *mode) { - int num_pipes = intel_joiner_num_pipes(crtc_state); + int num_pipes = intel_crtc_num_joined_pipes(crtc_state); - if (num_pipes < 2) + if (num_pipes == 1) return; mode->crtc_clock /= num_pipes; @@ -2411,7 +2411,7 @@ static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state drm_mode_copy(mode, pipe_mode); intel_mode_from_crtc_timings(mode, mode); mode->hdisplay = drm_rect_width(&crtc_state->pipe_src) * - (intel_joiner_num_pipes(crtc_state) ?: 1); + intel_crtc_num_joined_pipes(crtc_state); mode->vdisplay = drm_rect_height(&crtc_state->pipe_src); /* Derive per-pipe timings in case joiner is used */ @@ -2431,10 +2431,10 @@ void intel_encoder_get_config(struct intel_encoder *encoder, static void intel_joiner_compute_pipe_src(struct intel_crtc_state *crtc_state) { - int num_pipes = intel_joiner_num_pipes(crtc_state); + int num_pipes = intel_crtc_num_joined_pipes(crtc_state); int width, height; - if (num_pipes < 2) + if (num_pipes == 1) return; width = drm_rect_width(&crtc_state->pipe_src); @@ -2891,11 +2891,11 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - int num_pipes = intel_joiner_num_pipes(crtc_state); + int num_pipes = intel_crtc_num_joined_pipes(crtc_state); enum pipe primary_pipe, pipe = crtc->pipe; int width; - if (num_pipes < 2) + if (num_pipes == 1) return; primary_pipe = joiner_primary_pipe(crtc_state); From d095681373440cc4dda8aee9f9c3152a2396b4d4 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 16 Sep 2024 15:58:34 +0530 Subject: [PATCH 063/205] drm/i915/display: Use joined pipes in intel_dp_joiner_needs_dsc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of ultrajoiner, use number of joined pipes in the intel_dp_joiner_needs_dsc helper, instead of joiner flag. v2: Use intel_crtc_num_joined_pipes. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916102836.2149012-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_display.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 16 ++++++++++++---- drivers/gpu/drm/i915/display/intel_dp.h | 3 ++- drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 ++++++++-- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index da79a4522530..0e2dddfdddf3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -278,7 +278,7 @@ bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state) crtc->pipe == joiner_primary_pipe(crtc_state); } -static int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state) +int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state) { return hweight8(intel_crtc_joined_pipe_mask(crtc_state)); } diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 4bdb48084cab..06c26db3e272 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -574,5 +574,6 @@ bool assert_port_valid(struct drm_i915_private *i915, enum port port); }) bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915); +int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state); #endif diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index dd281eb7c4bf..221f78c1c299 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1318,6 +1318,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, u8 dsc_slice_count = 0; enum drm_mode_status status; bool dsc = false, joiner = false; + int num_joined_pipes; status = intel_cpu_transcoder_mode_valid(dev_priv, mode); if (status != MODE_OK) @@ -1343,6 +1344,9 @@ intel_dp_mode_valid(struct drm_connector *_connector, joiner = true; max_dotclk *= 2; } + + num_joined_pipes = joiner ? 2 : 1; + if (target_clock > max_dotclk) return MODE_CLOCK_HIGH; @@ -1399,7 +1403,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, dsc = dsc_max_compressed_bpp && dsc_slice_count; } - if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc) + if (intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes) && !dsc) return MODE_CLOCK_HIGH; if (mode_rate > max_rate && !dsc) @@ -2513,14 +2517,15 @@ int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state) return intel_dp_link_required(adjusted_mode->crtc_clock, bpp); } -bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner) +bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, + int num_joined_pipes) { /* * Pipe joiner needs compression up to display 12 due to bandwidth * limitation. DG2 onwards pipe joiner can be enabled without * compression. */ - return !HAS_UNCOMPRESSED_JOINER(i915) && use_joiner; + return !HAS_UNCOMPRESSED_JOINER(i915) && num_joined_pipes == 2; } static int @@ -2538,6 +2543,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct link_config_limits limits; bool dsc_needed, joiner_needs_dsc; + int num_joined_pipes; int ret = 0; if (pipe_config->fec_enable && @@ -2549,7 +2555,9 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock)) pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe); - joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, pipe_config->joiner_pipes); + num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); + + joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || !intel_dp_compute_config_limits(intel_dp, pipe_config, diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 1b9aaddd8c35..3aef57dd463a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -123,7 +123,8 @@ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16, int bw_overhead); int intel_dp_max_link_data_rate(struct intel_dp *intel_dp, int max_dprx_rate, int max_dprx_lanes); -bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner); +bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, + int num_joined_pipes); bool intel_dp_has_joiner(struct intel_dp *intel_dp); bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 15541932b809..8600ac55f766 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -568,6 +568,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, &pipe_config->hw.adjusted_mode; struct link_config_limits limits; bool dsc_needed, joiner_needs_dsc; + int num_joined_pipes; int ret = 0; if (pipe_config->fec_enable && @@ -582,11 +583,13 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock)) pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe); + num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); + pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, pipe_config->joiner_pipes); + joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || !intel_dp_mst_compute_config_limits(intel_dp, @@ -1426,6 +1429,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, u16 dsc_max_compressed_bpp = 0; u8 dsc_slice_count = 0; int target_clock = mode->clock; + int num_joined_pipes; if (drm_connector_is_unregistered(connector)) { *status = MODE_ERROR; @@ -1471,6 +1475,8 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, max_dotclk *= 2; } + num_joined_pipes = joiner ? 2 : 1; + ret = drm_modeset_lock(&mgr->base.lock, ctx); if (ret) return ret; @@ -1508,7 +1514,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, dsc = dsc_max_compressed_bpp && dsc_slice_count; } - if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc) { + if (intel_dp_joiner_needs_dsc(dev_priv, num_joined_pipes) && !dsc) { *status = MODE_CLOCK_HIGH; return 0; } From f87bdbd66de4a16069525825387e25dae3e0163e Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 16 Sep 2024 15:58:35 +0530 Subject: [PATCH 064/205] drm/i915/display: Use joined pipes in intel_mode_valid_max_plane_size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of ultrajoiner, use number of pipes in the intel_mode_valid_max_plane_size helper, instead of joiner flag. v2: Use num_joined_pipes 1 where there are no joined pipes (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916102836.2149012-4-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- drivers/gpu/drm/i915/display/intel_dsi.c | 2 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 0e2dddfdddf3..886abed1783b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8076,7 +8076,7 @@ enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *de enum drm_mode_status intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, const struct drm_display_mode *mode, - bool joiner) + int num_joined_pipes) { int plane_width_max, plane_height_max; @@ -8093,7 +8093,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, * too big for that. */ if (DISPLAY_VER(dev_priv) >= 11) { - plane_width_max = 5120 << joiner; + plane_width_max = 5120 * num_joined_pipes; plane_height_max = 4320; } else { plane_width_max = 5120; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 06c26db3e272..e48461410632 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -406,7 +406,7 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, enum drm_mode_status intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, const struct drm_display_mode *mode, - bool joiner); + int num_joined_pipes); enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915, const struct drm_display_mode *mode); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 221f78c1c299..79d7c70c3239 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1413,7 +1413,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, if (status != MODE_OK) return status; - return intel_mode_valid_max_plane_size(dev_priv, mode, joiner); + return intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes); } bool intel_dp_source_supports_tps3(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 8600ac55f766..1b94dfe9499a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1524,7 +1524,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, return 0; } - *status = intel_mode_valid_max_plane_size(dev_priv, mode, joiner); + *status = intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index bd5888ce4852..0be46c6c9611 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -76,7 +76,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, if (fixed_mode->clock > max_dotclk) return MODE_CLOCK_HIGH; - return intel_mode_valid_max_plane_size(dev_priv, mode, false); + return intel_mode_valid_max_plane_size(dev_priv, mode, 1); } struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 869fa00f7ef2..72ac910bf6ec 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2057,7 +2057,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector, return status; } - return intel_mode_valid_max_plane_size(dev_priv, mode, false); + return intel_mode_valid_max_plane_size(dev_priv, mode, 1); } bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, From f2e2092a979cd46b43445daf23628015ac776ac3 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 16 Sep 2024 15:58:36 +0530 Subject: [PATCH 065/205] drm/i915/display: Use joined pipes in dsc helpers for slices, bpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of ultrajoiner, use number of joined pipes in the dsc helpers to compute dsc slices and max compressed bpp, instead of using the joiner flag. v2: Adjust the formulae to use num of pipes as 1 (no joiner) or 2 (bigjoiner). (Ankit) Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal (v1) Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916102836.2149012-5-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 24 +++++++++++---------- drivers/gpu/drm/i915/display/intel_dp.h | 4 ++-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 8 ++++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 79d7c70c3239..19f78432cc8f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -868,14 +868,14 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p static u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915, u32 mode_clock, u32 mode_hdisplay, - bool bigjoiner) + int num_joined_pipes) { u32 max_bpp_small_joiner_ram; /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / mode_hdisplay; - if (bigjoiner) { + if (num_joined_pipes == 2) { int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24; /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ int ppc = 2; @@ -894,7 +894,7 @@ u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915, u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, u32 link_clock, u32 lane_count, u32 mode_clock, u32 mode_hdisplay, - bool bigjoiner, + int num_joined_pipes, enum intel_output_format output_format, u32 pipe_bpp, u32 timeslots) @@ -940,7 +940,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, intel_dp_mode_to_fec_clock(mode_clock)); joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock, - mode_hdisplay, bigjoiner); + mode_hdisplay, num_joined_pipes); bits_per_pixel = min(bits_per_pixel, joiner_max_bpp); bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp); @@ -950,7 +950,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, int mode_clock, int mode_hdisplay, - bool bigjoiner) + int num_joined_pipes) { struct drm_i915_private *i915 = to_i915(connector->base.dev); u8 min_slice_count, i; @@ -984,14 +984,14 @@ u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, /* Find the closest match to the valid slice count values */ for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) { - u8 test_slice_count = valid_dsc_slicecount[i] << bigjoiner; + u8 test_slice_count = valid_dsc_slicecount[i] * num_joined_pipes; if (test_slice_count > drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, false)) break; /* big joiner needs small joiner to be enabled */ - if (bigjoiner && test_slice_count < 4) + if (num_joined_pipes == 2 && test_slice_count < 4) continue; if (min_slice_count <= test_slice_count) @@ -1390,14 +1390,14 @@ intel_dp_mode_valid(struct drm_connector *_connector, max_lanes, target_clock, mode->hdisplay, - joiner, + num_joined_pipes, output_format, pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(connector, target_clock, mode->hdisplay, - joiner); + num_joined_pipes); } dsc = dsc_max_compressed_bpp && dsc_slice_count; @@ -2113,6 +2113,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; int dsc_joiner_max_bpp; + int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); dsc_src_min_bpp = dsc_src_min_compressed_bpp(); dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config); @@ -2127,7 +2128,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, adjusted_mode->clock, adjusted_mode->hdisplay, - pipe_config->joiner_pipes); + num_joined_pipes); dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp); dsc_max_bpp = min(dsc_max_bpp, fxp_q4_to_int(limits->link.max_bpp_x16)); @@ -2312,6 +2313,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; + int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); int ret; /* @@ -2367,7 +2369,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, intel_dp_dsc_get_slice_count(connector, adjusted_mode->crtc_clock, adjusted_mode->crtc_hdisplay, - pipe_config->joiner_pipes); + num_joined_pipes); if (!dsc_dp_slice_count) { drm_dbg_kms(&dev_priv->drm, "Compressed Slice Count not supported\n"); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 3aef57dd463a..a0a31fb64716 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -143,7 +143,7 @@ int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, u32 link_clock, u32 lane_count, u32 mode_clock, u32 mode_hdisplay, - bool bigjoiner, + int num_joined_pipes, enum intel_output_format output_format, u32 pipe_bpp, u32 timeslots); @@ -153,7 +153,7 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector int bpc); u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, int mode_clock, int mode_hdisplay, - bool bigjoiner); + int num_joined_pipes); bool intel_dp_need_joiner(struct intel_dp *intel_dp, struct intel_connector *connector, int hdisplay, int clock); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 1b94dfe9499a..dc050da29815 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -102,11 +102,13 @@ static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; if (dsc) { + int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state); + flags |= DRM_DP_BW_OVERHEAD_DSC; dsc_slice_count = intel_dp_dsc_get_slice_count(connector, adjusted_mode->clock, adjusted_mode->hdisplay, - crtc_state->joiner_pipes); + num_joined_pipes); } overhead = drm_dp_bw_overhead(crtc_state->lane_count, @@ -1501,14 +1503,14 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, max_lanes, target_clock, mode->hdisplay, - joiner, + num_joined_pipes, INTEL_OUTPUT_FORMAT_RGB, pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_connector, target_clock, mode->hdisplay, - joiner); + num_joined_pipes); } dsc = dsc_max_compressed_bpp && dsc_slice_count; From 2478e2234d7d0196138fa2be3e5e538eae3ff888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Mon, 16 Sep 2024 11:57:06 +0300 Subject: [PATCH 066/205] drm/i915/psr: eDP Panel Replay is not supported on pipes other than A and B MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not allow Panel Replay if pipe is other than A or B. Bspec: 68920 Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2736 Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20240916085706.2160511-1-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 4f29ac32ff85..5ed446f1e3ba 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1601,6 +1601,10 @@ _panel_replay_compute_config(struct intel_dp *intel_dp, /* Remaining checks are for eDP only */ + if (to_intel_crtc(crtc_state->uapi.crtc)->pipe != PIPE_A && + to_intel_crtc(crtc_state->uapi.crtc)->pipe != PIPE_B) + return false; + /* 128b/132b Panel Replay is not supported on eDP */ if (intel_dp_is_uhbr(crtc_state)) { drm_dbg_kms(display->drm, From 52c4abeec6fd40f492dead85beb2652719f479c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 11 Sep 2024 18:18:36 +0300 Subject: [PATCH 067/205] drm/i915/psr: Fix PSR sink enable sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the eDP spec, the source must first configure all PSR related DPCD registers apart from the actual enable bit, and only then set the enable bit. Split the current single DPCD write to two to match the spec. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240911151836.16800-1-ville.syrjala@linux.intel.com Reviewed-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_psr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 5ed446f1e3ba..5b355d0a3565 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -764,7 +764,7 @@ static void _psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(intel_dp); - u8 val = DP_PSR_ENABLE; + u8 val = 0; if (crtc_state->has_sel_update) { val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS; @@ -784,7 +784,9 @@ static void _psr_enable_sink(struct intel_dp *intel_dp, if (intel_dp->psr.entry_setup_frames > 0) val |= DP_PSR_FRAME_CAPTURE; + drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val); + val |= DP_PSR_ENABLE; drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val); } From 0f9f8b0fb1865bf87b5fb2aa93ad519aa8f64fd8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:41 +0300 Subject: [PATCH 068/205] drm/i915/pps: add vlv_ prefix to pps_pipe and active_pipe members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pps_pipe and active_pipe members of struct intel_pps are only relevant on VLV/CHV. Prefix them with vlv_. Note that there are still a few cases where they're accessed on non-VLV/CHV paths. We'll fix them separately. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/0e9a8998fc37796eb6f32692977859807222ce0a.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 4 +- .../drm/i915/display/intel_display_types.h | 4 +- drivers/gpu/drm/i915/display/intel_dp.c | 8 +- drivers/gpu/drm/i915/display/intel_pps.c | 82 +++++++++---------- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 526c8c4d7b53..1699fbbb56c9 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -481,7 +481,7 @@ intel_dp_link_down(struct intel_encoder *encoder, intel_wakeref_t wakeref; with_intel_pps_lock(intel_dp, wakeref) - intel_dp->pps.active_pipe = INVALID_PIPE; + intel_dp->pps.vlv_active_pipe = INVALID_PIPE; } } @@ -1277,7 +1277,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder) intel_wakeref_t wakeref; with_intel_pps_lock(intel_dp, wakeref) - intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); + intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); } intel_pps_encoder_reset(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 000ab373c887..d6616408df86 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1539,7 +1539,7 @@ struct intel_pps { * Pipe whose power sequencer is currently locked into * this port. Only relevant on VLV/CHV. */ - enum pipe pps_pipe; + enum pipe vlv_pps_pipe; /* * Power sequencer index. Only relevant on BXT+. @@ -1552,7 +1552,7 @@ struct intel_pps { * the use of the PPS for any pipe currentrly driving * external DP as that will mess things up on VLV. */ - enum pipe active_pipe; + enum pipe vlv_active_pipe; /* * Set if the sequencer may be reset due to a power transition, * requiring a reinitialization. Only relevant on BXT+. diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 19f78432cc8f..9dd86523012f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6638,7 +6638,7 @@ static void intel_edp_backlight_setup(struct intel_dp *intel_dp, pipe = vlv_active_pipe(intel_dp); if (pipe != PIPE_A && pipe != PIPE_B) - pipe = intel_dp->pps.pps_pipe; + pipe = intel_dp->pps.vlv_pps_pipe; if (pipe != PIPE_A && pipe != PIPE_B) pipe = PIPE_A; @@ -6867,8 +6867,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, return false; intel_dp->reset_link_params = true; - intel_dp->pps.pps_pipe = INVALID_PIPE; - intel_dp->pps.active_pipe = INVALID_PIPE; + intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; + intel_dp->pps.vlv_active_pipe = INVALID_PIPE; /* Preserve the current hw state. */ intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg); @@ -6896,7 +6896,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, intel_dp_set_default_max_sink_lane_count(intel_dp); if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); + intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); intel_dp_aux_init(intel_dp); intel_connector->dp.dsc_decompression_aux = &intel_dp->aux; diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index cdbac9f5a14c..b7c73842ea16 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -33,7 +33,7 @@ static const char *pps_name(struct intel_dp *intel_dp) struct intel_pps *pps = &intel_dp->pps; if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { - switch (pps->pps_pipe) { + switch (pps->vlv_pps_pipe) { case INVALID_PIPE: /* * FIXME would be nice if we can guarantee @@ -45,7 +45,7 @@ static const char *pps_name(struct intel_dp *intel_dp) case PIPE_B: return "PPS B"; default: - MISSING_CASE(pps->pps_pipe); + MISSING_CASE(pps->vlv_pps_pipe); break; } } else { @@ -96,7 +96,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) struct intel_display *display = to_intel_display(intel_dp); struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - enum pipe pipe = intel_dp->pps.pps_pipe; + enum pipe pipe = intel_dp->pps.vlv_pps_pipe; bool pll_enabled, release_cl_override = false; enum dpio_phy phy = vlv_pipe_to_phy(pipe); enum dpio_channel ch = vlv_pipe_to_channel(pipe); @@ -182,18 +182,18 @@ static enum pipe vlv_find_free_pps(struct intel_display *display) if (encoder->type == INTEL_OUTPUT_EDP) { drm_WARN_ON(display->drm, - intel_dp->pps.active_pipe != INVALID_PIPE && - intel_dp->pps.active_pipe != - intel_dp->pps.pps_pipe); + intel_dp->pps.vlv_active_pipe != INVALID_PIPE && + intel_dp->pps.vlv_active_pipe != + intel_dp->pps.vlv_pps_pipe); - if (intel_dp->pps.pps_pipe != INVALID_PIPE) - pipes &= ~(1 << intel_dp->pps.pps_pipe); + if (intel_dp->pps.vlv_pps_pipe != INVALID_PIPE) + pipes &= ~(1 << intel_dp->pps.vlv_pps_pipe); } else { drm_WARN_ON(display->drm, - intel_dp->pps.pps_pipe != INVALID_PIPE); + intel_dp->pps.vlv_pps_pipe != INVALID_PIPE); - if (intel_dp->pps.active_pipe != INVALID_PIPE) - pipes &= ~(1 << intel_dp->pps.active_pipe); + if (intel_dp->pps.vlv_active_pipe != INVALID_PIPE) + pipes &= ~(1 << intel_dp->pps.vlv_active_pipe); } } @@ -215,11 +215,11 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) /* We should never land here with regular DP ports */ drm_WARN_ON(display->drm, !intel_dp_is_edp(intel_dp)); - drm_WARN_ON(display->drm, intel_dp->pps.active_pipe != INVALID_PIPE && - intel_dp->pps.active_pipe != intel_dp->pps.pps_pipe); + drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE && + intel_dp->pps.vlv_active_pipe != intel_dp->pps.vlv_pps_pipe); - if (intel_dp->pps.pps_pipe != INVALID_PIPE) - return intel_dp->pps.pps_pipe; + if (intel_dp->pps.vlv_pps_pipe != INVALID_PIPE) + return intel_dp->pps.vlv_pps_pipe; pipe = vlv_find_free_pps(display); @@ -231,7 +231,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) pipe = PIPE_A; vlv_steal_power_sequencer(display, pipe); - intel_dp->pps.pps_pipe = pipe; + intel_dp->pps.vlv_pps_pipe = pipe; drm_dbg_kms(display->drm, "picked %s for [ENCODER:%d:%s]\n", @@ -248,7 +248,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) */ vlv_power_sequencer_kick(intel_dp); - return intel_dp->pps.pps_pipe; + return intel_dp->pps.vlv_pps_pipe; } static int @@ -327,19 +327,19 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) /* try to find a pipe with this port selected */ /* first pick one where the panel is on */ - intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(display, port, - pps_has_pp_on); + intel_dp->pps.vlv_pps_pipe = vlv_initial_pps_pipe(display, port, + pps_has_pp_on); /* didn't find one? pick one where vdd is on */ - if (intel_dp->pps.pps_pipe == INVALID_PIPE) - intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(display, port, - pps_has_vdd_on); + if (intel_dp->pps.vlv_pps_pipe == INVALID_PIPE) + intel_dp->pps.vlv_pps_pipe = vlv_initial_pps_pipe(display, port, + pps_has_vdd_on); /* didn't find one? pick one with just the correct port */ - if (intel_dp->pps.pps_pipe == INVALID_PIPE) - intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(display, port, - pps_any); + if (intel_dp->pps.vlv_pps_pipe == INVALID_PIPE) + intel_dp->pps.vlv_pps_pipe = vlv_initial_pps_pipe(display, port, + pps_any); /* didn't find one? just let vlv_power_sequencer_pipe() pick one when needed */ - if (intel_dp->pps.pps_pipe == INVALID_PIPE) { + if (intel_dp->pps.vlv_pps_pipe == INVALID_PIPE) { drm_dbg_kms(display->drm, "[ENCODER:%d:%s] no initial power sequencer\n", dig_port->base.base.base.id, dig_port->base.base.name); @@ -462,7 +462,7 @@ void intel_pps_reset_all(struct intel_display *display) /* * We can't grab pps_mutex here due to deadlock with power_domain * mutex when power_domain functions are called while holding pps_mutex. - * That also means that in order to use pps_pipe the code needs to + * That also means that in order to use vlv_pps_pipe the code needs to * hold both a power domain reference and pps_mutex, and the power domain * reference get/put must be done while _not_ holding pps_mutex. * pps_{lock,unlock}() do these steps in the correct order, so one @@ -473,7 +473,7 @@ void intel_pps_reset_all(struct intel_display *display) struct intel_dp *intel_dp = enc_to_intel_dp(encoder); drm_WARN_ON(display->drm, - intel_dp->pps.active_pipe != INVALID_PIPE); + intel_dp->pps.vlv_active_pipe != INVALID_PIPE); if (encoder->type != INTEL_OUTPUT_EDP) continue; @@ -481,7 +481,7 @@ void intel_pps_reset_all(struct intel_display *display) if (DISPLAY_VER(display) >= 9) intel_dp->pps.pps_reset = true; else - intel_dp->pps.pps_pipe = INVALID_PIPE; + intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; } } @@ -550,7 +550,7 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp) lockdep_assert_held(&display->pps.mutex); if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && - intel_dp->pps.pps_pipe == INVALID_PIPE) + intel_dp->pps.vlv_pps_pipe == INVALID_PIPE) return false; return (intel_de_read(display, _pp_stat_reg(intel_dp)) & PP_ON) != 0; @@ -564,7 +564,7 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp) lockdep_assert_held(&display->pps.mutex); if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && - intel_dp->pps.pps_pipe == INVALID_PIPE) + intel_dp->pps.vlv_pps_pipe == INVALID_PIPE) return false; return intel_de_read(display, _pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD; @@ -1153,10 +1153,10 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - enum pipe pipe = intel_dp->pps.pps_pipe; + enum pipe pipe = intel_dp->pps.vlv_pps_pipe; i915_reg_t pp_on_reg = PP_ON_DELAYS(display, pipe); - drm_WARN_ON(display->drm, intel_dp->pps.active_pipe != INVALID_PIPE); + drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE); if (drm_WARN_ON(display->drm, pipe != PIPE_A && pipe != PIPE_B)) return; @@ -1179,7 +1179,7 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp) intel_de_write(display, pp_on_reg, 0); intel_de_posting_read(display, pp_on_reg); - intel_dp->pps.pps_pipe = INVALID_PIPE; + intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; } static void vlv_steal_power_sequencer(struct intel_display *display, @@ -1192,12 +1192,12 @@ static void vlv_steal_power_sequencer(struct intel_display *display, for_each_intel_dp(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - drm_WARN(display->drm, intel_dp->pps.active_pipe == pipe, + drm_WARN(display->drm, intel_dp->pps.vlv_active_pipe == pipe, "stealing PPS %c from active [ENCODER:%d:%s]\n", pipe_name(pipe), encoder->base.base.id, encoder->base.name); - if (intel_dp->pps.pps_pipe != pipe) + if (intel_dp->pps.vlv_pps_pipe != pipe) continue; drm_dbg_kms(display->drm, @@ -1219,10 +1219,10 @@ void vlv_pps_init(struct intel_encoder *encoder, lockdep_assert_held(&display->pps.mutex); - drm_WARN_ON(display->drm, intel_dp->pps.active_pipe != INVALID_PIPE); + drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE); - if (intel_dp->pps.pps_pipe != INVALID_PIPE && - intel_dp->pps.pps_pipe != crtc->pipe) { + if (intel_dp->pps.vlv_pps_pipe != INVALID_PIPE && + intel_dp->pps.vlv_pps_pipe != crtc->pipe) { /* * If another power sequencer was being used on this * port previously make sure to turn off vdd there while @@ -1237,13 +1237,13 @@ void vlv_pps_init(struct intel_encoder *encoder, */ vlv_steal_power_sequencer(display, crtc->pipe); - intel_dp->pps.active_pipe = crtc->pipe; + intel_dp->pps.vlv_active_pipe = crtc->pipe; if (!intel_dp_is_edp(intel_dp)) return; /* now it's all ours */ - intel_dp->pps.pps_pipe = crtc->pipe; + intel_dp->pps.vlv_pps_pipe = crtc->pipe; drm_dbg_kms(display->drm, "initializing %s for [ENCODER:%d:%s]\n", From 66bdc6a61e679ac182c7ae998ad06ba0c47c0a59 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:42 +0300 Subject: [PATCH 069/205] drm/i915/pps: add bxt_ prefix to pps_reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pps_reset member of struct intel_pps is only relevant on BXT/GLK. Prefix it with bxt_. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/7d4552f555936be44fae27ca101007746fcff8c2.1726681620.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_pps.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index d6616408df86..3e694c1204db 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1557,7 +1557,7 @@ struct intel_pps { * Set if the sequencer may be reset due to a power transition, * requiring a reinitialization. Only relevant on BXT+. */ - bool pps_reset; + bool bxt_pps_reset; struct edp_power_seq pps_delays; struct edp_power_seq bios_pps_delays; }; diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index b7c73842ea16..2d8d911988ab 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -262,10 +262,10 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp) /* We should never land here with regular DP ports */ drm_WARN_ON(display->drm, !intel_dp_is_edp(intel_dp)); - if (!intel_dp->pps.pps_reset) + if (!intel_dp->pps.bxt_pps_reset) return pps_idx; - intel_dp->pps.pps_reset = false; + intel_dp->pps.bxt_pps_reset = false; /* * Only the HW needs to be reprogrammed, the SW state is fixed and @@ -479,7 +479,7 @@ void intel_pps_reset_all(struct intel_display *display) continue; if (DISPLAY_VER(display) >= 9) - intel_dp->pps.pps_reset = true; + intel_dp->pps.bxt_pps_reset = true; else intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; } From 254b109d65e53f58ec1926047868aa3a285c7e0a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:43 +0300 Subject: [PATCH 070/205] drm/i915/pps: only touch the vlv_ members on VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the struct intel_pps vlv_pps_pipe and vlv_active_pipe members are only relevant for VLV/CHV, we still initialize them on all platforms and check them on BXT/GLK. Wrap all access inside VLV/CHV checks for consistency. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/158c7b30e56d22aa3f9c9e51e87b9d89687d74d5.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 6 +++--- drivers/gpu/drm/i915/display/intel_pps.c | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9dd86523012f..9f908dbd45ea 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6867,8 +6867,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, return false; intel_dp->reset_link_params = true; - intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; - intel_dp->pps.vlv_active_pipe = INVALID_PIPE; /* Preserve the current hw state. */ intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg); @@ -6895,8 +6893,10 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, intel_dp_set_default_sink_rates(intel_dp); intel_dp_set_default_max_sink_lane_count(intel_dp); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); + } intel_dp_aux_init(intel_dp); intel_connector->dp.dsc_decompression_aux = &intel_dp->aux; diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 2d8d911988ab..649dc6ad2278 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -472,16 +472,17 @@ void intel_pps_reset_all(struct intel_display *display) for_each_intel_dp(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - drm_WARN_ON(display->drm, - intel_dp->pps.vlv_active_pipe != INVALID_PIPE); + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + drm_WARN_ON(display->drm, + intel_dp->pps.vlv_active_pipe != INVALID_PIPE); if (encoder->type != INTEL_OUTPUT_EDP) continue; - if (DISPLAY_VER(display) >= 9) - intel_dp->pps.bxt_pps_reset = true; - else + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; + else + intel_dp->pps.bxt_pps_reset = true; } } From 888b5dce567d0c998ae4d8dec06086dff13a3cd5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:44 +0300 Subject: [PATCH 071/205] drm/i915/pps: add vlv_pps_pipe_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to track PPS also for non-eDP usage on VLV/CHV. Add new vlv_pps_pipe_init() for initializing the related parts, hiding the PPS pipe details inside PPS code. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/2829a5bab5e9a4dcddc3a2bb87e12559000543ea.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 6 ++---- drivers/gpu/drm/i915/display/intel_pps.c | 7 +++++++ drivers/gpu/drm/i915/display/intel_pps.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9f908dbd45ea..12706f24a36d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6893,10 +6893,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, intel_dp_set_default_sink_rates(intel_dp); intel_dp_set_default_max_sink_lane_count(intel_dp); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; - intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); - } + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + vlv_pps_pipe_init(intel_dp); intel_dp_aux_init(intel_dp); intel_connector->dp.dsc_decompression_aux = &intel_dp->aux; diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 649dc6ad2278..5957e79186f0 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1211,6 +1211,13 @@ static void vlv_steal_power_sequencer(struct intel_display *display, } } +/* Call on all DP, not just eDP */ +void vlv_pps_pipe_init(struct intel_dp *intel_dp) +{ + intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; + intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); +} + void vlv_pps_init(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index 0c5da83a559e..5686e900e7de 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -45,6 +45,7 @@ void intel_pps_init_late(struct intel_dp *intel_dp); void intel_pps_encoder_reset(struct intel_dp *intel_dp); void intel_pps_reset_all(struct intel_display *display); +void vlv_pps_pipe_init(struct intel_dp *intel_dp); void vlv_pps_init(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); From 1afd9b4c6de4503cb02a446500cfc76b4be57d2a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:45 +0300 Subject: [PATCH 072/205] drm/i915/pps: add vlv_pps_pipe_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to track PPS also for non-eDP usage on VLV/CHV. Add new vlv_pps_pipe_reset() for resetting the related parts, hiding the PPS pipe details inside PPS code. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/e1bae913533baea8e502d8c63c06f6852a1cdb93.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 8 ++------ drivers/gpu/drm/i915/display/intel_pps.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_pps.h | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 1699fbbb56c9..edbd654757e2 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1273,12 +1273,8 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder) intel_dp->reset_link_params = true; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - intel_wakeref_t wakeref; - - with_intel_pps_lock(intel_dp, wakeref) - intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); - } + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + vlv_pps_pipe_reset(intel_dp); intel_pps_encoder_reset(intel_dp); } diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 5957e79186f0..e4b17bd5efb5 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1218,6 +1218,15 @@ void vlv_pps_pipe_init(struct intel_dp *intel_dp) intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); } +/* Call on all DP, not just eDP */ +void vlv_pps_pipe_reset(struct intel_dp *intel_dp) +{ + intel_wakeref_t wakeref; + + with_intel_pps_lock(intel_dp, wakeref) + intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); +} + void vlv_pps_init(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index 5686e900e7de..6509768cd55f 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -46,6 +46,7 @@ void intel_pps_encoder_reset(struct intel_dp *intel_dp); void intel_pps_reset_all(struct intel_display *display); void vlv_pps_pipe_init(struct intel_dp *intel_dp); +void vlv_pps_pipe_reset(struct intel_dp *intel_dp); void vlv_pps_init(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); From 696e909e543ffba3615f13ec5568525e166805ec Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:46 +0300 Subject: [PATCH 073/205] drm/i915/pps: add vlv_pps_port_disable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add vlv_pps_port_disable() and move the VLV/CHV active pipe clear there from intel_dp_link_down(), hiding the PPS pipe details inside PPS code. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/2546716a448205ca5af085cec9faeb5e5deac287.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 8 ++------ drivers/gpu/drm/i915/display/intel_pps.c | 12 ++++++++++++ drivers/gpu/drm/i915/display/intel_pps.h | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index edbd654757e2..e3db1cba11c9 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -477,12 +477,8 @@ intel_dp_link_down(struct intel_encoder *encoder, msleep(intel_dp->pps.panel_power_down_delay); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - intel_wakeref_t wakeref; - - with_intel_pps_lock(intel_dp, wakeref) - intel_dp->pps.vlv_active_pipe = INVALID_PIPE; - } + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + vlv_pps_port_disable(encoder, old_crtc_state); } static void g4x_dp_audio_enable(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index e4b17bd5efb5..465a555c9e24 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1272,6 +1272,18 @@ void vlv_pps_init(struct intel_encoder *encoder, pps_init_registers(intel_dp, true); } +/* Call on all DP, not just eDP */ +void vlv_pps_port_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + intel_wakeref_t wakeref; + + with_intel_pps_lock(intel_dp, wakeref) + intel_dp->pps.vlv_active_pipe = INVALID_PIPE; +} + static void pps_vdd_init(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index 6509768cd55f..795e25c91952 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -49,6 +49,8 @@ void vlv_pps_pipe_init(struct intel_dp *intel_dp); void vlv_pps_pipe_reset(struct intel_dp *intel_dp); void vlv_pps_init(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); +void vlv_pps_port_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); void intel_pps_unlock_regs_wa(struct intel_display *display); void intel_pps_setup(struct intel_display *display); From 75e57145a12f299b0daa2e44399d66f2d7c58f62 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:47 +0300 Subject: [PATCH 074/205] drm/i915/pps: rename vlv_pps_init() to vlv_pps_port_enable_unlocked() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the naming for vlv_pps_port_disable(), as these are counterparts, and add _unlocked suffix as it assumes the pps lock is held. v2: Add _unlocked suffix (Ville) Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/3b21141025a5e1e67f28bbe67a82a7008fd3f415.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_pps.c | 5 +++-- drivers/gpu/drm/i915/display/intel_pps.h | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index e3db1cba11c9..162802c54d4b 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -690,7 +690,7 @@ static void intel_enable_dp(struct intel_atomic_state *state, with_intel_pps_lock(intel_dp, wakeref) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - vlv_pps_init(encoder, pipe_config); + vlv_pps_port_enable_unlocked(encoder, pipe_config); intel_dp_enable_port(intel_dp, pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 465a555c9e24..63bae4c3a71a 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1227,8 +1227,9 @@ void vlv_pps_pipe_reset(struct intel_dp *intel_dp) intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); } -void vlv_pps_init(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +/* Call on all DP, not just eDP */ +void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index 795e25c91952..5b3eb7fb7e1f 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -47,8 +47,8 @@ void intel_pps_reset_all(struct intel_display *display); void vlv_pps_pipe_init(struct intel_dp *intel_dp); void vlv_pps_pipe_reset(struct intel_dp *intel_dp); -void vlv_pps_init(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state); +void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); void vlv_pps_port_disable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); From 3ac6d358124a104c4409f1aa79aec62e5537b736 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:48 +0300 Subject: [PATCH 075/205] drm/i915/pps: add vlv_pps_backlight_initial_pipe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add vlv_pps_backlight_initial_pipe() and move the VLV/CHV initial backlight pipe logic there, hiding the PPS pipe details inside PPS code. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/b0587f183d8bb06679a75b04f956762435d10181.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 16 ++-------------- drivers/gpu/drm/i915/display/intel_pps.c | 20 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_pps.h | 1 + 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 12706f24a36d..9859a7d3ce80 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6629,20 +6629,8 @@ static void intel_edp_backlight_setup(struct intel_dp *intel_dp, struct drm_i915_private *i915 = dp_to_i915(intel_dp); enum pipe pipe = INVALID_PIPE; - if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { - /* - * Figure out the current pipe for the initial backlight setup. - * If the current pipe isn't valid, try the PPS pipe, and if that - * fails just assume pipe A. - */ - pipe = vlv_active_pipe(intel_dp); - - if (pipe != PIPE_A && pipe != PIPE_B) - pipe = intel_dp->pps.vlv_pps_pipe; - - if (pipe != PIPE_A && pipe != PIPE_B) - pipe = PIPE_A; - } + if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) + pipe = vlv_pps_backlight_initial_pipe(intel_dp); intel_backlight_setup(connector, pipe); } diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 63bae4c3a71a..9cb091e7c94a 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1227,6 +1227,26 @@ void vlv_pps_pipe_reset(struct intel_dp *intel_dp) intel_dp->pps.vlv_active_pipe = vlv_active_pipe(intel_dp); } +enum pipe vlv_pps_backlight_initial_pipe(struct intel_dp *intel_dp) +{ + enum pipe pipe; + + /* + * Figure out the current pipe for the initial backlight setup. If the + * current pipe isn't valid, try the PPS pipe, and if that fails just + * assume pipe A. + */ + pipe = vlv_active_pipe(intel_dp); + + if (pipe != PIPE_A && pipe != PIPE_B) + pipe = intel_dp->pps.vlv_pps_pipe; + + if (pipe != PIPE_A && pipe != PIPE_B) + pipe = PIPE_A; + + return pipe; +} + /* Call on all DP, not just eDP */ void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index 5b3eb7fb7e1f..a5339a65485d 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -47,6 +47,7 @@ void intel_pps_reset_all(struct intel_display *display); void vlv_pps_pipe_init(struct intel_dp *intel_dp); void vlv_pps_pipe_reset(struct intel_dp *intel_dp); +enum pipe vlv_pps_backlight_initial_pipe(struct intel_dp *intel_dp); void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void vlv_pps_port_disable(struct intel_encoder *encoder, From 46f6a34a7926078ea07b69f4d59abd68c835a4df Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:47:49 +0300 Subject: [PATCH 076/205] drm/i915/pps: move vlv_active_pipe() to intel_pps.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the users for vlv_active_pipe() are within intel_pps.c now, and there are already uses of g4x_dp_port_enabled() and intel_dp->output_reg in there, so seems fine to reduce interfaces and move vlv_active_pipe() to intel_pps.c too. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/e12ae0a931f113f3bbbf1b4c66108b572a933efb.1726681620.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 14 -------------- drivers/gpu/drm/i915/display/g4x_dp.h | 5 ----- drivers/gpu/drm/i915/display/intel_pps.c | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 162802c54d4b..040478048b97 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1245,20 +1245,6 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) kfree(enc_to_dig_port(to_intel_encoder(encoder))); } -enum pipe vlv_active_pipe(struct intel_dp *intel_dp) -{ - struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - enum pipe pipe; - - if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg, - encoder->port, &pipe)) - return pipe; - - return INVALID_PIPE; -} - static void intel_dp_encoder_reset(struct drm_encoder *encoder) { struct intel_display *display = to_intel_display(encoder->dev); diff --git a/drivers/gpu/drm/i915/display/g4x_dp.h b/drivers/gpu/drm/i915/display/g4x_dp.h index a10638ab749c..c75e64ae79b7 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.h +++ b/drivers/gpu/drm/i915/display/g4x_dp.h @@ -19,7 +19,6 @@ struct intel_encoder; #ifdef I915 const struct dpll *vlv_get_dpll(struct drm_i915_private *i915); -enum pipe vlv_active_pipe(struct intel_dp *intel_dp); void g4x_dp_set_clock(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config); bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv, @@ -32,10 +31,6 @@ static inline const struct dpll *vlv_get_dpll(struct drm_i915_private *i915) { return NULL; } -static inline int vlv_active_pipe(struct intel_dp *intel_dp) -{ - return 0; -} static inline void g4x_dp_set_clock(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 9cb091e7c94a..819b2843946f 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1211,6 +1211,20 @@ static void vlv_steal_power_sequencer(struct intel_display *display, } } +static enum pipe vlv_active_pipe(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + enum pipe pipe; + + if (g4x_dp_port_enabled(dev_priv, intel_dp->output_reg, + encoder->port, &pipe)) + return pipe; + + return INVALID_PIPE; +} + /* Call on all DP, not just eDP */ void vlv_pps_pipe_init(struct intel_dp *intel_dp) { From 9988e6b33517b94da3c968783327341b10a98430 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Sep 2024 15:51:54 +0300 Subject: [PATCH 077/205] drm/i915/debugfs: remove superfluous kernel_param_lock/unlock We're not actually accessing the module params here anymore. The locking is completely unnecessary. Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/330360c3b27aaff1cdb132f1500ba68de9300508.1726231866.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_debugfs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 246fece628d6..b5fc7cc8020a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -76,10 +76,8 @@ static int i915_capabilities(struct seq_file *m, void *data) intel_gt_info_print(&to_gt(i915)->info, &p); intel_driver_caps_print(&i915->caps, &p); - kernel_param_lock(THIS_MODULE); i915_params_dump(&i915->params, &p); intel_display_params_dump(&display->params, display->drm->driver->name, &p); - kernel_param_unlock(THIS_MODULE); return 0; } From 5428eaa00af08c6279ea13041ea7ddb73e250636 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Sep 2024 15:51:55 +0300 Subject: [PATCH 078/205] drm/i915/debugfs: add dedicated intel_display_caps debugfs for display Add dedicated intel_display_caps for display, with device info and params. Intentionally prefix the file intel_ instead of i915_. Going forward, we should do the same for all debugfs files, making them independent of i915 and xe. Remove display param dumping from i915 specific i915_capabilities debugfs. Note that we don't add node_to_intel_display() functionality in to_intel_display(). It's too specific for that. Reviewed-by: Luca Coelho Link: https://patchwork.freedesktop.org/patch/msgid/1b825b893dd2d423da167a7b6b21d05e8cd0182c.1726231866.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_debugfs.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/i915_debugfs.c | 4 ---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 86403a9318b0..1b68be92e9e0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -41,11 +41,28 @@ #include "intel_vdsc.h" #include "intel_wm.h" +static struct intel_display *node_to_intel_display(struct drm_info_node *node) +{ + return to_intel_display(node->minor->dev); +} + static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) { return to_i915(node->minor->dev); } +static int intel_display_caps(struct seq_file *m, void *data) +{ + struct intel_display *display = node_to_intel_display(m->private); + struct drm_printer p = drm_seq_file_printer(m); + + intel_display_device_info_print(DISPLAY_INFO(display), + DISPLAY_RUNTIME_INFO(display), &p); + intel_display_params_dump(&display->params, display->drm->driver->name, &p); + + return 0; +} + static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1027,6 +1044,7 @@ static const struct file_operations i915_fifo_underrun_reset_ops = { }; static const struct drm_info_list intel_display_debugfs_list[] = { + {"intel_display_caps", intel_display_caps, 0}, {"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0}, {"i915_sr_status", i915_sr_status, 0}, {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b5fc7cc8020a..1c2a97f593c7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -33,8 +33,6 @@ #include #include -#include "display/intel_display_params.h" - #include "gem/i915_gem_context.h" #include "gt/intel_gt.h" #include "gt/intel_gt_buffer_pool.h" @@ -66,7 +64,6 @@ static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) static int i915_capabilities(struct seq_file *m, void *data) { struct drm_i915_private *i915 = node_to_i915(m->private); - struct intel_display *display = &i915->display; struct drm_printer p = drm_seq_file_printer(m); seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915)); @@ -77,7 +74,6 @@ static int i915_capabilities(struct seq_file *m, void *data) intel_driver_caps_print(&i915->caps, &p); i915_params_dump(&i915->params, &p); - intel_display_params_dump(&display->params, display->drm->driver->name, &p); return 0; } From 0644d2be99cd044e8c78e7a1ee781c622b60917c Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Wed, 18 Sep 2024 12:00:15 +0530 Subject: [PATCH 079/205] drm/i915: Add some essential functionality for joiners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In most of the cases we now try to avoid mentioning things like "bigjoiner" or "ultrajoiner" trying to unify the API and refer mostly to all this functionality as "joiner". In majority cases that should be way to go. However in some cases we still need to distinguish between bigjoiner primaries and secondaries(such as DSC register programming). Create correspondent helper functions and start using them, in order be prepared for adding ultrajoiner functionality. v2: Fixed checkpatch warnings (Ankit) v3: Introduce ultrajoiner helpers in next patch. v4: Streamline the helpers and add few more. (Ville) v5: Add comment to clarify that helpers apply to both bigjoiner and uncompressed joiner configurations. (Ville) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918063016.2667721-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 45 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_display.h | 2 + drivers/gpu/drm/i915/display/intel_vdsc.c | 4 +- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 886abed1783b..9f108d5e00ef 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -254,6 +254,51 @@ static enum pipe joiner_primary_pipe(const struct intel_crtc_state *crtc_state) return ffs(crtc_state->joiner_pipes) - 1; } +/* + * The following helper functions, despite being named for bigjoiner, + * are applicable to both bigjoiner and uncompressed joiner configurations. + */ +static bool is_bigjoiner(const struct intel_crtc_state *crtc_state) +{ + return hweight8(crtc_state->joiner_pipes) >= 2; +} + +static u8 bigjoiner_primary_pipes(const struct intel_crtc_state *crtc_state) +{ + if (!is_bigjoiner(crtc_state)) + return 0; + + return crtc_state->joiner_pipes & (0b01010101 << joiner_primary_pipe(crtc_state)); +} + +static unsigned int bigjoiner_secondary_pipes(const struct intel_crtc_state *crtc_state) +{ + if (!is_bigjoiner(crtc_state)) + return 0; + + return crtc_state->joiner_pipes & (0b10101010 << joiner_primary_pipe(crtc_state)); +} + +bool intel_crtc_is_bigjoiner_primary(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + if (!is_bigjoiner(crtc_state)) + return false; + + return BIT(crtc->pipe) & bigjoiner_primary_pipes(crtc_state); +} + +bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + if (!is_bigjoiner(crtc_state)) + return false; + + return BIT(crtc->pipe) & bigjoiner_secondary_pipes(crtc_state); +} + u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state) { if (crtc_state->joiner_pipes) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index e48461410632..64ca0f1ae013 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -416,6 +416,8 @@ bool is_trans_port_sync_master(const struct intel_crtc_state *state); u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_joiner_secondary(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state); +bool intel_crtc_is_bigjoiner_primary(const struct intel_crtc_state *crtc_state); +bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state); u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state); struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state); bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 2e849b015e74..8158e3702ed5 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -742,7 +742,7 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state) u32 dss_ctl1_val = 0; if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) { - if (intel_crtc_is_joiner_secondary(crtc_state)) + if (intel_crtc_is_bigjoiner_secondary(crtc_state)) dss_ctl1_val |= UNCOMPRESSED_JOINER_SECONDARY; else dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY; @@ -771,7 +771,7 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state) } if (crtc_state->joiner_pipes) { dss_ctl1_val |= BIG_JOINER_ENABLE; - if (!intel_crtc_is_joiner_secondary(crtc_state)) + if (intel_crtc_is_bigjoiner_primary(crtc_state)) dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE; } intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val); From ae5d0397b7e6a563aeb8708b08cad17390755a8f Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 18 Sep 2024 12:00:16 +0530 Subject: [PATCH 080/205] drm/i915/display: Enhance iterators for modeset en/disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Joiners have specific enabling and disabling order dependent on primary and secondary pipes. This becomes more complex with ultrajoiner where we have ultrajoiner primary/secondary pipes in addition to bigjoiner primary/secondary pipes. To unify the approach that works for present and future joiner cases, use primary and secondary pipe masks to iterate over pipes. If joiner is used, derive bigoiner primary and secondary pipe masks and use following sequences: Disabling : disable primary pipes followed by secondary pipes, Enabling: enable secondary pipes followed by primary pipes. This works well with ultrajoiner too, as ultrajoiner has 2 bigjoiner primary/secondary pairs (AC, BD). For non joiner case, enable/disable based on usual pipe order A-D, D-A respectively. v2: -Simplify the iterator macro. (Ville) -Use struct intel_display. (Ville) -Add prefix _intel to the helper name. (Ville) Signed-off-by: Ankit Nautiyal Suggested-by: Ville Syrjälä Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918063016.2667721-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 14 +++---- drivers/gpu/drm/i915/display/intel_display.c | 40 ++++++++++++-------- drivers/gpu/drm/i915/display/intel_display.h | 26 +++++++++++++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 14 +++---- 4 files changed, 64 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index b1c294236cc8..85e519a21542 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3115,11 +3115,12 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *pipe_crtc; + int i; - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(old_crtc_state)) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -3130,8 +3131,7 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, intel_ddi_disable_transcoder_func(old_crtc_state); - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(old_crtc_state)) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -3382,8 +3382,9 @@ static void intel_enable_ddi(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *pipe_crtc; + int i; intel_ddi_enable_transcoder_func(encoder, crtc_state); @@ -3394,8 +3395,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, intel_ddi_wait_for_fec_status(encoder, crtc_state, true); - for_each_intel_crtc_in_pipe_mask_reverse(&i915->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(crtc_state)) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state, i) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9f108d5e00ef..7cdc12188df9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -299,6 +299,21 @@ bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state return BIT(crtc->pipe) & bigjoiner_secondary_pipes(crtc_state); } +u8 _intel_modeset_primary_pipes(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + if (!is_bigjoiner(crtc_state)) + return BIT(crtc->pipe); + + return bigjoiner_primary_pipes(crtc_state); +} + +u8 _intel_modeset_secondary_pipes(const struct intel_crtc_state *crtc_state) +{ + return bigjoiner_secondary_pipes(crtc_state); +} + u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state) { if (crtc_state->joiner_pipes) @@ -1729,18 +1744,16 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; struct intel_crtc *pipe_crtc; + int i; if (drm_WARN_ON(&dev_priv->drm, crtc->active)) return; - - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(new_crtc_state)) + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) intel_dmc_enable_pipe(display, pipe_crtc->pipe); intel_encoders_pre_pll_enable(state, crtc); - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(new_crtc_state)) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -1750,8 +1763,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_enable(state, crtc); - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(new_crtc_state)) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -1769,8 +1781,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, if (!transcoder_is_dsi(cpu_transcoder)) hsw_configure_cpu_transcoder(new_crtc_state); - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(new_crtc_state)) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -1805,8 +1816,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_encoders_enable(state, crtc); - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(new_crtc_state)) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); enum pipe hsw_workaround_pipe; @@ -1889,10 +1899,10 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; + int i; /* * FIXME collapse everything to one hook. @@ -1901,8 +1911,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_disable(state, crtc); intel_encoders_post_disable(state, crtc); - for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(old_crtc_state)) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -1911,8 +1920,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_pll_disable(state, crtc); - for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(old_crtc_state)) + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) intel_dmc_disable_pipe(display, pipe_crtc->pipe); } diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 64ca0f1ae013..783562dc013b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -392,6 +392,30 @@ enum phy_fia { ((connector) = to_intel_connector((__state)->base.connectors[__i].ptr), \ (new_connector_state) = to_intel_digital_connector_state((__state)->base.connectors[__i].new_state), 1)) +#define for_each_crtc_in_masks(display, crtc, first_pipes, second_pipes, i) \ + for ((i) = 0; \ + (i) < (I915_MAX_PIPES * 2) && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \ + (i)++) \ + for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i)) + +#define for_each_crtc_in_masks_reverse(display, crtc, first_pipes, second_pipes, i) \ + for ((i) = (I915_MAX_PIPES * 2 - 1); \ + (i) >= 0 && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \ + (i)--) \ + for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i)) + +#define for_each_pipe_crtc_modeset_disable(display, crtc, crtc_state, i) \ + for_each_crtc_in_masks(display, crtc, \ + _intel_modeset_primary_pipes(crtc_state), \ + _intel_modeset_secondary_pipes(crtc_state), \ + i) + +#define for_each_pipe_crtc_modeset_enable(display, crtc, crtc_state, i) \ + for_each_crtc_in_masks_reverse(display, crtc, \ + _intel_modeset_primary_pipes(crtc_state), \ + _intel_modeset_secondary_pipes(crtc_state), \ + i) + int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state); int intel_atomic_add_affected_planes(struct intel_atomic_state *state, struct intel_crtc *crtc); @@ -419,6 +443,8 @@ bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_bigjoiner_primary(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state); u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state); +u8 _intel_modeset_primary_pipes(const struct intel_crtc_state *crtc_state); +u8 _intel_modeset_secondary_pipes(const struct intel_crtc_state *crtc_state); struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state); bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state); bool intel_pipe_config_compare(const struct intel_crtc_state *current_config, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index dc050da29815..7debefd4a0d6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -990,6 +990,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); struct intel_digital_port *dig_port = intel_mst->primary; struct intel_dp *intel_dp = &dig_port->dp; @@ -1006,6 +1007,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_crtc *pipe_crtc; bool last_mst_stream; + int i; intel_dp->active_mst_links--; last_mst_stream = intel_dp->active_mst_links == 0; @@ -1013,8 +1015,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, DISPLAY_VER(dev_priv) >= 12 && last_mst_stream && !intel_dp_mst_is_master_trans(old_crtc_state)); - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(old_crtc_state)) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -1038,8 +1039,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, intel_ddi_disable_transcoder_func(old_crtc_state); - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(old_crtc_state)) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -1248,6 +1248,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); struct intel_digital_port *dig_port = intel_mst->primary; struct intel_dp *intel_dp = &dig_port->dp; @@ -1258,7 +1259,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, enum transcoder trans = pipe_config->cpu_transcoder; bool first_mst_stream = intel_dp->active_mst_links == 1; struct intel_crtc *pipe_crtc; - int ret; + int ret, i; drm_WARN_ON(&dev_priv->drm, pipe_config->has_pch_encoder); @@ -1305,8 +1306,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_enable_transcoder(pipe_config); - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, - intel_crtc_joined_pipe_mask(pipe_config)) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config, i) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); From 84d2d0430f0833cdf52a3d051906add051f20ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 18:29:57 +0300 Subject: [PATCH 081/205] drm/i915/color: Extract intel_color_modeset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We always perform the same steps to program color management stuff during a full modeset. Extract that code to a helper to avoid duplication. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916152958.17332-2-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/intel_color.c | 17 ++++++++++ drivers/gpu/drm/i915/display/intel_color.h | 1 + drivers/gpu/drm/i915/display/intel_display.c | 33 +++----------------- 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 5d701f48351b..50f41aeb3c28 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1902,6 +1902,23 @@ void intel_color_post_update(const struct intel_crtc_state *crtc_state) i915->display.funcs.color->color_post_update(crtc_state); } +void intel_color_modeset(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + intel_color_load_luts(crtc_state); + intel_color_commit_noarm(crtc_state); + intel_color_commit_arm(crtc_state); + + if (DISPLAY_VER(display) < 9) { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_plane *plane = to_intel_plane(crtc->base.primary); + + /* update DSPCNTR to configure gamma/csc for pipe bottom color */ + plane->disable_arm(plane, crtc_state); + } +} + void intel_color_prepare_commit(struct intel_atomic_state *state, struct intel_crtc *crtc) { diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h index 79f230a1709a..ab3aaec06a2a 100644 --- a/drivers/gpu/drm/i915/display/intel_color.h +++ b/drivers/gpu/drm/i915/display/intel_color.h @@ -28,6 +28,7 @@ void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state); void intel_color_commit_arm(const struct intel_crtc_state *crtc_state); void intel_color_post_update(const struct intel_crtc_state *crtc_state); void intel_color_load_luts(const struct intel_crtc_state *crtc_state); +void intel_color_modeset(const struct intel_crtc_state *crtc_state); void intel_color_get_config(struct intel_crtc_state *crtc_state); bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state, const struct drm_property_blob *blob1, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7cdc12188df9..d1b889196001 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1563,14 +1563,6 @@ static void intel_encoders_update_pipe(struct intel_atomic_state *state, } } -static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_plane *plane = to_intel_plane(crtc->base.primary); - - plane->disable_arm(plane, crtc_state); -} - static void ilk_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -1636,11 +1628,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_color_load_luts(new_crtc_state); - intel_color_commit_noarm(new_crtc_state); - intel_color_commit_arm(new_crtc_state); - /* update DSPCNTR to configure gamma for pipe bottom color */ - intel_disable_primary_plane(new_crtc_state); + intel_color_modeset(new_crtc_state); intel_initial_watermarks(state, crtc); intel_enable_transcoder(new_crtc_state); @@ -1799,12 +1787,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_color_load_luts(pipe_crtc_state); - intel_color_commit_noarm(pipe_crtc_state); - intel_color_commit_arm(pipe_crtc_state); - /* update DSPCNTR to configure gamma/csc for pipe bottom color */ - if (DISPLAY_VER(dev_priv) < 9) - intel_disable_primary_plane(pipe_crtc_state); + intel_color_modeset(pipe_crtc_state); hsw_set_linetime_wm(pipe_crtc_state); @@ -2203,11 +2186,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, i9xx_pfit_enable(new_crtc_state); - intel_color_load_luts(new_crtc_state); - intel_color_commit_noarm(new_crtc_state); - intel_color_commit_arm(new_crtc_state); - /* update DSPCNTR to configure gamma for pipe bottom color */ - intel_disable_primary_plane(new_crtc_state); + intel_color_modeset(new_crtc_state); intel_initial_watermarks(state, crtc); intel_enable_transcoder(new_crtc_state); @@ -2243,11 +2222,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, i9xx_pfit_enable(new_crtc_state); - intel_color_load_luts(new_crtc_state); - intel_color_commit_noarm(new_crtc_state); - intel_color_commit_arm(new_crtc_state); - /* update DSPCNTR to configure gamma for pipe bottom color */ - intel_disable_primary_plane(new_crtc_state); + intel_color_modeset(new_crtc_state); if (!intel_initial_watermarks(state, crtc)) intel_update_watermarks(dev_priv); From 92699ba9561a032fa3b4a9f5c5dfd24bc9678c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 18:29:58 +0300 Subject: [PATCH 082/205] drm/i915: Extract intel_post_plane_update_after_readout() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up the main commit_tail() codepath a bit by pulling the post plane update steps that need to performed after readout into their own little function (intel_post_plane_update_after_readout()). Declutters intel_atomic_commit_tail() a bit, and should hopefully aid in keeping intel_pre_plane_update() vs. intel_post_plane_update*() in sync. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916152958.17332-3-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/intel_display.c | 25 +++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d1b889196001..eb5cacc9625f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1177,6 +1177,22 @@ static void intel_post_plane_update(struct intel_atomic_state *state, intel_encoders_audio_enable(state, crtc); } +static void intel_post_plane_update_after_readout(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + /* Must be done after gamma readout due to HSW split gamma vs. IPS w/a */ + hsw_ips_post_update(state, crtc); + + /* + * Activate DRRS after state readout to avoid + * dp_m_n vs. dp_m2_n2 confusion on BDW+. + */ + intel_drrs_activate(new_crtc_state); +} + static void intel_crtc_enable_flip_done(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -7532,14 +7548,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_modeset_verify_crtc(state, crtc); - /* Must be done after gamma readout due to HSW split gamma vs. IPS w/a */ - hsw_ips_post_update(state, crtc); - - /* - * Activate DRRS after state readout to avoid - * dp_m_n vs. dp_m2_n2 confusion on BDW+. - */ - intel_drrs_activate(new_crtc_state); + intel_post_plane_update_after_readout(state, crtc); /* * DSB cleanup is done in cleanup_work aligning with framebuffer From 35dba4834bded843d5416e8caadfe82bd0ce1904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 22:04:39 +0300 Subject: [PATCH 083/205] drm/i915/dp: Fix colorimetry detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp_init_connector() is no place for detecting stuff via DPCD (except perhaps for eDP). Move the colorimetry stuff into a more appropriate place. Cc: Jouni Högander Fixes: 00076671a648 ("drm/i915/display: Move colorimetry_support from intel_psr to intel_dp") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918190441.29071-1-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9859a7d3ce80..7008d3624e72 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4082,6 +4082,9 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector drm_dp_is_branch(intel_dp->dpcd)); intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident); + intel_dp->colorimetry_support = + intel_dp_get_colorimetry_status(intel_dp); + /* * Read the eDP display control registers. * @@ -4195,6 +4198,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident); + intel_dp->colorimetry_support = + intel_dp_get_colorimetry_status(intel_dp); + intel_dp_update_sink_caps(intel_dp); } @@ -6932,9 +6938,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, "HDCP init failed, skipping.\n"); } - intel_dp->colorimetry_support = - intel_dp_get_colorimetry_status(intel_dp); - intel_dp->frl.is_trained = false; intel_dp->frl.trained_rate_gbps = 0; From 8d9908e8fe9c4315368d3040fd8ba7f9a0ca0172 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 8 Apr 2024 15:54:44 +0300 Subject: [PATCH 084/205] drm/i915/display: remove small micro-optimizations in irq handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The raw register reads/writes are there as micro-optimizations to avoid multiple pointer indirections on uncore->regs. Presumably this is useful when there are plenty of register reads/writes in the same function. However, the display irq handling only has a few raw reads/writes. Remove them for simplification. Reviewed-by: Radhakrishna Sripada Acked-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240408125445.3227678-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_irq.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index b830756124c3..0ccbf7a1f2bf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1231,15 +1231,14 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) { - void __iomem * const regs = intel_uncore_regs(&i915->uncore); u32 iir; if (!(master_ctl & GEN11_GU_MISC_IRQ)) return 0; - iir = raw_reg_read(regs, GEN11_GU_MISC_IIR); + iir = intel_de_read(i915, GEN11_GU_MISC_IIR); if (likely(iir)) - raw_reg_write(regs, GEN11_GU_MISC_IIR, iir); + intel_de_write(i915, GEN11_GU_MISC_IIR, iir); return iir; } @@ -1254,18 +1253,18 @@ void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir) void gen11_display_irq_handler(struct drm_i915_private *i915) { - void __iomem * const regs = intel_uncore_regs(&i915->uncore); - const u32 disp_ctl = raw_reg_read(regs, GEN11_DISPLAY_INT_CTL); + u32 disp_ctl; disable_rpm_wakeref_asserts(&i915->runtime_pm); /* * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ * for the display related bits. */ - raw_reg_write(regs, GEN11_DISPLAY_INT_CTL, 0x0); + disp_ctl = intel_de_read(i915, GEN11_DISPLAY_INT_CTL); + + intel_de_write(i915, GEN11_DISPLAY_INT_CTL, 0); gen8_de_irq_handler(i915, disp_ctl); - raw_reg_write(regs, GEN11_DISPLAY_INT_CTL, - GEN11_DISPLAY_IRQ_ENABLE); + intel_de_write(i915, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); enable_rpm_wakeref_asserts(&i915->runtime_pm); } From dfecc2952e43ea64a5cca1be438cb8b16b3f7acd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 8 Apr 2024 15:54:45 +0300 Subject: [PATCH 085/205] drm/xe/display: remove compat raw reg read/write support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i915 display code no longer uses these interfaces. Remove them. Reviewed-by: Radhakrishna Sripada Acked-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240408125445.3227678-2-jani.nikula@intel.com --- .../drm/xe/compat-i915-headers/intel_uncore.h | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h index eb5b5f0e4bd9..97afa13ad4ce 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h @@ -155,30 +155,6 @@ static inline void intel_uncore_write_notrace(struct intel_uncore *uncore, xe_mmio_write32(__compat_uncore_to_gt(uncore), reg, val); } -static inline void __iomem *intel_uncore_regs(struct intel_uncore *uncore) -{ - struct xe_device *xe = container_of(uncore, struct xe_device, uncore); - - return xe_device_get_root_tile(xe)->mmio.regs; -} - -/* - * The raw_reg_{read,write} macros are intended as a micro-optimization for - * interrupt handlers so that the pointer indirection on uncore->regs can - * be computed once (and presumably cached in a register) instead of generating - * extra load instructions for each MMIO access. - * - * Given that these macros are only intended for non-GSI interrupt registers - * (and the goal is to avoid extra instructions generated by the compiler), - * these macros do not account for uncore->gsi_offset. Any caller that needs - * to use these macros on a GSI register is responsible for adding the - * appropriate GSI offset to the 'base' parameter. - */ -#define raw_reg_read(base, reg) \ - readl(base + i915_mmio_reg_offset(reg)) -#define raw_reg_write(base, reg, value) \ - writel(value, base + i915_mmio_reg_offset(reg)) - #define intel_uncore_forcewake_get(x, y) do { } while (0) #define intel_uncore_forcewake_put(x, y) do { } while (0) From 17cd58a8f13c7f1ea36e5bf705dc8afc8f6ec946 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:40 +0300 Subject: [PATCH 086/205] drm/i915/display: start a buffer object abstraction layer The display code needs to deal with gem objects, and mostly uses struct drm_i915_gem_object. That's not great, because for xe we need to redefine it struct xe_bo during build. Start a common interface using struct drm_gem_object, with separate implementations for i915 and xe. For starters, convert i9xx_wm.c to use it. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/df6867523a0b5fdd4eb63f657f545603ae6f6e0b.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/i9xx_wm.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_bo.c | 10 ++++++++++ drivers/gpu/drm/i915/display/intel_bo.h | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_fb.c | 5 +++++ drivers/gpu/drm/i915/display/intel_fb.h | 3 +++ drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/intel_bo.c | 12 ++++++++++++ 8 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_bo.c create mode 100644 drivers/gpu/drm/i915/display/intel_bo.h create mode 100644 drivers/gpu/drm/xe/display/intel_bo.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 9fcd9e09bc0b..bb67bad839ea 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -225,6 +225,7 @@ i915-y += \ display/intel_atomic_plane.o \ display/intel_audio.o \ display/intel_bios.o \ + display/intel_bo.o \ display/intel_bw.o \ display/intel_cdclk.o \ display/intel_color.o \ diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 5b21604312fd..5a75d7638aed 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -7,6 +7,7 @@ #include "i915_reg.h" #include "i9xx_wm.h" #include "intel_atomic.h" +#include "intel_bo.h" #include "intel_display.h" #include "intel_display_trace.h" #include "intel_fb.h" @@ -2185,12 +2186,12 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) crtc = single_enabled_crtc(dev_priv); if (IS_I915GM(dev_priv) && crtc) { - struct drm_i915_gem_object *obj; + struct drm_gem_object *obj; - obj = intel_fb_obj(crtc->base.primary->state->fb); + obj = intel_fb_bo(crtc->base.primary->state->fb); /* self-refresh seems busted with untiled */ - if (!i915_gem_object_is_tiled(obj)) + if (!intel_bo_is_tiled(obj)) crtc = NULL; } 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..fede0a545951 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2024 Intel Corporation */ + +#include "gem/i915_gem_object.h" +#include "intel_bo.h" + +bool intel_bo_is_tiled(struct drm_gem_object *obj) +{ + return i915_gem_object_is_tiled(to_intel_bo(obj)); +} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h new file mode 100644 index 000000000000..f5dfcc16d33e --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2024 Intel Corporation */ + +#ifndef __INTEL_BO__ +#define __INTEL_BO__ + +#include + +struct drm_gem_object; + +bool intel_bo_is_tiled(struct drm_gem_object *obj); + +#endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index d2ff21e98545..834a49395638 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2125,3 +2125,8 @@ struct drm_i915_gem_object *intel_fb_obj(const struct drm_framebuffer *fb) { return fb ? to_intel_bo(fb->obj[0]) : NULL; } + +struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb) +{ + return fb ? fb->obj[0] : NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 068f3aee99aa..2ca919bdbd7d 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -12,6 +12,7 @@ struct drm_device; struct drm_file; struct drm_framebuffer; +struct drm_gem_object; struct drm_i915_gem_object; struct drm_i915_private; struct drm_mode_fb_cmd2; @@ -98,4 +99,6 @@ unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier); struct drm_i915_gem_object *intel_fb_obj(const struct drm_framebuffer *fb); +struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb); + #endif /* __INTEL_FB_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index edfd812e0f41..54d41deaebe1 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -165,6 +165,7 @@ $(obj)/i915-display/%.o: $(srctree)/drivers/gpu/drm/i915/display/%.c FORCE xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/ext/i915_irq.o \ display/ext/i915_utils.o \ + display/intel_bo.o \ display/intel_fb_bo.o \ display/intel_fbdev_fb.o \ display/xe_display.o \ diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c new file mode 100644 index 000000000000..d564fb7d85e5 --- /dev/null +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2024 Intel Corporation */ + +#include + +#include "intel_bo.h" + +bool intel_bo_is_tiled(struct drm_gem_object *obj) +{ + /* legacy tiling is unused */ + return false; +} From a1cbdda8ec469fc1c92bce8cf9f7c2cd508a424e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:41 +0300 Subject: [PATCH 087/205] drm/i915/display: convert intel_atomic_plane.c to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/a60e14663f53e921bf228420af0e3d8762d92b82.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 928d985f9985..18c516298e79 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -35,11 +35,11 @@ #include #include -#include #include #include +#include +#include -#include "gem/i915_gem_object_types.h" #include "i915_config.h" #include "i9xx_plane_regs.h" #include "intel_atomic_plane.h" @@ -1115,8 +1115,8 @@ intel_prepare_plane_fb(struct drm_plane *_plane, struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); - struct drm_i915_gem_object *obj = intel_fb_obj(new_plane_state->hw.fb); - struct drm_i915_gem_object *old_obj = intel_fb_obj(old_plane_state->hw.fb); + struct drm_gem_object *obj = intel_fb_bo(new_plane_state->hw.fb); + struct drm_gem_object *old_obj = intel_fb_bo(old_plane_state->hw.fb); int ret; if (old_obj) { @@ -1136,7 +1136,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * can safely continue. */ if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) { - ret = add_dma_resv_fences(intel_bo_to_drm_bo(old_obj)->resv, + ret = add_dma_resv_fences(old_obj->resv, &new_plane_state->uapi); if (ret < 0) return ret; @@ -1196,7 +1196,7 @@ intel_cleanup_plane_fb(struct drm_plane *plane, struct intel_atomic_state *state = to_intel_atomic_state(old_plane_state->uapi.state); struct drm_i915_private *dev_priv = to_i915(plane->dev); - struct drm_i915_gem_object *obj = intel_fb_obj(old_plane_state->hw.fb); + struct drm_gem_object *obj = intel_fb_bo(old_plane_state->hw.fb); if (!obj) return; From 33fd02e4c8f5888efabb0c60908f3575552df2b5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 09:25:14 +0300 Subject: [PATCH 088/205] drm/i915/fb: convert parts of intel_fb.c to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Add new intel_bo_* functions as needed. v2: update comment for intel_bo_is_userptr() (Maarten) Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240918062514.1163290-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bo.c | 10 +++++++++ drivers/gpu/drm/i915/display/intel_bo.h | 2 ++ drivers/gpu/drm/i915/display/intel_fb.c | 29 +++++++++++++------------ drivers/gpu/drm/xe/display/intel_bo.c | 10 +++++++++ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index fede0a545951..5708d9bab1ab 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -8,3 +8,13 @@ bool intel_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) +{ + return i915_gem_object_is_userptr(to_intel_bo(obj)); +} + +void intel_bo_flush_if_display(struct drm_gem_object *obj) +{ + i915_gem_object_flush_if_display(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 f5dfcc16d33e..0fa29211a9d0 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -9,5 +9,7 @@ struct drm_gem_object; bool intel_bo_is_tiled(struct drm_gem_object *obj); +bool intel_bo_is_userptr(struct drm_gem_object *obj); +void intel_bo_flush_if_display(struct drm_gem_object *obj); #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 834a49395638..eb8dc3dd21ee 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -13,6 +13,7 @@ #include "gem/i915_gem_object_types.h" #include "i915_drv.h" #include "intel_atomic_plane.h" +#include "intel_bo.h" #include "intel_display.h" #include "intel_display_types.h" #include "intel_dpt.h" @@ -1225,7 +1226,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state) static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int color_plane, int plane_width, int *x, int *y) { - struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base); + struct drm_gem_object *obj = intel_fb_bo(&fb->base); int ret; ret = intel_fb_offset_to_xy(x, y, &fb->base, color_plane); @@ -1249,7 +1250,7 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co * fb layout agrees with the fence layout. We already check that the * fb stride matches the fence stride elsewhere. */ - if (color_plane == 0 && i915_gem_object_is_tiled(obj) && + if (color_plane == 0 && intel_bo_is_tiled(obj) && (*x + plane_width) * fb->base.format->cpp[color_plane] > fb->base.pitches[color_plane]) { drm_dbg_kms(fb->base.dev, "bad fb plane %d offset: 0x%x\n", @@ -1569,7 +1570,7 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb) int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb) { - struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base); + struct drm_gem_object *obj = intel_fb_bo(&fb->base); u32 gtt_offset_rotated = 0; u32 gtt_offset_remapped = 0; unsigned int max_size = 0; @@ -1642,10 +1643,10 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * max_size = max(max_size, offset + size); } - if (mul_u32_u32(max_size, tile_size) > intel_bo_to_drm_bo(obj)->size) { + if (mul_u32_u32(max_size, tile_size) > obj->size) { drm_dbg_kms(&i915->drm, "fb too big for bo (need %llu bytes, have %zu bytes)\n", - mul_u32_u32(max_size, tile_size), intel_bo_to_drm_bo(obj)->size); + mul_u32_u32(max_size, tile_size), obj->size); return -EINVAL; } @@ -1878,16 +1879,16 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, struct drm_file *file, unsigned int *handle) { - struct drm_i915_gem_object *obj = intel_fb_obj(fb); - struct drm_i915_private *i915 = to_i915(intel_bo_to_drm_bo(obj)->dev); + struct drm_gem_object *obj = intel_fb_bo(fb); + struct intel_display *display = to_intel_display(obj->dev); - if (i915_gem_object_is_userptr(obj)) { - drm_dbg(&i915->drm, + if (intel_bo_is_userptr(obj)) { + drm_dbg(display->drm, "attempting to use a userptr for a framebuffer, denied\n"); return -EINVAL; } - return drm_gem_handle_create(file, intel_bo_to_drm_bo(obj), handle); + return drm_gem_handle_create(file, obj, handle); } struct frontbuffer_fence_cb { @@ -1911,7 +1912,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_clip_rect *clips, unsigned int num_clips) { - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_gem_object *obj = intel_fb_bo(fb); struct intel_frontbuffer *front = to_intel_frontbuffer(fb); struct dma_fence *fence; struct frontbuffer_fence_cb *cb; @@ -1920,10 +1921,10 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, if (!atomic_read(&front->bits)) return 0; - if (dma_resv_test_signaled(intel_bo_to_drm_bo(obj)->resv, dma_resv_usage_rw(false))) + if (dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(false))) goto flush; - ret = dma_resv_get_singleton(intel_bo_to_drm_bo(obj)->resv, dma_resv_usage_rw(false), + ret = dma_resv_get_singleton(obj->resv, dma_resv_usage_rw(false), &fence); if (ret || !fence) goto flush; @@ -1950,7 +1951,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, return ret; flush: - i915_gem_object_flush_if_display(obj); + intel_bo_flush_if_display(obj); intel_frontbuffer_flush(front, ORIGIN_DIRTYFB); return ret; } diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index d564fb7d85e5..23e13cbddb1e 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -10,3 +10,13 @@ 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; +} + +void intel_bo_flush_if_display(struct drm_gem_object *obj) +{ +} From baa46d1bdda2f7ee0b468a9381ff47c9038d5d31 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:43 +0300 Subject: [PATCH 089/205] drm/i915/fbdev: convert intel_fbdev.c to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Add new intel_bo_* functions as needed. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/246b802bdbcd01a970ff8255d11db337f7b47b39.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bo.c | 11 ++++++++ drivers/gpu/drm/i915/display/intel_bo.h | 3 ++ drivers/gpu/drm/i915/display/intel_fbdev.c | 28 ++++++++----------- drivers/gpu/drm/i915/display/intel_fbdev_fb.c | 3 +- drivers/gpu/drm/i915/display/intel_fbdev_fb.h | 4 +-- drivers/gpu/drm/xe/display/intel_bo.c | 11 ++++++++ drivers/gpu/drm/xe/display/intel_fbdev_fb.c | 3 +- 7 files changed, 43 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index 5708d9bab1ab..c0d050cec4ad 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ +#include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" #include "intel_bo.h" @@ -14,7 +15,17 @@ bool intel_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) +{ + return i915_gem_object_is_shmem(to_intel_bo(obj)); +} + void intel_bo_flush_if_display(struct drm_gem_object *obj) { i915_gem_object_flush_if_display(to_intel_bo(obj)); } + +int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + return i915_gem_fb_mmap(to_intel_bo(obj), vma); +} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index 0fa29211a9d0..410f285d2ea1 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -7,9 +7,12 @@ #include struct drm_gem_object; +struct vm_area_struct; bool intel_bo_is_tiled(struct drm_gem_object *obj); bool intel_bo_is_userptr(struct drm_gem_object *obj); +bool intel_bo_is_shmem(struct drm_gem_object *obj); void intel_bo_flush_if_display(struct drm_gem_object *obj); +int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 56bf8641459b..00852ff5b247 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -41,13 +41,11 @@ #include #include #include +#include #include -#include "gem/i915_gem_mman.h" -#include "gem/i915_gem_object.h" -#include "gem/i915_gem_object_types.h" - #include "i915_drv.h" +#include "intel_bo.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fb_pin.h" @@ -130,10 +128,9 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct intel_fbdev *fbdev = to_intel_fbdev(info->par); - struct drm_gem_object *bo = drm_gem_fb_get_obj(&fbdev->fb->base, 0); - struct drm_i915_gem_object *obj = to_intel_bo(bo); + struct drm_gem_object *obj = drm_gem_fb_get_obj(&fbdev->fb->base, 0); - return i915_gem_fb_mmap(obj, vma); + return intel_bo_fb_mmap(obj, vma); } static void intel_fbdev_fb_destroy(struct fb_info *info) @@ -188,7 +185,7 @@ static int intelfb_create(struct drm_fb_helper *helper, struct i915_vma *vma; unsigned long flags = 0; bool prealloc = false; - struct drm_i915_gem_object *obj; + struct drm_gem_object *obj; int ret; mutex_lock(&ifbdev->hpd_lock); @@ -210,7 +207,7 @@ static int intelfb_create(struct drm_fb_helper *helper, drm_framebuffer_put(&fb->base); fb = NULL; } - if (!fb || drm_WARN_ON(dev, !intel_fb_obj(&fb->base))) { + if (!fb || drm_WARN_ON(dev, !intel_fb_bo(&fb->base))) { drm_dbg_kms(&dev_priv->drm, "no BIOS fb, allocating a new one\n"); fb = intel_fbdev_fb_alloc(helper, sizes); @@ -248,7 +245,7 @@ static int intelfb_create(struct drm_fb_helper *helper, info->fbops = &intelfb_ops; - obj = intel_fb_obj(&fb->base); + obj = intel_fb_bo(&fb->base); ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma); if (ret) @@ -260,7 +257,7 @@ static int intelfb_create(struct drm_fb_helper *helper, * If the object is stolen however, it will be full of whatever * garbage was left in there. */ - if (!i915_gem_object_is_shmem(obj) && !prealloc) + if (!intel_bo_is_shmem(obj) && !prealloc) memset_io(info->screen_base, 0, info->screen_size); /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ @@ -324,8 +321,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, to_intel_plane(crtc->base.primary); struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - struct drm_i915_gem_object *obj = - intel_fb_obj(plane_state->uapi.fb); + struct drm_gem_object *obj = intel_fb_bo(plane_state->uapi.fb); if (!crtc_state->uapi.active) { drm_dbg_kms(&i915->drm, @@ -341,12 +337,12 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, continue; } - if (intel_bo_to_drm_bo(obj)->size > max_size) { + if (obj->size > max_size) { drm_dbg_kms(&i915->drm, "found possible fb from [PLANE:%d:%s]\n", plane->base.base.id, plane->base.name); fb = to_intel_framebuffer(plane_state->uapi.fb); - max_size = intel_bo_to_drm_bo(obj)->size; + max_size = obj->size; } } @@ -534,7 +530,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous * full of whatever garbage was left in there. */ if (state == FBINFO_STATE_RUNNING && - !i915_gem_object_is_shmem(intel_fb_obj(&ifbdev->fb->base))) + !intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base))) memset_io(info->screen_base, 0, info->screen_size); drm_fb_helper_set_suspend(&ifbdev->helper, state); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c index 497525ef9668..77df36876ed5 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c @@ -67,8 +67,9 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, } int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, - struct drm_i915_gem_object *obj, struct i915_vma *vma) + struct drm_gem_object *_obj, struct i915_vma *vma) { + struct drm_i915_gem_object *obj = to_intel_bo(_obj); struct i915_gem_ww_ctx ww; void __iomem *vaddr; int ret; diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h index 4832fe688fbf..e502ae375fc0 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h @@ -8,7 +8,7 @@ struct drm_fb_helper; struct drm_fb_helper_surface_size; -struct drm_i915_gem_object; +struct drm_gem_object; struct drm_i915_private; struct fb_info; struct i915_vma; @@ -16,6 +16,6 @@ struct i915_vma; struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, - struct drm_i915_gem_object *obj, struct i915_vma *vma); + struct drm_gem_object *obj, struct i915_vma *vma); #endif diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 23e13cbddb1e..0c262313ecca 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -3,6 +3,7 @@ #include +#include "xe_bo.h" #include "intel_bo.h" bool intel_bo_is_tiled(struct drm_gem_object *obj) @@ -17,6 +18,16 @@ bool intel_bo_is_userptr(struct drm_gem_object *obj) return false; } +bool intel_bo_is_shmem(struct drm_gem_object *obj) +{ + return false; +} + void intel_bo_flush_if_display(struct drm_gem_object *obj) { } + +int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + return drm_gem_prime_mmap(obj, vma); +} diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c index 99499d6c0256..48478a6bed6f 100644 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c @@ -79,8 +79,9 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, } int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, - struct drm_i915_gem_object *obj, struct i915_vma *vma) + struct drm_gem_object *_obj, struct i915_vma *vma) { + struct xe_bo *obj = gem_to_xe_bo(_obj); struct pci_dev *pdev = to_pci_dev(i915->drm.dev); if (!(obj->flags & XE_BO_FLAG_SYSTEM)) { From ad36a322619c14ba35872129a401ee214bfad875 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:44 +0300 Subject: [PATCH 090/205] drm/i915/display: convert skl_universal_plane.c to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Add new intel_bo_* functions as needed. Convert intel_pxp_key_check() to struct drm_gem_object. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0a6d2bec50764efaae4322c9cfa33eefbfe1c054.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bo.c | 5 +++++ drivers/gpu/drm/i915/display/intel_bo.h | 1 + drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 +++-- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp.c | 4 +++- drivers/gpu/drm/i915/pxp/intel_pxp.h | 4 ++-- drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h | 10 ++-------- drivers/gpu/drm/xe/display/intel_bo.c | 5 +++++ 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index c0d050cec4ad..681970cf8701 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -20,6 +20,11 @@ bool intel_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) +{ + return i915_gem_object_is_protected(to_intel_bo(obj)); +} + void intel_bo_flush_if_display(struct drm_gem_object *obj) { i915_gem_object_flush_if_display(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 410f285d2ea1..222a12283a5a 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -12,6 +12,7 @@ struct vm_area_struct; bool intel_bo_is_tiled(struct drm_gem_object *obj); bool intel_bo_is_userptr(struct drm_gem_object *obj); bool intel_bo_is_shmem(struct drm_gem_object *obj); +bool intel_bo_is_protected(struct drm_gem_object *obj); void intel_bo_flush_if_display(struct drm_gem_object *obj); int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 17d4c880ecc4..fdb141cfa427 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -11,6 +11,7 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_atomic_plane.h" +#include "intel_bo.h" #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_types.h" @@ -2084,13 +2085,13 @@ static void check_protection(struct intel_plane_state *plane_state) struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_i915_private *i915 = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->hw.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_gem_object *obj = intel_fb_bo(fb); if (DISPLAY_VER(i915) < 11) return; plane_state->decrypt = intel_pxp_key_check(i915->pxp, obj, false) == 0; - plane_state->force_black = i915_gem_object_is_protected(obj) && + plane_state->force_black = intel_bo_is_protected(obj) && !plane_state->decrypt; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index a3b83cfe1726..f151640c1d13 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -915,7 +915,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle) */ if (i915_gem_context_uses_protected_content(eb->gem_context) && i915_gem_object_is_protected(obj)) { - err = intel_pxp_key_check(eb->i915->pxp, obj, true); + err = intel_pxp_key_check(eb->i915->pxp, intel_bo_to_drm_bo(obj), true); if (err) { i915_gem_object_put(obj); return ERR_PTR(err); diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 75278e78ca90..3a40e4ece925 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -461,9 +461,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp) } int intel_pxp_key_check(struct intel_pxp *pxp, - struct drm_i915_gem_object *obj, + struct drm_gem_object *_obj, bool assign) { + struct drm_i915_gem_object *obj = to_intel_bo(_obj); + if (!intel_pxp_is_active(pxp)) return -ENODEV; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h index d9372f6f7797..4ed97db5e7c6 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h @@ -9,7 +9,7 @@ #include #include -struct drm_i915_gem_object; +struct drm_gem_object; struct drm_i915_private; struct intel_pxp; @@ -32,7 +32,7 @@ int intel_pxp_start(struct intel_pxp *pxp); void intel_pxp_end(struct intel_pxp *pxp); int intel_pxp_key_check(struct intel_pxp *pxp, - struct drm_i915_gem_object *obj, + struct drm_gem_object *obj, bool assign); void intel_pxp_invalidate(struct intel_pxp *pxp); diff --git a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h index c2c30ece8f77..5dfc587c8237 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h @@ -9,20 +9,14 @@ #include #include -struct drm_i915_gem_object; +struct drm_gem_object; struct intel_pxp; static inline int intel_pxp_key_check(struct intel_pxp *pxp, - struct drm_i915_gem_object *obj, + struct drm_gem_object *obj, bool assign) { return -ENODEV; } -static inline bool -i915_gem_object_is_protected(const struct drm_i915_gem_object *obj) -{ - return false; -} - #endif diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 0c262313ecca..7543915c970a 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -23,6 +23,11 @@ bool intel_bo_is_shmem(struct drm_gem_object *obj) return false; } +bool intel_bo_is_protected(struct drm_gem_object *obj) +{ + return false; +} + void intel_bo_flush_if_display(struct drm_gem_object *obj) { } From 2b12fcd6c20e48027b47b71e5eb7a7ca20890d83 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:45 +0300 Subject: [PATCH 091/205] drm/i915/fb: convert intel_framebuffer_init() to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1b14bb0719c172304f38dfe59ea7240b3f42ed73.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 14 +++++++------- drivers/gpu/drm/i915/display/intel_fb.h | 2 +- drivers/gpu/drm/i915/display/intel_plane_initial.c | 2 +- drivers/gpu/drm/xe/display/xe_plane_initial.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index eb8dc3dd21ee..d863550021a0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1963,20 +1963,20 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = { }; int intel_framebuffer_init(struct intel_framebuffer *intel_fb, - struct drm_i915_gem_object *obj, + struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd) { - struct drm_i915_private *dev_priv = to_i915(intel_bo_to_drm_bo(obj)->dev); + struct drm_i915_private *dev_priv = to_i915(obj->dev); struct drm_framebuffer *fb = &intel_fb->base; u32 max_stride; int ret = -EINVAL; int i; - ret = intel_fb_bo_framebuffer_init(intel_fb, obj, mode_cmd); + ret = intel_fb_bo_framebuffer_init(intel_fb, to_intel_bo(obj), mode_cmd); if (ret) return ret; - intel_fb->frontbuffer = intel_frontbuffer_get(obj); + intel_fb->frontbuffer = intel_frontbuffer_get(to_intel_bo(obj)); if (!intel_fb->frontbuffer) { ret = -ENOMEM; goto err; @@ -2042,7 +2042,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, } } - fb->obj[i] = intel_bo_to_drm_bo(obj); + fb->obj[i] = obj; } ret = intel_fill_fb_info(dev_priv, intel_fb); @@ -2076,7 +2076,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, err_frontbuffer_put: intel_frontbuffer_put(intel_fb->frontbuffer); err: - intel_fb_bo_framebuffer_fini(obj); + intel_fb_bo_framebuffer_fini(to_intel_bo(obj)); return ret; } @@ -2111,7 +2111,7 @@ intel_framebuffer_create(struct drm_i915_gem_object *obj, if (!intel_fb) return ERR_PTR(-ENOMEM); - ret = intel_framebuffer_init(intel_fb, obj, mode_cmd); + ret = intel_framebuffer_init(intel_fb, intel_bo_to_drm_bo(obj), mode_cmd); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 2ca919bdbd7d..fef1f713dab0 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -85,7 +85,7 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio int intel_plane_compute_gtt(struct intel_plane_state *plane_state); int intel_framebuffer_init(struct intel_framebuffer *ifb, - struct drm_i915_gem_object *obj, + struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); struct drm_framebuffer * intel_user_framebuffer_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c index ada1792df5b3..62401f6a04e4 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c @@ -302,7 +302,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, mode_cmd.flags = DRM_MODE_FB_MODIFIERS; if (intel_framebuffer_init(to_intel_framebuffer(fb), - vma->obj, &mode_cmd)) { + intel_bo_to_drm_bo(vma->obj), &mode_cmd)) { drm_dbg_kms(&dev_priv->drm, "intel fb init failed\n"); goto err_vma; } diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c index a50ab9eae40a..1b10ea499d8c 100644 --- a/drivers/gpu/drm/xe/display/xe_plane_initial.c +++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c @@ -170,7 +170,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, return false; if (intel_framebuffer_init(to_intel_framebuffer(fb), - bo, &mode_cmd)) { + &bo->ttm.base, &mode_cmd)) { drm_dbg_kms(&xe->drm, "intel fb init failed\n"); goto err_bo; } From a426f671f361bf2bc82379e39c2b3d46ce190ebd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:46 +0300 Subject: [PATCH 092/205] drm/i915/fb: convert intel_fb_bo_lookup_valid_bo() to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/645307ea7bf858d131ecdeff6ee9c9b99ae00526.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 6 +++--- drivers/gpu/drm/i915/display/intel_fb_bo.c | 4 ++-- drivers/gpu/drm/i915/display/intel_fb_bo.h | 5 +++-- drivers/gpu/drm/xe/display/intel_fb_bo.c | 12 ++++++------ drivers/gpu/drm/xe/display/intel_fb_bo.h | 9 +++++---- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index d863550021a0..b705ae05c73e 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2086,7 +2086,7 @@ intel_user_framebuffer_create(struct drm_device *dev, const struct drm_mode_fb_cmd2 *user_mode_cmd) { struct drm_framebuffer *fb; - struct drm_i915_gem_object *obj; + struct drm_gem_object *obj; struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; struct drm_i915_private *i915 = to_i915(dev); @@ -2094,8 +2094,8 @@ intel_user_framebuffer_create(struct drm_device *dev, if (IS_ERR(obj)) return ERR_CAST(obj); - fb = intel_framebuffer_create(obj, &mode_cmd); - drm_gem_object_put(intel_bo_to_drm_bo(obj)); + fb = intel_framebuffer_create(to_intel_bo(obj), &mode_cmd); + drm_gem_object_put(obj); return fb; } diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c index 4be09541e509..c9a332afa601 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.c +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.c @@ -74,7 +74,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, return 0; } -struct drm_i915_gem_object * +struct drm_gem_object * intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, struct drm_file *filp, const struct drm_mode_fb_cmd2 *mode_cmd) @@ -93,5 +93,5 @@ intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, return ERR_PTR(-EREMOTE); } - return obj; + 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 index 232bf898b013..e7f4e57e8964 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.h +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.h @@ -7,9 +7,10 @@ #define __INTEL_FB_BO_H__ struct drm_file; -struct drm_mode_fb_cmd2; +struct drm_gem_object; struct drm_i915_gem_object; struct drm_i915_private; +struct drm_mode_fb_cmd2; struct intel_framebuffer; void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj); @@ -18,7 +19,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, struct drm_i915_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); -struct drm_i915_gem_object * +struct drm_gem_object * intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c index 63ce97cc4cfe..a973106d9e8c 100644 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.c +++ b/drivers/gpu/drm/xe/display/intel_fb_bo.c @@ -65,11 +65,11 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, return ret; } -struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd) +struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *mode_cmd) { - struct drm_i915_gem_object *bo; + struct xe_bo *bo; struct drm_gem_object *gem = drm_gem_object_lookup(filp, mode_cmd->handles[0]); if (!gem) @@ -78,11 +78,11 @@ struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, bo = gem_to_xe_bo(gem); /* Require vram placement or dma-buf import */ if (IS_DGFX(i915) && - !xe_bo_can_migrate(gem_to_xe_bo(gem), XE_PL_VRAM0) && + !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 bo; + return gem; } diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.h b/drivers/gpu/drm/xe/display/intel_fb_bo.h index 5d365b925b7a..430acca554fb 100644 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.h +++ b/drivers/gpu/drm/xe/display/intel_fb_bo.h @@ -7,8 +7,9 @@ #define __INTEL_FB_BO_H__ struct drm_file; -struct drm_mode_fb_cmd2; +struct drm_gem_object; struct drm_i915_private; +struct drm_mode_fb_cmd2; struct intel_framebuffer; struct xe_bo; @@ -17,8 +18,8 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, struct xe_bo *bo, struct drm_mode_fb_cmd2 *mode_cmd); -struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd); +struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *mode_cmd); #endif From 798a42505633554740ad2da5cbd5b42d428ab668 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:47 +0300 Subject: [PATCH 093/205] drm/i915/fb: convert intel_fb_bo_framebuffer_init() to struct drm_i915_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Add new intel_bo_* functions as needed. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/37f6dbb8946198cfac132e5e8eb5820f4f8dbc13.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_bo.c | 3 ++- drivers/gpu/drm/i915/display/intel_fb_bo.h | 2 +- drivers/gpu/drm/xe/display/intel_fb_bo.c | 3 ++- drivers/gpu/drm/xe/display/intel_fb_bo.h | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index b705ae05c73e..107ee5d3665f 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1972,7 +1972,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, int ret = -EINVAL; int i; - ret = intel_fb_bo_framebuffer_init(intel_fb, to_intel_bo(obj), mode_cmd); + ret = intel_fb_bo_framebuffer_init(intel_fb, obj, mode_cmd); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c index c9a332afa601..0932bd9f0100 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.c +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.c @@ -17,9 +17,10 @@ void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj) } int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, - struct drm_i915_gem_object *obj, + 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; diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.h b/drivers/gpu/drm/i915/display/intel_fb_bo.h index e7f4e57e8964..6030029042e7 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.h +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.h @@ -16,7 +16,7 @@ struct intel_framebuffer; void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj); int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, - struct drm_i915_gem_object *obj, + struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); struct drm_gem_object * diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c index a973106d9e8c..a3ec82d5ac8a 100644 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.c +++ b/drivers/gpu/drm/xe/display/intel_fb_bo.c @@ -23,9 +23,10 @@ void intel_fb_bo_framebuffer_fini(struct xe_bo *bo) } int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, - struct xe_bo *bo, + 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; diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.h b/drivers/gpu/drm/xe/display/intel_fb_bo.h index 430acca554fb..ad835bc050e8 100644 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.h +++ b/drivers/gpu/drm/xe/display/intel_fb_bo.h @@ -15,7 +15,7 @@ struct xe_bo; void intel_fb_bo_framebuffer_fini(struct xe_bo *bo); int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, - struct xe_bo *bo, + struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, From 3c81a414843117865ea5b019822ff05f1969a2b7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:48 +0300 Subject: [PATCH 094/205] drm/i915/fb: convert intel_fb_bo_framebuffer_fini() to struct drm_i915_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. The xe specific intel_fb_bo.h becomes redundant. Remove it, and rely on the common header in i915 display. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0efbc9ae2dbe157f92fa71d423ed37fd17346da5.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 4 ++-- drivers/gpu/drm/i915/display/intel_fb_bo.c | 2 +- drivers/gpu/drm/i915/display/intel_fb_bo.h | 3 +-- drivers/gpu/drm/xe/display/intel_fb_bo.c | 4 +++- drivers/gpu/drm/xe/display/intel_fb_bo.h | 25 ---------------------- 5 files changed, 7 insertions(+), 31 deletions(-) delete mode 100644 drivers/gpu/drm/xe/display/intel_fb_bo.h diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 107ee5d3665f..7bd4a519cd10 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1870,7 +1870,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) intel_frontbuffer_put(intel_fb->frontbuffer); - intel_fb_bo_framebuffer_fini(intel_fb_obj(fb)); + intel_fb_bo_framebuffer_fini(intel_fb_bo(fb)); kfree(intel_fb); } @@ -2076,7 +2076,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, err_frontbuffer_put: intel_frontbuffer_put(intel_fb->frontbuffer); err: - intel_fb_bo_framebuffer_fini(to_intel_bo(obj)); + intel_fb_bo_framebuffer_fini(obj); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.c b/drivers/gpu/drm/i915/display/intel_fb_bo.c index 0932bd9f0100..810ca6ff8640 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.c +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.c @@ -11,7 +11,7 @@ #include "intel_fb.h" #include "intel_fb_bo.h" -void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj) +void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj) { /* Nothing to do for i915 */ } diff --git a/drivers/gpu/drm/i915/display/intel_fb_bo.h b/drivers/gpu/drm/i915/display/intel_fb_bo.h index 6030029042e7..e71acd1bcb24 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_bo.h +++ b/drivers/gpu/drm/i915/display/intel_fb_bo.h @@ -8,12 +8,11 @@ struct drm_file; struct drm_gem_object; -struct drm_i915_gem_object; struct drm_i915_private; struct drm_mode_fb_cmd2; struct intel_framebuffer; -void intel_fb_bo_framebuffer_fini(struct drm_i915_gem_object *obj); +void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj); int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c index a3ec82d5ac8a..4d209ebc26c2 100644 --- a/drivers/gpu/drm/xe/display/intel_fb_bo.c +++ b/drivers/gpu/drm/xe/display/intel_fb_bo.c @@ -11,8 +11,10 @@ #include "intel_fb_bo.h" #include "xe_bo.h" -void intel_fb_bo_framebuffer_fini(struct xe_bo *bo) +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); diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.h b/drivers/gpu/drm/xe/display/intel_fb_bo.h deleted file mode 100644 index ad835bc050e8..000000000000 --- a/drivers/gpu/drm/xe/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_file; -struct drm_gem_object; -struct drm_i915_private; -struct drm_mode_fb_cmd2; -struct intel_framebuffer; -struct xe_bo; - -void intel_fb_bo_framebuffer_fini(struct xe_bo *bo); -int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, - struct drm_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd); - -struct drm_gem_object *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd); - -#endif From b7095d1266e7e61f4c779101863810a85e27e8e6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:49 +0300 Subject: [PATCH 095/205] drm/xe/display: use correct bo type in intel_fbdev_fb_alloc() It's really struct xe_bo, and struct drm_i915_gem_object only works because of -Ddrm_i915_gem_object=xe_bo in xe Makefile. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Acked-by: Lucas De Marchi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/344a5a4c88a3ce17dd276b0155bcdbf93e5fb475.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/display/intel_fbdev_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c index 48478a6bed6f..c290387964c0 100644 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c @@ -20,7 +20,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, struct drm_device *dev = helper->dev; struct xe_device *xe = to_xe_device(dev); struct drm_mode_fb_cmd2 mode_cmd = {}; - struct drm_i915_gem_object *obj; + struct xe_bo *obj; int size; /* we don't do packed 24bpp */ From e294868295325cb5fb40e330e1b6d5b3d37950e8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:50 +0300 Subject: [PATCH 096/205] drm/i915/fb: convert intel_framebuffer_create() to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Move the declaration to the right place while at it. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5120aa0f5e49e95526b3ac20c1325bac1d95aa21.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.h | 4 ---- drivers/gpu/drm/i915/display/intel_fb.c | 6 +++--- drivers/gpu/drm/i915/display/intel_fb.h | 3 +++ drivers/gpu/drm/i915/display/intel_fbdev_fb.c | 3 ++- drivers/gpu/drm/xe/display/intel_fbdev_fb.c | 3 ++- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 783562dc013b..1f0fed5ea7bc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -40,7 +40,6 @@ struct drm_encoder; struct drm_file; struct drm_format_info; struct drm_framebuffer; -struct drm_i915_gem_object; struct drm_i915_private; struct drm_mode_fb_cmd2; struct drm_modeset_acquire_ctx; @@ -493,9 +492,6 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp); void vlv_wait_port_ready(struct drm_i915_private *dev_priv, struct intel_digital_port *dig_port, unsigned int expected_mask); -struct drm_framebuffer * -intel_framebuffer_create(struct drm_i915_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd); bool intel_fuzzy_clock_check(int clock1, int clock2); diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 7bd4a519cd10..06bf25464ec9 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2094,14 +2094,14 @@ intel_user_framebuffer_create(struct drm_device *dev, if (IS_ERR(obj)) return ERR_CAST(obj); - fb = intel_framebuffer_create(to_intel_bo(obj), &mode_cmd); + fb = intel_framebuffer_create(obj, &mode_cmd); drm_gem_object_put(obj); return fb; } struct drm_framebuffer * -intel_framebuffer_create(struct drm_i915_gem_object *obj, +intel_framebuffer_create(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd) { struct intel_framebuffer *intel_fb; @@ -2111,7 +2111,7 @@ intel_framebuffer_create(struct drm_i915_gem_object *obj, if (!intel_fb) return ERR_PTR(-ENOMEM); - ret = intel_framebuffer_init(intel_fb, intel_bo_to_drm_bo(obj), mode_cmd); + ret = intel_framebuffer_init(intel_fb, obj, mode_cmd); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index fef1f713dab0..c11cca472747 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -88,6 +88,9 @@ int intel_framebuffer_init(struct intel_framebuffer *ifb, struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); struct drm_framebuffer * +intel_framebuffer_create(struct drm_gem_object *obj, + struct drm_mode_fb_cmd2 *mode_cmd); +struct drm_framebuffer * intel_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c index 77df36876ed5..4991c35a2632 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c @@ -9,6 +9,7 @@ #include "i915_drv.h" #include "intel_display_types.h" +#include "intel_fb.h" #include "intel_fbdev_fb.h" struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, @@ -60,7 +61,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, return ERR_PTR(-ENOMEM); } - fb = intel_framebuffer_create(obj, &mode_cmd); + fb = intel_framebuffer_create(intel_bo_to_drm_bo(obj), &mode_cmd); i915_gem_object_put(obj); return to_intel_framebuffer(fb); diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c index c290387964c0..c425349eac34 100644 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c @@ -6,6 +6,7 @@ #include #include "intel_display_types.h" +#include "intel_fb.h" #include "intel_fbdev_fb.h" #include "xe_bo.h" #include "xe_ttm_stolen_mgr.h" @@ -64,7 +65,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, goto err; } - fb = intel_framebuffer_create(obj, &mode_cmd); + fb = intel_framebuffer_create(&obj->ttm.base, &mode_cmd); if (IS_ERR(fb)) { xe_bo_unpin_map_no_vm(obj); goto err; From 4b4836d230d0097f3f652eeb455102a10ec84b61 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:51 +0300 Subject: [PATCH 097/205] drm/xe/display: stop using intel_fb_obj() in xe_fb_pin.c intel_fb_obj() returns struct drm_i915_gem_object, which is not right for xe, and only works because xe defines -Ddrm_i915_gem_object=xe_bo. Switch to intel_fb_bo() and convert to struct xe_bo from there. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Acked-by: Lucas De Marchi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/39f3d52cf156aecc4b2ed5cf1c9342b1c15143b4.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index b58fc4ba2aac..79dbbbe03c7f 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -84,7 +84,8 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); struct xe_ggtt *ggtt = tile0->mem.ggtt; - struct xe_bo *bo = intel_fb_obj(&fb->base), *dpt; + struct drm_gem_object *obj = intel_fb_bo(&fb->base); + struct xe_bo *bo = gem_to_xe_bo(obj), *dpt; u32 dpt_size, size = bo->ttm.base.size; if (view->type == I915_GTT_VIEW_NORMAL) @@ -185,7 +186,8 @@ static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb, const struct i915_gtt_view *view, struct i915_vma *vma) { - struct xe_bo *bo = intel_fb_obj(&fb->base); + struct drm_gem_object *obj = intel_fb_bo(&fb->base); + struct xe_bo *bo = gem_to_xe_bo(obj); struct xe_device *xe = to_xe_device(fb->base.dev); struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt; u32 align; @@ -269,7 +271,8 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb, struct drm_device *dev = fb->base.dev; struct xe_device *xe = to_xe_device(dev); struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); - struct xe_bo *bo = intel_fb_obj(&fb->base); + struct drm_gem_object *obj = intel_fb_bo(&fb->base); + struct xe_bo *bo = gem_to_xe_bo(obj); int ret; if (!vma) @@ -366,7 +369,8 @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags) int intel_plane_pin_fb(struct intel_plane_state *plane_state) { struct drm_framebuffer *fb = plane_state->hw.fb; - struct xe_bo *bo = intel_fb_obj(fb); + struct drm_gem_object *obj = intel_fb_bo(fb); + struct xe_bo *bo = gem_to_xe_bo(obj); struct i915_vma *vma; /* We reject creating !SCANOUT fb's, so this is weird.. */ From 63db15feff21b30253286bf2b114ec0cd2d9763f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:52 +0300 Subject: [PATCH 098/205] drm/i915/display: add intel_bo_read_from_page() and use it Add an interface based on struct drm_gem_object, and use it. Move the xe implementation to the intel_bo abstraction layer. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/45fcd209221a7b2ada5a243d95b8953237471e52.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bo.c | 5 ++++ drivers/gpu/drm/i915/display/intel_bo.h | 1 + drivers/gpu/drm/i915/display/intel_display.c | 12 ++++---- .../compat-i915-headers/gem/i915_gem_object.h | 30 ------------------- drivers/gpu/drm/xe/display/intel_bo.c | 30 +++++++++++++++++++ 5 files changed, 41 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index 681970cf8701..5643835cdfec 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -34,3 +34,8 @@ int intel_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) +{ + return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size); +} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index 222a12283a5a..2aab8e25b471 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -15,5 +15,6 @@ bool intel_bo_is_shmem(struct drm_gem_object *obj); bool intel_bo_is_protected(struct drm_gem_object *obj); void intel_bo_flush_if_display(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); #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index eb5cacc9625f..7136c80ac8cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -45,9 +45,6 @@ #include #include -#include "gem/i915_gem_lmem.h" -#include "gem/i915_gem_object.h" - #include "g4x_dp.h" #include "g4x_hdmi.h" #include "hsw_ips.h" @@ -61,6 +58,7 @@ #include "intel_atomic.h" #include "intel_atomic_plane.h" #include "intel_audio.h" +#include "intel_bo.h" #include "intel_bw.h" #include "intel_cdclk.h" #include "intel_clock_gating.h" @@ -7375,10 +7373,10 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s * caller made sure that the object is synced wrt. the related color clear value * GPU write on it. */ - ret = i915_gem_object_read_from_page(intel_fb_obj(fb), - fb->offsets[cc_plane] + 16, - &plane_state->ccval, - sizeof(plane_state->ccval)); + ret = intel_bo_read_from_page(intel_fb_bo(fb), + fb->offsets[cc_plane] + 16, + &plane_state->ccval, + sizeof(plane_state->ccval)); /* The above could only fail if the FB obj has an unexpected backing store type. */ drm_WARN_ON(&i915->drm, ret); } diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h index 777c20ceabab..9de90013bae3 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h @@ -31,34 +31,4 @@ static inline bool i915_gem_object_is_userptr(const struct xe_bo *bo) return false; } -static inline int i915_gem_object_read_from_page(struct xe_bo *bo, - u32 ofs, u64 *ptr, u32 size) -{ - struct ttm_bo_kmap_obj map; - void *src; - bool is_iomem; - int ret; - - ret = xe_bo_lock(bo, true); - if (ret) - return ret; - - ret = ttm_bo_kmap(&bo->ttm, ofs >> PAGE_SHIFT, 1, &map); - if (ret) - goto out_unlock; - - ofs &= ~PAGE_MASK; - src = ttm_kmap_obj_virtual(&map, &is_iomem); - src += ofs; - if (is_iomem) - memcpy_fromio(ptr, (void __iomem *)src, size); - else - memcpy(ptr, src, size); - - ttm_bo_kunmap(&map); -out_unlock: - xe_bo_unlock(bo); - return ret; -} - #endif diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 7543915c970a..e6003825d145 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -36,3 +36,33 @@ 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) +{ + struct xe_bo *bo = gem_to_xe_bo(obj); + struct ttm_bo_kmap_obj map; + void *src; + bool is_iomem; + int ret; + + ret = xe_bo_lock(bo, true); + if (ret) + return ret; + + ret = ttm_bo_kmap(&bo->ttm, offset >> PAGE_SHIFT, 1, &map); + if (ret) + goto out_unlock; + + offset &= ~PAGE_MASK; + src = ttm_kmap_obj_virtual(&map, &is_iomem); + src += offset; + if (is_iomem) + memcpy_fromio(dst, (void __iomem *)src, size); + else + memcpy(dst, src, size); + + ttm_bo_kunmap(&map); +out_unlock: + xe_bo_unlock(bo); + return ret; +} From ff992dbfbe34360e3cdfb9ff19166a27478c6e51 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:53 +0300 Subject: [PATCH 099/205] drm/i915/display: add intel_bo_get/set_frontbuffer() and use them Add the struct drm_gem_object based interfaces. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/3120ec430656f04701077dda39cce5f1ed415eee.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bo.c | 12 ++++++++++++ drivers/gpu/drm/i915/display/intel_bo.h | 4 ++++ drivers/gpu/drm/i915/display/intel_frontbuffer.c | 7 ++++--- drivers/gpu/drm/xe/display/intel_bo.c | 11 +++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index 5643835cdfec..3881b9ad08ee 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -3,6 +3,7 @@ #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" +#include "gem/i915_gem_object_frontbuffer.h" #include "intel_bo.h" bool intel_bo_is_tiled(struct drm_gem_object *obj) @@ -39,3 +40,14 @@ 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_get_frontbuffer(struct drm_gem_object *obj) +{ + return i915_gem_object_get_frontbuffer(to_intel_bo(obj)); +} + +struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, + struct intel_frontbuffer *front) +{ + return i915_gem_object_set_frontbuffer(to_intel_bo(obj), front); +} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index 2aab8e25b471..df0bd8c871a5 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -17,4 +17,8 @@ void intel_bo_flush_if_display(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_get_frontbuffer(struct drm_gem_object *obj); +struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, + struct intel_frontbuffer *front); + #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index e56d596485c3..1be72901efb0 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -59,6 +59,7 @@ #include "gem/i915_gem_object_types.h" #include "i915_active.h" #include "i915_drv.h" +#include "intel_bo.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_dp.h" @@ -266,7 +267,7 @@ static void frontbuffer_release(struct kref *ref) i915_ggtt_clear_scanout(obj); - ret = i915_gem_object_set_frontbuffer(obj, NULL); + ret = intel_bo_set_frontbuffer(intel_bo_to_drm_bo(obj), NULL); drm_WARN_ON(&intel_bo_to_i915(obj)->drm, ret); spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock); @@ -280,7 +281,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) struct drm_i915_private *i915 = intel_bo_to_i915(obj); struct intel_frontbuffer *front, *cur; - front = i915_gem_object_get_frontbuffer(obj); + front = intel_bo_get_frontbuffer(intel_bo_to_drm_bo(obj)); if (front) return front; @@ -298,7 +299,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work); spin_lock(&i915->display.fb_tracking.lock); - cur = i915_gem_object_set_frontbuffer(obj, front); + cur = intel_bo_set_frontbuffer(intel_bo_to_drm_bo(obj), front); spin_unlock(&i915->display.fb_tracking.lock); if (cur != front) kfree(front); diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index e6003825d145..4647f0d0338e 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -66,3 +66,14 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i xe_bo_unlock(bo); return ret; } + +struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj) +{ + return NULL; +} + +struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, + struct intel_frontbuffer *front) +{ + return front; +} From bca1cec057d08ce3b227ad214616cbebfe675582 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:54 +0300 Subject: [PATCH 100/205] drm/i915/frontbuffer: convert intel_frontbuffer_get() to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/358cfcb5eb666732cd7ae21e4f63d07837960ec2.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 2 +- drivers/gpu/drm/i915/display/intel_frontbuffer.c | 12 ++++++------ drivers/gpu/drm/i915/display/intel_frontbuffer.h | 3 ++- drivers/gpu/drm/i915/display/intel_overlay.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 06bf25464ec9..6ac9642a65ee 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1976,7 +1976,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, if (ret) return ret; - intel_fb->frontbuffer = intel_frontbuffer_get(to_intel_bo(obj)); + intel_fb->frontbuffer = intel_frontbuffer_get(obj); if (!intel_fb->frontbuffer) { ret = -ENOMEM; goto err; diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 1be72901efb0..8d8b0a905cc3 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -216,7 +216,7 @@ static void intel_frontbuffer_flush_work(struct work_struct *work) struct intel_frontbuffer *front = container_of(work, struct intel_frontbuffer, flush_work); - i915_gem_object_flush_if_display(front->obj); + intel_bo_flush_if_display(intel_bo_to_drm_bo(front->obj)); intel_frontbuffer_flush(front, ORIGIN_DIRTYFB); intel_frontbuffer_put(front); } @@ -276,12 +276,12 @@ static void frontbuffer_release(struct kref *ref) } struct intel_frontbuffer * -intel_frontbuffer_get(struct drm_i915_gem_object *obj) +intel_frontbuffer_get(struct drm_gem_object *obj) { - struct drm_i915_private *i915 = intel_bo_to_i915(obj); + struct drm_i915_private *i915 = to_i915(obj->dev); struct intel_frontbuffer *front, *cur; - front = intel_bo_get_frontbuffer(intel_bo_to_drm_bo(obj)); + front = intel_bo_get_frontbuffer(obj); if (front) return front; @@ -289,7 +289,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) if (!front) return NULL; - front->obj = obj; + front->obj = to_intel_bo(obj); kref_init(&front->ref); atomic_set(&front->bits, 0); i915_active_init(&front->write, @@ -299,7 +299,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work); spin_lock(&i915->display.fb_tracking.lock); - cur = intel_bo_set_frontbuffer(intel_bo_to_drm_bo(obj), front); + cur = intel_bo_set_frontbuffer(obj, front); spin_unlock(&i915->display.fb_tracking.lock); if (cur != front) kfree(front); diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index abb51e8bb920..128682b9ae12 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -30,6 +30,7 @@ #include "i915_active_types.h" +struct drm_gem_object; struct drm_i915_private; enum fb_op_origin { @@ -77,7 +78,7 @@ void intel_frontbuffer_flip(struct drm_i915_private *i915, void intel_frontbuffer_put(struct intel_frontbuffer *front); struct intel_frontbuffer * -intel_frontbuffer_get(struct drm_i915_gem_object *obj); +intel_frontbuffer_get(struct drm_gem_object *obj); void __intel_fb_invalidate(struct intel_frontbuffer *front, enum fb_op_origin origin, diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index b89541458765..2ec14096ba9c 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -294,7 +294,7 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, drm_WARN_ON(&overlay->i915->drm, overlay->old_vma); if (vma) - frontbuffer = intel_frontbuffer_get(vma->obj); + frontbuffer = intel_frontbuffer_get(intel_bo_to_drm_bo(vma->obj)); intel_frontbuffer_track(overlay->frontbuffer, frontbuffer, INTEL_FRONTBUFFER_OVERLAY(pipe)); From b03940082b6694cb2793238e27881841d02b3095 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:55 +0300 Subject: [PATCH 101/205] drm/i915/frontbuffer: convert frontbuffer->obj to struct drm_gem_object Prefer the driver agnostic struct drm_gem_object over i915 specific struct drm_i915_gem_object. Do some opportunistic struct intel_display conversions while at it, because it's more convenient to deal with. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/51bdb3c9b798e28bd70c259fc3874d80bc9b7443.1726589119.git.jani.nikula@intel.com --- .../gpu/drm/i915/display/intel_frontbuffer.c | 56 ++++++++++--------- .../gpu/drm/i915/display/intel_frontbuffer.h | 2 +- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 8d8b0a905cc3..6ed5f726ee60 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -55,8 +55,8 @@ * cancelled as soon as busyness is detected. */ -#include "gem/i915_gem_object_frontbuffer.h" -#include "gem/i915_gem_object_types.h" +#include + #include "i915_active.h" #include "i915_drv.h" #include "intel_bo.h" @@ -175,14 +175,14 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, enum fb_op_origin origin, unsigned int frontbuffer_bits) { - struct drm_i915_private *i915 = intel_bo_to_i915(front->obj); - struct intel_display *display = &i915->display; + struct intel_display *display = to_intel_display(front->obj->dev); + struct drm_i915_private *i915 = to_i915(display->drm); if (origin == ORIGIN_CS) { - spin_lock(&i915->display.fb_tracking.lock); - i915->display.fb_tracking.busy_bits |= frontbuffer_bits; - i915->display.fb_tracking.flip_bits &= ~frontbuffer_bits; - spin_unlock(&i915->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); + display->fb_tracking.busy_bits |= frontbuffer_bits; + display->fb_tracking.flip_bits &= ~frontbuffer_bits; + spin_unlock(&display->fb_tracking.lock); } trace_intel_frontbuffer_invalidate(display, frontbuffer_bits, origin); @@ -197,14 +197,15 @@ void __intel_fb_flush(struct intel_frontbuffer *front, enum fb_op_origin origin, unsigned int frontbuffer_bits) { - struct drm_i915_private *i915 = intel_bo_to_i915(front->obj); + struct intel_display *display = to_intel_display(front->obj->dev); + struct drm_i915_private *i915 = to_i915(display->drm); if (origin == ORIGIN_CS) { - spin_lock(&i915->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); /* Filter out new bits since rendering started. */ - frontbuffer_bits &= i915->display.fb_tracking.busy_bits; - i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits; - spin_unlock(&i915->display.fb_tracking.lock); + frontbuffer_bits &= display->fb_tracking.busy_bits; + display->fb_tracking.busy_bits &= ~frontbuffer_bits; + spin_unlock(&display->fb_tracking.lock); } if (frontbuffer_bits) @@ -216,7 +217,7 @@ static void intel_frontbuffer_flush_work(struct work_struct *work) struct intel_frontbuffer *front = container_of(work, struct intel_frontbuffer, flush_work); - intel_bo_flush_if_display(intel_bo_to_drm_bo(front->obj)); + intel_bo_flush_if_display(front->obj); intel_frontbuffer_flush(front, ORIGIN_DIRTYFB); intel_frontbuffer_put(front); } @@ -257,19 +258,20 @@ static void frontbuffer_retire(struct i915_active *ref) } static void frontbuffer_release(struct kref *ref) - __releases(&intel_bo_to_i915(front->obj)->display.fb_tracking.lock) + __releases(&to_intel_display(front->obj->dev)->fb_tracking.lock) { struct intel_frontbuffer *ret, *front = container_of(ref, typeof(*front), ref); - struct drm_i915_gem_object *obj = front->obj; + struct drm_gem_object *obj = front->obj; + struct intel_display *display = to_intel_display(obj->dev); - drm_WARN_ON(&intel_bo_to_i915(obj)->drm, atomic_read(&front->bits)); + drm_WARN_ON(display->drm, atomic_read(&front->bits)); - i915_ggtt_clear_scanout(obj); + i915_ggtt_clear_scanout(to_intel_bo(obj)); - ret = intel_bo_set_frontbuffer(intel_bo_to_drm_bo(obj), NULL); - drm_WARN_ON(&intel_bo_to_i915(obj)->drm, ret); - spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock); + ret = intel_bo_set_frontbuffer(obj, NULL); + drm_WARN_ON(display->drm, ret); + spin_unlock(&display->fb_tracking.lock); i915_active_fini(&front->write); kfree_rcu(front, rcu); @@ -289,7 +291,7 @@ intel_frontbuffer_get(struct drm_gem_object *obj) if (!front) return NULL; - front->obj = to_intel_bo(obj); + front->obj = obj; kref_init(&front->ref); atomic_set(&front->bits, 0); i915_active_init(&front->write, @@ -310,7 +312,7 @@ void intel_frontbuffer_put(struct intel_frontbuffer *front) { kref_put_lock(&front->ref, frontbuffer_release, - &intel_bo_to_i915(front->obj)->display.fb_tracking.lock); + &to_intel_display(front->obj->dev)->fb_tracking.lock); } /** @@ -339,13 +341,17 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old, BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE); if (old) { - drm_WARN_ON(&intel_bo_to_i915(old->obj)->drm, + struct intel_display *display = to_intel_display(old->obj->dev); + + drm_WARN_ON(display->drm, !(atomic_read(&old->bits) & frontbuffer_bits)); atomic_andnot(frontbuffer_bits, &old->bits); } if (new) { - drm_WARN_ON(&intel_bo_to_i915(new->obj)->drm, + struct intel_display *display = to_intel_display(new->obj->dev); + + drm_WARN_ON(display->drm, atomic_read(&new->bits) & frontbuffer_bits); atomic_or(frontbuffer_bits, &new->bits); } diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index 128682b9ae12..6237780a9f68 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -45,7 +45,7 @@ struct intel_frontbuffer { struct kref ref; atomic_t bits; struct i915_active write; - struct drm_i915_gem_object *obj; + struct drm_gem_object *obj; struct rcu_head rcu; struct work_struct flush_work; From 67e71a4b027b4996a58761d22943efa8393f9cf4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:56 +0300 Subject: [PATCH 102/205] drm/i915/display: add intel_bo_describe() and use it Add an interface based on struct drm_gem_object, and use it. This lets us delete the compat i915_debugfs.h header. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/66bcaaba9899a2bceb7ce4bd3be56ff60c5c9b09.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bo.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_bo.h | 3 +++ .../gpu/drm/i915/display/intel_display_debugfs.c | 6 +++--- .../gpu/drm/xe/compat-i915-headers/i915_debugfs.h | 14 -------------- drivers/gpu/drm/xe/display/intel_bo.c | 5 +++++ 5 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index 3881b9ad08ee..fbd16d7b58d9 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -4,6 +4,7 @@ #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" #include "gem/i915_gem_object_frontbuffer.h" +#include "i915_debugfs.h" #include "intel_bo.h" bool intel_bo_is_tiled(struct drm_gem_object *obj) @@ -51,3 +52,8 @@ struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, { return i915_gem_object_set_frontbuffer(to_intel_bo(obj), front); } + +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 df0bd8c871a5..ea7a2253aaa5 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -7,6 +7,7 @@ #include struct drm_gem_object; +struct seq_file; struct vm_area_struct; bool intel_bo_is_tiled(struct drm_gem_object *obj); @@ -21,4 +22,6 @@ struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj); struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, 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_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 1b68be92e9e0..a3f9514f69ea 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -11,10 +11,10 @@ #include #include "hsw_ips.h" -#include "i915_debugfs.h" #include "i915_irq.h" #include "i915_reg.h" #include "intel_alpm.h" +#include "intel_bo.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" #include "intel_de.h" @@ -125,7 +125,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) fbdev_fb->base.format->cpp[0] * 8, fbdev_fb->base.modifier, drm_framebuffer_read_refcount(&fbdev_fb->base)); - i915_debugfs_describe_obj(m, intel_fb_obj(&fbdev_fb->base)); + intel_bo_describe(m, intel_fb_bo(&fbdev_fb->base)); seq_putc(m, '\n'); } #endif @@ -143,7 +143,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) fb->base.format->cpp[0] * 8, fb->base.modifier, drm_framebuffer_read_refcount(&fb->base)); - i915_debugfs_describe_obj(m, intel_fb_obj(&fb->base)); + intel_bo_describe(m, intel_fb_bo(&fb->base)); seq_putc(m, '\n'); } mutex_unlock(&dev_priv->drm.mode_config.fb_lock); diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h deleted file mode 100644 index b4c47617b64b..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_debugfs.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef __I915_DEBUGFS_H__ -#define __I915_DEBUGFS_H__ - -struct drm_i915_gem_object; -struct seq_file; - -static inline void i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) {} - -#endif /* __I915_DEBUGFS_H__ */ diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 4647f0d0338e..9f54fad0f1c0 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -77,3 +77,8 @@ struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, { return front; } + +void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) +{ + /* FIXME */ +} From b652f407e87826940db767b6a501844c2ad98053 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:57 +0300 Subject: [PATCH 103/205] drm/i915/fb: remove intel_fb_obj() Convert remaining users of the struct drm_i915_gem_object based intel_fb_obj() to the struct drm_gem_object based intel_fb_bo(), and remove intel_fb_obj(). Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e1fbf33d71813f39621ba0ac7e404821a3f63588.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dpt.c | 2 +- drivers/gpu/drm/i915/display/intel_fb.c | 5 ----- drivers/gpu/drm/i915/display/intel_fb.h | 2 -- drivers/gpu/drm/i915/display/intel_fb_pin.c | 14 +++++++++----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 3a6d99044828..ce8c76e44e6a 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -242,7 +242,7 @@ void intel_dpt_suspend(struct drm_i915_private *i915) struct i915_address_space * intel_dpt_create(struct intel_framebuffer *fb) { - struct drm_gem_object *obj = &intel_fb_obj(&fb->base)->base; + struct drm_gem_object *obj = intel_fb_bo(&fb->base); struct drm_i915_private *i915 = to_i915(obj->dev); struct drm_i915_gem_object *dpt_obj; struct i915_address_space *vm; diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 6ac9642a65ee..eb5ff3ba156c 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2122,11 +2122,6 @@ intel_framebuffer_create(struct drm_gem_object *obj, return ERR_PTR(ret); } -struct drm_i915_gem_object *intel_fb_obj(const struct drm_framebuffer *fb) -{ - return fb ? to_intel_bo(fb->obj[0]) : NULL; -} - struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb) { return fb ? fb->obj[0] : NULL; diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index c11cca472747..8240febff84c 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -100,8 +100,6 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb); unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier); -struct drm_i915_gem_object *intel_fb_obj(const struct drm_framebuffer *fb); - struct drm_gem_object *intel_fb_bo(const struct drm_framebuffer *fb); #endif /* __INTEL_FB_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index 575b271e012b..d3a86f9c6bc8 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -26,7 +26,8 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, { struct drm_device *dev = fb->dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_gem_object *_obj = intel_fb_bo(fb); + struct drm_i915_gem_object *obj = to_intel_bo(_obj); struct i915_gem_ww_ctx ww; struct i915_vma *vma; int ret; @@ -111,7 +112,8 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, { struct drm_device *dev = fb->dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_gem_object *_obj = intel_fb_bo(fb); + struct drm_i915_gem_object *obj = to_intel_bo(_obj); intel_wakeref_t wakeref; struct i915_gem_ww_ctx ww; struct i915_vma *vma; @@ -274,9 +276,11 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state) * will trigger might_sleep() even if it won't actually sleep, * which is the case when the fb has already been pinned. */ - if (intel_plane_needs_physical(plane)) - plane_state->phys_dma_addr = - i915_gem_object_get_dma_address(intel_fb_obj(&fb->base), 0); + if (intel_plane_needs_physical(plane)) { + struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base)); + + plane_state->phys_dma_addr = i915_gem_object_get_dma_address(obj, 0); + } } else { unsigned int alignment = intel_plane_fb_min_alignment(plane_state); From 6f4429f9eb31db9418cc2484ee9f6090cc75589a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:58 +0300 Subject: [PATCH 104/205] drm/i915/display: clean up some gem/ includes Drop some unnecessary gem/ includes. We seem to include xe_device.h through some compat gem headers, so we need to include it directly in compat i915_drv.h to get xe_device_has_flat_ccs(). Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/afd2917cc0a943660886937bb5f45c277132e147.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_cursor.c | 2 -- drivers/gpu/drm/i915/display/intel_fb.c | 9 ++++----- drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h | 1 + 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 805e0af21a45..050eacc709cc 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -27,8 +27,6 @@ #include "intel_vblank.h" #include "skl_watermark.h" -#include "gem/i915_gem_object.h" - /* Cursor formats */ static const u32 intel_cursor_formats[] = { DRM_FORMAT_ARGB8888, diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index eb5ff3ba156c..c03060e5e503 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -3,14 +3,13 @@ * Copyright © 2021 Intel Corporation */ -#include -#include - #include #include -#include "gem/i915_gem_object.h" -#include "gem/i915_gem_object_types.h" +#include +#include +#include + #include "i915_drv.h" #include "intel_atomic_plane.h" #include "intel_bo.h" diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h index f27a2c75b56d..00d492f907d8 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -14,6 +14,7 @@ #include "i915_utils.h" #include "intel_runtime_pm.h" +#include "xe_device.h" /* for xe_device_has_flat_ccs() */ #include "xe_device_types.h" static inline struct drm_i915_private *to_i915(const struct drm_device *dev) From 2ae68b013c9570515713512bb328808001bb11ae Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:13:59 +0300 Subject: [PATCH 105/205] drm/xe/compat: remove a bunch of compat gem headers Now that we've switched to struct drm_gem_object and the intel_bo_* interfaces, we no longer need most of the compat gem headers. Remove. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Acked-by: Lucas De Marchi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/2ac115c5dd5f68da9172e9b5bd3a7eb4e10fce60.1726589119.git.jani.nikula@intel.com --- .../compat-i915-headers/gem/i915_gem_lmem.h | 1 - .../compat-i915-headers/gem/i915_gem_mman.h | 17 ---------- .../compat-i915-headers/gem/i915_gem_object.h | 34 ------------------- .../gem/i915_gem_object_frontbuffer.h | 12 ------- .../gem/i915_gem_object_types.h | 11 ------ 5 files changed, 75 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h deleted file mode 100644 index 710cecca972d..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_lmem.h +++ /dev/null @@ -1 +0,0 @@ -/* Empty */ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h deleted file mode 100644 index 650ea2803a97..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_mman.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef _I915_GEM_MMAN_H_ -#define _I915_GEM_MMAN_H_ - -#include "xe_bo_types.h" -#include - -static inline int i915_gem_fb_mmap(struct xe_bo *bo, struct vm_area_struct *vma) -{ - return drm_gem_prime_mmap(&bo->ttm.base, vma); -} - -#endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h deleted file mode 100644 index 9de90013bae3..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2022 Intel Corporation - */ - -#ifndef _I915_GEM_OBJECT_H_ -#define _I915_GEM_OBJECT_H_ - -#include - -#include "xe_bo.h" - -#define i915_gem_object_is_shmem(obj) (0) /* We don't use shmem */ - -static inline dma_addr_t i915_gem_object_get_dma_address(const struct xe_bo *bo, pgoff_t n) -{ - /* Should never be called */ - WARN_ON(1); - return n; -} - -static inline bool i915_gem_object_is_tiled(const struct xe_bo *bo) -{ - /* legacy tiling is unused */ - return false; -} - -static inline bool i915_gem_object_is_userptr(const struct xe_bo *bo) -{ - /* legacy tiling is unused */ - return false; -} - -#endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h deleted file mode 100644 index 2a3f12d2978c..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_frontbuffer.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2022 Intel Corporation - */ - -#ifndef _I915_GEM_OBJECT_FRONTBUFFER_H_ -#define _I915_GEM_OBJECT_FRONTBUFFER_H_ - -#define i915_gem_object_get_frontbuffer(obj) NULL -#define i915_gem_object_set_frontbuffer(obj, front) (front) - -#endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h deleted file mode 100644 index 7d6bb1abab73..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright © 2024 Intel Corporation */ - -#ifndef __I915_GEM_OBJECT_TYPES_H__ -#define __I915_GEM_OBJECT_TYPES_H__ - -#include "xe_bo.h" - -#define to_intel_bo(x) gem_to_xe_bo((x)) - -#endif From a1dc3a738ec75bca0743db239e1d6e1bfb66ba8b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:14:00 +0300 Subject: [PATCH 106/205] drm/xe: remove a number of superfluous compat macros Some compat macros have inadvertently been sprinkled in xe core headers. Remove the final users and the macros. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Acked-by: Lucas De Marchi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/418185993c5825a54ac3f87a85463c799c91e47d.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/display/intel_fbdev_fb.c | 4 ++-- drivers/gpu/drm/xe/xe_bo.h | 2 -- drivers/gpu/drm/xe/xe_bo_types.h | 3 --- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c index c425349eac34..ca95fcd098ec 100644 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c @@ -71,7 +71,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, goto err; } - drm_gem_object_put(intel_bo_to_drm_bo(obj)); + drm_gem_object_put(&obj->ttm.base); return to_intel_framebuffer(fb); @@ -102,7 +102,7 @@ int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info XE_WARN_ON(iosys_map_is_null(&obj->vmap)); info->screen_base = obj->vmap.vaddr_iomem; - info->screen_size = intel_bo_to_drm_bo(obj)->size; + info->screen_size = obj->ttm.base.size; return 0; } diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h index dbfb3209615d..2af2d0b10577 100644 --- a/drivers/gpu/drm/xe/xe_bo.h +++ b/drivers/gpu/drm/xe/xe_bo.h @@ -316,8 +316,6 @@ static inline unsigned int xe_sg_segment_size(struct device *dev) return round_down(max / 2, PAGE_SIZE); } -#define i915_gem_object_flush_if_display(obj) ((void)(obj)) - #if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST) /** * xe_bo_is_mem_type - Whether the bo currently resides in the given diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h index 2ed558ac2264..8b9201775081 100644 --- a/drivers/gpu/drm/xe/xe_bo_types.h +++ b/drivers/gpu/drm/xe/xe_bo_types.h @@ -78,7 +78,4 @@ struct xe_bo { struct list_head vram_userfault_link; }; -#define intel_bo_to_drm_bo(bo) (&(bo)->ttm.base) -#define intel_bo_to_i915(bo) to_i915(intel_bo_to_drm_bo(bo)->dev) - #endif From ffe558daed66163defb75a89d859717d87ad419a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Sep 2024 19:14:01 +0300 Subject: [PATCH 107/205] drm/xe: eradicate -Ddrm_i915_gem_object=xe_bo We've now completely stopped using drm_i915_gem_object in display code that gets built for xe. Kill off the -Ddrm_i915_gem_object=xe_bo hack. Good riddance. Reviewed-by: Maarten Lankhorst Acked-by: Rodrigo Vivi Acked-by: Lucas De Marchi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0eae2b62b635acafe5dc97dc4b205aaa34ce1e53.1726589119.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 54d41deaebe1..8fa7e4dd6d69 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -148,7 +148,6 @@ subdir-ccflags-$(CONFIG_DRM_XE_DISPLAY) += \ -I$(src)/display/ext \ -I$(src)/compat-i915-headers \ -I$(srctree)/drivers/gpu/drm/i915/display/ \ - -Ddrm_i915_gem_object=xe_bo \ -Ddrm_i915_private=xe_device # Rule to build SOC code shared with i915 From 66b281fd8e599ddd7a00a89dc0dcfb7a13411441 Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane Date: Tue, 10 Sep 2024 11:53:01 +0530 Subject: [PATCH 108/205] drm/i915/pciid: Add new PCI id for ARL Add new PCI id for ARL platform. Signed-off-by: Dnyaneshwar Bhadane Reviewed-by: Nemesa Garg Reviewed-by: Sai Teja Pottumuttu Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20240910062301.2006782-1-dnyaneshwar.bhadane@intel.com --- include/drm/intel/i915_pciids.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h index cbb12fdbcb7f..02156c6f79b6 100644 --- a/include/drm/intel/i915_pciids.h +++ b/include/drm/intel/i915_pciids.h @@ -769,7 +769,8 @@ MACRO__(0x7D41, ## __VA_ARGS__), \ MACRO__(0x7D51, ## __VA_ARGS__), \ MACRO__(0x7D67, ## __VA_ARGS__), \ - MACRO__(0x7DD1, ## __VA_ARGS__) + MACRO__(0x7DD1, ## __VA_ARGS__), \ + MACRO__(0xB640, ## __VA_ARGS__) /* MTL */ #define INTEL_MTL_IDS(MACRO__, ...) \ From 1007610ece094625deb259c3077b18fa9d992d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 20 Sep 2024 09:23:39 +0300 Subject: [PATCH 109/205] drm/i915/psr: Add intel_psr_needs_block_dc_vblank for blocking dc entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't prevent it in case of Panel Replay. Panel Replay switches main link off on DC entry. This means vblank interrupts are not fired and is a problem if user-space is polling for vblank events. For this purpose add new function to query need for dc entry blocking on. Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240920062340.1333777-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 31 ++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_psr.h | 1 + 2 files changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 5b355d0a3565..e3357f3b5c70 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -35,6 +35,7 @@ #include "intel_cursor_regs.h" #include "intel_ddi.h" #include "intel_de.h" +#include "intel_display_irq.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" @@ -2229,6 +2230,36 @@ void intel_psr_resume(struct intel_dp *intel_dp) mutex_unlock(&psr->lock); } +/** + * intel_psr_needs_block_dc_vblank - Check if block dc entry is needed + * @crtc_state: CRTC status + * + * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't + * prevent it in case of Panel Replay. Panel Replay switches main link off on + * DC entry. This means vblank interrupts are not fired and is a problem if + * user-space is polling for vblank events. + */ +bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_encoder *encoder; + + for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) { + struct intel_dp *intel_dp; + + if (!intel_encoder_is_dp(encoder)) + continue; + + intel_dp = enc_to_intel_dp(encoder); + + if (intel_dp_is_edp(intel_dp) && + CAN_PANEL_REPLAY(intel_dp)) + return true; + } + + return false; +} + static u32 man_trk_ctl_enable_bit_get(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 6eb5f15f674f..5f26f61f82aa 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -58,6 +58,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state); void intel_psr_pause(struct intel_dp *intel_dp); void intel_psr_resume(struct intel_dp *intel_dp); +bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state); void intel_psr_lock(const struct intel_crtc_state *crtc_state); void intel_psr_unlock(const struct intel_crtc_state *crtc_state); From aa451abcffb5a732a5b3421d41c5c6e502b2b8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 20 Sep 2024 09:23:40 +0300 Subject: [PATCH 110/205] drm/i915/display: Prevent DC6 while vblank is enabled for Panel Replay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't prevent DC6 in case of Panel Replay. This causes problems if user-space is polling for vblank events. Fix this by setting target DC state as DC_STATE_EN_UPTO_DC5 when both source and sink are supporting eDP Panel Replay and VBI is enabled. v4: - s/vblank_work/vblank_dc_work/ - changed type of block_dc_for_vblank to bool v3: - do flush_work for vblank_work on intel_crtc_vblank_off - no need to use READ_ONCE in bdw_enable_vblank - check crtc->block_dc_for_vblank in bdw_disable_vblank as well - move adding block_dc_for_vblank into this patch v2: - use READ_ONCE in intel_display_vblank_work - use DC_STATE_DISABLE instead of DC_STATE_EN_UPTO_DC6 - use intel_crtc->block_dc6_needed Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2296 Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240920062340.1333777-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 7 +++++ .../gpu/drm/i915/display/intel_display_core.h | 2 ++ .../gpu/drm/i915/display/intel_display_irq.c | 28 +++++++++++++++++++ .../drm/i915/display/intel_display_types.h | 2 ++ 4 files changed, 39 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index f95d169fc324..3a28d8450a38 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -124,6 +124,8 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + crtc->block_dc_for_vblank = intel_psr_needs_block_dc_vblank(crtc_state); + assert_vblank_disabled(&crtc->base); drm_crtc_set_max_vblank_count(&crtc->base, intel_crtc_max_vblank_count(crtc_state)); @@ -140,6 +142,7 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state) void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_display *display = to_intel_display(crtc); /* * Should really happen exactly when we disable the pipe @@ -150,6 +153,10 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state) drm_crtc_vblank_off(&crtc->base); assert_vblank_disabled(&crtc->base); + + crtc->block_dc_for_vblank = false; + + flush_work(&display->irq.vblank_dc_work); } struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 0a711114ff2b..ac4c005fe348 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -457,6 +457,8 @@ struct intel_display { /* For i915gm/i945gm vblank irq workaround */ u8 vblank_enabled; + struct work_struct vblank_dc_work; + u32 de_irq_mask[I915_MAX_PIPES]; u32 pipestat_irq_mask[I915_MAX_PIPES]; } irq; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 0ccbf7a1f2bf..6878dde85031 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1360,9 +1360,27 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, return true; } +static void intel_display_vblank_dc_work(struct work_struct *work) +{ + struct intel_display *display = + container_of(work, typeof(*display), irq.vblank_dc_work); + struct drm_i915_private *i915 = to_i915(display->drm); + u8 vblank_enabled = READ_ONCE(display->irq.vblank_enabled); + + /* + * NOTE: intel_display_power_set_target_dc_state is used only by PSR + * code for DC3CO handling. DC3CO target state is currently disabled in + * PSR code. If DC3CO is taken into use we need take that into account + * here as well. + */ + intel_display_power_set_target_dc_state(i915, vblank_enabled ? DC_STATE_DISABLE : + DC_STATE_EN_UPTO_DC6); +} + int bdw_enable_vblank(struct drm_crtc *_crtc) { struct intel_crtc *crtc = to_intel_crtc(_crtc); + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; unsigned long irqflags; @@ -1370,6 +1388,9 @@ int bdw_enable_vblank(struct drm_crtc *_crtc) if (gen11_dsi_configure_te(crtc, true)) return 0; + if (display->irq.vblank_enabled++ == 0 && crtc->block_dc_for_vblank) + schedule_work(&display->irq.vblank_dc_work); + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); @@ -1435,6 +1456,7 @@ void ilk_disable_vblank(struct drm_crtc *crtc) void bdw_disable_vblank(struct drm_crtc *_crtc) { struct intel_crtc *crtc = to_intel_crtc(_crtc); + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; unsigned long irqflags; @@ -1445,6 +1467,9 @@ void bdw_disable_vblank(struct drm_crtc *_crtc) spin_lock_irqsave(&dev_priv->irq_lock, irqflags); bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + + if (--display->irq.vblank_enabled == 0 && crtc->block_dc_for_vblank) + schedule_work(&display->irq.vblank_dc_work); } void vlv_display_irq_reset(struct drm_i915_private *dev_priv) @@ -1881,4 +1906,7 @@ void intel_display_irq_init(struct drm_i915_private *i915) i915->display.irq.display_irqs_enabled = false; intel_hotplug_irq_init(i915); + + INIT_WORK(&i915->display.irq.vblank_dc_work, + intel_display_vblank_dc_work); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3e694c1204db..513e843e19b9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1413,6 +1413,8 @@ struct intel_crtc { #ifdef CONFIG_DEBUG_FS struct intel_pipe_crc pipe_crc; #endif + + bool block_dc_for_vblank; }; struct intel_plane { From a5b40d4f038d9ed0e6f34cf2383cb629fe3a2c59 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:43 +0300 Subject: [PATCH 111/205] drm/i915/dp: split out intel_dp_test.[ch] to a dedicated file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp.c has become huge, over 7k lines. Split out the fairly well isolated chunk of DP test code to a dedicated file intel_dp_test.[ch]. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/262d565fe59715ba297702b67d4bcca81c736dc0.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/g4x_dp.c | 1 + drivers/gpu/drm/i915/display/intel_ddi.c | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 489 +----------------- drivers/gpu/drm/i915/display/intel_dp.h | 9 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +- drivers/gpu/drm/i915/display/intel_dp_test.c | 499 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dp_test.h | 18 + drivers/gpu/drm/xe/Makefile | 1 + 9 files changed, 534 insertions(+), 490 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dp_test.c create mode 100644 drivers/gpu/drm/i915/display/intel_dp_test.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index bb67bad839ea..70771e521b1c 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -327,6 +327,7 @@ i915-y += \ display/intel_dp_hdcp.o \ display/intel_dp_link_training.o \ display/intel_dp_mst.o \ + display/intel_dp_test.o \ display/intel_dsi.o \ display/intel_dsi_dcs_backlight.o \ display/intel_dsi_vbt.o \ diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 040478048b97..ac9dce8213a3 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -19,6 +19,7 @@ #include "intel_dp.h" #include "intel_dp_aux.h" #include "intel_dp_link_training.h" +#include "intel_dp_test.h" #include "intel_dpio_phy.h" #include "intel_encoder.h" #include "intel_fifo_underrun.h" diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 85e519a21542..c0ade280d816 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -54,6 +54,7 @@ #include "intel_dp_aux.h" #include "intel_dp_link_training.h" #include "intel_dp_mst.h" +#include "intel_dp_test.h" #include "intel_dp_tunnel.h" #include "intel_dpio_phy.h" #include "intel_dsi.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7008d3624e72..1cc73e2bf1fe 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -67,6 +67,7 @@ #include "intel_dp_hdcp.h" #include "intel_dp_link_training.h" #include "intel_dp_mst.h" +#include "intel_dp_test.h" #include "intel_dp_tunnel.h" #include "intel_dpio_phy.h" #include "intel_dpll.h" @@ -103,13 +104,6 @@ /* DP DSC FEC Overhead factor in ppm = 1/(0.972261) = 1.028530 */ #define DP_DSC_FEC_OVERHEAD_FACTOR 1028530 -/* Compliance test status bits */ -#define INTEL_DP_RESOLUTION_SHIFT_MASK 0 -#define INTEL_DP_RESOLUTION_PREFERRED (1 << INTEL_DP_RESOLUTION_SHIFT_MASK) -#define INTEL_DP_RESOLUTION_STANDARD (2 << INTEL_DP_RESOLUTION_SHIFT_MASK) -#define INTEL_DP_RESOLUTION_FAILSAFE (3 << INTEL_DP_RESOLUTION_SHIFT_MASK) - - /* Constants for DP DSC configurations */ static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15}; @@ -770,8 +764,8 @@ static void intel_dp_set_common_rates(struct intel_dp *intel_dp) intel_dp_link_config_init(intel_dp); } -static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, - u8 lane_count) +bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, + u8 lane_count) { /* * FIXME: we need to synchronize the current link parameters with @@ -1636,45 +1630,6 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp, return bpp; } -/* Adjust link config limits based on compliance test requests. */ -void -intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - struct link_config_limits *limits) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - - /* For DP Compliance we override the computed bpp for the pipe */ - if (intel_dp->compliance.test_data.bpc != 0) { - int bpp = 3 * intel_dp->compliance.test_data.bpc; - - limits->pipe.min_bpp = limits->pipe.max_bpp = bpp; - pipe_config->dither_force_disable = bpp == 6 * 3; - - drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp); - } - - /* Use values requested by Compliance Test Request */ - if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { - int index; - - /* Validate the compliance test data since max values - * might have changed due to link train fallback. - */ - if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate, - intel_dp->compliance.test_lane_count)) { - index = intel_dp_rate_index(intel_dp->common_rates, - intel_dp->num_common_rates, - intel_dp->compliance.test_link_rate); - if (index >= 0) - limits->min_rate = limits->max_rate = - intel_dp->compliance.test_link_rate; - limits->min_lane_count = limits->max_lane_count = - intel_dp->compliance.test_lane_count; - } - } -} - static bool has_seamless_m_n(struct intel_connector *connector) { struct drm_i915_private *i915 = to_i915(connector->base.dev); @@ -4786,328 +4741,6 @@ void intel_read_dp_sdp(struct intel_encoder *encoder, } } -static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - int status = 0; - int test_link_rate; - u8 test_lane_count, test_link_bw; - /* (DP CTS 1.2) - * 4.3.1.11 - */ - /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */ - status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT, - &test_lane_count); - - if (status <= 0) { - drm_dbg_kms(&i915->drm, "Lane count read failed\n"); - return DP_TEST_NAK; - } - test_lane_count &= DP_MAX_LANE_COUNT_MASK; - - status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE, - &test_link_bw); - if (status <= 0) { - drm_dbg_kms(&i915->drm, "Link Rate read failed\n"); - return DP_TEST_NAK; - } - test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); - - /* Validate the requested link rate and lane count */ - if (!intel_dp_link_params_valid(intel_dp, test_link_rate, - test_lane_count)) - return DP_TEST_NAK; - - intel_dp->compliance.test_lane_count = test_lane_count; - intel_dp->compliance.test_link_rate = test_link_rate; - - return DP_TEST_ACK; -} - -static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - u8 test_pattern; - u8 test_misc; - __be16 h_width, v_height; - int status = 0; - - /* Read the TEST_PATTERN (DP CTS 3.1.5) */ - status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN, - &test_pattern); - if (status <= 0) { - drm_dbg_kms(&i915->drm, "Test pattern read failed\n"); - return DP_TEST_NAK; - } - if (test_pattern != DP_COLOR_RAMP) - return DP_TEST_NAK; - - status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI, - &h_width, 2); - if (status <= 0) { - drm_dbg_kms(&i915->drm, "H Width read failed\n"); - return DP_TEST_NAK; - } - - status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI, - &v_height, 2); - if (status <= 0) { - drm_dbg_kms(&i915->drm, "V Height read failed\n"); - return DP_TEST_NAK; - } - - status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0, - &test_misc); - if (status <= 0) { - drm_dbg_kms(&i915->drm, "TEST MISC read failed\n"); - return DP_TEST_NAK; - } - if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB) - return DP_TEST_NAK; - if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA) - return DP_TEST_NAK; - switch (test_misc & DP_TEST_BIT_DEPTH_MASK) { - case DP_TEST_BIT_DEPTH_6: - intel_dp->compliance.test_data.bpc = 6; - break; - case DP_TEST_BIT_DEPTH_8: - intel_dp->compliance.test_data.bpc = 8; - break; - default: - return DP_TEST_NAK; - } - - intel_dp->compliance.test_data.video_pattern = test_pattern; - intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width); - intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height); - /* Set test active flag here so userspace doesn't interrupt things */ - intel_dp->compliance.test_active = true; - - return DP_TEST_ACK; -} - -static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - u8 test_result = DP_TEST_ACK; - struct intel_connector *intel_connector = intel_dp->attached_connector; - struct drm_connector *connector = &intel_connector->base; - - if (intel_connector->detect_edid == NULL || - connector->edid_corrupt || - intel_dp->aux.i2c_defer_count > 6) { - /* Check EDID read for NACKs, DEFERs and corruption - * (DP CTS 1.2 Core r1.1) - * 4.2.2.4 : Failed EDID read, I2C_NAK - * 4.2.2.5 : Failed EDID read, I2C_DEFER - * 4.2.2.6 : EDID corruption detected - * Use failsafe mode for all cases - */ - if (intel_dp->aux.i2c_nack_count > 0 || - intel_dp->aux.i2c_defer_count > 0) - drm_dbg_kms(&i915->drm, - "EDID read had %d NACKs, %d DEFERs\n", - intel_dp->aux.i2c_nack_count, - intel_dp->aux.i2c_defer_count); - intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE; - } else { - /* FIXME: Get rid of drm_edid_raw() */ - const struct edid *block = drm_edid_raw(intel_connector->detect_edid); - - /* We have to write the checksum of the last block read */ - block += block->extensions; - - if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM, - block->checksum) <= 0) - drm_dbg_kms(&i915->drm, - "Failed to write EDID checksum\n"); - - test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE; - intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED; - } - - /* Set test active flag here so userspace doesn't interrupt things */ - intel_dp->compliance.test_active = true; - - return test_result; -} - -static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = - to_i915(dp_to_dig_port(intel_dp)->base.base.dev); - struct drm_dp_phy_test_params *data = - &intel_dp->compliance.test_data.phytest; - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - enum pipe pipe = crtc->pipe; - u32 pattern_val; - - switch (data->phy_pattern) { - case DP_LINK_QUAL_PATTERN_DISABLE: - drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); - if (DISPLAY_VER(dev_priv) >= 10) - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), - DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, - DP_TP_CTL_LINK_TRAIN_NORMAL); - break; - case DP_LINK_QUAL_PATTERN_D10_2: - drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), - DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); - break; - case DP_LINK_QUAL_PATTERN_ERROR_RATE: - drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), - DDI_DP_COMP_CTL_ENABLE | - DDI_DP_COMP_CTL_SCRAMBLED_0); - break; - case DP_LINK_QUAL_PATTERN_PRBS7: - drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), - DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); - break; - case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM: - /* - * FIXME: Ideally pattern should come from DPCD 0x250. As - * current firmware of DPR-100 could not set it, so hardcoding - * now for complaince test. - */ - drm_dbg_kms(&dev_priv->drm, - "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); - pattern_val = 0x3e0f83e0; - intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val); - pattern_val = 0x0f83e0f8; - intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 1), pattern_val); - pattern_val = 0x0000f83e; - intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 2), pattern_val); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), - DDI_DP_COMP_CTL_ENABLE | - DDI_DP_COMP_CTL_CUSTOM80); - break; - case DP_LINK_QUAL_PATTERN_CP2520_PAT_1: - /* - * FIXME: Ideally pattern should come from DPCD 0x24A. As - * current firmware of DPR-100 could not set it, so hardcoding - * now for complaince test. - */ - drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n"); - pattern_val = 0xFB; - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), - DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | - pattern_val); - break; - case DP_LINK_QUAL_PATTERN_CP2520_PAT_3: - if (DISPLAY_VER(dev_priv) < 10) { - drm_warn(&dev_priv->drm, "Platform does not support TPS4\n"); - break; - } - drm_dbg_kms(&dev_priv->drm, "Set TPS4 compliance Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), - DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, - DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4); - break; - default: - drm_warn(&dev_priv->drm, "Invalid Phy Test Pattern\n"); - } -} - -static void intel_dp_process_phy_request(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - struct drm_dp_phy_test_params *data = - &intel_dp->compliance.test_data.phytest; - u8 link_status[DP_LINK_STATUS_SIZE]; - - if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, - link_status) < 0) { - drm_dbg_kms(&i915->drm, "failed to get link status\n"); - return; - } - - /* retrieve vswing & pre-emphasis setting */ - intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, - link_status); - - intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); - - intel_dp_phy_pattern_update(intel_dp, crtc_state); - - drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, - intel_dp->train_set, crtc_state->lane_count); - - drm_dp_set_phy_test_pattern(&intel_dp->aux, data, - intel_dp->dpcd[DP_DPCD_REV]); -} - -static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - struct drm_dp_phy_test_params *data = - &intel_dp->compliance.test_data.phytest; - - if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { - drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n"); - return DP_TEST_NAK; - } - - /* Set test active flag here so userspace doesn't interrupt things */ - intel_dp->compliance.test_active = true; - - return DP_TEST_ACK; -} - -static void intel_dp_handle_test_request(struct intel_dp *intel_dp) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - u8 response = DP_TEST_NAK; - u8 request = 0; - int status; - - status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request); - if (status <= 0) { - drm_dbg_kms(&i915->drm, - "Could not read test request from sink\n"); - goto update_status; - } - - switch (request) { - case DP_TEST_LINK_TRAINING: - drm_dbg_kms(&i915->drm, "LINK_TRAINING test requested\n"); - response = intel_dp_autotest_link_training(intel_dp); - break; - case DP_TEST_LINK_VIDEO_PATTERN: - drm_dbg_kms(&i915->drm, "TEST_PATTERN test requested\n"); - response = intel_dp_autotest_video_pattern(intel_dp); - break; - case DP_TEST_LINK_EDID_READ: - drm_dbg_kms(&i915->drm, "EDID test requested\n"); - response = intel_dp_autotest_edid(intel_dp); - break; - case DP_TEST_LINK_PHY_TEST_PATTERN: - drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n"); - response = intel_dp_autotest_phy_pattern(intel_dp); - break; - default: - drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n", - request); - break; - } - - if (response & DP_TEST_ACK) - intel_dp->compliance.test_type = request; - -update_status: - status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response); - if (status <= 0) - drm_dbg_kms(&i915->drm, - "Could not write test response to sink\n"); -} - static bool intel_dp_link_ok(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE]) { @@ -5308,8 +4941,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) return !intel_dp_link_ok(intel_dp, link_status); } -static bool intel_dp_has_connector(struct intel_dp *intel_dp, - const struct drm_connector_state *conn_state) +bool intel_dp_has_connector(struct intel_dp *intel_dp, + const struct drm_connector_state *conn_state) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct intel_encoder *encoder; @@ -5460,118 +5093,6 @@ void intel_dp_check_link_state(struct intel_dp *intel_dp) intel_encoder_link_check_queue_work(encoder, 0); } -static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, - struct drm_modeset_acquire_ctx *ctx, - u8 *pipe_mask) -{ - struct drm_i915_private *i915 = dp_to_i915(intel_dp); - struct drm_connector_list_iter conn_iter; - struct intel_connector *connector; - int ret = 0; - - *pipe_mask = 0; - - drm_connector_list_iter_begin(&i915->drm, &conn_iter); - for_each_intel_connector_iter(connector, &conn_iter) { - struct drm_connector_state *conn_state = - connector->base.state; - struct intel_crtc_state *crtc_state; - struct intel_crtc *crtc; - - if (!intel_dp_has_connector(intel_dp, conn_state)) - continue; - - crtc = to_intel_crtc(conn_state->crtc); - if (!crtc) - continue; - - ret = drm_modeset_lock(&crtc->base.mutex, ctx); - if (ret) - break; - - crtc_state = to_intel_crtc_state(crtc->base.state); - - drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state)); - - if (!crtc_state->hw.active) - continue; - - if (conn_state->commit && - !try_wait_for_completion(&conn_state->commit->hw_done)) - continue; - - *pipe_mask |= BIT(crtc->pipe); - } - drm_connector_list_iter_end(&conn_iter); - - return ret; -} - -static int intel_dp_do_phy_test(struct intel_encoder *encoder, - struct drm_modeset_acquire_ctx *ctx) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_crtc *crtc; - u8 pipe_mask; - int ret; - - ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, - ctx); - if (ret) - return ret; - - ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask); - if (ret) - return ret; - - if (pipe_mask == 0) - return 0; - - drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", - encoder->base.base.id, encoder->base.name); - - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { - const struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - - /* test on the MST master transcoder */ - if (DISPLAY_VER(dev_priv) >= 12 && - intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && - !intel_dp_mst_is_master_trans(crtc_state)) - continue; - - intel_dp_process_phy_request(intel_dp, crtc_state); - break; - } - - return 0; -} - -void intel_dp_phy_test(struct intel_encoder *encoder) -{ - struct drm_modeset_acquire_ctx ctx; - int ret; - - drm_modeset_acquire_init(&ctx, 0); - - for (;;) { - ret = intel_dp_do_phy_test(encoder, &ctx); - - if (ret == -EDEADLK) { - drm_modeset_backoff(&ctx); - continue; - } - - break; - } - - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - drm_WARN(encoder->base.dev, ret, - "Acquiring modeset locks failed with %i\n", ret); -} - static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index a0a31fb64716..3b869429e575 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -37,9 +37,6 @@ struct link_config_limits { }; void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp); -void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - struct link_config_limits *limits); bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); int intel_dp_min_bpp(enum intel_output_format output_format); @@ -191,7 +188,6 @@ void intel_dp_sync_state(struct intel_encoder *encoder, void intel_dp_check_frl_training(struct intel_dp *intel_dp); void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); -void intel_dp_phy_test(struct intel_encoder *encoder); void intel_dp_wait_source_oui(struct intel_dp *intel_dp); int intel_dp_output_bpp(enum intel_output_format output_format, int bpp); @@ -205,4 +201,9 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp, void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector); bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder); +bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, + u8 lane_count); +bool intel_dp_has_connector(struct intel_dp *intel_dp, + const struct drm_connector_state *conn_state); + #endif /* __INTEL_DP_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 7debefd4a0d6..c91e1e241a67 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -41,9 +41,10 @@ #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_hdcp.h" -#include "intel_dp_mst.h" -#include "intel_dp_tunnel.h" #include "intel_dp_link_training.h" +#include "intel_dp_mst.h" +#include "intel_dp_test.h" +#include "intel_dp_tunnel.h" #include "intel_dpio_phy.h" #include "intel_hdcp.h" #include "intel_hotplug.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c new file mode 100644 index 000000000000..41cb05f44670 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -0,0 +1,499 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2024 Intel Corporation */ + +#include +#include +#include + +#include "i915_drv.h" +#include "i915_reg.h" +#include "intel_ddi.h" +#include "intel_de.h" +#include "intel_display_types.h" +#include "intel_dp.h" +#include "intel_dp_link_training.h" +#include "intel_dp_mst.h" +#include "intel_dp_test.h" + +#define dp_to_i915(__intel_dp) to_i915(dp_to_dig_port(__intel_dp)->base.base.dev) + +/* Adjust link config limits based on compliance test requests. */ +void +intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + + /* For DP Compliance we override the computed bpp for the pipe */ + if (intel_dp->compliance.test_data.bpc != 0) { + int bpp = 3 * intel_dp->compliance.test_data.bpc; + + limits->pipe.min_bpp = limits->pipe.max_bpp = bpp; + pipe_config->dither_force_disable = bpp == 6 * 3; + + drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp); + } + + /* Use values requested by Compliance Test Request */ + if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { + int index; + + /* Validate the compliance test data since max values + * might have changed due to link train fallback. + */ + if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate, + intel_dp->compliance.test_lane_count)) { + index = intel_dp_rate_index(intel_dp->common_rates, + intel_dp->num_common_rates, + intel_dp->compliance.test_link_rate); + if (index >= 0) + limits->min_rate = limits->max_rate = + intel_dp->compliance.test_link_rate; + limits->min_lane_count = limits->max_lane_count = + intel_dp->compliance.test_lane_count; + } + } +} + +/* Compliance test status bits */ +#define INTEL_DP_RESOLUTION_SHIFT_MASK 0 +#define INTEL_DP_RESOLUTION_PREFERRED (1 << INTEL_DP_RESOLUTION_SHIFT_MASK) +#define INTEL_DP_RESOLUTION_STANDARD (2 << INTEL_DP_RESOLUTION_SHIFT_MASK) +#define INTEL_DP_RESOLUTION_FAILSAFE (3 << INTEL_DP_RESOLUTION_SHIFT_MASK) + +static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + int status = 0; + int test_link_rate; + u8 test_lane_count, test_link_bw; + /* (DP CTS 1.2) + * 4.3.1.11 + */ + /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */ + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT, + &test_lane_count); + + if (status <= 0) { + drm_dbg_kms(&i915->drm, "Lane count read failed\n"); + return DP_TEST_NAK; + } + test_lane_count &= DP_MAX_LANE_COUNT_MASK; + + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE, + &test_link_bw); + if (status <= 0) { + drm_dbg_kms(&i915->drm, "Link Rate read failed\n"); + return DP_TEST_NAK; + } + test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); + + /* Validate the requested link rate and lane count */ + if (!intel_dp_link_params_valid(intel_dp, test_link_rate, + test_lane_count)) + return DP_TEST_NAK; + + intel_dp->compliance.test_lane_count = test_lane_count; + intel_dp->compliance.test_link_rate = test_link_rate; + + return DP_TEST_ACK; +} + +static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 test_pattern; + u8 test_misc; + __be16 h_width, v_height; + int status = 0; + + /* Read the TEST_PATTERN (DP CTS 3.1.5) */ + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN, + &test_pattern); + if (status <= 0) { + drm_dbg_kms(&i915->drm, "Test pattern read failed\n"); + return DP_TEST_NAK; + } + if (test_pattern != DP_COLOR_RAMP) + return DP_TEST_NAK; + + status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI, + &h_width, 2); + if (status <= 0) { + drm_dbg_kms(&i915->drm, "H Width read failed\n"); + return DP_TEST_NAK; + } + + status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI, + &v_height, 2); + if (status <= 0) { + drm_dbg_kms(&i915->drm, "V Height read failed\n"); + return DP_TEST_NAK; + } + + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0, + &test_misc); + if (status <= 0) { + drm_dbg_kms(&i915->drm, "TEST MISC read failed\n"); + return DP_TEST_NAK; + } + if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB) + return DP_TEST_NAK; + if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA) + return DP_TEST_NAK; + switch (test_misc & DP_TEST_BIT_DEPTH_MASK) { + case DP_TEST_BIT_DEPTH_6: + intel_dp->compliance.test_data.bpc = 6; + break; + case DP_TEST_BIT_DEPTH_8: + intel_dp->compliance.test_data.bpc = 8; + break; + default: + return DP_TEST_NAK; + } + + intel_dp->compliance.test_data.video_pattern = test_pattern; + intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width); + intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height); + /* Set test active flag here so userspace doesn't interrupt things */ + intel_dp->compliance.test_active = true; + + return DP_TEST_ACK; +} + +static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 test_result = DP_TEST_ACK; + struct intel_connector *intel_connector = intel_dp->attached_connector; + struct drm_connector *connector = &intel_connector->base; + + if (intel_connector->detect_edid == NULL || + connector->edid_corrupt || + intel_dp->aux.i2c_defer_count > 6) { + /* Check EDID read for NACKs, DEFERs and corruption + * (DP CTS 1.2 Core r1.1) + * 4.2.2.4 : Failed EDID read, I2C_NAK + * 4.2.2.5 : Failed EDID read, I2C_DEFER + * 4.2.2.6 : EDID corruption detected + * Use failsafe mode for all cases + */ + if (intel_dp->aux.i2c_nack_count > 0 || + intel_dp->aux.i2c_defer_count > 0) + drm_dbg_kms(&i915->drm, + "EDID read had %d NACKs, %d DEFERs\n", + intel_dp->aux.i2c_nack_count, + intel_dp->aux.i2c_defer_count); + intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE; + } else { + /* FIXME: Get rid of drm_edid_raw() */ + const struct edid *block = drm_edid_raw(intel_connector->detect_edid); + + /* We have to write the checksum of the last block read */ + block += block->extensions; + + if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM, + block->checksum) <= 0) + drm_dbg_kms(&i915->drm, + "Failed to write EDID checksum\n"); + + test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE; + intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED; + } + + /* Set test active flag here so userspace doesn't interrupt things */ + intel_dp->compliance.test_active = true; + + return test_result; +} + +static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = + to_i915(dp_to_dig_port(intel_dp)->base.base.dev); + struct drm_dp_phy_test_params *data = + &intel_dp->compliance.test_data.phytest; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + enum pipe pipe = crtc->pipe; + u32 pattern_val; + + switch (data->phy_pattern) { + case DP_LINK_QUAL_PATTERN_DISABLE: + drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n"); + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); + if (DISPLAY_VER(dev_priv) >= 10) + intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, + DP_TP_CTL_LINK_TRAIN_NORMAL); + break; + case DP_LINK_QUAL_PATTERN_D10_2: + drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n"); + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); + break; + case DP_LINK_QUAL_PATTERN_ERROR_RATE: + drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n"); + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + DDI_DP_COMP_CTL_ENABLE | + DDI_DP_COMP_CTL_SCRAMBLED_0); + break; + case DP_LINK_QUAL_PATTERN_PRBS7: + drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n"); + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); + break; + case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM: + /* + * FIXME: Ideally pattern should come from DPCD 0x250. As + * current firmware of DPR-100 could not set it, so hardcoding + * now for complaince test. + */ + drm_dbg_kms(&dev_priv->drm, + "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); + pattern_val = 0x3e0f83e0; + intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val); + pattern_val = 0x0f83e0f8; + intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 1), pattern_val); + pattern_val = 0x0000f83e; + intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 2), pattern_val); + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + DDI_DP_COMP_CTL_ENABLE | + DDI_DP_COMP_CTL_CUSTOM80); + break; + case DP_LINK_QUAL_PATTERN_CP2520_PAT_1: + /* + * FIXME: Ideally pattern should come from DPCD 0x24A. As + * current firmware of DPR-100 could not set it, so hardcoding + * now for complaince test. + */ + drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n"); + pattern_val = 0xFB; + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | + pattern_val); + break; + case DP_LINK_QUAL_PATTERN_CP2520_PAT_3: + if (DISPLAY_VER(dev_priv) < 10) { + drm_warn(&dev_priv->drm, "Platform does not support TPS4\n"); + break; + } + drm_dbg_kms(&dev_priv->drm, "Set TPS4 compliance Phy Test Pattern\n"); + intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); + intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, + DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4); + break; + default: + drm_warn(&dev_priv->drm, "Invalid Phy Test Pattern\n"); + } +} + +static void intel_dp_process_phy_request(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct drm_dp_phy_test_params *data = + &intel_dp->compliance.test_data.phytest; + u8 link_status[DP_LINK_STATUS_SIZE]; + + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, + link_status) < 0) { + drm_dbg_kms(&i915->drm, "failed to get link status\n"); + return; + } + + /* retrieve vswing & pre-emphasis setting */ + intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, + link_status); + + intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); + + intel_dp_phy_pattern_update(intel_dp, crtc_state); + + drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, + intel_dp->train_set, crtc_state->lane_count); + + drm_dp_set_phy_test_pattern(&intel_dp->aux, data, + intel_dp->dpcd[DP_DPCD_REV]); +} + +static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct drm_dp_phy_test_params *data = + &intel_dp->compliance.test_data.phytest; + + if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { + drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n"); + return DP_TEST_NAK; + } + + /* Set test active flag here so userspace doesn't interrupt things */ + intel_dp->compliance.test_active = true; + + return DP_TEST_ACK; +} + +void intel_dp_handle_test_request(struct intel_dp *intel_dp) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 response = DP_TEST_NAK; + u8 request = 0; + int status; + + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request); + if (status <= 0) { + drm_dbg_kms(&i915->drm, + "Could not read test request from sink\n"); + goto update_status; + } + + switch (request) { + case DP_TEST_LINK_TRAINING: + drm_dbg_kms(&i915->drm, "LINK_TRAINING test requested\n"); + response = intel_dp_autotest_link_training(intel_dp); + break; + case DP_TEST_LINK_VIDEO_PATTERN: + drm_dbg_kms(&i915->drm, "TEST_PATTERN test requested\n"); + response = intel_dp_autotest_video_pattern(intel_dp); + break; + case DP_TEST_LINK_EDID_READ: + drm_dbg_kms(&i915->drm, "EDID test requested\n"); + response = intel_dp_autotest_edid(intel_dp); + break; + case DP_TEST_LINK_PHY_TEST_PATTERN: + drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n"); + response = intel_dp_autotest_phy_pattern(intel_dp); + break; + default: + drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n", + request); + break; + } + + if (response & DP_TEST_ACK) + intel_dp->compliance.test_type = request; + +update_status: + status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response); + if (status <= 0) + drm_dbg_kms(&i915->drm, + "Could not write test response to sink\n"); +} + +/* phy test */ + +static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, + struct drm_modeset_acquire_ctx *ctx, + u8 *pipe_mask) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct drm_connector_list_iter conn_iter; + struct intel_connector *connector; + int ret = 0; + + *pipe_mask = 0; + + drm_connector_list_iter_begin(&i915->drm, &conn_iter); + for_each_intel_connector_iter(connector, &conn_iter) { + struct drm_connector_state *conn_state = + connector->base.state; + struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc; + + if (!intel_dp_has_connector(intel_dp, conn_state)) + continue; + + crtc = to_intel_crtc(conn_state->crtc); + if (!crtc) + continue; + + ret = drm_modeset_lock(&crtc->base.mutex, ctx); + if (ret) + break; + + crtc_state = to_intel_crtc_state(crtc->base.state); + + drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state)); + + if (!crtc_state->hw.active) + continue; + + if (conn_state->commit && + !try_wait_for_completion(&conn_state->commit->hw_done)) + continue; + + *pipe_mask |= BIT(crtc->pipe); + } + drm_connector_list_iter_end(&conn_iter); + + return ret; +} + +static int intel_dp_do_phy_test(struct intel_encoder *encoder, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_crtc *crtc; + u8 pipe_mask; + int ret; + + ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, + ctx); + if (ret) + return ret; + + ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask); + if (ret) + return ret; + + if (pipe_mask == 0) + return 0; + + drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", + encoder->base.base.id, encoder->base.name); + + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + /* test on the MST master transcoder */ + if (DISPLAY_VER(dev_priv) >= 12 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && + !intel_dp_mst_is_master_trans(crtc_state)) + continue; + + intel_dp_process_phy_request(intel_dp, crtc_state); + break; + } + + return 0; +} + +void intel_dp_phy_test(struct intel_encoder *encoder) +{ + struct drm_modeset_acquire_ctx ctx; + int ret; + + drm_modeset_acquire_init(&ctx, 0); + + for (;;) { + ret = intel_dp_do_phy_test(encoder, &ctx); + + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + continue; + } + + break; + } + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + drm_WARN(encoder->base.dev, ret, + "Acquiring modeset locks failed with %i\n", ret); +} diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.h b/drivers/gpu/drm/i915/display/intel_dp_test.h new file mode 100644 index 000000000000..e865e6a3aaa3 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dp_test.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2024 Intel Corporation */ + +#ifndef __INTEL_DP_TEST_H__ +#define __INTEL_DP_TEST_H__ + +struct intel_crtc_state; +struct intel_dp; +struct intel_encoder; +struct link_config_limits; + +void intel_dp_handle_test_request(struct intel_dp *intel_dp); +void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits); +void intel_dp_phy_test(struct intel_encoder *encoder); + +#endif /* __INTEL_DP_TEST_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 8fa7e4dd6d69..d1ead7807146 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -220,6 +220,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_dp_hdcp.o \ i915-display/intel_dp_link_training.o \ i915-display/intel_dp_mst.o \ + i915-display/intel_dp_test.o \ i915-display/intel_dpll.o \ i915-display/intel_dpll_mgr.o \ i915-display/intel_dpt_common.o \ From 7cd3fcc90a4a7dafe01880181d96295ed807576d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:44 +0300 Subject: [PATCH 112/205] drm/i915/dp: fix style issues in intel_dp_test.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply some style fixes on top of the previous code movement. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/330f918a3b4fe6dd156dd89ee26c56cf8ae8ec31.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_test.c | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 41cb05f44670..0a49b15f99e6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -29,7 +29,8 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, if (intel_dp->compliance.test_data.bpc != 0) { int bpp = 3 * intel_dp->compliance.test_data.bpc; - limits->pipe.min_bpp = limits->pipe.max_bpp = bpp; + limits->pipe.min_bpp = bpp; + limits->pipe.max_bpp = bpp; pipe_config->dither_force_disable = bpp == 6 * 3; drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp); @@ -47,20 +48,20 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, index = intel_dp_rate_index(intel_dp->common_rates, intel_dp->num_common_rates, intel_dp->compliance.test_link_rate); - if (index >= 0) - limits->min_rate = limits->max_rate = - intel_dp->compliance.test_link_rate; - limits->min_lane_count = limits->max_lane_count = - intel_dp->compliance.test_lane_count; + if (index >= 0) { + limits->min_rate = intel_dp->compliance.test_link_rate; + limits->max_rate = intel_dp->compliance.test_link_rate; + } + limits->min_lane_count = intel_dp->compliance.test_lane_count; + limits->max_lane_count = intel_dp->compliance.test_lane_count; } } } /* Compliance test status bits */ -#define INTEL_DP_RESOLUTION_SHIFT_MASK 0 -#define INTEL_DP_RESOLUTION_PREFERRED (1 << INTEL_DP_RESOLUTION_SHIFT_MASK) -#define INTEL_DP_RESOLUTION_STANDARD (2 << INTEL_DP_RESOLUTION_SHIFT_MASK) -#define INTEL_DP_RESOLUTION_FAILSAFE (3 << INTEL_DP_RESOLUTION_SHIFT_MASK) +#define INTEL_DP_RESOLUTION_PREFERRED 1 +#define INTEL_DP_RESOLUTION_STANDARD 2 +#define INTEL_DP_RESOLUTION_FAILSAFE 3 static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) { @@ -169,8 +170,7 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) struct intel_connector *intel_connector = intel_dp->attached_connector; struct drm_connector *connector = &intel_connector->base; - if (intel_connector->detect_edid == NULL || - connector->edid_corrupt || + if (!intel_connector->detect_edid || connector->edid_corrupt || intel_dp->aux.i2c_defer_count > 6) { /* Check EDID read for NACKs, DEFERs and corruption * (DP CTS 1.2 Core r1.1) @@ -180,7 +180,7 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) * Use failsafe mode for all cases */ if (intel_dp->aux.i2c_nack_count > 0 || - intel_dp->aux.i2c_defer_count > 0) + intel_dp->aux.i2c_defer_count > 0) drm_dbg_kms(&i915->drm, "EDID read had %d NACKs, %d DEFERs\n", intel_dp->aux.i2c_nack_count, From 2783bb2a67270da3359c1b6dc9df8918877c18aa Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:45 +0300 Subject: [PATCH 113/205] drm/i915/dp: convert intel_dp_test.c struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefer struct intel_display over struct drm_i915_private. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/5b4ae05c6b3f1608bddb09078b616eff6b93efdd.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_test.c | 123 ++++++++++--------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 0a49b15f99e6..efdf25dfef51 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -15,15 +15,13 @@ #include "intel_dp_mst.h" #include "intel_dp_test.h" -#define dp_to_i915(__intel_dp) to_i915(dp_to_dig_port(__intel_dp)->base.base.dev) - /* Adjust link config limits based on compliance test requests. */ void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); /* For DP Compliance we override the computed bpp for the pipe */ if (intel_dp->compliance.test_data.bpc != 0) { @@ -33,7 +31,7 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, limits->pipe.max_bpp = bpp; pipe_config->dither_force_disable = bpp == 6 * 3; - drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp); + drm_dbg_kms(display->drm, "Setting pipe_bpp to %d\n", bpp); } /* Use values requested by Compliance Test Request */ @@ -65,7 +63,7 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); int status = 0; int test_link_rate; u8 test_lane_count, test_link_bw; @@ -77,7 +75,7 @@ static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) &test_lane_count); if (status <= 0) { - drm_dbg_kms(&i915->drm, "Lane count read failed\n"); + drm_dbg_kms(display->drm, "Lane count read failed\n"); return DP_TEST_NAK; } test_lane_count &= DP_MAX_LANE_COUNT_MASK; @@ -85,7 +83,7 @@ static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE, &test_link_bw); if (status <= 0) { - drm_dbg_kms(&i915->drm, "Link Rate read failed\n"); + drm_dbg_kms(display->drm, "Link Rate read failed\n"); return DP_TEST_NAK; } test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); @@ -103,7 +101,7 @@ static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); u8 test_pattern; u8 test_misc; __be16 h_width, v_height; @@ -113,7 +111,7 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN, &test_pattern); if (status <= 0) { - drm_dbg_kms(&i915->drm, "Test pattern read failed\n"); + drm_dbg_kms(display->drm, "Test pattern read failed\n"); return DP_TEST_NAK; } if (test_pattern != DP_COLOR_RAMP) @@ -122,21 +120,21 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI, &h_width, 2); if (status <= 0) { - drm_dbg_kms(&i915->drm, "H Width read failed\n"); + drm_dbg_kms(display->drm, "H Width read failed\n"); return DP_TEST_NAK; } status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI, &v_height, 2); if (status <= 0) { - drm_dbg_kms(&i915->drm, "V Height read failed\n"); + drm_dbg_kms(display->drm, "V Height read failed\n"); return DP_TEST_NAK; } status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0, &test_misc); if (status <= 0) { - drm_dbg_kms(&i915->drm, "TEST MISC read failed\n"); + drm_dbg_kms(display->drm, "TEST MISC read failed\n"); return DP_TEST_NAK; } if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB) @@ -165,7 +163,7 @@ static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); u8 test_result = DP_TEST_ACK; struct intel_connector *intel_connector = intel_dp->attached_connector; struct drm_connector *connector = &intel_connector->base; @@ -181,7 +179,7 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) */ if (intel_dp->aux.i2c_nack_count > 0 || intel_dp->aux.i2c_defer_count > 0) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "EDID read had %d NACKs, %d DEFERs\n", intel_dp->aux.i2c_nack_count, intel_dp->aux.i2c_defer_count); @@ -195,7 +193,7 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM, block->checksum) <= 0) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Failed to write EDID checksum\n"); test_result = DP_TEST_ACK | DP_TEST_EDID_CHECKSUM_WRITE; @@ -211,8 +209,7 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = - to_i915(dp_to_dig_port(intel_dp)->base.base.dev); + struct intel_display *display = to_intel_display(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -222,27 +219,28 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, switch (data->phy_pattern) { case DP_LINK_QUAL_PATTERN_DISABLE: - drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); - if (DISPLAY_VER(dev_priv) >= 10) - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + drm_dbg_kms(display->drm, "Disable Phy Test Pattern\n"); + intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0); + if (DISPLAY_VER(display) >= 10) + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, DP_TP_CTL_LINK_TRAIN_NORMAL); break; case DP_LINK_QUAL_PATTERN_D10_2: - drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + drm_dbg_kms(display->drm, "Set D10.2 Phy Test Pattern\n"); + intel_de_write(display, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); break; case DP_LINK_QUAL_PATTERN_ERROR_RATE: - drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + drm_dbg_kms(display->drm, + "Set Error Count Phy Test Pattern\n"); + intel_de_write(display, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_SCRAMBLED_0); break; case DP_LINK_QUAL_PATTERN_PRBS7: - drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + drm_dbg_kms(display->drm, "Set PRBS7 Phy Test Pattern\n"); + intel_de_write(display, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); break; case DP_LINK_QUAL_PATTERN_80BIT_CUSTOM: @@ -251,15 +249,15 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, * current firmware of DPR-100 could not set it, so hardcoding * now for complaince test. */ - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); pattern_val = 0x3e0f83e0; - intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val); + intel_de_write(display, DDI_DP_COMP_PAT(pipe, 0), pattern_val); pattern_val = 0x0f83e0f8; - intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 1), pattern_val); + intel_de_write(display, DDI_DP_COMP_PAT(pipe, 1), pattern_val); pattern_val = 0x0000f83e; - intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 2), pattern_val); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + intel_de_write(display, DDI_DP_COMP_PAT(pipe, 2), pattern_val); + intel_de_write(display, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_CUSTOM80); break; @@ -269,39 +267,42 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, * current firmware of DPR-100 could not set it, so hardcoding * now for complaince test. */ - drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n"); + drm_dbg_kms(display->drm, + "Set HBR2 compliance Phy Test Pattern\n"); pattern_val = 0xFB; - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), + intel_de_write(display, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | pattern_val); break; case DP_LINK_QUAL_PATTERN_CP2520_PAT_3: - if (DISPLAY_VER(dev_priv) < 10) { - drm_warn(&dev_priv->drm, "Platform does not support TPS4\n"); + if (DISPLAY_VER(display) < 10) { + drm_warn(display->drm, + "Platform does not support TPS4\n"); break; } - drm_dbg_kms(&dev_priv->drm, "Set TPS4 compliance Phy Test Pattern\n"); - intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + drm_dbg_kms(display->drm, + "Set TPS4 compliance Phy Test Pattern\n"); + intel_de_write(display, DDI_DP_COMP_CTL(pipe), 0x0); + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_TRAIN_PAT4_SEL_MASK | DP_TP_CTL_LINK_TRAIN_MASK, DP_TP_CTL_TRAIN_PAT4_SEL_TP4A | DP_TP_CTL_LINK_TRAIN_PAT4); break; default: - drm_warn(&dev_priv->drm, "Invalid Phy Test Pattern\n"); + drm_warn(display->drm, "Invalid Phy Test Pattern\n"); } } static void intel_dp_process_phy_request(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; u8 link_status[DP_LINK_STATUS_SIZE]; if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, link_status) < 0) { - drm_dbg_kms(&i915->drm, "failed to get link status\n"); + drm_dbg_kms(display->drm, "failed to get link status\n"); return; } @@ -322,12 +323,13 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { - drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n"); + drm_dbg_kms(display->drm, + "DP Phy Test pattern AUX read failure\n"); return DP_TEST_NAK; } @@ -339,37 +341,37 @@ static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) void intel_dp_handle_test_request(struct intel_dp *intel_dp) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); u8 response = DP_TEST_NAK; u8 request = 0; int status; status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request); if (status <= 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Could not read test request from sink\n"); goto update_status; } switch (request) { case DP_TEST_LINK_TRAINING: - drm_dbg_kms(&i915->drm, "LINK_TRAINING test requested\n"); + drm_dbg_kms(display->drm, "LINK_TRAINING test requested\n"); response = intel_dp_autotest_link_training(intel_dp); break; case DP_TEST_LINK_VIDEO_PATTERN: - drm_dbg_kms(&i915->drm, "TEST_PATTERN test requested\n"); + drm_dbg_kms(display->drm, "TEST_PATTERN test requested\n"); response = intel_dp_autotest_video_pattern(intel_dp); break; case DP_TEST_LINK_EDID_READ: - drm_dbg_kms(&i915->drm, "EDID test requested\n"); + drm_dbg_kms(display->drm, "EDID test requested\n"); response = intel_dp_autotest_edid(intel_dp); break; case DP_TEST_LINK_PHY_TEST_PATTERN: - drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n"); + drm_dbg_kms(display->drm, "PHY_PATTERN test requested\n"); response = intel_dp_autotest_phy_pattern(intel_dp); break; default: - drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n", + drm_dbg_kms(display->drm, "Invalid test request '%02x'\n", request); break; } @@ -380,7 +382,7 @@ void intel_dp_handle_test_request(struct intel_dp *intel_dp) update_status: status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response); if (status <= 0) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Could not write test response to sink\n"); } @@ -390,14 +392,14 @@ static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx, u8 *pipe_mask) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_display *display = to_intel_display(intel_dp); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; int ret = 0; *pipe_mask = 0; - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { struct drm_connector_state *conn_state = connector->base.state; @@ -417,7 +419,8 @@ static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, crtc_state = to_intel_crtc_state(crtc->base.state); - drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state)); + drm_WARN_ON(display->drm, + !intel_crtc_has_dp_encoder(crtc_state)); if (!crtc_state->hw.active) continue; @@ -436,13 +439,13 @@ static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, static int intel_dp_do_phy_test(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *crtc; u8 pipe_mask; int ret; - ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, + ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, ctx); if (ret) return ret; @@ -454,15 +457,15 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, if (pipe_mask == 0) return 0; - drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n", encoder->base.base.id, encoder->base.name); - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); /* test on the MST master transcoder */ - if (DISPLAY_VER(dev_priv) >= 12 && + if (DISPLAY_VER(display) >= 12 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && !intel_dp_mst_is_master_trans(crtc_state)) continue; From c617b5f34c9ef0ba35c3f1d76e7e813f4944aeea Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:46 +0300 Subject: [PATCH 114/205] drm/i915/dp: clean up intel_dp_test.[ch] interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conform to uniform function naming. Use intel_dp. Hide checks on intel_dp->compliance within intel_dp_test.[ch]. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/c2905006d2d47040032153ca69052898529a95d5.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 6 +----- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +----- drivers/gpu/drm/i915/display/intel_dp.c | 4 ++-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_test.c | 15 +++++++++++---- drivers/gpu/drm/i915/display/intel_dp_test.h | 13 +++++++------ 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index ac9dce8213a3..440fb3002f28 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1169,12 +1169,8 @@ intel_dp_hotplug(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); enum intel_hotplug_state state; - if (intel_dp->compliance.test_active && - intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { - intel_dp_phy_test(encoder); - /* just do the PHY test and nothing else */ + if (intel_dp_test_phy(intel_dp)) return INTEL_HOTPLUG_UNCHANGED; - } state = intel_encoder_hotplug(encoder, connector); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index c0ade280d816..fe1ded6707f9 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4551,12 +4551,8 @@ intel_ddi_hotplug(struct intel_encoder *encoder, enum intel_hotplug_state state; int ret; - if (intel_dp->compliance.test_active && - intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { - intel_dp_phy_test(encoder); - /* just do the PHY test and nothing else */ + if (intel_dp_test_phy(intel_dp)) return INTEL_HOTPLUG_UNCHANGED; - } state = intel_encoder_hotplug(encoder, connector); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 1cc73e2bf1fe..38aeb337ef53 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2455,7 +2455,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, limits->min_rate = limits->max_rate; } - intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits); + intel_dp_test_compute_config(intel_dp, crtc_state, limits); return intel_dp_compute_config_link_bpp_limits(intel_dp, crtc_state, @@ -5108,7 +5108,7 @@ static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp) drm_dp_dpcd_writeb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val); if (val & DP_AUTOMATED_TEST_REQUEST) - intel_dp_handle_test_request(intel_dp); + intel_dp_test_request(intel_dp); if (val & DP_CP_IRQ) intel_hdcp_handle_cp_irq(intel_dp->attached_connector); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c91e1e241a67..732d7543ad06 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -542,7 +542,7 @@ intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp, */ limits->pipe.max_bpp = min(crtc_state->pipe_bpp, 24); - intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits); + intel_dp_test_compute_config(intel_dp, crtc_state, limits); if (!intel_dp_compute_config_link_bpp_limits(intel_dp, crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index efdf25dfef51..4608aa34df42 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -16,8 +16,7 @@ #include "intel_dp_test.h" /* Adjust link config limits based on compliance test requests. */ -void -intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, +void intel_dp_test_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits) { @@ -339,7 +338,7 @@ static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) return DP_TEST_ACK; } -void intel_dp_handle_test_request(struct intel_dp *intel_dp) +void intel_dp_test_request(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); u8 response = DP_TEST_NAK; @@ -477,11 +476,17 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, return 0; } -void intel_dp_phy_test(struct intel_encoder *encoder) +bool intel_dp_test_phy(struct intel_dp *intel_dp) { + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *encoder = &dig_port->base; struct drm_modeset_acquire_ctx ctx; int ret; + if (!intel_dp->compliance.test_active || + intel_dp->compliance.test_type != DP_TEST_LINK_PHY_TEST_PATTERN) + return false; + drm_modeset_acquire_init(&ctx, 0); for (;;) { @@ -499,4 +504,6 @@ void intel_dp_phy_test(struct intel_encoder *encoder) drm_modeset_acquire_fini(&ctx); drm_WARN(encoder->base.dev, ret, "Acquiring modeset locks failed with %i\n", ret); + + return true; } diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.h b/drivers/gpu/drm/i915/display/intel_dp_test.h index e865e6a3aaa3..cfd3dccdd91d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.h +++ b/drivers/gpu/drm/i915/display/intel_dp_test.h @@ -4,15 +4,16 @@ #ifndef __INTEL_DP_TEST_H__ #define __INTEL_DP_TEST_H__ +#include + struct intel_crtc_state; struct intel_dp; -struct intel_encoder; struct link_config_limits; -void intel_dp_handle_test_request(struct intel_dp *intel_dp); -void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - struct link_config_limits *limits); -void intel_dp_phy_test(struct intel_encoder *encoder); +void intel_dp_test_request(struct intel_dp *intel_dp); +void intel_dp_test_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits); +bool intel_dp_test_phy(struct intel_dp *intel_dp); #endif /* __INTEL_DP_TEST_H__ */ From a60121f697ddc18b7ad70bc9910c745bafcc11fb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:47 +0300 Subject: [PATCH 115/205] drm/i915/dp: move DP test debugfs files next to the functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the DP test debugfs files to intel_dp_test.[ch]. Side note: The debugfs looks like it begs to be converted to connector debugfs, but that's for another day. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/46779bc4e420868e21bd5e72fdf245a541252fde.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_debugfs.c | 197 +--------------- drivers/gpu/drm/i915/display/intel_dp_test.c | 217 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dp_test.h | 2 + 3 files changed, 221 insertions(+), 195 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index a3f9514f69ea..484be08048cf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -27,6 +27,7 @@ #include "intel_dp.h" #include "intel_dp_link_training.h" #include "intel_dp_mst.h" +#include "intel_dp_test.h" #include "intel_drrs.h" #include "intel_fb.h" #include "intel_fbc.h" @@ -792,198 +793,6 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused) return 0; } -static ssize_t i915_displayport_test_active_write(struct file *file, - const char __user *ubuf, - size_t len, loff_t *offp) -{ - char *input_buffer; - int status = 0; - struct drm_device *dev; - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; - struct intel_dp *intel_dp; - int val = 0; - - dev = ((struct seq_file *)file->private_data)->private; - - if (len == 0) - return 0; - - input_buffer = memdup_user_nul(ubuf, len); - if (IS_ERR(input_buffer)) - return PTR_ERR(input_buffer); - - drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len); - - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - struct intel_encoder *encoder; - - if (connector->connector_type != - DRM_MODE_CONNECTOR_DisplayPort) - continue; - - encoder = to_intel_encoder(connector->encoder); - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) - continue; - - if (encoder && connector->status == connector_status_connected) { - intel_dp = enc_to_intel_dp(encoder); - status = kstrtoint(input_buffer, 10, &val); - if (status < 0) - break; - drm_dbg(dev, "Got %d for test active\n", val); - /* To prevent erroneous activation of the compliance - * testing code, only accept an actual value of 1 here - */ - if (val == 1) - intel_dp->compliance.test_active = true; - else - intel_dp->compliance.test_active = false; - } - } - drm_connector_list_iter_end(&conn_iter); - kfree(input_buffer); - if (status < 0) - return status; - - *offp += len; - return len; -} - -static int i915_displayport_test_active_show(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = m->private; - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; - struct intel_dp *intel_dp; - - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - struct intel_encoder *encoder; - - if (connector->connector_type != - DRM_MODE_CONNECTOR_DisplayPort) - continue; - - encoder = to_intel_encoder(connector->encoder); - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) - continue; - - if (encoder && connector->status == connector_status_connected) { - intel_dp = enc_to_intel_dp(encoder); - if (intel_dp->compliance.test_active) - seq_puts(m, "1"); - else - seq_puts(m, "0"); - } else - seq_puts(m, "0"); - } - drm_connector_list_iter_end(&conn_iter); - - return 0; -} - -static int i915_displayport_test_active_open(struct inode *inode, - struct file *file) -{ - return single_open(file, i915_displayport_test_active_show, - inode->i_private); -} - -static const struct file_operations i915_displayport_test_active_fops = { - .owner = THIS_MODULE, - .open = i915_displayport_test_active_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = i915_displayport_test_active_write -}; - -static int i915_displayport_test_data_show(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = m->private; - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; - struct intel_dp *intel_dp; - - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - struct intel_encoder *encoder; - - if (connector->connector_type != - DRM_MODE_CONNECTOR_DisplayPort) - continue; - - encoder = to_intel_encoder(connector->encoder); - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) - continue; - - if (encoder && connector->status == connector_status_connected) { - intel_dp = enc_to_intel_dp(encoder); - if (intel_dp->compliance.test_type == - DP_TEST_LINK_EDID_READ) - seq_printf(m, "%lx", - intel_dp->compliance.test_data.edid); - else if (intel_dp->compliance.test_type == - DP_TEST_LINK_VIDEO_PATTERN) { - seq_printf(m, "hdisplay: %d\n", - intel_dp->compliance.test_data.hdisplay); - seq_printf(m, "vdisplay: %d\n", - intel_dp->compliance.test_data.vdisplay); - seq_printf(m, "bpc: %u\n", - intel_dp->compliance.test_data.bpc); - } else if (intel_dp->compliance.test_type == - DP_TEST_LINK_PHY_TEST_PATTERN) { - seq_printf(m, "pattern: %d\n", - intel_dp->compliance.test_data.phytest.phy_pattern); - seq_printf(m, "Number of lanes: %d\n", - intel_dp->compliance.test_data.phytest.num_lanes); - seq_printf(m, "Link Rate: %d\n", - intel_dp->compliance.test_data.phytest.link_rate); - seq_printf(m, "level: %02x\n", - intel_dp->train_set[0]); - } - } else - seq_puts(m, "0"); - } - drm_connector_list_iter_end(&conn_iter); - - return 0; -} -DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data); - -static int i915_displayport_test_type_show(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = m->private; - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; - struct intel_dp *intel_dp; - - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - struct intel_encoder *encoder; - - if (connector->connector_type != - DRM_MODE_CONNECTOR_DisplayPort) - continue; - - encoder = to_intel_encoder(connector->encoder); - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) - continue; - - if (encoder && connector->status == connector_status_connected) { - intel_dp = enc_to_intel_dp(encoder); - seq_printf(m, "%02lx\n", intel_dp->compliance.test_type); - } else - seq_puts(m, "0"); - } - drm_connector_list_iter_end(&conn_iter); - - return 0; -} -DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type); - static ssize_t i915_fifo_underrun_reset_write(struct file *filp, const char __user *ubuf, @@ -1062,9 +871,6 @@ static const struct { const struct file_operations *fops; } intel_display_debugfs_files[] = { {"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops}, - {"i915_dp_test_data", &i915_displayport_test_data_fops}, - {"i915_dp_test_type", &i915_displayport_test_type_fops}, - {"i915_dp_test_active", &i915_displayport_test_active_fops}, }; void intel_display_debugfs_register(struct drm_i915_private *i915) @@ -1088,6 +894,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) intel_bios_debugfs_register(display); intel_cdclk_debugfs_register(display); intel_dmc_debugfs_register(display); + intel_dp_test_debugfs_register(display); intel_fbc_debugfs_register(display); intel_hpd_debugfs_register(i915); intel_opregion_debugfs_register(display); diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 4608aa34df42..7a9b0ad161d6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ +#include + #include #include #include @@ -507,3 +509,218 @@ bool intel_dp_test_phy(struct intel_dp *intel_dp) return true; } + +static ssize_t i915_displayport_test_active_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + char *input_buffer; + int status = 0; + struct drm_device *dev; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + struct intel_dp *intel_dp; + int val = 0; + + dev = ((struct seq_file *)file->private_data)->private; + + if (len == 0) + return 0; + + input_buffer = memdup_user_nul(ubuf, len); + if (IS_ERR(input_buffer)) + return PTR_ERR(input_buffer); + + drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len); + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + struct intel_encoder *encoder; + + if (connector->connector_type != + DRM_MODE_CONNECTOR_DisplayPort) + continue; + + encoder = to_intel_encoder(connector->encoder); + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) + continue; + + if (encoder && connector->status == connector_status_connected) { + intel_dp = enc_to_intel_dp(encoder); + status = kstrtoint(input_buffer, 10, &val); + if (status < 0) + break; + drm_dbg(dev, "Got %d for test active\n", val); + /* To prevent erroneous activation of the compliance + * testing code, only accept an actual value of 1 here + */ + if (val == 1) + intel_dp->compliance.test_active = true; + else + intel_dp->compliance.test_active = false; + } + } + drm_connector_list_iter_end(&conn_iter); + kfree(input_buffer); + if (status < 0) + return status; + + *offp += len; + return len; +} + +static int i915_displayport_test_active_show(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = m->private; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + struct intel_dp *intel_dp; + + drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + struct intel_encoder *encoder; + + if (connector->connector_type != + DRM_MODE_CONNECTOR_DisplayPort) + continue; + + encoder = to_intel_encoder(connector->encoder); + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) + continue; + + if (encoder && connector->status == connector_status_connected) { + intel_dp = enc_to_intel_dp(encoder); + if (intel_dp->compliance.test_active) + seq_puts(m, "1"); + else + seq_puts(m, "0"); + } else + seq_puts(m, "0"); + } + drm_connector_list_iter_end(&conn_iter); + + return 0; +} + +static int i915_displayport_test_active_open(struct inode *inode, + struct file *file) +{ + return single_open(file, i915_displayport_test_active_show, + inode->i_private); +} + +static const struct file_operations i915_displayport_test_active_fops = { + .owner = THIS_MODULE, + .open = i915_displayport_test_active_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = i915_displayport_test_active_write +}; + +static int i915_displayport_test_data_show(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = m->private; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + struct intel_dp *intel_dp; + + drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + struct intel_encoder *encoder; + + if (connector->connector_type != + DRM_MODE_CONNECTOR_DisplayPort) + continue; + + encoder = to_intel_encoder(connector->encoder); + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) + continue; + + if (encoder && connector->status == connector_status_connected) { + intel_dp = enc_to_intel_dp(encoder); + if (intel_dp->compliance.test_type == + DP_TEST_LINK_EDID_READ) + seq_printf(m, "%lx", + intel_dp->compliance.test_data.edid); + else if (intel_dp->compliance.test_type == + DP_TEST_LINK_VIDEO_PATTERN) { + seq_printf(m, "hdisplay: %d\n", + intel_dp->compliance.test_data.hdisplay); + seq_printf(m, "vdisplay: %d\n", + intel_dp->compliance.test_data.vdisplay); + seq_printf(m, "bpc: %u\n", + intel_dp->compliance.test_data.bpc); + } else if (intel_dp->compliance.test_type == + DP_TEST_LINK_PHY_TEST_PATTERN) { + seq_printf(m, "pattern: %d\n", + intel_dp->compliance.test_data.phytest.phy_pattern); + seq_printf(m, "Number of lanes: %d\n", + intel_dp->compliance.test_data.phytest.num_lanes); + seq_printf(m, "Link Rate: %d\n", + intel_dp->compliance.test_data.phytest.link_rate); + seq_printf(m, "level: %02x\n", + intel_dp->train_set[0]); + } + } else + seq_puts(m, "0"); + } + drm_connector_list_iter_end(&conn_iter); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data); + +static int i915_displayport_test_type_show(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = m->private; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + struct intel_dp *intel_dp; + + drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + struct intel_encoder *encoder; + + if (connector->connector_type != + DRM_MODE_CONNECTOR_DisplayPort) + continue; + + encoder = to_intel_encoder(connector->encoder); + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) + continue; + + if (encoder && connector->status == connector_status_connected) { + intel_dp = enc_to_intel_dp(encoder); + seq_printf(m, "%02lx\n", intel_dp->compliance.test_type); + } else + seq_puts(m, "0"); + } + drm_connector_list_iter_end(&conn_iter); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type); + +static const struct { + const char *name; + const struct file_operations *fops; +} intel_display_debugfs_files[] = { + {"i915_dp_test_data", &i915_displayport_test_data_fops}, + {"i915_dp_test_type", &i915_displayport_test_type_fops}, + {"i915_dp_test_active", &i915_displayport_test_active_fops}, +}; + +void intel_dp_test_debugfs_register(struct intel_display *display) +{ + struct drm_minor *minor = display->drm->primary; + int i; + + for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) { + debugfs_create_file(intel_display_debugfs_files[i].name, + 0644, + minor->debugfs_root, + to_i915(minor->dev), + intel_display_debugfs_files[i].fops); + } +} diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.h b/drivers/gpu/drm/i915/display/intel_dp_test.h index cfd3dccdd91d..d64158b5a468 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.h +++ b/drivers/gpu/drm/i915/display/intel_dp_test.h @@ -7,6 +7,7 @@ #include struct intel_crtc_state; +struct intel_display; struct intel_dp; struct link_config_limits; @@ -15,5 +16,6 @@ void intel_dp_test_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits); bool intel_dp_test_phy(struct intel_dp *intel_dp); +void intel_dp_test_debugfs_register(struct intel_display *display); #endif /* __INTEL_DP_TEST_H__ */ From cd7a9129cd03bbe21e813cae608469e40d160b35 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:48 +0300 Subject: [PATCH 116/205] drm/i915/dp: fix style issues in DP test debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply some style fixes on top of the previous code movement. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/733dc8f648498a534811adf1cf079b3f4cbbf8f5.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_test.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 7a9b0ad161d6..f086f6854bf0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -594,8 +594,9 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data) seq_puts(m, "1"); else seq_puts(m, "0"); - } else + } else { seq_puts(m, "0"); + } } drm_connector_list_iter_end(&conn_iter); @@ -662,8 +663,9 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data) seq_printf(m, "level: %02x\n", intel_dp->train_set[0]); } - } else + } else { seq_puts(m, "0"); + } } drm_connector_list_iter_end(&conn_iter); @@ -693,8 +695,9 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data) if (encoder && connector->status == connector_status_connected) { intel_dp = enc_to_intel_dp(encoder); seq_printf(m, "%02lx\n", intel_dp->compliance.test_type); - } else + } else { seq_puts(m, "0"); + } } drm_connector_list_iter_end(&conn_iter); From a4e0932dc68e71308d558caada0c91083c60dcec Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:49 +0300 Subject: [PATCH 117/205] drm/i915/display: remove the loop in fifo underrun debugfs file creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need for the loop for a single file, and no more files should be added here, but rather in functionality specific source files. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/bd74ff250075c599163c988ae6fb5316f92bf192.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_debugfs.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 484be08048cf..890ef7067b77 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -866,26 +866,13 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_lpsp_status", i915_lpsp_status, 0}, }; -static const struct { - const char *name; - const struct file_operations *fops; -} intel_display_debugfs_files[] = { - {"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops}, -}; - void intel_display_debugfs_register(struct drm_i915_private *i915) { struct intel_display *display = &i915->display; struct drm_minor *minor = i915->drm.primary; - int i; - for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) { - debugfs_create_file(intel_display_debugfs_files[i].name, - 0644, - minor->debugfs_root, - to_i915(minor->dev), - intel_display_debugfs_files[i].fops); - } + debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root, + to_i915(minor->dev), &i915_fifo_underrun_reset_ops); drm_debugfs_create_files(intel_display_debugfs_list, ARRAY_SIZE(intel_display_debugfs_list), From 79228153adbb361d01590ed9a3b442e09e3cabb1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:50 +0300 Subject: [PATCH 118/205] drm/i915/dp: convert DP test debugfs to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefer struct intel_display over struct drm_i915_private. Do some drive-by logging conversions to kms category. Observe that i915_displayport_test_active_write() was using the wrong type for m->private, but it has worked because struct drm_i915_private has struct drm_device at offset 0. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/4d29cf43c7067e910fdf1127afcc35dd558b4b0b.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_test.c | 25 ++++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index f086f6854bf0..8426c8ef947e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -514,16 +514,15 @@ static ssize_t i915_displayport_test_active_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) { + struct seq_file *m = file->private_data; + struct intel_display *display = m->private; char *input_buffer; int status = 0; - struct drm_device *dev; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; struct intel_dp *intel_dp; int val = 0; - dev = ((struct seq_file *)file->private_data)->private; - if (len == 0) return 0; @@ -531,9 +530,9 @@ static ssize_t i915_displayport_test_active_write(struct file *file, if (IS_ERR(input_buffer)) return PTR_ERR(input_buffer); - drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len); + drm_dbg_kms(display->drm, "Copied %d bytes from user\n", (unsigned int)len); - drm_connector_list_iter_begin(dev, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { struct intel_encoder *encoder; @@ -550,7 +549,7 @@ static ssize_t i915_displayport_test_active_write(struct file *file, status = kstrtoint(input_buffer, 10, &val); if (status < 0) break; - drm_dbg(dev, "Got %d for test active\n", val); + drm_dbg_kms(display->drm, "Got %d for test active\n", val); /* To prevent erroneous activation of the compliance * testing code, only accept an actual value of 1 here */ @@ -571,12 +570,12 @@ static ssize_t i915_displayport_test_active_write(struct file *file, static int i915_displayport_test_active_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; struct intel_dp *intel_dp; - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { struct intel_encoder *encoder; @@ -621,12 +620,12 @@ static const struct file_operations i915_displayport_test_active_fops = { static int i915_displayport_test_data_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; struct intel_dp *intel_dp; - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { struct intel_encoder *encoder; @@ -675,12 +674,12 @@ DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data); static int i915_displayport_test_type_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; struct intel_dp *intel_dp; - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { struct intel_encoder *encoder; @@ -723,7 +722,7 @@ void intel_dp_test_debugfs_register(struct intel_display *display) debugfs_create_file(intel_display_debugfs_files[i].name, 0644, minor->debugfs_root, - to_i915(minor->dev), + display, intel_display_debugfs_files[i].fops); } } From b0e9af07cbfeee89dc4df21bb68c0c741d3b511a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2024 14:56:51 +0300 Subject: [PATCH 119/205] drm/i915/dp: add intel_dp_test_reset() and intel_dp_test_short_pulse() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Abstract more DP test stuff. Now the only place touching intel_dp->compliance is intel_dp_test.c. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/ea2ad218bdba21be30bd15a3707663508518dfa5.1726833193.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 27 ++------------ drivers/gpu/drm/i915/display/intel_dp_test.c | 37 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dp_test.h | 2 ++ 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 38aeb337ef53..16dc1d26d2a2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5161,16 +5161,11 @@ static bool intel_dp_check_link_service_irq(struct intel_dp *intel_dp) static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u8 old_sink_count = intel_dp->sink_count; bool reprobe_needed = false; bool ret; - /* - * Clearing compliance test variables to allow capturing - * of values for next automated test request. - */ - memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance)); + intel_dp_test_reset(intel_dp); /* * Now read the DPCD to see if it's actually running @@ -5195,24 +5190,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_psr_short_pulse(intel_dp); - switch (intel_dp->compliance.test_type) { - case DP_TEST_LINK_TRAINING: - drm_dbg_kms(&dev_priv->drm, - "Link Training Compliance Test requested\n"); - /* Send a Hotplug Uevent to userspace to start modeset */ - drm_kms_helper_hotplug_event(&dev_priv->drm); - break; - case DP_TEST_LINK_PHY_TEST_PATTERN: - drm_dbg_kms(&dev_priv->drm, - "PHY test pattern Compliance Test requested\n"); - /* - * Schedule long hpd to do the test - * - * FIXME get rid of the ad-hoc phy test modeset code - * and properly incorporate it into the normal modeset. - */ + if (intel_dp_test_short_pulse(intel_dp)) reprobe_needed = true; - } return !reprobe_needed; } @@ -5569,7 +5548,7 @@ intel_dp_detect(struct drm_connector *connector, status = connector_status_disconnected; if (status == connector_status_disconnected) { - memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance)); + intel_dp_test_reset(intel_dp); memset(intel_connector->dp.dsc_dpcd, 0, sizeof(intel_connector->dp.dsc_dpcd)); intel_dp->psr.sink_panel_replay_support = false; intel_dp->psr.sink_panel_replay_su_support = false; diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 8426c8ef947e..e05819300d77 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" @@ -17,6 +18,15 @@ #include "intel_dp_mst.h" #include "intel_dp_test.h" +void intel_dp_test_reset(struct intel_dp *intel_dp) +{ + /* + * Clearing compliance test variables to allow capturing + * of values for next automated test request. + */ + memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance)); +} + /* Adjust link config limits based on compliance test requests. */ void intel_dp_test_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, @@ -510,6 +520,33 @@ bool intel_dp_test_phy(struct intel_dp *intel_dp) return true; } +bool intel_dp_test_short_pulse(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + bool reprobe_needed = false; + + switch (intel_dp->compliance.test_type) { + case DP_TEST_LINK_TRAINING: + drm_dbg_kms(display->drm, + "Link Training Compliance Test requested\n"); + /* Send a Hotplug Uevent to userspace to start modeset */ + drm_kms_helper_hotplug_event(display->drm); + break; + case DP_TEST_LINK_PHY_TEST_PATTERN: + drm_dbg_kms(display->drm, + "PHY test pattern Compliance Test requested\n"); + /* + * Schedule long hpd to do the test + * + * FIXME get rid of the ad-hoc phy test modeset code + * and properly incorporate it into the normal modeset. + */ + reprobe_needed = true; + } + + return reprobe_needed; +} + static ssize_t i915_displayport_test_active_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.h b/drivers/gpu/drm/i915/display/intel_dp_test.h index d64158b5a468..dcc167e4c7f6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.h +++ b/drivers/gpu/drm/i915/display/intel_dp_test.h @@ -11,11 +11,13 @@ struct intel_display; struct intel_dp; struct link_config_limits; +void intel_dp_test_reset(struct intel_dp *intel_dp); void intel_dp_test_request(struct intel_dp *intel_dp); void intel_dp_test_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits); bool intel_dp_test_phy(struct intel_dp *intel_dp); +bool intel_dp_test_short_pulse(struct intel_dp *intel_dp); void intel_dp_test_debugfs_register(struct intel_display *display); #endif /* __INTEL_DP_TEST_H__ */ From c6be231c9f98ec9e07884dc39e28d45123840958 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 Sep 2024 18:33:54 +0300 Subject: [PATCH 120/205] drm/i915/quirks: make intel_dpcd_quirks const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The array can be in rodate, make it const. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240919153354.1269295-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_quirks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c index 29b56d53a340..28f497ae785b 100644 --- a/drivers/gpu/drm/i915/display/intel_quirks.c +++ b/drivers/gpu/drm/i915/display/intel_quirks.c @@ -231,7 +231,7 @@ static struct intel_quirk intel_quirks[] = { { 0x0f31, 0x103c, 0x220f, quirk_invert_brightness }, }; -static struct intel_dpcd_quirk intel_dpcd_quirks[] = { +static const struct intel_dpcd_quirk intel_dpcd_quirks[] = { /* Dell Precision 5490 */ { .device = 0x7d55, @@ -272,7 +272,7 @@ void intel_init_dpcd_quirks(struct intel_dp *intel_dp, int i; for (i = 0; i < ARRAY_SIZE(intel_dpcd_quirks); i++) { - struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i]; + const struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i]; if (d->device == q->device && (d->subsystem_vendor == q->subsystem_vendor || From 39bc6d24f01f4a62b098f6531533dc72d1ecc99c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 Sep 2024 12:04:27 +0300 Subject: [PATCH 121/205] drm/i915/pps: split intel_pps_reset_all() to vlv and bxt variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The intel_pps_reset_all() function does similar but not quite the same things for VLV/CHV and BXT/GLK. Observe that it's called from platform specific code only, and a split to two functions vlv_pps_reset_all() and bxt_pps_reset_all() is natural. Remove the platform checks and warnings from the functions. We don't usually have them, unless we're unsure. To make this easier to reason about for BXT/GLK, change the condition on caller side from "!PCH" to "BXT || GLK". Suggested-by: Ville Syrjälä Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240919090427.1859032-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../i915/display/intel_display_power_well.c | 11 +++--- drivers/gpu/drm/i915/display/intel_pps.c | 34 +++++++++++-------- drivers/gpu/drm/i915/display/intel_pps.h | 3 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 1898aff50ac4..adaf7cf3a33b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -879,12 +879,11 @@ void bxt_enable_dc9(struct intel_display *display) drm_dbg_kms(display->drm, "Enabling DC9\n"); /* - * Power sequencer reset is not needed on - * platforms with South Display Engine on PCH, - * because PPS registers are always on. + * Power sequencer reset is needed on BXT/GLK, because the PPS registers + * aren't always on, unlike with South Display Engine on PCH. */ - if (!HAS_PCH_SPLIT(dev_priv)) - intel_pps_reset_all(display); + if (IS_BROXTON(dev_priv) || IS_GEMINILAKE(dev_priv)) + bxt_pps_reset_all(display); gen9_set_dc_state(display, DC_STATE_EN_DC9); } @@ -1270,7 +1269,7 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) /* make sure we're done processing display irqs */ intel_synchronize_irq(dev_priv); - intel_pps_reset_all(display); + vlv_pps_reset_all(display); /* Prevent us from re-enabling polling on accident in late suspend */ if (!dev_priv->drm.dev->power.is_suspended) diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 819b2843946f..88abc4c7cda1 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -70,7 +70,7 @@ intel_wakeref_t intel_pps_lock(struct intel_dp *intel_dp) intel_wakeref_t wakeref; /* - * See intel_pps_reset_all() why we need a power domain reference here. + * See vlv_pps_reset_all() why we need a power domain reference here. */ wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE); mutex_lock(&display->pps.mutex); @@ -448,14 +448,10 @@ pps_initial_setup(struct intel_dp *intel_dp) return intel_pps_is_valid(intel_dp); } -void intel_pps_reset_all(struct intel_display *display) +void vlv_pps_reset_all(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; - if (drm_WARN_ON(display->drm, !IS_LP(dev_priv))) - return; - if (!HAS_DISPLAY(display)) return; @@ -472,16 +468,26 @@ void intel_pps_reset_all(struct intel_display *display) for_each_intel_dp(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - drm_WARN_ON(display->drm, - intel_dp->pps.vlv_active_pipe != INVALID_PIPE); + drm_WARN_ON(display->drm, intel_dp->pps.vlv_active_pipe != INVALID_PIPE); - if (encoder->type != INTEL_OUTPUT_EDP) - continue; - - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (encoder->type == INTEL_OUTPUT_EDP) intel_dp->pps.vlv_pps_pipe = INVALID_PIPE; - else + } +} + +void bxt_pps_reset_all(struct intel_display *display) +{ + struct intel_encoder *encoder; + + if (!HAS_DISPLAY(display)) + return; + + /* See vlv_pps_reset_all() for why we can't grab pps_mutex here. */ + + for_each_intel_dp(display->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + if (encoder->type == INTEL_OUTPUT_EDP) intel_dp->pps.bxt_pps_reset = true; } } diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index a5339a65485d..bc5046d53626 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -43,7 +43,6 @@ void intel_pps_wait_power_cycle(struct intel_dp *intel_dp); bool intel_pps_init(struct intel_dp *intel_dp); void intel_pps_init_late(struct intel_dp *intel_dp); void intel_pps_encoder_reset(struct intel_dp *intel_dp); -void intel_pps_reset_all(struct intel_display *display); void vlv_pps_pipe_init(struct intel_dp *intel_dp); void vlv_pps_pipe_reset(struct intel_dp *intel_dp); @@ -52,6 +51,8 @@ void vlv_pps_port_enable_unlocked(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void vlv_pps_port_disable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); +void vlv_pps_reset_all(struct intel_display *display); +void bxt_pps_reset_all(struct intel_display *display); void intel_pps_unlock_regs_wa(struct intel_display *display); void intel_pps_setup(struct intel_display *display); From c2579a217799ba577fa39a2a12643a277334e691 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Fri, 20 Sep 2024 14:42:04 +0530 Subject: [PATCH 122/205] drm/i915/psr: Implement WA to help reach PC10 To reach PC10 when PKG_C_LATENCY is configure we must do the following things 1) Enter PSR1 only when delayed_vblank < 6 lines and DC5 can be entered 2) Allow PSR2 deep sleep when DC5 can be entered 3) DC5 can be entered when all transocoder have either PSR1, PSR2 or eDP 1.5 PR ALPM enabled and VBI is disabled and flips and pushes are not happening. --v2 -Switch condition and do an early return [Jani] -Do some checks in compute_config [Jani] -Do not use register reads as a method of checking states for DPKGC or delayed vblank [Jani] -Use another way to see is vblank interrupts are disabled or not [Jani] --v3 -Use has_psr to check if psr can be enabled or not for dc5_entry cond [Uma] -Move the dc5 entry computation to psr_compute_config [Jouni] -No need to change sequence of enabled and activate, so dont make hsw_psr1_activate return anything [Jouni] -Use has_psr to stop psr1 activation [Jouni] -Use lineage no. in WA -Add the display ver restrictions for WA --v4 -use more appropriate name for check_vblank_limit() [Jouni] -Cover the case for idle frames when dpkgc is not configured [Jouni] -Check psr only for edp [Jouni] --v5 -move psr1 handling to plane update [Jouni] -add todo for cases when vblank is enabled when psr enabled [Jouni] -use intel_display instead of drm_i915_private --v6 -check target_dc_state [Jouni] -fix condition in pre/post plane update [Jouni] --v7 -fix has_psr condition [Uma] -fix typo in commit subject [Uma] -put psr1_wa check in its own helper [Uma] -fix the dc_entry check [Jouni] -use HAS_PSR() to cover two edp one with psr and one nonpsr [Jouni] WA: 22019444797 Signed-off-by: Suraj Kandpal Reviewed-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20240920091203.1043308-2-suraj.kandpal@intel.com --- .../drm/i915/display/intel_display_types.h | 3 + drivers/gpu/drm/i915/display/intel_psr.c | 119 +++++++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 513e843e19b9..b1eed230285a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1579,6 +1579,9 @@ struct intel_psr { #define I915_PSR_DEBUG_PANEL_REPLAY_DISABLE 0x40 u32 debug; + bool is_dpkgc_configured; + bool is_dc5_entry_possible; + bool is_wa_delayed_vblank_limit; bool sink_support; bool source_support; bool enabled; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index e3357f3b5c70..39aa46de15e4 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" @@ -896,6 +897,89 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) return idle_frames; } +static bool +intel_psr_check_wa_delayed_vblank(const struct drm_display_mode *adjusted_mode) +{ + return (adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay) >= 6; +} + +/* + * PKG_C_LATENCY is configured only when DISPLAY_VER >= 20 and + * VRR is not enabled + */ +static bool intel_psr_is_dpkgc_configured(struct intel_display *display, + struct intel_atomic_state *state) +{ + struct intel_crtc *intel_crtc; + struct intel_crtc_state *crtc_state; + int i; + + if (DISPLAY_VER(display) < 20) + return false; + + for_each_new_intel_crtc_in_state(state, intel_crtc, crtc_state, i) { + if (!intel_crtc->active) + continue; + + if (crtc_state->vrr.enable) + return false; + } + + return true; +} + +static bool wa_22019444797_psr1_check(const struct intel_crtc_state *crtc_state, + struct intel_psr *psr) +{ + struct intel_display *display = to_intel_display(crtc_state); + + return DISPLAY_VER(display) == 20 && psr->is_dpkgc_configured && + (psr->is_wa_delayed_vblank_limit || !psr->is_dc5_entry_possible) && + !crtc_state->has_sel_update && !crtc_state->has_panel_replay; +} + +/* + * DC5 entry is only possible if vblank interrupt is disabled + * and either psr1, psr2, edp 1.5 pr alpm is enabled on all + * enabled encoders. + */ +static bool +intel_psr_is_dc5_entry_possible(struct intel_display *display, + struct intel_atomic_state *state) +{ + struct intel_crtc *intel_crtc; + struct intel_crtc_state *crtc_state; + int i; + + if ((display->power.domains.target_dc_state & + DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0) + return false; + + for_each_new_intel_crtc_in_state(state, intel_crtc, crtc_state, i) { + struct drm_crtc *crtc = &intel_crtc->base; + struct drm_vblank_crtc *vblank; + struct intel_encoder *encoder; + + if (!intel_crtc->active) + continue; + + vblank = drm_crtc_vblank_crtc(crtc); + + if (vblank->enabled) + return false; + + if (!crtc_state->has_psr) + return false; + + for_each_encoder_on_crtc(display->drm, crtc, encoder) + if (encoder->type != INTEL_OUTPUT_EDP || + !CAN_PSR(enc_to_intel_dp(encoder))) + return false; + } + + return true; +} + static void hsw_activate_psr1(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); @@ -1008,7 +1092,15 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) u32 val = EDP_PSR2_ENABLE; u32 psr_val = 0; - val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp)); + /* + * Wa_22019444797 + * TODO: Disable idle frames when vblank gets enabled while + * PSR2 is enabled + */ + if (DISPLAY_VER(dev_priv) != 20 || + !intel_dp->psr.is_dpkgc_configured || + intel_dp->psr.is_dc5_entry_possible) + val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp)); if (DISPLAY_VER(display) < 14 && !IS_ALDERLAKE_P(dev_priv)) val |= EDP_SU_TRACK_ENABLE; @@ -2723,10 +2815,20 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder; + bool dpkgc_configured = false, dc5_entry_possible = false; + bool wa_delayed_vblank_limit = false; if (!HAS_PSR(display)) return; + if (DISPLAY_VER(display) == 20) { + dpkgc_configured = intel_psr_is_dpkgc_configured(display, state); + dc5_entry_possible = + intel_psr_is_dc5_entry_possible(display, state); + wa_delayed_vblank_limit = + intel_psr_check_wa_delayed_vblank(&new_crtc_state->hw.adjusted_mode); + } + for_each_intel_encoder_mask_with_psr(state->base.dev, encoder, old_crtc_state->uapi.encoder_mask) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -2735,6 +2837,12 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, mutex_lock(&psr->lock); + if (DISPLAY_VER(i915) == 20) { + psr->is_dpkgc_configured = dpkgc_configured; + psr->is_dc5_entry_possible = dc5_entry_possible; + psr->is_wa_delayed_vblank_limit = wa_delayed_vblank_limit; + } + /* * Reasons to disable: * - PSR disabled in new state @@ -2742,6 +2850,7 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, * - Changing between PSR versions * - Region Early Transport changing * - Display WA #1136: skl, bxt + * - Display WA_22019444797 */ needs_to_disable |= intel_crtc_needs_modeset(new_crtc_state); needs_to_disable |= !new_crtc_state->has_psr; @@ -2751,6 +2860,8 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, psr->su_region_et_enabled; needs_to_disable |= DISPLAY_VER(i915) < 11 && new_crtc_state->wm_level_disabled; + /* TODO: Disable PSR1 when vblank gets enabled while PSR1 is enabled */ + needs_to_disable |= wa_22019444797_psr1_check(new_crtc_state, psr); if (psr->enabled && needs_to_disable) intel_psr_disable_locked(intel_dp); @@ -2791,6 +2902,12 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state, keep_disabled |= DISPLAY_VER(display) < 11 && crtc_state->wm_level_disabled; + /* + * Wa_22019444797 + * TODO: Disable PSR1 when vblank gets enabled while PSR1 is enabled + */ + keep_disabled |= wa_22019444797_psr1_check(crtc_state, psr); + if (!psr->enabled && !keep_disabled) intel_psr_enable_locked(intel_dp, crtc_state); else if (psr->enabled && !crtc_state->wm_level_disabled) From f86d45ac9d8da462a16e19e41128c614c6b40b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:07 +0300 Subject: [PATCH 123/205] drm/i915: Remove leftover intel_sprite_set_colorkey_ioctl() prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_sprite_set_colorkey_ioctl() lives in intel_sprice_uapi.{c,h} these days. For some reason the old protoype was left behind in intel_sprite.h and even used by i915_driver.c. Remove the leftovers and switch to including the correct header for the prototype. v2: Drop more unnecessary forward declarations Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-2-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_sprite.h | 5 ----- drivers/gpu/drm/i915/i915_driver.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h index 044a032e41b9..531079979c05 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.h +++ b/drivers/gpu/drm/i915/display/intel_sprite.h @@ -8,9 +8,6 @@ #include -struct drm_device; -struct drm_display_mode; -struct drm_file; struct drm_i915_private; struct intel_crtc_state; struct intel_plane_state; @@ -19,8 +16,6 @@ enum pipe; #ifdef I915 struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe, int plane); -int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); int chv_plane_check_rotation(const struct intel_plane_state *plane_state); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 3bf6482b60b0..6dc0104a3e36 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -59,7 +59,7 @@ #include "display/intel_overlay.h" #include "display/intel_pch_refclk.h" #include "display/intel_pps.h" -#include "display/intel_sprite.h" +#include "display/intel_sprite_uapi.h" #include "display/skl_watermark.h" #include "gem/i915_gem_context.h" From 9cf6f05cc5d275f6efd9583fb7fcd04eb7e7b092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:08 +0300 Subject: [PATCH 124/205] drm/i915: Combine .compute_{pipe,intermediate}_wm() into one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We always call .compute_pipe_wm() and .compute_intermediate_wm() back to back. Just combine them to a single hook for simplicity. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-3-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/i9xx_wm.c | 57 +++++++++++++++++-- drivers/gpu/drm/i915/display/intel_display.c | 17 +----- .../gpu/drm/i915/display/intel_display_core.h | 6 +- drivers/gpu/drm/i915/display/intel_wm.c | 24 ++------ drivers/gpu/drm/i915/display/intel_wm.h | 6 +- 5 files changed, 63 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 5a75d7638aed..15052a822cc4 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -1289,6 +1289,22 @@ static int g4x_compute_intermediate_wm(struct intel_atomic_state *state, return 0; } +static int g4x_compute_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + int ret; + + ret = g4x_compute_pipe_wm(state, crtc); + if (ret) + return ret; + + ret = g4x_compute_intermediate_wm(state, crtc); + if (ret) + return ret; + + return 0; +} + static void g4x_merge_wm(struct drm_i915_private *dev_priv, struct g4x_wm_values *wm) { @@ -1915,6 +1931,22 @@ static int vlv_compute_intermediate_wm(struct intel_atomic_state *state, return 0; } +static int vlv_compute_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + int ret; + + ret = vlv_compute_pipe_wm(state, crtc); + if (ret) + return ret; + + ret = vlv_compute_intermediate_wm(state, crtc); + if (ret) + return ret; + + return 0; +} + static void vlv_merge_wm(struct drm_i915_private *dev_priv, struct vlv_wm_values *wm) { @@ -2941,6 +2973,22 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, return 0; } +static int ilk_compute_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + int ret; + + ret = ilk_compute_pipe_wm(state, crtc); + if (ret) + return ret; + + ret = ilk_compute_intermediate_wm(state, crtc); + if (ret) + return ret; + + return 0; +} + /* * Merge the watermarks from all active pipes for a specific level. */ @@ -3987,16 +4035,14 @@ static void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) } static const struct intel_wm_funcs ilk_wm_funcs = { - .compute_pipe_wm = ilk_compute_pipe_wm, - .compute_intermediate_wm = ilk_compute_intermediate_wm, + .compute_watermarks = ilk_compute_watermarks, .initial_watermarks = ilk_initial_watermarks, .optimize_watermarks = ilk_optimize_watermarks, .get_hw_state = ilk_wm_get_hw_state, }; static const struct intel_wm_funcs vlv_wm_funcs = { - .compute_pipe_wm = vlv_compute_pipe_wm, - .compute_intermediate_wm = vlv_compute_intermediate_wm, + .compute_watermarks = vlv_compute_watermarks, .initial_watermarks = vlv_initial_watermarks, .optimize_watermarks = vlv_optimize_watermarks, .atomic_update_watermarks = vlv_atomic_update_fifo, @@ -4004,8 +4050,7 @@ static const struct intel_wm_funcs vlv_wm_funcs = { }; static const struct intel_wm_funcs g4x_wm_funcs = { - .compute_pipe_wm = g4x_compute_pipe_wm, - .compute_intermediate_wm = g4x_compute_intermediate_wm, + .compute_watermarks = g4x_compute_watermarks, .initial_watermarks = g4x_initial_watermarks, .optimize_watermarks = g4x_optimize_watermarks, .get_hw_state = g4x_wm_get_hw_state_and_sanitize, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7136c80ac8cc..ca98ecbf24a9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4334,22 +4334,11 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, if (ret) return ret; - ret = intel_compute_pipe_wm(state, crtc); + ret = intel_wm_compute(state, crtc); if (ret) { drm_dbg_kms(&dev_priv->drm, - "Target pipe watermarks are invalid\n"); - return ret; - } - - /* - * Calculate 'intermediate' watermarks that satisfy both the - * old state and the new state. We can program these - * immediately. - */ - ret = intel_compute_intermediate_wm(state, crtc); - if (ret) { - drm_dbg_kms(&dev_priv->drm, - "No valid intermediate pipe watermarks are possible\n"); + "[CRTC:%d:%s] watermarks are invalid\n", + crtc->base.base.id, crtc->base.name); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index ac4c005fe348..982dd9469195 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -81,10 +81,8 @@ struct intel_display_funcs { struct intel_wm_funcs { /* update_wm is for legacy wm management */ void (*update_wm)(struct drm_i915_private *dev_priv); - int (*compute_pipe_wm)(struct intel_atomic_state *state, - struct intel_crtc *crtc); - int (*compute_intermediate_wm)(struct intel_atomic_state *state, - struct intel_crtc *crtc); + int (*compute_watermarks)(struct intel_atomic_state *state, + struct intel_crtc *crtc); void (*initial_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); void (*atomic_update_watermarks)(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c index 462917bc488f..d7dc49aecd27 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.c +++ b/drivers/gpu/drm/i915/display/intel_wm.c @@ -50,29 +50,15 @@ void intel_update_watermarks(struct drm_i915_private *i915) i915->display.funcs.wm->update_wm(i915); } -int intel_compute_pipe_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc) +int intel_wm_compute(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - if (i915->display.funcs.wm->compute_pipe_wm) - return i915->display.funcs.wm->compute_pipe_wm(state, crtc); - - return 0; -} - -int intel_compute_intermediate_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *i915 = to_i915(state->base.dev); - - if (!i915->display.funcs.wm->compute_intermediate_wm) + if (!display->funcs.wm->compute_watermarks) return 0; - if (drm_WARN_ON(&i915->drm, !i915->display.funcs.wm->compute_pipe_wm)) - return 0; - - return i915->display.funcs.wm->compute_intermediate_wm(state, crtc); + return display->funcs.wm->compute_watermarks(state, crtc); } bool intel_initial_watermarks(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_wm.h b/drivers/gpu/drm/i915/display/intel_wm.h index 48429ac140d2..e97cdca89a5c 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.h +++ b/drivers/gpu/drm/i915/display/intel_wm.h @@ -15,10 +15,8 @@ struct intel_crtc_state; struct intel_plane_state; void intel_update_watermarks(struct drm_i915_private *i915); -int intel_compute_pipe_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc); -int intel_compute_intermediate_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc); +int intel_wm_compute(struct intel_atomic_state *state, + struct intel_crtc *crtc); bool intel_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_atomic_update_watermarks(struct intel_atomic_state *state, From 16d1d39db536205746eaaf43ee70780b893cd27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:09 +0300 Subject: [PATCH 125/205] drm/i915: Extract ilk_must_disable_lp_wm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the ilk/snb/ivb LP watermark disable checks into a separate function similar to the gmch counterpart (i9xx_must_disable_cxsr()). Reduces the clutter in intel_plane_atomic_calc_changes() significantly. Reviewed-by: Arun R Murthy Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-4-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_atomic_plane.c | 95 +++++++++++-------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 18c516298e79..cf6e9c6bb5fe 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -493,6 +493,61 @@ static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state return old_ctl != new_ctl; } +static bool ilk_must_disable_lp_wm(const struct intel_crtc_state *new_crtc_state, + const struct intel_plane_state *old_plane_state, + const struct intel_plane_state *new_plane_state) +{ + struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); + bool old_visible = old_plane_state->uapi.visible; + bool new_visible = new_plane_state->uapi.visible; + bool modeset, turn_on; + + if (plane->id == PLANE_CURSOR) + return false; + + modeset = intel_crtc_needs_modeset(new_crtc_state); + turn_on = new_visible && (!old_visible || modeset); + + /* + * ILK/SNB DVSACNTR/Sprite Enable + * IVB SPR_CTL/Sprite Enable + * "When in Self Refresh Big FIFO mode, a write to enable the + * plane will be internally buffered and delayed while Big FIFO + * mode is exiting." + * + * Which means that enabling the sprite can take an extra frame + * when we start in big FIFO mode (LP1+). Thus we need to drop + * down to LP0 and wait for vblank in order to make sure the + * sprite gets enabled on the next vblank after the register write. + * Doing otherwise would risk enabling the sprite one frame after + * we've already signalled flip completion. We can resume LP1+ + * once the sprite has been enabled. + * + * With experimental results seems this is needed also for primary + * plane, not only sprite plane. + */ + if (turn_on) + return true; + + /* + * WaCxSRDisabledForSpriteScaling:ivb + * IVB SPR_SCALE/Scaling Enable + * "Low Power watermarks must be disabled for at least one + * frame before enabling sprite scaling, and kept disabled + * until sprite scaling is disabled." + * + * ILK/SNB DVSASCALE/Scaling Enable + * "When in Self Refresh Big FIFO mode, scaling enable will be + * masked off while Big FIFO mode is exiting." + * + * Despite the w/a only being listed for IVB we assume that + * the ILK/SNB note has similar ramifications, hence we apply + * the w/a on all three platforms. + */ + return !intel_plane_is_scaled(old_plane_state) && + intel_plane_is_scaled(new_plane_state); +} + static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state, const struct intel_plane_state *old_plane_state, @@ -568,44 +623,8 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state)) new_crtc_state->disable_cxsr = true; - /* - * ILK/SNB DVSACNTR/Sprite Enable - * IVB SPR_CTL/Sprite Enable - * "When in Self Refresh Big FIFO mode, a write to enable the - * plane will be internally buffered and delayed while Big FIFO - * mode is exiting." - * - * Which means that enabling the sprite can take an extra frame - * when we start in big FIFO mode (LP1+). Thus we need to drop - * down to LP0 and wait for vblank in order to make sure the - * sprite gets enabled on the next vblank after the register write. - * Doing otherwise would risk enabling the sprite one frame after - * we've already signalled flip completion. We can resume LP1+ - * once the sprite has been enabled. - * - * - * WaCxSRDisabledForSpriteScaling:ivb - * IVB SPR_SCALE/Scaling Enable - * "Low Power watermarks must be disabled for at least one - * frame before enabling sprite scaling, and kept disabled - * until sprite scaling is disabled." - * - * ILK/SNB DVSASCALE/Scaling Enable - * "When in Self Refresh Big FIFO mode, scaling enable will be - * masked off while Big FIFO mode is exiting." - * - * Despite the w/a only being listed for IVB we assume that - * the ILK/SNB note has similar ramifications, hence we apply - * the w/a on all three platforms. - * - * With experimental results seems this is needed also for primary - * plane, not only sprite plane. - */ - if (plane->id != PLANE_CURSOR && - (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || - IS_IVYBRIDGE(dev_priv)) && - (turn_on || (!intel_plane_is_scaled(old_plane_state) && - intel_plane_is_scaled(new_plane_state)))) + if ((IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) && + ilk_must_disable_lp_wm(new_crtc_state, old_plane_state, new_plane_state)) new_crtc_state->disable_lp_wm = true; if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) { From 69aebe7a61ce49895e0352a1d5b5534e07094a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:10 +0300 Subject: [PATCH 126/205] drm/i915: Clean up intel_wm_need_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_wm_need_update() is a mess when it comes to variable names and constness. The checks also keep alternating randomly between 'old != cur' vs. 'cur != old'. Clean it all up. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-5-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- .../gpu/drm/i915/display/intel_atomic_plane.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index cf6e9c6bb5fe..49b5b2c4f2f2 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -393,22 +393,22 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, } /* FIXME nuke when all wm code is atomic */ -static bool intel_wm_need_update(const struct intel_plane_state *cur, - struct intel_plane_state *new) +static bool intel_wm_need_update(const struct intel_plane_state *old_plane_state, + const struct intel_plane_state *new_plane_state) { /* Update watermarks on tiling or size changes. */ - if (new->uapi.visible != cur->uapi.visible) + if (old_plane_state->uapi.visible != new_plane_state->uapi.visible) return true; - if (!cur->hw.fb || !new->hw.fb) + if (!old_plane_state->hw.fb || !new_plane_state->hw.fb) return false; - if (cur->hw.fb->modifier != new->hw.fb->modifier || - cur->hw.rotation != new->hw.rotation || - drm_rect_width(&new->uapi.src) != drm_rect_width(&cur->uapi.src) || - drm_rect_height(&new->uapi.src) != drm_rect_height(&cur->uapi.src) || - drm_rect_width(&new->uapi.dst) != drm_rect_width(&cur->uapi.dst) || - drm_rect_height(&new->uapi.dst) != drm_rect_height(&cur->uapi.dst)) + if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier || + old_plane_state->hw.rotation != new_plane_state->hw.rotation || + drm_rect_width(&old_plane_state->uapi.src) != drm_rect_width(&new_plane_state->uapi.src) || + drm_rect_height(&old_plane_state->uapi.src) != drm_rect_height(&new_plane_state->uapi.src) || + drm_rect_width(&old_plane_state->uapi.dst) != drm_rect_width(&new_plane_state->uapi.dst) || + drm_rect_height(&old_plane_state->uapi.dst) != drm_rect_height(&new_plane_state->uapi.dst)) return true; return false; From 7572d3f72ed3ad83d302d4fa0ff67706ce68994a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:11 +0300 Subject: [PATCH 127/205] drm/i915: Move the dodgy pre-g4x wm stuff into i9xx_wm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As with other watermark calculations, the dodgy pre-g4x update_wm_{pre,post} flag calcultion would like to know if a modeset is about to happen or not, and technically later stages in the atomic_check() may still flag one. In practice that shouldn't happen as we don't have dynamic CDCLK implemented for these old platforms. Regardless it'll be nice to move this old cruft out from the supposedly platform agnostic plane code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-6-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/i9xx_wm.c | 74 +++++++++++++++++++ .../gpu/drm/i915/display/intel_atomic_plane.c | 36 --------- 2 files changed, 74 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 15052a822cc4..999fc085af28 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -706,6 +706,76 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv) } } +static bool i9xx_wm_need_update(const struct intel_plane_state *old_plane_state, + const struct intel_plane_state *new_plane_state) +{ + /* Update watermarks on tiling or size changes. */ + if (old_plane_state->uapi.visible != new_plane_state->uapi.visible) + return true; + + if (!old_plane_state->hw.fb || !new_plane_state->hw.fb) + return false; + + if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier || + old_plane_state->hw.rotation != new_plane_state->hw.rotation || + drm_rect_width(&old_plane_state->uapi.src) != drm_rect_width(&new_plane_state->uapi.src) || + drm_rect_height(&old_plane_state->uapi.src) != drm_rect_height(&new_plane_state->uapi.src) || + drm_rect_width(&old_plane_state->uapi.dst) != drm_rect_width(&new_plane_state->uapi.dst) || + drm_rect_height(&old_plane_state->uapi.dst) != drm_rect_height(&new_plane_state->uapi.dst)) + return true; + + return false; +} + +static void i9xx_wm_compute(struct intel_crtc_state *new_crtc_state, + const struct intel_plane_state *old_plane_state, + const struct intel_plane_state *new_plane_state) +{ + bool turn_off, turn_on, visible, was_visible, mode_changed; + + mode_changed = intel_crtc_needs_modeset(new_crtc_state); + was_visible = old_plane_state->uapi.visible; + visible = new_plane_state->uapi.visible; + + if (!was_visible && !visible) + return; + + turn_off = was_visible && (!visible || mode_changed); + turn_on = visible && (!was_visible || mode_changed); + + /* FIXME nuke when all wm code is atomic */ + if (turn_on) { + new_crtc_state->update_wm_pre = true; + } else if (turn_off) { + new_crtc_state->update_wm_post = true; + } else if (i9xx_wm_need_update(old_plane_state, new_plane_state)) { + /* FIXME bollocks */ + new_crtc_state->update_wm_pre = true; + new_crtc_state->update_wm_post = true; + } +} + +static int i9xx_compute_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *old_plane_state; + const struct intel_plane_state *new_plane_state; + struct intel_plane *plane; + int i; + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + if (plane->pipe != crtc->pipe) + continue; + + i9xx_wm_compute(new_crtc_state, old_plane_state, new_plane_state); + } + + return 0; +} + /* * Documentation says: * "If the line size is small, the TLB fetches can get in the way of the @@ -4057,18 +4127,22 @@ static const struct intel_wm_funcs g4x_wm_funcs = { }; static const struct intel_wm_funcs pnv_wm_funcs = { + .compute_watermarks = i9xx_compute_watermarks, .update_wm = pnv_update_wm, }; static const struct intel_wm_funcs i965_wm_funcs = { + .compute_watermarks = i9xx_compute_watermarks, .update_wm = i965_update_wm, }; static const struct intel_wm_funcs i9xx_wm_funcs = { + .compute_watermarks = i9xx_compute_watermarks, .update_wm = i9xx_update_wm, }; static const struct intel_wm_funcs i845_wm_funcs = { + .compute_watermarks = i9xx_compute_watermarks, .update_wm = i845_update_wm, }; diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 49b5b2c4f2f2..b2cc7f1dee0c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -392,28 +392,6 @@ void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, plane_state->uapi.visible = false; } -/* FIXME nuke when all wm code is atomic */ -static bool intel_wm_need_update(const struct intel_plane_state *old_plane_state, - const struct intel_plane_state *new_plane_state) -{ - /* Update watermarks on tiling or size changes. */ - if (old_plane_state->uapi.visible != new_plane_state->uapi.visible) - return true; - - if (!old_plane_state->hw.fb || !new_plane_state->hw.fb) - return false; - - if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier || - old_plane_state->hw.rotation != new_plane_state->hw.rotation || - drm_rect_width(&old_plane_state->uapi.src) != drm_rect_width(&new_plane_state->uapi.src) || - drm_rect_height(&old_plane_state->uapi.src) != drm_rect_height(&new_plane_state->uapi.src) || - drm_rect_width(&old_plane_state->uapi.dst) != drm_rect_width(&new_plane_state->uapi.dst) || - drm_rect_height(&old_plane_state->uapi.dst) != drm_rect_height(&new_plane_state->uapi.dst)) - return true; - - return false; -} - static bool intel_plane_is_scaled(const struct intel_plane_state *plane_state) { int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; @@ -602,20 +580,6 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr was_visible, visible, turn_off, turn_on, mode_changed); - if (turn_on) { - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) - new_crtc_state->update_wm_pre = true; - } else if (turn_off) { - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) - new_crtc_state->update_wm_post = true; - } else if (intel_wm_need_update(old_plane_state, new_plane_state)) { - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) { - /* FIXME bollocks */ - new_crtc_state->update_wm_pre = true; - new_crtc_state->update_wm_post = true; - } - } - if (visible || was_visible) new_crtc_state->fb_bits |= plane->frontbuffer_bit; From d77037bba76011632cc341f6dd2859fd0e4b83df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:12 +0300 Subject: [PATCH 128/205] drm/i915: s/disable_lp_wm/disable_cxsr/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ilk+ disable_lp_wm boolean has the exact same role as disable_cxsr for gmch platforms. The documentation also still talks about CxSR on ilk+ even theough the way you control it has now change to involve toggling the LP watermarks. Get rid of disable_lp_wm and just use disable_cxsr for ilk+ as well. TODO: Unify even more to not have any gmch vs. ilk+ details in high level modeset code... Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-7-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/i9xx_wm.c | 2 +- drivers/gpu/drm/i915/display/i9xx_wm.h | 4 ++-- drivers/gpu/drm/i915/display/intel_atomic.c | 1 - drivers/gpu/drm/i915/display/intel_atomic_plane.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display_types.h | 3 --- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 999fc085af28..5b5f2875ea40 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -3397,7 +3397,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, dev_priv->display.wm.hw = *results; } -bool ilk_disable_lp_wm(struct drm_i915_private *dev_priv) +bool ilk_disable_cxsr(struct drm_i915_private *dev_priv) { return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); } diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.h b/drivers/gpu/drm/i915/display/i9xx_wm.h index de0920730ab2..06ac37c6c94b 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.h +++ b/drivers/gpu/drm/i915/display/i9xx_wm.h @@ -13,12 +13,12 @@ struct intel_crtc_state; struct intel_plane_state; #ifdef I915 -bool ilk_disable_lp_wm(struct drm_i915_private *i915); +bool ilk_disable_cxsr(struct drm_i915_private *i915); void ilk_wm_sanitize(struct drm_i915_private *i915); bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable); void i9xx_wm_init(struct drm_i915_private *i915); #else -static inline bool ilk_disable_lp_wm(struct drm_i915_private *i915) +static inline bool ilk_disable_cxsr(struct drm_i915_private *i915) { return false; } diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 12d6ed940751..6cac26af128c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -266,7 +266,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->update_pipe = false; crtc_state->update_m_n = false; crtc_state->update_lrr = false; - crtc_state->disable_lp_wm = false; crtc_state->disable_cxsr = false; crtc_state->update_wm_pre = false; crtc_state->update_wm_post = false; diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index b2cc7f1dee0c..3505a5b52eb9 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -471,9 +471,9 @@ static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state return old_ctl != new_ctl; } -static bool ilk_must_disable_lp_wm(const struct intel_crtc_state *new_crtc_state, - const struct intel_plane_state *old_plane_state, - const struct intel_plane_state *new_plane_state) +static bool ilk_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state, + const struct intel_plane_state *old_plane_state, + const struct intel_plane_state *new_plane_state) { struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); bool old_visible = old_plane_state->uapi.visible; @@ -588,8 +588,8 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr new_crtc_state->disable_cxsr = true; if ((IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) && - ilk_must_disable_lp_wm(new_crtc_state, old_plane_state, new_plane_state)) - new_crtc_state->disable_lp_wm = true; + ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state)) + new_crtc_state->disable_cxsr = true; if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) { new_crtc_state->do_async_flip = true; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ca98ecbf24a9..f7667931f9d9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1324,8 +1324,8 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * * WaCxSRDisabledForSpriteScaling:ivb */ - if (old_crtc_state->hw.active && - new_crtc_state->disable_lp_wm && ilk_disable_lp_wm(dev_priv)) + if (!HAS_GMCH(dev_priv) && old_crtc_state->hw.active && + new_crtc_state->disable_cxsr && ilk_disable_cxsr(dev_priv)) intel_crtc_wait_for_next_vblank(crtc); /* diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b1eed230285a..7ff97e5b83dd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1143,9 +1143,6 @@ struct intel_crtc_state { /* w/a for waiting 2 vblanks during crtc enable */ enum pipe hsw_workaround_pipe; - /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */ - bool disable_lp_wm; - struct intel_crtc_wm_state wm; int min_cdclk[I915_MAX_PLANES]; From 61b105809149978b594ddff0b77bdfd43b1c267a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2024 19:24:13 +0300 Subject: [PATCH 129/205] drm/i915: Rename variables in ilk_intermedidate_wm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ilk_compute_intermediate_wm() uses rather poor variable names for its watermark structs. Borrow a better naming convention from the g4x/vlv counterpart code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240916162413.8555-8-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/i9xx_wm.c | 35 +++++++++++++++----------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 5b5f2875ea40..e3b13886177a 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -2994,8 +2994,9 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); - struct intel_pipe_wm *a = &new_crtc_state->wm.ilk.intermediate; - const struct intel_pipe_wm *b = &old_crtc_state->wm.ilk.optimal; + struct intel_pipe_wm *intermediate = &new_crtc_state->wm.ilk.intermediate; + const struct intel_pipe_wm *optimal = &new_crtc_state->wm.ilk.optimal; + const struct intel_pipe_wm *active = &old_crtc_state->wm.ilk.optimal; int level; /* @@ -3003,25 +3004,29 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, * currently active watermarks to get values that are safe both before * and after the vblank. */ - *a = new_crtc_state->wm.ilk.optimal; + *intermediate = *optimal; if (!new_crtc_state->hw.active || intel_crtc_needs_modeset(new_crtc_state) || state->skip_intermediate_wm) return 0; - a->pipe_enabled |= b->pipe_enabled; - a->sprites_enabled |= b->sprites_enabled; - a->sprites_scaled |= b->sprites_scaled; + intermediate->pipe_enabled |= active->pipe_enabled; + intermediate->sprites_enabled |= active->sprites_enabled; + intermediate->sprites_scaled |= active->sprites_scaled; for (level = 0; level < dev_priv->display.wm.num_levels; level++) { - struct intel_wm_level *a_wm = &a->wm[level]; - const struct intel_wm_level *b_wm = &b->wm[level]; + struct intel_wm_level *intermediate_wm = &intermediate->wm[level]; + const struct intel_wm_level *active_wm = &active->wm[level]; - a_wm->enable &= b_wm->enable; - a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val); - a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val); - a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val); - a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val); + intermediate_wm->enable &= active_wm->enable; + intermediate_wm->pri_val = max(intermediate_wm->pri_val, + active_wm->pri_val); + intermediate_wm->spr_val = max(intermediate_wm->spr_val, + active_wm->spr_val); + intermediate_wm->cur_val = max(intermediate_wm->cur_val, + active_wm->cur_val); + intermediate_wm->fbc_val = max(intermediate_wm->fbc_val, + active_wm->fbc_val); } /* @@ -3030,14 +3035,14 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, * there's no safe way to transition from the old state to * the new state, so we need to fail the atomic transaction. */ - if (!ilk_validate_pipe_wm(dev_priv, a)) + if (!ilk_validate_pipe_wm(dev_priv, intermediate)) return -EINVAL; /* * If our intermediate WM are identical to the final WM, then we can * omit the post-vblank programming; only update if it's different. */ - if (memcmp(a, &new_crtc_state->wm.ilk.optimal, sizeof(*a)) != 0) + if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0) new_crtc_state->wm.need_postvbl_update = true; return 0; From e25c84e0abbeb164332d1b030323106979ef6593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:39 +0300 Subject: [PATCH 130/205] drm/i915: Set clear color block size to 0x0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't use the block size information for the clear color plane. Technically the entire fb is the single block for the single 64B clear color surface, so there is just no way to delcare that as a constant since the fb size can be anything. Define the clear color block size as 0x0 to make things less confusing. We already declared that cpp/chars_per_block=0 for the clear color as well. That also causes the drm core code to mostly ignore the clear color plane, which is exactly what we want since that code doesn't know how to deal with the clear color plane. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_fb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index c03060e5e503..6c2679e6c980 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -102,31 +102,31 @@ static const struct drm_format_info gen12_ccs_formats[] = { */ static const struct drm_format_info gen12_ccs_cc_formats[] = { { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3, - .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, .vsub = 1, }, { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3, - .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, .vsub = 1, }, { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3, - .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3, - .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, }; static const struct drm_format_info gen12_flat_ccs_cc_formats[] = { { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, - .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, .hsub = 1, .vsub = 1, }, { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, - .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, .hsub = 1, .vsub = 1, }, { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, - .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, - .char_per_block = { 4, 0 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, }; From 093ecfd550f6d403a858c80e81b6e5a21f2a5256 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Tue, 24 Sep 2024 13:04:51 +0530 Subject: [PATCH 131/205] drm/i915/hotplug: Reduce SHPD_FLITER_CNT for ICL and above Reduce SHPD_CNT to 250us for ICL and above as it lines up with DP1.4a(Table3-4) spec. --v2 -Update commit message and comment [Matt] --v3 -drop condition and use value of 250us for ICL and above [Matt] Signed-off-by: Suraj Kandpal Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20240924073450.1261535-2-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hotplug_irq.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c index 2c4e946d5575..3a105cfd3c90 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c @@ -849,10 +849,11 @@ static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv) enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); - if (INTEL_PCH_TYPE(dev_priv) <= PCH_TGP) - intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); - else - intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); + /* + * We reduce the value to 250us to be able to detect SHPD when an external display + * is connected. This is also expected of us as stated in DP1.4a Table 3-4. + */ + intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); From df3859a4aaa40783c50f43a6a8a53c7770d59ef1 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Mon, 23 Sep 2024 08:40:08 +0530 Subject: [PATCH 132/205] drm/i915/hotplug: Add comment for XE_LPD+ SHPD_FILTER_CNT value Add the reason for having SHPD_FILTER_CNT value for XE_LPD+ and above as 250us instead of 500us. --v2 -Update commit message [Matt] Signed-off-by: Suraj Kandpal Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20240923031007.1058072-4-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hotplug_irq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c index 3a105cfd3c90..5d055dc9366f 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c @@ -1061,6 +1061,10 @@ static void mtp_hpd_irq_setup(struct drm_i915_private *i915) enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd); hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd); + /* + * Use 250us here to align with the DP1.4a(Table 3-4) spec as to what the + * SHPD_FILTER_CNT value should be. + */ intel_de_write(i915, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); mtp_hpd_invert(i915); From 9572bdfeb1280fd1e5beb28e34e226a6bc851280 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 26 Sep 2024 13:43:28 +0530 Subject: [PATCH 133/205] drm/i915/vdsc: Add bpc check in intel_dsc_compute_params DSC does not support bpc under 8 according to DSC 1.2a Section 2 Requirements. Return an error if that happens to be the case. --v2 -should be bit_per_component [Mitul/Chaitanya] -Add reference to this restriction [Chaitanya] --v3 -Add the bpc in which we see this warning [Jani] Signed-off-by: Suraj Kandpal Reviewed-by: Chaitanya Kumar Borah Link: https://patchwork.freedesktop.org/patch/msgid/20240926081327.1409518-2-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 8158e3702ed5..208f117ece57 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -306,6 +306,12 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3; + if (vdsc_cfg->bits_per_component < 8) { + drm_dbg_kms(&dev_priv->drm, "DSC bpc requirements not met bpc: %d\n", + vdsc_cfg->bits_per_component); + return -EINVAL; + } + drm_dsc_set_rc_buf_thresh(vdsc_cfg); /* From 9d5a05f86d2f4f81abcac6abc856c0d511a8607b Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Fri, 27 Sep 2024 11:34:37 +0530 Subject: [PATCH 134/205] drm/i915/hdcp: Retry first read and writes to downstream Retry the first read and write to downstream at least 10 times with a 50ms delay if not hdcp2 capable(dock decides to stop advertising hdcp2 capability for some reason). The reason being that during suspend resume Dock usually keep the HDCP2 registers inaccesible causing AUX error. This wouldn't be a big problem if the userspace just kept retrying with some delay while it continues to play low values content but most userpace applications end up throwing an error when it receives one from KMD. This makes sure we give the dock and the sink devices to complete its power cycle and then try HDCP authentication. --v2 -Add more details in comment [Jani] -fix looping condition [Jani] -optimize loop exit condition [Jani] --v3 -Add comment explaining why the loop was added [Ankit] Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20240927060437.1422942-2-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_hdcp.c | 37 ++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 2afa92321b08..00d4c9ac6c45 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -1512,7 +1512,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) } msgs; const struct intel_hdcp_shim *shim = hdcp->shim; size_t size; - int ret; + int ret, i; /* Init for seq_num */ hdcp->seq_num_v = 0; @@ -1522,13 +1522,36 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) if (ret < 0) return ret; - ret = shim->write_2_2_msg(connector, &msgs.ake_init, - sizeof(msgs.ake_init)); - if (ret < 0) - return ret; + /* + * Retry the first read and write to downstream at least 10 times + * with a 50ms delay if not hdcp2 capable(dock decides to stop advertising + * hdcp2 capability for some reason). The reason being that + * during suspend resume dock usually keeps the HDCP2 registers inaccesible + * causing AUX error. This wouldn't be a big problem if the userspace + * just kept retrying with some delay while it continues to play low + * value content but most userpace applications end up throwing an error + * when it receives one from KMD. This makes sure we give the dock + * and the sink devices to complete its power cycle and then try HDCP + * authentication. The values of 10 and delay of 50ms was decided based + * on multiple trial and errors. + */ + for (i = 0; i < 10; i++) { + if (!intel_hdcp2_get_capability(connector)) { + msleep(50); + continue; + } + + ret = shim->write_2_2_msg(connector, &msgs.ake_init, + sizeof(msgs.ake_init)); + if (ret < 0) + continue; + + ret = shim->read_2_2_msg(connector, HDCP_2_2_AKE_SEND_CERT, + &msgs.send_cert, sizeof(msgs.send_cert)); + if (ret > 0) + break; + } - ret = shim->read_2_2_msg(connector, HDCP_2_2_AKE_SEND_CERT, - &msgs.send_cert, sizeof(msgs.send_cert)); if (ret < 0) return ret; From 89edc852fbe9893f7a61b7c001b0fb070623273a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 26 Sep 2024 19:13:19 +0530 Subject: [PATCH 135/205] drm/i915/display_device: Add Check HAS_DSC for bigjoiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bigjoiner needs DSC, but DSC might be disabled on some platforms. The platform check itself is not sufficient, so add a check for DSC to reflect that. v2: Modify the commit message to address the DSC fuse case. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240926134322.3728021-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 5306bbd13e59..6a5bee59e6aa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -118,7 +118,7 @@ enum intel_display_subplatform { #define HAS_4TILE(i915) (IS_DG2(i915) || DISPLAY_VER(i915) >= 14) #define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5) -#define HAS_BIGJOINER(i915) (DISPLAY_VER(i915) >= 11) +#define HAS_BIGJOINER(i915) (DISPLAY_VER(i915) >= 11 && HAS_DSC(i915)) #define HAS_CDCLK_CRAWL(i915) (DISPLAY_INFO(i915)->has_cdclk_crawl) #define HAS_CDCLK_SQUASH(i915) (DISPLAY_INFO(i915)->has_cdclk_squash) #define HAS_CUR_FBC(i915) (!HAS_GMCH(i915) && IS_DISPLAY_VER(i915, 7, 13)) From cdff99ff24b16ee37b0527fc64c0e7df4989a1ba Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 26 Sep 2024 19:13:20 +0530 Subject: [PATCH 136/205] drm/i915/display_debugfs: Allow force joiner only if supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we support joiner only for DP encoder. Do not create the debugfs for joiner if DP does not support the joiner. This will also help avoiding cases where config has eDP MSO, with which we do not support joiner. v2: Check for intel_dp_has_joiner and avoid creating debugfs if not supported. (Ville) v3: Remove HAS_BIGJOINER check. (Ville) v4: Reverse checks for connector type and intel_dp_has_joiner(). (Ville) v5: Drop the local variable intel_dp and use intel_attached_dp() directly. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240926134322.3728021-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 890ef7067b77..c38023b43682 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1362,9 +1362,9 @@ void intel_connector_debugfs_add(struct intel_connector *connector) connector, &i915_dsc_fractional_bpp_fops); } - if (HAS_BIGJOINER(i915) && - (connector_type == DRM_MODE_CONNECTOR_DisplayPort || - connector_type == DRM_MODE_CONNECTOR_eDP)) { + if ((connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector_type == DRM_MODE_CONNECTOR_eDP) && + intel_dp_has_joiner(intel_attached_dp(connector))) { debugfs_create_bool("i915_bigjoiner_force_enable", 0644, root, &connector->force_bigjoiner_enable); } From a47df3335a223c096b946b7934db12f9ac9948a4 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 26 Sep 2024 19:13:21 +0530 Subject: [PATCH 137/205] drm/i915/display: Modify debugfs for joiner to force n pipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the moment, the debugfs for joiner allows only to force enable/disable pipe joiner for 2 pipes. Modify it to force join 'n' number of pipes, where n is a valid pipe joiner configuration. This will help in case of ultra joiner where 4 pipes are joined. v2: -Fix commit message to state that only valid joiner config can be forced. (Suraj) -Rename the identifiers to have INTEL_BIG/NONE_JOINER_PIPES. (Suraj) v3: -Avoid enum for joiner pipe counts, use bare numbers for better readability. (Ville) -Remove redundant prints from debugfs. (Ville) v4: Return -EINVAL if joiner forced to an invalid value. v5: Remove extra debug message. (Ville) v6: Minor fix in switch case. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240926134322.3728021-4-ankit.k.nautiyal@intel.com --- .../drm/i915/display/intel_display_debugfs.c | 57 ++++++++++++++++++- .../drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index c38023b43682..ae3715f0f1d8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1316,6 +1316,59 @@ static int intel_crtc_pipe_show(struct seq_file *m, void *unused) } DEFINE_SHOW_ATTRIBUTE(intel_crtc_pipe); +static int i915_joiner_show(struct seq_file *m, void *data) +{ + struct intel_connector *connector = m->private; + + seq_printf(m, "%d\n", connector->force_joined_pipes); + + return 0; +} + +static ssize_t i915_joiner_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct intel_connector *connector = m->private; + int force_joined_pipes = 0; + int ret; + + if (len == 0) + return 0; + + ret = kstrtoint_from_user(ubuf, len, 0, &force_joined_pipes); + if (ret < 0) + return ret; + + switch (force_joined_pipes) { + case 0: + case 2: + connector->force_joined_pipes = force_joined_pipes; + break; + default: + return -EINVAL; + } + + *offp += len; + + return len; +} + +static int i915_joiner_open(struct inode *inode, struct file *file) +{ + return single_open(file, i915_joiner_show, inode->i_private); +} + +static const struct file_operations i915_joiner_fops = { + .owner = THIS_MODULE, + .open = i915_joiner_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = i915_joiner_write +}; + /** * intel_connector_debugfs_add - add i915 specific connector debugfs files * @connector: pointer to a registered intel_connector @@ -1365,8 +1418,8 @@ void intel_connector_debugfs_add(struct intel_connector *connector) if ((connector_type == DRM_MODE_CONNECTOR_DisplayPort || connector_type == DRM_MODE_CONNECTOR_eDP) && intel_dp_has_joiner(intel_attached_dp(connector))) { - debugfs_create_bool("i915_bigjoiner_force_enable", 0644, root, - &connector->force_bigjoiner_enable); + debugfs_create_file("i915_joiner_force_enable", 0644, root, + connector, &i915_joiner_fops); } if (connector_type == DRM_MODE_CONNECTOR_DSI || diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 7ff97e5b83dd..7fb3eeb0e0f2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -524,7 +524,7 @@ struct intel_connector { struct intel_dp *mst_port; - bool force_bigjoiner_enable; + int force_joined_pipes; struct { struct drm_dp_aux *dsc_decompression_aux; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 16dc1d26d2a2..a1a64758d30d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1274,7 +1274,7 @@ bool intel_dp_need_joiner(struct intel_dp *intel_dp, return false; return clock > i915->display.cdclk.max_dotclk_freq || hdisplay > 5120 || - connector->force_bigjoiner_enable; + connector->force_joined_pipes == 2; } bool intel_dp_has_dsc(const struct intel_connector *connector) From 84b2b38451a34e86f25bbfc5c5d50aab46713cd5 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 26 Sep 2024 19:13:22 +0530 Subject: [PATCH 138/205] drm/i915/dp: Add helper to compute num pipes required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper to compute the number of pipes required. This will depend on whether the joiner is required or is forced through the debugfs. If no joiner is required the helper returns 1. v2: -Return 1 if no joiner is required. (Ville) -Change the suffix from joined_pipes to num_pipes. (Ville) -Use number of pipes while calculating joined_pipe masks and max_dotclk. (Ville) v3: Simplify and rename the helper to intel_dp_num_joined_pipes(). Ville v4: Remove redundant 'fallthrough' statement. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240926134322.3728021-5-ankit.k.nautiyal@intel.com --- .../drm/i915/display/intel_display_debugfs.c | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 46 +++++++++++-------- drivers/gpu/drm/i915/display/intel_dp.h | 6 +-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 23 ++++------ 4 files changed, 40 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index ae3715f0f1d8..5923bbc232be 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1343,6 +1343,7 @@ static ssize_t i915_joiner_write(struct file *file, switch (force_joined_pipes) { case 0: + case 1: case 2: connector->force_joined_pipes = force_joined_pipes; break; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a1a64758d30d..f2a2541c1091 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1264,17 +1264,30 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector, return MODE_OK; } -bool intel_dp_need_joiner(struct intel_dp *intel_dp, - struct intel_connector *connector, - int hdisplay, int clock) +static +bool intel_dp_needs_bigjoiner(struct intel_dp *intel_dp, + struct intel_connector *connector, + int hdisplay, int clock) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); if (!intel_dp_has_joiner(intel_dp)) return false; - return clock > i915->display.cdclk.max_dotclk_freq || hdisplay > 5120 || - connector->force_joined_pipes == 2; + return clock > i915->display.cdclk.max_dotclk_freq || hdisplay > 5120; +} + +int intel_dp_num_joined_pipes(struct intel_dp *intel_dp, + struct intel_connector *connector, + int hdisplay, int clock) +{ + if (connector->force_joined_pipes) + return connector->force_joined_pipes; + + if (intel_dp_needs_bigjoiner(intel_dp, connector, hdisplay, clock)) + return 2; + + return 1; } bool intel_dp_has_dsc(const struct intel_connector *connector) @@ -1311,7 +1324,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, u16 dsc_max_compressed_bpp = 0; u8 dsc_slice_count = 0; enum drm_mode_status status; - bool dsc = false, joiner = false; + bool dsc = false; int num_joined_pipes; status = intel_cpu_transcoder_mode_valid(dev_priv, mode); @@ -1333,13 +1346,9 @@ intel_dp_mode_valid(struct drm_connector *_connector, target_clock = fixed_mode->clock; } - if (intel_dp_need_joiner(intel_dp, connector, - mode->hdisplay, target_clock)) { - joiner = true; - max_dotclk *= 2; - } - - num_joined_pipes = joiner ? 2 : 1; + num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector, + mode->hdisplay, target_clock); + max_dotclk *= num_joined_pipes; if (target_clock > max_dotclk) return MODE_CLOCK_HIGH; @@ -2507,12 +2516,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, !intel_dp_supports_fec(intel_dp, connector, pipe_config)) return -EINVAL; - if (intel_dp_need_joiner(intel_dp, connector, - adjusted_mode->crtc_hdisplay, - adjusted_mode->crtc_clock)) - pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe); - - num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); + num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector, + adjusted_mode->crtc_hdisplay, + adjusted_mode->crtc_clock); + if (num_joined_pipes > 1) + pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe); joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, num_joined_pipes); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 3b869429e575..53d1217800ef 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -151,9 +151,9 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, int mode_clock, int mode_hdisplay, int num_joined_pipes); -bool intel_dp_need_joiner(struct intel_dp *intel_dp, - struct intel_connector *connector, - int hdisplay, int clock); +int intel_dp_num_joined_pipes(struct intel_dp *intel_dp, + struct intel_connector *connector, + int hdisplay, int clock); static inline unsigned int intel_dp_unused_lane_mask(int lane_count) { diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 732d7543ad06..4765bda154c1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -581,12 +581,11 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; - if (intel_dp_need_joiner(intel_dp, connector, - adjusted_mode->crtc_hdisplay, - adjusted_mode->crtc_clock)) - pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe); - - num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); + num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector, + adjusted_mode->crtc_hdisplay, + adjusted_mode->crtc_clock); + if (num_joined_pipes > 1) + pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe); pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; @@ -1428,7 +1427,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq; int max_rate, mode_rate, max_lanes, max_link_clock; int ret; - bool dsc = false, joiner = false; + bool dsc = false; u16 dsc_max_compressed_bpp = 0; u8 dsc_slice_count = 0; int target_clock = mode->clock; @@ -1472,13 +1471,9 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, * corresponding link capabilities of the sink) in case the * stream is uncompressed for it by the last branch device. */ - if (intel_dp_need_joiner(intel_dp, intel_connector, - mode->hdisplay, target_clock)) { - joiner = true; - max_dotclk *= 2; - } - - num_joined_pipes = joiner ? 2 : 1; + num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, intel_connector, + mode->hdisplay, target_clock); + max_dotclk *= num_joined_pipes; ret = drm_modeset_lock(&mgr->base.lock, ctx); if (ret) From 4c1bfe259ed1d2ade826f95d437e1c41b274df04 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:35:43 +0300 Subject: [PATCH 139/205] drm/i915/gem: fix bitwise and logical AND mixup CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND is an int, defaulting to 250. When the wakeref is non-zero, it's either -1 or a dynamically allocated pointer, depending on CONFIG_DRM_I915_DEBUG_RUNTIME_PM. It's likely that the code works by coincidence with the bitwise AND, but with CONFIG_DRM_I915_DEBUG_RUNTIME_PM=y, there's the off chance that the condition evaluates to false, and intel_wakeref_auto() doesn't get called. Switch to the intended logical AND. v2: Use != to avoid clang -Wconstant-logical-operand (Nathan) Fixes: ad74457a6b5a ("drm/i915/dgfx: Release mmap on rpm suspend") Cc: Matthew Auld Cc: Rodrigo Vivi Cc: Anshuman Gupta Cc: Andi Shyti Cc: Nathan Chancellor Cc: stable@vger.kernel.org # v6.1+ Reviewed-by: Matthew Auld Reviewed-by: Andi Shyti # v1 Link: https://patchwork.freedesktop.org/patch/msgid/643cc0a4d12f47fd8403d42581e83b1e9c4543c7.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 5c72462d1f57..b22e2019768f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -1131,7 +1131,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) GEM_WARN_ON(!i915_ttm_cpu_maps_iomem(bo->resource)); } - if (wakeref & CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND) + if (wakeref && CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND != 0) intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref, msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)); From 3b8567486b5f3e576341a6cdb4b8b6aba7dac512 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:35:44 +0300 Subject: [PATCH 140/205] drm/i915: use INTEL_WAKEREF_DEF instead of magic -1 for intel_wakeref_t A number of places rely on the magic -1 to denote INTEL_WAKEREF_DEF. Switch to the macro. Define it for xe as well. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/57e5f1989113be4d63386478d9438cfc35a2a1f7.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- drivers/gpu/drm/i915/display/intel_display_power.h | 4 ++-- drivers/gpu/drm/i915/intel_runtime_pm.c | 6 +++--- drivers/gpu/drm/i915/intel_wakeref.h | 2 +- drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h | 7 ++++--- drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h | 2 ++ 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index ecabb674644b..40727a22f18b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -895,7 +895,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915, !bitmap_subset(mask->bits, power_domain_set->mask.bits, POWER_DOMAIN_NUM)); for_each_power_domain(domain, mask) { - intel_wakeref_t __maybe_unused wf = -1; + intel_wakeref_t __maybe_unused wf = INTEL_WAKEREF_DEF; #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) wf = fetch_and_zero(&power_domain_set->wakerefs[domain]); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 425452c5a469..3b7c1a0bb1de 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -232,7 +232,7 @@ intel_display_power_put_async(struct drm_i915_private *i915, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - __intel_display_power_put_async(i915, domain, -1, -1); + __intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, -1); } static inline void @@ -241,7 +241,7 @@ intel_display_power_put_async_delay(struct drm_i915_private *i915, intel_wakeref_t wakeref, int delay_ms) { - __intel_display_power_put_async(i915, domain, -1, delay_ms); + __intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, delay_ms); } #endif diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 2d0647aca964..a21f5a1c89bc 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -66,7 +66,7 @@ static intel_wakeref_t track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { if (!rpm->available || rpm->no_wakeref_tracking) - return -1; + return INTEL_WAKEREF_DEF; return intel_ref_tracker_alloc(&rpm->debug); } @@ -114,7 +114,7 @@ static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) static intel_wakeref_t track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { - return -1; + return INTEL_WAKEREF_DEF; } static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, @@ -336,7 +336,7 @@ intel_runtime_pm_put_raw(struct intel_runtime_pm *rpm, intel_wakeref_t wref) */ void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm) { - __intel_runtime_pm_put(rpm, -1, true); + __intel_runtime_pm_put(rpm, INTEL_WAKEREF_DEF, true); } #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index 68aa3be48251..3944587a5e78 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -314,7 +314,7 @@ static inline void intel_wakeref_untrack(struct intel_wakeref *wf, static inline intel_wakeref_t intel_wakeref_track(struct intel_wakeref *wf) { - return -1; + return INTEL_WAKEREF_DEF; } static inline void intel_wakeref_untrack(struct intel_wakeref *wf, diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h index 8c7b315aa8ac..380d25428bdb 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h @@ -24,14 +24,14 @@ static inline intel_wakeref_t intel_runtime_pm_get(struct xe_runtime_pm *pm) { struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - return xe_pm_runtime_resume_and_get(xe); + return xe_pm_runtime_resume_and_get(xe) ? INTEL_WAKEREF_DEF : 0; } static inline intel_wakeref_t intel_runtime_pm_get_if_in_use(struct xe_runtime_pm *pm) { struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - return xe_pm_runtime_get_if_in_use(xe); + return xe_pm_runtime_get_if_in_use(xe) ? INTEL_WAKEREF_DEF : 0; } static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm *pm) @@ -39,7 +39,8 @@ static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); xe_pm_runtime_get_noresume(xe); - return true; + + return INTEL_WAKEREF_DEF; } static inline void intel_runtime_pm_put_unchecked(struct xe_runtime_pm *pm) diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h index ecb1c0707706..5c139ba144a6 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h @@ -6,3 +6,5 @@ #include typedef unsigned long intel_wakeref_t; + +#define INTEL_WAKEREF_DEF ((intel_wakeref_t)(-1)) From c45c7b2475f7f47654377620533fa95b508a11a9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:35:45 +0300 Subject: [PATCH 141/205] drm/i915/display: return 0 instead of false for disabled power wakeref We can use 0 for intel_wakeref_t, but not false. Fix it. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202409190032.ZCHBxK9e-lkp@intel.com/ Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/263b062a37e7b9c345b5d3335282558ac38c5b73.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 40727a22f18b..7b16ba1a8226 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -545,7 +545,7 @@ intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, wakeref = intel_runtime_pm_get_if_in_use(&dev_priv->runtime_pm); if (!wakeref) - return false; + return 0; mutex_lock(&power_domains->lock); From 61dabe8234cbf1d0948f35601e055126cc1f7790 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:35:46 +0300 Subject: [PATCH 142/205] drm/i915/gt: add a macro for mock gt wakeref special value and use it Add a dedicated macro for the special mock gt wakeref value, with a cast to intel_wakeref_t, instead of assuming you can assign or compare the wakeref to -ENODEV directly. Arguably the whole thing is a hack that should not exist, but at least make it slightly less hacky. Side note: If this value were to ever end up in intel_ref_tracker_free(), it would wreak havoc. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/1da887a6b4fe1ec45355571ea7b56d91fadf0af2.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 6 +++++- drivers/gpu/drm/i915/gt/intel_tlb.c | 2 +- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h index 911fd0160221..fef8d5d288f8 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h @@ -105,9 +105,13 @@ int intel_gt_runtime_resume(struct intel_gt *gt); ktime_t intel_gt_get_awake_time(const struct intel_gt *gt); +#define INTEL_WAKEREF_MOCK_GT ((intel_wakeref_t)-ENODEV) + static inline bool is_mock_gt(const struct intel_gt *gt) { - return I915_SELFTEST_ONLY(gt->awake == -ENODEV); + BUILD_BUG_ON(INTEL_WAKEREF_DEF == INTEL_WAKEREF_MOCK_GT); + + return I915_SELFTEST_ONLY(gt->awake == INTEL_WAKEREF_MOCK_GT); } #endif /* INTEL_GT_PM_H */ diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c b/drivers/gpu/drm/i915/gt/intel_tlb.c index 756e9ebbc725..2487768bc230 100644 --- a/drivers/gpu/drm/i915/gt/intel_tlb.c +++ b/drivers/gpu/drm/i915/gt/intel_tlb.c @@ -122,7 +122,7 @@ void intel_gt_invalidate_tlb_full(struct intel_gt *gt, u32 seqno) { intel_wakeref_t wakeref; - if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) + if (is_mock_gt(gt)) return; if (intel_gt_is_wedged(gt)) diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 70f3d7bf47d0..ae57eb03dfca 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -203,7 +203,7 @@ struct drm_i915_private *mock_gem_device(void) intel_root_gt_init_early(i915); mock_uncore_init(&i915->uncore, i915); atomic_inc(&to_gt(i915)->wakeref.count); /* disable; no hw support */ - to_gt(i915)->awake = -ENODEV; + to_gt(i915)->awake = INTEL_WAKEREF_MOCK_GT; mock_gt_probe(i915); ret = intel_region_ttm_device_init(i915); From bc549f8fc6334cecc32bb2daf780e25da4ce8096 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:35:47 +0300 Subject: [PATCH 143/205] drm/i915/audio: be explicit about intel_wakeref_t conversions Use explicit casts to convert between intel_wakeref_t and unsigned long, to not rely on intel_wakeref_t underlying type remaining unsigned long, allowing us to change it as needed. (And yes, this is indeed preparation for changing the typedef for intel_wakeref_t.) Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/9d2a2c2399e70f36e0d68d88136ac688f02988fe.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_audio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index f5e7eefab2f1..32aa9ec1a204 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -982,12 +982,12 @@ static unsigned long i915_audio_component_get_power(struct device *kdev) { struct intel_display *display = to_intel_display(kdev); struct drm_i915_private *i915 = to_i915(display->drm); - intel_wakeref_t ret; + intel_wakeref_t wakeref; /* Catch potential impedance mismatches before they occur! */ BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long)); - ret = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK); + wakeref = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK); if (i915->display.audio.power_refcount++ == 0) { if (DISPLAY_VER(i915) >= 9) { @@ -1007,7 +1007,7 @@ static unsigned long i915_audio_component_get_power(struct device *kdev) 0, AUD_PIN_BUF_ENABLE); } - return ret; + return (unsigned long)wakeref; } static void i915_audio_component_put_power(struct device *kdev, @@ -1015,13 +1015,14 @@ static void i915_audio_component_put_power(struct device *kdev, { struct intel_display *display = to_intel_display(kdev); struct drm_i915_private *i915 = to_i915(display->drm); + intel_wakeref_t wakeref = (intel_wakeref_t)cookie; /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ if (--i915->display.audio.power_refcount == 0) if (IS_GEMINILAKE(i915)) glk_force_audio_cdclk(i915, false); - intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, cookie); + intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, wakeref); } static void i915_audio_component_codec_wake_override(struct device *kdev, From 2edc6a75f26c112d90ca67ff412ba79622069818 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2024 20:35:48 +0300 Subject: [PATCH 144/205] drm/i915: switch intel_wakeref_t underlying type to struct ref_tracker * For intel_wakeref_t, opaque is reasonable, but disguising the underlying struct ref_tracker * as an unsigned long is not so great. Update the typedef to remove one level of disguise. Although the kernel coding style strongly discourages pointer typedefs, it's a better alternative, and an incremental improvement on the status quo. It provides much better type safety than an unsigned long could, and prevents passing magic -1 instead of INTEL_WAKEREF_DEF. Moreover, it provides a gradual path for replacing intel_wakeref_t with struct ref_tracker * if desired. As an extra safety measure, check for error pointers in intel_ref_tracker_free() before passing them on to ref_tracker_free(), to catch any mistakes with mock gt special wakeref value. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/cca2b0631f816ad90461aa1bf4fe3f80c0e13464.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 2 +- drivers/gpu/drm/i915/intel_wakeref.h | 16 +++++++++------- .../drm/xe/compat-i915-headers/intel_wakeref.h | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h index fef8d5d288f8..dcbfc09194b7 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h @@ -105,7 +105,7 @@ int intel_gt_runtime_resume(struct intel_gt *gt); ktime_t intel_gt_get_awake_time(const struct intel_gt *gt); -#define INTEL_WAKEREF_MOCK_GT ((intel_wakeref_t)-ENODEV) +#define INTEL_WAKEREF_MOCK_GT ERR_PTR(-ENODEV) static inline bool is_mock_gt(const struct intel_gt *gt) { diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index 3944587a5e78..48836ef52d40 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -21,7 +21,7 @@ #include #include -typedef unsigned long intel_wakeref_t; +typedef struct ref_tracker *intel_wakeref_t; #define INTEL_REFTRACK_DEAD_COUNT 16 #define INTEL_REFTRACK_PRINT_LIMIT 16 @@ -273,7 +273,7 @@ __intel_wakeref_defer_park(struct intel_wakeref *wf) */ int intel_wakeref_wait_for_idle(struct intel_wakeref *wf); -#define INTEL_WAKEREF_DEF ((intel_wakeref_t)(-1)) +#define INTEL_WAKEREF_DEF ERR_PTR(-ENOENT) static inline intel_wakeref_t intel_ref_tracker_alloc(struct ref_tracker_dir *dir) { @@ -281,17 +281,19 @@ static inline intel_wakeref_t intel_ref_tracker_alloc(struct ref_tracker_dir *di ref_tracker_alloc(dir, &user, GFP_NOWAIT); - return (intel_wakeref_t)user ?: INTEL_WAKEREF_DEF; + return user ?: INTEL_WAKEREF_DEF; } static inline void intel_ref_tracker_free(struct ref_tracker_dir *dir, - intel_wakeref_t handle) + intel_wakeref_t wakeref) { - struct ref_tracker *user; + if (wakeref == INTEL_WAKEREF_DEF) + wakeref = NULL; - user = (handle == INTEL_WAKEREF_DEF) ? NULL : (void *)handle; + if (WARN_ON(IS_ERR(wakeref))) + return; - ref_tracker_free(dir, &user); + ref_tracker_free(dir, &wakeref); } void intel_ref_tracker_show(struct ref_tracker_dir *dir, diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h index 5c139ba144a6..2a32faea9db5 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_wakeref.h @@ -5,6 +5,6 @@ #include -typedef unsigned long intel_wakeref_t; +typedef struct ref_tracker *intel_wakeref_t; -#define INTEL_WAKEREF_DEF ((intel_wakeref_t)(-1)) +#define INTEL_WAKEREF_DEF ERR_PTR(-ENOENT) From 680d12cdb7e63c02e8fbd51982b4cef1d1fbb16f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Mon, 30 Sep 2024 10:13:29 +0300 Subject: [PATCH 145/205] Revert "drm/i915/psr: Implement WA to help reach PC10" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit c2579a217799ba577fa39a2a12643a277334e691. Reverting this commit as it is suspected being culprit on regression. Closes: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1649 Signed-off-by: Jouni Högander Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240930071329.1630583-1-jouni.hogander@intel.com Signed-off-by: Rodrigo Vivi --- .../drm/i915/display/intel_display_types.h | 3 - drivers/gpu/drm/i915/display/intel_psr.c | 119 +----------------- 2 files changed, 1 insertion(+), 121 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 7fb3eeb0e0f2..17fc21f6ae36 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1576,9 +1576,6 @@ struct intel_psr { #define I915_PSR_DEBUG_PANEL_REPLAY_DISABLE 0x40 u32 debug; - bool is_dpkgc_configured; - bool is_dc5_entry_possible; - bool is_wa_delayed_vblank_limit; bool sink_support; bool source_support; bool enabled; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 39aa46de15e4..e3357f3b5c70 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "i915_drv.h" #include "i915_reg.h" @@ -897,89 +896,6 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) return idle_frames; } -static bool -intel_psr_check_wa_delayed_vblank(const struct drm_display_mode *adjusted_mode) -{ - return (adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay) >= 6; -} - -/* - * PKG_C_LATENCY is configured only when DISPLAY_VER >= 20 and - * VRR is not enabled - */ -static bool intel_psr_is_dpkgc_configured(struct intel_display *display, - struct intel_atomic_state *state) -{ - struct intel_crtc *intel_crtc; - struct intel_crtc_state *crtc_state; - int i; - - if (DISPLAY_VER(display) < 20) - return false; - - for_each_new_intel_crtc_in_state(state, intel_crtc, crtc_state, i) { - if (!intel_crtc->active) - continue; - - if (crtc_state->vrr.enable) - return false; - } - - return true; -} - -static bool wa_22019444797_psr1_check(const struct intel_crtc_state *crtc_state, - struct intel_psr *psr) -{ - struct intel_display *display = to_intel_display(crtc_state); - - return DISPLAY_VER(display) == 20 && psr->is_dpkgc_configured && - (psr->is_wa_delayed_vblank_limit || !psr->is_dc5_entry_possible) && - !crtc_state->has_sel_update && !crtc_state->has_panel_replay; -} - -/* - * DC5 entry is only possible if vblank interrupt is disabled - * and either psr1, psr2, edp 1.5 pr alpm is enabled on all - * enabled encoders. - */ -static bool -intel_psr_is_dc5_entry_possible(struct intel_display *display, - struct intel_atomic_state *state) -{ - struct intel_crtc *intel_crtc; - struct intel_crtc_state *crtc_state; - int i; - - if ((display->power.domains.target_dc_state & - DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0) - return false; - - for_each_new_intel_crtc_in_state(state, intel_crtc, crtc_state, i) { - struct drm_crtc *crtc = &intel_crtc->base; - struct drm_vblank_crtc *vblank; - struct intel_encoder *encoder; - - if (!intel_crtc->active) - continue; - - vblank = drm_crtc_vblank_crtc(crtc); - - if (vblank->enabled) - return false; - - if (!crtc_state->has_psr) - return false; - - for_each_encoder_on_crtc(display->drm, crtc, encoder) - if (encoder->type != INTEL_OUTPUT_EDP || - !CAN_PSR(enc_to_intel_dp(encoder))) - return false; - } - - return true; -} - static void hsw_activate_psr1(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); @@ -1092,15 +1008,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) u32 val = EDP_PSR2_ENABLE; u32 psr_val = 0; - /* - * Wa_22019444797 - * TODO: Disable idle frames when vblank gets enabled while - * PSR2 is enabled - */ - if (DISPLAY_VER(dev_priv) != 20 || - !intel_dp->psr.is_dpkgc_configured || - intel_dp->psr.is_dc5_entry_possible) - val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp)); + val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp)); if (DISPLAY_VER(display) < 14 && !IS_ALDERLAKE_P(dev_priv)) val |= EDP_SU_TRACK_ENABLE; @@ -2815,20 +2723,10 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder; - bool dpkgc_configured = false, dc5_entry_possible = false; - bool wa_delayed_vblank_limit = false; if (!HAS_PSR(display)) return; - if (DISPLAY_VER(display) == 20) { - dpkgc_configured = intel_psr_is_dpkgc_configured(display, state); - dc5_entry_possible = - intel_psr_is_dc5_entry_possible(display, state); - wa_delayed_vblank_limit = - intel_psr_check_wa_delayed_vblank(&new_crtc_state->hw.adjusted_mode); - } - for_each_intel_encoder_mask_with_psr(state->base.dev, encoder, old_crtc_state->uapi.encoder_mask) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -2837,12 +2735,6 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, mutex_lock(&psr->lock); - if (DISPLAY_VER(i915) == 20) { - psr->is_dpkgc_configured = dpkgc_configured; - psr->is_dc5_entry_possible = dc5_entry_possible; - psr->is_wa_delayed_vblank_limit = wa_delayed_vblank_limit; - } - /* * Reasons to disable: * - PSR disabled in new state @@ -2850,7 +2742,6 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, * - Changing between PSR versions * - Region Early Transport changing * - Display WA #1136: skl, bxt - * - Display WA_22019444797 */ needs_to_disable |= intel_crtc_needs_modeset(new_crtc_state); needs_to_disable |= !new_crtc_state->has_psr; @@ -2860,8 +2751,6 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, psr->su_region_et_enabled; needs_to_disable |= DISPLAY_VER(i915) < 11 && new_crtc_state->wm_level_disabled; - /* TODO: Disable PSR1 when vblank gets enabled while PSR1 is enabled */ - needs_to_disable |= wa_22019444797_psr1_check(new_crtc_state, psr); if (psr->enabled && needs_to_disable) intel_psr_disable_locked(intel_dp); @@ -2902,12 +2791,6 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state, keep_disabled |= DISPLAY_VER(display) < 11 && crtc_state->wm_level_disabled; - /* - * Wa_22019444797 - * TODO: Disable PSR1 when vblank gets enabled while PSR1 is enabled - */ - keep_disabled |= wa_22019444797_psr1_check(crtc_state, psr); - if (!psr->enabled && !keep_disabled) intel_psr_enable_locked(intel_dp, crtc_state); else if (psr->enabled && !crtc_state->wm_level_disabled) From 4e6ebb419a02950840a4a610a5bfca8fe55b03c7 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:37 +0530 Subject: [PATCH 146/205] drm/i915: Split current joiner hw state readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to add a new sanity checks and also do some preparations for adding ultrajoiner hw state readout. Lets first split reading of the uncompressed joiner and bigjoiner bit masks into separate functions. v2: Fixed checkpatch warnings (Ankit) v3: Use struct intel_display in the new functions. (Ankit) v4: Use check for bigjoiner before reading the regs. (Ville) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 78 ++++++++++++++------ 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f7667931f9d9..8d37973864ee 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3580,26 +3580,57 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, return tmp & TRANS_DDI_FUNC_ENABLE; } -static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, - u8 *primary_pipes, u8 *secondary_pipes) +static void enabled_uncompressed_joiner_pipes(struct intel_display *display, + u8 *primary_pipes, u8 *secondary_pipes) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_crtc *crtc; *primary_pipes = 0; *secondary_pipes = 0; - if (!HAS_BIGJOINER(dev_priv)) + if (!HAS_UNCOMPRESSED_JOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, - joiner_pipes(dev_priv)) { + for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, + joiner_pipes(i915)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; intel_wakeref_t wakeref; - power_domain = intel_dsc_power_domain(crtc, (enum transcoder) pipe); - with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) { - u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe)); + power_domain = POWER_DOMAIN_PIPE(pipe); + with_intel_display_power_if_enabled(i915, power_domain, wakeref) { + u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); + + if (tmp & UNCOMPRESSED_JOINER_PRIMARY) + *primary_pipes |= BIT(pipe); + if (tmp & UNCOMPRESSED_JOINER_SECONDARY) + *secondary_pipes |= BIT(pipe); + } + } +} + +static void enabled_bigjoiner_pipes(struct intel_display *display, + u8 *primary_pipes, u8 *secondary_pipes) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_crtc *crtc; + + *primary_pipes = 0; + *secondary_pipes = 0; + + if (!HAS_BIGJOINER(display)) + return; + + for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, + joiner_pipes(i915)) { + enum intel_display_power_domain power_domain; + enum pipe pipe = crtc->pipe; + intel_wakeref_t wakeref; + + power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); + with_intel_display_power_if_enabled(i915, power_domain, wakeref) { + u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (!(tmp & BIG_JOINER_ENABLE)) continue; @@ -3609,20 +3640,25 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, else *secondary_pipes |= BIT(pipe); } - - if (!HAS_UNCOMPRESSED_JOINER(dev_priv)) - continue; - - power_domain = POWER_DOMAIN_PIPE(pipe); - with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) { - u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe)); - - if (tmp & UNCOMPRESSED_JOINER_PRIMARY) - *primary_pipes |= BIT(pipe); - if (tmp & UNCOMPRESSED_JOINER_SECONDARY) - *secondary_pipes |= BIT(pipe); - } } +} + +static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, + u8 *primary_pipes, u8 *secondary_pipes) +{ + struct intel_display *display = to_intel_display(&dev_priv->drm); + u8 primary_uncompressed_joiner_pipes, primary_bigjoiner_pipes; + u8 secondary_uncompressed_joiner_pipes, secondary_bigjoiner_pipes; + + enabled_uncompressed_joiner_pipes(display, &primary_uncompressed_joiner_pipes, + &secondary_uncompressed_joiner_pipes); + + enabled_bigjoiner_pipes(display, &primary_bigjoiner_pipes, + &secondary_bigjoiner_pipes); + + *primary_pipes = primary_uncompressed_joiner_pipes | primary_bigjoiner_pipes; + + *secondary_pipes = secondary_uncompressed_joiner_pipes | secondary_bigjoiner_pipes; /* Joiner pipes should always be consecutive primary and secondary */ drm_WARN(&dev_priv->drm, *secondary_pipes != *primary_pipes << 1, From 012daa8c625d00966e3010143e4c16deabbd6fdd Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 30 Sep 2024 22:05:38 +0530 Subject: [PATCH 147/205] drm/i915: Add bigjoiner and uncompressed joiner hw readout sanity checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sanity checks for primary and secondary bigjoiner/uncompressed bitmasks, should make it easier to spot possible issues. v2: -Streamline the expected masks and add few more drm_WARNs. (Ville) -Use %#x format specifier for printing joiner masks. (Ville) -Use struct intel_display instead of struct drm_i915_private. (Ankit) v3: -Rename helper to get expected uncompressed joiner pipes. (Ville) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal (v1) Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 51 +++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8d37973864ee..2d6260c3bca5 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3643,26 +3643,73 @@ static void enabled_bigjoiner_pipes(struct intel_display *display, } } +static u8 expected_secondary_pipes(u8 primary_pipes, int num_pipes) +{ + u8 secondary_pipes = 0; + + for (int i = 1; i < num_pipes; i++) + secondary_pipes |= primary_pipes << i; + + return secondary_pipes; +} + +static u8 expected_uncompressed_joiner_secondary_pipes(u8 uncompjoiner_primary_pipes) +{ + return expected_secondary_pipes(uncompjoiner_primary_pipes, 2); +} + +static u8 expected_bigjoiner_secondary_pipes(u8 bigjoiner_primary_pipes) +{ + return expected_secondary_pipes(bigjoiner_primary_pipes, 2); +} + static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, u8 *primary_pipes, u8 *secondary_pipes) { struct intel_display *display = to_intel_display(&dev_priv->drm); u8 primary_uncompressed_joiner_pipes, primary_bigjoiner_pipes; u8 secondary_uncompressed_joiner_pipes, secondary_bigjoiner_pipes; + u8 uncompressed_joiner_pipes, bigjoiner_pipes; enabled_uncompressed_joiner_pipes(display, &primary_uncompressed_joiner_pipes, &secondary_uncompressed_joiner_pipes); + drm_WARN_ON(display->drm, + (primary_uncompressed_joiner_pipes & secondary_uncompressed_joiner_pipes) != 0); + enabled_bigjoiner_pipes(display, &primary_bigjoiner_pipes, &secondary_bigjoiner_pipes); + drm_WARN_ON(display->drm, + (primary_bigjoiner_pipes & secondary_bigjoiner_pipes) != 0); + + uncompressed_joiner_pipes = primary_uncompressed_joiner_pipes | + secondary_uncompressed_joiner_pipes; + bigjoiner_pipes = primary_bigjoiner_pipes | secondary_bigjoiner_pipes; + + drm_WARN(display->drm, (uncompressed_joiner_pipes & bigjoiner_pipes) != 0, + "Uncomressed joiner pipes(%#x) and bigjoiner pipes(%#x) can't intersect\n", + uncompressed_joiner_pipes, bigjoiner_pipes); + + drm_WARN(display->drm, secondary_bigjoiner_pipes != + expected_bigjoiner_secondary_pipes(primary_bigjoiner_pipes), + "Wrong secondary bigjoiner pipes(expected %#x, current %#x)\n", + expected_bigjoiner_secondary_pipes(primary_bigjoiner_pipes), + secondary_bigjoiner_pipes); + + drm_WARN(display->drm, secondary_uncompressed_joiner_pipes != + expected_uncompressed_joiner_secondary_pipes(primary_uncompressed_joiner_pipes), + "Wrong secondary uncompressed joiner pipes(expected %#x, current %#x)\n", + expected_uncompressed_joiner_secondary_pipes(primary_uncompressed_joiner_pipes), + secondary_uncompressed_joiner_pipes); + *primary_pipes = primary_uncompressed_joiner_pipes | primary_bigjoiner_pipes; *secondary_pipes = secondary_uncompressed_joiner_pipes | secondary_bigjoiner_pipes; /* Joiner pipes should always be consecutive primary and secondary */ - drm_WARN(&dev_priv->drm, *secondary_pipes != *primary_pipes << 1, - "Joiner misconfigured (primary pipes 0x%x, secondary pipes 0x%x)\n", + drm_WARN(display->drm, *secondary_pipes != *primary_pipes << 1, + "Joiner misconfigured (primary pipes %#x, secondary pipes %#x)\n", *primary_pipes, *secondary_pipes); } From 8c2b586095fa390f862dbca3b773246684d8f35f Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:39 +0530 Subject: [PATCH 148/205] drm/i915/display: Add macro HAS_ULTRAJOINER() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add macro to check if platform supports Ultrajoiner. v2: -Use check for DISPLAY_VER >= 20, and add bmg as a special case. (Ville) -Add check for HAS_DSC. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-4-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display_device.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 6a5bee59e6aa..220cca6333ee 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -154,6 +154,9 @@ enum intel_display_subplatform { #define HAS_TRANSCODER(i915, trans) ((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \ BIT(trans)) != 0) #define HAS_UNCOMPRESSED_JOINER(i915) (DISPLAY_VER(i915) >= 13) +#define HAS_ULTRAJOINER(i915) ((DISPLAY_VER(i915) >= 20 || \ + (IS_DGFX(i915) && DISPLAY_VER(i915) == 14)) && \ + HAS_DSC(i915)) #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11) #define HAS_AS_SDP(i915) (DISPLAY_VER(i915) >= 13) #define HAS_CMRR(i915) (DISPLAY_VER(i915) >= 20) From f9ee6b5748e6ee09d135c588832a5022cadc8da7 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:40 +0530 Subject: [PATCH 149/205] drm/i915/display: Refactor enable_joiner_pipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the current pipe into enabled_joiner_pipes(), and let it figure out the proper bitmasks for us. Since the enabled_joiner_pipes now gets the primary and secondary pipes wrt a given pipe, the helpers to get primary pipe and secondary pipes are no longer required. v2: -Simplify helper get_joiner_primary_pipes. (Ville) -Nuke get_joiner_secondary_pipes. (Ville) -Add more drm_WARNs final primary/secondary pipes. (Ville) v3: Drop ultrajoiner stuff and add it in subsequent patches. (Ville) v4: -Replace input variable name primary_pipes to primary_pipe for enabled_joiner_pipes() -Avoid get_joiner_primary_pipe and use primary_pipes set by enabled_joiner_pipes(). (Ville) Signed-off-by: Ankit Nautiyal Suggested-by: Ville Syrjälä Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-5-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 90 ++++++++++---------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2d6260c3bca5..711811b3cb5e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3663,8 +3663,16 @@ static u8 expected_bigjoiner_secondary_pipes(u8 bigjoiner_primary_pipes) return expected_secondary_pipes(bigjoiner_primary_pipes, 2); } +static u8 get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes) +{ + primary_pipes &= GENMASK(pipe, 0); + + return primary_pipes ? BIT(fls(primary_pipes) - 1) : 0; +} + static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, - u8 *primary_pipes, u8 *secondary_pipes) + enum pipe pipe, + u8 *primary_pipe, u8 *secondary_pipes) { struct intel_display *display = to_intel_display(&dev_priv->drm); u8 primary_uncompressed_joiner_pipes, primary_bigjoiner_pipes; @@ -3703,45 +3711,38 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, expected_uncompressed_joiner_secondary_pipes(primary_uncompressed_joiner_pipes), secondary_uncompressed_joiner_pipes); - *primary_pipes = primary_uncompressed_joiner_pipes | primary_bigjoiner_pipes; + *primary_pipe = 0; + *secondary_pipes = 0; - *secondary_pipes = secondary_uncompressed_joiner_pipes | secondary_bigjoiner_pipes; + if (uncompressed_joiner_pipes & BIT(pipe)) { + *primary_pipe = get_joiner_primary_pipe(pipe, primary_uncompressed_joiner_pipes); + *secondary_pipes = secondary_uncompressed_joiner_pipes & + expected_uncompressed_joiner_secondary_pipes(*primary_pipe); - /* Joiner pipes should always be consecutive primary and secondary */ - drm_WARN(display->drm, *secondary_pipes != *primary_pipes << 1, - "Joiner misconfigured (primary pipes %#x, secondary pipes %#x)\n", - *primary_pipes, *secondary_pipes); -} + drm_WARN(display->drm, + expected_uncompressed_joiner_secondary_pipes(*primary_pipe) != + *secondary_pipes, + "Wrong uncompressed joiner secondary pipes for primary_pipe %#x (expected %#x, current %#x)\n", + *primary_pipe, + expected_uncompressed_joiner_secondary_pipes(*primary_pipe), + *secondary_pipes); + return; + } -static enum pipe get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes) -{ - if ((secondary_pipes & BIT(pipe)) == 0) - return pipe; + if (bigjoiner_pipes & BIT(pipe)) { + *primary_pipe = get_joiner_primary_pipe(pipe, primary_bigjoiner_pipes); + *secondary_pipes = secondary_bigjoiner_pipes & + expected_bigjoiner_secondary_pipes(*primary_pipe); - /* ignore everything above our pipe */ - primary_pipes &= ~GENMASK(7, pipe); - - /* highest remaining bit should be our primary pipe */ - return fls(primary_pipes) - 1; -} - -static u8 get_joiner_secondary_pipes(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes) -{ - enum pipe primary_pipe, next_primary_pipe; - - primary_pipe = get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes); - - if ((primary_pipes & BIT(primary_pipe)) == 0) - return 0; - - /* ignore our primary pipe and everything below it */ - primary_pipes &= ~GENMASK(primary_pipe, 0); - /* make sure a high bit is set for the ffs() */ - primary_pipes |= BIT(7); - /* lowest remaining bit should be the next primary pipe */ - next_primary_pipe = ffs(primary_pipes) - 1; - - return secondary_pipes & GENMASK(next_primary_pipe - 1, primary_pipe); + drm_WARN(display->drm, + expected_bigjoiner_secondary_pipes(*primary_pipe) != + *secondary_pipes, + "Wrong bigjoiner secondary pipes for primary_pipe %#x (expected %#x, current %#x)\n", + *primary_pipe, + expected_bigjoiner_secondary_pipes(*primary_pipe), + *secondary_pipes); + return; + } } static u8 hsw_panel_transcoders(struct drm_i915_private *i915) @@ -3760,7 +3761,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(dev); u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv); enum transcoder cpu_transcoder; - u8 primary_pipes, secondary_pipes; + u8 primary_pipe, secondary_pipes; u8 enabled_transcoders = 0; /* @@ -3813,10 +3814,9 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) enabled_transcoders |= BIT(cpu_transcoder); /* joiner secondary -> consider the primary pipe's transcoder as well */ - enabled_joiner_pipes(dev_priv, &primary_pipes, &secondary_pipes); + enabled_joiner_pipes(dev_priv, crtc->pipe, &primary_pipe, &secondary_pipes); if (secondary_pipes & BIT(crtc->pipe)) { - cpu_transcoder = (enum transcoder) - get_joiner_primary_pipe(crtc->pipe, primary_pipes, secondary_pipes); + cpu_transcoder = (enum transcoder)ffs(primary_pipe) - 1; if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder)) enabled_transcoders |= BIT(cpu_transcoder); } @@ -3947,17 +3947,15 @@ static void intel_joiner_get_config(struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); - u8 primary_pipes, secondary_pipes; + u8 primary_pipe, secondary_pipes; enum pipe pipe = crtc->pipe; - enabled_joiner_pipes(i915, &primary_pipes, &secondary_pipes); + enabled_joiner_pipes(i915, pipe, &primary_pipe, &secondary_pipes); - if (((primary_pipes | secondary_pipes) & BIT(pipe)) == 0) + if (((primary_pipe | secondary_pipes) & BIT(pipe)) == 0) return; - crtc_state->joiner_pipes = - BIT(get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes)) | - get_joiner_secondary_pipes(pipe, primary_pipes, secondary_pipes); + crtc_state->joiner_pipes = primary_pipe | secondary_pipes; } static bool hsw_get_pipe_config(struct intel_crtc *crtc, From 2e45a87eab34f7a9b9b8e5e254084a916c1d12d5 Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 30 Sep 2024 22:05:41 +0530 Subject: [PATCH 150/205] drm/i915: Implement hw state readout and checks for ultrajoiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ultrajoiner mode has some new bits and states to be read out from the hw. Lets make changes accordingly. v2: Fix checkpatch warnings. (Ankit) v3: Add separate functions for computing expected secondary_big/ultrajoiner pipes. (Ankit) v4: -Streamline the helpers for ultrajoiner. (Ville) -Add fixup to accommodate PIPED check for ultrajoiner. (Ville) -Add more Ultrajoiner drm_WARNs. (Ville) v5: Remove spurious newline. (Ville) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-6-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 88 +++++++++++++++++++ .../gpu/drm/i915/display/intel_vdsc_regs.h | 2 + 2 files changed, 90 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 711811b3cb5e..099304a74203 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3670,15 +3670,77 @@ static u8 get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes) return primary_pipes ? BIT(fls(primary_pipes) - 1) : 0; } +static u8 expected_ultrajoiner_secondary_pipes(u8 ultrajoiner_primary_pipes) +{ + return expected_secondary_pipes(ultrajoiner_primary_pipes, 4); +} + +static u8 fixup_ultrajoiner_secondary_pipes(u8 ultrajoiner_primary_pipes, + u8 ultrajoiner_secondary_pipes) +{ + return ultrajoiner_secondary_pipes | ultrajoiner_primary_pipes << 3; +} + +static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915, + u8 *primary_pipes, u8 *secondary_pipes) +{ + struct intel_crtc *crtc; + + *primary_pipes = 0; + *secondary_pipes = 0; + + if (!HAS_ULTRAJOINER(i915)) + return; + + for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, + joiner_pipes(i915)) { + enum intel_display_power_domain power_domain; + enum pipe pipe = crtc->pipe; + intel_wakeref_t wakeref; + + power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); + with_intel_display_power_if_enabled(i915, power_domain, wakeref) { + u32 tmp = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); + + if (!(tmp & ULTRA_JOINER_ENABLE)) + continue; + + if (tmp & PRIMARY_ULTRA_JOINER_ENABLE) + *primary_pipes |= BIT(pipe); + else + *secondary_pipes |= BIT(pipe); + } + } +} + static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, enum pipe pipe, u8 *primary_pipe, u8 *secondary_pipes) { struct intel_display *display = to_intel_display(&dev_priv->drm); + u8 primary_ultrajoiner_pipes; u8 primary_uncompressed_joiner_pipes, primary_bigjoiner_pipes; + u8 secondary_ultrajoiner_pipes; u8 secondary_uncompressed_joiner_pipes, secondary_bigjoiner_pipes; + u8 ultrajoiner_pipes; u8 uncompressed_joiner_pipes, bigjoiner_pipes; + enabled_ultrajoiner_pipes(dev_priv, &primary_ultrajoiner_pipes, + &secondary_ultrajoiner_pipes); + /* + * For some strange reason the last pipe in the set of four + * shouldn't have ultrajoiner enable bit set in hardware. + * Set the bit anyway to make life easier. + */ + drm_WARN_ON(&dev_priv->drm, + expected_secondary_pipes(primary_ultrajoiner_pipes, 3) != + secondary_ultrajoiner_pipes); + secondary_ultrajoiner_pipes = + fixup_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes, + secondary_ultrajoiner_pipes); + + drm_WARN_ON(&dev_priv->drm, (primary_ultrajoiner_pipes & secondary_ultrajoiner_pipes) != 0); + enabled_uncompressed_joiner_pipes(display, &primary_uncompressed_joiner_pipes, &secondary_uncompressed_joiner_pipes); @@ -3691,10 +3753,21 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, drm_WARN_ON(display->drm, (primary_bigjoiner_pipes & secondary_bigjoiner_pipes) != 0); + ultrajoiner_pipes = primary_ultrajoiner_pipes | secondary_ultrajoiner_pipes; uncompressed_joiner_pipes = primary_uncompressed_joiner_pipes | secondary_uncompressed_joiner_pipes; bigjoiner_pipes = primary_bigjoiner_pipes | secondary_bigjoiner_pipes; + drm_WARN(display->drm, (ultrajoiner_pipes & bigjoiner_pipes) != ultrajoiner_pipes, + "Ultrajoiner pipes(%#x) should be bigjoiner pipes(%#x)\n", + ultrajoiner_pipes, bigjoiner_pipes); + + drm_WARN(display->drm, secondary_ultrajoiner_pipes != + expected_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes), + "Wrong secondary ultrajoiner pipes(expected %#x, current %#x)\n", + expected_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes), + secondary_ultrajoiner_pipes); + drm_WARN(display->drm, (uncompressed_joiner_pipes & bigjoiner_pipes) != 0, "Uncomressed joiner pipes(%#x) and bigjoiner pipes(%#x) can't intersect\n", uncompressed_joiner_pipes, bigjoiner_pipes); @@ -3714,6 +3787,21 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, *primary_pipe = 0; *secondary_pipes = 0; + if (ultrajoiner_pipes & BIT(pipe)) { + *primary_pipe = get_joiner_primary_pipe(pipe, primary_ultrajoiner_pipes); + *secondary_pipes = secondary_ultrajoiner_pipes & + expected_ultrajoiner_secondary_pipes(*primary_pipe); + + drm_WARN(display->drm, + expected_ultrajoiner_secondary_pipes(*primary_pipe) != + *secondary_pipes, + "Wrong ultrajoiner secondary pipes for primary_pipe %#x (expected %#x, current %#x)\n", + *primary_pipe, + expected_ultrajoiner_secondary_pipes(*primary_pipe), + *secondary_pipes); + return; + } + if (uncompressed_joiner_pipes & BIT(pipe)) { *primary_pipe = get_joiner_primary_pipe(pipe, primary_uncompressed_joiner_pipes); *secondary_pipes = secondary_uncompressed_joiner_pipes & diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h index f921ad67b587..bf32a3b46fb1 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h @@ -37,6 +37,8 @@ #define SPLITTER_CONFIGURATION_MASK REG_GENMASK(26, 25) #define SPLITTER_CONFIGURATION_2_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 0) #define SPLITTER_CONFIGURATION_4_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 1) +#define ULTRA_JOINER_ENABLE REG_BIT(23) +#define PRIMARY_ULTRA_JOINER_ENABLE REG_BIT(22) #define UNCOMPRESSED_JOINER_PRIMARY (1 << 21) #define UNCOMPRESSED_JOINER_SECONDARY (1 << 20) From dc393d478d7d26581d72ea82d7f89359e0bc1f94 Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 30 Sep 2024 22:05:42 +0530 Subject: [PATCH 151/205] drm/i915/display/vdsc: Add ultrajoiner support with DSC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add changes to DSC which are required for Ultrajoiner. v2: -Use correct helper for setting bits for bigjoiner secondary. (Ankit) -Use primary/secondary instead of master/slave. (Suraj) v3: Add the ultrajoiner helpers and use it for setting ultrajoiner bits (Ankit) v4: Use num_vdsc_instances *= num_joined_pipes (Ville) v5: Align the helper to get ultrajoiner enabled pipes with other helpers (Ville) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-7-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 42 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_display.h | 3 ++ drivers/gpu/drm/i915/display/intel_vdsc.c | 11 ++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 099304a74203..40ad3fdaab10 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -312,6 +312,48 @@ u8 _intel_modeset_secondary_pipes(const struct intel_crtc_state *crtc_state) return bigjoiner_secondary_pipes(crtc_state); } +bool intel_crtc_is_ultrajoiner(const struct intel_crtc_state *crtc_state) +{ + return intel_crtc_num_joined_pipes(crtc_state) >= 4; +} + +static u8 ultrajoiner_primary_pipes(const struct intel_crtc_state *crtc_state) +{ + if (!intel_crtc_is_ultrajoiner(crtc_state)) + return 0; + + return crtc_state->joiner_pipes & (0b00010001 << joiner_primary_pipe(crtc_state)); +} + +bool intel_crtc_is_ultrajoiner_primary(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + return intel_crtc_is_ultrajoiner(crtc_state) && + BIT(crtc->pipe) & ultrajoiner_primary_pipes(crtc_state); +} + +/* + * The ultrajoiner enable bit doesn't seem to follow primary/secondary logic or + * any other logic, so lets just add helper function to + * at least hide this hassle.. + */ +static u8 ultrajoiner_enable_pipes(const struct intel_crtc_state *crtc_state) +{ + if (!intel_crtc_is_ultrajoiner(crtc_state)) + return 0; + + return crtc_state->joiner_pipes & (0b01110111 << joiner_primary_pipe(crtc_state)); +} + +bool intel_crtc_ultrajoiner_enable_needed(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + return intel_crtc_is_ultrajoiner(crtc_state) && + BIT(crtc->pipe) & ultrajoiner_enable_pipes(crtc_state); +} + u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state) { if (crtc_state->joiner_pipes) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 1f0fed5ea7bc..61e1df878de9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -441,6 +441,9 @@ bool intel_crtc_is_joiner_secondary(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_bigjoiner_primary(const struct intel_crtc_state *crtc_state); bool intel_crtc_is_bigjoiner_secondary(const struct intel_crtc_state *crtc_state); +bool intel_crtc_is_ultrajoiner(const struct intel_crtc_state *crtc_state); +bool intel_crtc_is_ultrajoiner_primary(const struct intel_crtc_state *crtc_state); +bool intel_crtc_ultrajoiner_enable_needed(const struct intel_crtc_state *crtc_state); u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state); u8 _intel_modeset_primary_pipes(const struct intel_crtc_state *crtc_state); u8 _intel_modeset_secondary_pipes(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 208f117ece57..40525f5c4c42 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -385,9 +385,9 @@ static int intel_dsc_get_vdsc_per_pipe(const struct intel_crtc_state *crtc_state int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state) { int num_vdsc_instances = intel_dsc_get_vdsc_per_pipe(crtc_state); + int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state); - if (crtc_state->joiner_pipes) - num_vdsc_instances *= 2; + num_vdsc_instances *= num_joined_pipes; return num_vdsc_instances; } @@ -776,7 +776,14 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state) dss_ctl1_val |= JOINER_ENABLE; } if (crtc_state->joiner_pipes) { + if (intel_crtc_ultrajoiner_enable_needed(crtc_state)) + dss_ctl1_val |= ULTRA_JOINER_ENABLE; + + if (intel_crtc_is_ultrajoiner_primary(crtc_state)) + dss_ctl1_val |= PRIMARY_ULTRA_JOINER_ENABLE; + dss_ctl1_val |= BIG_JOINER_ENABLE; + if (intel_crtc_is_bigjoiner_primary(crtc_state)) dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE; } From fb4dd411cf9cbd663042f50331ab2eb4a9735693 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:43 +0530 Subject: [PATCH 152/205] drm/i915/dp: Refactor joiner max_bpp calculations into separate functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently compressed max_bpp limitations for small joiner ram, big joiner etc are intermingled. Seprate these limitations into separate functions. v2: Use num_joined_pipes in small joiner ram helper and other minor fixes. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-8-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 46 +++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f2a2541c1091..29f8cb9c4dd0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -859,25 +859,51 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p return bits_per_pixel; } +static int bigjoiner_interface_bits(struct intel_display *display) +{ + return DISPLAY_VER(display) >= 14 ? 36 : 24; +} + +static u32 bigjoiner_bw_max_bpp(struct intel_display *display, u32 mode_clock) +{ + u32 max_bpp; + /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ + int ppc = 2; + + max_bpp = display->cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits(display) / + intel_dp_mode_to_fec_clock(mode_clock); + + return max_bpp; +} + +static u32 small_joiner_ram_max_bpp(struct intel_display *display, + u32 mode_hdisplay, + int num_joined_pipes) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + u32 max_bpp; + + /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ + max_bpp = small_joiner_ram_size_bits(i915) / mode_hdisplay; + + max_bpp *= num_joined_pipes; + + return max_bpp; +} + static u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915, u32 mode_clock, u32 mode_hdisplay, int num_joined_pipes) { + struct intel_display *display = to_intel_display(&i915->drm); u32 max_bpp_small_joiner_ram; - /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ - max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / mode_hdisplay; + max_bpp_small_joiner_ram = small_joiner_ram_max_bpp(display, mode_hdisplay, + num_joined_pipes); if (num_joined_pipes == 2) { - int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24; - /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ - int ppc = 2; - u32 max_bpp_bigjoiner = - i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits / - intel_dp_mode_to_fec_clock(mode_clock); - - max_bpp_small_joiner_ram *= 2; + u32 max_bpp_bigjoiner = bigjoiner_bw_max_bpp(display, mode_clock); return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner); } From 38c311f1c3101194c95fd5323d82452a9ced186d Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:44 +0530 Subject: [PATCH 153/205] drm/i915/dp: Use num_joined_pipes in bigjoiner_bw_max_bpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Streamline the helper to get max compressed bpp for bigjoiner case, to effectively use num of pipes joined. This will make the addition of ultrajoiner limitations easier and improve redability. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-9-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 29f8cb9c4dd0..a85527a55dc0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -864,16 +864,21 @@ static int bigjoiner_interface_bits(struct intel_display *display) return DISPLAY_VER(display) >= 14 ? 36 : 24; } -static u32 bigjoiner_bw_max_bpp(struct intel_display *display, u32 mode_clock) +static u32 bigjoiner_bw_max_bpp(struct intel_display *display, u32 mode_clock, + int num_joined_pipes) { u32 max_bpp; /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ int ppc = 2; + int num_big_joiners = num_joined_pipes / 2; max_bpp = display->cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits(display) / intel_dp_mode_to_fec_clock(mode_clock); + max_bpp *= num_big_joiners; + return max_bpp; + } static u32 small_joiner_ram_max_bpp(struct intel_display *display, @@ -903,7 +908,8 @@ u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915, num_joined_pipes); if (num_joined_pipes == 2) { - u32 max_bpp_bigjoiner = bigjoiner_bw_max_bpp(display, mode_clock); + u32 max_bpp_bigjoiner = bigjoiner_bw_max_bpp(display, mode_clock, + num_joined_pipes); return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner); } From 94d949103ddfa21361120cd936ee2e9ae05b0cd1 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:45 +0530 Subject: [PATCH 154/205] drm/i915/dp: Modify compressed bpp limitations for ultrajoiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add compressed bpp limitations for ultrajoiner. v2: Fix the case for 1 pipe. (Ankit) v3: Refactor existing helper separately and add only ultrajoiner limitation. (Ville) v4: Separate out function for ultrajoiner_ram_bits. v5: Make the helper function more concise. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-10-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 28 +++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a85527a55dc0..d8a4a6fa1514 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -896,25 +896,31 @@ static u32 small_joiner_ram_max_bpp(struct intel_display *display, return max_bpp; } +static int ultrajoiner_ram_bits(void) +{ + return 4 * 72 * 512; +} + +static u32 ultrajoiner_ram_max_bpp(u32 mode_hdisplay) +{ + return ultrajoiner_ram_bits() / mode_hdisplay; +} + static u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915, u32 mode_clock, u32 mode_hdisplay, int num_joined_pipes) { struct intel_display *display = to_intel_display(&i915->drm); - u32 max_bpp_small_joiner_ram; + u32 max_bpp = small_joiner_ram_max_bpp(display, mode_hdisplay, num_joined_pipes); - max_bpp_small_joiner_ram = small_joiner_ram_max_bpp(display, mode_hdisplay, - num_joined_pipes); + if (num_joined_pipes > 1) + max_bpp = min(max_bpp, bigjoiner_bw_max_bpp(display, mode_clock, + num_joined_pipes)); + if (num_joined_pipes == 4) + max_bpp = min(max_bpp, ultrajoiner_ram_max_bpp(mode_hdisplay)); - if (num_joined_pipes == 2) { - u32 max_bpp_bigjoiner = bigjoiner_bw_max_bpp(display, mode_clock, - num_joined_pipes); - - return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner); - } - - return max_bpp_small_joiner_ram; + return max_bpp; } u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, From f84be3b3f81a62163484e8a3a4ee7c0ca2063995 Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 30 Sep 2024 22:05:46 +0530 Subject: [PATCH 155/205] drm/i915/dp: Simplify helper to get slice count with joiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When bigjoiner is used, we need at least 2 dsc slices per pipe. Modify the condition in intel_dp_dsc_get_slice_count() to reflect the same. Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-11-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d8a4a6fa1514..8e091f74eb9a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1022,8 +1022,12 @@ u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, false)) break; - /* big joiner needs small joiner to be enabled */ - if (num_joined_pipes == 2 && test_slice_count < 4) + /* + * Bigjoiner needs small joiner to be enabled. + * So there should be at least 2 dsc slices per pipe, + * whenever bigjoiner is enabled. + */ + if (num_joined_pipes > 1 && valid_dsc_slicecount[i] < 2) continue; if (min_slice_count <= test_slice_count) From 988d9e5fdd520711ac4cb203e7207125b51197b2 Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 30 Sep 2024 22:05:47 +0530 Subject: [PATCH 156/205] drm/i915: Compute config and mode valid changes for ultrajoiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement required changes for mode validation and compute config, to support Ultrajoiner. v2: -Drop changes for HDMI. -Separate out DSC changes into another patch. v3: Fix check in can_ultrajoiner. (Ankit) v4: -Unify helper to check joiner requirement. (Ville) -Split patches for ultrajoiner changes for max dsc slices and compressed bpp.(Ankit) v5: Fix check for joiner. (Ville) Signed-off-by: Stanislav Lisovskiy Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-12-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 26 +++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8e091f74eb9a..c4fdae5097ec 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1307,26 +1307,38 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector, } static -bool intel_dp_needs_bigjoiner(struct intel_dp *intel_dp, - struct intel_connector *connector, - int hdisplay, int clock) +bool intel_dp_needs_joiner(struct intel_dp *intel_dp, + struct intel_connector *connector, + int hdisplay, int clock, + int num_joined_pipes) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); if (!intel_dp_has_joiner(intel_dp)) return false; - return clock > i915->display.cdclk.max_dotclk_freq || hdisplay > 5120; + num_joined_pipes /= 2; + + return clock > num_joined_pipes * i915->display.cdclk.max_dotclk_freq || + hdisplay > num_joined_pipes * 5120; } int intel_dp_num_joined_pipes(struct intel_dp *intel_dp, struct intel_connector *connector, int hdisplay, int clock) { + struct intel_display *display = to_intel_display(intel_dp); + struct drm_i915_private *i915 = to_i915(display->drm); + if (connector->force_joined_pipes) return connector->force_joined_pipes; - if (intel_dp_needs_bigjoiner(intel_dp, connector, hdisplay, clock)) + if (HAS_ULTRAJOINER(i915) && + intel_dp_needs_joiner(intel_dp, connector, hdisplay, clock, 4)) + return 4; + + if ((HAS_BIGJOINER(i915) || HAS_UNCOMPRESSED_JOINER(i915)) && + intel_dp_needs_joiner(intel_dp, connector, hdisplay, clock, 2)) return 2; return 1; @@ -2532,8 +2544,10 @@ bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, * Pipe joiner needs compression up to display 12 due to bandwidth * limitation. DG2 onwards pipe joiner can be enabled without * compression. + * Ultrajoiner always needs compression. */ - return !HAS_UNCOMPRESSED_JOINER(i915) && num_joined_pipes == 2; + return (!HAS_UNCOMPRESSED_JOINER(i915) && num_joined_pipes == 2) || + num_joined_pipes == 4; } static int From f4f8f0eaaafce3b06238be85b80d64ecf73be719 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:48 +0530 Subject: [PATCH 157/205] drm/i915/display: Consider ultrajoiner for computing maxdotclock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the check for ultrajoiner while computing maxdotclock. v2: Add Check for HAS_UNCOMPRESSED_JOINER. (Ville) v3: Remove extraneous newline. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-13-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 40ad3fdaab10..74311bb9d290 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8186,8 +8186,9 @@ static int max_dotclock(struct drm_i915_private *i915) { int max_dotclock = i915->display.cdclk.max_dotclk_freq; - /* icl+ might use joiner */ - if (HAS_BIGJOINER(i915)) + if (HAS_ULTRAJOINER(i915)) + max_dotclock *= 4; + else if (HAS_UNCOMPRESSED_JOINER(i915) || HAS_BIGJOINER(i915)) max_dotclock *= 2; return max_dotclock; From 9949bf7b025b469a9700f31c550eb186273651d9 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 30 Sep 2024 22:05:49 +0530 Subject: [PATCH 158/205] drm/i915/intel_dp: Add support for forcing ultrajoiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow forcing ultrajoiner through debugfs. v2: Minor refactoring of switch case logic. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930163549.416410-14-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 5923bbc232be..11aff485d8fa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1331,6 +1331,7 @@ static ssize_t i915_joiner_write(struct file *file, { struct seq_file *m = file->private_data; struct intel_connector *connector = m->private; + struct drm_i915_private *i915 = to_i915(connector->base.dev); int force_joined_pipes = 0; int ret; @@ -1347,6 +1348,13 @@ static ssize_t i915_joiner_write(struct file *file, case 2: connector->force_joined_pipes = force_joined_pipes; break; + case 4: + if (HAS_ULTRAJOINER(i915)) { + connector->force_joined_pipes = force_joined_pipes; + break; + } + + fallthrough; default: return -EINVAL; } From 80143072576d78a4233414f0b65efc2bfe1e7aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 23 Sep 2024 18:24:48 +0300 Subject: [PATCH 159/205] drm/i915/bios: Use drm_dbg_kms() consistently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the few oddball drm_dbg() calls in VBT related code with drm_dbg_kms() as that is what we generally use for all display code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240923152453.11230-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_bios.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index daa4b9535123..b00aad23d6c2 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1706,8 +1706,8 @@ parse_mipi_config(struct intel_display *display, return; } - drm_dbg(display->drm, "Found MIPI Config block, panel index = %d\n", - panel_type); + drm_dbg_kms(display->drm, "Found MIPI Config block, panel index = %d\n", + panel_type); /* * get hold of the correct configuration block and pps data as per @@ -2067,8 +2067,8 @@ parse_mipi_sequence(struct intel_display *display, return; } - drm_dbg(display->drm, "Found MIPI sequence block v%u\n", - sequence->version); + drm_dbg_kms(display->drm, "Found MIPI sequence block v%u\n", + sequence->version); seq_data = find_panel_sequence_block(display, sequence, panel_type, &seq_size); if (!seq_data) @@ -2114,7 +2114,7 @@ parse_mipi_sequence(struct intel_display *display, fixup_mipi_sequences(display, panel); - drm_dbg(display->drm, "MIPI related VBT parsing complete\n"); + drm_dbg_kms(display->drm, "MIPI related VBT parsing complete\n"); return; err: @@ -2771,9 +2771,9 @@ static bool child_device_size_valid(struct intel_display *display, int size) expected_size = child_device_expected_size(display->vbt.version); if (expected_size < 0) { expected_size = sizeof(struct child_device_config); - drm_dbg(display->drm, - "Expected child device config size for VBT version %u not known; assuming %d\n", - display->vbt.version, expected_size); + drm_dbg_kms(display->drm, + "Expected child device config size for VBT version %u not known; assuming %d\n", + display->vbt.version, expected_size); } /* Flag an error for unexpected size, but continue anyway. */ @@ -3143,14 +3143,14 @@ static struct vbt_header *oprom_get_vbt(struct intel_display *display, goto err_unmap_oprom; if (sizeof(struct vbt_header) > size) { - drm_dbg(display->drm, "VBT header incomplete\n"); + drm_dbg_kms(display->drm, "VBT header incomplete\n"); goto err_unmap_oprom; } vbt_size = ioread16(p + offsetof(struct vbt_header, vbt_size)); if (vbt_size > size) { - drm_dbg(display->drm, - "VBT incomplete (vbt_size overflows)\n"); + drm_dbg_kms(display->drm, + "VBT incomplete (vbt_size overflows)\n"); goto err_unmap_oprom; } From 1533b4057f1d8fd3296116e010880ae5b604edbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 23 Sep 2024 18:24:49 +0300 Subject: [PATCH 160/205] drm/i915/bios: Add some size checks to SPI VBT read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify the SPI vs. PCI ROM VBT read codepaths a bit by pulling some size overflow checks from the PCI side into the SPI side. v2: s/drm_dbg()/drm_dbg_kms()/ Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240923152453.11230-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index b00aad23d6c2..37f30bb76e08 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -3088,11 +3088,22 @@ static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, if (count >= oprom_size) goto err_not_found; + if (sizeof(struct vbt_header) > oprom_size - count) { + drm_dbg_kms(display->drm, "VBT header incomplete\n"); + goto err_not_found; + } + /* Get VBT size and allocate space for the VBT */ vbt_size = intel_spi_read(&i915->uncore, found + offsetof(struct vbt_header, vbt_size)); vbt_size &= 0xffff; + if (vbt_size > oprom_size - count) { + drm_dbg_kms(display->drm, + "VBT incomplete (vbt_size overflows)\n"); + goto err_not_found; + } + vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL); if (!vbt) goto err_not_found; From 3823683a0f170c45b84e8a32a3c282f783f9620a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 23 Sep 2024 18:24:50 +0300 Subject: [PATCH 161/205] drm/i915/bios: Round PCI ROM VBT allocation to multiple of 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SPI code rounds the VBT allocation to a multiple of four bytes (presumably because it reads the VBT 4 bytes at a time). Do the same for the PCI ROM side to eliminate pointless differences between the two codepaths. This will make no functional difference. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240923152453.11230-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 37f30bb76e08..d4281234773c 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -3166,7 +3166,7 @@ static struct vbt_header *oprom_get_vbt(struct intel_display *display, } /* The rest will be validated by intel_bios_is_valid_vbt() */ - vbt = kmalloc(vbt_size, GFP_KERNEL); + vbt = kmalloc(round_up(vbt_size, 4), GFP_KERNEL); if (!vbt) goto err_unmap_oprom; From 4c997c6e439013df942af27761edc01e1065cc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 23 Sep 2024 18:24:51 +0300 Subject: [PATCH 162/205] drm/i915/bios: Extract intel_spi_read16() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SPI VBT codepath only knows how to read 4 bytes at a time. So to read the 2 byte vbt_size it masks out the unwanted msbs. Hide that little implementation detail inside a new intel_spi_read16() helper. Alse rename the existing intel_spi_read() to intel_spi_read32() to make it clear what it does. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240923152453.11230-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index d4281234773c..38ea92b4ff13 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -3053,13 +3053,18 @@ static struct vbt_header *firmware_get_vbt(struct intel_display *display, return vbt; } -static u32 intel_spi_read(struct intel_uncore *uncore, u32 offset) +static u32 intel_spi_read32(struct intel_uncore *uncore, u32 offset) { intel_uncore_write(uncore, PRIMARY_SPI_ADDRESS, offset); return intel_uncore_read(uncore, PRIMARY_SPI_TRIGGER); } +static u16 intel_spi_read16(struct intel_uncore *uncore, u32 offset) +{ + return intel_spi_read32(uncore, offset) & 0xffff; +} + static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, size_t *size) { @@ -3078,7 +3083,7 @@ static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, oprom_offset &= OROM_OFFSET_MASK; for (count = 0; count < oprom_size; count += 4) { - data = intel_spi_read(&i915->uncore, oprom_offset + count); + data = intel_spi_read32(&i915->uncore, oprom_offset + count); if (data == *((const u32 *)"$VBT")) { found = oprom_offset + count; break; @@ -3094,9 +3099,8 @@ static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, } /* Get VBT size and allocate space for the VBT */ - vbt_size = intel_spi_read(&i915->uncore, - found + offsetof(struct vbt_header, vbt_size)); - vbt_size &= 0xffff; + vbt_size = intel_spi_read16(&i915->uncore, + found + offsetof(struct vbt_header, vbt_size)); if (vbt_size > oprom_size - count) { drm_dbg_kms(display->drm, @@ -3109,7 +3113,7 @@ static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, goto err_not_found; for (count = 0; count < vbt_size; count += 4) - *(vbt + store++) = intel_spi_read(&i915->uncore, found + count); + *(vbt + store++) = intel_spi_read32(&i915->uncore, found + count); if (!intel_bios_is_valid_vbt(display, vbt, vbt_size)) goto err_free_vbt; From 0667ca80024a0ffb73ac42544b152b421a205b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 23 Sep 2024 18:24:52 +0300 Subject: [PATCH 163/205] drm/i915/bios: Extract vbt_signature[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the three hand rolled "$VBT"s with a vbt_signature[] to avoid accidents. v2: Include terminating '\0' for safety (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240923152453.11230-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 38ea92b4ff13..c57426940cf8 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2964,6 +2964,9 @@ static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt) return _vbt + vbt->bdb_offset; } +static const char vbt_signature[] = "$VBT"; +static const int vbt_signature_len = 4; + /** * intel_bios_is_valid_vbt - does the given buffer contain a valid VBT * @display: display device @@ -2986,7 +2989,7 @@ bool intel_bios_is_valid_vbt(struct intel_display *display, return false; } - if (memcmp(vbt->signature, "$VBT", 4)) { + if (memcmp(vbt->signature, vbt_signature, vbt_signature_len)) { drm_dbg_kms(display->drm, "VBT invalid signature\n"); return false; } @@ -3082,9 +3085,12 @@ static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET); oprom_offset &= OROM_OFFSET_MASK; + BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1); + BUILD_BUG_ON(vbt_signature_len != sizeof(u32)); + for (count = 0; count < oprom_size; count += 4) { data = intel_spi_read32(&i915->uncore, oprom_offset + count); - if (data == *((const u32 *)"$VBT")) { + if (data == *((const u32 *)vbt_signature)) { found = oprom_offset + count; break; } @@ -3144,9 +3150,12 @@ static struct vbt_header *oprom_get_vbt(struct intel_display *display, if (!oprom) return NULL; + BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1); + BUILD_BUG_ON(vbt_signature_len != sizeof(u32)); + /* Scour memory looking for the VBT signature. */ for (i = 0; i + 4 < size; i += 4) { - if (ioread32(oprom + i) != *((const u32 *)"$VBT")) + if (ioread32(oprom + i) != *((const u32 *)vbt_signature)) continue; p = oprom + i; From e622905020fb8e2152804971db47586ccc846b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 23 Sep 2024 18:24:53 +0300 Subject: [PATCH 164/205] drm/i915/bios: Extract soc/intel_rom.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Abstract away the nuts and bolts of the SPI vs. PCI ROM stuff, and hide it all in soc/intel_rom.c so that the VBT code doesn't have to care about this stuff. This leaves intel_bios.c with a single codepath that can focus on the details related to the VBT layout. This should have no functional changes. v2: Rebase due to vbt_signature changes Drop unnecessary cast (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240923152453.11230-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/display/intel_bios.c | 151 ++++------------- drivers/gpu/drm/i915/soc/intel_rom.c | 160 ++++++++++++++++++ drivers/gpu/drm/i915/soc/intel_rom.h | 25 +++ drivers/gpu/drm/xe/Makefile | 3 +- .../xe/compat-i915-headers/soc/intel_rom.h | 6 + 6 files changed, 224 insertions(+), 124 deletions(-) create mode 100644 drivers/gpu/drm/i915/soc/intel_rom.c create mode 100644 drivers/gpu/drm/i915/soc/intel_rom.h create mode 100644 drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 70771e521b1c..e033bcaef4f3 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -51,7 +51,8 @@ i915-y += \ i915-y += \ soc/intel_dram.o \ soc/intel_gmch.o \ - soc/intel_pch.o + soc/intel_pch.o \ + soc/intel_rom.o # core library code i915-y += \ diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index c57426940cf8..9967b65e3cf6 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -33,12 +33,12 @@ #include #include +#include "soc/intel_rom.h" + #include "i915_drv.h" -#include "i915_reg.h" #include "intel_display.h" #include "intel_display_types.h" #include "intel_gmbus.h" -#include "intel_uncore.h" #define _INTEL_BIOS_PRIVATE #include "intel_vbt_defs.h" @@ -3056,152 +3056,59 @@ static struct vbt_header *firmware_get_vbt(struct intel_display *display, return vbt; } -static u32 intel_spi_read32(struct intel_uncore *uncore, u32 offset) -{ - intel_uncore_write(uncore, PRIMARY_SPI_ADDRESS, offset); - - return intel_uncore_read(uncore, PRIMARY_SPI_TRIGGER); -} - -static u16 intel_spi_read16(struct intel_uncore *uncore, u32 offset) -{ - return intel_spi_read32(uncore, offset) & 0xffff; -} - -static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display, - size_t *size) -{ - struct drm_i915_private *i915 = to_i915(display->drm); - u32 count, data, found, store = 0; - u32 static_region, oprom_offset; - u32 oprom_size = 0x200000; - u16 vbt_size; - u32 *vbt; - - static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS); - static_region &= OPTIONROM_SPI_REGIONID_MASK; - intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region); - - oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET); - oprom_offset &= OROM_OFFSET_MASK; - - BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1); - BUILD_BUG_ON(vbt_signature_len != sizeof(u32)); - - for (count = 0; count < oprom_size; count += 4) { - data = intel_spi_read32(&i915->uncore, oprom_offset + count); - if (data == *((const u32 *)vbt_signature)) { - found = oprom_offset + count; - break; - } - } - - if (count >= oprom_size) - goto err_not_found; - - if (sizeof(struct vbt_header) > oprom_size - count) { - drm_dbg_kms(display->drm, "VBT header incomplete\n"); - goto err_not_found; - } - - /* Get VBT size and allocate space for the VBT */ - vbt_size = intel_spi_read16(&i915->uncore, - found + offsetof(struct vbt_header, vbt_size)); - - if (vbt_size > oprom_size - count) { - drm_dbg_kms(display->drm, - "VBT incomplete (vbt_size overflows)\n"); - goto err_not_found; - } - - vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL); - if (!vbt) - goto err_not_found; - - for (count = 0; count < vbt_size; count += 4) - *(vbt + store++) = intel_spi_read32(&i915->uncore, found + count); - - if (!intel_bios_is_valid_vbt(display, vbt, vbt_size)) - goto err_free_vbt; - - drm_dbg_kms(display->drm, "Found valid VBT in SPI flash\n"); - - if (size) - *size = vbt_size; - - return (struct vbt_header *)vbt; - -err_free_vbt: - kfree(vbt); -err_not_found: - return NULL; -} - static struct vbt_header *oprom_get_vbt(struct intel_display *display, - size_t *sizep) + struct intel_rom *rom, + size_t *size, const char *type) { - struct pci_dev *pdev = to_pci_dev(display->drm->dev); - void __iomem *p = NULL, *oprom; struct vbt_header *vbt; - u16 vbt_size; - size_t i, size; + size_t vbt_size; + loff_t offset; - oprom = pci_map_rom(pdev, &size); - if (!oprom) + if (!rom) return NULL; BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1); BUILD_BUG_ON(vbt_signature_len != sizeof(u32)); - /* Scour memory looking for the VBT signature. */ - for (i = 0; i + 4 < size; i += 4) { - if (ioread32(oprom + i) != *((const u32 *)vbt_signature)) - continue; + offset = intel_rom_find(rom, *(const u32 *)vbt_signature); + if (offset < 0) + goto err_free_rom; - p = oprom + i; - size -= i; - break; - } - - if (!p) - goto err_unmap_oprom; - - if (sizeof(struct vbt_header) > size) { + if (sizeof(struct vbt_header) > intel_rom_size(rom) - offset) { drm_dbg_kms(display->drm, "VBT header incomplete\n"); - goto err_unmap_oprom; + goto err_free_rom; } - vbt_size = ioread16(p + offsetof(struct vbt_header, vbt_size)); - if (vbt_size > size) { - drm_dbg_kms(display->drm, - "VBT incomplete (vbt_size overflows)\n"); - goto err_unmap_oprom; + BUILD_BUG_ON(sizeof(vbt->vbt_size) != sizeof(u16)); + + vbt_size = intel_rom_read16(rom, offset + offsetof(struct vbt_header, vbt_size)); + if (vbt_size > intel_rom_size(rom) - offset) { + drm_dbg_kms(display->drm, "VBT incomplete (vbt_size overflows)\n"); + goto err_free_rom; } - /* The rest will be validated by intel_bios_is_valid_vbt() */ - vbt = kmalloc(round_up(vbt_size, 4), GFP_KERNEL); + vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL); if (!vbt) - goto err_unmap_oprom; + goto err_free_rom; - memcpy_fromio(vbt, p, vbt_size); + intel_rom_read_block(rom, vbt, offset, vbt_size); if (!intel_bios_is_valid_vbt(display, vbt, vbt_size)) goto err_free_vbt; - pci_unmap_rom(pdev, oprom); + drm_dbg_kms(display->drm, "Found valid VBT in %s\n", type); - if (sizep) - *sizep = vbt_size; + if (size) + *size = vbt_size; - drm_dbg_kms(display->drm, "Found valid VBT in PCI ROM\n"); + intel_rom_free(rom); return vbt; err_free_vbt: kfree(vbt); -err_unmap_oprom: - pci_unmap_rom(pdev, oprom); - +err_free_rom: + intel_rom_free(rom); return NULL; } @@ -3223,11 +3130,11 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display */ if (!vbt && IS_DGFX(i915)) with_intel_runtime_pm(&i915->runtime_pm, wakeref) - vbt = spi_oprom_get_vbt(display, sizep); + vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash"); if (!vbt) with_intel_runtime_pm(&i915->runtime_pm, wakeref) - vbt = oprom_get_vbt(display, sizep); + vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM"); return vbt; } diff --git a/drivers/gpu/drm/i915/soc/intel_rom.c b/drivers/gpu/drm/i915/soc/intel_rom.c new file mode 100644 index 000000000000..243d98cab8c3 --- /dev/null +++ b/drivers/gpu/drm/i915/soc/intel_rom.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2024 Intel Corporation + */ + +#include "i915_drv.h" +#include "i915_reg.h" + +#include "intel_rom.h" +#include "intel_uncore.h" + +struct intel_rom { + /* for PCI ROM */ + struct pci_dev *pdev; + void __iomem *oprom; + + /* for SPI */ + struct intel_uncore *uncore; + loff_t offset; + + size_t size; + + u32 (*read32)(struct intel_rom *rom, loff_t offset); + u16 (*read16)(struct intel_rom *rom, loff_t offset); + void (*read_block)(struct intel_rom *rom, void *data, loff_t offset, size_t size); + void (*free)(struct intel_rom *rom); +}; + +static u32 spi_read32(struct intel_rom *rom, loff_t offset) +{ + intel_uncore_write(rom->uncore, PRIMARY_SPI_ADDRESS, + rom->offset + offset); + + return intel_uncore_read(rom->uncore, PRIMARY_SPI_TRIGGER); +} + +static u16 spi_read16(struct intel_rom *rom, loff_t offset) +{ + return spi_read32(rom, offset) & 0xffff; +} + +struct intel_rom *intel_rom_spi(struct drm_i915_private *i915) +{ + struct intel_rom *rom; + u32 static_region; + + rom = kzalloc(sizeof(*rom), GFP_KERNEL); + if (!rom) + return NULL; + + rom->uncore = &i915->uncore; + + static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS); + static_region &= OPTIONROM_SPI_REGIONID_MASK; + intel_uncore_write(rom->uncore, PRIMARY_SPI_REGIONID, static_region); + + rom->offset = intel_uncore_read(rom->uncore, OROM_OFFSET) & OROM_OFFSET_MASK; + + rom->size = 0x200000; + + rom->read32 = spi_read32; + rom->read16 = spi_read16; + + return rom; +} + +static u32 pci_read32(struct intel_rom *rom, loff_t offset) +{ + return ioread32(rom->oprom + offset); +} + +static u16 pci_read16(struct intel_rom *rom, loff_t offset) +{ + return ioread16(rom->oprom + offset); +} + +static void pci_read_block(struct intel_rom *rom, void *data, + loff_t offset, size_t size) +{ + memcpy_fromio(data, rom->oprom + offset, size); +} + +static void pci_free(struct intel_rom *rom) +{ + pci_unmap_rom(rom->pdev, rom->oprom); +} + +struct intel_rom *intel_rom_pci(struct drm_i915_private *i915) +{ + struct intel_rom *rom; + + rom = kzalloc(sizeof(*rom), GFP_KERNEL); + if (!rom) + return NULL; + + rom->pdev = to_pci_dev(i915->drm.dev); + + rom->oprom = pci_map_rom(rom->pdev, &rom->size); + if (!rom->oprom) { + kfree(rom); + return NULL; + } + + rom->read32 = pci_read32; + rom->read16 = pci_read16; + rom->read_block = pci_read_block; + rom->free = pci_free; + + return rom; +} + +u32 intel_rom_read32(struct intel_rom *rom, loff_t offset) +{ + return rom->read32(rom, offset); +} + +u16 intel_rom_read16(struct intel_rom *rom, loff_t offset) +{ + return rom->read16(rom, offset); +} + +void intel_rom_read_block(struct intel_rom *rom, void *data, + loff_t offset, size_t size) +{ + u32 *ptr = data; + loff_t index; + + if (rom->read_block) { + rom->read_block(rom, data, offset, size); + return; + } + + for (index = 0; index < size; index += 4) + *ptr++ = rom->read32(rom, offset + index); +} + +loff_t intel_rom_find(struct intel_rom *rom, u32 needle) +{ + loff_t offset; + + for (offset = 0; offset < rom->size; offset += 4) { + if (rom->read32(rom, offset) == needle) + return offset; + } + + return -ENOENT; +} + +size_t intel_rom_size(struct intel_rom *rom) +{ + return rom->size; +} + +void intel_rom_free(struct intel_rom *rom) +{ + if (rom && rom->free) + rom->free(rom); + + kfree(rom); +} diff --git a/drivers/gpu/drm/i915/soc/intel_rom.h b/drivers/gpu/drm/i915/soc/intel_rom.h new file mode 100644 index 000000000000..fb2979c8ef7f --- /dev/null +++ b/drivers/gpu/drm/i915/soc/intel_rom.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef __INTEL_ROM_H__ +#define __INTEL_ROM_H__ + +#include + +struct drm_i915_private; +struct intel_rom; + +struct intel_rom *intel_rom_spi(struct drm_i915_private *i915); +struct intel_rom *intel_rom_pci(struct drm_i915_private *i915); + +u32 intel_rom_read32(struct intel_rom *rom, loff_t offset); +u16 intel_rom_read16(struct intel_rom *rom, loff_t offset); +void intel_rom_read_block(struct intel_rom *rom, void *data, + loff_t offset, size_t size); +loff_t intel_rom_find(struct intel_rom *rom, u32 needle); +size_t intel_rom_size(struct intel_rom *rom); +void intel_rom_free(struct intel_rom *rom); + +#endif /* __INTEL_ROM_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index d1ead7807146..d432e761f957 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -180,7 +180,8 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ # SOC code shared with i915 xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-soc/intel_dram.o \ - i915-soc/intel_pch.o + i915-soc/intel_pch.o \ + i915-soc/intel_rom.o # Display code shared with i915 xe-$(CONFIG_DRM_XE_DISPLAY) += \ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h b/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h new file mode 100644 index 000000000000..05cbfb697b2b --- /dev/null +++ b/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_rom.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#include "../../../i915/soc/intel_rom.h" From 8f6b856ebe7f1f35c10fb6ccddd4f7a7d66e317a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 27 Sep 2024 17:35:42 +0300 Subject: [PATCH 165/205] drm/i915: Introduce i915_has_legacy_blc_interrupt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i915_has_asle() is a bit of a mess. It does some kind of partial check whether the platform has the legacy BLC interrupt or not, and then it checks whether OpRegion ASLE is present. Let's split the legacy BLC interrupt check into its own thing, and while at it let's make it accurate. Currently it misses i85x (not a problem since gen2 never has OpRegion, nor do we currently call i915_enable_asle_pipestat() on gen2), and it doesn't reject ILK-M (not that anyone should call this on ILK). The exlusion of VLV/CHV (where one might even consider calling this, being gmch platforms) only happens due to .is_mobile==false. List the platforms that actually do have the legacy BLC interrupt in a bit more explicit fashion. i915gm/i945gm/i965gm/gm45 we can cover with a display_ver+is_mobile check, pnv needs an exception due to having a variant with is_mobile==false, and i85x is the only relevant gen2 platform so easier to handle on its own. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240927143545.8665-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 6878dde85031..ba82830c464e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -272,14 +272,17 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv, intel_uncore_posting_read(&dev_priv->uncore, reg); } -static bool i915_has_asle(struct drm_i915_private *i915) +static bool i915_has_legacy_blc_interrupt(struct intel_display *display) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); - if (!IS_PINEVIEW(i915) && !IS_MOBILE(i915)) - return false; + if (IS_I85X(i915)) + return true; - return intel_opregion_asle_present(display); + if (IS_PINEVIEW(i915)) + return true; + + return IS_DISPLAY_VER(display, 3, 4) && IS_MOBILE(i915); } /** @@ -288,7 +291,12 @@ static bool i915_has_asle(struct drm_i915_private *i915) */ void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv) { - if (!i915_has_asle(dev_priv)) + struct intel_display *display = &dev_priv->display; + + if (!intel_opregion_asle_present(display)) + return; + + if (!i915_has_legacy_blc_interrupt(display)) return; spin_lock_irq(&dev_priv->irq_lock); From 3bda3b66be2519a8af6f26d9e69335070212d2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 27 Sep 2024 17:35:43 +0300 Subject: [PATCH 166/205] drm/i915: Clean up gen3 hotplug irq setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the "always on/unmasked" interrupts we initialize dev_priv->irq_mask first, then enable_mask. Follow the same order for the hotplug interrupt so that things are a bit less confusing. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240927143545.8665-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a784803f709a..ee7a2a49f08e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1065,10 +1065,10 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) I915_USER_INTERRUPT; if (I915_HAS_HOTPLUG(dev_priv)) { - /* Enable in IER... */ - enable_mask |= I915_DISPLAY_PORT_INTERRUPT; /* and unmask in IMR */ dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; + /* Enable in IER... */ + enable_mask |= I915_DISPLAY_PORT_INTERRUPT; } GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask); From 17b018c28c08c1c3591d9b2ecb57a72aee452e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 27 Sep 2024 17:35:44 +0300 Subject: [PATCH 167/205] drm/i915: Clean up some comments in gmch irq code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up some comments in the gmch irq code: - drop redundant comments - s/iir/IIR/ to make it clear it's referring to the register Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240927143545.8665-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_irq.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ee7a2a49f08e..fb8dbcfd8e87 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -298,7 +298,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be - * signalled in iir */ + * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | @@ -380,7 +380,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be - * signalled in iir */ + * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | @@ -883,7 +883,6 @@ static void i8xx_irq_postinstall(struct drm_i915_private *dev_priv) intel_uncore_write16(uncore, EMR, i9xx_error_mask(dev_priv)); - /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | @@ -1009,7 +1008,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; /* Call regardless, as some status bits might not be - * signalled in iir */ + * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & I915_MASTER_ERROR_INTERRUPT) @@ -1050,7 +1049,6 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) intel_uncore_write(uncore, EMR, i9xx_error_mask(dev_priv)); - /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | @@ -1065,9 +1063,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) I915_USER_INTERRUPT; if (I915_HAS_HOTPLUG(dev_priv)) { - /* and unmask in IMR */ dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; - /* Enable in IER... */ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; } @@ -1111,7 +1107,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be - * signalled in iir */ + * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & I915_MASTER_ERROR_INTERRUPT) @@ -1174,7 +1170,6 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) intel_uncore_write(uncore, EMR, i965_error_mask(dev_priv)); - /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | I915_DISPLAY_PORT_INTERRUPT | @@ -1233,7 +1228,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be - * signalled in iir */ + * signalled in IIR */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & I915_MASTER_ERROR_INTERRUPT) From 8c827853f60dd133c8804b28e90501b7b3ebc03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 27 Sep 2024 17:35:45 +0300 Subject: [PATCH 168/205] drm/i915: Switch over to gen3 irq code on gen2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only real reason why we have the gen2 vs. gen3+ split in irq handling is that bspec claims that IIR/IMR/IER/ISR and EMR are only 16 bits on gen2, as opposed to being 32 bits on gen3+. That doesn't seem to be a meaningful distinction as 32bit access to these registers works perfectly fine on gen2 Interestingly the 16 msbs of IMR are in fact hardcoded to 1 on gen2, which to me indicates that 32bit access was the plan all along, and perhaps someone just forgot to update the spec. Nuke the special 16bit gen2 irq code and switch over to the gen3 code. Gen2 doesn't have the ASLE interrupt, which just needs a small tweak in i915_irq_postinstall(). And so far we've not had a codepath that could enable the legacy BLC interrupt on gen2. Now we do, but we'll never actually do it since gen2 machines don't have OpRegion. (and neither do i915/i945 machines btw). On these older platforms the legacy BLC interrupt is meant to be used in conjunction with the LBPC backlight stuff, but we never actually switch off the legacy/combination mode and thus don't use the interrupt either. This was quickly smoke tested on all gen2 variants. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240927143545.8665-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 18 -- .../gpu/drm/i915/display/intel_display_irq.h | 1 - drivers/gpu/drm/i915/i915_irq.c | 187 +----------------- 3 files changed, 9 insertions(+), 197 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index ba82830c464e..8c548ee56c12 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -493,28 +493,10 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, spin_unlock(&dev_priv->irq_lock); } -void i8xx_pipestat_irq_handler(struct drm_i915_private *dev_priv, - u16 iir, u32 pipe_stats[I915_MAX_PIPES]) -{ - enum pipe pipe; - - for_each_pipe(dev_priv, pipe) { - if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); - - if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); - - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); - } -} - void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { struct intel_display *display = &dev_priv->display; - bool blc_event = false; enum pipe pipe; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 093e356a2894..bf9d269d0e3f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -75,7 +75,6 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *i915, u32 iir, u32 pipe_stat void i915_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]); -void i8xx_pipestat_irq_handler(struct drm_i915_private *i915, u16 iir, u32 pipe_stats[I915_MAX_PIPES]); void intel_display_irq_init(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fb8dbcfd8e87..ef1a60fc26fa 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -92,20 +92,6 @@ void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr, intel_uncore_posting_read(uncore, iir); } -static void gen2_irq_reset(struct intel_uncore *uncore) -{ - intel_uncore_write16(uncore, GEN2_IMR, 0xffff); - intel_uncore_posting_read16(uncore, GEN2_IMR); - - intel_uncore_write16(uncore, GEN2_IER, 0); - - /* IIR can theoretically queue up two events. Be paranoid. */ - intel_uncore_write16(uncore, GEN2_IIR, 0xffff); - intel_uncore_posting_read16(uncore, GEN2_IIR); - intel_uncore_write16(uncore, GEN2_IIR, 0xffff); - intel_uncore_posting_read16(uncore, GEN2_IIR); -} - /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. */ @@ -125,22 +111,6 @@ void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg) intel_uncore_posting_read(uncore, reg); } -static void gen2_assert_iir_is_zero(struct intel_uncore *uncore) -{ - u16 val = intel_uncore_read16(uncore, GEN2_IIR); - - if (val == 0) - return; - - drm_WARN(&uncore->i915->drm, 1, - "Interrupt register 0x%x is not zero: 0x%08x\n", - i915_mmio_reg_offset(GEN2_IIR), val); - intel_uncore_write16(uncore, GEN2_IIR, 0xffff); - intel_uncore_posting_read16(uncore, GEN2_IIR); - intel_uncore_write16(uncore, GEN2_IIR, 0xffff); - intel_uncore_posting_read16(uncore, GEN2_IIR); -} - void gen3_irq_init(struct intel_uncore *uncore, i915_reg_t imr, u32 imr_val, i915_reg_t ier, u32 ier_val, @@ -153,16 +123,6 @@ void gen3_irq_init(struct intel_uncore *uncore, intel_uncore_posting_read(uncore, imr); } -static void gen2_irq_init(struct intel_uncore *uncore, - u32 imr_val, u32 ier_val) -{ - gen2_assert_iir_is_zero(uncore); - - intel_uncore_write16(uncore, GEN2_IER, ier_val); - intel_uncore_write16(uncore, GEN2_IMR, imr_val); - intel_uncore_posting_read16(uncore, GEN2_IMR); -} - /** * ivb_parity_work - Workqueue called when a parity error interrupt * occurred. @@ -845,16 +805,6 @@ static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv) intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ); } -static void i8xx_irq_reset(struct drm_i915_private *dev_priv) -{ - struct intel_uncore *uncore = &dev_priv->uncore; - - i9xx_display_irq_reset(dev_priv); - - gen2_irq_reset(uncore); - dev_priv->irq_mask = ~0u; -} - static u32 i9xx_error_mask(struct drm_i915_private *i915) { /* @@ -876,75 +826,6 @@ static u32 i9xx_error_mask(struct drm_i915_private *i915) I915_ERROR_MEMORY_REFRESH); } -static void i8xx_irq_postinstall(struct drm_i915_private *dev_priv) -{ - struct intel_uncore *uncore = &dev_priv->uncore; - u16 enable_mask; - - intel_uncore_write16(uncore, EMR, i9xx_error_mask(dev_priv)); - - dev_priv->irq_mask = - ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_MASTER_ERROR_INTERRUPT); - - enable_mask = - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_MASTER_ERROR_INTERRUPT | - I915_USER_INTERRUPT; - - gen2_irq_init(uncore, dev_priv->irq_mask, enable_mask); - - /* Interrupt setup is already guaranteed to be single-threaded, this is - * just to make the assert_spin_locked check happy. */ - spin_lock_irq(&dev_priv->irq_lock); - i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); - i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); - spin_unlock_irq(&dev_priv->irq_lock); -} - -static void i8xx_error_irq_ack(struct drm_i915_private *i915, - u16 *eir, u16 *eir_stuck) -{ - struct intel_uncore *uncore = &i915->uncore; - u16 emr; - - *eir = intel_uncore_read16(uncore, EIR); - intel_uncore_write16(uncore, EIR, *eir); - - *eir_stuck = intel_uncore_read16(uncore, EIR); - if (*eir_stuck == 0) - return; - - /* - * Toggle all EMR bits to make sure we get an edge - * in the ISR master error bit if we don't clear - * all the EIR bits. Otherwise the edge triggered - * IIR on i965/g4x wouldn't notice that an interrupt - * is still pending. Also some EIR bits can't be - * cleared except by handling the underlying error - * (or by a GPU reset) so we mask any bit that - * remains set. - */ - emr = intel_uncore_read16(uncore, EMR); - intel_uncore_write16(uncore, EMR, 0xffff); - intel_uncore_write16(uncore, EMR, emr | *eir_stuck); -} - -static void i8xx_error_irq_handler(struct drm_i915_private *dev_priv, - u16 eir, u16 eir_stuck) -{ - drm_dbg(&dev_priv->drm, "Master Error: EIR 0x%04x\n", eir); - - if (eir_stuck) - drm_dbg(&dev_priv->drm, "EIR stuck: 0x%04x, masked\n", - eir_stuck); - - drm_dbg(&dev_priv->drm, "PGTBL_ER: 0x%08x\n", - intel_uncore_read(&dev_priv->uncore, PGTBL_ER)); -} - static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv, u32 *eir, u32 *eir_stuck) { @@ -985,53 +866,6 @@ static void i9xx_error_irq_handler(struct drm_i915_private *dev_priv, intel_uncore_read(&dev_priv->uncore, PGTBL_ER)); } -static irqreturn_t i8xx_irq_handler(int irq, void *arg) -{ - struct drm_i915_private *dev_priv = arg; - irqreturn_t ret = IRQ_NONE; - - if (!intel_irqs_enabled(dev_priv)) - return IRQ_NONE; - - /* IRQs are synced during runtime_suspend, we don't require a wakeref */ - disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); - - do { - u32 pipe_stats[I915_MAX_PIPES] = {}; - u16 eir = 0, eir_stuck = 0; - u16 iir; - - iir = intel_uncore_read16(&dev_priv->uncore, GEN2_IIR); - if (iir == 0) - break; - - ret = IRQ_HANDLED; - - /* Call regardless, as some status bits might not be - * signalled in IIR */ - i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); - - if (iir & I915_MASTER_ERROR_INTERRUPT) - i8xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - - intel_uncore_write16(&dev_priv->uncore, GEN2_IIR, iir); - - if (iir & I915_USER_INTERRUPT) - intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], iir); - - if (iir & I915_MASTER_ERROR_INTERRUPT) - i8xx_error_irq_handler(dev_priv, eir, eir_stuck); - - i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats); - } while (0); - - pmu_irq_stats(dev_priv, ret); - - enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); - - return ret; -} - static void i915_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; @@ -1050,18 +884,21 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) intel_uncore_write(uncore, EMR, i9xx_error_mask(dev_priv)); dev_priv->irq_mask = - ~(I915_ASLE_INTERRUPT | - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | + ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_MASTER_ERROR_INTERRUPT); enable_mask = - I915_ASLE_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_MASTER_ERROR_INTERRUPT | I915_USER_INTERRUPT; + if (DISPLAY_VER(dev_priv) >= 3) { + dev_priv->irq_mask &= ~I915_ASLE_INTERRUPT; + enable_mask |= I915_ASLE_INTERRUPT; + } + if (I915_HAS_HOTPLUG(dev_priv)) { dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; enable_mask |= I915_DISPLAY_PORT_INTERRUPT; @@ -1303,10 +1140,8 @@ static irq_handler_t intel_irq_handler(struct drm_i915_private *dev_priv) return valleyview_irq_handler; else if (GRAPHICS_VER(dev_priv) == 4) return i965_irq_handler; - else if (GRAPHICS_VER(dev_priv) == 3) - return i915_irq_handler; else - return i8xx_irq_handler; + return i915_irq_handler; } else { if (GRAPHICS_VER_FULL(dev_priv) >= IP_VER(12, 10)) return dg1_irq_handler; @@ -1328,10 +1163,8 @@ static void intel_irq_reset(struct drm_i915_private *dev_priv) valleyview_irq_reset(dev_priv); else if (GRAPHICS_VER(dev_priv) == 4) i965_irq_reset(dev_priv); - else if (GRAPHICS_VER(dev_priv) == 3) - i915_irq_reset(dev_priv); else - i8xx_irq_reset(dev_priv); + i915_irq_reset(dev_priv); } else { if (GRAPHICS_VER_FULL(dev_priv) >= IP_VER(12, 10)) dg1_irq_reset(dev_priv); @@ -1353,10 +1186,8 @@ static void intel_irq_postinstall(struct drm_i915_private *dev_priv) valleyview_irq_postinstall(dev_priv); else if (GRAPHICS_VER(dev_priv) == 4) i965_irq_postinstall(dev_priv); - else if (GRAPHICS_VER(dev_priv) == 3) - i915_irq_postinstall(dev_priv); else - i8xx_irq_postinstall(dev_priv); + i915_irq_postinstall(dev_priv); } else { if (GRAPHICS_VER_FULL(dev_priv) >= IP_VER(12, 10)) dg1_irq_postinstall(dev_priv); From 06f4d328438171f841f23dd34a14cbd545094485 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Sep 2024 15:40:55 +0300 Subject: [PATCH 169/205] drm/i915: remove IS_LP() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .is_lp member of struct intel_device_info and its wrapper IS_LP() are used to identify just four platforms, VLV/CHV/BXT/GLK. It didn't become as important as it was perhaps originally planned. Just remove it, and replace with exact platform identification. In a few places this becomes slightly verbose, but in many places it improves clarity to immediately see the exact platforms. Additionally, this lets us remove the xe compat macro. Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930124056.3541988-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_device.h | 2 +- drivers/gpu/drm/i915/display/intel_dpll.c | 7 +++++-- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 5 ++--- drivers/gpu/drm/i915/i915_pci.c | 3 --- drivers/gpu/drm/i915/intel_device_info.h | 1 - drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h | 1 - 7 files changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 220cca6333ee..3ef537fa551a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -150,7 +150,7 @@ enum intel_display_subplatform { #define HAS_PSR(i915) (DISPLAY_INFO(i915)->has_psr) #define HAS_PSR_HW_TRACKING(i915) (DISPLAY_INFO(i915)->has_psr_hw_tracking) #define HAS_PSR2_SEL_FETCH(i915) (DISPLAY_VER(i915) >= 12) -#define HAS_SAGV(i915) (DISPLAY_VER(i915) >= 9 && !IS_LP(i915)) +#define HAS_SAGV(i915) (DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915) && !IS_GEMINILAKE(i915)) #define HAS_TRANSCODER(i915, trans) ((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \ BIT(trans)) != 0) #define HAS_UNCOMPRESSED_JOINER(i915) (DISPLAY_VER(i915) >= 13) diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 38e34b72bc4e..b679c5391fe6 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -589,11 +589,14 @@ static bool intel_pll_is_valid(struct drm_i915_private *dev_priv, if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) return false; - if (!IS_PINEVIEW(dev_priv) && !IS_LP(dev_priv)) + if (!IS_PINEVIEW(dev_priv) && + !IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && + !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) if (clock->m1 <= clock->m2) return false; - if (!IS_LP(dev_priv)) { + if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && + !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) { if (clock->p < limit->p.min || limit->p.max < clock->p) return false; if (clock->m < limit->m.min || limit->m.max < clock->m) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index d29005980806..9d958a6f377e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -457,7 +457,7 @@ static int init_reserved_stolen(struct drm_i915_private *i915) icl_get_stolen_reserved(i915, uncore, &reserved_base, &reserved_size); } else if (GRAPHICS_VER(i915) >= 8) { - if (IS_LP(i915)) + if (IS_CHERRYVIEW(i915) || IS_BROXTON(i915) || IS_GEMINILAKE(i915)) chv_get_stolen_reserved(i915, uncore, &reserved_base, &reserved_size); else diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index def3ca135406..3c4b106cc7a0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -612,9 +612,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define IS_TIGERLAKE_UY(i915) \ IS_SUBPLATFORM(i915, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY) -#define IS_LP(i915) (INTEL_INFO(i915)->is_lp) -#define IS_GEN9_LP(i915) (GRAPHICS_VER(i915) == 9 && IS_LP(i915)) -#define IS_GEN9_BC(i915) (GRAPHICS_VER(i915) == 9 && !IS_LP(i915)) +#define IS_GEN9_LP(i915) (IS_BROXTON(i915) || IS_GEMINILAKE(i915)) +#define IS_GEN9_BC(i915) (GRAPHICS_VER(i915) == 9 && !IS_GEN9_LP(i915)) #define __HAS_ENGINE(engine_mask, id) ((engine_mask) & BIT(id)) #define HAS_ENGINE(gt, id) __HAS_ENGINE((gt)->info.engine_mask, id) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 617f411feb8c..eaf8a098e1c5 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -367,7 +367,6 @@ static const struct intel_device_info ivb_q_info = { static const struct intel_device_info vlv_info = { PLATFORM(INTEL_VALLEYVIEW), GEN(7), - .is_lp = 1, .has_runtime_pm = 1, .has_rc6 = 1, .has_reset_engine = true, @@ -451,7 +450,6 @@ static const struct intel_device_info bdw_gt3_info = { static const struct intel_device_info chv_info = { PLATFORM(INTEL_CHERRYVIEW), GEN(8), - .is_lp = 1, .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), .has_64bit_reloc = 1, .has_runtime_pm = 1, @@ -512,7 +510,6 @@ static const struct intel_device_info skl_gt4_info = { #define GEN9_LP_FEATURES \ GEN(9), \ - .is_lp = 1, \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \ .has_3d_pipeline = 1, \ .has_64bit_reloc = 1, \ diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 643ff1bf74ee..4f4aa4ff9963 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -138,7 +138,6 @@ enum intel_ppgtt_type { #define DEV_INFO_FOR_EACH_FLAG(func) \ func(is_mobile); \ - func(is_lp); \ func(require_force_probe); \ func(is_dgfx); \ /* Keep has_* in alphabetical order */ \ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h index 00d492f907d8..900003d855a6 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -76,7 +76,6 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev) #define IS_MOBILE(xe) (xe && 0) -#define IS_LP(xe) ((xe) && 0) #define IS_GEN9_LP(xe) ((xe) && 0) #define IS_GEN9_BC(xe) ((xe) && 0) From 0ca97fcdba9a42f4afd66a43129fb1d6dca0a26a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Sep 2024 15:40:56 +0300 Subject: [PATCH 170/205] drm/i915/soc: stop using IS_GEN9_LP() and IS_GEN9_BC() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace IS_GEN9_LP() and IS_GEN9_BC() with direct platform checks. This lets us remove their compat counterparts, as neither soc/ nor /display now no longer needs them. v2: Use !A && !B instead of !(A || B) (Ville) Reviewed-by: Ville Syrjälä # v1 Link: https://patchwork.freedesktop.org/patch/msgid/20240930124056.3541988-2-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/soc/intel_dram.c | 4 ++-- drivers/gpu/drm/i915/soc/intel_pch.c | 5 ++++- drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h | 3 --- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index 4aba47bccc63..9e310f4099f4 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -714,7 +714,7 @@ void intel_dram_detect(struct drm_i915_private *i915) * Assume level 0 watermark latency adjustment is needed until proven * otherwise, this w/a is not needed by bxt/glk. */ - dram_info->wm_lv_0_adjust_needed = !IS_GEN9_LP(i915); + dram_info->wm_lv_0_adjust_needed = !IS_BROXTON(i915) && !IS_GEMINILAKE(i915); if (DISPLAY_VER(i915) >= 14) ret = xelpdp_get_dram_info(i915); @@ -722,7 +722,7 @@ void intel_dram_detect(struct drm_i915_private *i915) ret = gen12_get_dram_info(i915); else if (GRAPHICS_VER(i915) >= 11) ret = gen11_get_dram_info(i915); - else if (IS_GEN9_LP(i915)) + else if (IS_BROXTON(i915) || IS_GEMINILAKE(i915)) ret = bxt_get_dram_info(i915); else ret = skl_get_dram_info(i915); diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c index 542eea50093c..842db43e46c0 100644 --- a/drivers/gpu/drm/i915/soc/intel_pch.c +++ b/drivers/gpu/drm/i915/soc/intel_pch.c @@ -124,7 +124,10 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) drm_dbg_kms(&dev_priv->drm, "Found Tiger Lake LP PCH\n"); drm_WARN_ON(&dev_priv->drm, !IS_TIGERLAKE(dev_priv) && !IS_ROCKETLAKE(dev_priv) && - !IS_GEN9_BC(dev_priv)); + !IS_SKYLAKE(dev_priv) && + !IS_KABYLAKE(dev_priv) && + !IS_COFFEELAKE(dev_priv) && + !IS_COMETLAKE(dev_priv)); return PCH_TGP; case INTEL_PCH_JSP_DEVICE_ID_TYPE: drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n"); diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h index 900003d855a6..b7041b578e5e 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -76,9 +76,6 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev) #define IS_MOBILE(xe) (xe && 0) -#define IS_GEN9_LP(xe) ((xe) && 0) -#define IS_GEN9_BC(xe) ((xe) && 0) - #define IS_TIGERLAKE_UY(xe) (xe && 0) #define IS_COMETLAKE_ULX(xe) (xe && 0) #define IS_COFFEELAKE_ULX(xe) (xe && 0) From 09b003ad1dd6a4bf1b364e8f03cba87b2de38d21 Mon Sep 17 00:00:00 2001 From: He Lugang Date: Wed, 25 Sep 2024 14:40:16 +0800 Subject: [PATCH 171/205] drm/i915:Remove unused parameter in marco The parameter dev_priv is actually not used in macro PORT_ALPM_CTL and PORT_ALPM_LFPS_CTL,so remove it to simplify the code. Reviewed-by: Jani Nikula Signed-off-by: He Lugang Link: https://patchwork.freedesktop.org/patch/msgid/6C2E07E089F0CB73+20240925064016.733173-1-helugang@uniontech.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_alpm.c | 4 ++-- drivers/gpu/drm/i915/display/intel_psr.c | 2 +- drivers/gpu/drm/i915/display/intel_psr_regs.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index 31c068f393b7..55f3ae1e68c9 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.c +++ b/drivers/gpu/drm/i915/display/intel_alpm.c @@ -332,7 +332,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp, ALPM_CTL_AUX_LESS_WAKE_TIME(intel_dp->alpm_parameters.aux_less_wake_lines); intel_de_write(display, - PORT_ALPM_CTL(display, port), + PORT_ALPM_CTL(port), PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE | PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) | PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) | @@ -340,7 +340,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp, intel_dp->alpm_parameters.silence_period_sym_clocks)); intel_de_write(display, - PORT_ALPM_LFPS_CTL(display, port), + PORT_ALPM_LFPS_CTL(port), PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) | PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION( intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) | diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index e3357f3b5c70..8e9f068b9b2b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2123,7 +2123,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); intel_de_rmw(display, - PORT_ALPM_CTL(display, cpu_transcoder), + PORT_ALPM_CTL(cpu_transcoder), PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); } diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h index 945fdc750a03..0841242543ca 100644 --- a/drivers/gpu/drm/i915/display/intel_psr_regs.h +++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h @@ -296,7 +296,7 @@ #define _PORT_ALPM_CTL_A 0x16fa2c #define _PORT_ALPM_CTL_B 0x16fc2c -#define PORT_ALPM_CTL(dev_priv, port) _MMIO_PORT(port, _PORT_ALPM_CTL_A, _PORT_ALPM_CTL_B) +#define PORT_ALPM_CTL(port) _MMIO_PORT(port, _PORT_ALPM_CTL_A, _PORT_ALPM_CTL_B) #define PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(31) #define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK REG_GENMASK(23, 20) #define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK, val) @@ -307,7 +307,7 @@ #define _PORT_ALPM_LFPS_CTL_A 0x16fa30 #define _PORT_ALPM_LFPS_CTL_B 0x16fc30 -#define PORT_ALPM_LFPS_CTL(dev_priv, port) _MMIO_PORT(port, _PORT_ALPM_LFPS_CTL_A, _PORT_ALPM_LFPS_CTL_B) +#define PORT_ALPM_LFPS_CTL(port) _MMIO_PORT(port, _PORT_ALPM_LFPS_CTL_A, _PORT_ALPM_LFPS_CTL_B) #define PORT_ALPM_LFPS_CTL_LFPS_START_POLARITY REG_BIT(31) #define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MASK REG_GENMASK(27, 24) #define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MIN 7 From abc0742c79bdb3b164eacab24aea0916d2ec1cb5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 24 Sep 2024 18:30:22 +0300 Subject: [PATCH 172/205] drm/i915/hdcp: fix connector refcounting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We acquire a connector reference before scheduling an HDCP prop work, and expect the work function to release the reference. However, if the work was already queued, it won't be queued multiple times, and the reference is not dropped. Release the reference immediately if the work was already queued. Fixes: a6597faa2d59 ("drm/i915: Protect workers against disappearing connectors") Cc: Sean Paul Cc: Suraj Kandpal Cc: Ville Syrjälä Cc: stable@vger.kernel.org # v5.10+ Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240924153022.2255299-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_hdcp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 00d4c9ac6c45..ed6aa87403e2 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -1097,7 +1097,8 @@ static void intel_hdcp_update_value(struct intel_connector *connector, hdcp->value = value; if (update_property) { drm_connector_get(&connector->base); - queue_work(i915->unordered_wq, &hdcp->prop_work); + if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) + drm_connector_put(&connector->base); } } @@ -2554,7 +2555,8 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, mutex_lock(&hdcp->mutex); hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; drm_connector_get(&connector->base); - queue_work(i915->unordered_wq, &hdcp->prop_work); + if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) + drm_connector_put(&connector->base); mutex_unlock(&hdcp->mutex); } @@ -2571,7 +2573,9 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state, */ if (!desired_and_not_enabled && !content_protection_type_changed) { drm_connector_get(&connector->base); - queue_work(i915->unordered_wq, &hdcp->prop_work); + if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) + drm_connector_put(&connector->base); + } } From 9075efdd96c79a0ed873a5f1bb92158c2578f4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 1 Oct 2024 22:58:00 +0300 Subject: [PATCH 173/205] drm/i915/irq: Nuke stale comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the tall tales about getting passed pipe indices into the .vblank_{enable,disable}() hooks. This hasn't been true since commit 08fa8fd0faa5 ("drm/i915: Switch to per-crtc vblank vfuncs"). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241001195803.3371-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_irq.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 8c548ee56c12..0ea1fcc61dde 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1259,9 +1259,6 @@ void gen11_display_irq_handler(struct drm_i915_private *i915) enable_rpm_wakeref_asserts(&i915->runtime_pm); } -/* Called from drm generic code, passed 'crtc' which - * we use as a pipe index - */ int i8xx_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); @@ -1394,9 +1391,6 @@ int bdw_enable_vblank(struct drm_crtc *_crtc) return 0; } -/* Called from drm generic code, passed 'crtc' which - * we use as a pipe index - */ void i8xx_disable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); From 8923422ba48f548f046d8d3c9f0244086c794214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 1 Oct 2024 22:58:01 +0300 Subject: [PATCH 174/205] drm/i915/irq: Pair up the vblank enable/disable functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current way of organizing all .vblank_enable() functions before all .vblabk_disable() functions is infuriating. It's really hard to compare the enable() vs. disable() for the same platform to make sure they properly mirror each other. Reorganize the functions so that the enable+disable for the same platoform are next to each. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241001195803.3371-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 0ea1fcc61dde..43a0b3565bc8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1272,6 +1272,17 @@ int i8xx_enable_vblank(struct drm_crtc *crtc) return 0; } +void i8xx_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + enum pipe pipe = to_intel_crtc(crtc)->pipe; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +} + int i915gm_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *i915 = to_i915(crtc->dev); @@ -1288,6 +1299,16 @@ int i915gm_enable_vblank(struct drm_crtc *crtc) return i8xx_enable_vblank(crtc); } +void i915gm_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_i915_private *i915 = to_i915(crtc->dev); + + i8xx_disable_vblank(crtc); + + if (--i915->display.irq.vblank_enabled == 0) + intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); +} + int i965_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); @@ -1302,6 +1323,18 @@ int i965_enable_vblank(struct drm_crtc *crtc) return 0; } +void i965_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + enum pipe pipe = to_intel_crtc(crtc)->pipe; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_disable_pipestat(dev_priv, pipe, + PIPE_START_VBLANK_INTERRUPT_STATUS); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +} + int ilk_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); @@ -1323,6 +1356,19 @@ int ilk_enable_vblank(struct drm_crtc *crtc) return 0; } +void ilk_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + enum pipe pipe = to_intel_crtc(crtc)->pipe; + unsigned long irqflags; + u32 bit = DISPLAY_VER(dev_priv) >= 7 ? + DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + ilk_disable_display_irq(dev_priv, bit); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +} + static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, bool enable) { @@ -1391,52 +1437,6 @@ int bdw_enable_vblank(struct drm_crtc *_crtc) return 0; } -void i8xx_disable_vblank(struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - enum pipe pipe = to_intel_crtc(crtc)->pipe; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -void i915gm_disable_vblank(struct drm_crtc *crtc) -{ - struct drm_i915_private *i915 = to_i915(crtc->dev); - - i8xx_disable_vblank(crtc); - - if (--i915->display.irq.vblank_enabled == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); -} - -void i965_disable_vblank(struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - enum pipe pipe = to_intel_crtc(crtc)->pipe; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, pipe, - PIPE_START_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -void ilk_disable_vblank(struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - enum pipe pipe = to_intel_crtc(crtc)->pipe; - unsigned long irqflags; - u32 bit = DISPLAY_VER(dev_priv) >= 7 ? - DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ilk_disable_display_irq(dev_priv, bit); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - void bdw_disable_vblank(struct drm_crtc *_crtc) { struct intel_crtc *crtc = to_intel_crtc(_crtc); From f45cc1d373aeeabaaed0cef6c938bfcbbbd9962f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 1 Oct 2024 22:58:02 +0300 Subject: [PATCH 175/205] drm/i915: Extract i915gm_irq_cstate_wa_{disable,enable}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the i915gm/i945gm vblank irq C-state workaround to separate functions. We'll need to reuse these in order to guarantee timely CRC interrupt delivery as well. The irq.vblank_enabled count is currently protected by the drm vblank locks, so let's assert that the innermost of those is held, in anticipation of other callers. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241001195803.3371-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 43a0b3565bc8..feeb3a29972a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1259,6 +1259,28 @@ void gen11_display_irq_handler(struct drm_i915_private *i915) enable_rpm_wakeref_asserts(&i915->runtime_pm); } +static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) +{ + lockdep_assert_held(&i915->drm.vblank_time_lock); + + /* + * Vblank interrupts fail to wake the device up from C2+. + * Disabling render clock gating during C-states avoids + * the problem. There is a small power cost so we do this + * only when vblank interrupts are actually enabled. + */ + if (i915->display.irq.vblank_enabled++ == 0) + intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); +} + +static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915) +{ + lockdep_assert_held(&i915->drm.vblank_time_lock); + + if (--i915->display.irq.vblank_enabled == 0) + intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); +} + int i8xx_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); @@ -1287,14 +1309,7 @@ int i915gm_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *i915 = to_i915(crtc->dev); - /* - * Vblank interrupts fail to wake the device up from C2+. - * Disabling render clock gating during C-states avoids - * the problem. There is a small power cost so we do this - * only when vblank interrupts are actually enabled. - */ - if (i915->display.irq.vblank_enabled++ == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + i915gm_irq_cstate_wa_enable(i915); return i8xx_enable_vblank(crtc); } @@ -1305,8 +1320,7 @@ void i915gm_disable_vblank(struct drm_crtc *crtc) i8xx_disable_vblank(crtc); - if (--i915->display.irq.vblank_enabled == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + i915gm_irq_cstate_wa_disable(i915); } int i965_enable_vblank(struct drm_crtc *crtc) From e2f5812ebf6af7e67ac50f0abb11249f6171b8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 1 Oct 2024 22:58:03 +0300 Subject: [PATCH 176/205] drm/i915: Apply the i915gm/i945gm irq C-state w/a to CRC interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out CRC interrupts also fail to wake up i915gm/i945gm from C2+. I suppose this is a generic problem, but for most other interrupts the system will be busy enough already prior to the irq being issued. But CRC interrupts are like vblank interrupts and only fire once per frame, so plenty of time to fall asleep in between them. Apply the same core clock gating trick to CRC interrupts that we use for vblank interrupts. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241001195803.3371-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_irq.c | 16 ++++++++++++++-- drivers/gpu/drm/i915/display/intel_display_irq.h | 2 ++ drivers/gpu/drm/i915/display/intel_pipe_crc.c | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index feeb3a29972a..a09909c3c6cd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1264,10 +1264,10 @@ static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) lockdep_assert_held(&i915->drm.vblank_time_lock); /* - * Vblank interrupts fail to wake the device up from C2+. + * Vblank/CRC interrupts fail to wake the device up from C2+. * Disabling render clock gating during C-states avoids * the problem. There is a small power cost so we do this - * only when vblank interrupts are actually enabled. + * only when vblank/CRC interrupts are actually enabled. */ if (i915->display.irq.vblank_enabled++ == 0) intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); @@ -1281,6 +1281,18 @@ static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915) intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } +void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable) +{ + spin_lock_irq(&i915->drm.vblank_time_lock); + + if (enable) + i915gm_irq_cstate_wa_enable(i915); + else + i915gm_irq_cstate_wa_disable(i915); + + spin_unlock_irq(&i915->drm.vblank_time_lock); +} + int i8xx_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index bf9d269d0e3f..4b493cff7b8e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -78,4 +78,6 @@ void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_sta void intel_display_irq_init(struct drm_i915_private *i915); +void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable); + #endif /* __INTEL_DISPLAY_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c index 82ceede0b2b1..304da826dee1 100644 --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c @@ -32,6 +32,7 @@ #include "i915_reg.h" #include "intel_atomic.h" #include "intel_de.h" +#include "intel_display_irq.h" #include "intel_display_types.h" #include "intel_pipe_crc.h" #include "intel_pipe_crc_regs.h" @@ -285,6 +286,9 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable) struct drm_modeset_acquire_ctx ctx; int ret; + if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv)) + i915gm_irq_cstate_wa(dev_priv, enable); + drm_modeset_acquire_init(&ctx, 0); state = drm_atomic_state_alloc(&dev_priv->drm); From f31b2cfe6234e59ba7efbcf4f57642e9e0d3866c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 22:04:40 +0300 Subject: [PATCH 177/205] drm/i915/dp: Make intel_dp_get_colorimetry_status() static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp_get_colorimetry_status() is not used outside of intel_dp.c. Make it static. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918190441.29071-2-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c4fdae5097ec..d22649e0f8e1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3934,7 +3934,7 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, str_enable_disable(tmp)); } -bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp) +static bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp) { u8 dprx = 0; diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 53d1217800ef..60baf4072dc9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -114,7 +114,6 @@ void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, bool intel_dp_source_supports_tps3(struct drm_i915_private *i915); bool intel_dp_source_supports_tps4(struct drm_i915_private *i915); -bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp); int intel_dp_link_required(int pixel_clock, int bpp); int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16, int bw_overhead); From cade191506a89de39bf515482aa54cd907db4d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 22:04:41 +0300 Subject: [PATCH 178/205] drm/i915/dp: Extract intel_edp_set_sink_rates() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declutter intel_edp_init_dpcd() a bit by extracting the sink rates probing into its own function. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918190441.29071-3-ville.syrjala@linux.intel.com Reviewed-by: Luca Coelho --- drivers/gpu/drm/i915/display/intel_dp.c | 76 +++++++++++++------------ 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d22649e0f8e1..fbb096be02ad 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4085,6 +4085,45 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp) intel_dp->mso_pixel_overlap = mso ? info->mso_pixel_overlap : 0; } +static void +intel_edp_set_sink_rates(struct intel_dp *intel_dp) +{ + intel_dp->num_sink_rates = 0; + + if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { + __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; + int i; + + drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES, + sink_rates, sizeof(sink_rates)); + + for (i = 0; i < ARRAY_SIZE(sink_rates); i++) { + int val = le16_to_cpu(sink_rates[i]); + + if (val == 0) + break; + + /* Value read multiplied by 200kHz gives the per-lane + * link rate in kHz. The source rates are, however, + * stored in terms of LS_Clk kHz. The full conversion + * back to symbols is + * (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte) + */ + intel_dp->sink_rates[i] = (val * 200) / 10; + } + intel_dp->num_sink_rates = i; + } + + /* + * Use DP_LINK_RATE_SET if DP_SUPPORTED_LINK_RATES are available, + * default to DP_MAX_LINK_RATE and DP_LINK_BW_SET otherwise. + */ + if (intel_dp->num_sink_rates) + intel_dp->use_rate_select = true; + else + intel_dp_set_sink_rates(intel_dp); +} + static bool intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector) { @@ -4129,42 +4168,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector */ intel_psr_init_dpcd(intel_dp); - /* Clear the default sink rates */ - intel_dp->num_sink_rates = 0; - - /* Read the eDP 1.4+ supported link rates. */ - if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { - __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; - int i; - - drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES, - sink_rates, sizeof(sink_rates)); - - for (i = 0; i < ARRAY_SIZE(sink_rates); i++) { - int val = le16_to_cpu(sink_rates[i]); - - if (val == 0) - break; - - /* Value read multiplied by 200kHz gives the per-lane - * link rate in kHz. The source rates are, however, - * stored in terms of LS_Clk kHz. The full conversion - * back to symbols is - * (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte) - */ - intel_dp->sink_rates[i] = (val * 200) / 10; - } - intel_dp->num_sink_rates = i; - } - - /* - * Use DP_LINK_RATE_SET if DP_SUPPORTED_LINK_RATES are available, - * default to DP_MAX_LINK_RATE and DP_LINK_BW_SET otherwise. - */ - if (intel_dp->num_sink_rates) - intel_dp->use_rate_select = true; - else - intel_dp_set_sink_rates(intel_dp); + intel_edp_set_sink_rates(intel_dp); intel_dp_set_max_sink_lane_count(intel_dp); /* Read the eDP DSC DPCD registers */ From 9b63562694e463741c209837d462b032f1b5d05a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 2 Oct 2024 13:26:43 +0300 Subject: [PATCH 179/205] drm/i915/irq: add struct i915_irq_regs triplet Add struct i915_irq_regs to hold IMR/IER/IIR register offsets to pass to gen3_irq_reset() and gen3_irq_init(). This helps in grouping the registers and further cleanup. Note: gen3_irq_reset() and gen3_irq_init() really did have the IMR/IER/IIR parameters in different order. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20241002102645.136155-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_irq.c | 31 ++++++++++------------- drivers/gpu/drm/i915/i915_irq.h | 30 ++++++++++------------ drivers/gpu/drm/i915/i915_reg_defs.h | 10 ++++++++ drivers/gpu/drm/xe/display/ext/i915_irq.c | 31 ++++++++++------------- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ef1a60fc26fa..db3b4f7f1759 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -77,19 +77,18 @@ static inline void pmu_irq_stats(struct drm_i915_private *i915, WRITE_ONCE(i915->pmu.irq_count, i915->pmu.irq_count + 1); } -void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr, - i915_reg_t iir, i915_reg_t ier) +void gen3_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs) { - intel_uncore_write(uncore, imr, 0xffffffff); - intel_uncore_posting_read(uncore, imr); + intel_uncore_write(uncore, regs.imr, 0xffffffff); + intel_uncore_posting_read(uncore, regs.imr); - intel_uncore_write(uncore, ier, 0); + intel_uncore_write(uncore, regs.ier, 0); /* IIR can theoretically queue up two events. Be paranoid. */ - intel_uncore_write(uncore, iir, 0xffffffff); - intel_uncore_posting_read(uncore, iir); - intel_uncore_write(uncore, iir, 0xffffffff); - intel_uncore_posting_read(uncore, iir); + intel_uncore_write(uncore, regs.iir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.iir); + intel_uncore_write(uncore, regs.iir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.iir); } /* @@ -111,16 +110,14 @@ void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg) intel_uncore_posting_read(uncore, reg); } -void gen3_irq_init(struct intel_uncore *uncore, - i915_reg_t imr, u32 imr_val, - i915_reg_t ier, u32 ier_val, - i915_reg_t iir) +void gen3_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, + u32 imr_val, u32 ier_val) { - gen3_assert_iir_is_zero(uncore, iir); + gen3_assert_iir_is_zero(uncore, regs.iir); - intel_uncore_write(uncore, ier, ier_val); - intel_uncore_write(uncore, imr, imr_val); - intel_uncore_posting_read(uncore, imr); + intel_uncore_write(uncore, regs.ier, ier_val); + intel_uncore_write(uncore, regs.imr, imr_val); + intel_uncore_posting_read(uncore, regs.imr); } /** diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h index cde4cac5eca2..361ba46eed76 100644 --- a/drivers/gpu/drm/i915/i915_irq.h +++ b/drivers/gpu/drm/i915/i915_irq.h @@ -42,37 +42,33 @@ void intel_synchronize_hardirq(struct drm_i915_private *i915); void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg); -void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr, - i915_reg_t iir, i915_reg_t ier); +void gen3_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs); -void gen3_irq_init(struct intel_uncore *uncore, - i915_reg_t imr, u32 imr_val, - i915_reg_t ier, u32 ier_val, - i915_reg_t iir); +void gen3_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, + u32 imr_val, u32 ier_val); #define GEN8_IRQ_RESET_NDX(uncore, type, which) \ ({ \ unsigned int which_ = which; \ - gen3_irq_reset((uncore), GEN8_##type##_IMR(which_), \ - GEN8_##type##_IIR(which_), GEN8_##type##_IER(which_)); \ + gen3_irq_reset((uncore), I915_IRQ_REGS(GEN8_##type##_IMR(which_), \ + GEN8_##type##_IER(which_), \ + GEN8_##type##_IIR(which_))); \ }) #define GEN3_IRQ_RESET(uncore, type) \ - gen3_irq_reset((uncore), type##IMR, type##IIR, type##IER) + gen3_irq_reset((uncore), I915_IRQ_REGS(type##IMR, type##IER, type##IIR)) #define GEN8_IRQ_INIT_NDX(uncore, type, which, imr_val, ier_val) \ ({ \ unsigned int which_ = which; \ - gen3_irq_init((uncore), \ - GEN8_##type##_IMR(which_), imr_val, \ - GEN8_##type##_IER(which_), ier_val, \ - GEN8_##type##_IIR(which_)); \ + gen3_irq_init((uncore), I915_IRQ_REGS(GEN8_##type##_IMR(which_), \ + GEN8_##type##_IER(which_), \ + GEN8_##type##_IIR(which_)), \ + imr_val, ier_val); \ }) #define GEN3_IRQ_INIT(uncore, type, imr_val, ier_val) \ - gen3_irq_init((uncore), \ - type##IMR, imr_val, \ - type##IER, ier_val, \ - type##IIR) + gen3_irq_init((uncore), I915_IRQ_REGS(type##IMR, type##IER, type##IIR), \ + imr_val, ier_val) #endif /* __I915_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h index a685db1e815d..e251bcc0c89f 100644 --- a/drivers/gpu/drm/i915/i915_reg_defs.h +++ b/drivers/gpu/drm/i915/i915_reg_defs.h @@ -284,4 +284,14 @@ typedef struct { #define i915_mmio_reg_equal(a, b) (i915_mmio_reg_offset(a) == i915_mmio_reg_offset(b)) #define i915_mmio_reg_valid(r) (!i915_mmio_reg_equal(r, INVALID_MMIO_REG)) +/* A triplet for IMR/IER/IIR registers. */ +struct i915_irq_regs { + i915_reg_t imr; + i915_reg_t ier; + i915_reg_t iir; +}; + +#define I915_IRQ_REGS(_imr, _ier, _iir) \ + ((const struct i915_irq_regs){ .imr = (_imr), .ier = (_ier), .iir = (_iir) }) + #endif /* __I915_REG_DEFS__ */ diff --git a/drivers/gpu/drm/xe/display/ext/i915_irq.c b/drivers/gpu/drm/xe/display/ext/i915_irq.c index eb40f1cb44f6..977ef47ea1f9 100644 --- a/drivers/gpu/drm/xe/display/ext/i915_irq.c +++ b/drivers/gpu/drm/xe/display/ext/i915_irq.c @@ -7,19 +7,18 @@ #include "i915_reg.h" #include "intel_uncore.h" -void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr, - i915_reg_t iir, i915_reg_t ier) +void gen3_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs) { - intel_uncore_write(uncore, imr, 0xffffffff); - intel_uncore_posting_read(uncore, imr); + intel_uncore_write(uncore, regs.imr, 0xffffffff); + intel_uncore_posting_read(uncore, regs.imr); - intel_uncore_write(uncore, ier, 0); + intel_uncore_write(uncore, regs.ier, 0); /* IIR can theoretically queue up two events. Be paranoid. */ - intel_uncore_write(uncore, iir, 0xffffffff); - intel_uncore_posting_read(uncore, iir); - intel_uncore_write(uncore, iir, 0xffffffff); - intel_uncore_posting_read(uncore, iir); + intel_uncore_write(uncore, regs.iir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.iir); + intel_uncore_write(uncore, regs.iir, 0xffffffff); + intel_uncore_posting_read(uncore, regs.iir); } /* @@ -42,16 +41,14 @@ void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg) intel_uncore_posting_read(uncore, reg); } -void gen3_irq_init(struct intel_uncore *uncore, - i915_reg_t imr, u32 imr_val, - i915_reg_t ier, u32 ier_val, - i915_reg_t iir) +void gen3_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, + u32 imr_val, u32 ier_val) { - gen3_assert_iir_is_zero(uncore, iir); + gen3_assert_iir_is_zero(uncore, regs.iir); - intel_uncore_write(uncore, ier, ier_val); - intel_uncore_write(uncore, imr, imr_val); - intel_uncore_posting_read(uncore, imr); + intel_uncore_write(uncore, regs.ier, ier_val); + intel_uncore_write(uncore, regs.imr, imr_val); + intel_uncore_posting_read(uncore, regs.imr); } bool intel_irqs_enabled(struct xe_device *xe) From 7a26b3f1f6facffd24a332f9cdc772cfc7bfa017 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 2 Oct 2024 13:26:44 +0300 Subject: [PATCH 180/205] drm/i915/irq: remove GEN3_IRQ_RESET() and GEN3_IRQ_INIT() macros Define register offset triplets for all registers used with GEN3_IRQ_RESET() and GEN3_IRQ_INIT() macros, and call the underlying gen3_irq_reset() and gen3_irq_init() functions directly. Remove the macros, along with the macro name concatenation hackery. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20241002102645.136155-2-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 34 +++++++------- drivers/gpu/drm/i915/gt/intel_gt_irq.c | 8 ++-- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 4 ++ drivers/gpu/drm/i915/i915_irq.c | 28 ++++++------ drivers/gpu/drm/i915/i915_irq.h | 7 --- drivers/gpu/drm/i915/i915_reg.h | 45 +++++++++++++++++++ 6 files changed, 84 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index a09909c3c6cd..1f6ddc66799f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1496,7 +1496,7 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv) i9xx_pipestat_irq_reset(dev_priv); - GEN3_IRQ_RESET(uncore, VLV_); + gen3_irq_reset(uncore, VLV_IRQ_REGS); dev_priv->irq_mask = ~0u; } @@ -1539,7 +1539,7 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->irq_mask = ~enable_mask; - GEN3_IRQ_INIT(uncore, VLV_, dev_priv->irq_mask, enable_mask); + gen3_irq_init(uncore, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask); } void gen8_display_irq_reset(struct drm_i915_private *dev_priv) @@ -1558,8 +1558,8 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv) POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); - GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_); - GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_); + gen3_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS); + gen3_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS); } void gen11_display_irq_reset(struct drm_i915_private *dev_priv) @@ -1601,16 +1601,16 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); - GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_); - GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_); + gen3_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS); + gen3_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS); if (DISPLAY_VER(dev_priv) >= 14) - GEN3_IRQ_RESET(uncore, PICAINTERRUPT_); + gen3_irq_reset(uncore, PICAINTERRUPT_IRQ_REGS); else - GEN3_IRQ_RESET(uncore, GEN11_DE_HPD_); + gen3_irq_reset(uncore, GEN11_DE_HPD_IRQ_REGS); if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - GEN3_IRQ_RESET(uncore, SDE); + gen3_irq_reset(uncore, SDE_IRQ_REGS); } void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, @@ -1685,7 +1685,7 @@ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) else mask = SDE_GMBUS_CPT; - GEN3_IRQ_INIT(uncore, SDE, ~mask, 0xffffffff); + gen3_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff); } void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) @@ -1753,7 +1753,7 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915) ibx_irq_postinstall(i915); - GEN3_IRQ_INIT(uncore, DE, i915->irq_mask, + gen3_irq_init(uncore, DE_IRQ_REGS, i915->irq_mask, display_mask | extra_mask); } @@ -1844,15 +1844,15 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) de_pipe_enables); } - GEN3_IRQ_INIT(uncore, GEN8_DE_PORT_, ~de_port_masked, de_port_enables); - GEN3_IRQ_INIT(uncore, GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); + gen3_irq_init(uncore, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, de_port_enables); + gen3_irq_init(uncore, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked); if (IS_DISPLAY_VER(dev_priv, 11, 13)) { u32 de_hpd_masked = 0; u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK | GEN11_DE_TBT_HOTPLUG_MASK; - GEN3_IRQ_INIT(uncore, GEN11_DE_HPD_, ~de_hpd_masked, + gen3_irq_init(uncore, GEN11_DE_HPD_IRQ_REGS, ~de_hpd_masked, de_hpd_enables); } } @@ -1865,10 +1865,10 @@ static void mtp_irq_postinstall(struct drm_i915_private *i915) u32 de_hpd_enables = de_hpd_mask | XELPDP_DP_ALT_HOTPLUG_MASK | XELPDP_TBT_HOTPLUG_MASK; - GEN3_IRQ_INIT(uncore, PICAINTERRUPT_, ~de_hpd_mask, + gen3_irq_init(uncore, PICAINTERRUPT_IRQ_REGS, ~de_hpd_mask, de_hpd_enables); - GEN3_IRQ_INIT(uncore, SDE, ~sde_mask, 0xffffffff); + gen3_irq_init(uncore, SDE_IRQ_REGS, ~sde_mask, 0xffffffff); } static void icp_irq_postinstall(struct drm_i915_private *dev_priv) @@ -1876,7 +1876,7 @@ static void icp_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; u32 mask = SDE_GMBUS_ICP; - GEN3_IRQ_INIT(uncore, SDE, ~mask, 0xffffffff); + gen3_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff); } void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index ad4c51f18d3a..fbb3117e324a 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -514,9 +514,9 @@ void gen5_gt_irq_reset(struct intel_gt *gt) { struct intel_uncore *uncore = gt->uncore; - GEN3_IRQ_RESET(uncore, GT); + gen3_irq_reset(uncore, GT_IRQ_REGS); if (GRAPHICS_VER(gt->i915) >= 6) - GEN3_IRQ_RESET(uncore, GEN6_PM); + gen3_irq_reset(uncore, GEN6_PM_IRQ_REGS); } void gen5_gt_irq_postinstall(struct intel_gt *gt) @@ -538,7 +538,7 @@ void gen5_gt_irq_postinstall(struct intel_gt *gt) else gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; - GEN3_IRQ_INIT(uncore, GT, gt->gt_imr, gt_irqs); + gen3_irq_init(uncore, GT_IRQ_REGS, gt->gt_imr, gt_irqs); if (GRAPHICS_VER(gt->i915) >= 6) { /* @@ -551,6 +551,6 @@ void gen5_gt_irq_postinstall(struct intel_gt *gt) } gt->pm_imr = 0xffffffff; - GEN3_IRQ_INIT(uncore, GEN6_PM, gt->pm_imr, pm_irqs); + gen3_irq_init(uncore, GEN6_PM_IRQ_REGS, gt->pm_imr, pm_irqs); } } diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index 57a3c83d3655..04577658695e 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -1472,6 +1472,10 @@ GEN6_PM_RP_DOWN_THRESHOLD | \ GEN6_PM_RP_DOWN_TIMEOUT) +#define GEN6_PM_IRQ_REGS I915_IRQ_REGS(GEN6_PMIMR, \ + GEN6_PMIER, \ + GEN6_PMIIR) + #define GEN7_GT_SCRATCH(i) _MMIO(0x4f100 + (i) * 4) #define GEN7_GT_SCRATCH_REG_NUM 8 diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index db3b4f7f1759..333d58343b37 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -622,7 +622,7 @@ static void ibx_irq_reset(struct drm_i915_private *dev_priv) if (HAS_PCH_NOP(dev_priv)) return; - GEN3_IRQ_RESET(uncore, SDE); + gen3_irq_reset(uncore, SDE_IRQ_REGS); if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) intel_uncore_write(&dev_priv->uncore, SERR_INT, 0xffffffff); @@ -634,7 +634,7 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; - GEN3_IRQ_RESET(uncore, DE); + gen3_irq_reset(uncore, DE_IRQ_REGS); dev_priv->irq_mask = ~0u; if (GRAPHICS_VER(dev_priv) == 7) @@ -671,7 +671,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv) gen8_gt_irq_reset(to_gt(dev_priv)); gen8_display_irq_reset(dev_priv); - GEN3_IRQ_RESET(uncore, GEN8_PCU_); + gen3_irq_reset(uncore, GEN8_PCU_IRQ_REGS); if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_reset(dev_priv); @@ -688,8 +688,8 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv) gen11_gt_irq_reset(gt); gen11_display_irq_reset(dev_priv); - GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_); - GEN3_IRQ_RESET(uncore, GEN8_PCU_); + gen3_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS); + gen3_irq_reset(uncore, GEN8_PCU_IRQ_REGS); } static void dg1_irq_reset(struct drm_i915_private *dev_priv) @@ -705,8 +705,8 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv) gen11_display_irq_reset(dev_priv); - GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_); - GEN3_IRQ_RESET(uncore, GEN8_PCU_); + gen3_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS); + gen3_irq_reset(uncore, GEN8_PCU_IRQ_REGS); intel_uncore_write(uncore, GEN11_GFX_MSTR_IRQ, ~0); } @@ -720,7 +720,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv) gen8_gt_irq_reset(to_gt(dev_priv)); - GEN3_IRQ_RESET(uncore, GEN8_PCU_); + gen3_irq_reset(uncore, GEN8_PCU_IRQ_REGS); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display.irq.display_irqs_enabled) @@ -765,7 +765,7 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv) gen11_gt_irq_postinstall(gt); gen11_de_irq_postinstall(dev_priv); - GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked); + gen3_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); gen11_master_intr_enable(intel_uncore_regs(uncore)); intel_uncore_posting_read(&dev_priv->uncore, GEN11_GFX_MSTR_IRQ); @@ -781,7 +781,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv) for_each_gt(gt, dev_priv, i) gen11_gt_irq_postinstall(gt); - GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked); + gen3_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); dg1_de_irq_postinstall(dev_priv); @@ -869,7 +869,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv) i9xx_display_irq_reset(dev_priv); - GEN3_IRQ_RESET(uncore, GEN2_); + gen3_irq_reset(uncore, GEN2_IRQ_REGS); dev_priv->irq_mask = ~0u; } @@ -901,7 +901,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) enable_mask |= I915_DISPLAY_PORT_INTERRUPT; } - GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask); + gen3_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -974,7 +974,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv) i9xx_display_irq_reset(dev_priv); - GEN3_IRQ_RESET(uncore, GEN2_); + gen3_irq_reset(uncore, GEN2_IRQ_REGS); dev_priv->irq_mask = ~0u; } @@ -1022,7 +1022,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) if (IS_G4X(dev_priv)) enable_mask |= I915_BSD_USER_INTERRUPT; - GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask); + gen3_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h index 361ba46eed76..06a38671b32b 100644 --- a/drivers/gpu/drm/i915/i915_irq.h +++ b/drivers/gpu/drm/i915/i915_irq.h @@ -55,9 +55,6 @@ void gen3_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, GEN8_##type##_IIR(which_))); \ }) -#define GEN3_IRQ_RESET(uncore, type) \ - gen3_irq_reset((uncore), I915_IRQ_REGS(type##IMR, type##IER, type##IIR)) - #define GEN8_IRQ_INIT_NDX(uncore, type, which, imr_val, ier_val) \ ({ \ unsigned int which_ = which; \ @@ -67,8 +64,4 @@ void gen3_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, imr_val, ier_val); \ }) -#define GEN3_IRQ_INIT(uncore, type, imr_val, ier_val) \ - gen3_irq_init((uncore), I915_IRQ_REGS(type##IMR, type##IER, type##IIR), \ - imr_val, ier_val) - #endif /* __I915_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7396fc630e29..818fb71f7efc 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -422,6 +422,11 @@ #define GEN2_IIR _MMIO(0x20a4) #define GEN2_IMR _MMIO(0x20a8) #define GEN2_ISR _MMIO(0x20ac) + +#define GEN2_IRQ_REGS I915_IRQ_REGS(GEN2_IMR, \ + GEN2_IER, \ + GEN2_IIR) + #define VLV_GUNIT_CLOCK_GATE _MMIO(VLV_DISPLAY_BASE + 0x2060) #define GINT_DIS (1 << 22) #define GCFG_DIS (1 << 8) @@ -434,6 +439,10 @@ #define VLV_PCBR _MMIO(VLV_DISPLAY_BASE + 0x2120) #define VLV_PCBR_ADDR_SHIFT 12 +#define VLV_IRQ_REGS I915_IRQ_REGS(VLV_IMR, \ + VLV_IER, \ + VLV_IIR) + #define DISPLAY_PLANE_FLIP_PENDING(plane) (1 << (11 - (plane))) /* A and B only */ #define EIR _MMIO(0x20b0) #define EMR _MMIO(0x20b4) @@ -2444,11 +2453,19 @@ #define DEIIR _MMIO(0x44008) #define DEIER _MMIO(0x4400c) +#define DE_IRQ_REGS I915_IRQ_REGS(DEIMR, \ + DEIER, \ + DEIIR) + #define GTISR _MMIO(0x44010) #define GTIMR _MMIO(0x44014) #define GTIIR _MMIO(0x44018) #define GTIER _MMIO(0x4401c) +#define GT_IRQ_REGS I915_IRQ_REGS(GTIMR, \ + GTIER, \ + GTIIR) + #define GEN8_MASTER_IRQ _MMIO(0x44200) #define GEN8_MASTER_IRQ_CONTROL (1 << 31) #define GEN8_PCU_IRQ (1 << 30) @@ -2560,6 +2577,10 @@ #define TGL_DE_PORT_AUX_DDIB REG_BIT(1) #define TGL_DE_PORT_AUX_DDIA REG_BIT(0) +#define GEN8_DE_PORT_IRQ_REGS I915_IRQ_REGS(GEN8_DE_PORT_IMR, \ + GEN8_DE_PORT_IER, \ + GEN8_DE_PORT_IIR) + #define GEN8_DE_MISC_ISR _MMIO(0x44460) #define GEN8_DE_MISC_IMR _MMIO(0x44464) #define GEN8_DE_MISC_IIR _MMIO(0x44468) @@ -2570,17 +2591,29 @@ #define GEN8_DE_EDP_PSR REG_BIT(19) #define XELPDP_PMDEMAND_RSP REG_BIT(3) +#define GEN8_DE_MISC_IRQ_REGS I915_IRQ_REGS(GEN8_DE_MISC_IMR, \ + GEN8_DE_MISC_IER, \ + GEN8_DE_MISC_IIR) + #define GEN8_PCU_ISR _MMIO(0x444e0) #define GEN8_PCU_IMR _MMIO(0x444e4) #define GEN8_PCU_IIR _MMIO(0x444e8) #define GEN8_PCU_IER _MMIO(0x444ec) +#define GEN8_PCU_IRQ_REGS I915_IRQ_REGS(GEN8_PCU_IMR, \ + GEN8_PCU_IER, \ + GEN8_PCU_IIR) + #define GEN11_GU_MISC_ISR _MMIO(0x444f0) #define GEN11_GU_MISC_IMR _MMIO(0x444f4) #define GEN11_GU_MISC_IIR _MMIO(0x444f8) #define GEN11_GU_MISC_IER _MMIO(0x444fc) #define GEN11_GU_MISC_GSE (1 << 27) +#define GEN11_GU_MISC_IRQ_REGS I915_IRQ_REGS(GEN11_GU_MISC_IMR, \ + GEN11_GU_MISC_IER, \ + GEN11_GU_MISC_IIR) + #define GEN11_GFX_MSTR_IRQ _MMIO(0x190010) #define GEN11_MASTER_IRQ (1 << 31) #define GEN11_PCU_IRQ (1 << 30) @@ -2624,6 +2657,10 @@ GEN11_TBT_HOTPLUG(HPD_PORT_TC2) | \ GEN11_TBT_HOTPLUG(HPD_PORT_TC1)) +#define GEN11_DE_HPD_IRQ_REGS I915_IRQ_REGS(GEN11_DE_HPD_IMR, \ + GEN11_DE_HPD_IER, \ + GEN11_DE_HPD_IIR) + #define GEN11_TBT_HOTPLUG_CTL _MMIO(0x44030) #define GEN11_TC_HOTPLUG_CTL _MMIO(0x44038) #define GEN11_HOTPLUG_CTL_ENABLE(hpd_pin) (8 << (_HPD_PIN_TC(hpd_pin) * 4)) @@ -2644,6 +2681,10 @@ #define XELPDP_TBT_HOTPLUG(hpd_pin) REG_BIT(_HPD_PIN_TC(hpd_pin)) #define XELPDP_TBT_HOTPLUG_MASK REG_GENMASK(3, 0) +#define PICAINTERRUPT_IRQ_REGS I915_IRQ_REGS(PICAINTERRUPT_IMR, \ + PICAINTERRUPT_IER, \ + PICAINTERRUPT_IIR) + #define XELPDP_PORT_HOTPLUG_CTL(hpd_pin) _MMIO(0x16F270 + (_HPD_PIN_TC(hpd_pin) * 0x200)) #define XELPDP_TBT_HOTPLUG_ENABLE REG_BIT(6) #define XELPDP_TBT_HPD_LONG_DETECT REG_BIT(5) @@ -3000,6 +3041,10 @@ #define SDEIIR _MMIO(0xc4008) #define SDEIER _MMIO(0xc400c) +#define SDE_IRQ_REGS I915_IRQ_REGS(SDEIMR, \ + SDEIER, \ + SDEIIR) + #define SERR_INT _MMIO(0xc4040) #define SERR_INT_POISON (1 << 31) #define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1 << ((pipe) * 3)) From de0cbc741818460f6da2a70a0f9edbff61f53e86 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 2 Oct 2024 13:26:45 +0300 Subject: [PATCH 181/205] drm/i915/irq: remove GEN8_IRQ_RESET_NDX() and GEN8_IRQ_INIT_NDX() macros Define register offset triplets for all registers used with GEN8_IRQ_RESET_NDX() and GEN8_IRQ_INIT_NDX() macros, and call the underlying gen3_irq_reset() and gen3_irq_init() functions directly. Remove the macros, along with the macro name concatenation hackery. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20241002102645.136155-3-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 18 +++++++++--------- drivers/gpu/drm/i915/gt/intel_gt_irq.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_irq.h | 17 ----------------- drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++ 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 1f6ddc66799f..a4367ddc7a44 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1556,7 +1556,7 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); + gen3_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe)); gen3_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS); gen3_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS); @@ -1599,7 +1599,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); + gen3_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe)); gen3_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS); gen3_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS); @@ -1630,9 +1630,9 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, } for_each_pipe_masked(dev_priv, pipe, pipe_mask) - GEN8_IRQ_INIT_NDX(uncore, DE_PIPE, pipe, - dev_priv->display.irq.de_irq_mask[pipe], - ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier); + gen3_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe), + dev_priv->display.irq.de_irq_mask[pipe], + ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier); spin_unlock_irq(&dev_priv->irq_lock); } @@ -1651,7 +1651,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, } for_each_pipe_masked(dev_priv, pipe, pipe_mask) - GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); + gen3_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe)); spin_unlock_irq(&dev_priv->irq_lock); @@ -1839,9 +1839,9 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - GEN8_IRQ_INIT_NDX(uncore, DE_PIPE, pipe, - dev_priv->display.irq.de_irq_mask[pipe], - de_pipe_enables); + gen3_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe), + dev_priv->display.irq.de_irq_mask[pipe], + de_pipe_enables); } gen3_irq_init(uncore, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, de_port_enables); diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index fbb3117e324a..0c1e405240af 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -452,10 +452,10 @@ void gen8_gt_irq_reset(struct intel_gt *gt) { struct intel_uncore *uncore = gt->uncore; - GEN8_IRQ_RESET_NDX(uncore, GT, 0); - GEN8_IRQ_RESET_NDX(uncore, GT, 1); - GEN8_IRQ_RESET_NDX(uncore, GT, 2); - GEN8_IRQ_RESET_NDX(uncore, GT, 3); + gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(0)); + gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(1)); + gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(2)); + gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(3)); } void gen8_gt_irq_postinstall(struct intel_gt *gt) @@ -476,14 +476,14 @@ void gen8_gt_irq_postinstall(struct intel_gt *gt) gt->pm_ier = 0x0; gt->pm_imr = ~gt->pm_ier; - GEN8_IRQ_INIT_NDX(uncore, GT, 0, ~gt_interrupts[0], gt_interrupts[0]); - GEN8_IRQ_INIT_NDX(uncore, GT, 1, ~gt_interrupts[1], gt_interrupts[1]); + gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(0), ~gt_interrupts[0], gt_interrupts[0]); + gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(1), ~gt_interrupts[1], gt_interrupts[1]); /* * RPS interrupts will get enabled/disabled on demand when RPS itself * is enabled/disabled. Same wil be the case for GuC interrupts. */ - GEN8_IRQ_INIT_NDX(uncore, GT, 2, gt->pm_imr, gt->pm_ier); - GEN8_IRQ_INIT_NDX(uncore, GT, 3, ~gt_interrupts[3], gt_interrupts[3]); + gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(2), gt->pm_imr, gt->pm_ier); + gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(3), ~gt_interrupts[3], gt_interrupts[3]); } static void gen5_gt_update_irq(struct intel_gt *gt, diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h index 06a38671b32b..da3d97143511 100644 --- a/drivers/gpu/drm/i915/i915_irq.h +++ b/drivers/gpu/drm/i915/i915_irq.h @@ -47,21 +47,4 @@ void gen3_irq_reset(struct intel_uncore *uncore, struct i915_irq_regs regs); void gen3_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs, u32 imr_val, u32 ier_val); -#define GEN8_IRQ_RESET_NDX(uncore, type, which) \ -({ \ - unsigned int which_ = which; \ - gen3_irq_reset((uncore), I915_IRQ_REGS(GEN8_##type##_IMR(which_), \ - GEN8_##type##_IER(which_), \ - GEN8_##type##_IIR(which_))); \ -}) - -#define GEN8_IRQ_INIT_NDX(uncore, type, which, imr_val, ier_val) \ -({ \ - unsigned int which_ = which; \ - gen3_irq_init((uncore), I915_IRQ_REGS(GEN8_##type##_IMR(which_), \ - GEN8_##type##_IER(which_), \ - GEN8_##type##_IIR(which_)), \ - imr_val, ier_val); \ -}) - #endif /* __I915_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 818fb71f7efc..818142f5a10c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2491,6 +2491,10 @@ #define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which))) #define GEN8_GT_IER(which) _MMIO(0x4430c + (0x10 * (which))) +#define GEN8_GT_IRQ_REGS(which) I915_IRQ_REGS(GEN8_GT_IMR(which), \ + GEN8_GT_IER(which), \ + GEN8_GT_IIR(which)) + #define GEN8_RCS_IRQ_SHIFT 0 #define GEN8_BCS_IRQ_SHIFT 16 #define GEN8_VCS0_IRQ_SHIFT 0 /* NB: VCS1 in bspec! */ @@ -2542,6 +2546,10 @@ #define GEN8_PIPE_VSYNC REG_BIT(1) #define GEN8_PIPE_VBLANK REG_BIT(0) +#define GEN8_DE_PIPE_IRQ_REGS(pipe) I915_IRQ_REGS(GEN8_DE_PIPE_IMR(pipe), \ + GEN8_DE_PIPE_IER(pipe), \ + GEN8_DE_PIPE_IIR(pipe)) + #define _HPD_PIN_DDI(hpd_pin) ((hpd_pin) - HPD_PORT_A) #define _HPD_PIN_TC(hpd_pin) ((hpd_pin) - HPD_PORT_TC1) From 0e94059113f615af15ce0cb2e56908f7f42ffcc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:03 +0300 Subject: [PATCH 182/205] drm/i915/dsb: Avoid reads of the DSB buffer for indexed register writes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading from the DSB command buffer might be somewhat expensive on discrete GPUs because the buffer resides in GPU local memory. Avoid such reads in the indexed register write handling by tracking the previous instruction in intel_dsb. TODO: actually measure this Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 54 ++++++++++++++---------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index c39bae1be89e..1a574c9300b1 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -37,9 +37,16 @@ struct intel_dsb { unsigned int free_pos; /* - * ins_start_offset will help to store start dword of the dsb - * instuction and help in identifying the batch of auto-increment - * register. + * Previously emitted DSB instruction. Used to + * identify/adjust the instruction for indexed + * register writes. + */ + u32 ins[2]; + + /* + * Start of the previously emitted DSB instruction. + * Used to adjust the instruction for indexed + * register writes. */ unsigned int ins_start_offset; @@ -215,9 +222,11 @@ static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw) dsb->free_pos = ALIGN(dsb->free_pos, 2); dsb->ins_start_offset = dsb->free_pos; + dsb->ins[0] = ldw; + dsb->ins[1] = udw; - intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, ldw); - intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, udw); + intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, dsb->ins[0]); + intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, dsb->ins[1]); } static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb, @@ -233,10 +242,8 @@ static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb, if (dsb->free_pos == 0) return false; - prev_opcode = intel_dsb_buffer_read(&dsb->dsb_buf, - dsb->ins_start_offset + 1) & ~DSB_REG_VALUE_MASK; - prev_reg = intel_dsb_buffer_read(&dsb->dsb_buf, - dsb->ins_start_offset + 1) & DSB_REG_VALUE_MASK; + prev_opcode = dsb->ins[1] & ~DSB_REG_VALUE_MASK; + prev_reg = dsb->ins[1] & DSB_REG_VALUE_MASK; return prev_opcode == opcode && prev_reg == i915_mmio_reg_offset(reg); } @@ -269,8 +276,6 @@ static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_ void intel_dsb_reg_write(struct intel_dsb *dsb, i915_reg_t reg, u32 val) { - u32 old_val; - /* * For example the buffer will look like below for 3 dwords for auto * increment register: @@ -299,23 +304,27 @@ void intel_dsb_reg_write(struct intel_dsb *dsb, /* convert to indexed write? */ if (intel_dsb_prev_ins_is_mmio_write(dsb, reg)) { - u32 prev_val = intel_dsb_buffer_read(&dsb->dsb_buf, - dsb->ins_start_offset + 0); + u32 prev_val = dsb->ins[0]; - intel_dsb_buffer_write(&dsb->dsb_buf, - dsb->ins_start_offset + 0, 1); /* count */ + dsb->ins[0] = 1; /* count */ + dsb->ins[1] = (DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT) | + i915_mmio_reg_offset(reg); + + intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0, + dsb->ins[0]); intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 1, - (DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT) | - i915_mmio_reg_offset(reg)); - intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 2, prev_val); + dsb->ins[1]); + intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 2, + prev_val); dsb->free_pos++; } intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, val); /* Update the count */ - old_val = intel_dsb_buffer_read(&dsb->dsb_buf, dsb->ins_start_offset); - intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset, old_val + 1); + dsb->ins[0]++; + intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0, + dsb->ins[0]); /* if number of data words is odd, then the last dword should be 0.*/ if (dsb->free_pos & 0x1) @@ -671,6 +680,9 @@ void intel_dsb_wait(struct intel_dsb *dsb) /* Attempt to reset it */ dsb->free_pos = 0; dsb->ins_start_offset = 0; + dsb->ins[0] = 0; + dsb->ins[1] = 0; + intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id), 0); intel_de_write_fw(display, DSB_INTERRUPT(pipe, dsb->id), @@ -727,8 +739,6 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, dsb->id = dsb_id; dsb->crtc = crtc; dsb->size = size / 4; /* in dwords */ - dsb->free_pos = 0; - dsb->ins_start_offset = 0; dsb->chicken = dsb_chicken(state, crtc); dsb->hw_dewake_scanline = From b7e247b3c927493593414dd07ab12702b0977635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:04 +0300 Subject: [PATCH 183/205] drm/i915: Prepare clear color before wait_for_dependencies() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read out the clear color as soon as fences and the transient data flush have finished. There is no need to wait for all the display specific operations that might still be going on. This could parallelize things a bit more effectively. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 74311bb9d290..ed2a0298646b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7596,6 +7596,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_td_flush(dev_priv); + intel_atomic_prepare_plane_clear_colors(state); + drm_atomic_helper_wait_for_dependencies(&state->base); drm_dp_mst_atomic_wait_for_dependencies(&state->base); intel_atomic_global_state_wait_for_dependencies(state); @@ -7629,8 +7631,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) */ wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF); - intel_atomic_prepare_plane_clear_colors(state); - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (intel_crtc_needs_modeset(new_crtc_state) || From b0413571bc4421977c08fdf2179ccacd88f60446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:05 +0300 Subject: [PATCH 184/205] drm/i915/dsb: Generate the DSB buffer in commit_tail() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Once we start using DSB for plane updates we'll need to defer generating the DSB buffer until the clear color has been read out. So we need to move at some of the DSB stuff into commit_tail(). That is perhaps a better place for it anyway as the ioctl thread can move on immediately without spending time building the DSB commands. We always have the MMIO fallback (in case the DSB buffer allocation fails), so there's no real reason to keep any of this in the synchronous part of the ioctl. Because the DSB LUT programming doesn't depend on the plane clear color we can still do that part before waiting for fences/etc. which should help paralleize things a bit more. The DSB plane programming will need to happen after those however as that depends on the clear color. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 23 +++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ed2a0298646b..dfbe1d4de627 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6981,17 +6981,12 @@ int intel_atomic_check(struct drm_device *dev, static int intel_atomic_prepare_commit(struct intel_atomic_state *state) { - struct intel_crtc_state __maybe_unused *crtc_state; - struct intel_crtc *crtc; - int i, ret; + int ret; ret = drm_atomic_helper_prepare_planes(state->base.dev, &state->base); if (ret < 0) return ret; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) - intel_color_prepare_commit(state, crtc); - return 0; } @@ -7582,6 +7577,12 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s } } +static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + intel_color_prepare_commit(state, crtc); +} + static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct drm_device *dev = state->base.dev; @@ -7592,6 +7593,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_wakeref_t wakeref = 0; int i; + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + intel_atomic_dsb_prepare(state, crtc); + intel_atomic_commit_fence_wait(state); intel_td_flush(dev_priv); @@ -7903,13 +7907,6 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, ret = intel_atomic_swap_state(state); if (ret) { - struct intel_crtc_state *new_crtc_state; - struct intel_crtc *crtc; - int i; - - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) - intel_color_cleanup_commit(new_crtc_state); - drm_atomic_helper_unprepare_planes(dev, &state->base); intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); return ret; From 9e9953715ed7cd2097f42832ae6b48da53b72679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:06 +0300 Subject: [PATCH 185/205] drm/i915/dsb: Enable programmable DSB interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DSB can signal a programmable interrupt in response to a specific DSB command getting executed. Hook that up. For now we'll just use this to signal the completion of the commit via a vblank event. If, in the future, we'll need to do other things in response to DSB interrupts we may need to come up with some kind of fancier DSB interrupt framework where the caller can specify a custom handler... Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-5-ville.syrjala@linux.intel.com --- .../drm/i915/display/intel_display_types.h | 2 ++ drivers/gpu/drm/i915/display/intel_dsb.c | 29 +++++++++++++++++-- drivers/gpu/drm/i915/display/intel_dsb.h | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 17fc21f6ae36..e0ec21266047 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1358,6 +1358,8 @@ struct intel_crtc { /* armed event for async flip */ struct drm_pending_vblank_event *flip_done_event; + /* armed event for DSB based updates */ + struct drm_pending_vblank_event *dsb_event; /* Access to these should be protected by dev_priv->irq_lock. */ bool cpu_fifo_underrun_disabled; diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 1a574c9300b1..8514d7219140 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -4,6 +4,8 @@ * */ +#include + #include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" @@ -379,6 +381,12 @@ void intel_dsb_nonpost_end(struct intel_dsb *dsb) intel_dsb_noop(dsb, 4); } +void intel_dsb_interrupt(struct intel_dsb *dsb) +{ + intel_dsb_emit(dsb, 0, + DSB_OPCODE_INTERRUPT << DSB_OPCODE_SHIFT); +} + static void intel_dsb_emit_wait_dsl(struct intel_dsb *dsb, u32 opcode, int lower, int upper) { @@ -544,7 +552,7 @@ static void _intel_dsb_chain(struct intel_atomic_state *state, intel_dsb_reg_write(dsb, DSB_INTERRUPT(pipe, chained_dsb->id), dsb_error_int_status(display) | DSB_PROG_INT_STATUS | - dsb_error_int_en(display)); + dsb_error_int_en(display) | DSB_PROG_INT_EN); if (ctrl & DSB_WAIT_FOR_VBLANK) { int dewake_scanline = dsb_dewake_scanline_start(state, crtc); @@ -612,7 +620,7 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl, intel_de_write_fw(display, DSB_INTERRUPT(pipe, dsb->id), dsb_error_int_status(display) | DSB_PROG_INT_STATUS | - dsb_error_int_en(display)); + dsb_error_int_en(display) | DSB_PROG_INT_EN); intel_de_write_fw(display, DSB_HEAD(pipe, dsb->id), intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf)); @@ -779,6 +787,23 @@ void intel_dsb_irq_handler(struct intel_display *display, tmp = intel_de_read_fw(display, DSB_INTERRUPT(pipe, dsb_id)); intel_de_write_fw(display, DSB_INTERRUPT(pipe, dsb_id), tmp); + if (tmp & DSB_PROG_INT_STATUS) { + spin_lock(&display->drm->event_lock); + + if (crtc->dsb_event) { + /* + * Update vblank counter/timestmap in case it + * hasn't been done yet for this frame. + */ + drm_crtc_accurate_vblank_count(&crtc->base); + + drm_crtc_send_vblank_event(&crtc->base, crtc->dsb_event); + crtc->dsb_event = NULL; + } + + spin_unlock(&display->drm->event_lock); + } + errors = tmp & dsb_error_int_status(display); if (errors) drm_err(display->drm, "[CRTC:%d:%s] DSB %d error interrupt: 0x%x\n", diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index c352c12aa59f..ff3b89dfffc1 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -39,6 +39,7 @@ void intel_dsb_reg_write_masked(struct intel_dsb *dsb, void intel_dsb_noop(struct intel_dsb *dsb, int count); void intel_dsb_nonpost_start(struct intel_dsb *dsb); void intel_dsb_nonpost_end(struct intel_dsb *dsb); +void intel_dsb_interrupt(struct intel_dsb *dsb); void intel_dsb_wait_scanline_in(struct intel_atomic_state *state, struct intel_dsb *dsb, int lower, int upper); From 63b41d207dc12ee2632fcad6229bfca2c54da5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:07 +0300 Subject: [PATCH 186/205] drm/i915/dsb: Introduce intel_dsb_vblank_evade() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper for performing vblank evasion on the DSB. DSB based plane updates will need this to guarantee all the double buffered arming registers will get programmed atomically within the same frame. With VRR we more or less have two vblanks to worry about: - vmax vblank start in case no push was sent - vmin vblank start in case a push was already sent during the vertical active. Only a concern for mailbox updates, which I suppose could happen if the legacy cursor updates take the non-fastpath without setting state->legacy_cursor_update to false. Since we don't know which case is relevant we'll just evade both. We must also make sure to evade both the delayed vblank (for pipe/plane registers) and the undelayed vblank (for transcoder registers and chained DSBs w/ DSB_WAIT_FOR_VBLANK). TODO: come up with a sensible usec number for the evasion... Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 31 ++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 8514d7219140..9ed7b03c1e33 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -128,6 +128,12 @@ pre_commit_crtc_state(struct intel_atomic_state *state, return old_crtc_state; } +static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + return intel_mode_vblank_start(&crtc_state->hw.adjusted_mode) - + intel_mode_vdisplay(&crtc_state->hw.adjusted_mode); +} + static int dsb_vtotal(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -527,6 +533,31 @@ static u32 dsb_error_int_en(struct intel_display *display) return errors; } +void intel_dsb_vblank_evade(struct intel_atomic_state *state, + struct intel_dsb *dsb) +{ + struct intel_crtc *crtc = dsb->crtc; + const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + /* FIXME calibrate sensibly */ + int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20); + int vblank_delay = dsb_vblank_delay(crtc_state); + int start, end; + + if (pre_commit_is_vrr_active(state, crtc)) { + end = intel_vrr_vmin_vblank_start(crtc_state); + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + + end = intel_vrr_vmax_vblank_start(crtc_state); + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + } else { + end = intel_mode_vblank_start(&crtc_state->hw.adjusted_mode); + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + } +} + static void _intel_dsb_chain(struct intel_atomic_state *state, struct intel_dsb *dsb, struct intel_dsb *chained_dsb, diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index ff3b89dfffc1..cce5cb1c6071 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -46,6 +46,8 @@ void intel_dsb_wait_scanline_in(struct intel_atomic_state *state, void intel_dsb_wait_scanline_out(struct intel_atomic_state *state, struct intel_dsb *dsb, int lower, int upper); +void intel_dsb_vblank_evade(struct intel_atomic_state *state, + struct intel_dsb *dsb); void intel_dsb_chain(struct intel_atomic_state *state, struct intel_dsb *dsb, struct intel_dsb *chained_dsb, From de968532fd562af00cd630b5bb7f42e36dbbe755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:08 +0300 Subject: [PATCH 187/205] drm/i915/dsb: Introduce intel_dsb_wait_usec() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a function to emit the DSB "wait usecs" instruction. This is just a usleep() for the DSB. As a lower bound it seems pretty accurate, but the upper bound seemed oddly relaxed (ie. sometimes I've seen waits that are quite a bit longer than specified, not sure why). Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 9ed7b03c1e33..3aaed94c7e65 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -393,6 +393,12 @@ void intel_dsb_interrupt(struct intel_dsb *dsb) DSB_OPCODE_INTERRUPT << DSB_OPCODE_SHIFT); } +void intel_dsb_wait_usec(struct intel_dsb *dsb, int count) +{ + intel_dsb_emit(dsb, count, + DSB_OPCODE_WAIT_USEC << DSB_OPCODE_SHIFT); +} + static void intel_dsb_emit_wait_dsl(struct intel_dsb *dsb, u32 opcode, int lower, int upper) { diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index cce5cb1c6071..882088f55580 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -40,6 +40,7 @@ void intel_dsb_noop(struct intel_dsb *dsb, int count); void intel_dsb_nonpost_start(struct intel_dsb *dsb); void intel_dsb_nonpost_end(struct intel_dsb *dsb); void intel_dsb_interrupt(struct intel_dsb *dsb); +void intel_dsb_wait_usec(struct intel_dsb *dsb, int count); void intel_dsb_wait_scanline_in(struct intel_atomic_state *state, struct intel_dsb *dsb, int lower, int upper); From d6dfbc6f81c3f86497b0d2e4e4f32ea6642aa5df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:09 +0300 Subject: [PATCH 188/205] drm/i915/dsb: Introduce intel_dsb_wait_vblanks() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a function to emit a DSB wait for vblank instruction. This just waits until the specified number of vblanks. Note that this triggers on the transcoder's undelayed vblank, as opposed to the pipe's delayed vblank. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 3aaed94c7e65..373e815a7639 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -399,6 +399,12 @@ void intel_dsb_wait_usec(struct intel_dsb *dsb, int count) DSB_OPCODE_WAIT_USEC << DSB_OPCODE_SHIFT); } +void intel_dsb_wait_vblanks(struct intel_dsb *dsb, int count) +{ + intel_dsb_emit(dsb, count, + DSB_OPCODE_WAIT_VBLANKS << DSB_OPCODE_SHIFT); +} + static void intel_dsb_emit_wait_dsl(struct intel_dsb *dsb, u32 opcode, int lower, int upper) { diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index 882088f55580..115f51c75a1e 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -41,6 +41,7 @@ void intel_dsb_nonpost_start(struct intel_dsb *dsb); void intel_dsb_nonpost_end(struct intel_dsb *dsb); void intel_dsb_interrupt(struct intel_dsb *dsb); void intel_dsb_wait_usec(struct intel_dsb *dsb, int count); +void intel_dsb_wait_vblanks(struct intel_dsb *dsb, int count); void intel_dsb_wait_scanline_in(struct intel_atomic_state *state, struct intel_dsb *dsb, int lower, int upper); From d4f9a053bfe703b699f673f7adb67bae1f3bc01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:10 +0300 Subject: [PATCH 189/205] drm/i915: Introduce intel_scanlines_to_usecs() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce intel_scanlines_to_usecs() as a counterpart to intel_usecs_to_scanlines(). We'll have some use for this in DSB code as we want to do relative scanline waits to evade the delayed vblank, but unfortunately DSB can't do relative scanline waits (only absolute). So we'll instead convert the relative scanline count to usec and do a relative usec wait instead (which the DSB knows how to do). Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 11 +++++++++++ drivers/gpu/drm/i915/display/intel_crtc.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 3a28d8450a38..8ed8dd5fe458 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -483,6 +483,17 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 1000 * adjusted_mode->crtc_htotal); } +int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode, + int scanlines) +{ + /* paranoia */ + if (!adjusted_mode->crtc_clock) + return 1; + + return DIV_ROUND_UP_ULL(mul_u32_u32(scanlines, adjusted_mode->crtc_htotal * 1000), + adjusted_mode->crtc_clock); +} + /** * intel_pipe_update_start() - start update of a set of display registers * @state: the atomic state diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index a58ecd11bba2..34ffbd2ee1b7 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -31,6 +31,8 @@ struct intel_display; int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, int usecs); +int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode, + int scanlines); void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state); u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state); int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe); From 08222ca194b67193d5264ce14ea0ddda3ff64a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:11 +0300 Subject: [PATCH 190/205] drm/i915/dsb: Introduce intel_dsb_wait_vblank_delay() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add intel_dsb_wait_vblank_delay() which instructs the DSB to wait for duration between the undelayed and delayed vblanks. We'll need this as the DSB can only directly wait for the undelayed vblank, but we'll need to wait until the delayed vblank has elapsed as well. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-10-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 11 +++++++++++ drivers/gpu/drm/i915/display/intel_dsb.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 373e815a7639..780f4cee59d6 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -637,6 +637,17 @@ void intel_dsb_chain(struct intel_atomic_state *state, wait_for_vblank ? DSB_WAIT_FOR_VBLANK : 0); } +void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state, + struct intel_dsb *dsb) +{ + struct intel_crtc *crtc = dsb->crtc; + const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc); + int usecs = intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode, + dsb_vblank_delay(crtc_state)) + 1; + + intel_dsb_wait_usec(dsb, usecs); +} + static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl, int hw_dewake_scanline) { diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index 115f51c75a1e..33e0fc2ab380 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -42,6 +42,8 @@ void intel_dsb_nonpost_end(struct intel_dsb *dsb); void intel_dsb_interrupt(struct intel_dsb *dsb); void intel_dsb_wait_usec(struct intel_dsb *dsb, int count); void intel_dsb_wait_vblanks(struct intel_dsb *dsb, int count); +void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state, + struct intel_dsb *dsb); void intel_dsb_wait_scanline_in(struct intel_atomic_state *state, struct intel_dsb *dsb, int lower, int upper); From dd6ec895bac91035fdcb065d39c5d920a539ebc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:12 +0300 Subject: [PATCH 191/205] drm/i915: Extract intel_crtc_prepare_vblank_event() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the code for staging the vblank event for the flip done interrupt handler. We'll reuse this for DSB stuff later. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-11-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_crtc.c | 21 +++++++++++++++------ drivers/gpu/drm/i915/display/intel_crtc.h | 3 +++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 8ed8dd5fe458..4c653e9076d5 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -521,12 +521,8 @@ void intel_pipe_update_start(struct intel_atomic_state *state, intel_psr_lock(new_crtc_state); if (new_crtc_state->do_async_flip) { - spin_lock_irq(&crtc->base.dev->event_lock); - /* arm the event for the flip done irq handler */ - crtc->flip_done_event = new_crtc_state->uapi.event; - spin_unlock_irq(&crtc->base.dev->event_lock); - - new_crtc_state->uapi.event = NULL; + intel_crtc_prepare_vblank_event(new_crtc_state, + &crtc->flip_done_event); return; } @@ -626,6 +622,19 @@ void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state) crtc_state->uapi.event = NULL; } +void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state, + struct drm_pending_vblank_event **event) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + unsigned long irqflags; + + spin_lock_irqsave(&crtc->base.dev->event_lock, irqflags); + *event = crtc_state->uapi.event; + spin_unlock_irqrestore(&crtc->base.dev->event_lock, irqflags); + + crtc_state->uapi.event = NULL; +} + /** * intel_pipe_update_end() - end update of a set of display registers * @state: the atomic state diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index 34ffbd2ee1b7..de54ae1deedf 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -14,6 +14,7 @@ struct drm_device; struct drm_display_mode; struct drm_file; struct drm_i915_private; +struct drm_pending_vblank_event; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; @@ -34,6 +35,8 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode, int scanlines); void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state); +void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state, + struct drm_pending_vblank_event **event); u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state); int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe); int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, From 01389846f7d61d262cc92d42ad4d1a25730e3eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:13 +0300 Subject: [PATCH 192/205] drm/i915: Plumb 'dsb' all way to the plane hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to be able to do both MMIO and DSB based pipe/plane programming. To that end plumb the 'dsb' all way from the top into the plane commit hooks. The compiler appears smart enough to combine the branches from all the back-to-back register writes into a single branch. So the generated asm ends up looking more or less like this: plane_hook() { if (dsb) { intel_dsb_reg_write(); intel_dsb_reg_write(); ... } else { intel_de_write_fw(); intel_de_write_fw(); ... } } which seems like a reasonably efficient way to do this. An alternative I was also considering is some kind of closure (register write function + display vs. dsb pointer passed to it). That does result is smaller code as there are no branches anymore, but having each register access go via function pointer sounds less efficient. Not that I actually measured the overhead of either approach yet. Also the reg_rw tracepoint seems to be making a huge mess of the generated code for the mmio path. And additionally there's some kind of IS_GSI_REG() hack in __raw_uncore_read() which ends up generating a pointless branch for every mmio register access. So looks like there might be quite a bit of room for improvement in the mmio path still. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-12-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 22 +- .../gpu/drm/i915/display/intel_atomic_plane.c | 49 +-- .../gpu/drm/i915/display/intel_atomic_plane.h | 19 +- drivers/gpu/drm/i915/display/intel_color.c | 2 +- drivers/gpu/drm/i915/display/intel_cursor.c | 101 +++--- drivers/gpu/drm/i915/display/intel_de.h | 11 + drivers/gpu/drm/i915/display/intel_display.c | 25 +- .../drm/i915/display/intel_display_types.h | 16 +- drivers/gpu/drm/i915/display/intel_sprite.c | 27 +- .../drm/i915/display/skl_universal_plane.c | 305 ++++++++++-------- drivers/gpu/drm/xe/display/xe_plane_initial.c | 2 +- 11 files changed, 333 insertions(+), 246 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 9447f7229b60..17a1e3801a85 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -416,7 +416,8 @@ static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state, return DIV_ROUND_UP(pixel_rate * num, den); } -static void i9xx_plane_update_noarm(struct intel_plane *plane, +static void i9xx_plane_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -444,7 +445,8 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane, } } -static void i9xx_plane_update_arm(struct intel_plane *plane, +static void i9xx_plane_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -507,7 +509,8 @@ static void i9xx_plane_update_arm(struct intel_plane *plane, intel_plane_ggtt_offset(plane_state) + dspaddr_offset); } -static void i830_plane_update_arm(struct intel_plane *plane, +static void i830_plane_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -517,11 +520,12 @@ static void i830_plane_update_arm(struct intel_plane *plane, * Additional breakage on i830 causes register reads to return * the last latched value instead of the last written value [ALM026]. */ - i9xx_plane_update_noarm(plane, crtc_state, plane_state); - i9xx_plane_update_arm(plane, crtc_state, plane_state); + i9xx_plane_update_noarm(dsb, plane, crtc_state, plane_state); + i9xx_plane_update_arm(dsb, plane, crtc_state, plane_state); } -static void i9xx_plane_disable_arm(struct intel_plane *plane, +static void i9xx_plane_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); @@ -549,7 +553,8 @@ static void i9xx_plane_disable_arm(struct intel_plane *plane, } static void -g4x_primary_async_flip(struct intel_plane *plane, +g4x_primary_async_flip(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, bool async_flip) @@ -569,7 +574,8 @@ g4x_primary_async_flip(struct intel_plane *plane, } static void -vlv_primary_async_flip(struct intel_plane *plane, +vlv_primary_async_flip(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, bool async_flip) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 3505a5b52eb9..b7e462075ded 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -774,7 +774,8 @@ skl_next_plane_to_commit(struct intel_atomic_state *state, return NULL; } -void intel_plane_update_noarm(struct intel_plane *plane, +void intel_plane_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -783,10 +784,11 @@ void intel_plane_update_noarm(struct intel_plane *plane, trace_intel_plane_update_noarm(plane, crtc); if (plane->update_noarm) - plane->update_noarm(plane, crtc_state, plane_state); + plane->update_noarm(dsb, plane, crtc_state, plane_state); } -void intel_plane_async_flip(struct intel_plane *plane, +void intel_plane_async_flip(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, bool async_flip) @@ -794,34 +796,37 @@ void intel_plane_async_flip(struct intel_plane *plane, struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); trace_intel_plane_async_flip(plane, crtc, async_flip); - plane->async_flip(plane, crtc_state, plane_state, async_flip); + plane->async_flip(dsb, plane, crtc_state, plane_state, async_flip); } -void intel_plane_update_arm(struct intel_plane *plane, +void intel_plane_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); if (crtc_state->do_async_flip && plane->async_flip) { - intel_plane_async_flip(plane, crtc_state, plane_state, true); + intel_plane_async_flip(dsb, plane, crtc_state, plane_state, true); return; } trace_intel_plane_update_arm(plane, crtc); - plane->update_arm(plane, crtc_state, plane_state); + plane->update_arm(dsb, plane, crtc_state, plane_state); } -void intel_plane_disable_arm(struct intel_plane *plane, +void intel_plane_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); trace_intel_plane_disable_arm(plane, crtc); - plane->disable_arm(plane, crtc_state); + plane->disable_arm(dsb, plane, crtc_state); } -void intel_crtc_planes_update_noarm(struct intel_atomic_state *state, +void intel_crtc_planes_update_noarm(struct intel_dsb *dsb, + struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_crtc_state *new_crtc_state = @@ -846,11 +851,13 @@ void intel_crtc_planes_update_noarm(struct intel_atomic_state *state, /* TODO: for mailbox updates this should be skipped */ if (new_plane_state->uapi.visible || new_plane_state->planar_slave) - intel_plane_update_noarm(plane, new_crtc_state, new_plane_state); + intel_plane_update_noarm(dsb, plane, + new_crtc_state, new_plane_state); } } -static void skl_crtc_planes_update_arm(struct intel_atomic_state *state, +static void skl_crtc_planes_update_arm(struct intel_dsb *dsb, + struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_crtc_state *old_crtc_state = @@ -877,13 +884,14 @@ static void skl_crtc_planes_update_arm(struct intel_atomic_state *state, */ if (new_plane_state->uapi.visible || new_plane_state->planar_slave) - intel_plane_update_arm(plane, new_crtc_state, new_plane_state); + intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state); else - intel_plane_disable_arm(plane, new_crtc_state); + intel_plane_disable_arm(dsb, plane, new_crtc_state); } } -static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state, +static void i9xx_crtc_planes_update_arm(struct intel_dsb *dsb, + struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_crtc_state *new_crtc_state = @@ -903,21 +911,22 @@ static void i9xx_crtc_planes_update_arm(struct intel_atomic_state *state, * would have to be called here as well. */ if (new_plane_state->uapi.visible) - intel_plane_update_arm(plane, new_crtc_state, new_plane_state); + intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state); else - intel_plane_disable_arm(plane, new_crtc_state); + intel_plane_disable_arm(dsb, plane, new_crtc_state); } } -void intel_crtc_planes_update_arm(struct intel_atomic_state *state, +void intel_crtc_planes_update_arm(struct intel_dsb *dsb, + struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *i915 = to_i915(state->base.dev); if (DISPLAY_VER(i915) >= 9) - skl_crtc_planes_update_arm(state, crtc); + skl_crtc_planes_update_arm(dsb, state, crtc); else - i9xx_crtc_planes_update_arm(state, crtc); + i9xx_crtc_planes_update_arm(dsb, state, crtc); } int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 6c4fe3596465..0f982f452ff3 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -14,6 +14,7 @@ struct drm_rect; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_dsb; struct intel_plane; struct intel_plane_state; enum plane_id; @@ -32,26 +33,32 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state, struct intel_crtc *crtc); void intel_plane_copy_hw_state(struct intel_plane_state *plane_state, const struct intel_plane_state *from_plane_state); -void intel_plane_async_flip(struct intel_plane *plane, +void intel_plane_async_flip(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, bool async_flip); -void intel_plane_update_noarm(struct intel_plane *plane, +void intel_plane_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); -void intel_plane_update_arm(struct intel_plane *plane, +void intel_plane_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); -void intel_plane_disable_arm(struct intel_plane *plane, +void intel_plane_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state); struct intel_plane *intel_plane_alloc(void); void intel_plane_free(struct intel_plane *plane); struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); void intel_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); -void intel_crtc_planes_update_noarm(struct intel_atomic_state *state, +void intel_crtc_planes_update_noarm(struct intel_dsb *dsb, + struct intel_atomic_state *state, struct intel_crtc *crtc); -void intel_crtc_planes_update_arm(struct intel_atomic_state *state, +void intel_crtc_planes_update_arm(struct intel_dsb *dsbx, + struct intel_atomic_state *state, struct intel_crtc *crtc); int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 50f41aeb3c28..6175a8e31302 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1915,7 +1915,7 @@ void intel_color_modeset(const struct intel_crtc_state *crtc_state) struct intel_plane *plane = to_intel_plane(crtc->base.primary); /* update DSPCNTR to configure gamma/csc for pipe bottom color */ - plane->disable_arm(plane, crtc_state); + plane->disable_arm(NULL, plane, crtc_state); } } diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 050eacc709cc..9ba77970dab7 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -274,7 +274,8 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state, } /* TODO: split into noarm+arm pair */ -static void i845_cursor_update_arm(struct intel_plane *plane, +static void i845_cursor_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -314,10 +315,11 @@ static void i845_cursor_update_arm(struct intel_plane *plane, } } -static void i845_cursor_disable_arm(struct intel_plane *plane, +static void i845_cursor_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - i845_cursor_update_arm(plane, crtc_state, NULL); + i845_cursor_update_arm(dsb, plane, crtc_state, NULL); } static bool i845_cursor_get_hw_state(struct intel_plane *plane, @@ -526,22 +528,25 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, return 0; } -static void i9xx_cursor_disable_sel_fetch_arm(struct intel_plane *plane, +static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) return; - intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), 0); + intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0); } -static void wa_16021440873(struct intel_plane *plane, +static void wa_16021440873(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); u32 ctl = plane_state->ctl; int et_y_position = drm_rect_height(&crtc_state->pipe_src) + 1; @@ -550,16 +555,18 @@ static void wa_16021440873(struct intel_plane *plane, ctl &= ~MCURSOR_MODE_MASK; ctl |= MCURSOR_MODE_64_2B; - intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), ctl); + intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), ctl); - intel_de_write(dev_priv, CURPOS_ERLY_TPT(dev_priv, pipe), - CURSOR_POS_Y(et_y_position)); + intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), + CURSOR_POS_Y(et_y_position)); } -static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane, +static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; @@ -570,19 +577,17 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane, if (crtc_state->enable_psr2_su_region_et) { u32 val = intel_cursor_position(crtc_state, plane_state, true); - intel_de_write_fw(dev_priv, - CURPOS_ERLY_TPT(dev_priv, pipe), - val); + + intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), val); } - intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), - plane_state->ctl); + intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), plane_state->ctl); } else { /* Wa_16021440873 */ if (crtc_state->enable_psr2_su_region_et) - wa_16021440873(plane, crtc_state, plane_state); + wa_16021440873(dsb, plane, crtc_state, plane_state); else - i9xx_cursor_disable_sel_fetch_arm(plane, crtc_state); + i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state); } } @@ -609,9 +614,11 @@ static u32 skl_cursor_wm_reg_val(const struct skl_wm_level *level) return val; } -static void skl_write_cursor_wm(struct intel_plane *plane, +static void skl_write_cursor_wm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *i915 = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -621,30 +628,32 @@ static void skl_write_cursor_wm(struct intel_plane *plane, int level; for (level = 0; level < i915->display.wm.num_levels; level++) - intel_de_write_fw(i915, CUR_WM(pipe, level), - skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level))); + intel_de_write_dsb(display, dsb, CUR_WM(pipe, level), + skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level))); - intel_de_write_fw(i915, CUR_WM_TRANS(pipe), - skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id))); + intel_de_write_dsb(display, dsb, CUR_WM_TRANS(pipe), + skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id))); if (HAS_HW_SAGV_WM(i915)) { const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id]; - intel_de_write_fw(i915, CUR_WM_SAGV(pipe), - skl_cursor_wm_reg_val(&wm->sagv.wm0)); - intel_de_write_fw(i915, CUR_WM_SAGV_TRANS(pipe), - skl_cursor_wm_reg_val(&wm->sagv.trans_wm)); + intel_de_write_dsb(display, dsb, CUR_WM_SAGV(pipe), + skl_cursor_wm_reg_val(&wm->sagv.wm0)); + intel_de_write_dsb(display, dsb, CUR_WM_SAGV_TRANS(pipe), + skl_cursor_wm_reg_val(&wm->sagv.trans_wm)); } - intel_de_write_fw(i915, CUR_BUF_CFG(pipe), - skl_cursor_ddb_reg_val(ddb)); + intel_de_write_dsb(display, dsb, CUR_BUF_CFG(pipe), + skl_cursor_ddb_reg_val(ddb)); } /* TODO: split into noarm+arm pair */ -static void i9xx_cursor_update_arm(struct intel_plane *plane, +static void i9xx_cursor_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0; @@ -684,38 +693,36 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane, */ if (DISPLAY_VER(dev_priv) >= 9) - skl_write_cursor_wm(plane, crtc_state); + skl_write_cursor_wm(dsb, plane, crtc_state); if (plane_state) - i9xx_cursor_update_sel_fetch_arm(plane, crtc_state, - plane_state); + i9xx_cursor_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state); else - i9xx_cursor_disable_sel_fetch_arm(plane, crtc_state); + i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state); if (plane->cursor.base != base || plane->cursor.size != fbc_ctl || plane->cursor.cntl != cntl) { if (HAS_CUR_FBC(dev_priv)) - intel_de_write_fw(dev_priv, - CUR_FBC_CTL(dev_priv, pipe), - fbc_ctl); - intel_de_write_fw(dev_priv, CURCNTR(dev_priv, pipe), cntl); - intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos); - intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base); + intel_de_write_dsb(display, dsb, CUR_FBC_CTL(dev_priv, pipe), fbc_ctl); + intel_de_write_dsb(display, dsb, CURCNTR(dev_priv, pipe), cntl); + intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos); + intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base); plane->cursor.base = base; plane->cursor.size = fbc_ctl; plane->cursor.cntl = cntl; } else { - intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos); - intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base); + intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos); + intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base); } } -static void i9xx_cursor_disable_arm(struct intel_plane *plane, +static void i9xx_cursor_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - i9xx_cursor_update_arm(plane, crtc_state, NULL); + i9xx_cursor_update_arm(dsb, plane, crtc_state, NULL); } static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, @@ -904,10 +911,10 @@ intel_legacy_cursor_update(struct drm_plane *_plane, } if (new_plane_state->uapi.visible) { - intel_plane_update_noarm(plane, crtc_state, new_plane_state); - intel_plane_update_arm(plane, crtc_state, new_plane_state); + intel_plane_update_noarm(NULL, plane, crtc_state, new_plane_state); + intel_plane_update_arm(NULL, plane, crtc_state, new_plane_state); } else { - intel_plane_disable_arm(plane, crtc_state); + intel_plane_disable_arm(NULL, plane, crtc_state); } local_irq_enable(); diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index e881bfeafb47..e017cd4a8168 100644 --- a/drivers/gpu/drm/i915/display/intel_de.h +++ b/drivers/gpu/drm/i915/display/intel_de.h @@ -8,6 +8,7 @@ #include "i915_drv.h" #include "i915_trace.h" +#include "intel_dsb.h" #include "intel_uncore.h" static inline struct intel_uncore *__to_uncore(struct intel_display *display) @@ -233,4 +234,14 @@ __intel_de_write_notrace(struct intel_display *display, i915_reg_t reg, } #define intel_de_write_notrace(p,...) __intel_de_write_notrace(__to_intel_display(p), __VA_ARGS__) +static __always_inline void +intel_de_write_dsb(struct intel_display *display, struct intel_dsb *dsb, + i915_reg_t reg, u32 val) +{ + if (dsb) + intel_dsb_reg_write(dsb, reg, val); + else + intel_de_write_fw(display, reg, val); +} + #endif /* __INTEL_DE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index dfbe1d4de627..3f4e629aa88e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -134,7 +134,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state); static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state); static void hsw_set_transconf(const struct intel_crtc_state *crtc_state); -static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state); +static void bdw_set_pipe_misc(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); /* returns HPLL frequency in kHz */ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv) @@ -816,7 +817,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, if (DISPLAY_VER(dev_priv) == 2 && !crtc_state->active_planes) intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); - intel_plane_disable_arm(plane, crtc_state); + intel_plane_disable_arm(NULL, plane, crtc_state); intel_crtc_wait_for_next_vblank(crtc); } @@ -1289,8 +1290,8 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state, * Apart from the async flip bit we want to * preserve the old state for the plane. */ - intel_plane_async_flip(plane, old_crtc_state, - old_plane_state, false); + intel_plane_async_flip(NULL, plane, + old_crtc_state, old_plane_state, false); need_vbl_wait = true; } } @@ -1432,7 +1433,7 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state, !(update_mask & BIT(plane->id))) continue; - intel_plane_disable_arm(plane, new_crtc_state); + intel_plane_disable_arm(NULL, plane, new_crtc_state); if (old_plane_state->uapi.visible) fb_bits |= plane->frontbuffer_bit; @@ -1819,7 +1820,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_set_pipe_src_size(pipe_crtc_state); if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - bdw_set_pipe_misc(pipe_crtc_state); + bdw_set_pipe_misc(NULL, pipe_crtc_state); } if (!transcoder_is_dsi(cpu_transcoder)) @@ -3334,9 +3335,11 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); } -static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state) +static void bdw_set_pipe_misc(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_display *display = to_intel_display(crtc->base.dev); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 val = 0; @@ -3381,7 +3384,7 @@ static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state) if (IS_BROADWELL(dev_priv)) val |= PIPE_MISC_PSR_MASK_SPRITE_ENABLE; - intel_de_write(dev_priv, PIPE_MISC(crtc->pipe), val); + intel_de_write_dsb(display, dsb, PIPE_MISC(crtc->pipe), val); } int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc) @@ -7072,7 +7075,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, intel_color_commit_arm(new_crtc_state); if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - bdw_set_pipe_misc(new_crtc_state); + bdw_set_pipe_misc(NULL, new_crtc_state); if (intel_crtc_needs_fastset(new_crtc_state)) intel_pipe_fastset(old_crtc_state, new_crtc_state); @@ -7172,7 +7175,7 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_noarm(new_crtc_state); - intel_crtc_planes_update_noarm(state, crtc); + intel_crtc_planes_update_noarm(NULL, state, crtc); } static void intel_update_crtc(struct intel_atomic_state *state, @@ -7188,7 +7191,7 @@ static void intel_update_crtc(struct intel_atomic_state *state, commit_pipe_pre_planes(state, crtc); - intel_crtc_planes_update_arm(state, crtc); + intel_crtc_planes_update_arm(NULL, state, crtc); commit_pipe_post_planes(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index e0ec21266047..3902b25e7d24 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -909,6 +909,10 @@ struct intel_csc_matrix { u16 postoff[3]; }; +void intel_io_mmio_fw_write(void *ctx, i915_reg_t reg, u32 val); + +typedef void (*intel_io_reg_write)(void *ctx, i915_reg_t reg, u32 val); + struct intel_crtc_state { /* * uapi (drm) state. This is the software state shown to userspace. @@ -1452,22 +1456,26 @@ struct intel_plane { u32 pixel_format, u64 modifier, unsigned int rotation); /* Write all non-self arming plane registers */ - void (*update_noarm)(struct intel_plane *plane, + void (*update_noarm)(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); /* Write all self-arming plane registers */ - void (*update_arm)(struct intel_plane *plane, + void (*update_arm)(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); /* Disable the plane, must arm */ - void (*disable_arm)(struct intel_plane *plane, + void (*disable_arm)(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state); bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe); int (*check_plane)(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); int (*min_cdclk)(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); - void (*async_flip)(struct intel_plane *plane, + void (*async_flip)(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, bool async_flip); diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index e657b09ede99..e6fadcef58e0 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -378,7 +378,8 @@ static void vlv_sprite_update_gamma(const struct intel_plane_state *plane_state) } static void -vlv_sprite_update_noarm(struct intel_plane *plane, +vlv_sprite_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -399,7 +400,8 @@ vlv_sprite_update_noarm(struct intel_plane *plane, } static void -vlv_sprite_update_arm(struct intel_plane *plane, +vlv_sprite_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -449,7 +451,8 @@ vlv_sprite_update_arm(struct intel_plane *plane, } static void -vlv_sprite_disable_arm(struct intel_plane *plane, +vlv_sprite_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(plane->base.dev); @@ -795,7 +798,8 @@ static void ivb_sprite_update_gamma(const struct intel_plane_state *plane_state) } static void -ivb_sprite_update_noarm(struct intel_plane *plane, +ivb_sprite_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -826,7 +830,8 @@ ivb_sprite_update_noarm(struct intel_plane *plane, } static void -ivb_sprite_update_arm(struct intel_plane *plane, +ivb_sprite_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -874,7 +879,8 @@ ivb_sprite_update_arm(struct intel_plane *plane, } static void -ivb_sprite_disable_arm(struct intel_plane *plane, +ivb_sprite_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(plane->base.dev); @@ -1133,7 +1139,8 @@ static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state) } static void -g4x_sprite_update_noarm(struct intel_plane *plane, +g4x_sprite_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -1162,7 +1169,8 @@ g4x_sprite_update_noarm(struct intel_plane *plane, } static void -g4x_sprite_update_arm(struct intel_plane *plane, +g4x_sprite_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -1206,7 +1214,8 @@ g4x_sprite_update_arm(struct intel_plane *plane, } static void -g4x_sprite_disable_arm(struct intel_plane *plane, +g4x_sprite_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(plane->base.dev); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index fdb141cfa427..9207b7e96974 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -594,11 +594,11 @@ static u32 skl_plane_min_alignment(struct intel_plane *plane, * in full-range YCbCr. */ static void -icl_program_input_csc(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state, +icl_program_input_csc(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum pipe pipe = plane->pipe; enum plane_id plane_id = plane->id; @@ -642,31 +642,31 @@ icl_program_input_csc(struct intel_plane *plane, }; const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding]; - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), - ROFF(csc[0]) | GOFF(csc[1])); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), - BOFF(csc[2])); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), - ROFF(csc[3]) | GOFF(csc[4])); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), - BOFF(csc[5])); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), - ROFF(csc[6]) | GOFF(csc[7])); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), - BOFF(csc[8])); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), + ROFF(csc[0]) | GOFF(csc[1])); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), + BOFF(csc[2])); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), + ROFF(csc[3]) | GOFF(csc[4])); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), + BOFF(csc[5])); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), + ROFF(csc[6]) | GOFF(csc[7])); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), + BOFF(csc[8])); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), - PREOFF_YUV_TO_RGB_HI); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), - PREOFF_YUV_TO_RGB_ME); - intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), - PREOFF_YUV_TO_RGB_LO); - intel_de_write_fw(dev_priv, - PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0); - intel_de_write_fw(dev_priv, - PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0); - intel_de_write_fw(dev_priv, - PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), + PREOFF_YUV_TO_RGB_HI); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), + PREOFF_YUV_TO_RGB_ME); + intel_de_write_dsb(display, dsb, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), + PREOFF_YUV_TO_RGB_LO); + intel_de_write_dsb(display, dsb, + PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0); + intel_de_write_dsb(display, dsb, + PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0); + intel_de_write_dsb(display, dsb, + PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0); } static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb, @@ -720,9 +720,11 @@ static u32 skl_plane_wm_reg_val(const struct skl_wm_level *level) return val; } -static void skl_write_plane_wm(struct intel_plane *plane, +static void skl_write_plane_wm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *i915 = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -734,71 +736,75 @@ static void skl_write_plane_wm(struct intel_plane *plane, int level; for (level = 0; level < i915->display.wm.num_levels; level++) - intel_de_write_fw(i915, PLANE_WM(pipe, plane_id, level), - skl_plane_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level))); + intel_de_write_dsb(display, dsb, PLANE_WM(pipe, plane_id, level), + skl_plane_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level))); - intel_de_write_fw(i915, PLANE_WM_TRANS(pipe, plane_id), - skl_plane_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id))); + intel_de_write_dsb(display, dsb, PLANE_WM_TRANS(pipe, plane_id), + skl_plane_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id))); if (HAS_HW_SAGV_WM(i915)) { const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id]; - intel_de_write_fw(i915, PLANE_WM_SAGV(pipe, plane_id), - skl_plane_wm_reg_val(&wm->sagv.wm0)); - intel_de_write_fw(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id), - skl_plane_wm_reg_val(&wm->sagv.trans_wm)); + intel_de_write_dsb(display, dsb, PLANE_WM_SAGV(pipe, plane_id), + skl_plane_wm_reg_val(&wm->sagv.wm0)); + intel_de_write_dsb(display, dsb, PLANE_WM_SAGV_TRANS(pipe, plane_id), + skl_plane_wm_reg_val(&wm->sagv.trans_wm)); } - intel_de_write_fw(i915, PLANE_BUF_CFG(pipe, plane_id), - skl_plane_ddb_reg_val(ddb)); + intel_de_write_dsb(display, dsb, PLANE_BUF_CFG(pipe, plane_id), + skl_plane_ddb_reg_val(ddb)); if (DISPLAY_VER(i915) < 11) - intel_de_write_fw(i915, PLANE_NV12_BUF_CFG(pipe, plane_id), - skl_plane_ddb_reg_val(ddb_y)); + intel_de_write_dsb(display, dsb, PLANE_NV12_BUF_CFG(pipe, plane_id), + skl_plane_ddb_reg_val(ddb_y)); } static void -skl_plane_disable_arm(struct intel_plane *plane, +skl_plane_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; - skl_write_plane_wm(plane, crtc_state); + skl_write_plane_wm(dsb, plane, crtc_state); - intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0); - intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0); + intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), 0); + intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), 0); } -static void icl_plane_disable_sel_fetch_arm(struct intel_plane *plane, +static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) return; - intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0); + intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0); } static void -icl_plane_disable_arm(struct intel_plane *plane, +icl_plane_disable_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; if (icl_is_hdr_plane(dev_priv, plane_id)) - intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0); + intel_de_write_dsb(display, dsb, PLANE_CUS_CTL(pipe, plane_id), 0); - skl_write_plane_wm(plane, crtc_state); + skl_write_plane_wm(dsb, plane, crtc_state); - icl_plane_disable_sel_fetch_arm(plane, crtc_state); - intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0); - intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0); + icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state); + intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), 0); + intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), 0); } static bool @@ -1235,28 +1241,30 @@ static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state) return keymsk; } -static void icl_plane_csc_load_black(struct intel_plane *plane) +static void icl_plane_csc_load_black(struct intel_dsb *dsb, + struct intel_plane *plane, + const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; - intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 0), 0); - intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 1), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 0), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 1), 0); - intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 2), 0); - intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 3), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 2), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 3), 0); - intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 4), 0); - intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 5), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 4), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane_id, 5), 0); - intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0); - intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0); - intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0); - intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0); - intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0); - intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0); + intel_de_write_dsb(display, dsb, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0); } static int icl_plane_color_plane(const struct intel_plane_state *plane_state) @@ -1269,11 +1277,12 @@ static int icl_plane_color_plane(const struct intel_plane_state *plane_state) } static void -skl_plane_update_noarm(struct intel_plane *plane, +skl_plane_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 stride = skl_plane_stride(plane_state, 0); @@ -1288,21 +1297,23 @@ skl_plane_update_noarm(struct intel_plane *plane, crtc_y = 0; } - intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), - PLANE_STRIDE_(stride)); - intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id), - PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x)); - intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id), - PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1)); + intel_de_write_dsb(display, dsb, PLANE_STRIDE(pipe, plane_id), + PLANE_STRIDE_(stride)); + intel_de_write_dsb(display, dsb, PLANE_POS(pipe, plane_id), + PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x)); + intel_de_write_dsb(display, dsb, PLANE_SIZE(pipe, plane_id), + PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1)); - skl_write_plane_wm(plane, crtc_state); + skl_write_plane_wm(dsb, plane, crtc_state); } static void -skl_plane_update_arm(struct intel_plane *plane, +skl_plane_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -1322,22 +1333,26 @@ skl_plane_update_arm(struct intel_plane *plane, plane_color_ctl = plane_state->color_ctl | glk_plane_color_ctl_crtc(crtc_state); - intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state)); - intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state)); - intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state)); + intel_de_write_dsb(display, dsb, PLANE_KEYVAL(pipe, plane_id), + skl_plane_keyval(plane_state)); + intel_de_write_dsb(display, dsb, PLANE_KEYMSK(pipe, plane_id), + skl_plane_keymsk(plane_state)); + intel_de_write_dsb(display, dsb, PLANE_KEYMAX(pipe, plane_id), + skl_plane_keymax(plane_state)); - intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id), - PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x)); + intel_de_write_dsb(display, dsb, PLANE_OFFSET(pipe, plane_id), + PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x)); - intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), - skl_plane_aux_dist(plane_state, 0)); + intel_de_write_dsb(display, dsb, PLANE_AUX_DIST(pipe, plane_id), + skl_plane_aux_dist(plane_state, 0)); - intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id), - PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) | - PLANE_OFFSET_X(plane_state->view.color_plane[1].x)); + intel_de_write_dsb(display, dsb, PLANE_AUX_OFFSET(pipe, plane_id), + PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) | + PLANE_OFFSET_X(plane_state->view.color_plane[1].x)); if (DISPLAY_VER(dev_priv) >= 10) - intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); + intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id), + plane_color_ctl); /* * Enable the scaler before the plane so that we don't @@ -1354,17 +1369,19 @@ skl_plane_update_arm(struct intel_plane *plane, * disabled. Try to make the plane enable atomic by writing * the control register just before the surface register. */ - intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); - intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), - skl_plane_surf(plane_state, 0)); + intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), + plane_ctl); + intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), + skl_plane_surf(plane_state, 0)); } -static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane, +static void icl_plane_update_sel_fetch_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, int color_plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum pipe pipe = plane->pipe; const struct drm_rect *clip; u32 val; @@ -1381,7 +1398,7 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane, y = (clip->y1 + plane_state->uapi.dst.y1); val = y << 16; val |= plane_state->uapi.dst.x1; - intel_de_write_fw(i915, SEL_FETCH_PLANE_POS(pipe, plane->id), val); + intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_POS(pipe, plane->id), val); x = plane_state->view.color_plane[color_plane].x; @@ -1396,20 +1413,21 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane, val = y << 16 | x; - intel_de_write_fw(i915, SEL_FETCH_PLANE_OFFSET(pipe, plane->id), - val); + intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_OFFSET(pipe, plane->id), val); /* Sizes are 0 based */ val = (drm_rect_height(clip) - 1) << 16; val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1; - intel_de_write_fw(i915, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val); + intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val); } static void -icl_plane_update_noarm(struct intel_plane *plane, +icl_plane_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; @@ -1433,76 +1451,82 @@ icl_plane_update_noarm(struct intel_plane *plane, crtc_y = 0; } - intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), - PLANE_STRIDE_(stride)); - intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id), - PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x)); - intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id), - PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1)); + intel_de_write_dsb(display, dsb, PLANE_STRIDE(pipe, plane_id), + PLANE_STRIDE_(stride)); + intel_de_write_dsb(display, dsb, PLANE_POS(pipe, plane_id), + PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x)); + intel_de_write_dsb(display, dsb, PLANE_SIZE(pipe, plane_id), + PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1)); - intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state)); - intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state)); - intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state)); + intel_de_write_dsb(display, dsb, PLANE_KEYVAL(pipe, plane_id), + skl_plane_keyval(plane_state)); + intel_de_write_dsb(display, dsb, PLANE_KEYMSK(pipe, plane_id), + skl_plane_keymsk(plane_state)); + intel_de_write_dsb(display, dsb, PLANE_KEYMAX(pipe, plane_id), + skl_plane_keymax(plane_state)); - intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id), - PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x)); + intel_de_write_dsb(display, dsb, PLANE_OFFSET(pipe, plane_id), + PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x)); if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) { - intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0), - lower_32_bits(plane_state->ccval)); - intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 1), - upper_32_bits(plane_state->ccval)); + intel_de_write_dsb(display, dsb, PLANE_CC_VAL(pipe, plane_id, 0), + lower_32_bits(plane_state->ccval)); + intel_de_write_dsb(display, dsb, PLANE_CC_VAL(pipe, plane_id, 1), + upper_32_bits(plane_state->ccval)); } /* FLAT CCS doesn't need to program AUX_DIST */ if (!HAS_FLAT_CCS(dev_priv) && DISPLAY_VER(dev_priv) < 20) - intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), - skl_plane_aux_dist(plane_state, color_plane)); + intel_de_write_dsb(display, dsb, PLANE_AUX_DIST(pipe, plane_id), + skl_plane_aux_dist(plane_state, color_plane)); if (icl_is_hdr_plane(dev_priv, plane_id)) - intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), - plane_state->cus_ctl); + intel_de_write_dsb(display, dsb, PLANE_CUS_CTL(pipe, plane_id), + plane_state->cus_ctl); - intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); + intel_de_write_dsb(display, dsb, PLANE_COLOR_CTL(pipe, plane_id), + plane_color_ctl); if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) - icl_program_input_csc(plane, crtc_state, plane_state); + icl_program_input_csc(dsb, plane, plane_state); - skl_write_plane_wm(plane, crtc_state); + skl_write_plane_wm(dsb, plane, crtc_state); /* * FIXME: pxp session invalidation can hit any time even at time of commit * or after the commit, display content will be garbage. */ if (plane_state->force_black) - icl_plane_csc_load_black(plane); + icl_plane_csc_load_black(dsb, plane, crtc_state); - icl_plane_update_sel_fetch_noarm(plane, crtc_state, plane_state, color_plane); + icl_plane_update_sel_fetch_noarm(dsb, plane, crtc_state, plane_state, color_plane); } -static void icl_plane_update_sel_fetch_arm(struct intel_plane *plane, +static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum pipe pipe = plane->pipe; if (!crtc_state->enable_psr2_sel_fetch) return; if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0) - intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id), - SEL_FETCH_PLANE_CTL_ENABLE); + intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), + SEL_FETCH_PLANE_CTL_ENABLE); else - icl_plane_disable_sel_fetch_arm(plane, crtc_state); + icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state); } static void -icl_plane_update_arm(struct intel_plane *plane, +icl_plane_update_arm(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; int color_plane = icl_plane_color_plane(plane_state); @@ -1521,25 +1545,27 @@ icl_plane_update_arm(struct intel_plane *plane, if (plane_state->scaler_id >= 0) skl_program_plane_scaler(plane, crtc_state, plane_state); - icl_plane_update_sel_fetch_arm(plane, crtc_state, plane_state); + icl_plane_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state); /* * The control register self-arms if the plane was previously * disabled. Try to make the plane enable atomic by writing * the control register just before the surface register. */ - intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); - intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), - skl_plane_surf(plane_state, color_plane)); + intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), + plane_ctl); + intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), + skl_plane_surf(plane_state, color_plane)); } static void -skl_plane_async_flip(struct intel_plane *plane, +skl_plane_async_flip(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, bool async_flip) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 plane_ctl = plane_state->ctl; @@ -1549,9 +1575,10 @@ skl_plane_async_flip(struct intel_plane *plane, if (async_flip) plane_ctl |= PLANE_CTL_ASYNC_FLIP; - intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); - intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), - skl_plane_surf(plane_state, 0)); + intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id), + plane_ctl); + intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id), + skl_plane_surf(plane_state, 0)); } static bool intel_format_is_p01x(u32 format) diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c index 1b10ea499d8c..8c113463a3d5 100644 --- a/drivers/gpu/drm/xe/display/xe_plane_initial.c +++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c @@ -248,7 +248,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, * the lookup of sysmem scratch pages. */ plane->check_plane(crtc_state, plane_state); - plane->async_flip(plane, crtc_state, plane_state, true); + plane->async_flip(NULL, plane, crtc_state, plane_state, true); return; nofb: From a6d4d9776e1ebfae9a8e96241f1bfb223adff40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:14 +0300 Subject: [PATCH 193/205] drm/i915: Plumb 'dsb' all way to the color commit hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the 'dsb' all the way down to the color commit hooks so that we'll be able to update the double buffered color management registers (eg. CSC) via the DSB. Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-13-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 180 ++++++++++-------- drivers/gpu/drm/i915/display/intel_color.h | 7 +- drivers/gpu/drm/i915/display/intel_display.c | 4 +- .../drm/i915/display/intel_modeset_setup.c | 4 +- 4 files changed, 111 insertions(+), 84 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 6175a8e31302..4df580019560 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -39,7 +39,8 @@ struct intel_color_funcs { * the next vblank start, alongside any other double buffered * registers involved with the same commit. This hook is optional. */ - void (*color_commit_noarm)(const struct intel_crtc_state *crtc_state); + void (*color_commit_noarm)(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); /* * Program arming double buffered color management registers * during vblank evasion. The registers (and whatever other registers @@ -47,7 +48,8 @@ struct intel_color_funcs { * during the next vblank start, alongside any other double buffered * registers involved with the same commit. */ - void (*color_commit_arm)(const struct intel_crtc_state *crtc_state); + void (*color_commit_arm)(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); /* * Perform any extra tasks needed after all the * double buffered registers have been latched. @@ -205,37 +207,44 @@ static u64 *ctm_mult_by_limited(u64 *result, const u64 *input) return result; } -static void ilk_update_pipe_csc(struct intel_crtc *crtc, +static void ilk_update_pipe_csc(struct intel_dsb *dsb, + struct intel_crtc *crtc, const struct intel_csc_matrix *csc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc->base.dev); enum pipe pipe = crtc->pipe; - intel_de_write_fw(i915, PIPE_CSC_PREOFF_HI(pipe), csc->preoff[0]); - intel_de_write_fw(i915, PIPE_CSC_PREOFF_ME(pipe), csc->preoff[1]); - intel_de_write_fw(i915, PIPE_CSC_PREOFF_LO(pipe), csc->preoff[2]); + intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_HI(pipe), + csc->preoff[0]); + intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_ME(pipe), + csc->preoff[1]); + intel_de_write_dsb(display, dsb, PIPE_CSC_PREOFF_LO(pipe), + csc->preoff[2]); - intel_de_write_fw(i915, PIPE_CSC_COEFF_RY_GY(pipe), - csc->coeff[0] << 16 | csc->coeff[1]); - intel_de_write_fw(i915, PIPE_CSC_COEFF_BY(pipe), - csc->coeff[2] << 16); + intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RY_GY(pipe), + csc->coeff[0] << 16 | csc->coeff[1]); + intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BY(pipe), + csc->coeff[2] << 16); - intel_de_write_fw(i915, PIPE_CSC_COEFF_RU_GU(pipe), - csc->coeff[3] << 16 | csc->coeff[4]); - intel_de_write_fw(i915, PIPE_CSC_COEFF_BU(pipe), - csc->coeff[5] << 16); + intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RU_GU(pipe), + csc->coeff[3] << 16 | csc->coeff[4]); + intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BU(pipe), + csc->coeff[5] << 16); - intel_de_write_fw(i915, PIPE_CSC_COEFF_RV_GV(pipe), - csc->coeff[6] << 16 | csc->coeff[7]); - intel_de_write_fw(i915, PIPE_CSC_COEFF_BV(pipe), - csc->coeff[8] << 16); + intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_RV_GV(pipe), + csc->coeff[6] << 16 | csc->coeff[7]); + intel_de_write_dsb(display, dsb, PIPE_CSC_COEFF_BV(pipe), + csc->coeff[8] << 16); - if (DISPLAY_VER(i915) < 7) + if (DISPLAY_VER(display) < 7) return; - intel_de_write_fw(i915, PIPE_CSC_POSTOFF_HI(pipe), csc->postoff[0]); - intel_de_write_fw(i915, PIPE_CSC_POSTOFF_ME(pipe), csc->postoff[1]); - intel_de_write_fw(i915, PIPE_CSC_POSTOFF_LO(pipe), csc->postoff[2]); + intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_HI(pipe), + csc->postoff[0]); + intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_ME(pipe), + csc->postoff[1]); + intel_de_write_dsb(display, dsb, PIPE_CSC_POSTOFF_LO(pipe), + csc->postoff[2]); } static void ilk_read_pipe_csc(struct intel_crtc *crtc, @@ -304,34 +313,41 @@ static void skl_read_csc(struct intel_crtc_state *crtc_state) ilk_read_pipe_csc(crtc, &crtc_state->csc); } -static void icl_update_output_csc(struct intel_crtc *crtc, +static void icl_update_output_csc(struct intel_dsb *dsb, + struct intel_crtc *crtc, const struct intel_csc_matrix *csc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc->base.dev); enum pipe pipe = crtc->pipe; - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), csc->preoff[0]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), csc->preoff[1]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), csc->preoff[2]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), + csc->preoff[0]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), + csc->preoff[1]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), + csc->preoff[2]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), - csc->coeff[0] << 16 | csc->coeff[1]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BY(pipe), - csc->coeff[2] << 16); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), + csc->coeff[0] << 16 | csc->coeff[1]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BY(pipe), + csc->coeff[2] << 16); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), - csc->coeff[3] << 16 | csc->coeff[4]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BU(pipe), - csc->coeff[5] << 16); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), + csc->coeff[3] << 16 | csc->coeff[4]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BU(pipe), + csc->coeff[5] << 16); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), - csc->coeff[6] << 16 | csc->coeff[7]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BV(pipe), - csc->coeff[8] << 16); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), + csc->coeff[6] << 16 | csc->coeff[7]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_COEFF_BV(pipe), + csc->coeff[8] << 16); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), csc->postoff[0]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), csc->postoff[1]); - intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), csc->postoff[2]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), + csc->postoff[0]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), + csc->postoff[1]); + intel_de_write_dsb(display, dsb, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), + csc->postoff[2]); } static void icl_read_output_csc(struct intel_crtc *crtc, @@ -526,12 +542,13 @@ static void ilk_assign_csc(struct intel_crtc_state *crtc_state) } } -static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state) +static void ilk_load_csc_matrix(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); if (crtc_state->csc_enable) - ilk_update_pipe_csc(crtc, &crtc_state->csc); + ilk_update_pipe_csc(dsb, crtc, &crtc_state->csc); } static void icl_assign_csc(struct intel_crtc_state *crtc_state) @@ -563,15 +580,16 @@ static void icl_assign_csc(struct intel_crtc_state *crtc_state) } } -static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state) +static void icl_load_csc_matrix(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); if (crtc_state->csc_mode & ICL_CSC_ENABLE) - ilk_update_pipe_csc(crtc, &crtc_state->csc); + ilk_update_pipe_csc(dsb, crtc, &crtc_state->csc); if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) - icl_update_output_csc(crtc, &crtc_state->output_csc); + icl_update_output_csc(dsb, crtc, &crtc_state->output_csc); } static u16 ctm_to_twos_complement(u64 coeff, int int_bits, int frac_bits) @@ -953,7 +971,8 @@ static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw) REG_FIELD_GET(PREC_PALETTE_12P4_BLUE_LDW_MASK, ldw); } -static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state) +static void icl_color_commit_noarm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { /* * Despite Wa_1406463849, ICL no longer suffers from the SKL @@ -963,10 +982,11 @@ static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state) * * On TGL+ all CSC arming issues have been properly fixed. */ - icl_load_csc_matrix(crtc_state); + icl_load_csc_matrix(dsb, crtc_state); } -static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state) +static void skl_color_commit_noarm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { /* * Possibly related to display WA #1184, SKL CSC loses the latched @@ -979,21 +999,24 @@ static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state) * which is called after PSR exit. */ if (!crtc_state->has_psr) - ilk_load_csc_matrix(crtc_state); + ilk_load_csc_matrix(dsb, crtc_state); } -static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state) +static void ilk_color_commit_noarm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { - ilk_load_csc_matrix(crtc_state); + ilk_load_csc_matrix(dsb, crtc_state); } -static void i9xx_color_commit_arm(const struct intel_crtc_state *crtc_state) +static void i9xx_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { /* update TRANSCONF GAMMA_MODE */ i9xx_set_pipeconf(crtc_state); } -static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state) +static void ilk_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -1005,7 +1028,8 @@ static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state) crtc_state->csc_mode); } -static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state) +static void hsw_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -1076,15 +1100,16 @@ static void skl_get_config(struct intel_crtc_state *crtc_state) crtc_state->csc_enable = true; } -static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state) +static void skl_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 val = 0; if (crtc_state->has_psr) - ilk_load_csc_matrix(crtc_state); + ilk_load_csc_matrix(dsb, crtc_state); /* * We don't (yet) allow userspace to control the pipe background color, @@ -1095,32 +1120,29 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state) val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE; if (crtc_state->csc_enable) val |= SKL_BOTTOM_COLOR_CSC_ENABLE; - intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), val); + intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), val); - intel_de_write(i915, GAMMA_MODE(crtc->pipe), - crtc_state->gamma_mode); + intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode); - intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe), - crtc_state->csc_mode); + intel_de_write_dsb(display, dsb, PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode); } -static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state) +static void icl_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc->base.dev); enum pipe pipe = crtc->pipe; /* * We don't (yet) allow userspace to control the pipe background color, * so force it to black. */ - intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0); + intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), 0); - intel_de_write(i915, GAMMA_MODE(crtc->pipe), - crtc_state->gamma_mode); + intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode); - intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe), - crtc_state->csc_mode); + intel_de_write_dsb(display, dsb, PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode); } static void icl_color_post_update(const struct intel_crtc_state *crtc_state) @@ -1876,19 +1898,21 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state) i915->display.funcs.color->load_luts(crtc_state); } -void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state) +void intel_color_commit_noarm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); if (i915->display.funcs.color->color_commit_noarm) - i915->display.funcs.color->color_commit_noarm(crtc_state); + i915->display.funcs.color->color_commit_noarm(dsb, crtc_state); } -void intel_color_commit_arm(const struct intel_crtc_state *crtc_state) +void intel_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); - i915->display.funcs.color->color_commit_arm(crtc_state); + i915->display.funcs.color->color_commit_arm(dsb, crtc_state); if (crtc_state->dsb_color_commit) intel_dsb_commit(crtc_state->dsb_color_commit, false); @@ -1907,8 +1931,8 @@ void intel_color_modeset(const struct intel_crtc_state *crtc_state) struct intel_display *display = to_intel_display(crtc_state); intel_color_load_luts(crtc_state); - intel_color_commit_noarm(crtc_state); - intel_color_commit_arm(crtc_state); + intel_color_commit_noarm(NULL, crtc_state); + intel_color_commit_arm(NULL, crtc_state); if (DISPLAY_VER(display) < 9) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h index ab3aaec06a2a..ba493f381031 100644 --- a/drivers/gpu/drm/i915/display/intel_color.h +++ b/drivers/gpu/drm/i915/display/intel_color.h @@ -11,6 +11,7 @@ struct intel_atomic_state; struct intel_crtc_state; struct intel_crtc; +struct intel_dsb; struct drm_i915_private; struct drm_property_blob; @@ -24,8 +25,10 @@ void intel_color_prepare_commit(struct intel_atomic_state *state, void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state); bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state); void intel_color_wait_commit(const struct intel_crtc_state *crtc_state); -void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state); -void intel_color_commit_arm(const struct intel_crtc_state *crtc_state); +void intel_color_commit_noarm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); +void intel_color_commit_arm(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); void intel_color_post_update(const struct intel_crtc_state *crtc_state); void intel_color_load_luts(const struct intel_crtc_state *crtc_state); void intel_color_modeset(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3f4e629aa88e..10a30cfd0cd6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7072,7 +7072,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, */ if (!modeset) { if (intel_crtc_needs_color_update(new_crtc_state)) - intel_color_commit_arm(new_crtc_state); + intel_color_commit_arm(NULL, new_crtc_state); if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) bdw_set_pipe_misc(NULL, new_crtc_state); @@ -7173,7 +7173,7 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, if (!modeset && intel_crtc_needs_color_update(new_crtc_state)) - intel_color_commit_noarm(new_crtc_state); + intel_color_commit_noarm(NULL, new_crtc_state); intel_crtc_planes_update_noarm(NULL, state, crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index bcc5cf137a88..2c8668b1ebae 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -493,8 +493,8 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc, } /* Disable any background color/etc. set by the BIOS */ - intel_color_commit_noarm(crtc_state); - intel_color_commit_arm(crtc_state); + intel_color_commit_noarm(NULL, crtc_state); + intel_color_commit_arm(NULL, crtc_state); } if (!crtc_state->hw.active || From 45c548642b563ec7fd761a3f3a412e99b3c88e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 30 Sep 2024 20:04:15 +0300 Subject: [PATCH 194/205] drm/i915/dsb: Use DSB for plane/color management updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Push regular plane/color management updates to the DSB, if other constraints allow it. The first part of the sequence will go as follows: - CPU will kick off DSB0 immediately - DSB0 writes double bufferd non-arming registers - DSB0 evades the vblank - DSB0 writes double buffered arming registers If no color management updates is needed we follow that up with: - DSB0 waits for the undelayed vblank - DSB0 waits for the delayed vblank (usec wait) - DSB0 emits an interrupt which will cause the CPU to complete the commit If color management update is needed: - DSB0 will start DSB1 with wait for undelayed vblank - DSB0 will in parallel perform the force DEwake tricks - DSB1 writes single buffered LUT registers - DSB1 waits for the delayed vblank (usec wait) - DSB1 emits an interrupt which will cause the CPU to complete the commit With this sequence we don't need to increase the vblank delay to make room for register programming during vblank, which is a good thing for high refresh rate display. But I'll need to still think of some way to eliminate VRR commit completion related races under this scheme. Stuff that isn't ready for DSB yet: - modesets (potentially we could do at least the plane enabling via DSB) - fastsets - VRR - PSR - scalers - async flips Reviewed-by: Animesh Manna Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240930170415.23841-14-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_atomic.c | 5 +- drivers/gpu/drm/i915/display/intel_color.c | 25 +--- drivers/gpu/drm/i915/display/intel_crtc.c | 5 +- drivers/gpu/drm/i915/display/intel_display.c | 128 ++++++++++++++++-- .../drm/i915/display/intel_display_types.h | 5 +- 5 files changed, 128 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 6cac26af128c..03dc54c802d3 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -276,7 +276,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->fb_bits = 0; crtc_state->update_planes = 0; crtc_state->dsb_color_vblank = NULL; - crtc_state->dsb_color_commit = NULL; + crtc_state->dsb_commit = NULL; + crtc_state->use_dsb = false; return &crtc_state->uapi; } @@ -311,7 +312,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc, struct intel_crtc_state *crtc_state = to_intel_crtc_state(state); drm_WARN_ON(crtc->dev, crtc_state->dsb_color_vblank); - drm_WARN_ON(crtc->dev, crtc_state->dsb_color_commit); + drm_WARN_ON(crtc->dev, crtc_state->dsb_commit); __drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi); intel_crtc_free_hw_state(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 4df580019560..caf1af039960 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1913,9 +1913,6 @@ void intel_color_commit_arm(struct intel_dsb *dsb, struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); i915->display.funcs.color->color_commit_arm(dsb, crtc_state); - - if (crtc_state->dsb_color_commit) - intel_dsb_commit(crtc_state->dsb_color_commit, false); } void intel_color_post_update(const struct intel_crtc_state *crtc_state) @@ -1966,28 +1963,14 @@ void intel_color_prepare_commit(struct intel_atomic_state *state, i915->display.funcs.color->load_luts(crtc_state); + intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank); + intel_dsb_interrupt(crtc_state->dsb_color_vblank); + intel_dsb_finish(crtc_state->dsb_color_vblank); - - crtc_state->dsb_color_commit = intel_dsb_prepare(state, crtc, INTEL_DSB_0, 16); - if (!crtc_state->dsb_color_commit) { - intel_dsb_cleanup(crtc_state->dsb_color_vblank); - crtc_state->dsb_color_vblank = NULL; - return; - } - - intel_dsb_chain(state, crtc_state->dsb_color_commit, - crtc_state->dsb_color_vblank, true); - - intel_dsb_finish(crtc_state->dsb_color_commit); } void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state) { - if (crtc_state->dsb_color_commit) { - intel_dsb_cleanup(crtc_state->dsb_color_commit); - crtc_state->dsb_color_commit = NULL; - } - if (crtc_state->dsb_color_vblank) { intel_dsb_cleanup(crtc_state->dsb_color_vblank); crtc_state->dsb_color_vblank = NULL; @@ -1996,8 +1979,6 @@ void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state) void intel_color_wait_commit(const struct intel_crtc_state *crtc_state) { - if (crtc_state->dsb_color_commit) - intel_dsb_wait(crtc_state->dsb_color_commit); if (crtc_state->dsb_color_vblank) intel_dsb_wait(crtc_state->dsb_color_vblank); } diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 4c653e9076d5..3c9168a57f38 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -416,10 +416,11 @@ int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state) { return crtc_state->hw.active && - !intel_crtc_needs_modeset(crtc_state) && !crtc_state->preload_luts && + !intel_crtc_needs_modeset(crtc_state) && intel_crtc_needs_color_update(crtc_state) && - !intel_color_uses_dsb(crtc_state); + !intel_color_uses_dsb(crtc_state) && + !crtc_state->use_dsb; } static void intel_crtc_vblank_work(struct kthread_work *base) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 10a30cfd0cd6..f2b3b73c5432 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7070,7 +7070,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, * During modesets pipe configuration was programmed as the * CRTC was enabled. */ - if (!modeset) { + if (!modeset && !new_crtc_state->use_dsb) { if (intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_arm(NULL, new_crtc_state); @@ -7172,10 +7172,12 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF)); if (!modeset && - intel_crtc_needs_color_update(new_crtc_state)) + intel_crtc_needs_color_update(new_crtc_state) && + !new_crtc_state->use_dsb) intel_color_commit_noarm(NULL, new_crtc_state); - intel_crtc_planes_update_noarm(NULL, state, crtc); + if (!new_crtc_state->use_dsb) + intel_crtc_planes_update_noarm(NULL, state, crtc); } static void intel_update_crtc(struct intel_atomic_state *state, @@ -7186,16 +7188,25 @@ static void intel_update_crtc(struct intel_atomic_state *state, struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - /* Perform vblank evasion around commit operation */ - intel_pipe_update_start(state, crtc); + if (new_crtc_state->use_dsb) { + intel_crtc_prepare_vblank_event(new_crtc_state, &crtc->dsb_event); - commit_pipe_pre_planes(state, crtc); + intel_dsb_commit(new_crtc_state->dsb_commit, false); + } else { + /* Perform vblank evasion around commit operation */ + intel_pipe_update_start(state, crtc); - intel_crtc_planes_update_arm(NULL, state, crtc); + if (new_crtc_state->dsb_commit) + intel_dsb_commit(new_crtc_state->dsb_commit, false); - commit_pipe_post_planes(state, crtc); + commit_pipe_pre_planes(state, crtc); - intel_pipe_update_end(state, crtc); + intel_crtc_planes_update_arm(NULL, state, crtc); + + commit_pipe_post_planes(state, crtc); + + intel_pipe_update_end(state, crtc); + } /* * VRR/Seamless M/N update may need to update frame timings. @@ -7520,6 +7531,24 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat } } +static void intel_atomic_dsb_wait_commit(struct intel_crtc_state *crtc_state) +{ + if (crtc_state->dsb_commit) + intel_dsb_wait(crtc_state->dsb_commit); + + intel_color_wait_commit(crtc_state); +} + +static void intel_atomic_dsb_cleanup(struct intel_crtc_state *crtc_state) +{ + if (crtc_state->dsb_commit) { + intel_dsb_cleanup(crtc_state->dsb_commit); + crtc_state->dsb_commit = NULL; + } + + intel_color_cleanup_commit(crtc_state); +} + static void intel_atomic_cleanup_work(struct work_struct *work) { struct intel_atomic_state *state = @@ -7530,7 +7559,7 @@ static void intel_atomic_cleanup_work(struct work_struct *work) int i; for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) - intel_color_cleanup_commit(old_crtc_state); + intel_atomic_dsb_cleanup(old_crtc_state); drm_atomic_helper_cleanup_planes(&i915->drm, &state->base); drm_atomic_helper_commit_cleanup_done(&state->base); @@ -7586,6 +7615,78 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, intel_color_prepare_commit(state, crtc); } +static void intel_atomic_dsb_finish(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + if (!new_crtc_state->hw.active) + return; + + if (state->base.legacy_cursor_update) + return; + + /* FIXME deal with everything */ + new_crtc_state->use_dsb = + new_crtc_state->update_planes && + !new_crtc_state->vrr.enable && + !new_crtc_state->do_async_flip && + !new_crtc_state->has_psr && + !new_crtc_state->scaler_state.scaler_users && + !old_crtc_state->scaler_state.scaler_users && + !intel_crtc_needs_modeset(new_crtc_state) && + !intel_crtc_needs_fastset(new_crtc_state); + + if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color_vblank) + return; + + /* + * Rough estimate: + * ~64 registers per each plane * 8 planes = 512 + * Double that for pipe stuff and other overhead. + */ + new_crtc_state->dsb_commit = intel_dsb_prepare(state, crtc, INTEL_DSB_0, + new_crtc_state->use_dsb ? 1024 : 16); + if (!new_crtc_state->dsb_commit) { + new_crtc_state->use_dsb = false; + intel_color_cleanup_commit(new_crtc_state); + return; + } + + if (new_crtc_state->use_dsb) { + if (intel_crtc_needs_color_update(new_crtc_state)) + intel_color_commit_noarm(new_crtc_state->dsb_commit, + new_crtc_state); + intel_crtc_planes_update_noarm(new_crtc_state->dsb_commit, + state, crtc); + + intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit); + + if (intel_crtc_needs_color_update(new_crtc_state)) + intel_color_commit_arm(new_crtc_state->dsb_commit, + new_crtc_state); + bdw_set_pipe_misc(new_crtc_state->dsb_commit, + new_crtc_state); + intel_crtc_planes_update_arm(new_crtc_state->dsb_commit, + state, crtc); + + if (!new_crtc_state->dsb_color_vblank) { + intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1); + intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit); + intel_dsb_interrupt(new_crtc_state->dsb_commit); + } + } + + if (new_crtc_state->dsb_color_vblank) + intel_dsb_chain(state, new_crtc_state->dsb_commit, + new_crtc_state->dsb_color_vblank, true); + + intel_dsb_finish(new_crtc_state->dsb_commit); +} + static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct drm_device *dev = state->base.dev; @@ -7605,6 +7706,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_atomic_prepare_plane_clear_colors(state); + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + intel_atomic_dsb_finish(state, crtc); + drm_atomic_helper_wait_for_dependencies(&state->base); drm_dp_mst_atomic_wait_for_dependencies(&state->base); intel_atomic_global_state_wait_for_dependencies(state); @@ -7718,7 +7822,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) if (new_crtc_state->do_async_flip) intel_crtc_disable_flip_done(state, crtc); - intel_color_wait_commit(new_crtc_state); + intel_atomic_dsb_wait_commit(new_crtc_state); } /* @@ -7763,7 +7867,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * FIXME get rid of this funny new->old swapping */ old_crtc_state->dsb_color_vblank = fetch_and_zero(&new_crtc_state->dsb_color_vblank); - old_crtc_state->dsb_color_commit = fetch_and_zero(&new_crtc_state->dsb_color_commit); + old_crtc_state->dsb_commit = fetch_and_zero(&new_crtc_state->dsb_commit); } /* Underruns don't always raise interrupts, so check manually */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3902b25e7d24..2bb1fa64da2f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1270,8 +1270,9 @@ struct intel_crtc_state { /* Only valid on TGL+ */ enum transcoder mst_master_transcoder; - /* For DSB based color LUT updates */ - struct intel_dsb *dsb_color_vblank, *dsb_color_commit; + /* For DSB based pipe updates */ + struct intel_dsb *dsb_color_vblank, *dsb_commit; + bool use_dsb; u32 psr2_man_track_ctl; From 8231ac7e72ae38e0e13d1eab0a11b48878bc9779 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 2 Oct 2024 21:16:55 +0300 Subject: [PATCH 195/205] drm/i915: use NULL for zero wakeref_t instead of plain integer 0 As of commit 2edc6a75f26c ("drm/i915: switch intel_wakeref_t underlying type to struct ref_tracker *") we gained quite a few sparse warnings about "Using plain integer as NULL pointer" for using 0 to initialize wakeref_t. Switch to NULL everywhere. Signed-off-by: Jani Nikula Reviewed-by: Chaitanya Kumar Borah Link: https://patchwork.freedesktop.org/patch/msgid/20241002181655.582597-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_display_power.c | 6 +++--- drivers/gpu/drm/i915/display/intel_display_power.h | 4 ++-- drivers/gpu/drm/i915/display/intel_pps.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 6 +++--- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +- drivers/gpu/drm/i915/i915_vma.c | 4 ++-- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.h | 6 +++--- drivers/gpu/drm/i915/intel_wakeref.c | 14 +++++++------- drivers/gpu/drm/i915/pxp/intel_pxp.c | 2 +- .../drm/xe/compat-i915-headers/intel_runtime_pm.h | 6 +++--- 15 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f2b3b73c5432..2b36ae6444d9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7694,7 +7694,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; int i; for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 7b16ba1a8226..c2bc80f5bf6b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -545,7 +545,7 @@ intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, wakeref = intel_runtime_pm_get_if_in_use(&dev_priv->runtime_pm); if (!wakeref) - return 0; + return NULL; mutex_lock(&power_domains->lock); @@ -560,7 +560,7 @@ intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, if (!is_enabled) { intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); - wakeref = 0; + wakeref = NULL; } return wakeref; @@ -648,7 +648,7 @@ intel_display_power_put_async_work(struct work_struct *work) struct i915_power_domains *power_domains = &dev_priv->display.power.domains; struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm); - intel_wakeref_t old_work_wakeref = 0; + intel_wakeref_t old_work_wakeref = NULL; mutex_lock(&power_domains->lock); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 3b7c1a0bb1de..3f8f84df4733 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -297,10 +297,10 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, #define with_intel_display_power(i915, domain, wf) \ for ((wf) = intel_display_power_get((i915), (domain)); (wf); \ - intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) + intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL) #define with_intel_display_power_if_enabled(i915, domain, wf) \ for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \ - intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) + intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL) #endif /* __INTEL_DISPLAY_POWER_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 88abc4c7cda1..ffeee9daa568 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -87,7 +87,7 @@ intel_wakeref_t intel_pps_unlock(struct intel_dp *intel_dp, mutex_unlock(&display->pps.mutex); intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref); - return 0; + return NULL; } static void diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index d166052eb2ce..9117e9422844 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -117,7 +117,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, }, { NULL, 0 }, }, *phase; - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; unsigned long count = 0; unsigned long scanned = 0; int err = 0, i = 0; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index b22e2019768f..abb82be0d0aa 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -1038,7 +1038,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) struct ttm_buffer_object *bo = area->vm_private_data; struct drm_device *dev = bo->base.dev; struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; vm_fault_t ret; int idx; @@ -1195,7 +1195,7 @@ static u64 i915_ttm_mmap_offset(struct drm_i915_gem_object *obj) static void i915_ttm_unmap_virtual(struct drm_i915_gem_object *obj) { struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; assert_object_held_shared(obj); diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index 20b9b04ec1e0..cc866773ba6f 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -70,7 +70,7 @@ static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) if (!--b->irq_enabled) b->irq_disable(b); - WRITE_ONCE(b->irq_armed, 0); + WRITE_ONCE(b->irq_armed, NULL); intel_gt_pm_put_async(b->irq_engine->gt, wakeref); } diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h index dcbfc09194b7..6f25c747bc29 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h @@ -35,7 +35,7 @@ static inline void __intel_gt_pm_get(struct intel_gt *gt) static inline intel_wakeref_t intel_gt_pm_get_if_awake(struct intel_gt *gt) { if (!intel_wakeref_get_if_active(>->wakeref)) - return 0; + return NULL; return intel_wakeref_track(>->wakeref); } @@ -73,7 +73,7 @@ static inline void intel_gt_pm_put_async(struct intel_gt *gt, intel_wakeref_t ha } #define with_intel_gt_pm(gt, wf) \ - for (wf = intel_gt_pm_get(gt); wf; intel_gt_pm_put(gt, wf), wf = 0) + for ((wf) = intel_gt_pm_get(gt); (wf); intel_gt_pm_put((gt), (wf)), (wf) = NULL) /** * with_intel_gt_pm_if_awake - if GT is PM awake, get a reference to prevent @@ -84,7 +84,7 @@ static inline void intel_gt_pm_put_async(struct intel_gt *gt, intel_wakeref_t ha * @wf: pointer to a temporary wakeref. */ #define with_intel_gt_pm_if_awake(gt, wf) \ - for (wf = intel_gt_pm_get_if_awake(gt); wf; intel_gt_pm_put_async(gt, wf), wf = 0) + for ((wf) = intel_gt_pm_get_if_awake(gt); (wf); intel_gt_pm_put_async((gt), (wf)), (wf) = NULL) static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt) { diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index ed979847187f..9ede6f240d79 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1339,7 +1339,7 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now) * start_gt_clk is derived from GuC state. To get a consistent * view of activity, we query the GuC state only if gt is awake. */ - wakeref = in_reset ? 0 : intel_gt_pm_get_if_awake(gt); + wakeref = in_reset ? NULL : intel_gt_pm_get_if_awake(gt); if (wakeref) { stats_saved = *stats; gt_stamp_saved = guc->timestamp.gt_stamp; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index d2f064d2525c..776f8cc51b2f 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -2157,7 +2157,7 @@ static struct dma_fence *__i915_vma_unbind_async(struct i915_vma *vma) int i915_vma_unbind(struct i915_vma *vma) { struct i915_address_space *vm = vma->vm; - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; int err; assert_object_held_shared(vma->obj); @@ -2196,7 +2196,7 @@ int i915_vma_unbind_async(struct i915_vma *vma, bool trylock_vm) { struct drm_i915_gem_object *obj = vma->obj; struct i915_address_space *vm = vma->vm; - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; struct dma_fence *fence; int err; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index a21f5a1c89bc..1a47ecfd3fd8 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -250,7 +250,7 @@ static intel_wakeref_t __intel_runtime_pm_get_if_active(struct intel_runtime_pm pm_runtime_get_if_active(rpm->kdev) <= 0) || (!ignore_usecount && pm_runtime_get_if_in_use(rpm->kdev) <= 0)) - return 0; + return NULL; } intel_runtime_pm_acquire(rpm, true); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index 796a2dcb307e..126f8320f86e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -188,15 +188,15 @@ intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); #define with_intel_runtime_pm(rpm, wf) \ for ((wf) = intel_runtime_pm_get(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) #define with_intel_runtime_pm_if_in_use(rpm, wf) \ for ((wf) = intel_runtime_pm_get_if_in_use(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) #define with_intel_runtime_pm_if_active(rpm, wf) \ for ((wf) = intel_runtime_pm_get_if_active(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c index dea2f63184f8..87f246047312 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.c +++ b/drivers/gpu/drm/i915/intel_wakeref.c @@ -27,11 +27,11 @@ int __intel_wakeref_get_first(struct intel_wakeref *wf) if (!atomic_read(&wf->count)) { INTEL_WAKEREF_BUG_ON(wf->wakeref); wf->wakeref = wakeref; - wakeref = 0; + wakeref = NULL; ret = wf->ops->get(wf); if (ret) { - wakeref = xchg(&wf->wakeref, 0); + wakeref = xchg(&wf->wakeref, NULL); wake_up_var(&wf->wakeref); goto unlock; } @@ -52,7 +52,7 @@ int __intel_wakeref_get_first(struct intel_wakeref *wf) static void ____intel_wakeref_put_last(struct intel_wakeref *wf) { - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref = NULL; INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0); if (unlikely(!atomic_dec_and_test(&wf->count))) @@ -61,7 +61,7 @@ static void ____intel_wakeref_put_last(struct intel_wakeref *wf) /* ops->put() must reschedule its own release on error/deferral */ if (likely(!wf->ops->put(wf))) { INTEL_WAKEREF_BUG_ON(!wf->wakeref); - wakeref = xchg(&wf->wakeref, 0); + wakeref = xchg(&wf->wakeref, NULL); wake_up_var(&wf->wakeref); } @@ -107,7 +107,7 @@ void __intel_wakeref_init(struct intel_wakeref *wf, __mutex_init(&wf->mutex, "wakeref.mutex", &key->mutex); atomic_set(&wf->count, 0); - wf->wakeref = 0; + wf->wakeref = NULL; INIT_DELAYED_WORK(&wf->work, __intel_wakeref_put_work); lockdep_init_map(&wf->work.work.lockdep_map, @@ -142,7 +142,7 @@ static void wakeref_auto_timeout(struct timer_list *t) if (!refcount_dec_and_lock_irqsave(&wf->count, &wf->lock, &flags)) return; - wakeref = fetch_and_zero(&wf->wakeref); + wakeref = xchg(&wf->wakeref, NULL); spin_unlock_irqrestore(&wf->lock, flags); intel_runtime_pm_put(&wf->i915->runtime_pm, wakeref); @@ -154,7 +154,7 @@ void intel_wakeref_auto_init(struct intel_wakeref_auto *wf, spin_lock_init(&wf->lock); timer_setup(&wf->timer, wakeref_auto_timeout, 0); refcount_set(&wf->count, 0); - wf->wakeref = 0; + wf->wakeref = NULL; wf->i915 = i915; } diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 3a40e4ece925..da3577149769 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -531,7 +531,7 @@ void intel_pxp_invalidate(struct intel_pxp *pxp) if (ctx->pxp_wakeref) { intel_runtime_pm_put(&i915->runtime_pm, ctx->pxp_wakeref); - ctx->pxp_wakeref = 0; + ctx->pxp_wakeref = NULL; } spin_lock_irq(&i915->gem.contexts.lock); diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h index 380d25428bdb..cba587ceba1b 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h @@ -24,14 +24,14 @@ static inline intel_wakeref_t intel_runtime_pm_get(struct xe_runtime_pm *pm) { struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - return xe_pm_runtime_resume_and_get(xe) ? INTEL_WAKEREF_DEF : 0; + return xe_pm_runtime_resume_and_get(xe) ? INTEL_WAKEREF_DEF : NULL; } static inline intel_wakeref_t intel_runtime_pm_get_if_in_use(struct xe_runtime_pm *pm) { struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm); - return xe_pm_runtime_get_if_in_use(xe) ? INTEL_WAKEREF_DEF : 0; + return xe_pm_runtime_get_if_in_use(xe) ? INTEL_WAKEREF_DEF : NULL; } static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm *pm) @@ -63,6 +63,6 @@ static inline void intel_runtime_pm_put(struct xe_runtime_pm *pm, intel_wakeref_ #define with_intel_runtime_pm(rpm, wf) \ for ((wf) = intel_runtime_pm_get(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) #endif From e5ffdd866f9beb68d0e3b4d666b9980e459ab833 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 2 Oct 2024 08:49:03 +0100 Subject: [PATCH 196/205] drm/i915/display: Fix spelling mistake "Uncomressed" -> "Uncompressed" There is a spelling mistake in a drm_WARN message. Fix it. Signed-off-by: Colin Ian King Reviewed-by: Ankit Nautiyal Link: https://patchwork.freedesktop.org/patch/msgid/20241002074903.833232-1-colin.i.king@gmail.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2b36ae6444d9..e1f6255e918b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3814,7 +3814,7 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, secondary_ultrajoiner_pipes); drm_WARN(display->drm, (uncompressed_joiner_pipes & bigjoiner_pipes) != 0, - "Uncomressed joiner pipes(%#x) and bigjoiner pipes(%#x) can't intersect\n", + "Uncompressed joiner pipes(%#x) and bigjoiner pipes(%#x) can't intersect\n", uncompressed_joiner_pipes, bigjoiner_pipes); drm_WARN(display->drm, secondary_bigjoiner_pipes != From f3c25031bb321d8cef15ecd4df27d0f644a95193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 26 Sep 2024 09:47:58 +0300 Subject: [PATCH 197/205] drm/i915/psr: Add new SU area calculation helper to apply workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_psr2_sel_fetch_update is already quite long function. Now we are about to add one more HW workaround. Let's split applying workarounds to selective update area into a separate function. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20240926064759.1313335-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 8e9f068b9b2b..e3743f687536 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2519,11 +2519,24 @@ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *c return true; } +static void +intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + + /* Wa_14014971492 */ + if (!crtc_state->has_panel_replay && + ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) || + IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) && + crtc_state->splitter.enable) + crtc_state->psr2_su_area.y1 = 0; +} + int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_plane_state *new_plane_state, *old_plane_state; struct intel_plane *plane; @@ -2628,12 +2641,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (full_update) goto skip_sel_fetch_set_loop; - /* Wa_14014971492 */ - if (!crtc_state->has_panel_replay && - ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) || - IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv))) && - crtc_state->splitter.enable) - crtc_state->psr2_su_area.y1 = 0; + intel_psr_apply_su_area_workarounds(crtc_state); ret = drm_atomic_add_affected_planes(&state->base, &crtc->base); if (ret) From d92df66fd3e78ed307aee64d947be314e91e8cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 26 Sep 2024 09:47:59 +0300 Subject: [PATCH 198/205] drm/i915/psr: Implement Wa 14019834836 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements HW workaround 14019834836 for display version 30. v2: - move Wa 14019834836 to it's own function - apply only for display version 30 Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20240926064759.1313335-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index e3743f687536..3b20325b3f6a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2519,6 +2519,38 @@ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *c return true; } +/* Wa 14019834836 */ +static void intel_psr_apply_pr_link_on_su_wa(struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_encoder *encoder; + int hactive_limit; + + if (crtc_state->psr2_su_area.y1 != 0 || + crtc_state->psr2_su_area.y2 != 0) + return; + + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) + hactive_limit = intel_dp_is_uhbr(crtc_state) ? 1230 : 546; + else + hactive_limit = intel_dp_is_uhbr(crtc_state) ? 615 : 273; + + if (crtc_state->hw.adjusted_mode.hdisplay < hactive_limit) + return; + + for_each_intel_encoder_mask_with_psr(display->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + if (!intel_dp_is_edp(intel_dp) && + intel_dp->psr.panel_replay_enabled && + intel_dp->psr.sel_update_enabled) { + crtc_state->psr2_su_area.y2++; + return; + } + } +} + static void intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state) { @@ -2531,6 +2563,10 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state) IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) && crtc_state->splitter.enable) crtc_state->psr2_su_area.y1 = 0; + + /* Wa 14019834836 */ + if (DISPLAY_VER(display) == 30) + intel_psr_apply_pr_link_on_su_wa(crtc_state); } int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, From 0ddae025ab6cefa9aba757da3cd1d27908d70b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:40 +0300 Subject: [PATCH 199/205] drm/i915: Disable compression tricks on JSL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec asks us to disable some compression trick on JSL. While the bspec description is pretty vague it looks like this is some extra trick for 10bpc+ CCS which presumably the ICL derived display engine doesn't support. Note that we aren't currently exposing 10bpc CCS scanout support, but once that gets added this presumably becomes an issue. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-3-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 1 + drivers/gpu/drm/i915/gt/intel_workarounds.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index 04577658695e..6dba65e54cdb 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -432,6 +432,7 @@ #define XEHPG_INSTDONE_GEOM_SVG MCR_REG(0x666c) #define CACHE_MODE_0_GEN7 _MMIO(0x7000) /* IVB+ */ +#define DISABLE_REPACKING_FOR_COMPRESSION REG_BIT(15) /* jsl+ */ #define RC_OP_FLUSH_ENABLE (1 << 0) #define HIZ_RAW_STALL_OPT_DISABLE (1 << 2) #define CACHE_MODE_1 _MMIO(0x7004) /* IVB+ */ diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index e539a656cfc3..6972525fe6be 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -2299,6 +2299,15 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) GEN8_RC_SEMA_IDLE_MSG_DISABLE); } + if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) { + /* + * "Disable Repacking for Compression (masked R/W access) + * before rendering compressed surfaces for display." + */ + wa_masked_en(wal, CACHE_MODE_0_GEN7, + DISABLE_REPACKING_FOR_COMPRESSION); + } + if (GRAPHICS_VER(i915) == 11) { /* This is not an Wa. Enable for better image quality */ wa_masked_en(wal, From c315fbfa44f4da2e9b13ff99e5cba5e645693aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:41 +0300 Subject: [PATCH 200/205] drm/i915: Enable 10bpc + CCS on TGL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TGL+ support 10bpc compressed scanout. Enable it. v2: Set .depth=30 for all variants to match drm_fourcc.c Set clear color block size to 0x0 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-4-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_fb.c | 36 +++++++++++++++++++ .../drm/i915/display/skl_universal_plane.c | 8 ++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 6c2679e6c980..8ee9fef446c6 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -67,6 +67,18 @@ static const struct drm_format_info gen12_ccs_formats[] = { { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, { .format = DRM_FORMAT_YUYV, .num_planes = 2, .char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, @@ -113,6 +125,18 @@ static const struct drm_format_info gen12_ccs_cc_formats[] = { { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3, .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3, + .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, }; static const struct drm_format_info gen12_flat_ccs_cc_formats[] = { @@ -128,6 +152,18 @@ static const struct drm_format_info gen12_flat_ccs_cc_formats[] = { { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2, + .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, }; struct intel_modifier_desc { diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 9207b7e96974..2a82fd6d2f89 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2343,6 +2343,10 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ARGB8888: case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: if (intel_fb_is_ccs_modifier(modifier)) return true; fallthrough; @@ -2359,10 +2363,6 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, return true; fallthrough; case DRM_FORMAT_RGB565: - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ABGR2101010: case DRM_FORMAT_XVYU2101010: case DRM_FORMAT_C8: case DRM_FORMAT_XBGR16161616F: From 0c787d4f61dfefe099bace54930ded72698772b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:42 +0300 Subject: [PATCH 201/205] drm/i915: Enable 10bpc + CCS on ICL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ICL also supports compressed 10bpc scanout. Enable it. v2: Set .depth=30 for all variants to match drm_fourcc.c Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-5-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_fb.c | 8 +++ .../drm/i915/display/skl_universal_plane.c | 65 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 8ee9fef446c6..415d8bb7143f 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -45,6 +45,14 @@ static const struct drm_format_info skl_ccs_formats[] = { .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, }, { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, }, + { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2, + .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, + { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2, + .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, + { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2, + .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, }, + { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2, + .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, }, }; /* diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 2a82fd6d2f89..d49bc0bef939 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2330,6 +2330,60 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane, } } +static bool icl_plane_format_mod_supported(struct drm_plane *_plane, + u32 format, u64 modifier) +{ + struct intel_plane *plane = to_intel_plane(_plane); + + if (!intel_fb_plane_supports_modifier(plane, modifier)) + return false; + + switch (format) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: + if (intel_fb_is_ccs_modifier(modifier)) + return true; + fallthrough; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_NV12: + case DRM_FORMAT_XYUV8888: + case DRM_FORMAT_P010: + case DRM_FORMAT_P012: + case DRM_FORMAT_P016: + case DRM_FORMAT_XVYU2101010: + if (modifier == I915_FORMAT_MOD_Yf_TILED) + return true; + fallthrough; + case DRM_FORMAT_C8: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + case DRM_FORMAT_Y210: + case DRM_FORMAT_Y212: + case DRM_FORMAT_Y216: + case DRM_FORMAT_XVYU12_16161616: + case DRM_FORMAT_XVYU16161616: + if (modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED || + modifier == I915_FORMAT_MOD_Y_TILED) + return true; + fallthrough; + default: + return false; + } +} + static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, u32 format, u64 modifier) { @@ -2391,6 +2445,15 @@ static const struct drm_plane_funcs skl_plane_funcs = { .format_mod_supported = skl_plane_format_mod_supported, }; +static const struct drm_plane_funcs icl_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = intel_plane_destroy, + .atomic_duplicate_state = intel_plane_duplicate_state, + .atomic_destroy_state = intel_plane_destroy_state, + .format_mod_supported = icl_plane_format_mod_supported, +}; + static const struct drm_plane_funcs gen12_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -2570,6 +2633,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, if (DISPLAY_VER(dev_priv) >= 12) plane_funcs = &gen12_plane_funcs; + else if (DISPLAY_VER(dev_priv) == 11) + plane_funcs = &icl_plane_funcs; else plane_funcs = &skl_plane_funcs; From 7c35015fab5d5b49e59426079bef6ae48719705e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:43 +0300 Subject: [PATCH 202/205] drm/i915: Enable fp16 + CCS on TGL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TGL+ support compressed fp16 scanout. Enable it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-6-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_fb.c | 36 +++++++++++++++++++ .../drm/i915/display/skl_universal_plane.c | 8 ++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 415d8bb7143f..70ced57ab102 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -87,6 +87,18 @@ static const struct drm_format_info gen12_ccs_formats[] = { { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2, .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 1 }, .block_w = { 1, 1 }, .block_h = { 1, 1 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, { .format = DRM_FORMAT_YUYV, .num_planes = 2, .char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, @@ -145,6 +157,18 @@ static const struct drm_format_info gen12_ccs_cc_formats[] = { { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3, .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 3, + .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 3, + .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 3, + .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 3, + .char_per_block = { 8, 1, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, }; static const struct drm_format_info gen12_flat_ccs_cc_formats[] = { @@ -172,6 +196,18 @@ static const struct drm_format_info gen12_flat_ccs_cc_formats[] = { { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2, .char_per_block = { 4, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, }, + { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 2, + .char_per_block = { 8, 0 }, .block_w = { 1, 0 }, .block_h = { 1, 0 }, + .hsub = 1, .vsub = 1, .has_alpha = true }, }; struct intel_modifier_desc { diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index d49bc0bef939..ed0c9f565d72 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2401,6 +2401,10 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_ARGB2101010: case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: if (intel_fb_is_ccs_modifier(modifier)) return true; fallthrough; @@ -2419,10 +2423,6 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, case DRM_FORMAT_RGB565: case DRM_FORMAT_XVYU2101010: case DRM_FORMAT_C8: - case DRM_FORMAT_XBGR16161616F: - case DRM_FORMAT_ABGR16161616F: - case DRM_FORMAT_XRGB16161616F: - case DRM_FORMAT_ARGB16161616F: case DRM_FORMAT_Y210: case DRM_FORMAT_Y212: case DRM_FORMAT_Y216: From e6b72ba9c1ea4b5556027d502316a8362f1a9e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:44 +0300 Subject: [PATCH 203/205] drm/i915: Drop GEN12_MC_CCS check from skl_plane_max_width() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS is tgl+ only, so checking for it in skl_plane_max_width() (which only applies to pre-glk hardware) is pointless. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-7-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index ed0c9f565d72..7bf2eee87072 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -350,7 +350,6 @@ static int skl_plane_max_width(const struct drm_framebuffer *fb, return 5120; case I915_FORMAT_MOD_Y_TILED_CCS: case I915_FORMAT_MOD_Yf_TILED_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: /* FIXME AUX plane? */ case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Yf_TILED: From 87aaea1234af6bf96603f41b921aa281189bf02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 18 Sep 2024 17:44:45 +0300 Subject: [PATCH 204/205] drm/i915: s/gen12/tgl/ in the universal plane code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using "gen12" in display code is not desirable. Replace it with "tgl" to match how we talk about other platforms in the same code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240918144445.5716-8-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- .../gpu/drm/i915/display/skl_universal_plane.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 7bf2eee87072..9557b08ca2e2 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2383,8 +2383,8 @@ static bool icl_plane_format_mod_supported(struct drm_plane *_plane, } } -static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, - u32 format, u64 modifier) +static bool tgl_plane_format_mod_supported(struct drm_plane *_plane, + u32 format, u64 modifier) { struct intel_plane *plane = to_intel_plane(_plane); @@ -2453,13 +2453,13 @@ static const struct drm_plane_funcs icl_plane_funcs = { .format_mod_supported = icl_plane_format_mod_supported, }; -static const struct drm_plane_funcs gen12_plane_funcs = { +static const struct drm_plane_funcs tgl_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = intel_plane_destroy, .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, - .format_mod_supported = gen12_plane_format_mod_supported, + .format_mod_supported = tgl_plane_format_mod_supported, }; static void @@ -2501,8 +2501,8 @@ static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915, (plane_id == PLANE_1 || plane_id == PLANE_2); } -static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915, - enum plane_id plane_id) +static bool tgl_plane_has_mc_ccs(struct drm_i915_private *i915, + enum plane_id plane_id) { if (DISPLAY_VER(i915) < 12) return false; @@ -2540,7 +2540,7 @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915, caps |= INTEL_PLANE_CAP_CCS_RC_CC; } - if (gen12_plane_has_mc_ccs(i915, plane_id)) + if (tgl_plane_has_mc_ccs(i915, plane_id)) caps |= INTEL_PLANE_CAP_CCS_MC; if (DISPLAY_VER(i915) >= 14 && IS_DGFX(i915)) @@ -2631,7 +2631,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane_id, &num_formats); if (DISPLAY_VER(dev_priv) >= 12) - plane_funcs = &gen12_plane_funcs; + plane_funcs = &tgl_plane_funcs; else if (DISPLAY_VER(dev_priv) == 11) plane_funcs = &icl_plane_funcs; else From 388629a219ace83a09f8431a2e709c6c2efcf6ee Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane Date: Tue, 27 Aug 2024 19:43:56 +0530 Subject: [PATCH 205/205] drm/i915/mtl: Update PLL c20 phy value for DP uhbr20 Update mtl c20 phy DP table for uhbr20 values according to the revised specifications. Bspec: 74165 Signed-off-by: Dnyaneshwar Bhadane Reviewed-by: Sai Teja Pottumuttu Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20240827141356.3024760-1-dnyaneshwar.bhadane@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 4a6c3040ca15..f73d576fd99e 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -923,10 +923,10 @@ static const struct intel_c20pll_state mtl_c20_dp_uhbr20 = { }, .mplla = { 0x3104, /* mplla cfg0 */ 0xd105, /* mplla cfg1 */ - 0xc025, /* mplla cfg2 */ - 0xc025, /* mplla cfg3 */ - 0xa6ab, /* mplla cfg4 */ - 0x8c00, /* mplla cfg5 */ + 0x9217, /* mplla cfg2 */ + 0x9217, /* mplla cfg3 */ + 0x8c00, /* mplla cfg4 */ + 0x759a, /* mplla cfg5 */ 0x4000, /* mplla cfg6 */ 0x0003, /* mplla cfg7 */ 0x3555, /* mplla cfg8 */