All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-07 21:58 ` Lyude Paul
  0 siblings, 0 replies; 18+ messages in thread
From: Lyude Paul @ 2023-07-07 21:58 UTC (permalink / raw)
  To: nouveau, dri-devel
  Cc: Ben Skeggs, Karol Herbst, David Airlie, Daniel Vetter,
	Dave Airlie, open list

Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
nouveau in order to read the DPCD of a DP connector, which makes sure we do
the right thing and also check for extended DPCD caps. However, it turns
out we're not currently doing this on the nvkm side since we don't have
access to the drm_dp_aux structure there - which means that the DRM side of
the driver and the NVKM side can end up with different DPCD capabilities
for the same connector.

Ideally to fix this, we want to start setting up the drm_dp_aux device in
NVKM before we've made contact with the DRM side - which should be pretty
easy to accomplish (I'm already working on it!). Until then however, let's
workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
NVKM - which should fix this issue.

Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
index 40c8ea43c42f..b8ac66b4a2c4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
@@ -26,6 +26,8 @@
 #include "head.h"
 #include "ior.h"
 
+#include <drm/display/drm_dp.h>
+
 #include <subdev/bios.h>
 #include <subdev/bios/init.h>
 #include <subdev/gpio.h>
@@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
 	return outp->dp.rates != 0;
 }
 
+/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
+ * converted to work inside nvkm. This is a temporary holdover until we start
+ * passing the drm_dp_aux device through NVKM
+ */
+static int
+nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
+{
+	struct nvkm_i2c_aux *aux = outp->dp.aux;
+	u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
+	int ret;
+
+	ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Prior to DP1.3 the bit represented by
+	 * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
+	 * If it is set DP_DPCD_REV at 0000h could be at a value less than
+	 * the true capability of the panel. The only way to check is to
+	 * then compare 0000h and 2200h.
+	 */
+	if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+	      DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
+		return 0;
+
+	ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
+	if (ret < 0)
+		return ret;
+
+	if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
+		OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
+			 outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
+		return 0;
+	}
+
+	if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
+		return 0;
+
+	memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
+
+	return 0;
+}
+
 void
 nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
 {
@@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
 			memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
 		}
 
-		if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
+		if (!nvkm_dp_read_dpcd_caps(outp)) {
 			const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
 			const u8 *rate;
 			int rate_max;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Nouveau] [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-07 21:58 ` Lyude Paul
  0 siblings, 0 replies; 18+ messages in thread
From: Lyude Paul @ 2023-07-07 21:58 UTC (permalink / raw)
  To: nouveau, dri-devel; +Cc: open list, Ben Skeggs, Daniel Vetter, Dave Airlie

Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
nouveau in order to read the DPCD of a DP connector, which makes sure we do
the right thing and also check for extended DPCD caps. However, it turns
out we're not currently doing this on the nvkm side since we don't have
access to the drm_dp_aux structure there - which means that the DRM side of
the driver and the NVKM side can end up with different DPCD capabilities
for the same connector.

Ideally to fix this, we want to start setting up the drm_dp_aux device in
NVKM before we've made contact with the DRM side - which should be pretty
easy to accomplish (I'm already working on it!). Until then however, let's
workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
NVKM - which should fix this issue.

Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
index 40c8ea43c42f..b8ac66b4a2c4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
@@ -26,6 +26,8 @@
 #include "head.h"
 #include "ior.h"
 
+#include <drm/display/drm_dp.h>
+
 #include <subdev/bios.h>
 #include <subdev/bios/init.h>
 #include <subdev/gpio.h>
@@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
 	return outp->dp.rates != 0;
 }
 
+/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
+ * converted to work inside nvkm. This is a temporary holdover until we start
+ * passing the drm_dp_aux device through NVKM
+ */
+static int
+nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
+{
+	struct nvkm_i2c_aux *aux = outp->dp.aux;
+	u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
+	int ret;
+
+	ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Prior to DP1.3 the bit represented by
+	 * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
+	 * If it is set DP_DPCD_REV at 0000h could be at a value less than
+	 * the true capability of the panel. The only way to check is to
+	 * then compare 0000h and 2200h.
+	 */
+	if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+	      DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
+		return 0;
+
+	ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
+	if (ret < 0)
+		return ret;
+
+	if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
+		OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
+			 outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
+		return 0;
+	}
+
+	if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
+		return 0;
+
+	memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
+
+	return 0;
+}
+
 void
 nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
 {
@@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
 			memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
 		}
 
