Ben Skeggs
2023-Jul-19  04:40 UTC
[Nouveau] [PATCH 1/3] drm/nouveau/i2c: fix number of aux event slots
From: Ben Skeggs <bskeggs at redhat.com>
This was completely bogus before, using maximum DCB device index rather
than maximum AUX ID to size the buffer that stores event refcounts.
*Pretty* unlikely to have been an actual problem on most configurations,
that is, unless you've got one of the rare boards that have off-chip DP.
There, it'll likely crash.
Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h |  4 ++--
 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c    | 11 +++++++++--
 2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
index 40a1065ae626..ef441dfdea09 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
@@ -16,7 +16,7 @@ struct nvkm_i2c_bus {
 	const struct nvkm_i2c_bus_func *func;
 	struct nvkm_i2c_pad *pad;
 #define NVKM_I2C_BUS_CCB(n) /* 'n' is ccb index */                     
(n)
-#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n)
+ 0x100)
+#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ 
((n) + 0x10)
 #define NVKM_I2C_BUS_PRI /* ccb primary comm. port */                        -1
 #define NVKM_I2C_BUS_SEC /* ccb secondary comm. port */                      -2
 	int id;
@@ -38,7 +38,7 @@ struct nvkm_i2c_aux {
 	const struct nvkm_i2c_aux_func *func;
 	struct nvkm_i2c_pad *pad;
 #define NVKM_I2C_AUX_CCB(n) /* 'n' is ccb index */                     
(n)
-#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n)
+ 0x100)
+#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ 
((n) + 0x10)
 	int id;
 
 	struct mutex mutex;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
index 976539de4220..731b2f68d3db 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
@@ -260,10 +260,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct
nvkm_device *device,
 {
 	struct nvkm_bios *bios = device->bios;
 	struct nvkm_i2c *i2c;
+	struct nvkm_i2c_aux *aux;
 	struct dcb_i2c_entry ccbE;
 	struct dcb_output dcbE;
 	u8 ver, hdr;
-	int ret, i;
+	int ret, i, ids;
 
 	if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL)))
 		return -ENOMEM;
@@ -406,5 +407,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct
nvkm_device *device,
 		}
 	}
 
-	return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, i,
&i2c->event);
+	ids = 0;
+	list_for_each_entry(aux, &i2c->aux, head)
+		ids = max(ids, aux->id + 1);
+	if (!ids)
+		return 0;
+
+	return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, ids,
&i2c->event);
 }
-- 
2.41.0
Ben Skeggs
2023-Jul-19  04:40 UTC
[Nouveau] [PATCH 2/3] drm/nouveau/disp: PIOR DP uses GPIO for HPD, not PMGR AUX interrupts
From: Ben Skeggs <bskeggs at redhat.com>
Fixes crash on boards with ANX9805 TMDS/DP encoders.
Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
---
 .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c  | 27 ++++++++++++-------
 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
index dad942be6679..46b057fe1412 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
@@ -81,20 +81,29 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv,
u32 argc, struct nvkm_
 		return -ENOSYS;
 
 	list_for_each_entry(outp, &conn->disp->outps, head) {
-		if (outp->info.connector == conn->index && outp->dp.aux) {
-			if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |=
NVKM_I2C_PLUG;
-			if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |=
NVKM_I2C_UNPLUG;
-			if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ   ) bits |= NVKM_I2C_IRQ;
+		if (outp->info.connector == conn->index)
+			break;
+	}
 
-			return nvkm_uevent_add(uevent, &device->i2c->event,
outp->dp.aux->id, bits,
-					       nvkm_uconn_uevent_aux);
-		}
+	if (&outp->head == &conn->disp->outps)
+		return -EINVAL;
+
+	if (outp->dp.aux && !outp->info.location) {
+		if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_I2C_PLUG;
+		if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |=
NVKM_I2C_UNPLUG;
+		if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ   ) bits |= NVKM_I2C_IRQ;
+
+		return nvkm_uevent_add(uevent, &device->i2c->event,
outp->dp.aux->id, bits,
+				       nvkm_uconn_uevent_aux);
 	}
 
 	if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_GPIO_HI;
 	if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO;
