Blob Blame History Raw
From 1f0c9eaf31bba3e1cac5534ba17602c115b76cf8 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Fri, 19 May 2017 23:59:35 +1000
Subject: [PATCH] drm/nouveau/disp/nv50-: implement a common supervisor 2.1
Git-commit: 1f0c9eaf31bba3e1cac5534ba17602c115b76cf8
Patch-mainline: v4.13-rc1
References: bsc#1095094

This makes use of all the additional routing and state added in previous
commits, making it possible to deal with GM20x macro link routing, while
also sharing code between the NV50 and GF119 implementations.

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

---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c |   15 ++-------------
 drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c  |   16 ++++++++--------
 drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h  |    1 +
 3 files changed, 11 insertions(+), 21 deletions(-)

--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
@@ -139,17 +139,6 @@ exec_clkcmp(struct nv50_disp *disp, int
 }
 
 static void
-gf119_disp_intr_unk2_1(struct nv50_disp *disp, int head)
-{
-	struct nvkm_device *device = disp->base.engine.subdev.device;
-	struct nvkm_devinit *devinit = device->devinit;
-	u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
-	if (pclk)
-		nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head, pclk);
-	nvkm_wr32(device, 0x612200 + (head * 0x800), 0x00000000);
-}
-
-static void
 gf119_disp_intr_unk2_2_tu(struct nv50_disp *disp, int head,
 			  struct dcb_output *outp)
 {
@@ -260,6 +249,7 @@ gf119_disp_intr_unk2_2(struct nv50_disp
 	}
 
 	nvkm_mask(device, addr, 0x00000707, data);
+	nvkm_wr32(device, 0x612200 + (head * 0x800), 0x00000000);
 }
 
 static void
@@ -307,8 +297,7 @@ gf119_disp_super(struct work_struct *wor
 		list_for_each_entry(head, &disp->base.head, head) {
 			if (!(mask[head->id] & 0x00010000))
 				continue;
-			nvkm_debug(subdev, "supervisor 2.1 - head %d\n", head->id);
-			gf119_disp_intr_unk2_1(disp, head->id);
+			nv50_disp_super_2_1(disp, head);
 		}
 		list_for_each_entry(head, &disp->base.head, head) {
 			if (!(mask[head->id] & 0x00001000))
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
@@ -532,14 +532,14 @@ nv50_disp_intr_unk20_2(struct nv50_disp
 	nv50_disp_dptmds_war_2(disp, &outp->info);
 }
 
-static void
-nv50_disp_intr_unk20_1(struct nv50_disp *disp, int head)
+void
+nv50_disp_super_2_1(struct nv50_disp *disp, struct nvkm_head *head)
 {
-	struct nvkm_device *device = disp->base.engine.subdev.device;
-	struct nvkm_devinit *devinit = device->devinit;
-	u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff;
-	if (pclk)
-		nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head, pclk);
+	struct nvkm_devinit *devinit = disp->base.engine.subdev.device->devinit;
+	u32 khz = head->asy.hz / 1000;
+	HEAD_DBG(head, "supervisor 2.1 - %d khz", khz);
+	if (khz)
+		nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head->id, khz);
 }
 
 void
@@ -631,7 +631,7 @@ nv50_disp_super(struct work_struct *work
 		list_for_each_entry(head, &disp->base.head, head) {
 			if (!(super & (0x00000200 << head->id)))
 				continue;
-			nv50_disp_intr_unk20_1(disp, head->id);
+			nv50_disp_super_2_1(disp, head);
 		}
 		list_for_each_entry(head, &disp->base.head, head) {
 			if (!(super & (0x00000080 << head->id)))
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
@@ -29,6 +29,7 @@ struct nv50_disp {
 void nv50_disp_super_1(struct nv50_disp *);
 void nv50_disp_super_1_0(struct nv50_disp *, struct nvkm_head *);
 void nv50_disp_super_2_0(struct nv50_disp *, struct nvkm_head *);
+void nv50_disp_super_2_1(struct nv50_disp *, struct nvkm_head *);
 
 int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *,
 		   int index, int heads, struct nvkm_disp **);