]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/nouveau/disp/nv50-: initialise from the engine, rather than the user object
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:46 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:20 +0000 (15:01 +1000)
Engines are initialised on an as-needed basis, so this results in the
same behaviour, whilst allowing us to simplify things a bit.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
33 files changed:
drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h

index 5b9d9c632aeb1ba54ad3bfcc9cfb1940a3a53615..32fa94a9773f558686cf8a698ac3de53305a6007 100644 (file)
@@ -220,6 +220,9 @@ nvkm_disp_fini(struct nvkm_engine *engine, bool suspend)
        struct nvkm_conn *conn;
        struct nvkm_outp *outp;
 
+       if (disp->func->fini)
+               disp->func->fini(disp);
+
        list_for_each_entry(outp, &disp->outp, head) {
                nvkm_outp_fini(outp);
        }
@@ -237,6 +240,7 @@ nvkm_disp_init(struct nvkm_engine *engine)
        struct nvkm_disp *disp = nvkm_disp(engine);
        struct nvkm_conn *conn;
        struct nvkm_outp *outp;
+       struct nvkm_ior *ior;
 
        list_for_each_entry(conn, &disp->conn, head) {
                nvkm_conn_init(conn);
@@ -246,6 +250,19 @@ nvkm_disp_init(struct nvkm_engine *engine)
                nvkm_outp_init(outp);
        }
 
+       if (disp->func->init) {
+               int ret = disp->func->init(disp);
+               if (ret)
+                       return ret;
+       }
+
+       /* Set 'normal' (ie. when it's attached to a head) state for
+        * each output resource to 'fully enabled'.
+        */
+       list_for_each_entry(ior, &disp->ior, head) {
+               ior->func->power(ior, true, true, true, true, true);
+       }
+
        return 0;
 }
 
index 40681db91a022a9cd90d20f01b8e19b03c8324a2..b5185853b7d8d448520ecc52f810d1201f42a418 100644 (file)
@@ -4,6 +4,7 @@
 #define nv50_disp_chan(p) container_of((p), struct nv50_disp_chan, object)
 #include <core/object.h>
 #include "nv50.h"