-		if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
+		if (!nvkm_dp_read_dpcd_caps(outp)) {
 			const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
 			const u8 *rate;
 			int rate_max;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-07 21:58 ` Lyude Paul
  0 siblings, 0 replies; 18+ messages in thread
From: Lyude Paul @ 2023-07-07 21:58 UTC (permalink / raw)
  To: nouveau, dri-devel; +Cc: Karol Herbst, open list, Ben Skeggs, Dave Airlie

Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
nouveau in order to read the DPCD of a DP connector, which makes sure we do
the right thing and also check for extended DPCD caps. However, it turns
out we're not currently doing this on the nvkm side since we don't have
access to the drm_dp_aux structure there - which means that the DRM side of
the driver and the NVKM side can end up with different DPCD capabilities
for the same connector.

Ideally to fix this, we want to start setting up the drm_dp_aux device in
NVKM before we've made contact with the DRM side - which should be pretty
easy to accomplish (I'm already working on it!). Until then however, let's
workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
NVKM - which should fix this issue.

Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
index 40c8ea43c42f..b8ac66b4a2c4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
@@ -26,6 +26,8 @@
 #include "head.h"
 #include "ior.h"
 
+#include <drm/display/drm_dp.h>
+
 #include <subdev/bios.h>
 #include <subdev/bios/init.h>
 #include <subdev/gpio.h>
@@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
 	return outp->dp.rates != 0;
 }
 
+/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
+ * converted to work inside nvkm. This is a temporary holdover until we start
+ * passing the drm_dp_aux device through NVKM
+ */
+static int
+nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
+{
+	struct nvkm_i2c_aux *aux = outp->dp.aux;
+	u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
+	int ret;
+
+	ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Prior to DP1.3 the bit represented by
+	 * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
+	 * If it is set DP_DPCD_REV at 0000h could be at a value less than
+	 * the true capability of the panel. The only way to check is to
+	 * then compare 0000h and 2200h.
+	 */
+	if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+	      DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
+		return 0;
+
+	ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
+	if (ret < 0)
+		return ret;
+
+	if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
+		OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
+			 outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
+		return 0;
+	}
+
+	if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
+		return 0;
+
+	memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
+
+	return 0;
+}
+
 void
 nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
 {
@@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
 			memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
 		}
 
-		if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
+		if (!nvkm_dp_read_dpcd_caps(outp)) {
 			const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
 			const u8 *rate;
 			int rate_max;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Nouveau] [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
  2023-07-07 21:58 ` [Nouveau] " Lyude Paul
  (?)
@ 2023-07-08 23:42   ` Karol Herbst
  -1 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-08 23:42 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, open list, dri-devel, Ben Skeggs, Daniel Vetter, Dave Airlie

On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
>
> Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> nouveau in order to read the DPCD of a DP connector, which makes sure we do
> the right thing and also check for extended DPCD caps. However, it turns
> out we're not currently doing this on the nvkm side since we don't have
> access to the drm_dp_aux structure there - which means that the DRM side of
> the driver and the NVKM side can end up with different DPCD capabilities
> for the same connector.
>
> Ideally to fix this, we want to start setting up the drm_dp_aux device in
> NVKM before we've made contact with the DRM side - which should be pretty
> easy to accomplish (I'm already working on it!). Until then however, let's
> workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> NVKM - which should fix this issue.
>
> Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211

Should a Fixes: or Cc: stable tag be added so it gets backported?

> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> index 40c8ea43c42f..b8ac66b4a2c4 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> @@ -26,6 +26,8 @@
>  #include "head.h"
>  #include "ior.h"
>
> +#include <drm/display/drm_dp.h>
> +
>  #include <subdev/bios.h>
>  #include <subdev/bios/init.h>
>  #include <subdev/gpio.h>
> @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
>         return outp->dp.rates != 0;
>  }
>
> +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()

Well.. maybe we should rephrase that _if_ we want to see it
backported. But is this code really that bad? It kinda looks
reasonable enough.

> + * converted to work inside nvkm. This is a temporary holdover until we start
> + * passing the drm_dp_aux device through NVKM
> + */
> +static int
> +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> +{
> +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> +       int ret;
> +
> +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> +       if (ret < 0)
> +               return ret;
> +
> +       /*
> +        * Prior to DP1.3 the bit represented by
> +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> +        * the true capability of the panel. The only way to check is to
> +        * then compare 0000h and 2200h.
> +        */
> +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> +               return 0;
> +
> +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> +       if (ret < 0)
> +               return ret;
> +
> +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> +               return 0;
> +       }
> +
> +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> +               return 0;
> +
> +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> +       return 0;
> +}
> +
>  void
>  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>  {
> @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
>                 }
>
> -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> +               if (!nvkm_dp_read_dpcd_caps(outp)) {
>                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
>                         const u8 *rate;
>                         int rate_max;
> --
> 2.40.1
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-08 23:42   ` Karol Herbst
  0 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-08 23:42 UTC (permalink / raw)
  To: Lyude Paul; +Cc: nouveau, open list, dri-devel, Ben Skeggs, Dave Airlie

On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
>
> Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> nouveau in order to read the DPCD of a DP connector, which makes sure we do
> the right thing and also check for extended DPCD caps. However, it turns
> out we're not currently doing this on the nvkm side since we don't have
> access to the drm_dp_aux structure there - which means that the DRM side of
> the driver and the NVKM side can end up with different DPCD capabilities
> for the same connector.
>
> Ideally to fix this, we want to start setting up the drm_dp_aux device in
> NVKM before we've made contact with the DRM side - which should be pretty
> easy to accomplish (I'm already working on it!). Until then however, let's
> workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> NVKM - which should fix this issue.
>
> Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211

Should a Fixes: or Cc: stable tag be added so it gets backported?

> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> index 40c8ea43c42f..b8ac66b4a2c4 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> @@ -26,6 +26,8 @@
>  #include "head.h"
>  #include "ior.h"
>
> +#include <drm/display/drm_dp.h>
> +
>  #include <subdev/bios.h>
>  #include <subdev/bios/init.h>
>  #include <subdev/gpio.h>
> @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
>         return outp->dp.rates != 0;
>  }
>
> +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()

Well.. maybe we should rephrase that _if_ we want to see it
backported. But is this code really that bad? It kinda looks
reasonable enough.

> + * converted to work inside nvkm. This is a temporary holdover until we start
> + * passing the drm_dp_aux device through NVKM
> + */
> +static int
> +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> +{
> +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> +       int ret;
> +
> +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> +       if (ret < 0)
> +               return ret;
> +
> +       /*
> +        * Prior to DP1.3 the bit represented by
> +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> +        * the true capability of the panel. The only way to check is to
> +        * then compare 0000h and 2200h.
> +        */
> +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> +               return 0;
> +
> +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> +       if (ret < 0)
> +               return ret;
> +
> +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> +               return 0;
> +       }
> +
> +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> +               return 0;
> +
> +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> +       return 0;
> +}
> +
>  void
>  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>  {
> @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
>                 }
>
> -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> +               if (!nvkm_dp_read_dpcd_caps(outp)) {
>                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
>                         const u8 *rate;
>                         int rate_max;
> --
> 2.40.1
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-08 23:42   ` Karol Herbst
  0 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-08 23:42 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, dri-devel, Ben Skeggs, David Airlie, Daniel Vetter,
	Dave Airlie, open list

On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
>
> Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> nouveau in order to read the DPCD of a DP connector, which makes sure we do
> the right thing and also check for extended DPCD caps. However, it turns
> out we're not currently doing this on the nvkm side since we don't have
> access to the drm_dp_aux structure there - which means that the DRM side of
> the driver and the NVKM side can end up with different DPCD capabilities
> for the same connector.
>
> Ideally to fix this, we want to start setting up the drm_dp_aux device in
> NVKM before we've made contact with the DRM side - which should be pretty
> easy to accomplish (I'm already working on it!). Until then however, let's
> workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> NVKM - which should fix this issue.
>
> Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211

Should a Fixes: or Cc: stable tag be added so it gets backported?

> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> index 40c8ea43c42f..b8ac66b4a2c4 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> @@ -26,6 +26,8 @@
>  #include "head.h"
>  #include "ior.h"
>
> +#include <drm/display/drm_dp.h>
> +
>  #include <subdev/bios.h>
>  #include <subdev/bios/init.h>
>  #include <subdev/gpio.h>
> @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
>         return outp->dp.rates != 0;
>  }
>
> +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()

Well.. maybe we should rephrase that _if_ we want to see it
backported. But is this code really that bad? It kinda looks
reasonable enough.

> + * converted to work inside nvkm. This is a temporary holdover until we start
> + * passing the drm_dp_aux device through NVKM
> + */
> +static int
> +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> +{
> +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> +       int ret;
> +
> +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> +       if (ret < 0)
> +               return ret;
> +
> +       /*
> +        * Prior to DP1.3 the bit represented by
> +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> +        * the true capability of the panel. The only way to check is to
> +        * then compare 0000h and 2200h.
> +        */
> +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> +               return 0;
> +
> +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> +       if (ret < 0)
> +               return ret;
> +
> +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> +               return 0;
> +       }
> +
> +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> +               return 0;
> +
> +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> +       return 0;
> +}
> +
>  void
>  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>  {
> @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
>                 }
>
> -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> +               if (!nvkm_dp_read_dpcd_caps(outp)) {
>                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
>                         const u8 *rate;
>                         int rate_max;
> --
> 2.40.1
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
  2023-07-07 21:58 ` [Nouveau] " Lyude Paul
  (?)
@ 2023-07-19  5:17   ` Ben Skeggs
  -1 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2023-07-19  5:17 UTC (permalink / raw)
  To: Lyude Paul
  Cc: Karol Herbst, nouveau, open list, dri-devel, Ben Skeggs, Dave Airlie

On Sat, 8 Jul 2023 at 07:59, Lyude Paul <lyude@redhat.com> wrote:
>
> Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> nouveau in order to read the DPCD of a DP connector, which makes sure we do
> the right thing and also check for extended DPCD caps. However, it turns
> out we're not currently doing this on the nvkm side since we don't have
> access to the drm_dp_aux structure there - which means that the DRM side of
> the driver and the NVKM side can end up with different DPCD capabilities
> for the same connector.
>
> Ideally to fix this, we want to start setting up the drm_dp_aux device in
> NVKM before we've made contact with the DRM side - which should be pretty
> easy to accomplish (I'm already working on it!). Until then however, let's
> workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> NVKM - which should fix this issue.
I wouldn't worry about this.  I'm moving basically everything to the
DRM side of the driver for the GSP work anyway.

Ben.
>
> Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> index 40c8ea43c42f..b8ac66b4a2c4 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> @@ -26,6 +26,8 @@
>  #include "head.h"
>  #include "ior.h"
>
> +#include <drm/display/drm_dp.h>
> +
>  #include <subdev/bios.h>
>  #include <subdev/bios/init.h>
>  #include <subdev/gpio.h>
> @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
>         return outp->dp.rates != 0;
>  }
>
> +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> + * converted to work inside nvkm. This is a temporary holdover until we start
> + * passing the drm_dp_aux device through NVKM
> + */
> +static int
> +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> +{
> +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> +       int ret;
> +
> +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> +       if (ret < 0)
> +               return ret;
> +
> +       /*
> +        * Prior to DP1.3 the bit represented by
> +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> +        * the true capability of the panel. The only way to check is to
> +        * then compare 0000h and 2200h.
> +        */
> +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> +               return 0;
> +
> +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> +       if (ret < 0)
> +               return ret;
> +
> +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> +               return 0;
> +       }
> +
> +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> +               return 0;
> +
> +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> +       return 0;
> +}
> +
>  void
>  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>  {
> @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
>                 }
>
> -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> +               if (!nvkm_dp_read_dpcd_caps(outp)) {
>                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
>                         const u8 *rate;
>                         int rate_max;
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-19  5:17   ` Ben Skeggs
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2023-07-19  5:17 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, dri-devel, Karol Herbst, open list, Ben Skeggs, Dave Airlie

On Sat, 8 Jul 2023 at 07:59, Lyude Paul <lyude@redhat.com> wrote:
>
> Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> nouveau in order to read the DPCD of a DP connector, which makes sure we do
> the right thing and also check for extended DPCD caps. However, it turns
> out we're not currently doing this on the nvkm side since we don't have
> access to the drm_dp_aux structure there - which means that the DRM side of
> the driver and the NVKM side can end up with different DPCD capabilities
> for the same connector.
>
> Ideally to fix this, we want to start setting up the drm_dp_aux device in
> NVKM before we've made contact with the DRM side - which should be pretty
> easy to accomplish (I'm already working on it!). Until then however, let's
> workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> NVKM - which should fix this issue.
I wouldn't worry about this.  I'm moving basically everything to the
DRM side of the driver for the GSP work anyway.

Ben.
>
> Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> index 40c8ea43c42f..b8ac66b4a2c4 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> @@ -26,6 +26,8 @@
>  #include "head.h"
>  #include "ior.h"
>
> +#include <drm/display/drm_dp.h>
> +
>  #include <subdev/bios.h>
>  #include <subdev/bios/init.h>
>  #include <subdev/gpio.h>
> @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
>         return outp->dp.rates != 0;
>  }
>
> +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> + * converted to work inside nvkm. This is a temporary holdover until we start
> + * passing the drm_dp_aux device through NVKM
> + */
> +static int
> +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> +{
> +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> +       int ret;
> +
> +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> +       if (ret < 0)
> +               return ret;
> +
> +       /*
> +        * Prior to DP1.3 the bit represented by
> +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> +        * the true capability of the panel. The only way to check is to
> +        * then compare 0000h and 2200h.
> +        */
> +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> +               return 0;
> +
> +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> +       if (ret < 0)
> +               return ret;
> +
> +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> +               return 0;
> +       }
> +
> +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> +               return 0;
> +
> +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> +       return 0;
> +}
> +
>  void
>  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>  {
> @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
>                 }
>
> -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> +               if (!nvkm_dp_read_dpcd_caps(outp)) {
>                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
>                         const u8 *rate;
>                         int rate_max;
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Nouveau] [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-19  5:17   ` Ben Skeggs
  0 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2023-07-19  5:17 UTC (permalink / raw)
  To: Lyude Paul; +Cc: nouveau, open list, dri-devel, Ben Skeggs, Dave Airlie

On Sat, 8 Jul 2023 at 07:59, Lyude Paul <lyude@redhat.com> wrote:
>
> Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> nouveau in order to read the DPCD of a DP connector, which makes sure we do
> the right thing and also check for extended DPCD caps. However, it turns
> out we're not currently doing this on the nvkm side since we don't have
> access to the drm_dp_aux structure there - which means that the DRM side of
> the driver and the NVKM side can end up with different DPCD capabilities
> for the same connector.
>
> Ideally to fix this, we want to start setting up the drm_dp_aux device in
> NVKM before we've made contact with the DRM side - which should be pretty
> easy to accomplish (I'm already working on it!). Until then however, let's
> workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> NVKM - which should fix this issue.
I wouldn't worry about this.  I'm moving basically everything to the
DRM side of the driver for the GSP work anyway.

Ben.
>
> Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> index 40c8ea43c42f..b8ac66b4a2c4 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> @@ -26,6 +26,8 @@
>  #include "head.h"
>  #include "ior.h"
>
> +#include <drm/display/drm_dp.h>
> +
>  #include <subdev/bios.h>
>  #include <subdev/bios/init.h>
>  #include <subdev/gpio.h>
> @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
>         return outp->dp.rates != 0;
>  }
>
> +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> + * converted to work inside nvkm. This is a temporary holdover until we start
> + * passing the drm_dp_aux device through NVKM
> + */
> +static int
> +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> +{
> +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> +       int ret;
> +
> +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> +       if (ret < 0)
> +               return ret;
> +
> +       /*
> +        * Prior to DP1.3 the bit represented by
> +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> +        * the true capability of the panel. The only way to check is to
> +        * then compare 0000h and 2200h.
> +        */
> +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> +               return 0;
> +
> +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> +       if (ret < 0)
> +               return ret;
> +
> +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> +               return 0;
> +       }
> +
> +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> +               return 0;
> +
> +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> +       return 0;
> +}
> +
>  void
>  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>  {
> @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
>                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
>                 }
>
> -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> +               if (!nvkm_dp_read_dpcd_caps(outp)) {
>                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
>                         const u8 *rate;
>                         int rate_max;
> --
> 2.40.1
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
  2023-07-08 23:42   ` Karol Herbst
  (?)
@ 2023-07-27 21:57     ` Lyude Paul
  -1 siblings, 0 replies; 18+ messages in thread
From: Lyude Paul @ 2023-07-27 21:57 UTC (permalink / raw)
  To: Karol Herbst
  Cc: nouveau, dri-devel, Ben Skeggs, David Airlie, Daniel Vetter,
	Dave Airlie, open list

On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > 
> > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > the right thing and also check for extended DPCD caps. However, it turns
> > out we're not currently doing this on the nvkm side since we don't have
> > access to the drm_dp_aux structure there - which means that the DRM side of
> > the driver and the NVKM side can end up with different DPCD capabilities
> > for the same connector.
> > 
> > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > NVKM before we've made contact with the DRM side - which should be pretty
> > easy to accomplish (I'm already working on it!). Until then however, let's
> > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > NVKM - which should fix this issue.
> > 
> > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> 
> Should a Fixes: or Cc: stable tag be added so it gets backported?

JFYI I think not adding one is fine nowadays? The stable bot seems to be
pretty good at catching anything with the words fix/fixes in it

> 
> > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > ---
> >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> >  1 file changed, 47 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > @@ -26,6 +26,8 @@
> >  #include "head.h"
> >  #include "ior.h"
> > 
> > +#include <drm/display/drm_dp.h>
> > +
> >  #include <subdev/bios.h>
> >  #include <subdev/bios/init.h>
> >  #include <subdev/gpio.h>
> > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> >         return outp->dp.rates != 0;
> >  }
> > 
> > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> 
> Well.. maybe we should rephrase that _if_ we want to see it
> backported. But is this code really that bad? It kinda looks
> reasonable enough.
> 
> > + * converted to work inside nvkm. This is a temporary holdover until we start
> > + * passing the drm_dp_aux device through NVKM
> > + */
> > +static int
> > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > +{
> > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > +       int ret;
> > +
> > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       /*
> > +        * Prior to DP1.3 the bit represented by
> > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > +        * the true capability of the panel. The only way to check is to
> > +        * then compare 0000h and 2200h.
> > +        */
> > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > +               return 0;
> > +
> > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > +               return 0;
> > +       }
> > +
> > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > +               return 0;
> > +
> > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > +
> > +       return 0;
> > +}
> > +
> >  void
> >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> >  {
> > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> >                 }
> > 
> > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> >                         const u8 *rate;
> >                         int rate_max;
> > --
> > 2.40.1
> > 
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Nouveau] [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-27 21:57     ` Lyude Paul
  0 siblings, 0 replies; 18+ messages in thread
From: Lyude Paul @ 2023-07-27 21:57 UTC (permalink / raw)
  To: Karol Herbst
  Cc: nouveau, open list, dri-devel, Ben Skeggs, Daniel Vetter, Dave Airlie

On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > 
> > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > the right thing and also check for extended DPCD caps. However, it turns
> > out we're not currently doing this on the nvkm side since we don't have
> > access to the drm_dp_aux structure there - which means that the DRM side of
> > the driver and the NVKM side can end up with different DPCD capabilities
> > for the same connector.
> > 
> > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > NVKM before we've made contact with the DRM side - which should be pretty
> > easy to accomplish (I'm already working on it!). Until then however, let's
> > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > NVKM - which should fix this issue.
> > 
> > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> 
> Should a Fixes: or Cc: stable tag be added so it gets backported?

JFYI I think not adding one is fine nowadays? The stable bot seems to be
pretty good at catching anything with the words fix/fixes in it

> 
> > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > ---
> >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> >  1 file changed, 47 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > @@ -26,6 +26,8 @@
> >  #include "head.h"
> >  #include "ior.h"
> > 
> > +#include <drm/display/drm_dp.h>
> > +
> >  #include <subdev/bios.h>
> >  #include <subdev/bios/init.h>
> >  #include <subdev/gpio.h>
> > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> >         return outp->dp.rates != 0;
> >  }
> > 
> > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> 
> Well.. maybe we should rephrase that _if_ we want to see it
> backported. But is this code really that bad? It kinda looks
> reasonable enough.
> 
> > + * converted to work inside nvkm. This is a temporary holdover until we start
> > + * passing the drm_dp_aux device through NVKM
> > + */
> > +static int
> > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > +{
> > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > +       int ret;
> > +
> > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       /*
> > +        * Prior to DP1.3 the bit represented by
> > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > +        * the true capability of the panel. The only way to check is to
> > +        * then compare 0000h and 2200h.
> > +        */
> > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > +               return 0;
> > +
> > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > +               return 0;
> > +       }
> > +
> > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > +               return 0;
> > +
> > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > +
> > +       return 0;
> > +}
> > +
> >  void
> >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> >  {
> > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> >                 }
> > 
> > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> >                         const u8 *rate;
> >                         int rate_max;
> > --
> > 2.40.1
> > 
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-27 21:57     ` Lyude Paul
  0 siblings, 0 replies; 18+ messages in thread
From: Lyude Paul @ 2023-07-27 21:57 UTC (permalink / raw)
  To: Karol Herbst; +Cc: nouveau, open list, dri-devel, Ben Skeggs, Dave Airlie

On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > 
> > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > the right thing and also check for extended DPCD caps. However, it turns
> > out we're not currently doing this on the nvkm side since we don't have
> > access to the drm_dp_aux structure there - which means that the DRM side of
> > the driver and the NVKM side can end up with different DPCD capabilities
> > for the same connector.
> > 
> > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > NVKM before we've made contact with the DRM side - which should be pretty
> > easy to accomplish (I'm already working on it!). Until then however, let's
> > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > NVKM - which should fix this issue.
> > 
> > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> 
> Should a Fixes: or Cc: stable tag be added so it gets backported?

JFYI I think not adding one is fine nowadays? The stable bot seems to be
pretty good at catching anything with the words fix/fixes in it

> 
> > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > ---
> >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> >  1 file changed, 47 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > @@ -26,6 +26,8 @@
> >  #include "head.h"
> >  #include "ior.h"
> > 
> > +#include <drm/display/drm_dp.h>
> > +
> >  #include <subdev/bios.h>
> >  #include <subdev/bios/init.h>
> >  #include <subdev/gpio.h>
> > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> >         return outp->dp.rates != 0;
> >  }
> > 
> > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> 
> Well.. maybe we should rephrase that _if_ we want to see it
> backported. But is this code really that bad? It kinda looks
> reasonable enough.
> 
> > + * converted to work inside nvkm. This is a temporary holdover until we start
> > + * passing the drm_dp_aux device through NVKM
> > + */
> > +static int
> > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > +{
> > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > +       int ret;
> > +
> > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       /*
> > +        * Prior to DP1.3 the bit represented by
> > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > +        * the true capability of the panel. The only way to check is to
> > +        * then compare 0000h and 2200h.
> > +        */
> > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > +               return 0;
> > +
> > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > +               return 0;
> > +       }
> > +
> > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > +               return 0;
> > +
> > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > +
> > +       return 0;
> > +}
> > +
> >  void
> >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> >  {
> > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> >                 }
> > 
> > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> >                         const u8 *rate;
> >                         int rate_max;
> > --
> > 2.40.1
> > 
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
  2023-07-27 21:57     ` [Nouveau] " Lyude Paul
  (?)
