From: Lyude Paul <lyude@redhat.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
nouveau@lists.freedesktop.org
Cc: David Airlie <airlied@linux.ie>, Ben Skeggs <bskeggs@redhat.com>,
open list <linux-kernel@vger.kernel.org>
Subject: [Intel-gfx] [RFC v2 17/20] drm/nouveau/kms/nv50-: Add support for DP_SINK_COUNT
Date: Thu, 20 Aug 2020 14:30:09 -0400 [thread overview]
Message-ID: <20200820183012.288794-18-lyude@redhat.com> (raw)
In-Reply-To: <20200820183012.288794-1-lyude@redhat.com>
This is another bit that we never implemented for nouveau: dongle
detection. When a "dongle", e.g. an active display adaptor, is hooked up
to the system and causes an HPD to be fired, we don't actually know
whether or not there's anything plugged into the dongle without checking
the sink count. As a result, plugging in a dongle without anything
plugged into it currently results in a bogus EDID retrieval error in the kernel log.
Additionally, most dongles won't send another long HPD signal if the
user suddenly plugs something in, they'll only send a short HPD IRQ with
the expectation that the source will check the sink count and reprobe
the connector if it's changed - something we don't actually do. As a
result, nothing will happen if the user plugs the dongle in before
plugging something into the dongle.
So, let's fix this by checking the sink count in both
nouveau_dp_probe_dpcd() and nouveau_dp_irq(), and reprobing the
connector if things change.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
---
drivers/gpu/drm/nouveau/nouveau_dp.c | 54 ++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_encoder.h | 2 +
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index c200f197083f9..89afc97ee2591 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -36,12 +36,22 @@ MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1;
module_param_named(mst, nouveau_mst, int, 0400);
+static bool
+nouveau_dp_has_sink_count(struct drm_connector *connector,
+ struct nouveau_encoder *outp)
+{
+ return drm_dp_has_sink_count(connector, outp->dp.dpcd,
+ &outp->dp.desc);
+}
+
static enum drm_connector_status
nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
struct nouveau_encoder *outp)
{
+ struct drm_connector *connector = &nv_connector->base;
struct drm_dp_aux *aux = &nv_connector->aux;
struct nv50_mstm *mstm = NULL;
+ enum drm_connector_status status = connector_status_disconnected;
int ret;
u8 *dpcd = outp->dp.dpcd;
@@ -50,9 +60,9 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
ret = drm_dp_read_desc(aux, &outp->dp.desc,
drm_dp_is_branch(dpcd));
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
} else {
- return connector_status_disconnected;
+ goto out;
}
if (nouveau_mst) {
@@ -61,12 +71,33 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
mstm->can_mst = drm_dp_has_mst(aux, dpcd);
}
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(aux);
+ if (ret < 0)
+ goto out;
+
+ outp->dp.sink_count = ret;
+
+ /*
+ * Dongle connected, but no display. Don't bother reading
+ * downstream port info
+ */
+ if (!outp->dp.sink_count)
+ return connector_status_disconnected;
+ }
+
ret = drm_dp_downstream_read_info(aux, dpcd,
outp->dp.downstream_ports);
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
- return connector_status_connected;
+ status = connector_status_connected;
+out:
+ if (status != connector_status_connected) {
+ /* Clear any cached info */
+ outp->dp.sink_count = 0;
+ }
+ return status;
}
int
@@ -159,6 +190,8 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
struct drm_connector *connector = &nv_connector->base;
struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
struct nv50_mstm *mstm;
+ int ret;
+ bool send_hpd = false;
if (!outp)
return;
@@ -170,12 +203,23 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
if (mstm && mstm->is_mst) {
if (!nv50_mstm_service(drm, nv_connector, mstm))
- nouveau_connector_hpd(connector);
+ send_hpd = true;
} else {
drm_dp_cec_irq(&nv_connector->aux);
+
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(&nv_connector->aux);
+ if (ret != outp->dp.sink_count)
+ send_hpd = true;
+ if (ret >= 0)
+ outp->dp.sink_count = ret;
+ }
}
mutex_unlock(&outp->dp.hpd_irq_lock);
+
+ if (send_hpd)
+ nouveau_connector_hpd(connector);
}
/* TODO:
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index c1924a4529a7b..21937f1c7dd90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -74,6 +74,8 @@ struct nouveau_encoder {
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
struct drm_dp_desc desc;
+
+ u8 sink_count;
} dp;
};
--
2.26.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
WARNING: multiple messages have this Message-ID (diff)
From: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: David Airlie <airlied-cv59FeDIM0c@public.gmane.org>,
Ben Skeggs <bskeggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org>,
open list <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: [RFC v2 17/20] drm/nouveau/kms/nv50-: Add support for DP_SINK_COUNT
Date: Thu, 20 Aug 2020 14:30:09 -0400 [thread overview]
Message-ID: <20200820183012.288794-18-lyude@redhat.com> (raw)
In-Reply-To: <20200820183012.288794-1-lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
This is another bit that we never implemented for nouveau: dongle
detection. When a "dongle", e.g. an active display adaptor, is hooked up
to the system and causes an HPD to be fired, we don't actually know
whether or not there's anything plugged into the dongle without checking
the sink count. As a result, plugging in a dongle without anything
plugged into it currently results in a bogus EDID retrieval error in the kernel log.
Additionally, most dongles won't send another long HPD signal if the
user suddenly plugs something in, they'll only send a short HPD IRQ with
the expectation that the source will check the sink count and reprobe
the connector if it's changed - something we don't actually do. As a
result, nothing will happen if the user plugs the dongle in before
plugging something into the dongle.
So, let's fix this by checking the sink count in both
nouveau_dp_probe_dpcd() and nouveau_dp_irq(), and reprobing the
connector if things change.
Signed-off-by: Lyude Paul <lyude-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Ben Skeggs <bskeggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/gpu/drm/nouveau/nouveau_dp.c | 54 ++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_encoder.h | 2 +
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index c200f197083f9..89afc97ee2591 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -36,12 +36,22 @@ MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1;
module_param_named(mst, nouveau_mst, int, 0400);
+static bool
+nouveau_dp_has_sink_count(struct drm_connector *connector,
+ struct nouveau_encoder *outp)
+{
+ return drm_dp_has_sink_count(connector, outp->dp.dpcd,
+ &outp->dp.desc);
+}
+
static enum drm_connector_status
nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
struct nouveau_encoder *outp)
{
+ struct drm_connector *connector = &nv_connector->base;
struct drm_dp_aux *aux = &nv_connector->aux;
struct nv50_mstm *mstm = NULL;
+ enum drm_connector_status status = connector_status_disconnected;
int ret;
u8 *dpcd = outp->dp.dpcd;
@@ -50,9 +60,9 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
ret = drm_dp_read_desc(aux, &outp->dp.desc,
drm_dp_is_branch(dpcd));
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
} else {
- return connector_status_disconnected;
+ goto out;
}
if (nouveau_mst) {
@@ -61,12 +71,33 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
mstm->can_mst = drm_dp_has_mst(aux, dpcd);
}
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(aux);
+ if (ret < 0)
+ goto out;
+
+ outp->dp.sink_count = ret;
+
+ /*
+ * Dongle connected, but no display. Don't bother reading
+ * downstream port info
+ */
+ if (!outp->dp.sink_count)
+ return connector_status_disconnected;
+ }
+
ret = drm_dp_downstream_read_info(aux, dpcd,
outp->dp.downstream_ports);
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
- return connector_status_connected;
+ status = connector_status_connected;
+out:
+ if (status != connector_status_connected) {
+ /* Clear any cached info */
+ outp->dp.sink_count = 0;
+ }
+ return status;
}
int
@@ -159,6 +190,8 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
struct drm_connector *connector = &nv_connector->base;
struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
struct nv50_mstm *mstm;
+ int ret;
+ bool send_hpd = false;
if (!outp)
return;
@@ -170,12 +203,23 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
if (mstm && mstm->is_mst) {
if (!nv50_mstm_service(drm, nv_connector, mstm))
- nouveau_connector_hpd(connector);
+ send_hpd = true;
} else {
drm_dp_cec_irq(&nv_connector->aux);
+
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(&nv_connector->aux);
+ if (ret != outp->dp.sink_count)
+ send_hpd = true;
+ if (ret >= 0)
+ outp->dp.sink_count = ret;
+ }
}
mutex_unlock(&outp->dp.hpd_irq_lock);
+
+ if (send_hpd)
+ nouveau_connector_hpd(connector);
}
/* TODO:
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index c1924a4529a7b..21937f1c7dd90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -74,6 +74,8 @@ struct nouveau_encoder {
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
struct drm_dp_desc desc;
+
+ u8 sink_count;
} dp;
};
--
2.26.2
WARNING: multiple messages have this Message-ID (diff)
From: Lyude Paul <lyude@redhat.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
nouveau@lists.freedesktop.org
Cc: David Airlie <airlied@linux.ie>, Ben Skeggs <bskeggs@redhat.com>,
open list <linux-kernel@vger.kernel.org>
Subject: [RFC v2 17/20] drm/nouveau/kms/nv50-: Add support for DP_SINK_COUNT
Date: Thu, 20 Aug 2020 14:30:09 -0400 [thread overview]
Message-ID: <20200820183012.288794-18-lyude@redhat.com> (raw)
In-Reply-To: <20200820183012.288794-1-lyude@redhat.com>
This is another bit that we never implemented for nouveau: dongle
detection. When a "dongle", e.g. an active display adaptor, is hooked up
to the system and causes an HPD to be fired, we don't actually know
whether or not there's anything plugged into the dongle without checking
the sink count. As a result, plugging in a dongle without anything
plugged into it currently results in a bogus EDID retrieval error in the kernel log.
Additionally, most dongles won't send another long HPD signal if the
user suddenly plugs something in, they'll only send a short HPD IRQ with
the expectation that the source will check the sink count and reprobe
the connector if it's changed - something we don't actually do. As a
result, nothing will happen if the user plugs the dongle in before
plugging something into the dongle.
So, let's fix this by checking the sink count in both
nouveau_dp_probe_dpcd() and nouveau_dp_irq(), and reprobing the
connector if things change.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
---
drivers/gpu/drm/nouveau/nouveau_dp.c | 54 ++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_encoder.h | 2 +
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index c200f197083f9..89afc97ee2591 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -36,12 +36,22 @@ MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1;
module_param_named(mst, nouveau_mst, int, 0400);
+static bool
+nouveau_dp_has_sink_count(struct drm_connector *connector,
+ struct nouveau_encoder *outp)
+{
+ return drm_dp_has_sink_count(connector, outp->dp.dpcd,
+ &outp->dp.desc);
+}
+
static enum drm_connector_status
nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
struct nouveau_encoder *outp)
{
+ struct drm_connector *connector = &nv_connector->base;
struct drm_dp_aux *aux = &nv_connector->aux;
struct nv50_mstm *mstm = NULL;
+ enum drm_connector_status status = connector_status_disconnected;
int ret;
u8 *dpcd = outp->dp.dpcd;
@@ -50,9 +60,9 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
ret = drm_dp_read_desc(aux, &outp->dp.desc,
drm_dp_is_branch(dpcd));
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
} else {
- return connector_status_disconnected;
+ goto out;
}
if (nouveau_mst) {
@@ -61,12 +71,33 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
mstm->can_mst = drm_dp_has_mst(aux, dpcd);
}
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(aux);
+ if (ret < 0)
+ goto out;
+
+ outp->dp.sink_count = ret;
+
+ /*
+ * Dongle connected, but no display. Don't bother reading
+ * downstream port info
+ */
+ if (!outp->dp.sink_count)
+ return connector_status_disconnected;
+ }
+
ret = drm_dp_downstream_read_info(aux, dpcd,
outp->dp.downstream_ports);
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
- return connector_status_connected;
+ status = connector_status_connected;
+out:
+ if (status != connector_status_connected) {
+ /* Clear any cached info */
+ outp->dp.sink_count = 0;
+ }
+ return status;
}
int
@@ -159,6 +190,8 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
struct drm_connector *connector = &nv_connector->base;
struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
struct nv50_mstm *mstm;
+ int ret;
+ bool send_hpd = false;
if (!outp)
return;
@@ -170,12 +203,23 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
if (mstm && mstm->is_mst) {
if (!nv50_mstm_service(drm, nv_connector, mstm))
- nouveau_connector_hpd(connector);
+ send_hpd = true;
} else {
drm_dp_cec_irq(&nv_connector->aux);
+
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(&nv_connector->aux);
+ if (ret != outp->dp.sink_count)
+ send_hpd = true;
+ if (ret >= 0)
+ outp->dp.sink_count = ret;
+ }
}
mutex_unlock(&outp->dp.hpd_irq_lock);
+
+ if (send_hpd)
+ nouveau_connector_hpd(connector);
}
/* TODO:
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index c1924a4529a7b..21937f1c7dd90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -74,6 +74,8 @@ struct nouveau_encoder {
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
struct drm_dp_desc desc;
+
+ u8 sink_count;
} dp;
};
--
2.26.2
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
WARNING: multiple messages have this Message-ID (diff)
From: Lyude Paul <lyude@redhat.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
nouveau@lists.freedesktop.org
Cc: Ben Skeggs <bskeggs@redhat.com>, David Airlie <airlied@linux.ie>,
Daniel Vetter <daniel@ffwll.ch>,
linux-kernel@vger.kernel.org (open list)
Subject: [RFC v2 17/20] drm/nouveau/kms/nv50-: Add support for DP_SINK_COUNT
Date: Thu, 20 Aug 2020 14:30:09 -0400 [thread overview]
Message-ID: <20200820183012.288794-18-lyude@redhat.com> (raw)
In-Reply-To: <20200820183012.288794-1-lyude@redhat.com>
This is another bit that we never implemented for nouveau: dongle
detection. When a "dongle", e.g. an active display adaptor, is hooked up
to the system and causes an HPD to be fired, we don't actually know
whether or not there's anything plugged into the dongle without checking
the sink count. As a result, plugging in a dongle without anything
plugged into it currently results in a bogus EDID retrieval error in the kernel log.
Additionally, most dongles won't send another long HPD signal if the
user suddenly plugs something in, they'll only send a short HPD IRQ with
the expectation that the source will check the sink count and reprobe
the connector if it's changed - something we don't actually do. As a
result, nothing will happen if the user plugs the dongle in before
plugging something into the dongle.
So, let's fix this by checking the sink count in both
nouveau_dp_probe_dpcd() and nouveau_dp_irq(), and reprobing the
connector if things change.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
---
drivers/gpu/drm/nouveau/nouveau_dp.c | 54 ++++++++++++++++++++---
drivers/gpu/drm/nouveau/nouveau_encoder.h | 2 +
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index c200f197083f9..89afc97ee2591 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -36,12 +36,22 @@ MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1;
module_param_named(mst, nouveau_mst, int, 0400);
+static bool
+nouveau_dp_has_sink_count(struct drm_connector *connector,
+ struct nouveau_encoder *outp)
+{
+ return drm_dp_has_sink_count(connector, outp->dp.dpcd,
+ &outp->dp.desc);
+}
+
static enum drm_connector_status
nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
struct nouveau_encoder *outp)
{
+ struct drm_connector *connector = &nv_connector->base;
struct drm_dp_aux *aux = &nv_connector->aux;
struct nv50_mstm *mstm = NULL;
+ enum drm_connector_status status = connector_status_disconnected;
int ret;
u8 *dpcd = outp->dp.dpcd;
@@ -50,9 +60,9 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
ret = drm_dp_read_desc(aux, &outp->dp.desc,
drm_dp_is_branch(dpcd));
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
} else {
- return connector_status_disconnected;
+ goto out;
}
if (nouveau_mst) {
@@ -61,12 +71,33 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
mstm->can_mst = drm_dp_has_mst(aux, dpcd);
}
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(aux);
+ if (ret < 0)
+ goto out;
+
+ outp->dp.sink_count = ret;
+
+ /*
+ * Dongle connected, but no display. Don't bother reading
+ * downstream port info
+ */
+ if (!outp->dp.sink_count)
+ return connector_status_disconnected;
+ }
+
ret = drm_dp_downstream_read_info(aux, dpcd,
outp->dp.downstream_ports);
if (ret < 0)
- return connector_status_disconnected;
+ goto out;
- return connector_status_connected;
+ status = connector_status_connected;
+out:
+ if (status != connector_status_connected) {
+ /* Clear any cached info */
+ outp->dp.sink_count = 0;
+ }
+ return status;
}
int
@@ -159,6 +190,8 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
struct drm_connector *connector = &nv_connector->base;
struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
struct nv50_mstm *mstm;
+ int ret;
+ bool send_hpd = false;
if (!outp)
return;
@@ -170,12 +203,23 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
if (mstm && mstm->is_mst) {
if (!nv50_mstm_service(drm, nv_connector, mstm))
- nouveau_connector_hpd(connector);
+ send_hpd = true;
} else {
drm_dp_cec_irq(&nv_connector->aux);
+
+ if (nouveau_dp_has_sink_count(connector, outp)) {
+ ret = drm_dp_get_sink_count(&nv_connector->aux);
+ if (ret != outp->dp.sink_count)
+ send_hpd = true;
+ if (ret >= 0)
+ outp->dp.sink_count = ret;
+ }
}
mutex_unlock(&outp->dp.hpd_irq_lock);
+
+ if (send_hpd)
+ nouveau_connector_hpd(connector);
}
/* TODO:
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index c1924a4529a7b..21937f1c7dd90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -74,6 +74,8 @@ struct nouveau_encoder {
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
struct drm_dp_desc desc;
+
+ u8 sink_count;
} dp;
};
--
2.26.2
next prev parent reply other threads:[~2020-08-20 18:32 UTC|newest]
Thread overview: 103+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-20 18:29 [Intel-gfx] [RFC v2 00/20] drm/dp, i915, nouveau: Cleanup nouveau HPD and add DP features from i915 Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 01/20] drm/nouveau/kms: Fix some indenting in nouveau_dp_detect() Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 02/20] drm/nouveau/kms/nv50-: Remove open-coded drm_dp_read_desc() Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 03/20] drm/nouveau/kms/nv50-: Just use drm_dp_dpcd_read() in nouveau_dp.c Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 04/20] drm/nouveau/kms/nv50-: Use macros for DP registers " Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 05/20] drm/nouveau/kms: Don't clear DP_MST_CTRL DPCD in nv50_mstm_new() Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 06/20] drm/nouveau/kms: Search for encoders' connectors properly Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-21 12:10 ` Dan Carpenter
2020-08-21 12:10 ` Dan Carpenter
2020-08-21 17:48 ` [Intel-gfx] [RFC v3] " Lyude Paul
2020-08-21 17:48 ` Lyude Paul
2020-08-21 17:48 ` Lyude Paul
2020-08-21 17:48 ` Lyude Paul
2020-08-20 18:29 ` [Intel-gfx] [RFC v2 07/20] drm/nouveau/kms/nv50-: Use drm_dp_dpcd_(readb|writeb)() in nv50_sor_disable() Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:29 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 08/20] drm/nouveau/kms/nv50-: Refactor and cleanup DP HPD handling Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-24 11:14 ` [Intel-gfx] " Dan Carpenter
2020-08-24 11:14 ` Dan Carpenter
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 09/20] drm/i915/dp: Extract drm_dp_has_mst() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 10/20] drm/nouveau/kms: Use new drm_dp_has_mst() helper for checking MST caps Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 11/20] drm/nouveau/kms: Move drm_dp_cec_unset_edid() into nouveau_connector_detect() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 12/20] drm/nouveau/kms: Only use hpd_work for reprobing in HPD paths Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 13/20] drm/i915/dp: Extract drm_dp_downstream_read_info() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-21 19:27 ` [Intel-gfx] " Sean Paul
2020-08-21 19:27 ` Sean Paul
2020-08-21 19:27 ` Sean Paul
2020-08-21 19:27 ` Sean Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 14/20] drm/nouveau/kms/nv50-: Use downstream DP clock limits for mode validation Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 15/20] drm/i915/dp: Extract drm_dp_has_sink_count() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 16/20] drm/i915/dp: Extract drm_dp_get_sink_count() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul [this message]
2020-08-20 18:30 ` [RFC v2 17/20] drm/nouveau/kms/nv50-: Add support for DP_SINK_COUNT Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 18/20] drm/nouveau/kms: Don't change EDID when it hasn't actually changed Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 19/20] drm/i915/dp: Extract drm_dp_read_dpcd_caps() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` [Intel-gfx] [RFC v2 20/20] drm/nouveau/kms: Start using drm_dp_read_dpcd_caps() Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 18:30 ` Lyude Paul
2020-08-20 19:11 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/dp, i915, nouveau: Cleanup nouveau HPD and add DP features from i915 (rev4) Patchwork
2020-08-20 19:12 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-08-20 19:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-08-21 5:16 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2020-08-21 17:57 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/dp, i915, nouveau: Cleanup nouveau HPD and add DP features from i915 (rev5) Patchwork
2020-08-21 17:58 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-08-21 18:13 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-08-21 20:38 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200820183012.288794-18-lyude@redhat.com \
--to=lyude@redhat.com \
--cc=airlied@linux.ie \
--cc=bskeggs@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nouveau@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.