+struct nv50_disp_root;
 
 struct nv50_disp_chan {
        const struct nv50_disp_chan_func *func;
index ce7cd74fbd5dbad174a4272ea24aa2106784c81f..6680ff8bf029a93d2128edc1854c98a5466ea91e 100644 (file)
@@ -31,7 +31,7 @@ int
 gf119_disp_dmac_bind(struct nv50_disp_dmac *chan,
                     struct nvkm_object *object, u32 handle)
 {
-       return nvkm_ramht_insert(chan->base.root->ramht, object,
+       return nvkm_ramht_insert(chan->base.root->disp->ramht, object,
                                 chan->base.chid.user, -9, handle,
                                 chan->base.chid.user << 27 | 0x00000001);
 }
index 070ec5e18fdb43797069ce275d7e35fb0905bc4e..c80d0479c79a38a4cff86645b6f4dab3d02844d4 100644 (file)
@@ -33,7 +33,7 @@
 
 struct nv50_disp_dmac_object {
        struct nvkm_oproxy oproxy;
-       struct nv50_disp_root *root;
+       struct nv50_disp *disp;
        int hash;
 };
 
@@ -42,7 +42,7 @@ nv50_disp_dmac_child_del_(struct nvkm_oproxy *base)
 {
        struct nv50_disp_dmac_object *object =
                container_of(base, typeof(*object), oproxy);
-       nvkm_ramht_remove(object->root->ramht, object->hash);
+       nvkm_ramht_remove(object->disp->ramht, object->hash);
 }
 
 static const struct nvkm_oproxy_func
@@ -56,8 +56,8 @@ nv50_disp_dmac_child_new_(struct nv50_disp_chan *base,
                          void *data, u32 size, struct nvkm_object **pobject)
 {
        struct nv50_disp_dmac *chan = nv50_disp_dmac(base);
-       struct nv50_disp_root *root = chan->base.root;
-       struct nvkm_device *device = root->disp->base.engine.subdev.device;
+       struct nv50_disp *disp = chan->base.root->disp;
+       struct nvkm_device *device = disp->base.engine.subdev.device;
        const struct nvkm_device_oclass *sclass = oclass->priv;
        struct nv50_disp_dmac_object *object;
        int ret;
@@ -65,7 +65,7 @@ nv50_disp_dmac_child_new_(struct nv50_disp_chan *base,
        if (!(object = kzalloc(sizeof(*object), GFP_KERNEL)))
                return -ENOMEM;
        nvkm_oproxy_ctor(&nv50_disp_dmac_child_func_, oclass, &object->oproxy);
-       object->root = root;
+       object->disp = disp;
        *pobject = &object->oproxy.base;
 
        ret = sclass->ctor(device, oclass, data, size, &object->oproxy.object);
@@ -177,7 +177,7 @@ int
 nv50_disp_dmac_bind(struct nv50_disp_dmac *chan,
                    struct nvkm_object *object, u32 handle)
 {
-       return nvkm_ramht_insert(chan->base.root->ramht, object,
+       return nvkm_ramht_insert(chan->base.root->disp->ramht, object,
                                 chan->base.chid.user, -10, handle,
                                 chan->base.chid.user << 28 |
                                 chan->base.chid.user);
index 1ec81f3e5d0a086fc2879152f1ad0dce1f57dcf1..731f188fc1ee7d69fe959dd28d8d67c0855d8890 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 g84_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index 791c2cd157dcb36412d51870cc8228d98df1c1ac..def54fe1951ec36641ec6a140b86bcff5e3f4c7c 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 g94_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index 0139d143c733b4fcc997ec87a3b42ee11c7c2b00..382e6a6a6ff2c23cbecb9d2fbf1adac4db5a5645 100644 (file)
@@ -26,6 +26,9 @@
 #include "ior.h"
 #include "rootnv50.h"
 
+#include <core/ramht.h>
+#include <subdev/timer.h>
+
 void
 gf119_disp_super(struct work_struct *work)
 {
@@ -164,8 +167,87 @@ gf119_disp_intr(struct nv50_disp *disp)
        }
 }
 
+void
+gf119_disp_fini(struct nv50_disp *disp)
+{
+       struct nvkm_device *device = disp->base.engine.subdev.device;
+       /* disable all interrupts */
+       nvkm_wr32(device, 0x6100b0, 0x00000000);
+}
+
+int
+gf119_disp_init(struct nv50_disp *disp)
+{
+       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_head *head;
+       u32 tmp;
+       int i;
+
+       /* The below segments of code copying values from one register to
+        * another appear to inform EVO of the display capabilities or
+        * something similar.
+        */
+
+       /* ... CRTC caps */
+       list_for_each_entry(head, &disp->base.head, head) {
+               const u32 hoff = head->id * 0x800;
+               tmp = nvkm_rd32(device, 0x616104 + hoff);
+               nvkm_wr32(device, 0x6101b4 + hoff, tmp);
+               tmp = nvkm_rd32(device, 0x616108 + hoff);
+               nvkm_wr32(device, 0x6101b8 + hoff, tmp);
+               tmp = nvkm_rd32(device, 0x61610c + hoff);
+               nvkm_wr32(device, 0x6101bc + hoff, tmp);
+       }
+
+       /* ... DAC caps */
+       for (i = 0; i < disp->dac.nr; i++) {
+               tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
+               nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp);
+       }
+
+       /* ... SOR caps */
+       for (i = 0; i < disp->sor.nr; i++) {
+               tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
+               nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp);
+       }
+
+       /* steal display away from vbios, or something like that */
+       if (nvkm_rd32(device, 0x6100ac) & 0x00000100) {
+               nvkm_wr32(device, 0x6100ac, 0x00000100);
+               nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
+               if (nvkm_msec(device, 2000,
+                       if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
+                               break;
+               ) < 0)
+                       return -EBUSY;
+       }
+
+       /* point at display engine memory area (hash table, objects) */
+       nvkm_wr32(device, 0x610010, (disp->inst->addr >> 8) | 9);
+
+       /* enable supervisor interrupts, disable everything else */
+       nvkm_wr32(device, 0x610090, 0x00000000);
+       nvkm_wr32(device, 0x6100a0, 0x00000000);
+       nvkm_wr32(device, 0x6100b0, 0x00000307);
+
+       /* disable underflow reporting, preventing an intermittent issue
+        * on some gk104 boards where the production vbios left this
+        * setting enabled by default.
+        *
+        * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt
+        */
+       list_for_each_entry(head, &disp->base.head, head) {
+               const u32 hoff = head->id * 0x800;
+               nvkm_mask(device, 0x616308 + hoff, 0x00000111, 0x00000010);
+       }
+
+       return 0;
+}
+
 static const struct nv50_disp_func
 gf119_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index 6a59a52468c1fce8829c64d685271093bc9d48ba..4c3439b1a62da6d7472ed7869b2cd3c2576f3ac5 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gk104_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index f3b10dc4e67353b862703bd4db9c511a597197b8..bc6f4750c942eb57e8c34f1f5c0b90787e94921e 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gk110_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index 068c5951efe38404fd0d4cfb500d093c9d18dc8f..031cf6b03a76680f045b222440622df752f9731c 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gm107_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index 1c27dbe6cceca792687cf94c26cd658b5dff63a2..ec9c33a5162d798e87c816fbb8e03b7e626b5588 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gm200_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index 84933b6119f2cee1aa0df7fbdc93a9c494e43b6c..fd6216684f6d2e90167dac6c2bd3cab694a2bdd3 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gp100_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index b36d926f0264242ef81fd85604771d2e021804ab..0a2c5b5f87eb620287cbea27d363eb2969469c66 100644 (file)
@@ -54,6 +54,8 @@ gp102_disp_intr_error(struct nv50_disp *disp, int chid)
 
 static const struct nv50_disp_func
 gp102_disp = {
+       .init = gf119_disp_init,
+       .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gp102_disp_intr_error,
        .uevent = &gf119_disp_chan_uevent,
index 62e721d5963a27351c7c649a2284a495afa9b4bf..f80183701f448dc36b7a921e2d811a2ae41e9feb 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gt200_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index a5b1b1416740cb3e35131ba30ce6b64484fe5f44..7581efc1357e90d355625374097e43dd5da67df8 100644 (file)
@@ -28,6 +28,8 @@
 
 static const struct nv50_disp_func
 gt215_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index ff49040a581999663d017c2aec941dbca5389ef6..cfdce23ab83a6a4bacb3f60ae3ba4f54556c1fc9 100644 (file)
@@ -26,6 +26,8 @@
 
 static const struct nv50_disp_func
 mcp77_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index 0cf968d58fca77a706e59e883d9d23cc5b076c34..85d9329cfa0e1507d258b8473f16a2178a1046b6 100644 (file)
@@ -26,6 +26,8 @@
 
 static const struct nv50_disp_func
 mcp89_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index c0faa3908a0060b03020d78c033e827d5f0a7897..1d2280ab3194ebacc419fb8bca94069081a6f637 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <core/client.h>
 #include <core/enum.h>
-#include <core/gpuobj.h>
+#include <core/ramht.h>
 #include <subdev/bios.h>
 #include <subdev/bios/disp.h>
 #include <subdev/bios/init.h>
@@ -49,13 +49,32 @@ nv50_disp_intr_(struct nvkm_disp *base)
        disp->func->intr(disp);
 }
 
+static void
+nv50_disp_fini_(struct nvkm_disp *base)
+{
+       struct nv50_disp *disp = nv50_disp(base);
+       disp->func->fini(disp);
+}
+
+static int
+nv50_disp_init_(struct nvkm_disp *base)
+{
+       struct nv50_disp *disp = nv50_disp(base);
+       return disp->func->init(disp);
+}
+
 static void *
 nv50_disp_dtor_(struct nvkm_disp *base)
 {
        struct nv50_disp *disp = nv50_disp(base);
+
+       nvkm_ramht_del(&disp->ramht);
+       nvkm_gpuobj_del(&disp->inst);
+
        nvkm_event_fini(&disp->uevent);
        if (disp->wq)
                destroy_workqueue(disp->wq);
+
        return disp;
 }
 
@@ -65,6 +84,7 @@ nv50_disp_oneinit_(struct nvkm_disp *base)
        struct nv50_disp *disp = nv50_disp(base);
        const struct nv50_disp_func *func = disp->func;
        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_device *device = subdev->device;
        int ret, i;
 
        disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask);
@@ -107,13 +127,20 @@ nv50_disp_oneinit_(struct nvkm_disp *base)
                        return ret;
        }
 
-       return 0;
+       ret = nvkm_gpuobj_new(device, 0x10000, 0x10000, false, NULL,
+                             &disp->inst);
+       if (ret)
+               return ret;
+
+       return nvkm_ramht_new(device, 0x1000, 0, disp->inst, &disp->ramht);
 }
 
 static const struct nvkm_disp_func
 nv50_disp_ = {
        .dtor = nv50_disp_dtor_,
        .oneinit = nv50_disp_oneinit_,
+       .init = nv50_disp_init_,
+       .fini = nv50_disp_fini_,
        .intr = nv50_disp_intr_,
        .root = nv50_disp_root_,
 };