@ 2023-07-27 23:11       ` Karol Herbst
  -1 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-27 23:11 UTC (permalink / raw)
  To: Lyude Paul; +Cc: nouveau, open list, dri-devel, Ben Skeggs, Dave Airlie

On Thu, Jul 27, 2023 at 11:57 PM Lyude Paul <lyude@redhat.com> wrote:
>
> On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> > On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > >
> > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > > the right thing and also check for extended DPCD caps. However, it turns
> > > out we're not currently doing this on the nvkm side since we don't have
> > > access to the drm_dp_aux structure there - which means that the DRM side of
> > > the driver and the NVKM side can end up with different DPCD capabilities
> > > for the same connector.
> > >
> > > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > > NVKM before we've made contact with the DRM side - which should be pretty
> > > easy to accomplish (I'm already working on it!). Until then however, let's
> > > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > > NVKM - which should fix this issue.
> > >
> > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> >
> > Should a Fixes: or Cc: stable tag be added so it gets backported?
>
> JFYI I think not adding one is fine nowadays? The stable bot seems to be
> pretty good at catching anything with the words fix/fixes in it
>

Yeah not sure.. I'd rather be specific and add it just to be sure.
Anyway, it could also be done while pushing. I think the bigger
question here was if this fix is good enough for stable or if you plan
to rework it.

> >
> > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > ---
> > >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> > >  1 file changed, 47 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > @@ -26,6 +26,8 @@
> > >  #include "head.h"
> > >  #include "ior.h"
> > >
> > > +#include <drm/display/drm_dp.h>
> > > +
> > >  #include <subdev/bios.h>
> > >  #include <subdev/bios/init.h>
> > >  #include <subdev/gpio.h>
> > > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> > >         return outp->dp.rates != 0;
> > >  }
> > >
> > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> >
> > Well.. maybe we should rephrase that _if_ we want to see it
> > backported. But is this code really that bad? It kinda looks
> > reasonable enough.
> >
> > > + * converted to work inside nvkm. This is a temporary holdover until we start
> > > + * passing the drm_dp_aux device through NVKM
> > > + */
> > > +static int
> > > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > > +{
> > > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > > +       int ret;
> > > +
> > > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       /*
> > > +        * Prior to DP1.3 the bit represented by
> > > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > > +        * the true capability of the panel. The only way to check is to
> > > +        * then compare 0000h and 2200h.
> > > +        */
> > > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > > +               return 0;
> > > +
> > > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > > +               return 0;
> > > +       }
> > > +
> > > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > > +               return 0;
> > > +
> > > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > > +
> > > +       return 0;
> > > +}
> > > +
> > >  void
> > >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > >  {
> > > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> > >                 }
> > >
> > > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> > >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> > >                         const u8 *rate;
> > >                         int rate_max;
> > > --
> > > 2.40.1
> > >
> >
>
> --
> Cheers,
>  Lyude Paul (she/her)
>  Software Engineer at Red Hat
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-27 23:11       ` Karol Herbst
  0 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-27 23:11 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, dri-devel, Ben Skeggs, David Airlie, Daniel Vetter,
	Dave Airlie, open list

