Blob Blame History Raw
From 7df1bb87b8cb0b618e4b5964f89d81d8ce52c58e Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Sat, 17 Jun 2017 11:19:22 +1000
Subject: [PATCH] drm/nouveau/disp/nv50-: avoid creating ORs that aren't present on HW
Git-commit: 7df1bb87b8cb0b618e4b5964f89d81d8ce52c58e
Patch-mainline: v4.13-rc1
References: bsc#1095094

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c |    3 +++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c  |    3 +++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h      |    2 ++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c |    3 +++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c   |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c   |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c |   11 ++++++++++-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c |    2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c  |   11 ++++++++++-
 14 files changed, 39 insertions(+), 10 deletions(-)

--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c
@@ -58,5 +58,8 @@ gf119_dac = {
 int
 gf119_dac_new(struct nvkm_disp *disp, int id)
 {
+	struct nvkm_device *device = disp->engine.subdev.device;
+	if (!(nvkm_rd32(device, 0x612004) & (0x00000010 << id)))
+		return 0;
 	return nvkm_ior_new_(&gf119_dac, disp, DAC, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c
@@ -109,5 +109,8 @@ nv50_dac = {
 int
 nv50_dac_new(struct nvkm_disp *disp, int id)
 {
+	struct nvkm_device *device = disp->engine.subdev.device;
+	if (!(nvkm_rd32(device, 0x610184) & (0x00100000 << id)))
+		return 0;
 	return nvkm_ior_new_(&nv50_dac, disp, DAC, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -104,6 +104,7 @@ nv50_sor_link(struct nvkm_ior *ior)
 	return nv50_ior_base(ior) + ((ior->asy.link == 2) * 0x80);
 }
 
+int nv50_sor_new_(const struct nvkm_ior_func *, struct nvkm_disp *, int id);
 void nv50_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
 void nv50_sor_power(struct nvkm_ior *, bool, bool, bool, bool, bool);
 void nv50_sor_clock(struct nvkm_ior *);
@@ -119,6 +120,7 @@ void g94_sor_dp_watermark(struct nvkm_io
 
 void gt215_sor_dp_audio(struct nvkm_ior *, int, bool);
 
+int gf119_sor_new_(const struct nvkm_ior_func *, struct nvkm_disp *, int id);
 void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
 void gf119_sor_clock(struct nvkm_ior *);
 int gf119_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
@@ -127,5 +127,8 @@ nv50_pior = {
 int
 nv50_pior_new(struct nvkm_disp *disp, int id)
 {
+	struct nvkm_device *device = disp->engine.subdev.device;
+	if (!(nvkm_rd32(device, 0x610184) & (0x10000000 << id)))
+		return 0;
 	return nvkm_ior_new_(&nv50_pior, disp, PIOR, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c
@@ -34,5 +34,5 @@ g84_sor = {
 int
 g84_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&g84_sor, disp, SOR, id);
+	return nv50_sor_new_(&g84_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
@@ -279,5 +279,5 @@ g94_sor = {
 int
 g94_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&g94_sor, disp, SOR, id);
+	return nv50_sor_new_(&g94_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
@@ -152,6 +152,15 @@ gf119_sor_state(struct nvkm_ior *sor, st
 	state->head = ctrl & 0x0000000f;
 }
 
+int
+gf119_sor_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp, int id)
+{
+	struct nvkm_device *device = disp->engine.subdev.device;
+	if (!(nvkm_rd32(device, 0x612004) & (0x00000100 << id)))
+		return 0;
+	return nvkm_ior_new_(func, disp, SOR, id);
+}
+
 static const struct nvkm_ior_func
 gf119_sor = {
 	.state = gf119_sor_state,
@@ -179,5 +188,5 @@ gf119_sor = {
 int
 gf119_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&gf119_sor, disp, SOR, id);
+	return gf119_sor_new_(&gf119_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c
@@ -49,5 +49,5 @@ gk104_sor = {
 int
 gk104_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&gk104_sor, disp, SOR, id);
+	return gf119_sor_new_(&gk104_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
@@ -63,5 +63,5 @@ gm107_sor = {
 int
 gm107_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&gm107_sor, disp, SOR, id);
+	return gf119_sor_new_(&gm107_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
@@ -120,5 +120,5 @@ gm200_sor = {
 int
 gm200_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&gm200_sor, disp, SOR, id);
+	return gf119_sor_new_(&gm200_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c
@@ -65,5 +65,5 @@ gt215_sor = {
 int
 gt215_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&gt215_sor, disp, SOR, id);
+	return nv50_sor_new_(&gt215_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c
@@ -44,5 +44,5 @@ mcp77_sor = {
 int
 mcp77_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&mcp77_sor, disp, SOR, id);
+	return nv50_sor_new_(&mcp77_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c
@@ -49,5 +49,5 @@ mcp89_sor = {
 int
 mcp89_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&mcp89_sor, disp, SOR, id);
+	return nv50_sor_new_(&mcp89_sor, disp, id);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c
@@ -84,6 +84,15 @@ nv50_sor_state(struct nvkm_ior *sor, str
 	state->head = ctrl & 0x00000003;
 }
 
+int
+nv50_sor_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp, int id)
+{
+	struct nvkm_device *device = disp->engine.subdev.device;
+	if (!(nvkm_rd32(device, 0x610184) & (0x01000000 << id)))
+		return 0;
+	return nvkm_ior_new_(func, disp, SOR, id);
+}
+
 static const struct nvkm_ior_func
 nv50_sor = {
 	.state = nv50_sor_state,
@@ -94,5 +103,5 @@ nv50_sor = {
 int
 nv50_sor_new(struct nvkm_disp *disp, int id)
 {
-	return nvkm_ior_new_(&nv50_sor, disp, SOR, id);
+	return nv50_sor_new_(&nv50_sor, disp, id);
 }