[Nouveau] [PATCH] disp/gf119-: avoid creating non-existent heads

Ilia Mirkin imirkin at alum.mit.edu
Mon Jul 3 17:06:26 UTC 2017


We assume that each board has 4 heads for GF119+. However this is not
necessarily true - in the case of a GP108 board, the register indicated
that there were only 2.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101601
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---

I'm not extremely happy about the fact that we have to duplicate the head count
in both the nv50_display logic for creating DRM-side CRTC's, as well as the
nvkm-side logic for creating heads. However I don't immediately see an easy way
around it without creating a nvif ioctl to get the number of heads.

 drm/nouveau/nv50_display.c               | 8 +++++---
 drm/nouveau/nvkm/engine/disp/gf119.c     | 2 +-
 drm/nouveau/nvkm/engine/disp/headgf119.c | 4 +++-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drm/nouveau/nv50_display.c b/drm/nouveau/nv50_display.c
index e3132a2c..e2170efb 100644
--- a/drm/nouveau/nv50_display.c
+++ b/drm/nouveau/nv50_display.c
@@ -4443,11 +4443,13 @@ nv50_display_create(struct drm_device *dev)
 
 	/* create crtc objects to represent the hw heads */
 	if (disp->disp->oclass >= GF110_DISP)
-		crtcs = nvif_rd32(&device->object, 0x022448);
+		crtcs = nvif_rd32(&device->object, 0x612004) & 0xf;
 	else
-		crtcs = 2;
+		crtcs = 0x3;
 
-	for (i = 0; i < crtcs; i++) {
+	for (i = 0; i < fls(crtcs); i++) {
+		if (!(crtcs & (1 << i)))
+			continue;
 		ret = nv50_head_create(dev, i);
 		if (ret)
 			goto out;
diff --git a/drm/nouveau/nvkm/engine/disp/gf119.c b/drm/nouveau/nvkm/engine/disp/gf119.c
index d8765b57..415987e9 100644
--- a/drm/nouveau/nvkm/engine/disp/gf119.c
+++ b/drm/nouveau/nvkm/engine/disp/gf119.c
@@ -168,7 +168,7 @@ int
 gf119_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
 		int index, struct nvkm_disp **pdisp)
 {
-	u32 heads = nvkm_rd32(device, 0x022448);
+	u32 heads = fls(nvkm_rd32(device, 0x612004) & 0xf);
 	return nv50_disp_new_(func, device, index, heads, pdisp);
 }
 
diff --git a/drm/nouveau/nvkm/engine/disp/headgf119.c b/drm/nouveau/nvkm/engine/disp/headgf119.c
index b3355275..8d44bdf6 100644
--- a/drm/nouveau/nvkm/engine/disp/headgf119.c
+++ b/drm/nouveau/nvkm/engine/disp/headgf119.c
@@ -92,5 +92,7 @@ gf119_head = {
 int
 gf119_head_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_head_new_(&gf119_head, disp, id);
+	if (nvkm_rd32(disp->engine.subdev.device, 0x612004) & 0xf & (1 << id))
+		return nvkm_head_new_(&gf119_head, disp, id);
+	return 0;
 }
-- 
2.13.0



More information about the Nouveau mailing list