drm/nouveau/disp/nv50-: implement a common supervisor 2.1
authorBen Skeggs <bskeggs@redhat.com>
Fri, 19 May 2017 13:59:35 +0000 (23:59 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 16 Jun 2017 04:05:00 +0000 (14:05 +1000)
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>
drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h

index 986069f82d242cc1f21db12c20eec45a8579b68b..d25b3b7f4fb8b92a9191030b644e4fa51aa43c4a 100644 (file)
@@ -138,17 +138,6 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
        return outp;
 }
 
-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 *disp, int head)
        }
 
        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 *work)
                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))
index 6c51045e284af95db6a9e5b5e0b94ac334aba35c..ebe7657bf2afdfabd0007abd32bf5fd604039075 100644 (file)
@@ -532,14 +532,14 @@ nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head)
        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)))
index f6bafe6dcaa43a91db83d2e5dd1fa933089d5178..310a568c3fdb34cc12a09afbcb0687d8bd97294d 100644 (file)
@@ -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 **);