@@ -643,8 +670,84 @@ nv50_disp_intr(struct nv50_disp *disp)
        }
 }
 
+void
+nv50_disp_fini(struct nv50_disp *disp)
+{
+       struct nvkm_device *device = disp->base.engine.subdev.device;
+       /* disable all interrupts */
+       nvkm_wr32(device, 0x610024, 0x00000000);
+       nvkm_wr32(device, 0x610020, 0x00000000);
+}
+
+int
+nv50_disp_init(struct nv50_disp *disp)
+{
+       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_head *head;
+       u32 tmp;
+       int i;
+
+       /* The below segments of code copying values from one register to
+        * another appear to inform EVO of the display capabilities or
+        * something similar.  NFI what the 0x614004 caps are for..
+        */
+       tmp = nvkm_rd32(device, 0x614004);
+       nvkm_wr32(device, 0x610184, tmp);
+
+       /* ... CRTC caps */
+       list_for_each_entry(head, &disp->base.head, head) {
+               tmp = nvkm_rd32(device, 0x616100 + (head->id * 0x800));
+               nvkm_wr32(device, 0x610190 + (head->id * 0x10), tmp);
+               tmp = nvkm_rd32(device, 0x616104 + (head->id * 0x800));
+               nvkm_wr32(device, 0x610194 + (head->id * 0x10), tmp);
+               tmp = nvkm_rd32(device, 0x616108 + (head->id * 0x800));
+               nvkm_wr32(device, 0x610198 + (head->id * 0x10), tmp);
+               tmp = nvkm_rd32(device, 0x61610c + (head->id * 0x800));
+               nvkm_wr32(device, 0x61019c + (head->id * 0x10), tmp);
+       }
+
+       /* ... DAC caps */
+       for (i = 0; i < disp->dac.nr; i++) {
+               tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
+               nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp);
+       }
+
+       /* ... SOR caps */
+       for (i = 0; i < disp->sor.nr; i++) {
+               tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
+               nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp);
+       }
+
+       /* ... PIOR caps */
+       for (i = 0; i < disp->pior.nr; i++) {
+               tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800));
+               nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp);
+       }
+
+       /* steal display away from vbios, or something like that */
+       if (nvkm_rd32(device, 0x610024) & 0x00000100) {
+               nvkm_wr32(device, 0x610024, 0x00000100);
+               nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
+               if (nvkm_msec(device, 2000,
+                       if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
+                               break;
+               ) < 0)
+                       return -EBUSY;
+       }
+
+       /* point at display engine memory area (hash table, objects) */
+       nvkm_wr32(device, 0x610010, (disp->inst->addr >> 8) | 9);
+
+       /* enable supervisor interrupts, disable everything else */
+       nvkm_wr32(device, 0x61002c, 0x00000370);
+       nvkm_wr32(device, 0x610028, 0x00000000);
+       return 0;
+}
+
 static const struct nv50_disp_func
 nv50_disp = {
+       .init = nv50_disp_init,
+       .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
        .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
index a29bcf73ce6fc21e2138b5a5185a3ca2f37c346c..bb622d0f6d639bb0e07cf97d863a941f8a8a137a 100644 (file)
@@ -32,6 +32,9 @@ struct nv50_disp {
                u8 type[3];
        } pior;
 
+       struct nvkm_gpuobj *inst;
+       struct nvkm_ramht *ramht;
+
        struct nv50_disp_chan *chan[21];
 };
 