On Thu, Jul 27, 2023 at 11:57 PM Lyude Paul <lyude@redhat.com> wrote:
>
> On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> > On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > >
> > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > > the right thing and also check for extended DPCD caps. However, it turns
> > > out we're not currently doing this on the nvkm side since we don't have
> > > access to the drm_dp_aux structure there - which means that the DRM side of
> > > the driver and the NVKM side can end up with different DPCD capabilities
> > > for the same connector.
> > >
> > > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > > NVKM before we've made contact with the DRM side - which should be pretty
> > > easy to accomplish (I'm already working on it!). Until then however, let's
> > > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > > NVKM - which should fix this issue.
> > >
> > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> >
> > Should a Fixes: or Cc: stable tag be added so it gets backported?
>
> JFYI I think not adding one is fine nowadays? The stable bot seems to be
> pretty good at catching anything with the words fix/fixes in it
>

Yeah not sure.. I'd rather be specific and add it just to be sure.
Anyway, it could also be done while pushing. I think the bigger
question here was if this fix is good enough for stable or if you plan
to rework it.

> >
> > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > ---
> > >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> > >  1 file changed, 47 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > @@ -26,6 +26,8 @@
> > >  #include "head.h"
> > >  #include "ior.h"
> > >
> > > +#include <drm/display/drm_dp.h>
> > > +
> > >  #include <subdev/bios.h>
> > >  #include <subdev/bios/init.h>
> > >  #include <subdev/gpio.h>
> > > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> > >         return outp->dp.rates != 0;
> > >  }
> > >
> > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> >
> > Well.. maybe we should rephrase that _if_ we want to see it
> > backported. But is this code really that bad? It kinda looks
> > reasonable enough.
> >
> > > + * converted to work inside nvkm. This is a temporary holdover until we start
> > > + * passing the drm_dp_aux device through NVKM
> > > + */
> > > +static int
> > > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > > +{
> > > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > > +       int ret;
> > > +
> > > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       /*
> > > +        * Prior to DP1.3 the bit represented by
> > > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > > +        * the true capability of the panel. The only way to check is to
> > > +        * then compare 0000h and 2200h.
> > > +        */
> > > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > > +               return 0;
> > > +
> > > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > > +               return 0;
> > > +       }
> > > +
> > > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > > +               return 0;
> > > +
> > > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > > +
> > > +       return 0;
> > > +}
> > > +
> > >  void
> > >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > >  {
> > > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> > >                 }
> > >
> > > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> > >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> > >                         const u8 *rate;
> > >                         int rate_max;
> > > --
> > > 2.40.1
> > >
> >
>
> --
> Cheers,
>  Lyude Paul (she/her)
>  Software Engineer at Red Hat
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Nouveau] [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-27 23:11       ` Karol Herbst
  0 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-27 23:11 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, open list, dri-devel, Ben Skeggs, Daniel Vetter, Dave Airlie

On Thu, Jul 27, 2023 at 11:57 PM Lyude Paul <lyude@redhat.com> wrote:
>
> On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> > On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > >
> > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > > the right thing and also check for extended DPCD caps. However, it turns
> > > out we're not currently doing this on the nvkm side since we don't have
> > > access to the drm_dp_aux structure there - which means that the DRM side of
> > > the driver and the NVKM side can end up with different DPCD capabilities
> > > for the same connector.
> > >
> > > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > > NVKM before we've made contact with the DRM side - which should be pretty
> > > easy to accomplish (I'm already working on it!). Until then however, let's
> > > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > > NVKM - which should fix this issue.
> > >
> > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> >
> > Should a Fixes: or Cc: stable tag be added so it gets backported?
>
> JFYI I think not adding one is fine nowadays? The stable bot seems to be
> pretty good at catching anything with the words fix/fixes in it
>

Yeah not sure.. I'd rather be specific and add it just to be sure.
Anyway, it could also be done while pushing. I think the bigger
question here was if this fix is good enough for stable or if you plan
to rework it.

> >
> > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > ---
> > >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> > >  1 file changed, 47 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > @@ -26,6 +26,8 @@
> > >  #include "head.h"
> > >  #include "ior.h"
> > >
> > > +#include <drm/display/drm_dp.h>
> > > +
> > >  #include <subdev/bios.h>
> > >  #include <subdev/bios/init.h>
> > >  #include <subdev/gpio.h>
> > > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> > >         return outp->dp.rates != 0;
> > >  }
> > >
> > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> >
> > Well.. maybe we should rephrase that _if_ we want to see it
> > backported. But is this code really that bad? It kinda looks
> > reasonable enough.
> >
> > > + * converted to work inside nvkm. This is a temporary holdover until we start
> > > + * passing the drm_dp_aux device through NVKM
> > > + */
> > > +static int
> > > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > > +{
> > > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > > +       int ret;
> > > +
> > > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       /*
> > > +        * Prior to DP1.3 the bit represented by
> > > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > > +        * the true capability of the panel. The only way to check is to
> > > +        * then compare 0000h and 2200h.
> > > +        */
> > > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > > +               return 0;
> > > +
> > > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > > +               return 0;
> > > +       }
> > > +
> > > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > > +               return 0;
> > > +
> > > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > > +
> > > +       return 0;
> > > +}
> > > +
> > >  void
> > >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > >  {
> > > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> > >                 }
> > >
> > > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> > >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> > >                         const u8 *rate;
> > >                         int rate_max;
> > > --
> > > 2.40.1
> > >
> >
>
> --
> Cheers,
>  Lyude Paul (she/her)
>  Software Engineer at Red Hat
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Nouveau] [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
  2023-07-27 23:11       ` Karol Herbst
  (?)
@ 2023-07-28  9:59         ` Karol Herbst
  -1 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-28  9:59 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, open list, dri-devel, Ben Skeggs, Daniel Vetter, Dave Airlie

On Fri, Jul 28, 2023 at 1:11 AM Karol Herbst <kherbst@redhat.com> wrote:
>
> On Thu, Jul 27, 2023 at 11:57 PM Lyude Paul <lyude@redhat.com> wrote:
> >
> > On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> > > On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > > >
> > > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > > > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > > > the right thing and also check for extended DPCD caps. However, it turns
> > > > out we're not currently doing this on the nvkm side since we don't have
> > > > access to the drm_dp_aux structure there - which means that the DRM side of
> > > > the driver and the NVKM side can end up with different DPCD capabilities
> > > > for the same connector.
> > > >
> > > > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > > > NVKM before we've made contact with the DRM side - which should be pretty
> > > > easy to accomplish (I'm already working on it!). Until then however, let's
> > > > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > > > NVKM - which should fix this issue.
> > > >
> > > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> > >
> > > Should a Fixes: or Cc: stable tag be added so it gets backported?
> >
> > JFYI I think not adding one is fine nowadays? The stable bot seems to be
> > pretty good at catching anything with the words fix/fixes in it
> >
>
> Yeah not sure.. I'd rather be specific and add it just to be sure.
> Anyway, it could also be done while pushing. I think the bigger
> question here was if this fix is good enough for stable or if you plan
> to rework it.
>
> > >
> > > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > > ---
> > > >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> > > >  1 file changed, 47 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > @@ -26,6 +26,8 @@
> > > >  #include "head.h"
> > > >  #include "ior.h"
> > > >
> > > > +#include <drm/display/drm_dp.h>
> > > > +
> > > >  #include <subdev/bios.h>
> > > >  #include <subdev/bios/init.h>
> > > >  #include <subdev/gpio.h>
> > > > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> > > >         return outp->dp.rates != 0;
> > > >  }
> > > >
> > > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> > >
> > > Well.. maybe we should rephrase that _if_ we want to see it
> > > backported. But is this code really that bad? It kinda looks
> > > reasonable enough.
> > >
> > > > + * converted to work inside nvkm. This is a temporary holdover until we start
> > > > + * passing the drm_dp_aux device through NVKM
> > > > + */
> > > > +static int
> > > > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > > > +{
> > > > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > > > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > > > +       int ret;
> > > > +
> > > > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > > > +       if (ret < 0)
> > > > +               return ret;
> > > > +
> > > > +       /*
> > > > +        * Prior to DP1.3 the bit represented by
> > > > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > > > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > > > +        * the true capability of the panel. The only way to check is to
> > > > +        * then compare 0000h and 2200h.
> > > > +        */
> > > > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > > > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > > > +               return 0;
> > > > +
> > > > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > > > +       if (ret < 0)
> > > > +               return ret;
> > > > +
> > > > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > > > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > > > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > > > +               return 0;
> > > > +       }
> > > > +
> > > > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > > > +               return 0;
> > > > +
> > > > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > >  void
> > > >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > > >  {
> > > > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > > >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> > > >                 }
> > > >
> > > > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > > > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> > > >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> > > >                         const u8 *rate;
> > > >                         int rate_max;
> > > > --
> > > > 2.40.1
> > > >
> > >
> >
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> >

before I forget:

Reviewed-by: Karol Herbst <kherbst@redhat.com>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-28  9:59         ` Karol Herbst
  0 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-28  9:59 UTC (permalink / raw)
  To: Lyude Paul; +Cc: nouveau, open list, dri-devel, Ben Skeggs, Dave Airlie

On Fri, Jul 28, 2023 at 1:11 AM Karol Herbst <kherbst@redhat.com> wrote:
>
> On Thu, Jul 27, 2023 at 11:57 PM Lyude Paul <lyude@redhat.com> wrote:
> >
> > On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> > > On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > > >
> > > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > > > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > > > the right thing and also check for extended DPCD caps. However, it turns
> > > > out we're not currently doing this on the nvkm side since we don't have
> > > > access to the drm_dp_aux structure there - which means that the DRM side of
> > > > the driver and the NVKM side can end up with different DPCD capabilities
> > > > for the same connector.
> > > >
> > > > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > > > NVKM before we've made contact with the DRM side - which should be pretty
> > > > easy to accomplish (I'm already working on it!). Until then however, let's
> > > > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > > > NVKM - which should fix this issue.
> > > >
> > > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> > >
> > > Should a Fixes: or Cc: stable tag be added so it gets backported?
> >
> > JFYI I think not adding one is fine nowadays? The stable bot seems to be
> > pretty good at catching anything with the words fix/fixes in it
> >
>
> Yeah not sure.. I'd rather be specific and add it just to be sure.
> Anyway, it could also be done while pushing. I think the bigger
> question here was if this fix is good enough for stable or if you plan
> to rework it.
>
> > >
> > > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > > ---
> > > >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> > > >  1 file changed, 47 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > @@ -26,6 +26,8 @@
> > > >  #include "head.h"
> > > >  #include "ior.h"
> > > >
> > > > +#include <drm/display/drm_dp.h>
> > > > +
> > > >  #include <subdev/bios.h>
> > > >  #include <subdev/bios/init.h>
> > > >  #include <subdev/gpio.h>
> > > > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> > > >         return outp->dp.rates != 0;
> > > >  }
> > > >
> > > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> > >
> > > Well.. maybe we should rephrase that _if_ we want to see it
> > > backported. But is this code really that bad? It kinda looks
> > > reasonable enough.
> > >
> > > > + * converted to work inside nvkm. This is a temporary holdover until we start
> > > > + * passing the drm_dp_aux device through NVKM
> > > > + */
> > > > +static int
> > > > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > > > +{
> > > > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > > > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > > > +       int ret;
> > > > +
> > > > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > > > +       if (ret < 0)
> > > > +               return ret;
> > > > +
> > > > +       /*
> > > > +        * Prior to DP1.3 the bit represented by
> > > > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > > > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > > > +        * the true capability of the panel. The only way to check is to
> > > > +        * then compare 0000h and 2200h.
> > > > +        */
> > > > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > > > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > > > +               return 0;
> > > > +
> > > > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > > > +       if (ret < 0)
> > > > +               return ret;
> > > > +
> > > > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > > > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > > > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > > > +               return 0;
> > > > +       }
> > > > +
> > > > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > > > +               return 0;
> > > > +
> > > > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > >  void
> > > >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > > >  {
> > > > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > > >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> > > >                 }
> > > >
> > > > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > > > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> > > >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> > > >                         const u8 *rate;
> > > >                         int rate_max;
> > > > --
> > > > 2.40.1
> > > >
> > >
> >
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> >

before I forget:

Reviewed-by: Karol Herbst <kherbst@redhat.com>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
@ 2023-07-28  9:59         ` Karol Herbst
  0 siblings, 0 replies; 18+ messages in thread
From: Karol Herbst @ 2023-07-28  9:59 UTC (permalink / raw)
  To: Lyude Paul
  Cc: nouveau, dri-devel, Ben Skeggs, David Airlie, Daniel Vetter,
	Dave Airlie, open list

On Fri, Jul 28, 2023 at 1:11 AM Karol Herbst <kherbst@redhat.com> wrote:
>
> On Thu, Jul 27, 2023 at 11:57 PM Lyude Paul <lyude@redhat.com> wrote:
> >
> > On Sun, 2023-07-09 at 01:42 +0200, Karol Herbst wrote:
> > > On Fri, Jul 7, 2023 at 11:58 PM Lyude Paul <lyude@redhat.com> wrote:
> > > >
> > > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of
> > > > nouveau in order to read the DPCD of a DP connector, which makes sure we do
> > > > the right thing and also check for extended DPCD caps. However, it turns
> > > > out we're not currently doing this on the nvkm side since we don't have
> > > > access to the drm_dp_aux structure there - which means that the DRM side of
> > > > the driver and the NVKM side can end up with different DPCD capabilities
> > > > for the same connector.
> > > >
> > > > Ideally to fix this, we want to start setting up the drm_dp_aux device in
> > > > NVKM before we've made contact with the DRM side - which should be pretty
> > > > easy to accomplish (I'm already working on it!). Until then however, let's
> > > > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into
> > > > NVKM - which should fix this issue.
> > > >
> > > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211
> > >
> > > Should a Fixes: or Cc: stable tag be added so it gets backported?
> >
> > JFYI I think not adding one is fine nowadays? The stable bot seems to be
> > pretty good at catching anything with the words fix/fixes in it
> >
>
> Yeah not sure.. I'd rather be specific and add it just to be sure.
> Anyway, it could also be done while pushing. I think the bigger
> question here was if this fix is good enough for stable or if you plan
> to rework it.
>
> > >
> > > > Signed-off-by: Lyude Paul <lyude@redhat.com>
> > > > ---
> > > >  drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++++++++++++++++++-
> > > >  1 file changed, 47 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > index 40c8ea43c42f..b8ac66b4a2c4 100644
> > > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
> > > > @@ -26,6 +26,8 @@
> > > >  #include "head.h"
> > > >  #include "ior.h"
> > > >
> > > > +#include <drm/display/drm_dp.h>
> > > > +
> > > >  #include <subdev/bios.h>
> > > >  #include <subdev/bios/init.h>
> > > >  #include <subdev/gpio.h>
> > > > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
> > > >         return outp->dp.rates != 0;
> > > >  }
> > > >
> > > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps()
> > >
> > > Well.. maybe we should rephrase that _if_ we want to see it
> > > backported. But is this code really that bad? It kinda looks
> > > reasonable enough.
> > >
> > > > + * converted to work inside nvkm. This is a temporary holdover until we start
> > > > + * passing the drm_dp_aux device through NVKM
> > > > + */
> > > > +static int
> > > > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp)
> > > > +{
> > > > +       struct nvkm_i2c_aux *aux = outp->dp.aux;
> > > > +       u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
> > > > +       int ret;
> > > > +
> > > > +       ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE);
> > > > +       if (ret < 0)
> > > > +               return ret;
> > > > +
> > > > +       /*
> > > > +        * Prior to DP1.3 the bit represented by
> > > > +        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> > > > +        * If it is set DP_DPCD_REV at 0000h could be at a value less than
> > > > +        * the true capability of the panel. The only way to check is to
> > > > +        * then compare 0000h and 2200h.
> > > > +        */
> > > > +       if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > > > +             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> > > > +               return 0;
> > > > +
> > > > +       ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext));
> > > > +       if (ret < 0)
> > > > +               return ret;
> > > > +
> > > > +       if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> > > > +               OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n",
> > > > +                        outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]);
> > > > +               return 0;
> > > > +       }
> > > > +
> > > > +       if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)))
> > > > +               return 0;
> > > > +
> > > > +       memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext));
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > >  void
> > > >  nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > > >  {
> > > > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
> > > >                         memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
> > > >                 }
> > > >
> > > > -               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
> > > > +               if (!nvkm_dp_read_dpcd_caps(outp)) {
> > > >                         const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
> > > >                         const u8 *rate;
> > > >                         int rate_max;
> > > > --
> > > > 2.40.1
> > > >
> > >
> >
> > --
> > Cheers,
> >  Lyude Paul (she/her)
> >  Software Engineer at Red Hat
> >

before I forget:

Reviewed-by: Karol Herbst <kherbst@redhat.com>


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2023-07-28 10:01 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-07 21:58 [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues Lyude Paul
2023-07-07 21:58 ` Lyude Paul
2023-07-07 21:58 ` [Nouveau] " Lyude Paul
2023-07-08 23:42 ` Karol Herbst
2023-07-08 23:42   ` Karol Herbst
2023-07-08 23:42   ` Karol Herbst
2023-07-27 21:57   ` Lyude Paul
2023-07-27 21:57     ` Lyude Paul
2023-07-27 21:57     ` [Nouveau] " Lyude Paul
2023-07-27 23:11     ` Karol Herbst
2023-07-27 23:11       ` [Nouveau] " Karol Herbst
2023-07-27 23:11       ` Karol Herbst
2023-07-28  9:59       ` [Nouveau] " Karol Herbst
2023-07-28  9:59         ` Karol Herbst
2023-07-28  9:59         ` Karol Herbst
2023-07-19  5:17 ` Ben Skeggs
2023-07-19  5:17   ` [Nouveau] " Ben Skeggs
2023-07-19  5:17   ` Ben Skeggs

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.