-	if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ)
-		return -EINVAL;
+	if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) {
+		/* TODO: support DP IRQ on ANX9805 and remove this hack. */
+		if (!outp->info.location)
+			return -EINVAL;
+	}
 
 	return nvkm_uevent_add(uevent, &device->gpio->event,
conn->info.hpd, bits,
 			       nvkm_uconn_uevent_gpio);
-- 
2.41.0
Ben Skeggs
2023-Jul-19  04:40 UTC
[Nouveau] [PATCH 3/3] drm/nouveau/kms/nv50-: init hpd_irq_lock for PIOR DP
From: Ben Skeggs <bskeggs at redhat.com> Fixes OOPS on boards with ANX9805 DP encoders. Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 42e1665ba11a..1ecd3d63b108 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1873,6 +1873,8 @@ nv50_pior_destroy(struct drm_encoder *encoder) nvif_outp_dtor(&nv_encoder->outp); drm_encoder_cleanup(encoder); + + mutex_destroy(&nv_encoder->dp.hpd_irq_lock); kfree(encoder); } @@ -1917,6 +1919,8 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) nv_encoder->i2c = ddc; nv_encoder->aux = aux; + mutex_init(&nv_encoder->dp.hpd_irq_lock); + encoder = to_drm_encoder(nv_encoder); encoder->possible_crtcs = dcbe->heads; encoder->possible_clones = 0; -- 2.41.0
Karol Herbst
2023-Jul-19  09:00 UTC
[Nouveau] [PATCH 1/3] drm/nouveau/i2c: fix number of aux event slots
On Wed, Jul 19, 2023 at 6:41?AM Ben Skeggs <skeggsb at gmail.com> wrote:> > From: Ben Skeggs <bskeggs at redhat.com> > > This was completely bogus before, using maximum DCB device index rather > than maximum AUX ID to size the buffer that stores event refcounts. > > *Pretty* unlikely to have been an actual problem on most configurations, > that is, unless you've got one of the rare boards that have off-chip DP. > > There, it'll likely crash. > > Signed-off-by: Ben Skeggs <bskeggs at redhat.com> > --- > drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h | 4 ++-- > drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 11 +++++++++-- > 2 files changed, 11 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h > index 40a1065ae626..ef441dfdea09 100644 > --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h > +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h > @@ -16,7 +16,7 @@ struct nvkm_i2c_bus { > const struct nvkm_i2c_bus_func *func; > struct nvkm_i2c_pad *pad; > #define NVKM_I2C_BUS_CCB(n) /* 'n' is ccb index */ (n) > -#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100) > +#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x10) > #define NVKM_I2C_BUS_PRI /* ccb primary comm. port */ -1 > #define NVKM_I2C_BUS_SEC /* ccb secondary comm. port */ -2 > int id; > @@ -38,7 +38,7 @@ struct nvkm_i2c_aux { > const struct nvkm_i2c_aux_func *func; > struct nvkm_i2c_pad *pad; > #define NVKM_I2C_AUX_CCB(n) /* 'n' is ccb index */ (n) > -#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100) > +#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x10) > int id; > > struct mutex mutex; > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c > index 976539de4220..731b2f68d3db 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c > @@ -260,10 +260,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device, > { > struct nvkm_bios *bios = device->bios; > struct nvkm_i2c *i2c; > + struct nvkm_i2c_aux *aux; > struct dcb_i2c_entry ccbE; > struct dcb_output dcbE; > u8 ver, hdr; > - int ret, i; > + int ret, i, ids; > > if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) > return -ENOMEM; > @@ -406,5 +407,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device, > } > } > > - return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, i, &i2c->event); > + ids = 0; > + list_for_each_entry(aux, &i2c->aux, head) > + ids = max(ids, aux->id + 1); > + if (!ids) > + return 0; > + > + return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, ids, &i2c->event); > } > -- > 2.41.0 >Reviewed-by: Karol Herbst <kherbst at redhat.com>