@@ -46,6 +49,8 @@ int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *,
                   int index, struct nvkm_disp **);
 
 struct nv50_disp_func {
+       int (*init)(struct nv50_disp *);
+       void (*fini)(struct nv50_disp *);
        void (*intr)(struct nv50_disp *);
        void (*intr_error)(struct nv50_disp *, int chid);
 
@@ -60,9 +65,13 @@ struct nv50_disp_func {
        } head, dac, sor, pior;
 };
 
+int nv50_disp_init(struct nv50_disp *);
+void nv50_disp_fini(struct nv50_disp *);
 void nv50_disp_intr(struct nv50_disp *);
 void nv50_disp_super(struct work_struct *);
 
+int gf119_disp_init(struct nv50_disp *);
+void gf119_disp_fini(struct nv50_disp *);
 void gf119_disp_intr(struct nv50_disp *);
 void gf119_disp_super(struct work_struct *);
 void gf119_disp_intr_error(struct nv50_disp *, int);
index c614351f50127c750625cb50a8ba72c02bd4ee48..ef66c5f38ad51f8586e8b86100039538c22bcfca 100644 (file)
@@ -13,6 +13,8 @@ void nvkm_disp_vblank(struct nvkm_disp *, int head);
 struct nvkm_disp_func {
        void *(*dtor)(struct nvkm_disp *);
        int (*oneinit)(struct nvkm_disp *);
+       int (*init)(struct nvkm_disp *);
+       void (*fini)(struct nvkm_disp *);
        void (*intr)(struct nvkm_disp *);
 
        const struct nvkm_disp_oclass *(*root)(struct nvkm_disp *);
index 721e4f74d1fcee88a127fb8a434b9f32957d4f5f..36ac0d4237c7aab4c0fac0b689316350ea4e1ad9 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 g84_disp_root = {
-       .init = nv50_disp_root_init,
-       .fini = nv50_disp_root_fini,
        .dmac = {
                &g84_disp_core_oclass,
                &g84_disp_base_oclass,
index 9493f6edf62be2f05a4e46d8d5e3a60ab8323a31..18b87b3df862ffedd6e204a2f72b2d5a0d0ba656 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 g94_disp_root = {
-       .init = nv50_disp_root_init,
-       .fini = nv50_disp_root_fini,
        .dmac = {
                &g94_disp_core_oclass,
                &gt200_disp_base_oclass,
index 4ba2d80db52ba303d82f21a31a557933ec1549f1..7c5701f0b496be7ec1b08dbe79543a5add80cbad 100644 (file)
  * Authors: Ben Skeggs
  */
 #include "rootnv50.h"
-#include "head.h"
 #include "dmacnv50.h"
 
-#include <core/ramht.h>
-#include <subdev/timer.h>
-
 #include <nvif/class.h>
 
-void
-gf119_disp_root_fini(struct nv50_disp_root *root)
-{
-       struct nvkm_device *device = root->disp->base.engine.subdev.device;
-       /* disable all interrupts */
-       nvkm_wr32(device, 0x6100b0, 0x00000000);
-}
-
-int
-gf119_disp_root_init(struct nv50_disp_root *root)
-{
-       struct nv50_disp *disp = root->disp;
-       struct nvkm_head *head;
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       u32 tmp;
-       int i;
-
-       /* The below segments of code copying values from one register to
-        * another appear to inform EVO of the display capabilities or
-        * something similar.
-        */
-
-       /* ... CRTC caps */
-       list_for_each_entry(head, &disp->base.head, head) {
-               const u32 hoff = head->id * 0x800;
-               tmp = nvkm_rd32(device, 0x616104 + hoff);
-               nvkm_wr32(device, 0x6101b4 + hoff, tmp);
-               tmp = nvkm_rd32(device, 0x616108 + hoff);
-               nvkm_wr32(device, 0x6101b8 + hoff, tmp);
-               tmp = nvkm_rd32(device, 0x61610c + hoff);
-               nvkm_wr32(device, 0x6101bc + hoff, tmp);
-       }
-
-       /* ... DAC caps */
-       for (i = 0; i < disp->dac.nr; i++) {
-               tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
-               nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp);
-       }
-
-       /* ... SOR caps */
-       for (i = 0; i < disp->sor.nr; i++) {
-               tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
-               nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp);
-       }
-
-       /* steal display away from vbios, or something like that */
-       if (nvkm_rd32(device, 0x6100ac) & 0x00000100) {
-               nvkm_wr32(device, 0x6100ac, 0x00000100);
-               nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
-               if (nvkm_msec(device, 2000,
-                       if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
-                               break;
-               ) < 0)
-                       return -EBUSY;
-       }
-
-       /* point at display engine memory area (hash table, objects) */
-       nvkm_wr32(device, 0x610010, (root->instmem->addr >> 8) | 9);
-
-       /* enable supervisor interrupts, disable everything else */
-       nvkm_wr32(device, 0x610090, 0x00000000);
-       nvkm_wr32(device, 0x6100a0, 0x00000000);
-       nvkm_wr32(device, 0x6100b0, 0x00000307);
-
-       /* disable underflow reporting, preventing an intermittent issue
-        * on some gk104 boards where the production vbios left this
-        * setting enabled by default.
-        *
-        * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt
-        */
-       list_for_each_entry(head, &disp->base.head, head) {
-               const u32 hoff = head->id * 0x800;
-               nvkm_mask(device, 0x616308 + hoff, 0x00000111, 0x00000010);
-       }
-
-       return 0;
-}
-
 static const struct nv50_disp_root_func
 gf119_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gf119_disp_core_oclass,
                &gf119_disp_base_oclass,
index 0bfdb1d1c6ab4bd96dfff7d1e399cfb340899e0c..c0946a602b719ec5a802329519118fee5ae2e5de 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gk104_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gk104_disp_core_oclass,
                &gk104_disp_base_oclass,
index 1e8dbed8a67c222988a6ccdb159aa040accba543..2ebc16687b507d80a14f5e8282384b9f0bd0e5f4 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gk110_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gk110_disp_core_oclass,
                &gk110_disp_base_oclass,
index 44c55be69e996200d4368902617930c483542ee8..5a62c9e1a2cf074c8fdd63cad5caf2d20b24cc19 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gm107_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gm107_disp_core_oclass,
                &gk110_disp_base_oclass,
index 38f5ee1dfc581a4b2487b3f9160a0e8128a87523..2634e06bf6663b629b8243b237994285e7cb9a14 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gm200_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gm200_disp_core_oclass,
                &gk110_disp_base_oclass,
index ac8fdd728ec68d55e7681cc2a15cca98839fa16f..784723597c7eb2345084f82206f4e2782a223699 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gp100_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gp100_disp_core_oclass,
                &gk110_disp_base_oclass,
index 37122ca579ad6b4a1fb77a951e0a8ebeb6c0a75d..2fdfa8df037820cd2926a95425595dd5d05cb996 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gp102_disp_root = {
-       .init = gf119_disp_root_init,
-       .fini = gf119_disp_root_fini,
        .dmac = {
                &gp102_disp_core_oclass,
                &gp102_disp_base_oclass,
index 124a0c24f92cf5e3b0b3e19b0bfc82362d3824cf..facad2794eb6979cf646448ebce1452c5cb41364 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gt200_disp_root = {
-       .init = nv50_disp_root_init,
-       .fini = nv50_disp_root_fini,
        .dmac = {
                &gt200_disp_core_oclass,
                &gt200_disp_base_oclass,
index dff52f30668bd7eb4b1e6d8f82dfcb5706cdc7bc..3e93db58263f323c21336bc9f05e58046681172b 100644 (file)
@@ -28,8 +28,6 @@
 
 static const struct nv50_disp_root_func
 gt215_disp_root = {
-       .init = nv50_disp_root_init,
-       .fini = nv50_disp_root_fini,
        .dmac = {
                &gt215_disp_core_oclass,
                &gt215_disp_base_oclass,
index c8379bf37a6da5828e0124e927616db350fb0433..072c8c0e7096046a5717f18990d94fc885f7e49f 100644 (file)
@@ -28,8 +28,6 @@
 #include "ior.h"
 
 #include <core/client.h>
-#include <core/ramht.h>
-#include <subdev/timer.h>
 
 #include <nvif/class.h>
 #include <nvif/cl5070.h>
@@ -315,49 +313,16 @@ nv50_disp_root_child_get_(struct nvkm_object *object, int index,
        return -EINVAL;
 }
 
-static int
-nv50_disp_root_fini_(struct nvkm_object *object, bool suspend)
-{
-       struct nv50_disp_root *root = nv50_disp_root(object);
-       root->func->fini(root);
-       return 0;
-}
-
-static int
-nv50_disp_root_init_(struct nvkm_object *object)
-{
-       struct nv50_disp_root *root = nv50_disp_root(object);
-       struct nvkm_ior *ior;
-       int ret;
-
-       ret = root->func->init(root);
-       if (ret)
-               return ret;
-
-       /* Set 'normal' (ie. when it's attached to a head) state for
-        * each output resource to 'fully enabled'.
-        */
-       list_for_each_entry(ior, &root->disp->base.ior, head) {
-               ior->func->power(ior, true, true, true, true, true);
-       }
-
-       return 0;
-}
-
 static void *
 nv50_disp_root_dtor_(struct nvkm_object *object)
 {
        struct nv50_disp_root *root = nv50_disp_root(object);
-       nvkm_ramht_del(&root->ramht);
-       nvkm_gpuobj_del(&root->instmem);
        return root;
 }
 
 static const struct nvkm_object_func
 nv50_disp_root_ = {
        .dtor = nv50_disp_root_dtor_,
-       .init = nv50_disp_root_init_,
-       .fini = nv50_disp_root_fini_,
        .mthd = nv50_disp_root_mthd_,
        .ntfy = nvkm_disp_ntfy,
        .sclass = nv50_disp_root_child_get_,
@@ -370,8 +335,6 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func,
 {
        struct nv50_disp *disp = nv50_disp(base);
        struct nv50_disp_root *root;
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       int ret;
 
        if (!(root = kzalloc(sizeof(*root), GFP_KERNEL)))
                return -ENOMEM;
@@ -380,94 +343,11 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func,
        nvkm_object_ctor(&nv50_disp_root_, oclass, &root->object);
        root->func = func;
        root->disp = disp;
-
-       ret = nvkm_gpuobj_new(disp->base.engine.subdev.device, 0x10000, 0x10000,
-                             false, NULL, &root->instmem);
-       if (ret)
-               return ret;
-
-       return nvkm_ramht_new(device, 0x1000, 0, root->instmem, &root->ramht);
-}
-
-void
-nv50_disp_root_fini(struct nv50_disp_root *root)
-{
-       struct nvkm_device *device = root->disp->base.engine.subdev.device;
-       /* disable all interrupts */
-       nvkm_wr32(device, 0x610024, 0x00000000);
-       nvkm_wr32(device, 0x610020, 0x00000000);
-}
-
-int
-nv50_disp_root_init(struct nv50_disp_root *root)
-{
-       struct nv50_disp *disp = root->disp;
-       struct nvkm_head *head;
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       u32 tmp;
-       int i;
-
-       /* The below segments of code copying values from one register to
-        * another appear to inform EVO of the display capabilities or
-        * something similar.  NFI what the 0x614004 caps are for..
-        */
-       tmp = nvkm_rd32(device, 0x614004);
-       nvkm_wr32(device, 0x610184, tmp);
-
-       /* ... CRTC caps */
-       list_for_each_entry(head, &disp->base.head, head) {
-               tmp = nvkm_rd32(device, 0x616100 + (head->id * 0x800));
-               nvkm_wr32(device, 0x610190 + (head->id * 0x10), tmp);
-               tmp = nvkm_rd32(device, 0x616104 + (head->id * 0x800));
-               nvkm_wr32(device, 0x610194 + (head->id * 0x10), tmp);
-               tmp = nvkm_rd32(device, 0x616108 + (head->id * 0x800));
-               nvkm_wr32(device, 0x610198 + (head->id * 0x10), tmp);
-               tmp = nvkm_rd32(device, 0x61610c + (head->id * 0x800));
-               nvkm_wr32(device, 0x61019c + (head->id * 0x10), tmp);
-       }
-
-       /* ... DAC caps */
-       for (i = 0; i < disp->dac.nr; i++) {
-               tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
-               nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp);
-       }
-
-       /* ... SOR caps */
-       for (i = 0; i < disp->sor.nr; i++) {
-               tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
-               nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp);
-       }
-
-       /* ... PIOR caps */
-       for (i = 0; i < disp->pior.nr; i++) {
-               tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800));
-               nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp);
-       }
-
-       /* steal display away from vbios, or something like that */
-       if (nvkm_rd32(device, 0x610024) & 0x00000100) {
-               nvkm_wr32(device, 0x610024, 0x00000100);
-               nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
-               if (nvkm_msec(device, 2000,
-                       if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
-                               break;
-               ) < 0)
-                       return -EBUSY;
-       }
-
-       /* point at display engine memory area (hash table, objects) */
-       nvkm_wr32(device, 0x610010, (root->instmem->addr >> 8) | 9);
-
-       /* enable supervisor interrupts, disable everything else */
-       nvkm_wr32(device, 0x61002c, 0x00000370);
-       nvkm_wr32(device, 0x610028, 0x00000000);
        return 0;
 }
 
 static const struct nv50_disp_root_func
 nv50_disp_root = {
-       .init = nv50_disp_root_init,
-       .fini = nv50_disp_root_fini,
        .dmac = {
                &nv50_disp_core_oclass,
                &nv50_disp_base_oclass,
index 4818fa69ae6cff0dd46d622b8e46476e0c829cdc..06b554b212bdfab1b415003a4490e5fcc858fd95 100644 (file)
@@ -10,14 +10,9 @@ struct nv50_disp_root {
        const struct nv50_disp_root_func *func;
        struct nv50_disp *disp;
        struct nvkm_object object;
-
-       struct nvkm_gpuobj *instmem;
-       struct nvkm_ramht *ramht;
 };
 
 struct nv50_disp_root_func {
-       int (*init)(struct nv50_disp_root *);
-       void (*fini)(struct nv50_disp_root *);
        const struct nv50_disp_dmac_oclass *dmac[3];
        const struct nv50_disp_pioc_oclass *pioc[2];
 };
@@ -25,11 +20,6 @@ struct nv50_disp_root_func {
 int  nv50_disp_root_new_(const struct nv50_disp_root_func *, struct nvkm_disp *,
                         const struct nvkm_oclass *, void *data, u32 size,
                         struct nvkm_object **);
-int  nv50_disp_root_init(struct nv50_disp_root *);
-void nv50_disp_root_fini(struct nv50_disp_root *);
-
-int  gf119_disp_root_init(struct nv50_disp_root *);
-void gf119_disp_root_fini(struct nv50_disp_root *);
 
 extern const struct nvkm_disp_oclass nv50_disp_root_oclass;
 extern const struct nvkm_disp_oclass g84_disp_root_oclass;