* [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without DPRX caps
2026-03-05 8:18 [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Arun R Murthy
@ 2026-03-05 8:18 ` Arun R Murthy
2026-03-05 9:18 ` Jani Nikula
2026-03-05 16:29 ` Imre Deak
2026-03-05 8:18 ` [PATCH RFC 2/4] drm/i915/dp: Read LTTPR caps followed by " Arun R Murthy
` (3 subsequent siblings)
4 siblings, 2 replies; 14+ messages in thread
From: Arun R Murthy @ 2026-03-05 8:18 UTC (permalink / raw)
To: Imre Deak, Ville Syrjälä, Jani Nikula
Cc: dri-devel, intel-gfx, intel-xe, Arun R Murthy
We at present have drm_dp_Read_lttpr_common_caps to read the LTTPR caps,
but this function required DPRX caps to be passed. As per the DP2.1 spec
section 3.6.8.6.1, section 2.12.1, section 2.12.3 (Link Policy) the
LTTPR caps is to be read first followed by the DPRX capability.
Hence adding another function to read the LTTPR caps without the need
for DPRX caps.
In order to handle the issue
https://gitlab.freedesktop.org/drm/intel/-/issues/4531
of reading corrupted values for LTTPR caps on few pannels with DP Rev 1.2
the workaround of reducing the block size to 1 and reading one block at a
time is done by checking for a valid link rate.
Fixes: 657586e474bd ("drm/i915: Add a DP1.2 compatible way to read LTTPR capabilities")
Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
---
drivers/gpu/drm/display/drm_dp_helper.c | 63 +++++++++++++++++++++++++++++++++
include/drm/display/drm_dp_helper.h | 2 ++
2 files changed, 65 insertions(+)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index a697cc227e28964cd8322803298178e7d788e820..9fe7db73027a43b01c4d12927f1f0e61444658e5 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -3050,6 +3050,69 @@ static int drm_dp_read_lttpr_regs(struct drm_dp_aux *aux,
return 0;
}
+static bool drm_dp_valid_link_rate(u8 link_rate)
+{
+ switch (link_rate) {
+ case 0x06:
+ case 0x0a:
+ case 0x14:
+ case 0x1e:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * drm_dp_read_lttpr_caps - read the LTTPR capabilities
+ * @aux: DisplayPort AUX channel
+ * @caps: buffer to return the capability info in
+ *
+ * Read capabilities common to all LTTPRs.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
+ u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
+{
+ /*
+ * At least the DELL P2715Q monitor with a DPCD_REV < 0x14 returns
+ * corrupted values when reading from the 0xF0000- range with a block
+ * size bigger than 1.
+ * For DP as per the spec DP2.1 section 3.6.8.6.1, section 2.12.1, section
+ * 2.12.3 (Link Policy) the LTTPR caps is to be read first followed by the
+ * DPRX capability.
+ * So ideally we dont have DPCD_REV yet to check for the revision, instead
+ * check for the correctness of the read value and in found corrupted read
+ * block by block.
+ */
+ int block_size;
+ int offset;
+ int ret;
+ int address = DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV;
+ int buf_size = DP_LTTPR_COMMON_CAP_SIZE;
+
+ ret = drm_dp_dpcd_read_data(aux, address, &caps, buf_size);
+ if (ret < 0)
+ return ret;
+
+ if (caps[0] == 0x14) {
+ if (!drm_dp_valid_link_rate(caps[1])) {
+ block_size = 1;
+ for (offset = 0; offset < buf_size; offset += block_size) {
+ ret = drm_dp_dpcd_read_data(aux,
+ address + offset,
+ &caps[offset],
+ block_size);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_read_lttpr_caps);
+
/**
* drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities
* @aux: DisplayPort AUX channel
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index 1d0acd58f48676f60ff6a07cc6812f72cbb452e8..def145e67011c325b790c807f934b288304260c1 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -755,6 +755,8 @@ bool drm_dp_read_sink_count_cap(struct drm_connector *connector,
const struct drm_dp_desc *desc);
int drm_dp_read_sink_count(struct drm_dp_aux *aux);
+int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
+ u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
const u8 dpcd[DP_RECEIVER_CAP_SIZE],
u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without DPRX caps
2026-03-05 8:18 ` [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without " Arun R Murthy
@ 2026-03-05 9:18 ` Jani Nikula
2026-03-06 4:08 ` Murthy, Arun R
2026-03-05 16:29 ` Imre Deak
1 sibling, 1 reply; 14+ messages in thread
From: Jani Nikula @ 2026-03-05 9:18 UTC (permalink / raw)
To: Arun R Murthy, Imre Deak, Ville Syrjälä
Cc: dri-devel, intel-gfx, intel-xe, Arun R Murthy
On Thu, 05 Mar 2026, Arun R Murthy <arun.r.murthy@intel.com> wrote:
> We at present have drm_dp_Read_lttpr_common_caps to read the LTTPR caps,
> but this function required DPRX caps to be passed. As per the DP2.1 spec
> section 3.6.8.6.1, section 2.12.1, section 2.12.3 (Link Policy) the
> LTTPR caps is to be read first followed by the DPRX capability.
> Hence adding another function to read the LTTPR caps without the need
> for DPRX caps.
If the spec says something, why are we keeping the function that does it
the other way?
> In order to handle the issue
> https://gitlab.freedesktop.org/drm/intel/-/issues/4531
> of reading corrupted values for LTTPR caps on few pannels with DP Rev 1.2
> the workaround of reducing the block size to 1 and reading one block at a
> time is done by checking for a valid link rate.
>
> Fixes: 657586e474bd ("drm/i915: Add a DP1.2 compatible way to read LTTPR capabilities")
You're not calling the code being added here. This can't fix anything on
its own. This is not how the Fixes: tag works.
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
> drivers/gpu/drm/display/drm_dp_helper.c | 63 +++++++++++++++++++++++++++++++++
> include/drm/display/drm_dp_helper.h | 2 ++
> 2 files changed, 65 insertions(+)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
> index a697cc227e28964cd8322803298178e7d788e820..9fe7db73027a43b01c4d12927f1f0e61444658e5 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -3050,6 +3050,69 @@ static int drm_dp_read_lttpr_regs(struct drm_dp_aux *aux,
> return 0;
> }
>
> +static bool drm_dp_valid_link_rate(u8 link_rate)
> +{
> + switch (link_rate) {
> + case 0x06:
> + case 0x0a:
> + case 0x14:
> + case 0x1e:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> +/**
> + * drm_dp_read_lttpr_caps - read the LTTPR capabilities
> + * @aux: DisplayPort AUX channel
> + * @caps: buffer to return the capability info in
> + *
> + * Read capabilities common to all LTTPRs.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
> +{
> + /*
> + * At least the DELL P2715Q monitor with a DPCD_REV < 0x14 returns
> + * corrupted values when reading from the 0xF0000- range with a block
> + * size bigger than 1.
> + * For DP as per the spec DP2.1 section 3.6.8.6.1, section 2.12.1, section
> + * 2.12.3 (Link Policy) the LTTPR caps is to be read first followed by the
> + * DPRX capability.
> + * So ideally we dont have DPCD_REV yet to check for the revision, instead
> + * check for the correctness of the read value and in found corrupted read
> + * block by block.
> + */
> + int block_size;
> + int offset;
> + int ret;
> + int address = DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV;
> + int buf_size = DP_LTTPR_COMMON_CAP_SIZE;
> +
> + ret = drm_dp_dpcd_read_data(aux, address, &caps, buf_size);
> + if (ret < 0)
> + return ret;
> +
> + if (caps[0] == 0x14) {
> + if (!drm_dp_valid_link_rate(caps[1])) {
So you first read the whole thing once, and then in some cases read the
whole thing again one byte at a time?
Everything about this smells like a quirk for a specific display, not
something you do normally. We shouldn't have to have two ways to read
the lttpr caps in the normal case.
> + block_size = 1;
What's the point with the variable?
> + for (offset = 0; offset < buf_size; offset += block_size) {
> + ret = drm_dp_dpcd_read_data(aux,
> + address + offset,
> + &caps[offset],
> + block_size);
> + if (ret < 0)
> + return ret;
> + }
> + }
> + }
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_read_lttpr_caps);
> +
> /**
> * drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities
> * @aux: DisplayPort AUX channel
> diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
> index 1d0acd58f48676f60ff6a07cc6812f72cbb452e8..def145e67011c325b790c807f934b288304260c1 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -755,6 +755,8 @@ bool drm_dp_read_sink_count_cap(struct drm_connector *connector,
> const struct drm_dp_desc *desc);
> int drm_dp_read_sink_count(struct drm_dp_aux *aux);
>
> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
> int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
> const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without DPRX caps
2026-03-05 9:18 ` Jani Nikula
@ 2026-03-06 4:08 ` Murthy, Arun R
0 siblings, 0 replies; 14+ messages in thread
From: Murthy, Arun R @ 2026-03-06 4:08 UTC (permalink / raw)
To: Jani Nikula, Imre Deak, Ville Syrjälä
Cc: dri-devel, intel-gfx, intel-xe
On 05-03-2026 14:48, Jani Nikula wrote:
> On Thu, 05 Mar 2026, Arun R Murthy <arun.r.murthy@intel.com> wrote:
>> We at present have drm_dp_Read_lttpr_common_caps to read the LTTPR caps,
>> but this function required DPRX caps to be passed. As per the DP2.1 spec
>> section 3.6.8.6.1, section 2.12.1, section 2.12.3 (Link Policy) the
>> LTTPR caps is to be read first followed by the DPRX capability.
>> Hence adding another function to read the LTTPR caps without the need
>> for DPRX caps.
> If the spec says something, why are we keeping the function that does it
> the other way?
Sure will remove the other one!
>
>> In order to handle the issue
>> https://gitlab.freedesktop.org/drm/intel/-/issues/4531
>> of reading corrupted values for LTTPR caps on few pannels with DP Rev 1.2
>> the workaround of reducing the block size to 1 and reading one block at a
>> time is done by checking for a valid link rate.
>>
>> Fixes: 657586e474bd ("drm/i915: Add a DP1.2 compatible way to read LTTPR capabilities")
> You're not calling the code being added here. This can't fix anything on
> its own. This is not how the Fixes: tag works.
Got it, will remove the Fixes tag and just provide ref to this patch for
getting to know the issue.
>
>> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
>> ---
>> drivers/gpu/drm/display/drm_dp_helper.c | 63 +++++++++++++++++++++++++++++++++
>> include/drm/display/drm_dp_helper.h | 2 ++
>> 2 files changed, 65 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
>> index a697cc227e28964cd8322803298178e7d788e820..9fe7db73027a43b01c4d12927f1f0e61444658e5 100644
>> --- a/drivers/gpu/drm/display/drm_dp_helper.c
>> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
>> @@ -3050,6 +3050,69 @@ static int drm_dp_read_lttpr_regs(struct drm_dp_aux *aux,
>> return 0;
>> }
>>
>> +static bool drm_dp_valid_link_rate(u8 link_rate)
>> +{
>> + switch (link_rate) {
>> + case 0x06:
>> + case 0x0a:
>> + case 0x14:
>> + case 0x1e:
>> + return true;
>> + default:
>> + return false;
>> + }
>> +}
>> +
>> +/**
>> + * drm_dp_read_lttpr_caps - read the LTTPR capabilities
>> + * @aux: DisplayPort AUX channel
>> + * @caps: buffer to return the capability info in
>> + *
>> + * Read capabilities common to all LTTPRs.
>> + *
>> + * Returns 0 on success or a negative error code on failure.
>> + */
>> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
>> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
>> +{
>> + /*
>> + * At least the DELL P2715Q monitor with a DPCD_REV < 0x14 returns
>> + * corrupted values when reading from the 0xF0000- range with a block
>> + * size bigger than 1.
>> + * For DP as per the spec DP2.1 section 3.6.8.6.1, section 2.12.1, section
>> + * 2.12.3 (Link Policy) the LTTPR caps is to be read first followed by the
>> + * DPRX capability.
>> + * So ideally we dont have DPCD_REV yet to check for the revision, instead
>> + * check for the correctness of the read value and in found corrupted read
>> + * block by block.
>> + */
>> + int block_size;
>> + int offset;
>> + int ret;
>> + int address = DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV;
>> + int buf_size = DP_LTTPR_COMMON_CAP_SIZE;
>> +
>> + ret = drm_dp_dpcd_read_data(aux, address, &caps, buf_size);
>> + if (ret < 0)
>> + return ret;
>> +
>> + if (caps[0] == 0x14) {
>> + if (!drm_dp_valid_link_rate(caps[1])) {
> So you first read the whole thing once, and then in some cases read the
> whole thing again one byte at a time?
Yes, this was one option that I could think and the other option
mentioned in the cover letter, i.e read the lttpr caps, and then read
the dprx caps, now check if DPCD rev > 1.4 then re-read the lttpr 1
block at a time.
Another open would be do we need to address this issue and add a
workaround in the driver as the DP2.1 Spec says that LTTPR is supported
only from DPCD rev 1.4 onwards and in this case the workaround that we
are trying to add is for a DPCD rev 1.2 panel with LTTPR.
>
> Everything about this smells like a quirk for a specific display, not
> something you do normally. We shouldn't have to have two ways to read
> the lttpr caps in the normal case.
Agree adding this as a quirk makes the code straight as per the spec and
cleaner.
>> + block_size = 1;
> What's the point with the variable?
will replace with a magic value.
Thanks and Regards,
Arun R Murthy
-------------------
>
>> + for (offset = 0; offset < buf_size; offset += block_size) {
>> + ret = drm_dp_dpcd_read_data(aux,
>> + address + offset,
>> + &caps[offset],
>> + block_size);
>> + if (ret < 0)
>> + return ret;
>> + }
>> + }
>> + }
>> + return 0;
>> +}
>> +EXPORT_SYMBOL(drm_dp_read_lttpr_caps);
>> +
>> /**
>> * drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities
>> * @aux: DisplayPort AUX channel
>> diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
>> index 1d0acd58f48676f60ff6a07cc6812f72cbb452e8..def145e67011c325b790c807f934b288304260c1 100644
>> --- a/include/drm/display/drm_dp_helper.h
>> +++ b/include/drm/display/drm_dp_helper.h
>> @@ -755,6 +755,8 @@ bool drm_dp_read_sink_count_cap(struct drm_connector *connector,
>> const struct drm_dp_desc *desc);
>> int drm_dp_read_sink_count(struct drm_dp_aux *aux);
>>
>> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
>> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
>> int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
>> const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>> u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without DPRX caps
2026-03-05 8:18 ` [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without " Arun R Murthy
2026-03-05 9:18 ` Jani Nikula
@ 2026-03-05 16:29 ` Imre Deak
2026-03-06 4:10 ` Murthy, Arun R
1 sibling, 1 reply; 14+ messages in thread
From: Imre Deak @ 2026-03-05 16:29 UTC (permalink / raw)
To: Arun R Murthy
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
On Thu, Mar 05, 2026 at 01:48:11PM +0530, Arun R Murthy wrote:
> We at present have drm_dp_Read_lttpr_common_caps to read the LTTPR caps,
> but this function required DPRX caps to be passed. As per the DP2.1 spec
> section 3.6.8.6.1, section 2.12.1, section 2.12.3 (Link Policy) the
> LTTPR caps is to be read first followed by the DPRX capability.
> Hence adding another function to read the LTTPR caps without the need
> for DPRX caps.
>
> In order to handle the issue
> https://gitlab.freedesktop.org/drm/intel/-/issues/4531
> of reading corrupted values for LTTPR caps on few pannels with DP Rev 1.2
> the workaround of reducing the block size to 1 and reading one block at a
> time is done by checking for a valid link rate.
>
> Fixes: 657586e474bd ("drm/i915: Add a DP1.2 compatible way to read LTTPR capabilities")
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
> drivers/gpu/drm/display/drm_dp_helper.c | 63 +++++++++++++++++++++++++++++++++
> include/drm/display/drm_dp_helper.h | 2 ++
> 2 files changed, 65 insertions(+)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
> index a697cc227e28964cd8322803298178e7d788e820..9fe7db73027a43b01c4d12927f1f0e61444658e5 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -3050,6 +3050,69 @@ static int drm_dp_read_lttpr_regs(struct drm_dp_aux *aux,
> return 0;
> }
>
> +static bool drm_dp_valid_link_rate(u8 link_rate)
> +{
> + switch (link_rate) {
> + case 0x06:
> + case 0x0a:
> + case 0x14:
> + case 0x1e:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> +/**
> + * drm_dp_read_lttpr_caps - read the LTTPR capabilities
> + * @aux: DisplayPort AUX channel
> + * @caps: buffer to return the capability info in
> + *
> + * Read capabilities common to all LTTPRs.
> + *
> + * Returns 0 on success or a negative error code on failure.
> + */
> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
> +{
> + /*
> + * At least the DELL P2715Q monitor with a DPCD_REV < 0x14 returns
> + * corrupted values when reading from the 0xF0000- range with a block
> + * size bigger than 1.
> + * For DP as per the spec DP2.1 section 3.6.8.6.1, section 2.12.1, section
> + * 2.12.3 (Link Policy) the LTTPR caps is to be read first followed by the
> + * DPRX capability.
> + * So ideally we dont have DPCD_REV yet to check for the revision, instead
> + * check for the correctness of the read value and in found corrupted read
> + * block by block.
> + */
> + int block_size;
> + int offset;
> + int ret;
> + int address = DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV;
> + int buf_size = DP_LTTPR_COMMON_CAP_SIZE;
> +
> + ret = drm_dp_dpcd_read_data(aux, address, &caps, buf_size);
> + if (ret < 0)
> + return ret;
> +
> + if (caps[0] == 0x14) {
> + if (!drm_dp_valid_link_rate(caps[1])) {
I don't think the code can depend on what will be in caps[1] (i.e.
DP_MAX_LINK_RATE_PHY_REPEATER / 0xF0001) after the monitor returned a
corrupted value when reading this register. That is the code cannot
depend on this register value being a valid link rate encoding or
some other value.
> + block_size = 1;
> + for (offset = 0; offset < buf_size; offset += block_size) {
> + ret = drm_dp_dpcd_read_data(aux,
> + address + offset,
> + &caps[offset],
> + block_size);
> + if (ret < 0)
> + return ret;
> + }
> + }
> + }
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_dp_read_lttpr_caps);
> +
> /**
> * drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities
> * @aux: DisplayPort AUX channel
> diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
> index 1d0acd58f48676f60ff6a07cc6812f72cbb452e8..def145e67011c325b790c807f934b288304260c1 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -755,6 +755,8 @@ bool drm_dp_read_sink_count_cap(struct drm_connector *connector,
> const struct drm_dp_desc *desc);
> int drm_dp_read_sink_count(struct drm_dp_aux *aux);
>
> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
> int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
> const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without DPRX caps
2026-03-05 16:29 ` Imre Deak
@ 2026-03-06 4:10 ` Murthy, Arun R
0 siblings, 0 replies; 14+ messages in thread
From: Murthy, Arun R @ 2026-03-06 4:10 UTC (permalink / raw)
To: imre.deak
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
On 05-03-2026 21:59, Imre Deak wrote:
> On Thu, Mar 05, 2026 at 01:48:11PM +0530, Arun R Murthy wrote:
>> We at present have drm_dp_Read_lttpr_common_caps to read the LTTPR caps,
>> but this function required DPRX caps to be passed. As per the DP2.1 spec
>> section 3.6.8.6.1, section 2.12.1, section 2.12.3 (Link Policy) the
>> LTTPR caps is to be read first followed by the DPRX capability.
>> Hence adding another function to read the LTTPR caps without the need
>> for DPRX caps.
>>
>> In order to handle the issue
>> https://gitlab.freedesktop.org/drm/intel/-/issues/4531
>> of reading corrupted values for LTTPR caps on few pannels with DP Rev 1.2
>> the workaround of reducing the block size to 1 and reading one block at a
>> time is done by checking for a valid link rate.
>>
>> Fixes: 657586e474bd ("drm/i915: Add a DP1.2 compatible way to read LTTPR capabilities")
>> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
>> ---
>> drivers/gpu/drm/display/drm_dp_helper.c | 63 +++++++++++++++++++++++++++++++++
>> include/drm/display/drm_dp_helper.h | 2 ++
>> 2 files changed, 65 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
>> index a697cc227e28964cd8322803298178e7d788e820..9fe7db73027a43b01c4d12927f1f0e61444658e5 100644
>> --- a/drivers/gpu/drm/display/drm_dp_helper.c
>> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
>> @@ -3050,6 +3050,69 @@ static int drm_dp_read_lttpr_regs(struct drm_dp_aux *aux,
>> return 0;
>> }
>>
>> +static bool drm_dp_valid_link_rate(u8 link_rate)
>> +{
>> + switch (link_rate) {
>> + case 0x06:
>> + case 0x0a:
>> + case 0x14:
>> + case 0x1e:
>> + return true;
>> + default:
>> + return false;
>> + }
>> +}
>> +
>> +/**
>> + * drm_dp_read_lttpr_caps - read the LTTPR capabilities
>> + * @aux: DisplayPort AUX channel
>> + * @caps: buffer to return the capability info in
>> + *
>> + * Read capabilities common to all LTTPRs.
>> + *
>> + * Returns 0 on success or a negative error code on failure.
>> + */
>> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
>> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
>> +{
>> + /*
>> + * At least the DELL P2715Q monitor with a DPCD_REV < 0x14 returns
>> + * corrupted values when reading from the 0xF0000- range with a block
>> + * size bigger than 1.
>> + * For DP as per the spec DP2.1 section 3.6.8.6.1, section 2.12.1, section
>> + * 2.12.3 (Link Policy) the LTTPR caps is to be read first followed by the
>> + * DPRX capability.
>> + * So ideally we dont have DPCD_REV yet to check for the revision, instead
>> + * check for the correctness of the read value and in found corrupted read
>> + * block by block.
>> + */
>> + int block_size;
>> + int offset;
>> + int ret;
>> + int address = DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV;
>> + int buf_size = DP_LTTPR_COMMON_CAP_SIZE;
>> +
>> + ret = drm_dp_dpcd_read_data(aux, address, &caps, buf_size);
>> + if (ret < 0)
>> + return ret;
>> +
>> + if (caps[0] == 0x14) {
>> + if (!drm_dp_valid_link_rate(caps[1])) {
> I don't think the code can depend on what will be in caps[1] (i.e.
> DP_MAX_LINK_RATE_PHY_REPEATER / 0xF0001) after the monitor returned a
> corrupted value when reading this register. That is the code cannot
> depend on this register value being a valid link rate encoding or
> some other value.
I have mentioned another option as well in the cover letter, i.e read
the lttpr caps and then the dprx caps. Now check the DPCD rev and if <
1.4 re-read the lttpr caps one block at a time.
Thanks and Regards,
Arun R Murthy
------------------
>> + block_size = 1;
>> + for (offset = 0; offset < buf_size; offset += block_size) {
>> + ret = drm_dp_dpcd_read_data(aux,
>> + address + offset,
>> + &caps[offset],
>> + block_size);
>> + if (ret < 0)
>> + return ret;
>> + }
>> + }
>> + }
>> + return 0;
>> +}
>> +EXPORT_SYMBOL(drm_dp_read_lttpr_caps);
>> +
>> /**
>> * drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities
>> * @aux: DisplayPort AUX channel
>> diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
>> index 1d0acd58f48676f60ff6a07cc6812f72cbb452e8..def145e67011c325b790c807f934b288304260c1 100644
>> --- a/include/drm/display/drm_dp_helper.h
>> +++ b/include/drm/display/drm_dp_helper.h
>> @@ -755,6 +755,8 @@ bool drm_dp_read_sink_count_cap(struct drm_connector *connector,
>> const struct drm_dp_desc *desc);
>> int drm_dp_read_sink_count(struct drm_dp_aux *aux);
>>
>> +int drm_dp_read_lttpr_caps(struct drm_dp_aux *aux,
>> + u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
>> int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
>> const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>> u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
>>
>> --
>> 2.25.1
>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH RFC 2/4] drm/i915/dp: Read LTTPR caps followed by DPRX caps
2026-03-05 8:18 [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Arun R Murthy
2026-03-05 8:18 ` [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without " Arun R Murthy
@ 2026-03-05 8:18 ` Arun R Murthy
2026-03-05 8:18 ` [PATCH RFC 3/4] drm/i915/dp: On HPD read " Arun R Murthy
` (2 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Arun R Murthy @ 2026-03-05 8:18 UTC (permalink / raw)
To: Imre Deak, Ville Syrjälä, Jani Nikula
Cc: dri-devel, intel-gfx, intel-xe, Arun R Murthy
As per the DP spec DP2.1 section 3.6.8.6.1, section 2.12.1,
section 2.12.3 (Link Policy) the LTTPR caps is to be read first followed
by the DPRX capability.
Read the LTTPR capabilities followed by the DPRX capabilities and then
the ULP capabilities.
Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
---
.../gpu/drm/i915/display/intel_dp_link_training.c | 35 ++++++++++------------
1 file changed, 15 insertions(+), 20 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 54c585c59b900eb3c480502d89736fefa111eba4..68ab938f18f3b6f3c889f408cd1901041834fe82 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -93,13 +93,11 @@ static void intel_dp_read_lttpr_phy_caps(struct intel_dp *intel_dp,
phy_caps);
}
-static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp,
- const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp)
{
int ret;
- ret = drm_dp_read_lttpr_common_caps(&intel_dp->aux, dpcd,
- intel_dp->lttpr_common_caps);
+ ret = drm_dp_read_lttpr_caps(&intel_dp->aux, intel_dp->lttpr_common_caps);
if (ret < 0)
goto reset_caps;
@@ -145,12 +143,12 @@ bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
* Return the number of detected LTTPRs in non-transparent mode or 0 if the
* LTTPRs are in transparent mode or the detection failed.
*/
-static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+static int intel_dp_init_lttpr(struct intel_dp *intel_dp)
{
int lttpr_count;
int ret;
- if (!intel_dp_read_lttpr_common_caps(intel_dp, dpcd))
+ if (!intel_dp_read_lttpr_common_caps(intel_dp))
return 0;
lttpr_count = drm_dp_lttpr_count(intel_dp->lttpr_common_caps);
@@ -195,19 +193,16 @@ static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_
return 0;
}
-static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, int lttpr_count)
{
- int lttpr_count;
int i;
- lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd);
-
for (i = 0; i < lttpr_count; i++) {
- intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i));
+ intel_dp_read_lttpr_phy_caps(intel_dp, intel_dp->dpcd, DP_PHY_LTTPR(i));
drm_dp_dump_lttpr_desc(&intel_dp->aux, DP_PHY_LTTPR(i));
}
- return lttpr_count;
+ return 0;
}
int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE])
@@ -261,23 +256,23 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
*/
if (!intel_dp_is_edp(intel_dp) &&
(DISPLAY_VER(display) >= 10 && !display->platform.geminilake)) {
- u8 dpcd[DP_RECEIVER_CAP_SIZE];
- int err = intel_dp_read_dprx_caps(intel_dp, dpcd);
-
- if (err != 0)
- return err;
-
- lttpr_count = intel_dp_init_lttpr(intel_dp, dpcd);
+ /*
+ * Spec DP2.1 section 3.6.8.6.1, section 2.12.1, section 2.12.3
+ * (Link Policy) the LTTPR caps is to be read first followed by
+ * the DPRX capability
+ */
+ lttpr_count = intel_dp_init_lttpr(intel_dp);
}
/*
* The DPTX shall read the DPRX caps after LTTPR detection, so re-read
* it here.
*/
- if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) {
+ if (intel_dp_read_dprx_caps(intel_dp, intel_dp->dpcd)) {
intel_dp_reset_lttpr_common_caps(intel_dp);
return -EIO;
}
+ intel_dp_init_lttpr_phys(intel_dp, lttpr_count);
return lttpr_count;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH RFC 3/4] drm/i915/dp: On HPD read LTTPR caps followed by DPRX caps
2026-03-05 8:18 [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Arun R Murthy
2026-03-05 8:18 ` [PATCH RFC 1/4] drm/display/dp: Read LTTPR caps without " Arun R Murthy
2026-03-05 8:18 ` [PATCH RFC 2/4] drm/i915/dp: Read LTTPR caps followed by " Arun R Murthy
@ 2026-03-05 8:18 ` Arun R Murthy
2026-03-05 8:18 ` [PATCH RFC 4/4] drm/i915/dp: DPRX/LTTPR caps for DP should be read once Arun R Murthy
2026-03-05 16:11 ` [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Imre Deak
4 siblings, 0 replies; 14+ messages in thread
From: Arun R Murthy @ 2026-03-05 8:18 UTC (permalink / raw)
To: Imre Deak, Ville Syrjälä, Jani Nikula
Cc: dri-devel, intel-gfx, intel-xe, Arun R Murthy
On HPD for DP read LTTPR caps and then read the DPRX caps. Dont directly
read the DPRX caps at first as per Spec DP2.1 Sec 3.6.8.1
Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
---
drivers/gpu/drm/i915/display/intel_dp.c | 3 +--
drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 +-
drivers/gpu/drm/i915/display/intel_dp_link_training.h | 1 -
drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 3 +--
4 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 0c03b6fb6fd82b0b010fe5f7591ce5e0d8d2d04c..956099e90b32aae5ae21d472ab5dc9dd7d110f60 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6811,7 +6811,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
{
struct intel_display *display = to_intel_display(dig_port);
struct intel_dp *intel_dp = &dig_port->dp;
- u8 dpcd[DP_RECEIVER_CAP_SIZE];
if (dig_port->base.type == INTEL_OUTPUT_EDP &&
(long_hpd ||
@@ -6847,7 +6846,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
if (long_hpd) {
intel_dp_dpcd_set_probe(intel_dp, true);
- intel_dp_read_dprx_caps(intel_dp, dpcd);
+ intel_dp_init_lttpr_and_dprx_caps(intel_dp);
intel_dp->reset_link_params = true;
intel_dp_invalidate_source_oui(intel_dp);
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 68ab938f18f3b6f3c889f408cd1901041834fe82..76a5bfb507c34733db09cd7c2ba9895afcbf6b10 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -205,7 +205,7 @@ static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, int lttpr_count)
return 0;
}
-int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE])
+static int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
struct intel_display *display = to_intel_display(intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 1ba22ed6db087b73d2ec479c6f31104e97243061..d5f35637b7f375bdc7bdd01c25137fb9f0de37dc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -13,7 +13,6 @@ struct intel_connector;
struct intel_crtc_state;
struct intel_dp;
-int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE]);
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
index 1fd1ac8d556d84bd794b965ba6f513ee4550f060..6fe9ff757f264a1064ca3e77e4a2bb8c1228214a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c
@@ -337,7 +337,6 @@ void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
struct intel_display *display = to_intel_display(intel_dp);
struct intel_connector *connector = intel_dp->attached_connector;
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
- u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 pipe_mask;
int err = 0;
@@ -360,7 +359,7 @@ void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
* capabilities were updated already during resume.
*/
if (!dpcd_updated) {
- err = intel_dp_read_dprx_caps(intel_dp, dpcd);
+ err = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
if (err) {
drm_dp_tunnel_set_io_error(intel_dp->tunnel);
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH RFC 4/4] drm/i915/dp: DPRX/LTTPR caps for DP should be read once
2026-03-05 8:18 [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Arun R Murthy
` (2 preceding siblings ...)
2026-03-05 8:18 ` [PATCH RFC 3/4] drm/i915/dp: On HPD read " Arun R Murthy
@ 2026-03-05 8:18 ` Arun R Murthy
2026-03-05 16:11 ` [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Imre Deak
4 siblings, 0 replies; 14+ messages in thread
From: Arun R Murthy @ 2026-03-05 8:18 UTC (permalink / raw)
To: Imre Deak, Ville Syrjälä, Jani Nikula
Cc: dri-devel, intel-gfx, intel-xe, Arun R Murthy
The DPRX/LTTPR caps for DP is read on detect and should be read only
once. This value is stored in intl_dp struct and will be retained until
hotplug.
Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
---
drivers/gpu/drm/i915/display/intel_dp_link_training.c | 3 +++
1 file changed, 3 insertions(+)
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 76a5bfb507c34733db09cd7c2ba9895afcbf6b10..b78fc69cf21dea630313a5c93ff4bd3670f32293 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -250,6 +250,9 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
struct intel_display *display = to_intel_display(intel_dp);
int lttpr_count = 0;
+ /* this function is meant to be called only once */
+ drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
+
/*
* Detecting LTTPRs must be avoided on platforms with an AUX timeout
* period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1).
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps
2026-03-05 8:18 [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Arun R Murthy
` (3 preceding siblings ...)
2026-03-05 8:18 ` [PATCH RFC 4/4] drm/i915/dp: DPRX/LTTPR caps for DP should be read once Arun R Murthy
@ 2026-03-05 16:11 ` Imre Deak
2026-03-06 4:29 ` Murthy, Arun R
2026-03-06 4:29 ` Murthy, Arun R
4 siblings, 2 replies; 14+ messages in thread
From: Imre Deak @ 2026-03-05 16:11 UTC (permalink / raw)
To: Arun R Murthy
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
On Thu, Mar 05, 2026 at 01:48:10PM +0530, Arun R Murthy wrote:
> As per the spec DP2.1 section 3.6.8.6.1, section 2.12.1,
> section 2.12.3 (Link Policy) the LTTPR caps is to be read first
> followed by the DPRX capability.
Not exactly. The Standard requires reading the DPRX capabilities after
the LTTPR caps are read. The driver does read the DPRX caps after
reading the LTTPR caps. The DP Standard does not mandate that the first
read after a sink is connected (i.e. after the HPD signal of the sink is
asserted) must be an LTTPR capability read and cannot be any other DPCD
register read. In fact this would be impossible to guarantee, a DPRX
capability read - or any DPCD register read for that matter - could
happen at any point and so it could happen right after the HPD signal
got asserted.
> Git log shows that initially drm dp helper exposed function to read
> lttpr caps. Driver reads the lttpr caps and then the dprx caps.
> For a particular issue
> https://gitlab.freedesktop.org/drm/intel/-/issues/3415
> as a workaround reading dprx caps was done first to know if the panel is
> < DP1.4 and then read 1 block at a time for lttpr caps.
>
> This can be handled in a better way and two such ways is what I see.
> 1. Read LTTPR caps followed by DPRX caps as per the spec. Then on
> reading dprx caps if revision < 1.4 then re-read the lttpr caps one
> block at a time.
>
> 2. Read LTTPR caps and if 8b/10b check for correctness of the link rate
> supported(lttpr caps 0xf0001), if some corrupted value is read then read
> one block at a time.
The driver does read the DPRX capabilities after reading the LTTPR
capabilities. This is what the standard mandates.
The workaround for issues/3415 depends on the DPCD_REV value, so this is
read separately before reading the LTTPR caps. I don't see a better way
to implement the workaround and such read is not prohibited by the DP
Standard either. So I don't see the point of the changes in this
patchset.
> I am open for either of the two or you have any other options as well I
> am open.
>
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
> Arun R Murthy (4):
> drm/display/dp: Read LTTPR caps without DPRX caps
> drm/i915/dp: Read LTTPR caps followed by DPRX caps
> drm/i915/dp: On HPD read LTTPR caps followed by DPRX caps
> drm/i915/dp: DPRX/LTTPR caps for DP should be read once
>
> drivers/gpu/drm/display/drm_dp_helper.c | 63 ++++++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
> .../gpu/drm/i915/display/intel_dp_link_training.c | 40 +++++++-------
> .../gpu/drm/i915/display/intel_dp_link_training.h | 1 -
> drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 3 +-
> include/drm/display/drm_dp_helper.h | 2 +
> 6 files changed, 86 insertions(+), 26 deletions(-)
> ---
> base-commit: cfc20c776480fda8c1b0517b187bb71ec0781cd4
> change-id: 20260305-dp_aux-1e27599e06c8
>
> Best regards,
> --
> Arun R Murthy <arun.r.murthy@intel.com>
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps
2026-03-05 16:11 ` [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Imre Deak
@ 2026-03-06 4:29 ` Murthy, Arun R
2026-03-06 9:46 ` Imre Deak
2026-03-06 4:29 ` Murthy, Arun R
1 sibling, 1 reply; 14+ messages in thread
From: Murthy, Arun R @ 2026-03-06 4:29 UTC (permalink / raw)
To: imre.deak
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
On 05-03-2026 21:41, Imre Deak wrote:
> On Thu, Mar 05, 2026 at 01:48:10PM +0530, Arun R Murthy wrote:
>> As per the spec DP2.1 section 3.6.8.6.1, section 2.12.1,
>> section 2.12.3 (Link Policy) the LTTPR caps is to be read first
>> followed by the DPRX capability.
> Not exactly. The Standard requires reading the DPRX capabilities after
> the LTTPR caps are read.
I also mean the same, sorry if my wordings were complex.
> The driver does read the DPRX caps after
> reading the LTTPR caps.
In intel_dp_link_training.c function intel_dp_init_lttpr_and_dprx_caps()
int err = intel_dp_read_dprx_caps()
if (err != 0)
return err;
lttpr_count = intel_dp_init_lttpr()
Here we are reading dprx caps and then passing this dprx caps to the the
func intel_dp_init_lttpr(). I think this will be a deviation of the spec.
> The DP Standard does not mandate that the first
> read after a sink is connected (i.e. after the HPD signal of the sink is
> asserted) must be an LTTPR capability read and cannot be any other DPCD
> register read. In fact this would be impossible to guarantee, a DPRX
> capability read - or any DPCD register read for that matter - could
> happen at any point and so it could happen right after the HPD signal
> got asserted.
Spec DP2.1 Section 3.6.8.6.1 LTTPR Recognition
After HPD is propagated from the DPRX to the DPTX, a DP Source device
with a DPTX shall
read specific registers within the DPCD LTTPR Capability and ID Field
(DPCD F0000h through
F0009h; see Section 3.6.5)
After LTTPR recognition, a DP Source device with a DPTX shall read the
DP Sink device with
a DPRX’s capability by reading the DisplayID or legacy EDID and the
DPRX’s Receiver
Capability field (DPCD 00000h through 000FFh; see Table 2-232).
>> Git log shows that initially drm dp helper exposed function to read
>> lttpr caps. Driver reads the lttpr caps and then the dprx caps.
>> For a particular issue
>> https://gitlab.freedesktop.org/drm/intel/-/issues/3415
>> as a workaround reading dprx caps was done first to know if the panel is
>> < DP1.4 and then read 1 block at a time for lttpr caps.
>>
>> This can be handled in a better way and two such ways is what I see.
>> 1. Read LTTPR caps followed by DPRX caps as per the spec. Then on
>> reading dprx caps if revision < 1.4 then re-read the lttpr caps one
>> block at a time.
>>
>> 2. Read LTTPR caps and if 8b/10b check for correctness of the link rate
>> supported(lttpr caps 0xf0001), if some corrupted value is read then read
>> one block at a time.
> The driver does read the DPRX capabilities after reading the LTTPR
> capabilities. This is what the standard mandates.
Yes but before reading the LTTPR capabilities also DPRX capabilities is
read. Have added ref to the code snipped above.
Please let me know if my understanding is wrong.
>
> The workaround for issues/3415 depends on the DPCD_REV value, so this is
> read separately before reading the LTTPR caps. I don't see a better way
> to implement the workaround and such read is not prohibited by the DP
> Standard either. So I don't see the point of the changes in this
> patchset.
As Jani pointed this can be added as a quirk for that particular panel
instead of mandating this kind of reading dprx caps first and then
reading the lttpr caps for all the monitors.
Thanks and Regards,
Arun R Murthy
-------------------
>
>> I am open for either of the two or you have any other options as well I
>> am open.
>>
>> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
>> ---
>> Arun R Murthy (4):
>> drm/display/dp: Read LTTPR caps without DPRX caps
>> drm/i915/dp: Read LTTPR caps followed by DPRX caps
>> drm/i915/dp: On HPD read LTTPR caps followed by DPRX caps
>> drm/i915/dp: DPRX/LTTPR caps for DP should be read once
>>
>> drivers/gpu/drm/display/drm_dp_helper.c | 63 ++++++++++++++++++++++
>> drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
>> .../gpu/drm/i915/display/intel_dp_link_training.c | 40 +++++++-------
>> .../gpu/drm/i915/display/intel_dp_link_training.h | 1 -
>> drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 3 +-
>> include/drm/display/drm_dp_helper.h | 2 +
>> 6 files changed, 86 insertions(+), 26 deletions(-)
>> ---
>> base-commit: cfc20c776480fda8c1b0517b187bb71ec0781cd4
>> change-id: 20260305-dp_aux-1e27599e06c8
>>
>> Best regards,
>> --
>> Arun R Murthy <arun.r.murthy@intel.com>
>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps
2026-03-06 4:29 ` Murthy, Arun R
@ 2026-03-06 9:46 ` Imre Deak
2026-03-10 8:58 ` Murthy, Arun R
0 siblings, 1 reply; 14+ messages in thread
From: Imre Deak @ 2026-03-06 9:46 UTC (permalink / raw)
To: Murthy, Arun R
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
On Fri, Mar 06, 2026 at 09:59:10AM +0530, Murthy, Arun R wrote:
>
> On 05-03-2026 21:41, Imre Deak wrote:
> > On Thu, Mar 05, 2026 at 01:48:10PM +0530, Arun R Murthy wrote:
> > > As per the spec DP2.1 section 3.6.8.6.1, section 2.12.1,
> > > section 2.12.3 (Link Policy) the LTTPR caps is to be read first
> > > followed by the DPRX capability.
> > Not exactly. The Standard requires reading the DPRX capabilities after
> > the LTTPR caps are read.
>
> I also mean the same, sorry if my wordings were complex.
>
> > The driver does read the DPRX caps after
> > reading the LTTPR caps.
>
> In intel_dp_link_training.c function intel_dp_init_lttpr_and_dprx_caps()
>
> int err = intel_dp_read_dprx_caps()
> if (err != 0)
> return err;
> lttpr_count = intel_dp_init_lttpr()
>
> Here we are reading dprx caps and then passing this dprx caps to the the
> func intel_dp_init_lttpr(). I think this will be a deviation of the spec.
No, it's not a deviation of the spec, because the spec does not forbid
reading the DPCD_REV or other DPCD registers before reading the LTTPR
capability registers and it cannot really forbid this as I explained.
What the spec requires is reading the DPRX capabilities after the LTTPR
capabilities were read out, which the driver does: after the above lines
there is also:
/*
* The DPTX shall read the DPRX caps after LTTPR detection, so re-read
* it here.
*/
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) ...
> > The DP Standard does not mandate that the first read after a sink is
> > connected (i.e. after the HPD signal of the sink is asserted) must
> > be an LTTPR capability read and cannot be any other DPCD register
> > read. In fact this would be impossible to guarantee, a DPRX
> > capability read - or any DPCD register read for that matter - could
> > happen at any point and so it could happen right after the HPD
> > signal got asserted.
>
> Spec DP2.1 Section 3.6.8.6.1 LTTPR Recognition After HPD is propagated
> from the DPRX to the DPTX, a DP Source device with a DPTX shall read
> specific registers within the DPCD LTTPR Capability and ID Field (DPCD
> F0000h through F0009h; see Section 3.6.5) After LTTPR recognition, a
> DP Source device with a DPTX shall read the DP Sink device with a
> DPRX’s capability by reading the DisplayID or legacy EDID and the
> DPRX’s Receiver Capability field (DPCD 00000h through 000FFh; see
> Table 2-232).
The above does not prohibit reading non-LTTPR DPCD registers before
reading F0000h - F0009h, and it cannot forbid this as explained above.
> > > Git log shows that initially drm dp helper exposed function to read
> > > lttpr caps. Driver reads the lttpr caps and then the dprx caps.
> > > For a particular issue
> > > https://gitlab.freedesktop.org/drm/intel/-/issues/3415
> > > as a workaround reading dprx caps was done first to know if the panel is
> > > < DP1.4 and then read 1 block at a time for lttpr caps.
> > >
> > > This can be handled in a better way and two such ways is what I see.
> > > 1. Read LTTPR caps followed by DPRX caps as per the spec. Then on
> > > reading dprx caps if revision < 1.4 then re-read the lttpr caps one
> > > block at a time.
> > >
> > > 2. Read LTTPR caps and if 8b/10b check for correctness of the link rate
> > > supported(lttpr caps 0xf0001), if some corrupted value is read then read
> > > one block at a time.
>
> > The driver does read the DPRX capabilities after reading the LTTPR
> > capabilities. This is what the standard mandates.
>
> Yes but before reading the LTTPR capabilities also DPRX capabilities is
> read. Have added ref to the code snipped above.
This is not forbidden by the specification.
> Please let me know if my understanding is wrong.
>
> > The workaround for issues/3415 depends on the DPCD_REV value, so this is
> > read separately before reading the LTTPR caps. I don't see a better way
> > to implement the workaround and such read is not prohibited by the DP
> > Standard either. So I don't see the point of the changes in this
> > patchset.
>
> As Jani pointed this can be added as a quirk for that particular panel
> instead of mandating this kind of reading dprx caps first and then reading
> the lttpr caps for all the monitors.
There is already a quirk in the driver - to read out the LTTPR
capabilities 1 byte at a time - and the quirk is applied based on the
DPCD_REV register value of the monitor.
> Thanks and Regards,
> Arun R Murthy
> -------------------
>
> >
> > > I am open for either of the two or you have any other options as well I
> > > am open.
> > >
> > > Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> > > ---
> > > Arun R Murthy (4):
> > > drm/display/dp: Read LTTPR caps without DPRX caps
> > > drm/i915/dp: Read LTTPR caps followed by DPRX caps
> > > drm/i915/dp: On HPD read LTTPR caps followed by DPRX caps
> > > drm/i915/dp: DPRX/LTTPR caps for DP should be read once
> > >
> > > drivers/gpu/drm/display/drm_dp_helper.c | 63 ++++++++++++++++++++++
> > > drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
> > > .../gpu/drm/i915/display/intel_dp_link_training.c | 40 +++++++-------
> > > .../gpu/drm/i915/display/intel_dp_link_training.h | 1 -
> > > drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 3 +-
> > > include/drm/display/drm_dp_helper.h | 2 +
> > > 6 files changed, 86 insertions(+), 26 deletions(-)
> > > ---
> > > base-commit: cfc20c776480fda8c1b0517b187bb71ec0781cd4
> > > change-id: 20260305-dp_aux-1e27599e06c8
> > >
> > > Best regards,
> > > --
> > > Arun R Murthy <arun.r.murthy@intel.com>
> > >
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps
2026-03-06 9:46 ` Imre Deak
@ 2026-03-10 8:58 ` Murthy, Arun R
0 siblings, 0 replies; 14+ messages in thread
From: Murthy, Arun R @ 2026-03-10 8:58 UTC (permalink / raw)
To: imre.deak
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
I understand that with race conditions from user get_connector it still
cannot guarantee that lttpr caps are read first, dropping this patch for
now!
Thanks and Regards,
Arun R Murthy
-------------------
On 06-03-2026 15:16, Imre Deak wrote:
> On Fri, Mar 06, 2026 at 09:59:10AM +0530, Murthy, Arun R wrote:
>> On 05-03-2026 21:41, Imre Deak wrote:
>>> On Thu, Mar 05, 2026 at 01:48:10PM +0530, Arun R Murthy wrote:
>>>> As per the spec DP2.1 section 3.6.8.6.1, section 2.12.1,
>>>> section 2.12.3 (Link Policy) the LTTPR caps is to be read first
>>>> followed by the DPRX capability.
>>> Not exactly. The Standard requires reading the DPRX capabilities after
>>> the LTTPR caps are read.
>> I also mean the same, sorry if my wordings were complex.
>>
>>> The driver does read the DPRX caps after
>>> reading the LTTPR caps.
>> In intel_dp_link_training.c function intel_dp_init_lttpr_and_dprx_caps()
>>
>> int err = intel_dp_read_dprx_caps()
>> if (err != 0)
>> return err;
>> lttpr_count = intel_dp_init_lttpr()
>>
>> Here we are reading dprx caps and then passing this dprx caps to the the
>> func intel_dp_init_lttpr(). I think this will be a deviation of the spec.
> No, it's not a deviation of the spec, because the spec does not forbid
> reading the DPCD_REV or other DPCD registers before reading the LTTPR
> capability registers and it cannot really forbid this as I explained.
>
> What the spec requires is reading the DPRX capabilities after the LTTPR
> capabilities were read out, which the driver does: after the above lines
> there is also:
>
> /*
> * The DPTX shall read the DPRX caps after LTTPR detection, so re-read
> * it here.
> */
> if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) ...
>
>>> The DP Standard does not mandate that the first read after a sink is
>>> connected (i.e. after the HPD signal of the sink is asserted) must
>>> be an LTTPR capability read and cannot be any other DPCD register
>>> read. In fact this would be impossible to guarantee, a DPRX
>>> capability read - or any DPCD register read for that matter - could
>>> happen at any point and so it could happen right after the HPD
>>> signal got asserted.
>> Spec DP2.1 Section 3.6.8.6.1 LTTPR Recognition After HPD is propagated
>> from the DPRX to the DPTX, a DP Source device with a DPTX shall read
>> specific registers within the DPCD LTTPR Capability and ID Field (DPCD
>> F0000h through F0009h; see Section 3.6.5) After LTTPR recognition, a
>> DP Source device with a DPTX shall read the DP Sink device with a
>> DPRX’s capability by reading the DisplayID or legacy EDID and the
>> DPRX’s Receiver Capability field (DPCD 00000h through 000FFh; see
>> Table 2-232).
> The above does not prohibit reading non-LTTPR DPCD registers before
> reading F0000h - F0009h, and it cannot forbid this as explained above.
>
>>>> Git log shows that initially drm dp helper exposed function to read
>>>> lttpr caps. Driver reads the lttpr caps and then the dprx caps.
>>>> For a particular issue
>>>> https://gitlab.freedesktop.org/drm/intel/-/issues/3415
>>>> as a workaround reading dprx caps was done first to know if the panel is
>>>> < DP1.4 and then read 1 block at a time for lttpr caps.
>>>>
>>>> This can be handled in a better way and two such ways is what I see.
>>>> 1. Read LTTPR caps followed by DPRX caps as per the spec. Then on
>>>> reading dprx caps if revision < 1.4 then re-read the lttpr caps one
>>>> block at a time.
>>>>
>>>> 2. Read LTTPR caps and if 8b/10b check for correctness of the link rate
>>>> supported(lttpr caps 0xf0001), if some corrupted value is read then read
>>>> one block at a time.
>>> The driver does read the DPRX capabilities after reading the LTTPR
>>> capabilities. This is what the standard mandates.
>> Yes but before reading the LTTPR capabilities also DPRX capabilities is
>> read. Have added ref to the code snipped above.
> This is not forbidden by the specification.
>
>> Please let me know if my understanding is wrong.
>>
>>> The workaround for issues/3415 depends on the DPCD_REV value, so this is
>>> read separately before reading the LTTPR caps. I don't see a better way
>>> to implement the workaround and such read is not prohibited by the DP
>>> Standard either. So I don't see the point of the changes in this
>>> patchset.
>> As Jani pointed this can be added as a quirk for that particular panel
>> instead of mandating this kind of reading dprx caps first and then reading
>> the lttpr caps for all the monitors.
> There is already a quirk in the driver - to read out the LTTPR
> capabilities 1 byte at a time - and the quirk is applied based on the
> DPCD_REV register value of the monitor.
>
>> Thanks and Regards,
>> Arun R Murthy
>> -------------------
>>
>>>> I am open for either of the two or you have any other options as well I
>>>> am open.
>>>>
>>>> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
>>>> ---
>>>> Arun R Murthy (4):
>>>> drm/display/dp: Read LTTPR caps without DPRX caps
>>>> drm/i915/dp: Read LTTPR caps followed by DPRX caps
>>>> drm/i915/dp: On HPD read LTTPR caps followed by DPRX caps
>>>> drm/i915/dp: DPRX/LTTPR caps for DP should be read once
>>>>
>>>> drivers/gpu/drm/display/drm_dp_helper.c | 63 ++++++++++++++++++++++
>>>> drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
>>>> .../gpu/drm/i915/display/intel_dp_link_training.c | 40 +++++++-------
>>>> .../gpu/drm/i915/display/intel_dp_link_training.h | 1 -
>>>> drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 3 +-
>>>> include/drm/display/drm_dp_helper.h | 2 +
>>>> 6 files changed, 86 insertions(+), 26 deletions(-)
>>>> ---
>>>> base-commit: cfc20c776480fda8c1b0517b187bb71ec0781cd4
>>>> change-id: 20260305-dp_aux-1e27599e06c8
>>>>
>>>> Best regards,
>>>> --
>>>> Arun R Murthy <arun.r.murthy@intel.com>
>>>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps
2026-03-05 16:11 ` [PATCH RFC 0/4] DP: Read LTTPR caps followed by DPRX caps Imre Deak
2026-03-06 4:29 ` Murthy, Arun R
@ 2026-03-06 4:29 ` Murthy, Arun R
1 sibling, 0 replies; 14+ messages in thread
From: Murthy, Arun R @ 2026-03-06 4:29 UTC (permalink / raw)
To: imre.deak
Cc: Ville Syrjälä, Jani Nikula, dri-devel, intel-gfx,
intel-xe
On 05-03-2026 21:41, Imre Deak wrote:
> On Thu, Mar 05, 2026 at 01:48:10PM +0530, Arun R Murthy wrote:
>> As per the spec DP2.1 section 3.6.8.6.1, section 2.12.1,
>> section 2.12.3 (Link Policy) the LTTPR caps is to be read first
>> followed by the DPRX capability.
> Not exactly. The Standard requires reading the DPRX capabilities after
> the LTTPR caps are read.
I also mean the same, sorry if my wordings were complex.
> The driver does read the DPRX caps after
> reading the LTTPR caps.
In intel_dp_link_training.c function intel_dp_init_lttpr_and_dprx_caps()
int err = intel_dp_read_dprx_caps()
if (err != 0)
return err;
lttpr_count = intel_dp_init_lttpr()
Here we are reading dprx caps and then passing this dprx caps to the the
func intel_dp_init_lttpr(). I think this will be a deviation of the spec.
> The DP Standard does not mandate that the first
> read after a sink is connected (i.e. after the HPD signal of the sink is
> asserted) must be an LTTPR capability read and cannot be any other DPCD
> register read. In fact this would be impossible to guarantee, a DPRX
> capability read - or any DPCD register read for that matter - could
> happen at any point and so it could happen right after the HPD signal
> got asserted.
Spec DP2.1 Section 3.6.8.6.1 LTTPR Recognition
After HPD is propagated from the DPRX to the DPTX, a DP Source device
with a DPTX shall
read specific registers within the DPCD LTTPR Capability and ID Field
(DPCD F0000h through
F0009h; see Section 3.6.5)
After LTTPR recognition, a DP Source device with a DPTX shall read the
DP Sink device with
a DPRX’s capability by reading the DisplayID or legacy EDID and the
DPRX’s Receiver
Capability field (DPCD 00000h through 000FFh; see Table 2-232).
>> Git log shows that initially drm dp helper exposed function to read
>> lttpr caps. Driver reads the lttpr caps and then the dprx caps.
>> For a particular issue
>> https://gitlab.freedesktop.org/drm/intel/-/issues/3415
>> as a workaround reading dprx caps was done first to know if the panel is
>> < DP1.4 and then read 1 block at a time for lttpr caps.
>>
>> This can be handled in a better way and two such ways is what I see.
>> 1. Read LTTPR caps followed by DPRX caps as per the spec. Then on
>> reading dprx caps if revision < 1.4 then re-read the lttpr caps one
>> block at a time.
>>
>> 2. Read LTTPR caps and if 8b/10b check for correctness of the link rate
>> supported(lttpr caps 0xf0001), if some corrupted value is read then read
>> one block at a time.
> The driver does read the DPRX capabilities after reading the LTTPR
> capabilities. This is what the standard mandates.
Yes but before reading the LTTPR capabilities also DPRX capabilities is
read. Have added ref to the code snipped above.
Please let me know if my understanding is wrong.
>
> The workaround for issues/3415 depends on the DPCD_REV value, so this is
> read separately before reading the LTTPR caps. I don't see a better way
> to implement the workaround and such read is not prohibited by the DP
> Standard either. So I don't see the point of the changes in this
> patchset.
As Jani commented this can be added as a quirk for that particular panel
instead of mandating this kind of reading dprx caps first and then
reading the lttpr caps for all the monitors.
Thanks and Regards,
Arun R Murthy
-------------------
>
>> I am open for either of the two or you have any other options as well I
>> am open.
>>
>> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
>> ---
>> Arun R Murthy (4):
>> drm/display/dp: Read LTTPR caps without DPRX caps
>> drm/i915/dp: Read LTTPR caps followed by DPRX caps
>> drm/i915/dp: On HPD read LTTPR caps followed by DPRX caps
>> drm/i915/dp: DPRX/LTTPR caps for DP should be read once
>>
>> drivers/gpu/drm/display/drm_dp_helper.c | 63 ++++++++++++++++++++++
>> drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
>> .../gpu/drm/i915/display/intel_dp_link_training.c | 40 +++++++-------
>> .../gpu/drm/i915/display/intel_dp_link_training.h | 1 -
>> drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 3 +-
>> include/drm/display/drm_dp_helper.h | 2 +
>> 6 files changed, 86 insertions(+), 26 deletions(-)
>> ---
>> base-commit: cfc20c776480fda8c1b0517b187bb71ec0781cd4
>> change-id: 20260305-dp_aux-1e27599e06c8
>>
>> Best regards,
>> --
>> Arun R Murthy <arun.r.murthy@intel.com>
>>
^ permalink raw reply [flat|nested] 14+ messages in thread