Merge tag 'topic/nouveau-misc-2022-07-27' of git://anongit.freedesktop.org/drm/drm...
authorDave Airlie <airlied@redhat.com>
Wed, 27 Jul 2022 00:11:59 +0000 (10:11 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 27 Jul 2022 01:34:07 +0000 (11:34 +1000)
drm/nouveau-misc: display patches.

These are just some precursor and cleanup display patches from Ben,
tested by Lyude.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Dave Airlie <airlied@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAPM=9ty0R37q0mohBr_CegpYLXK2=fAH54QfAsMhHfPygTsdQA@mail.gmail.com
158 files changed:
drivers/gpu/drm/nouveau/dispnv50/base507c.c
drivers/gpu/drm/nouveau/dispnv50/core507d.c
drivers/gpu/drm/nouveau/dispnv50/curs507a.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/oimm507b.c
drivers/gpu/drm/nouveau/dispnv50/ovly507e.c
drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c
drivers/gpu/drm/nouveau/dispnv50/wndw.c
drivers/gpu/drm/nouveau/dispnv50/wndw.h
drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
drivers/gpu/drm/nouveau/include/nvif/cl5070.h
drivers/gpu/drm/nouveau/include/nvif/cl507a.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/cl507b.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/cl507c.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/cl507d.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/cl507e.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/class.h
drivers/gpu/drm/nouveau/include/nvif/clc37b.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/clc37e.h [deleted file]
drivers/gpu/drm/nouveau/include/nvif/conn.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/include/nvif/disp.h
drivers/gpu/drm/nouveau/include/nvif/if0010.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/include/nvif/if0011.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/include/nvif/if0012.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/include/nvif/if0014.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/include/nvif/outp.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/include/nvif/printf.h
drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nvif/Kbuild
drivers/gpu/drm/nouveau/nvif/conn.c [moved from drivers/gpu/drm/nouveau/nvkm/engine/disp/rootga102.c with 56% similarity]
drivers/gpu/drm/nouveau/nvif/disp.c
drivers/gpu/drm/nouveau/nvif/outp.c [moved from drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c with 54% similarity]
drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h
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/ga102.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/gv100.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/head.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv04.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
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/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c [deleted file]

index 788db04..cad5a64 100644 (file)
@@ -21,8 +21,7 @@
  */
 #include "base.h"
 
-#include <nvif/cl507c.h>
-#include <nvif/event.h>
+#include <nvif/if0014.h>
 #include <nvif/push507c.h>
 #include <nvif/timer.h>
 
@@ -306,8 +305,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
              struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
              struct nv50_wndw **pwndw)
 {
-       struct nv50_disp_base_channel_dma_v0 args = {
-               .head = head,
+       struct nvif_disp_chan_v0 args = {
+               .id = head,
        };
        struct nouveau_display *disp = nouveau_display(drm->dev);
        struct nv50_disp *disp50 = nv50_disp(drm->dev);
@@ -328,16 +327,6 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
                return ret;
        }
 
-       ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsBaseNtfy",
-                              wndw->notify.func, false,
-                              NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT,
-                              &(struct nvif_notify_uevent_req) {},
-                              sizeof(struct nvif_notify_uevent_req),
-                              sizeof(struct nvif_notify_uevent_rep),
-                              &wndw->notify);
-       if (ret)
-               return ret;
-
        wndw->ntfy = NV50_DISP_BASE_NTFY(wndw->id);
        wndw->sema = NV50_DISP_BASE_SEM0(wndw->id);
        wndw->data = 0x00000000;
index 1a1d806..e5bb5ca 100644 (file)
@@ -22,7 +22,7 @@
 #include "core.h"
 #include "head.h"
 
-#include <nvif/cl507d.h>
+#include <nvif/if0014.h>
 #include <nvif/push507c.h>
 #include <nvif/timer.h>
 
@@ -157,7 +157,7 @@ int
 core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm,
              s32 oclass, struct nv50_core **pcore)
 {
-       struct nv50_disp_core_channel_dma_v0 args = {};
+       struct nvif_disp_chan_v0 args = {};
        struct nv50_disp *disp = nv50_disp(drm->dev);
        struct nv50_core *core;
        int ret;
index 00e19fd..cd2c79e 100644 (file)
@@ -23,7 +23,7 @@
 #include "core.h"
 #include "head.h"
 
-#include <nvif/cl507a.h>
+#include <nvif/if0014.h>
 #include <nvif/timer.h>
 
 #include <nvhw/class/cl507a.h>
@@ -150,8 +150,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
              int head, s32 oclass, u32 interlock_data,
              struct nv50_wndw **pwndw)
 {
-       struct nv50_disp_cursor_v0 args = {
-               .head = head,
+       struct nvif_disp_chan_v0 args = {
+               .id = head,
        };
        struct nv50_disp *disp = nv50_disp(drm->dev);
        struct nv50_wndw *wndw;
index ade2988..a53d685 100644 (file)
@@ -48,8 +48,8 @@
 #include <nvif/class.h>
 #include <nvif/cl0002.h>
 #include <nvif/cl5070.h>
-#include <nvif/cl507d.h>
 #include <nvif/event.h>
+#include <nvif/if0014.h>
 #include <nvif/timer.h>
 
 #include <nvhw/class/cl507c.h>
@@ -231,7 +231,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
                 struct nv50_dmac *dmac)
 {
        struct nouveau_cli *cli = (void *)device->object.client;
-       struct nv50_disp_core_channel_dma_v0 *args = data;
+       struct nvif_disp_chan_v0 *args = data;
        u8 type = NVIF_MEM_COHERENT;
        int ret;
 
@@ -529,24 +529,15 @@ static enum drm_connector_status
 nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-       struct nv50_disp *disp = nv50_disp(encoder->dev);
-       struct {
-               struct nv50_disp_mthd_v1 base;
-               struct nv50_disp_dac_load_v0 load;
-       } args = {
-               .base.version = 1,
-               .base.method = NV50_DISP_MTHD_V1_DAC_LOAD,
-               .base.hasht  = nv_encoder->dcb->hasht,
-               .base.hashm  = nv_encoder->dcb->hashm,
-       };
+       u32 loadval;
        int ret;
 
-       args.load.data = nouveau_drm(encoder->dev)->vbios.dactestval;
-       if (args.load.data == 0)
-               args.load.data = 340;
+       loadval = nouveau_drm(encoder->dev)->vbios.dactestval;
+       if (loadval == 0)
+               loadval = 340;
 
-       ret = nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
-       if (ret || !args.load.load)
+       ret = nvif_outp_load_detect(&nv_encoder->outp, loadval);
+       if (ret <= 0)
                return connector_status_disconnected;
 
        return connector_status_connected;
@@ -563,6 +554,10 @@ nv50_dac_help = {
 static void
 nv50_dac_destroy(struct drm_encoder *encoder)
 {
+       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+       nvif_outp_dtor(&nv_encoder->outp);
+
        drm_encoder_cleanup(encoder);
        kfree(encoder);
 }
@@ -576,6 +571,7 @@ static int
 nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
 {
        struct nouveau_drm *drm = nouveau_drm(connector->dev);
+       struct nv50_disp *disp = nv50_disp(connector->dev);
        struct nvkm_i2c *i2c = nvxx_i2c(&drm->client.device);
        struct nvkm_i2c_bus *bus;
        struct nouveau_encoder *nv_encoder;
@@ -599,7 +595,7 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
        drm_encoder_helper_add(encoder, &nv50_dac_help);
 
        drm_connector_attach_encoder(connector, encoder);
-       return 0;
+       return nvif_outp_ctor(disp->disp, nv_encoder->base.base.name, dcbe->id, &nv_encoder->outp);
 }
 
 /*
@@ -1822,6 +1818,9 @@ static void
 nv50_sor_destroy(struct drm_encoder *encoder)
 {
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+       nvif_outp_dtor(&nv_encoder->outp);
+
        nv50_mstm_del(&nv_encoder->dp.mstm);
        drm_encoder_cleanup(encoder);
 
@@ -1918,7 +1917,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
                        nv_encoder->i2c = &bus->i2c;
        }
 
-       return 0;
+       return nvif_outp_ctor(disp->disp, nv_encoder->base.base.name, dcbe->id, &nv_encoder->outp);
 }
 
 /******************************************************************************
@@ -1999,6 +1998,10 @@ nv50_pior_help = {
 static void
 nv50_pior_destroy(struct drm_encoder *encoder)
 {
+       struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+       nvif_outp_dtor(&nv_encoder->outp);
+
        drm_encoder_cleanup(encoder);
        kfree(encoder);
 }
@@ -2056,7 +2059,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
        disp->core->func->pior->get_caps(disp, nv_encoder, ffs(dcbe->or) - 1);
        nv50_outp_dump_caps(drm, nv_encoder);
 
-       return 0;
+       return nvif_outp_ctor(disp->disp, nv_encoder->base.base.name, dcbe->id, &nv_encoder->outp);
 }
 
 /******************************************************************************
index a6c3a9b..752318c 100644 (file)
  */
 #include "oimm.h"
 
-#include <nvif/cl507b.h>
+#include <nvif/if0014.h>
 
 static int
 oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
               s32 oclass, struct nv50_wndw *wndw)
 {
-       struct nv50_disp_overlay_v0 args = {
-               .head = wndw->id,
+       struct nvif_disp_chan_v0 args = {
+               .id = wndw->id,
        };
        struct nv50_disp *disp = nv50_disp(drm->dev);
        int ret;
index afd6c72..d4af69e 100644 (file)
@@ -26,8 +26,7 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_plane_helper.h>
 
-#include <nvif/cl507e.h>
-#include <nvif/event.h>
+#include <nvif/if0014.h>
 #include <nvif/push507c.h>
 
 #include <nvhw/class/cl507e.h>
@@ -147,8 +146,8 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
              struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
              struct nv50_wndw **pwndw)
 {
-       struct nv50_disp_overlay_channel_dma_v0 args = {
-               .head = head,
+       struct nvif_disp_chan_v0 args = {
+               .id = head,
        };
        struct nv50_disp *disp = nv50_disp(drm->dev);
        struct nv50_wndw *wndw;
@@ -169,16 +168,6 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
                return ret;
        }
 
-       ret = nvif_notify_ctor(&wndw->wndw.base.user, "kmsOvlyNtfy",
-                              wndw->notify.func, false,
-                              NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT,
-                              &(struct nvif_notify_uevent_req) {},
-                              sizeof(struct nvif_notify_uevent_req),
-                              sizeof(struct nvif_notify_uevent_rep),
-                              &wndw->notify);
-       if (ret)
-               return ret;
-
        wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id);
        wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id);
        wndw->data = 0x00000000;
index b390029..ee76b09 100644 (file)
@@ -23,7 +23,7 @@
 #include "atom.h"
 #include "wndw.h"
 
-#include <nvif/clc37b.h>
+#include <nvif/if0014.h>
 #include <nvif/pushc37b.h>
 
 #include <nvhw/class/clc37b.h>
@@ -68,9 +68,8 @@ static int
 wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
               s32 oclass, struct nv50_wndw *wndw)
 {
-       struct nvc37b_window_imm_channel_dma_v0 args = {
-               .pushbuf = 0xb0007b00 | wndw->id,
-               .index = wndw->id,
+       struct nvif_disp_chan_v0 args = {
+               .id = wndw->id,
        };
        struct nv50_disp *disp = nv50_disp(drm->dev);
        int ret;
index b21f49f..7a2ccea 100644 (file)
@@ -644,7 +644,6 @@ nv50_wndw_destroy(struct drm_plane *plane)
                nv50_wndw_ctxdma_del(ctxdma);
        }
 
-       nvif_notify_dtor(&wndw->notify);
        nv50_dmac_destroy(&wndw->wimm);
        nv50_dmac_destroy(&wndw->wndw);
 
@@ -688,12 +687,6 @@ nv50_wndw = {
        .format_mod_supported = nv50_plane_format_mod_supported,
 };
 
-static int
-nv50_wndw_notify(struct nvif_notify *notify)
-{
-       return NVIF_NOTIFY_KEEP;
-}
-
 static const u64 nv50_cursor_format_modifiers[] = {
        DRM_FORMAT_MOD_LINEAR,
        DRM_FORMAT_MOD_INVALID,
@@ -747,8 +740,6 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
                        return ret;
        }
 
-       wndw->notify.func = nv50_wndw_notify;
-
        if (wndw->func->blend_set) {
                ret = drm_plane_create_zpos_property(&wndw->plane,
                                nv50_wndw_zpos_default(&wndw->plane), 0, 254);
index 96542ce..591c852 100644 (file)
@@ -5,8 +5,6 @@
 #include "atom.h"
 #include "lut.h"
 
-#include <nvif/notify.h>
-
 struct nv50_wndw_ctxdma {
        struct list_head head;
        struct nvif_object object;
@@ -30,7 +28,6 @@ struct nv50_wndw {
        struct nv50_dmac wndw;
        struct nv50_dmac wimm;
 
-       struct nvif_notify notify;
        u16 ntfy;
        u16 sema;
        u32 data;
index 183d2c0..082a66d 100644 (file)
@@ -26,7 +26,7 @@
 #include <drm/drm_plane_helper.h>
 #include <nouveau_bo.h>
 
-#include <nvif/clc37e.h>
+#include <nvif/if0014.h>
 #include <nvif/pushc37b.h>
 
 #include <nvhw/class/clc37e.h>
@@ -351,9 +351,8 @@ wndwc37e_new_(const struct nv50_wndw_func *func, struct nouveau_drm *drm,
              enum drm_plane_type type, int index, s32 oclass, u32 heads,
              struct nv50_wndw **pwndw)
 {
-       struct nvc37e_window_channel_dma_v0 args = {
-               .pushbuf = 0xb0007e00 | index,
-               .index = index,
+       struct nvif_disp_chan_v0 args = {
+               .id = index,
        };
        struct nv50_disp *disp = nv50_disp(drm->dev);
        struct nv50_wndw *wndw;
index 37f6da8..31167c3 100644 (file)
@@ -26,7 +26,6 @@
 #include <drm/drm_plane_helper.h>
 #include <nouveau_bo.h>
 
-#include <nvif/clc37e.h>
 #include <nvif/pushc37b.h>
 
 #include <nvhw/class/clc57e.h>
index 53800fb..56affb6 100644 (file)
@@ -30,7 +30,6 @@ struct nv50_disp_mthd_v1 {
        __u8  version;
 #define NV50_DISP_MTHD_V1_ACQUIRE                                          0x01
 #define NV50_DISP_MTHD_V1_RELEASE                                          0x02
-#define NV50_DISP_MTHD_V1_DAC_LOAD                                         0x11
 #define NV50_DISP_MTHD_V1_SOR_HDA_ELD                                      0x21
 #define NV50_DISP_MTHD_V1_SOR_HDMI_PWR                                     0x22
 #define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT                                  0x23
@@ -50,13 +49,6 @@ struct nv50_disp_acquire_v0 {
        __u8  pad04[4];
 };
 
-struct nv50_disp_dac_load_v0 {
-       __u8  version;
-       __u8  load;
-       __u8  pad02[2];
-       __u32 data;
-};
-
 struct nv50_disp_sor_hda_eld_v0 {
        __u8  version;
        __u8  pad01[7];
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl507a.h b/drivers/gpu/drm/nouveau/include/nvif/cl507a.h
deleted file mode 100644 (file)
index 3b2a980..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CL507A_H__
-#define __NVIF_CL507A_H__
-
-struct nv50_disp_cursor_v0 {
-       __u8  version;
-       __u8  head;
-       __u8  pad02[6];
-};
-
-#define NV50_DISP_CURSOR_V0_NTFY_UEVENT                                    0x00
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl507b.h b/drivers/gpu/drm/nouveau/include/nvif/cl507b.h
deleted file mode 100644 (file)
index 0f3d055..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CL507B_H__
-#define __NVIF_CL507B_H__
-
-struct nv50_disp_overlay_v0 {
-       __u8  version;
-       __u8  head;
-       __u8  pad02[6];
-};
-
-#define NV50_DISP_OVERLAY_V0_NTFY_UEVENT                                   0x00
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl507c.h b/drivers/gpu/drm/nouveau/include/nvif/cl507c.h
deleted file mode 100644 (file)
index 7da8813..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CL507C_H__
-#define __NVIF_CL507C_H__
-
-struct nv50_disp_base_channel_dma_v0 {
-       __u8  version;
-       __u8  head;
-       __u8  pad02[6];
-       __u64 pushbuf;
-};
-
-#define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT                          0x00
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl507d.h b/drivers/gpu/drm/nouveau/include/nvif/cl507d.h
deleted file mode 100644 (file)
index 4a56e42..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CL507D_H__
-#define __NVIF_CL507D_H__
-
-struct nv50_disp_core_channel_dma_v0 {
-       __u8  version;
-       __u8  pad01[7];
-       __u64 pushbuf;
-};
-
-#define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT                          0x00
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl507e.h b/drivers/gpu/drm/nouveau/include/nvif/cl507e.h
deleted file mode 100644 (file)
index 633936c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CL507E_H__
-#define __NVIF_CL507E_H__
-
-struct nv50_disp_overlay_channel_dma_v0 {
-       __u8  version;
-       __u8  head;
-       __u8  pad02[6];
-       __u64 pushbuf;
-};
-
-#define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT                       0x00
-#endif
index a582c0c..8641db6 100644 (file)
 #define NVIF_CLASS_VMM_GM200                         /* ifb00d.h */  0x8000b00d
 #define NVIF_CLASS_VMM_GP100                         /* ifc00d.h */  0x8000c00d
 
+#define NVIF_CLASS_DISP                              /* if0010.h */  0x80000010
+#define NVIF_CLASS_CONN                              /* if0011.h */  0x80000011
+#define NVIF_CLASS_OUTP                              /* if0012.h */  0x80000012
+#define NVIF_CLASS_DISP_CHAN                         /* if0014.h */  0x80000014
+
 /* the below match nvidia-assigned (either in hw, or sw) class numbers */
 #define NV_NULL_CLASS                                                0x00000030
 
 #define TURING_CHANNEL_GPFIFO_A                       /* clc36f.h */ 0x0000c46f
 #define AMPERE_CHANNEL_GPFIFO_B                       /* clc36f.h */ 0x0000c76f
 
-#define NV50_DISP                                     /* cl5070.h */ 0x00005070
-#define G82_DISP                                      /* cl5070.h */ 0x00008270
-#define GT200_DISP                                    /* cl5070.h */ 0x00008370
-#define GT214_DISP                                    /* cl5070.h */ 0x00008570
-#define GT206_DISP                                    /* cl5070.h */ 0x00008870
-#define GF110_DISP                                    /* cl5070.h */ 0x00009070
-#define GK104_DISP                                    /* cl5070.h */ 0x00009170
-#define GK110_DISP                                    /* cl5070.h */ 0x00009270
-#define GM107_DISP                                    /* cl5070.h */ 0x00009470
-#define GM200_DISP                                    /* cl5070.h */ 0x00009570
-#define GP100_DISP                                    /* cl5070.h */ 0x00009770
-#define GP102_DISP                                    /* cl5070.h */ 0x00009870
-#define GV100_DISP                                    /* cl5070.h */ 0x0000c370
-#define TU102_DISP                                    /* cl5070.h */ 0x0000c570
-#define GA102_DISP                                    /* cl5070.h */ 0x0000c670
+#define NV50_DISP                                     /* if0010.h */ 0x00005070
+#define G82_DISP                                      /* if0010.h */ 0x00008270
+#define GT200_DISP                                    /* if0010.h */ 0x00008370
+#define GT214_DISP                                    /* if0010.h */ 0x00008570
+#define GT206_DISP                                    /* if0010.h */ 0x00008870
+#define GF110_DISP                                    /* if0010.h */ 0x00009070
+#define GK104_DISP                                    /* if0010.h */ 0x00009170
+#define GK110_DISP                                    /* if0010.h */ 0x00009270
+#define GM107_DISP                                    /* if0010.h */ 0x00009470
+#define GM200_DISP                                    /* if0010.h */ 0x00009570
+#define GP100_DISP                                    /* if0010.h */ 0x00009770
+#define GP102_DISP                                    /* if0010.h */ 0x00009870
+#define GV100_DISP                                    /* if0010.h */ 0x0000c370
+#define TU102_DISP                                    /* if0010.h */ 0x0000c570
+#define GA102_DISP                                    /* if0010.h */ 0x0000c670
 
 #define GV100_DISP_CAPS                                              0x0000c373
 
 
 #define NV74_VP2                                                     0x00007476
 
-#define NV50_DISP_CURSOR                              /* cl507a.h */ 0x0000507a
-#define G82_DISP_CURSOR                               /* cl507a.h */ 0x0000827a
-#define GT214_DISP_CURSOR                             /* cl507a.h */ 0x0000857a
-#define GF110_DISP_CURSOR                             /* cl507a.h */ 0x0000907a
-#define GK104_DISP_CURSOR                             /* cl507a.h */ 0x0000917a
-#define GV100_DISP_CURSOR                             /* cl507a.h */ 0x0000c37a
-#define TU102_DISP_CURSOR                             /* cl507a.h */ 0x0000c57a
-#define GA102_DISP_CURSOR                             /* cl507a.h */ 0x0000c67a
-
-#define NV50_DISP_OVERLAY                             /* cl507b.h */ 0x0000507b
-#define G82_DISP_OVERLAY                              /* cl507b.h */ 0x0000827b
-#define GT214_DISP_OVERLAY                            /* cl507b.h */ 0x0000857b
-#define GF110_DISP_OVERLAY                            /* cl507b.h */ 0x0000907b
-#define GK104_DISP_OVERLAY                            /* cl507b.h */ 0x0000917b
-
-#define GV100_DISP_WINDOW_IMM_CHANNEL_DMA             /* clc37b.h */ 0x0000c37b
-#define TU102_DISP_WINDOW_IMM_CHANNEL_DMA             /* clc37b.h */ 0x0000c57b
-#define GA102_DISP_WINDOW_IMM_CHANNEL_DMA             /* clc37b.h */ 0x0000c67b
-
-#define NV50_DISP_BASE_CHANNEL_DMA                    /* cl507c.h */ 0x0000507c
-#define G82_DISP_BASE_CHANNEL_DMA                     /* cl507c.h */ 0x0000827c
-#define GT200_DISP_BASE_CHANNEL_DMA                   /* cl507c.h */ 0x0000837c
-#define GT214_DISP_BASE_CHANNEL_DMA                   /* cl507c.h */ 0x0000857c
-#define GF110_DISP_BASE_CHANNEL_DMA                   /* cl507c.h */ 0x0000907c
-#define GK104_DISP_BASE_CHANNEL_DMA                   /* cl507c.h */ 0x0000917c
-#define GK110_DISP_BASE_CHANNEL_DMA                   /* cl507c.h */ 0x0000927c
-
-#define NV50_DISP_CORE_CHANNEL_DMA                    /* cl507d.h */ 0x0000507d
-#define G82_DISP_CORE_CHANNEL_DMA                     /* cl507d.h */ 0x0000827d
-#define GT200_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000837d
-#define GT214_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000857d
-#define GT206_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000887d
-#define GF110_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000907d
-#define GK104_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000917d
-#define GK110_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000927d
-#define GM107_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000947d
-#define GM200_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000957d
-#define GP100_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000977d
-#define GP102_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000987d
-#define GV100_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000c37d
-#define TU102_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000c57d
-#define GA102_DISP_CORE_CHANNEL_DMA                   /* cl507d.h */ 0x0000c67d
-
-#define NV50_DISP_OVERLAY_CHANNEL_DMA                 /* cl507e.h */ 0x0000507e
-#define G82_DISP_OVERLAY_CHANNEL_DMA                  /* cl507e.h */ 0x0000827e
-#define GT200_DISP_OVERLAY_CHANNEL_DMA                /* cl507e.h */ 0x0000837e
-#define GT214_DISP_OVERLAY_CHANNEL_DMA                /* cl507e.h */ 0x0000857e
-#define GF110_DISP_OVERLAY_CONTROL_DMA                /* cl507e.h */ 0x0000907e
-#define GK104_DISP_OVERLAY_CONTROL_DMA                /* cl507e.h */ 0x0000917e
-
-#define GV100_DISP_WINDOW_CHANNEL_DMA                 /* clc37e.h */ 0x0000c37e
-#define TU102_DISP_WINDOW_CHANNEL_DMA                 /* clc37e.h */ 0x0000c57e
-#define GA102_DISP_WINDOW_CHANNEL_DMA                 /* clc37e.h */ 0x0000c67e
+#define NV50_DISP_CURSOR                              /* if0014.h */ 0x0000507a
+#define G82_DISP_CURSOR                               /* if0014.h */ 0x0000827a
+#define GT214_DISP_CURSOR                             /* if0014.h */ 0x0000857a
+#define GF110_DISP_CURSOR                             /* if0014.h */ 0x0000907a
+#define GK104_DISP_CURSOR                             /* if0014.h */ 0x0000917a
+#define GV100_DISP_CURSOR                             /* if0014.h */ 0x0000c37a
+#define TU102_DISP_CURSOR                             /* if0014.h */ 0x0000c57a
+#define GA102_DISP_CURSOR                             /* if0014.h */ 0x0000c67a
+
+#define NV50_DISP_OVERLAY                             /* if0014.h */ 0x0000507b
+#define G82_DISP_OVERLAY                              /* if0014.h */ 0x0000827b
+#define GT214_DISP_OVERLAY                            /* if0014.h */ 0x0000857b
+#define GF110_DISP_OVERLAY                            /* if0014.h */ 0x0000907b
+#define GK104_DISP_OVERLAY                            /* if0014.h */ 0x0000917b
+
+#define GV100_DISP_WINDOW_IMM_CHANNEL_DMA             /* if0014.h */ 0x0000c37b
+#define TU102_DISP_WINDOW_IMM_CHANNEL_DMA             /* if0014.h */ 0x0000c57b
+#define GA102_DISP_WINDOW_IMM_CHANNEL_DMA             /* if0014.h */ 0x0000c67b
+
+#define NV50_DISP_BASE_CHANNEL_DMA                    /* if0014.h */ 0x0000507c
+#define G82_DISP_BASE_CHANNEL_DMA                     /* if0014.h */ 0x0000827c
+#define GT200_DISP_BASE_CHANNEL_DMA                   /* if0014.h */ 0x0000837c
+#define GT214_DISP_BASE_CHANNEL_DMA                   /* if0014.h */ 0x0000857c
+#define GF110_DISP_BASE_CHANNEL_DMA                   /* if0014.h */ 0x0000907c
+#define GK104_DISP_BASE_CHANNEL_DMA                   /* if0014.h */ 0x0000917c
+#define GK110_DISP_BASE_CHANNEL_DMA                   /* if0014.h */ 0x0000927c
+
+#define NV50_DISP_CORE_CHANNEL_DMA                    /* if0014.h */ 0x0000507d
+#define G82_DISP_CORE_CHANNEL_DMA                     /* if0014.h */ 0x0000827d
+#define GT200_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000837d
+#define GT214_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000857d
+#define GT206_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000887d
+#define GF110_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000907d
+#define GK104_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000917d
+#define GK110_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000927d
+#define GM107_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000947d
+#define GM200_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000957d
+#define GP100_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000977d
+#define GP102_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000987d
+#define GV100_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000c37d
+#define TU102_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000c57d
+#define GA102_DISP_CORE_CHANNEL_DMA                   /* if0014.h */ 0x0000c67d
+
+#define NV50_DISP_OVERLAY_CHANNEL_DMA                 /* if0014.h */ 0x0000507e
+#define G82_DISP_OVERLAY_CHANNEL_DMA                  /* if0014.h */ 0x0000827e
+#define GT200_DISP_OVERLAY_CHANNEL_DMA                /* if0014.h */ 0x0000837e
+#define GT214_DISP_OVERLAY_CHANNEL_DMA                /* if0014.h */ 0x0000857e
+#define GF110_DISP_OVERLAY_CONTROL_DMA                /* if0014.h */ 0x0000907e
+#define GK104_DISP_OVERLAY_CONTROL_DMA                /* if0014.h */ 0x0000917e
+
+#define GV100_DISP_WINDOW_CHANNEL_DMA                 /* if0014.h */ 0x0000c37e
+#define TU102_DISP_WINDOW_CHANNEL_DMA                 /* if0014.h */ 0x0000c57e
+#define GA102_DISP_WINDOW_CHANNEL_DMA                 /* if0014.h */ 0x0000c67e
 
 #define NV50_TESLA                                                   0x00005097
 #define G82_TESLA                                                    0x00008297
diff --git a/drivers/gpu/drm/nouveau/include/nvif/clc37b.h b/drivers/gpu/drm/nouveau/include/nvif/clc37b.h
deleted file mode 100644 (file)
index 970a5ac..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CLC37B_H__
-#define __NVIF_CLC37B_H__
-
-struct nvc37b_window_imm_channel_dma_v0 {
-       __u8  version;
-       __u8  index;
-       __u8  pad02[6];
-       __u64 pushbuf;
-};
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/clc37e.h b/drivers/gpu/drm/nouveau/include/nvif/clc37e.h
deleted file mode 100644 (file)
index 7ea2369..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_CLC37E_H__
-#define __NVIF_CLC37E_H__
-
-struct nvc37e_window_channel_dma_v0 {
-       __u8  version;
-       __u8  index;
-       __u8  pad02[6];
-       __u64 pushbuf;
-};
-
-#define NVC37E_WINDOW_CHANNEL_DMA_V0_NTFY_UEVENT                           0x00
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/conn.h b/drivers/gpu/drm/nouveau/include/nvif/conn.h
new file mode 100644 (file)
index 0000000..f72a8f1
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_CONN_H__
+#define __NVIF_CONN_H__
+#include <nvif/object.h>
+struct nvif_disp;
+
+struct nvif_conn {
+       struct nvif_object object;
+};
+
+int nvif_conn_ctor(struct nvif_disp *, const char *name, int id, struct nvif_conn *);
+void nvif_conn_dtor(struct nvif_conn *);
+
+#define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */
+#define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1
+#define NVIF_CONN_HPD_STATUS_PRESENT     2
+int nvif_conn_hpd_status(struct nvif_conn *);
+#endif
index 07ac544..742632a 100644 (file)
@@ -5,6 +5,8 @@ struct nvif_device;
 
 struct nvif_disp {
        struct nvif_object object;
+       unsigned long conn_mask;
+       unsigned long outp_mask;
 };
 
 int nvif_disp_ctor(struct nvif_device *, const char *name, s32 oclass,
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0010.h b/drivers/gpu/drm/nouveau/include/nvif/if0010.h
new file mode 100644 (file)
index 0000000..fc236ef
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_IF0010_H__
+#define __NVIF_IF0010_H__
+
+union nvif_disp_args {
+       struct nvif_disp_v0 {
+               __u8 version;
+               __u8 pad01[3];
+               __u32 conn_mask;
+               __u32 outp_mask;
+       } v0;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0011.h b/drivers/gpu/drm/nouveau/include/nvif/if0011.h
new file mode 100644 (file)
index 0000000..04ba658
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_IF0011_H__
+#define __NVIF_IF0011_H__
+
+union nvif_conn_args {
+       struct nvif_conn_v0 {
+               __u8 version;
+               __u8 id;        /* DCB connector table index. */
+               __u8 pad02[6];
+       } v0;
+};
+
+#define NVIF_CONN_V0_HPD_STATUS 0x00000000
+
+union nvif_conn_hpd_status_args {
+       struct nvif_conn_hpd_status_v0 {
+               __u8 version;
+               __u8 support;
+               __u8 present;
+               __u8 pad03[5];
+       } v0;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
new file mode 100644 (file)
index 0000000..243bd35
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_IF0012_H__
+#define __NVIF_IF0012_H__
+
+union nvif_outp_args {
+       struct nvif_outp_v0 {
+               __u8 version;
+               __u8 id;        /* DCB device index. */
+               __u8 pad02[6];
+       } v0;
+};
+
+#define NVIF_OUTP_V0_LOAD_DETECT 0x00
+
+union nvif_outp_load_detect_args {
+       struct nvif_outp_load_detect_v0 {
+               __u8  version;
+               __u8  load;
+               __u8  pad02[2];
+               __u32 data; /*TODO: move vbios loadval parsing into nvkm */
+       } v0;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0014.h b/drivers/gpu/drm/nouveau/include/nvif/if0014.h
new file mode 100644 (file)
index 0000000..be03628
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_IF0014_H__
+#define __NVIF_IF0014_H__
+
+union nvif_disp_chan_args {
+       struct nvif_disp_chan_v0 {
+               __u8  version;
+               __u8  id;
+               __u8  pad02[6];
+               __u64 pushbuf;
+       } v0;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h b/drivers/gpu/drm/nouveau/include/nvif/outp.h
new file mode 100644 (file)
index 0000000..0d6aa07
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_OUTP_H__
+#define __NVIF_OUTP_H__
+#include <nvif/object.h>
+struct nvif_disp;
+
+struct nvif_outp {
+       struct nvif_object object;
+};
+
+int nvif_outp_ctor(struct nvif_disp *, const char *name, int id, struct nvif_outp *);
+void nvif_outp_dtor(struct nvif_outp *);
+int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
+#endif
index 6c299ec..ec524b2 100644 (file)
 #endif
 
 #define NVIF_ERROR(o,f,a...) NVIF_PRINT(errorf, (o), f, ##a)
+#define NVIF_ERRON(c,o,f,a...) do {                            \
+       struct nvif_object *_object = (o);                     \
+       int _cond = (c);                                       \
+       if (_cond) {                                           \
+               NVIF_ERROR(_object, f" (ret:%d)", ##a, _cond); \
+       } else {                                               \
+               NVIF_DEBUG(_object, f, ##a);                   \
+       }                                                      \
+} while(0)
 #endif
index d08d333..8b5d8a4 100644 (file)
@@ -3,23 +3,56 @@
 #define __NVKM_DISP_H__
 #define nvkm_disp(p) container_of((p), struct nvkm_disp, engine)
 #include <core/engine.h>
+#include <core/object.h>
 #include <core/event.h>
 
 struct nvkm_disp {
        const struct nvkm_disp_func *func;
        struct nvkm_engine engine;
 
-       struct list_head head;
-       struct list_head ior;
-       struct list_head outp;
-       struct list_head conn;
+       struct list_head heads;
+       struct list_head iors;
+       struct list_head outps;
+       struct list_head conns;
 
        struct nvkm_event hpd;
        struct nvkm_event vblank;
 
        struct {
+               struct workqueue_struct *wq;
+               struct work_struct work;
+               u32 pending;
+               struct mutex mutex;
+       } super;
+
+#define NVKM_DISP_EVENT_CHAN_AWAKEN BIT(0)
+       struct nvkm_event uevent;
+
+       struct {
+               unsigned long mask;
+               int nr;
+       } wndw, head, dac;
+
+       struct {
+               unsigned long mask;
+               int nr;
+               u32 lvdsconf;
+       } sor;
+
+       struct {
+               unsigned long mask;
+               int nr;
+               u8 type[3];
+       } pior;
+
+       struct nvkm_gpuobj *inst;
+       struct nvkm_ramht *ramht;
+
+       struct nvkm_disp_chan *chan[81];
+
+       struct {
                spinlock_t lock;
-               struct nvkm_oproxy *object;
+               struct nvkm_object object;
        } client;
 };
 
index a27a0f3..73f9d99 100644 (file)
@@ -54,6 +54,7 @@ struct dcb_output {
                } tmdsconf;
        };
        bool i2c_upper_default;
+       int id;
 };
 
 u16 dcb_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
index 41b78e9..189903b 100644 (file)
@@ -1801,6 +1801,8 @@ parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp)
                        ret = parse_dcb20_entry(dev, dcb, conn, conf, entry);
                else
                        ret = parse_dcb15_entry(dev, dcb, conn, conf, entry);
+               entry->id = idx;
+
                if (!ret)
                        return 1; /* stop parsing */
 
index df83c46..43a9d1e 100644 (file)
@@ -404,6 +404,7 @@ nouveau_connector_destroy(struct drm_connector *connector)
                drm_dp_cec_unregister_connector(&nv_connector->aux);
                kfree(nv_connector->aux.name);
        }
+       nvif_conn_dtor(&nv_connector->conn);
        kfree(connector);
 }
 
@@ -1386,6 +1387,15 @@ nouveau_connector_create(struct drm_device *dev,
        drm_connector_init(dev, connector, funcs, type);
        drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
 
+       if (nv_connector->dcb && (disp->disp.conn_mask & BIT(nv_connector->index))) {
+               ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index,
+                                    &nv_connector->conn);
+               if (ret) {
+                       kfree(nv_connector);
+                       return ERR_PTR(ret);
+               }
+       }
+
        connector->funcs->reset(connector);
        nouveau_conn_attach_properties(connector);
 
index b0773af..4bf0c70 100644 (file)
@@ -26,7 +26,7 @@
 
 #ifndef __NOUVEAU_CONNECTOR_H__
 #define __NOUVEAU_CONNECTOR_H__
-
+#include <nvif/conn.h>
 #include <nvif/notify.h>
 
 #include <nvhw/class/cl507d.h>
@@ -123,6 +123,7 @@ struct nouveau_connector {
        u8 index;
        u8 *dcb;
 
+       struct nvif_conn conn;
        struct nvif_notify hpd;
 
        struct drm_dp_aux aux;
index c36f510..20db8ea 100644 (file)
@@ -107,7 +107,7 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
        struct nv50_mstm *mstm = nv_encoder->dp.mstm;
        enum drm_connector_status status;
        u8 *dpcd = nv_encoder->dp.dpcd;
-       int ret = NOUVEAU_DP_NONE;
+       int ret = NOUVEAU_DP_NONE, hpd;
 
        /* If we've already read the DPCD on an eDP device, we don't need to
         * reread it as it won't change
@@ -133,6 +133,16 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
                }
        }
 
+       /* Check status of HPD pin before attempting an AUX transaction that
+        * would result in a number of (futile) retries on a connector which
+        * has no display plugged.
+        *
+        * TODO: look into checking this before probing I2C to detect DVI/HDMI
+        */
+       hpd = nvif_conn_hpd_status(&nv_connector->conn);
+       if (hpd == NVIF_CONN_HPD_STATUS_NOT_PRESENT)
+               goto out;
+
        status = nouveau_dp_probe_dpcd(nv_connector, nv_encoder);
        if (status == connector_status_disconnected)
                goto out;
index c2f5f0c..b72e578 100644 (file)
@@ -26,7 +26,7 @@
 
 #ifndef __NOUVEAU_ENCODER_H__
 #define __NOUVEAU_ENCODER_H__
-
+#include <nvif/outp.h>
 #include <subdev/bios/dcb.h>
 
 #include <drm/display/drm_dp_helper.h>
@@ -46,6 +46,7 @@ struct nouveau_encoder {
        struct drm_encoder_slave base;
 
        struct dcb_output *dcb;
+       struct nvif_outp outp;
        int or;
        int link;
 
index f194d35..6abc4bc 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: MIT
 nvif-y := nvif/object.o
 nvif-y += nvif/client.o
+nvif-y += nvif/conn.o
 nvif-y += nvif/device.o
 nvif-y += nvif/disp.o
 nvif-y += nvif/driver.o
@@ -8,6 +9,7 @@ nvif-y += nvif/fifo.o
 nvif-y += nvif/mem.o
 nvif-y += nvif/mmu.o
 nvif-y += nvif/notify.o
+nvif-y += nvif/outp.o
 nvif-y += nvif/timer.o
 nvif-y += nvif/vmm.o
 
similarity index 56%
rename from drivers/gpu/drm/nouveau/nvkm/engine/disp/rootga102.c
rename to drivers/gpu/drm/nouveau/nvif/conn.c
index 9af07c3..4ce935d 100644 (file)
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "rootnv50.h"
-#include "channv50.h"
+#include <nvif/conn.h>
+#include <nvif/disp.h>
+#include <nvif/printf.h>
 
 #include <nvif/class.h>
+#include <nvif/if0011.h>
 
-static const struct nv50_disp_root_func
-ga102_disp_root = {
-       .user = {
-               {{-1,-1,GV100_DISP_CAPS                }, gv100_disp_caps_new },
-               {{0,0,GA102_DISP_CURSOR                }, gv100_disp_curs_new },
-               {{0,0,GA102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new },
-               {{0,0,GA102_DISP_CORE_CHANNEL_DMA      }, gv100_disp_core_new },
-               {{0,0,GA102_DISP_WINDOW_CHANNEL_DMA    }, gv100_disp_wndw_new },
-               {}
-       },
-};
-
-static int
-ga102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
+int
+nvif_conn_hpd_status(struct nvif_conn *conn)
 {
-       return nv50_disp_root_new_(&ga102_disp_root, disp, oclass, data, size, pobject);
+       struct nvif_conn_hpd_status_v0 args;
+       int ret;
+
+       args.version = 0;
+
+       ret = nvif_mthd(&conn->object, NVIF_CONN_V0_HPD_STATUS, &args, sizeof(args));
+       NVIF_ERRON(ret, &conn->object, "[HPD_STATUS] support:%d present:%d",
+                  args.support, args.present);
+       return ret ? ret : !!args.support + !!args.present;
+}
+
+void
+nvif_conn_dtor(struct nvif_conn *conn)
+{
+       nvif_object_dtor(&conn->object);
 }
 
-const struct nvkm_disp_oclass
-ga102_disp_root_oclass = {
-       .base.oclass = GA102_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = ga102_disp_root_new,
-};
+int
+nvif_conn_ctor(struct nvif_disp *disp, const char *name, int id, struct nvif_conn *conn)
+{
+       struct nvif_conn_v0 args;
+       int ret;
+
+       args.version = 0;
+       args.id = id;
+
+       ret = nvif_object_ctor(&disp->object, name ?: "nvifConn", id, NVIF_CLASS_CONN,
+                              &args, sizeof(args), &conn->object);
+       NVIF_ERRON(ret, &disp->object, "[NEW conn id:%d]", id);
+       return ret;
+}
index 529cb60..926b0c0 100644 (file)
  */
 #include <nvif/disp.h>
 #include <nvif/device.h>
+#include <nvif/printf.h>
 
 #include <nvif/class.h>
+#include <nvif/if0010.h>
 
 void
 nvif_disp_dtor(struct nvif_disp *disp)
@@ -31,33 +33,48 @@ nvif_disp_dtor(struct nvif_disp *disp)
 }
 
 int
-nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass,
-              struct nvif_disp *disp)
+nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, struct nvif_disp *disp)
 {
        static const struct nvif_mclass disps[] = {
-               { GA102_DISP, -1 },
-               { TU102_DISP, -1 },
-               { GV100_DISP, -1 },
-               { GP102_DISP, -1 },
-               { GP100_DISP, -1 },
-               { GM200_DISP, -1 },
-               { GM107_DISP, -1 },
-               { GK110_DISP, -1 },
-               { GK104_DISP, -1 },
-               { GF110_DISP, -1 },
-               { GT214_DISP, -1 },
-               { GT206_DISP, -1 },
-               { GT200_DISP, -1 },
-               {   G82_DISP, -1 },
-               {  NV50_DISP, -1 },
-               {  NV04_DISP, -1 },
+               { GA102_DISP, 0 },
+               { TU102_DISP, 0 },
+               { GV100_DISP, 0 },
+               { GP102_DISP, 0 },
+               { GP100_DISP, 0 },
+               { GM200_DISP, 0 },
+               { GM107_DISP, 0 },
+               { GK110_DISP, 0 },
+               { GK104_DISP, 0 },
+               { GF110_DISP, 0 },
+               { GT214_DISP, 0 },
+               { GT206_DISP, 0 },
+               { GT200_DISP, 0 },
+               {   G82_DISP, 0 },
+               {  NV50_DISP, 0 },
+               {  NV04_DISP, 0 },
                {}
        };
-       int cid = nvif_sclass(&device->object, disps, oclass);
+       struct nvif_disp_v0 args;
+       int cid, ret;
+
+       cid = nvif_sclass(&device->object, disps, oclass);
        disp->object.client = NULL;
-       if (cid < 0)
+       if (cid < 0) {
+               NVIF_ERRON(cid, &device->object, "[NEW disp%04x] not supported", oclass);
                return cid;
+       }
+
+       args.version = 0;
+
+       ret = nvif_object_ctor(&device->object, name ?: "nvifDisp", 0,
+                              disps[cid].oclass, &args, sizeof(args), &disp->object);
+       NVIF_ERRON(ret, &device->object, "[NEW disp%04x]", disps[cid].oclass);
+       if (ret)
+               return ret;
 
-       return nvif_object_ctor(&device->object, name ? name : "nvifDisp", 0,
-                               disps[cid].oclass, NULL, 0, &disp->object);
+       NVIF_DEBUG(&disp->object, "[NEW] conn_mask:%08x outp_mask:%08x",
+                  args.conn_mask, args.outp_mask);
+       disp->conn_mask = args.conn_mask;
+       disp->outp_mask = args.outp_mask;
+       return 0;
 }
similarity index 54%
rename from drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c
rename to drivers/gpu/drm/nouveau/nvif/outp.c
index ef579eb..7bfe91a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Red Hat Inc.
+ * Copyright 2021 Red Hat Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
  */
-#include "rootnv50.h"
-#include "channv50.h"
+#include <nvif/outp.h>
+#include <nvif/disp.h>
+#include <nvif/printf.h>
 
 #include <nvif/class.h>
+#include <nvif/if0012.h>
+
+int
+nvif_outp_load_detect(struct nvif_outp *outp, u32 loadval)
+{
+       struct nvif_outp_load_detect_v0 args;
+       int ret;
+
+       args.version = 0;
+       args.data = loadval;
+
+       ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_LOAD_DETECT, &args, sizeof(args));
+       NVIF_ERRON(ret, &outp->object, "[LOAD_DETECT data:%08x] load:%02x", args.data, args.load);
+       return ret < 0 ? ret : args.load;
+}
 
-static const struct nv50_disp_root_func
-g94_disp_root = {
-       .user = {
-               {{0,0,  G82_DISP_CURSOR             },  nv50_disp_curs_new },
-               {{0,0,  G82_DISP_OVERLAY            },  nv50_disp_oimm_new },
-               {{0,0,GT200_DISP_BASE_CHANNEL_DMA   },   g84_disp_base_new },
-               {{0,0,GT206_DISP_CORE_CHANNEL_DMA   },   g94_disp_core_new },
-               {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-g94_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                 void *data, u32 size, struct nvkm_object **pobject)
+void
+nvif_outp_dtor(struct nvif_outp *outp)
 {
-       return nv50_disp_root_new_(&g94_disp_root, disp, oclass,
-                                  data, size, pobject);
+       nvif_object_dtor(&outp->object);
 }
 
-const struct nvkm_disp_oclass
-g94_disp_root_oclass = {
-       .base.oclass = GT206_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = g94_disp_root_new,
-};
+int
+nvif_outp_ctor(struct nvif_disp *disp, const char *name, int id, struct nvif_outp *outp)
+{
+       struct nvif_outp_v0 args;
+       int ret;
+
+       args.version = 0;
+       args.id = id;
+
+       ret = nvif_object_ctor(&disp->object, name ?: "nvifOutp", id, NVIF_CLASS_OUTP,
+                              &args, sizeof(args), &outp->object);
+       NVIF_ERRON(ret, &disp->object, "[NEW outp id:%d]", id);
+       return ret;
+}
index b03f043..600072a 100644 (file)
@@ -1,5 +1,14 @@
 # SPDX-License-Identifier: MIT
 nvkm-y += nvkm/engine/disp/base.o
+nvkm-y += nvkm/engine/disp/chan.o
+nvkm-y += nvkm/engine/disp/conn.o
+nvkm-y += nvkm/engine/disp/dp.o
+nvkm-y += nvkm/engine/disp/hdmi.o
+nvkm-y += nvkm/engine/disp/head.o
+nvkm-y += nvkm/engine/disp/ior.o
+nvkm-y += nvkm/engine/disp/outp.o
+nvkm-y += nvkm/engine/disp/vga.o
+
 nvkm-y += nvkm/engine/disp/nv04.o
 nvkm-y += nvkm/engine/disp/nv50.o
 nvkm-y += nvkm/engine/disp/g84.o
@@ -18,110 +27,10 @@ nvkm-y += nvkm/engine/disp/gp102.o
 nvkm-y += nvkm/engine/disp/gv100.o
 nvkm-y += nvkm/engine/disp/tu102.o
 nvkm-y += nvkm/engine/disp/ga102.o
-nvkm-y += nvkm/engine/disp/vga.o
-
-nvkm-y += nvkm/engine/disp/head.o
-nvkm-y += nvkm/engine/disp/headnv04.o
-nvkm-y += nvkm/engine/disp/headnv50.o
-nvkm-y += nvkm/engine/disp/headgf119.o
-nvkm-y += nvkm/engine/disp/headgv100.o
-
-nvkm-y += nvkm/engine/disp/ior.o
-nvkm-y += nvkm/engine/disp/dacnv50.o
-nvkm-y += nvkm/engine/disp/dacgf119.o
-nvkm-y += nvkm/engine/disp/piornv50.o
-nvkm-y += nvkm/engine/disp/sornv50.o
-nvkm-y += nvkm/engine/disp/sorg84.o
-nvkm-y += nvkm/engine/disp/sorg94.o
-nvkm-y += nvkm/engine/disp/sormcp77.o
-nvkm-y += nvkm/engine/disp/sorgt215.o
-nvkm-y += nvkm/engine/disp/sormcp89.o
-nvkm-y += nvkm/engine/disp/sorgf119.o
-nvkm-y += nvkm/engine/disp/sorgk104.o
-nvkm-y += nvkm/engine/disp/sorgm107.o
-nvkm-y += nvkm/engine/disp/sorgm200.o
-nvkm-y += nvkm/engine/disp/sorgp100.o
-nvkm-y += nvkm/engine/disp/sorgv100.o
-nvkm-y += nvkm/engine/disp/sortu102.o
-nvkm-y += nvkm/engine/disp/sorga102.o
-
-nvkm-y += nvkm/engine/disp/outp.o
-nvkm-y += nvkm/engine/disp/dp.o
-
-nvkm-y += nvkm/engine/disp/hdagt215.o
-nvkm-y += nvkm/engine/disp/hdagf119.o
-nvkm-y += nvkm/engine/disp/hdagv100.o
-
-nvkm-y += nvkm/engine/disp/hdmi.o
-nvkm-y += nvkm/engine/disp/hdmig84.o
-nvkm-y += nvkm/engine/disp/hdmigt215.o
-nvkm-y += nvkm/engine/disp/hdmigf119.o
-nvkm-y += nvkm/engine/disp/hdmigk104.o
-nvkm-y += nvkm/engine/disp/hdmigm200.o
-nvkm-y += nvkm/engine/disp/hdmigv100.o
-
-nvkm-y += nvkm/engine/disp/conn.o
 
 nvkm-y += nvkm/engine/disp/rootnv04.o
 nvkm-y += nvkm/engine/disp/rootnv50.o
-nvkm-y += nvkm/engine/disp/rootg84.o
-nvkm-y += nvkm/engine/disp/rootg94.o
-nvkm-y += nvkm/engine/disp/rootgt200.o
-nvkm-y += nvkm/engine/disp/rootgt215.o
-nvkm-y += nvkm/engine/disp/rootgf119.o
-nvkm-y += nvkm/engine/disp/rootgk104.o
-nvkm-y += nvkm/engine/disp/rootgk110.o
-nvkm-y += nvkm/engine/disp/rootgm107.o
-nvkm-y += nvkm/engine/disp/rootgm200.o
-nvkm-y += nvkm/engine/disp/rootgp100.o
-nvkm-y += nvkm/engine/disp/rootgp102.o
-nvkm-y += nvkm/engine/disp/rootgv100.o
-nvkm-y += nvkm/engine/disp/roottu102.o
-nvkm-y += nvkm/engine/disp/rootga102.o
-
-nvkm-y += nvkm/engine/disp/capsgv100.o
-
-nvkm-y += nvkm/engine/disp/channv50.o
-nvkm-y += nvkm/engine/disp/changf119.o
-nvkm-y += nvkm/engine/disp/changv100.o
-
-nvkm-y += nvkm/engine/disp/dmacnv50.o
-nvkm-y += nvkm/engine/disp/dmacgf119.o
-nvkm-y += nvkm/engine/disp/dmacgp102.o
-nvkm-y += nvkm/engine/disp/dmacgv100.o
-
-nvkm-y += nvkm/engine/disp/basenv50.o
-nvkm-y += nvkm/engine/disp/baseg84.o
-nvkm-y += nvkm/engine/disp/basegf119.o
-nvkm-y += nvkm/engine/disp/basegp102.o
-
-nvkm-y += nvkm/engine/disp/corenv50.o
-nvkm-y += nvkm/engine/disp/coreg84.o
-nvkm-y += nvkm/engine/disp/coreg94.o
-nvkm-y += nvkm/engine/disp/coregf119.o
-nvkm-y += nvkm/engine/disp/coregk104.o
-nvkm-y += nvkm/engine/disp/coregp102.o
-nvkm-y += nvkm/engine/disp/coregv100.o
-
-nvkm-y += nvkm/engine/disp/ovlynv50.o
-nvkm-y += nvkm/engine/disp/ovlyg84.o
-nvkm-y += nvkm/engine/disp/ovlygt200.o
-nvkm-y += nvkm/engine/disp/ovlygf119.o
-nvkm-y += nvkm/engine/disp/ovlygk104.o
-nvkm-y += nvkm/engine/disp/ovlygp102.o
-
-nvkm-y += nvkm/engine/disp/wimmgv100.o
-
-nvkm-y += nvkm/engine/disp/wndwgv100.o
-
-nvkm-y += nvkm/engine/disp/piocnv50.o
-nvkm-y += nvkm/engine/disp/piocgf119.o
-
-nvkm-y += nvkm/engine/disp/cursnv50.o
-nvkm-y += nvkm/engine/disp/cursgf119.o
-nvkm-y += nvkm/engine/disp/cursgp102.o
-nvkm-y += nvkm/engine/disp/cursgv100.o
 
-nvkm-y += nvkm/engine/disp/oimmnv50.o
-nvkm-y += nvkm/engine/disp/oimmgf119.o
-nvkm-y += nvkm/engine/disp/oimmgp102.o
+nvkm-y += nvkm/engine/disp/udisp.o
+nvkm-y += nvkm/engine/disp/uconn.o
+nvkm-y += nvkm/engine/disp/uoutp.o
index 5daa777..65c99d9 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <core/client.h>
 #include <core/notify.h>
-#include <core/oproxy.h>
+#include <core/ramht.h>
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
 
@@ -108,7 +108,7 @@ nvkm_disp_hpd_ctor(struct nvkm_object *object, void *data, u32 size,
 
        if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
                notify->size = sizeof(struct nvif_notify_conn_rep_v0);
-               list_for_each_entry(outp, &disp->outp, head) {
+               list_for_each_entry(outp, &disp->outps, head) {
                        if (ret = -ENXIO, outp->conn->index == req->v0.conn) {
                                if (ret = -ENODEV, outp->conn->hpd.event) {
                                        notify->types = req->v0.mask;
@@ -145,45 +145,12 @@ nvkm_disp_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **event)
        return -EINVAL;
 }
 
-static void
-nvkm_disp_class_del(struct nvkm_oproxy *oproxy)
-{
-       struct nvkm_disp *disp = nvkm_disp(oproxy->base.engine);
-       spin_lock(&disp->client.lock);
-       if (disp->client.object == oproxy)
-               disp->client.object = NULL;
-       spin_unlock(&disp->client.lock);
-}
-
-static const struct nvkm_oproxy_func
-nvkm_disp_class = {
-       .dtor[1] = nvkm_disp_class_del,
-};
-
 static int
 nvkm_disp_class_new(struct nvkm_device *device,
                    const struct nvkm_oclass *oclass, void *data, u32 size,
                    struct nvkm_object **pobject)
 {
-       const struct nvkm_disp_oclass *sclass = oclass->engn;
-       struct nvkm_disp *disp = nvkm_disp(oclass->engine);
-       struct nvkm_oproxy *oproxy;
-       int ret;
-
-       ret = nvkm_oproxy_new_(&nvkm_disp_class, oclass, &oproxy);
-       if (ret)
-               return ret;
-       *pobject = &oproxy->base;
-
-       spin_lock(&disp->client.lock);
-       if (disp->client.object) {
-               spin_unlock(&disp->client.lock);
-               return -EBUSY;
-       }
-       disp->client.object = oproxy;
-       spin_unlock(&disp->client.lock);
-
-       return sclass->ctor(disp, oclass, data, size, &oproxy->object);
+       return nvkm_udisp_new(oclass, data, size, pobject);
 }
 
 static const struct nvkm_device_oclass
@@ -197,9 +164,7 @@ nvkm_disp_class_get(struct nvkm_oclass *oclass, int index,
 {
        struct nvkm_disp *disp = nvkm_disp(oclass->engine);
        if (index == 0) {
-               const struct nvkm_disp_oclass *root = disp->func->root(disp);
-               oclass->base = root->base;
-               oclass->engn = root;
+               oclass->base = disp->func->root;
                *class = &nvkm_disp_sclass;
                return 0;
        }
@@ -223,11 +188,11 @@ nvkm_disp_fini(struct nvkm_engine *engine, bool suspend)
        if (disp->func->fini)
                disp->func->fini(disp);
 
-       list_for_each_entry(outp, &disp->outp, head) {
+       list_for_each_entry(outp, &disp->outps, head) {
                nvkm_outp_fini(outp);
        }
 
-       list_for_each_entry(conn, &disp->conn, head) {
+       list_for_each_entry(conn, &disp->conns, head) {
                nvkm_conn_fini(conn);
        }
 
@@ -242,11 +207,11 @@ nvkm_disp_init(struct nvkm_engine *engine)
        struct nvkm_outp *outp;
        struct nvkm_ior *ior;
 
-       list_for_each_entry(conn, &disp->conn, head) {
+       list_for_each_entry(conn, &disp->conns, head) {
                nvkm_conn_init(conn);
        }
 
-       list_for_each_entry(outp, &disp->outp, head) {
+       list_for_each_entry(outp, &disp->outps, head) {
                nvkm_outp_init(outp);
        }
 
@@ -259,7 +224,7 @@ nvkm_disp_init(struct nvkm_engine *engine)
        /* 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) {
+       list_for_each_entry(ior, &disp->iors, head) {
                ior->func->power(ior, true, true, true, true, true);
        }
 
@@ -326,12 +291,12 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
                        continue;
                }
 
-               list_add_tail(&outp->head, &disp->outp);
+               list_add_tail(&outp->head, &disp->outps);
                hpd = max(hpd, (u8)(dcbE.connector + 1));
        }
 
        /* Create connector objects based on available output paths. */
-       list_for_each_entry_safe(outp, outt, &disp->outp, head) {
+       list_for_each_entry_safe(outp, outt, &disp->outps, head) {
                /* VBIOS data *should* give us the most useful information. */
                data = nvbios_connEp(bios, outp->info.connector, &ver, &hdr,
                                     &connE);
@@ -345,7 +310,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
                         */
                        int ccb_index = outp->info.i2c_index;
                        if (ccb_index != 0xf) {
-                               list_for_each_entry(pair, &disp->outp, head) {
+                               list_for_each_entry(pair, &disp->outps, head) {
                                        if (pair->info.i2c_index == ccb_index) {
                                                outp->conn = pair->conn;
                                                break;
@@ -365,7 +330,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
                }
 
                /* Check that we haven't already created this connector. */
-               list_for_each_entry(conn, &disp->conn, head) {
+               list_for_each_entry(conn, &disp->conns, head) {
                        if (conn->index == outp->info.connector) {
                                outp->conn = conn;
                                break;
@@ -387,7 +352,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
                        continue;
                }
 
-               list_add_tail(&outp->conn->head, &disp->conn);
+               list_add_tail(&outp->conn->head, &disp->conns);
        }
 
        ret = nvkm_event_init(&nvkm_disp_hpd_func, 3, hpd, &disp->hpd);
@@ -403,7 +368,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
        /* Enforce identity-mapped SOR assignment for panels, which have
         * certain bits (ie. backlight controls) wired to a specific SOR.
         */
-       list_for_each_entry(outp, &disp->outp, head) {
+       list_for_each_entry(outp, &disp->outps, head) {
                if (outp->conn->info.type == DCB_CONNECTOR_LVDS ||
                    outp->conn->info.type == DCB_CONNECTOR_eDP) {
                        ior = nvkm_ior_find(disp, SOR, ffs(outp->info.or) - 1);
@@ -414,7 +379,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
        }
 
        i = 0;
-       list_for_each_entry(head, &disp->head, head)
+       list_for_each_entry(head, &disp->heads, head)
                i = max(i, head->id + 1);
 
        return nvkm_event_init(&nvkm_disp_vblank_func, 1, i, &disp->vblank);
@@ -426,35 +391,42 @@ nvkm_disp_dtor(struct nvkm_engine *engine)
        struct nvkm_disp *disp = nvkm_disp(engine);
        struct nvkm_conn *conn;
        struct nvkm_outp *outp;
+       struct nvkm_ior *ior;
+       struct nvkm_head *head;
        void *data = disp;
 
-       if (disp->func->dtor)
-               data = disp->func->dtor(disp);
+       nvkm_ramht_del(&disp->ramht);
+       nvkm_gpuobj_del(&disp->inst);
+
+       nvkm_event_fini(&disp->uevent);
+
+       if (disp->super.wq) {
+               destroy_workqueue(disp->super.wq);
+               mutex_destroy(&disp->super.mutex);
+       }
 
        nvkm_event_fini(&disp->vblank);
        nvkm_event_fini(&disp->hpd);
 
-       while (!list_empty(&disp->conn)) {
-               conn = list_first_entry(&disp->conn, typeof(*conn), head);
+       while (!list_empty(&disp->conns)) {
+               conn = list_first_entry(&disp->conns, typeof(*conn), head);
                list_del(&conn->head);
                nvkm_conn_del(&conn);
        }
 
-       while (!list_empty(&disp->outp)) {
-               outp = list_first_entry(&disp->outp, typeof(*outp), head);
+       while (!list_empty(&disp->outps)) {
+               outp = list_first_entry(&disp->outps, typeof(*outp), head);
                list_del(&outp->head);
                nvkm_outp_del(&outp);
        }
 
-       while (!list_empty(&disp->ior)) {
-               struct nvkm_ior *ior =
-                       list_first_entry(&disp->ior, typeof(*ior), head);
+       while (!list_empty(&disp->iors)) {
+               ior = list_first_entry(&disp->iors, typeof(*ior), head);
                nvkm_ior_del(&ior);
        }
 
-       while (!list_empty(&disp->head)) {
-               struct nvkm_head *head =
-                       list_first_entry(&disp->head, typeof(*head), head);
+       while (!list_empty(&disp->heads)) {
+               head = list_first_entry(&disp->heads, typeof(*head), head);
                nvkm_head_del(&head);
        }
 
@@ -472,23 +444,34 @@ nvkm_disp = {
 };
 
 int
-nvkm_disp_ctor(const struct nvkm_disp_func *func, struct nvkm_device *device,
-              enum nvkm_subdev_type type, int inst, struct nvkm_disp *disp)
-{
-       disp->func = func;
-       INIT_LIST_HEAD(&disp->head);
-       INIT_LIST_HEAD(&disp->ior);
-       INIT_LIST_HEAD(&disp->outp);
-       INIT_LIST_HEAD(&disp->conn);
-       spin_lock_init(&disp->client.lock);
-       return nvkm_engine_ctor(&nvkm_disp, device, type, inst, true, &disp->engine);
-}
-
-int
 nvkm_disp_new_(const struct nvkm_disp_func *func, struct nvkm_device *device,
               enum nvkm_subdev_type type, int inst, struct nvkm_disp **pdisp)
 {
-       if (!(*pdisp = kzalloc(sizeof(**pdisp), GFP_KERNEL)))
+       struct nvkm_disp *disp;
+       int ret;
+
+       if (!(disp = *pdisp = kzalloc(sizeof(**pdisp), GFP_KERNEL)))
                return -ENOMEM;
-       return nvkm_disp_ctor(func, device, type, inst, *pdisp);
+
+       disp->func = func;
+       INIT_LIST_HEAD(&disp->heads);
+       INIT_LIST_HEAD(&disp->iors);
+       INIT_LIST_HEAD(&disp->outps);
+       INIT_LIST_HEAD(&disp->conns);
+       spin_lock_init(&disp->client.lock);
+
+       ret = nvkm_engine_ctor(&nvkm_disp, device, type, inst, true, &disp->engine);
+       if (ret)
+               return ret;
+
+       if (func->super) {
+               disp->super.wq = create_singlethread_workqueue("nvkm-disp");
+               if (!disp->super.wq)
+                       return -ENOMEM;
+
+               INIT_WORK(&disp->super.work, func->super);
+               mutex_init(&disp->super.mutex);
+       }
+
+       return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan), &disp->uevent);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c
deleted file mode 100644 (file)
index 01253f4..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-g84_disp_base_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x000000 },
-               { 0x0084, 0x0008c4 },
-               { 0x0088, 0x0008d0 },
-               { 0x008c, 0x0008dc },
-               { 0x0090, 0x0008e4 },
-               { 0x0094, 0x610884 },
-               { 0x00a0, 0x6108a0 },
-               { 0x00a4, 0x610878 },
-               { 0x00c0, 0x61086c },
-               { 0x00c4, 0x610800 },
-               { 0x00c8, 0x61080c },
-               { 0x00cc, 0x610818 },
-               { 0x00e0, 0x610858 },
-               { 0x00e4, 0x610860 },
-               { 0x00e8, 0x6108ac },
-               { 0x00ec, 0x6108b4 },
-               { 0x00fc, 0x610824 },
-               { 0x0100, 0x610894 },
-               { 0x0104, 0x61082c },
-               { 0x0110, 0x6108bc },
-               { 0x0114, 0x61088c },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-g84_disp_base_mthd = {
-       .name = "Base",
-       .addr = 0x000540,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &g84_disp_base_mthd_base },
-               {  "Image", 2, &nv50_disp_base_mthd_image },
-               {}
-       }
-};
-
-int
-g84_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                 struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_base_new_(&nv50_disp_dmac_func, &g84_disp_base_mthd,
-                                  disp, 1, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c
deleted file mode 100644 (file)
index 389e19d..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-gf119_disp_base_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x661080 },
-               { 0x0084, 0x661084 },
-               { 0x0088, 0x661088 },
-               { 0x008c, 0x66108c },
-               { 0x0090, 0x661090 },
-               { 0x0094, 0x661094 },
-               { 0x00a0, 0x6610a0 },
-               { 0x00a4, 0x6610a4 },
-               { 0x00c0, 0x6610c0 },
-               { 0x00c4, 0x6610c4 },
-               { 0x00c8, 0x6610c8 },
-               { 0x00cc, 0x6610cc },
-               { 0x00e0, 0x6610e0 },
-               { 0x00e4, 0x6610e4 },
-               { 0x00e8, 0x6610e8 },
-               { 0x00ec, 0x6610ec },
-               { 0x00fc, 0x6610fc },
-               { 0x0100, 0x661100 },
-               { 0x0104, 0x661104 },
-               { 0x0108, 0x661108 },
-               { 0x010c, 0x66110c },
-               { 0x0110, 0x661110 },
-               { 0x0114, 0x661114 },
-               { 0x0118, 0x661118 },
-               { 0x011c, 0x66111c },
-               { 0x0130, 0x661130 },
-               { 0x0134, 0x661134 },
-               { 0x0138, 0x661138 },
-               { 0x013c, 0x66113c },
-               { 0x0140, 0x661140 },
-               { 0x0144, 0x661144 },
-               { 0x0148, 0x661148 },
-               { 0x014c, 0x66114c },
-               { 0x0150, 0x661150 },
-               { 0x0154, 0x661154 },
-               { 0x0158, 0x661158 },
-               { 0x015c, 0x66115c },
-               { 0x0160, 0x661160 },
-               { 0x0164, 0x661164 },
-               { 0x0168, 0x661168 },
-               { 0x016c, 0x66116c },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-gf119_disp_base_mthd_image = {
-       .mthd = 0x0020,
-       .addr = 0x000020,
-       .data = {
-               { 0x0400, 0x661400 },
-               { 0x0404, 0x661404 },
-               { 0x0408, 0x661408 },
-               { 0x040c, 0x66140c },
-               { 0x0410, 0x661410 },
-               {}
-       }
-};
-
-const struct nv50_disp_chan_mthd
-gf119_disp_base_mthd = {
-       .name = "Base",
-       .addr = 0x001000,
-       .prev = -0x020000,
-       .data = {
-               { "Global", 1, &gf119_disp_base_mthd_base },
-               {  "Image", 2, &gf119_disp_base_mthd_image },
-               {}
-       }
-};
-
-int
-gf119_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_base_new_(&gf119_disp_dmac_func, &gf119_disp_base_mthd,
-                                  disp, 1, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c
deleted file mode 100644 (file)
index 0cb23d6..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "channv50.h"
-
-int
-gp102_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_base_new_(&gp102_disp_dmac_func, &gf119_disp_base_mthd,
-                                  disp, 1, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c
deleted file mode 100644 (file)
index 19eb7dd..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "head.h"
-
-#include <core/client.h>
-
-#include <nvif/cl507c.h>
-#include <nvif/unpack.h>
-
-int
-nv50_disp_base_new_(const struct nv50_disp_chan_func *func,
-                   const struct nv50_disp_chan_mthd *mthd,
-                   struct nv50_disp *disp, int chid,
-                   const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nvkm_object **pobject)
-{
-       union {
-               struct nv50_disp_base_channel_dma_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       int head, ret = -ENOSYS;
-       u64 push;
-
-       nvif_ioctl(parent, "create disp base channel dma size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create disp base channel dma vers %d "
-                                  "pushbuf %016llx head %d\n",
-                          args->v0.version, args->v0.pushbuf, args->v0.head);
-               if (!nvkm_head_find(&disp->base, args->v0.head))
-                       return -EINVAL;
-               push = args->v0.pushbuf;
-               head = args->v0.head;
-       } else
-               return ret;
-
-       return nv50_disp_dmac_new_(func, mthd, disp, chid + head,
-                                  head, push, oclass, pobject);
-}
-
-static const struct nv50_disp_mthd_list
-nv50_disp_base_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x000000 },
-               { 0x0084, 0x0008c4 },
-               { 0x0088, 0x0008d0 },
-               { 0x008c, 0x0008dc },
-               { 0x0090, 0x0008e4 },
-               { 0x0094, 0x610884 },
-               { 0x00a0, 0x6108a0 },
-               { 0x00a4, 0x610878 },
-               { 0x00c0, 0x61086c },
-               { 0x00e0, 0x610858 },
-               { 0x00e4, 0x610860 },
-               { 0x00e8, 0x6108ac },
-               { 0x00ec, 0x6108b4 },
-               { 0x0100, 0x610894 },
-               { 0x0110, 0x6108bc },
-               { 0x0114, 0x61088c },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-nv50_disp_base_mthd_image = {
-       .mthd = 0x0400,
-       .addr = 0x000000,
-       .data = {
-               { 0x0800, 0x6108f0 },
-               { 0x0804, 0x6108fc },
-               { 0x0808, 0x61090c },
-               { 0x080c, 0x610914 },
-               { 0x0810, 0x610904 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-nv50_disp_base_mthd = {
-       .name = "Base",
-       .addr = 0x000540,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &nv50_disp_base_mthd_base },
-               {  "Image", 2, &nv50_disp_base_mthd_image },
-               {}
-       }
-};
-
-int
-nv50_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                  struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_base_new_(&nv50_disp_dmac_func, &nv50_disp_base_mthd,
-                                  disp, 1, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c
deleted file mode 100644 (file)
index 5026e53..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2020 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#define gv100_disp_caps(p) container_of((p), struct gv100_disp_caps, object)
-#include "rootnv50.h"
-
-struct gv100_disp_caps {
-       struct nvkm_object object;
-       struct nv50_disp *disp;
-};
-
-static int
-gv100_disp_caps_map(struct nvkm_object *object, void *argv, u32 argc,
-                   enum nvkm_object_map *type, u64 *addr, u64 *size)
-{
-       struct gv100_disp_caps *caps = gv100_disp_caps(object);
-       struct nvkm_device *device = caps->disp->base.engine.subdev.device;
-       *type = NVKM_OBJECT_MAP_IO;
-       *addr = 0x640000 + device->func->resource_addr(device, 0);
-       *size = 0x1000;
-       return 0;
-}
-
-static const struct nvkm_object_func
-gv100_disp_caps = {
-       .map = gv100_disp_caps_map,
-};
-
-int
-gv100_disp_caps_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       struct gv100_disp_caps *caps;
-
-       if (!(caps = kzalloc(sizeof(*caps), GFP_KERNEL)))
-               return -ENOMEM;
-       *pobject = &caps->object;
-
-       nvkm_object_ctor(&gv100_disp_caps, oclass, &caps->object);
-       caps->disp = disp;
-       return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c
new file mode 100644 (file)
index 0000000..d5e18da
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2021 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "chan.h"
+
+#include <core/oproxy.h>
+#include <core/ramht.h>
+
+#include <nvif/if0014.h>
+
+static int
+nvkm_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       u64 size, base = chan->func->user(chan, &size);
+
+       *data = nvkm_rd32(device, base + addr);
+       return 0;
+}
+
+static int
+nvkm_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       u64 size, base = chan->func->user(chan, &size);
+
+       nvkm_wr32(device, base + addr, data);
+       return 0;
+}
+
+static int
+nvkm_disp_chan_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **pevent)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+       struct nvkm_disp *disp = chan->disp;
+
+       switch (type) {
+       case 0:
+               *pevent = &disp->uevent;
+               return 0;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int
+nvkm_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc,
+                  enum nvkm_object_map *type, u64 *addr, u64 *size)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u64 base = device->func->resource_addr(device, 0);
+
+       *type = NVKM_OBJECT_MAP_IO;
+       *addr = base + chan->func->user(chan, size);
+       return 0;
+}
+
+struct nvkm_disp_chan_object {
+       struct nvkm_oproxy oproxy;
+       struct nvkm_disp *disp;
+       int hash;
+};
+
+static void
+nvkm_disp_chan_child_del_(struct nvkm_oproxy *base)
+{
+       struct nvkm_disp_chan_object *object = container_of(base, typeof(*object), oproxy);
+
+       nvkm_ramht_remove(object->disp->ramht, object->hash);
+}
+
+static const struct nvkm_oproxy_func
+nvkm_disp_chan_child_func_ = {
+       .dtor[0] = nvkm_disp_chan_child_del_,
+};
+
+static int
+nvkm_disp_chan_child_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
+                        struct nvkm_object **pobject)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(oclass->parent);
+       struct nvkm_disp *disp = chan->disp;
+       struct nvkm_device *device = disp->engine.subdev.device;
+       const struct nvkm_device_oclass *sclass = oclass->priv;
+       struct nvkm_disp_chan_object *object;
+       int ret;
+
+       if (!(object = kzalloc(sizeof(*object), GFP_KERNEL)))
+               return -ENOMEM;
+       nvkm_oproxy_ctor(&nvkm_disp_chan_child_func_, oclass, &object->oproxy);
+       object->disp = disp;
+       *pobject = &object->oproxy.base;
+
+       ret = sclass->ctor(device, oclass, argv, argc, &object->oproxy.object);
+       if (ret)
+               return ret;
+
+       object->hash = chan->func->bind(chan, object->oproxy.object, oclass->handle);
+       if (object->hash < 0)
+               return object->hash;
+
+       return 0;
+}
+
+static int
+nvkm_disp_chan_child_get(struct nvkm_object *object, int index, struct nvkm_oclass *sclass)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const struct nvkm_device_oclass *oclass = NULL;
+
+       if (chan->func->bind)
+               sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ, 0);
+       else
+               sclass->engine = NULL;
+
+       if (sclass->engine && sclass->engine->func->base.sclass) {
+               sclass->engine->func->base.sclass(sclass, index, &oclass);
+               if (oclass) {
+                       sclass->ctor = nvkm_disp_chan_child_new;
+                       sclass->priv = oclass;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int
+nvkm_disp_chan_fini(struct nvkm_object *object, bool suspend)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+
+       chan->func->fini(chan);
+       chan->func->intr(chan, false);
+       return 0;
+}
+
+static int
+nvkm_disp_chan_init(struct nvkm_object *object)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+
+       chan->func->intr(chan, true);
+       return chan->func->init(chan);
+}
+
+static void *
+nvkm_disp_chan_dtor(struct nvkm_object *object)
+{
+       struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
+       struct nvkm_disp *disp = chan->disp;
+
+       spin_lock(&disp->client.lock);
+       if (disp->chan[chan->chid.user] == chan)
+               disp->chan[chan->chid.user] = NULL;
+       spin_unlock(&disp->client.lock);
+
+       nvkm_memory_unref(&chan->memory);
+       return chan;
+}
+
+static const struct nvkm_object_func
+nvkm_disp_chan = {
+       .dtor = nvkm_disp_chan_dtor,
+       .init = nvkm_disp_chan_init,
+       .fini = nvkm_disp_chan_fini,
+       .rd32 = nvkm_disp_chan_rd32,
+       .wr32 = nvkm_disp_chan_wr32,
+       .ntfy = nvkm_disp_chan_ntfy,
+       .map = nvkm_disp_chan_map,
+       .sclass = nvkm_disp_chan_child_get,
+};
+
+static int
+nvkm_disp_chan_new_(struct nvkm_disp *disp, int nr, const struct nvkm_oclass *oclass,
+                   void *argv, u32 argc, struct nvkm_object **pobject)
+{
+       const struct nvkm_disp_chan_user *user = NULL;
+       struct nvkm_disp_chan *chan;
+       union nvif_disp_chan_args *args = argv;
+       int ret, i;
+
+       for (i = 0; disp->func->user[i].ctor; i++) {
+               if (disp->func->user[i].base.oclass == oclass->base.oclass) {
+                       user = disp->func->user[i].chan;
+                       break;
+               }
+       }
+
+       if (WARN_ON(!user))
+               return -EINVAL;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+       if (args->v0.id >= nr || !args->v0.pushbuf != !user->func->push)
+               return -EINVAL;
+
+       if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
+               return -ENOMEM;
+       *pobject = &chan->object;
+
+       nvkm_object_ctor(&nvkm_disp_chan, oclass, &chan->object);
+       chan->func = user->func;
+       chan->mthd = user->mthd;
+       chan->disp = disp;
+       chan->chid.ctrl = user->ctrl + args->v0.id;
+       chan->chid.user = user->user + args->v0.id;
+       chan->head = args->v0.id;
+
+       if (chan->func->push) {
+               ret = chan->func->push(chan, args->v0.pushbuf);
+               if (ret)
+                       return ret;
+       }
+
+       spin_lock(&disp->client.lock);
+       if (disp->chan[chan->chid.user]) {
+               spin_unlock(&disp->client.lock);
+               return -EBUSY;
+       }
+       disp->chan[chan->chid.user] = chan;
+       spin_unlock(&disp->client.lock);
+       return 0;
+}
+
+int
+nvkm_disp_wndw_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
+                  struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+
+       return nvkm_disp_chan_new_(disp, disp->wndw.nr, oclass, argv, argc, pobject);
+}
+
+int
+nvkm_disp_chan_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
+                  struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+
+       return nvkm_disp_chan_new_(disp, disp->head.nr, oclass, argv, argc, pobject);
+}
+
+int
+nvkm_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
+                  struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+
+       return nvkm_disp_chan_new_(disp, 1, oclass, argv, argc, pobject);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.h
new file mode 100644 (file)
index 0000000..398336f
--- /dev/null
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_DISP_CHAN_H__
+#define __NVKM_DISP_CHAN_H__
+#define nvkm_disp_chan(p) container_of((p), struct nvkm_disp_chan, object)
+#include <core/object.h>
+#include "priv.h"
+
+struct nvkm_disp_chan {
+       const struct nvkm_disp_chan_func *func;
+       const struct nvkm_disp_chan_mthd *mthd;
+       struct nvkm_disp *disp;
+
+       struct {
+               int ctrl;
+               int user;
+       } chid;
+       int head;
+
+       struct nvkm_object object;
+
+       struct nvkm_memory *memory;
+       u64 push;
+
+       u32 suspend_put;
+};
+
+int nvkm_disp_core_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
+int nvkm_disp_chan_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
+int nvkm_disp_wndw_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
+
+struct nvkm_disp_chan_func {
+       int (*push)(struct nvkm_disp_chan *, u64 object);
+       int (*init)(struct nvkm_disp_chan *);
+       void (*fini)(struct nvkm_disp_chan *);
+       void (*intr)(struct nvkm_disp_chan *, bool en);
+       u64 (*user)(struct nvkm_disp_chan *, u64 *size);
+       int (*bind)(struct nvkm_disp_chan *, struct nvkm_object *, u32 handle);
+};
+
+void nv50_disp_chan_intr(struct nvkm_disp_chan *, bool);
+u64 nv50_disp_chan_user(struct nvkm_disp_chan *, u64 *);
+extern const struct nvkm_disp_chan_func nv50_disp_pioc_func;
+extern const struct nvkm_disp_chan_func nv50_disp_dmac_func;
+int nv50_disp_dmac_push(struct nvkm_disp_chan *, u64);
+int nv50_disp_dmac_bind(struct nvkm_disp_chan *, struct nvkm_object *, u32);
+extern const struct nvkm_disp_chan_func nv50_disp_core_func;
+
+void gf119_disp_chan_intr(struct nvkm_disp_chan *, bool);
+extern const struct nvkm_disp_chan_func gf119_disp_pioc_func;
+extern const struct nvkm_disp_chan_func gf119_disp_dmac_func;
+void gf119_disp_dmac_fini(struct nvkm_disp_chan *);
+int gf119_disp_dmac_bind(struct nvkm_disp_chan *, struct nvkm_object *, u32);
+extern const struct nvkm_disp_chan_func gf119_disp_core_func;
+void gf119_disp_core_fini(struct nvkm_disp_chan *);
+
+extern const struct nvkm_disp_chan_func gp102_disp_dmac_func;
+
+u64 gv100_disp_chan_user(struct nvkm_disp_chan *, u64 *);
+int gv100_disp_dmac_init(struct nvkm_disp_chan *);
+void gv100_disp_dmac_fini(struct nvkm_disp_chan *);
+int gv100_disp_dmac_bind(struct nvkm_disp_chan *, struct nvkm_object *, u32);
+
+struct nvkm_disp_chan_user {
+       const struct nvkm_disp_chan_func *func;
+       int ctrl;
+       int user;
+       const struct nvkm_disp_chan_mthd *mthd;
+};
+
+extern const struct nvkm_disp_chan_user nv50_disp_oimm;
+extern const struct nvkm_disp_chan_user nv50_disp_curs;
+
+extern const struct nvkm_disp_chan_user g84_disp_core;
+extern const struct nvkm_disp_chan_user g84_disp_base;
+extern const struct nvkm_disp_chan_user g84_disp_ovly;
+
+extern const struct nvkm_disp_chan_user g94_disp_core;
+
+extern const struct nvkm_disp_chan_user gt200_disp_ovly;
+
+extern const struct nvkm_disp_chan_user gf119_disp_base;
+extern const struct nvkm_disp_chan_user gf119_disp_oimm;
+extern const struct nvkm_disp_chan_user gf119_disp_curs;
+
+extern const struct nvkm_disp_chan_user gk104_disp_core;
+extern const struct nvkm_disp_chan_user gk104_disp_ovly;
+
+extern const struct nvkm_disp_chan_user gv100_disp_core;
+extern const struct nvkm_disp_chan_user gv100_disp_curs;
+extern const struct nvkm_disp_chan_user gv100_disp_wndw;
+extern const struct nvkm_disp_chan_user gv100_disp_wimm;
+
+struct nvkm_disp_mthd_list {
+       u32 mthd;
+       u32 addr;
+       struct {
+               u32 mthd;
+               u32 addr;
+               const char *name;
+       } data[];
+};
+
+struct nvkm_disp_chan_mthd {
+       const char *name;
+       u32 addr;
+       s32 prev;
+       struct {
+               const char *name;
+               int nr;
+               const struct nvkm_disp_mthd_list *mthd;
+       } data[];
+};
+
+void nv50_disp_chan_mthd(struct nvkm_disp_chan *, int debug);
+
+extern const struct nvkm_disp_mthd_list nv50_disp_core_mthd_base;
+extern const struct nvkm_disp_mthd_list nv50_disp_core_mthd_sor;
+extern const struct nvkm_disp_mthd_list nv50_disp_core_mthd_pior;
+extern const struct nvkm_disp_mthd_list nv50_disp_base_mthd_image;
+
+extern const struct nvkm_disp_chan_mthd g84_disp_core_mthd;
+extern const struct nvkm_disp_mthd_list g84_disp_core_mthd_dac;
+extern const struct nvkm_disp_mthd_list g84_disp_core_mthd_head;
+
+extern const struct nvkm_disp_chan_mthd g94_disp_core_mthd;
+
+extern const struct nvkm_disp_mthd_list gf119_disp_core_mthd_base;
+extern const struct nvkm_disp_mthd_list gf119_disp_core_mthd_dac;
+extern const struct nvkm_disp_mthd_list gf119_disp_core_mthd_sor;
+extern const struct nvkm_disp_mthd_list gf119_disp_core_mthd_pior;
+extern const struct nvkm_disp_chan_mthd gf119_disp_base_mthd;
+
+extern const struct nvkm_disp_chan_mthd gk104_disp_core_mthd;
+extern const struct nvkm_disp_chan_mthd gk104_disp_ovly_mthd;
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c
deleted file mode 100644 (file)
index 525f95d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static void
-gf119_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
-{
-       struct nv50_disp *disp = container_of(event, typeof(*disp), uevent);
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       nvkm_mask(device, 0x610090, 0x00000001 << index, 0x00000000 << index);
-       nvkm_wr32(device, 0x61008c, 0x00000001 << index);
-}
-
-static void
-gf119_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
-{
-       struct nv50_disp *disp = container_of(event, typeof(*disp), uevent);
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       nvkm_wr32(device, 0x61008c, 0x00000001 << index);
-       nvkm_mask(device, 0x610090, 0x00000001 << index, 0x00000001 << index);
-}
-
-const struct nvkm_event_func
-gf119_disp_chan_uevent = {
-       .ctor = nv50_disp_chan_uevent_ctor,
-       .init = gf119_disp_chan_uevent_init,
-       .fini = gf119_disp_chan_uevent_fini,
-};
-
-void
-gf119_disp_chan_intr(struct nv50_disp_chan *chan, bool en)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 mask = 0x00000001 << chan->chid.user;
-       if (!en) {
-               nvkm_mask(device, 0x610090, mask, 0x00000000);
-               nvkm_mask(device, 0x6100a0, mask, 0x00000000);
-       } else {
-               nvkm_mask(device, 0x6100a0, mask, mask);
-       }
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c
deleted file mode 100644 (file)
index 75247c9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "channv50.h"
-
-const struct nvkm_event_func
-gv100_disp_chan_uevent = {
-       .ctor = nv50_disp_chan_uevent_ctor,
-};
-
-u64
-gv100_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize)
-{
-       *psize = 0x1000;
-       return 0x690000 + ((chan->chid.user - 1) * 0x1000);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
deleted file mode 100644 (file)
index a7a7eb0..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "rootnv50.h"
-
-#include <core/client.h>
-#include <core/notify.h>
-#include <core/oproxy.h>
-#include <core/ramht.h>
-#include <engine/dma.h>
-
-#include <nvif/cl507d.h>
-#include <nvif/event.h>
-#include <nvif/unpack.h>
-
-static void
-nv50_disp_mthd_list(struct nv50_disp *disp, int debug, u32 base, int c,
-                   const struct nv50_disp_mthd_list *list, int inst)
-{
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int i;
-
-       for (i = 0; list->data[i].mthd; i++) {
-               if (list->data[i].addr) {
-                       u32 next = nvkm_rd32(device, list->data[i].addr + base + 0);
-                       u32 prev = nvkm_rd32(device, list->data[i].addr + base + c);
-                       u32 mthd = list->data[i].mthd + (list->mthd * inst);
-                       const char *name = list->data[i].name;
-                       char mods[16];
-
-                       if (prev != next)
-                               snprintf(mods, sizeof(mods), "-> %08x", next);
-                       else
-                               snprintf(mods, sizeof(mods), "%13c", ' ');
-
-                       nvkm_printk_(subdev, debug, info,
-                                    "\t%04x: %08x %s%s%s\n",
-                                    mthd, prev, mods, name ? " // " : "",
-                                    name ? name : "");
-               }
-       }
-}
-
-void
-nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug)
-{
-       struct nv50_disp *disp = chan->disp;
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
-       const struct nv50_disp_chan_mthd *mthd = chan->mthd;
-       const struct nv50_disp_mthd_list *list;
-       int i, j;
-
-       if (debug > subdev->debug)
-               return;
-       if (!mthd)
-               return;
-
-       for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) {
-               u32 base = chan->head * mthd->addr;
-               for (j = 0; j < mthd->data[i].nr; j++, base += list->addr) {
-                       const char *cname = mthd->name;
-                       const char *sname = "";
-                       char cname_[16], sname_[16];
-
-                       if (mthd->addr) {
-                               snprintf(cname_, sizeof(cname_), "%s %d",
-                                        mthd->name, chan->chid.user);
-                               cname = cname_;
-                       }
-
-                       if (mthd->data[i].nr > 1) {
-                               snprintf(sname_, sizeof(sname_), " - %s %d",
-                                        mthd->data[i].name, j);
-                               sname = sname_;
-                       }
-
-                       nvkm_printk_(subdev, debug, info, "%s%s:\n", cname, sname);
-                       nv50_disp_mthd_list(disp, debug, base, mthd->prev,
-                                           list, j);
-               }
-       }
-}
-
-static void
-nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
-{
-       struct nv50_disp *disp = container_of(event, typeof(*disp), uevent);
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       nvkm_mask(device, 0x610028, 0x00000001 << index, 0x00000000 << index);
-       nvkm_wr32(device, 0x610020, 0x00000001 << index);
-}
-
-static void
-nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
-{
-       struct nv50_disp *disp = container_of(event, typeof(*disp), uevent);
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       nvkm_wr32(device, 0x610020, 0x00000001 << index);
-       nvkm_mask(device, 0x610028, 0x00000001 << index, 0x00000001 << index);
-}
-
-void
-nv50_disp_chan_uevent_send(struct nv50_disp *disp, int chid)
-{
-       struct nvif_notify_uevent_rep {
-       } rep;
-
-       nvkm_event_send(&disp->uevent, 1, chid, &rep, sizeof(rep));
-}
-
-int
-nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
-                          struct nvkm_notify *notify)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       union {
-               struct nvif_notify_uevent_req none;
-       } *args = data;
-       int ret = -ENOSYS;
-
-       if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
-               notify->size  = sizeof(struct nvif_notify_uevent_rep);
-               notify->types = 1;
-               notify->index = chan->chid.user;
-               return 0;
-       }
-
-       return ret;
-}
-
-const struct nvkm_event_func
-nv50_disp_chan_uevent = {
-       .ctor = nv50_disp_chan_uevent_ctor,
-       .init = nv50_disp_chan_uevent_init,
-       .fini = nv50_disp_chan_uevent_fini,
-};
-
-u64
-nv50_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize)
-{
-       *psize = 0x1000;
-       return 0x640000 + (chan->chid.user * 0x1000);
-}
-
-void
-nv50_disp_chan_intr(struct nv50_disp_chan *chan, bool en)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 mask = 0x00010001 << chan->chid.user;
-       const u32 data = en ? 0x00010000 << chan->chid.user : 0x00000000;
-       nvkm_mask(device, 0x610028, mask, data);
-}
-
-static int
-nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       u64 size, base = chan->func->user(chan, &size);
-       *data = nvkm_rd32(device, base + addr);
-       return 0;
-}
-
-static int
-nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       u64 size, base = chan->func->user(chan, &size);
-       nvkm_wr32(device, base + addr, data);
-       return 0;
-}
-
-static int
-nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type,
-                   struct nvkm_event **pevent)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       struct nv50_disp *disp = chan->disp;
-       switch (type) {
-       case NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT:
-               *pevent = &disp->uevent;
-               return 0;
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
-static int
-nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc,
-                  enum nvkm_object_map *type, u64 *addr, u64 *size)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u64 base = device->func->resource_addr(device, 0);
-       *type = NVKM_OBJECT_MAP_IO;
-       *addr = base + chan->func->user(chan, size);
-       return 0;
-}
-
-struct nv50_disp_chan_object {
-       struct nvkm_oproxy oproxy;
-       struct nv50_disp *disp;
-       int hash;
-};
-
-static void
-nv50_disp_chan_child_del_(struct nvkm_oproxy *base)
-{
-       struct nv50_disp_chan_object *object =
-               container_of(base, typeof(*object), oproxy);
-       nvkm_ramht_remove(object->disp->ramht, object->hash);
-}
-
-static const struct nvkm_oproxy_func
-nv50_disp_chan_child_func_ = {
-       .dtor[0] = nv50_disp_chan_child_del_,
-};
-
-static int
-nv50_disp_chan_child_new(const struct nvkm_oclass *oclass,
-                        void *argv, u32 argc, struct nvkm_object **pobject)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(oclass->parent);
-       struct nv50_disp *disp = chan->disp;
-       struct nvkm_device *device = disp->base.engine.subdev.device;
-       const struct nvkm_device_oclass *sclass = oclass->priv;
-       struct nv50_disp_chan_object *object;
-       int ret;
-
-       if (!(object = kzalloc(sizeof(*object), GFP_KERNEL)))
-               return -ENOMEM;
-       nvkm_oproxy_ctor(&nv50_disp_chan_child_func_, oclass, &object->oproxy);
-       object->disp = disp;
-       *pobject = &object->oproxy.base;
-
-       ret = sclass->ctor(device, oclass, argv, argc, &object->oproxy.object);
-       if (ret)
-               return ret;
-
-       object->hash = chan->func->bind(chan, object->oproxy.object,
-                                             oclass->handle);
-       if (object->hash < 0)
-               return object->hash;
-
-       return 0;
-}
-
-static int
-nv50_disp_chan_child_get(struct nvkm_object *object, int index,
-                        struct nvkm_oclass *sclass)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const struct nvkm_device_oclass *oclass = NULL;
-
-       if (chan->func->bind)
-               sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ, 0);
-       else
-               sclass->engine = NULL;
-
-       if (sclass->engine && sclass->engine->func->base.sclass) {
-               sclass->engine->func->base.sclass(sclass, index, &oclass);
-               if (oclass) {
-                       sclass->ctor = nv50_disp_chan_child_new,
-                       sclass->priv = oclass;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int
-nv50_disp_chan_fini(struct nvkm_object *object, bool suspend)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       chan->func->fini(chan);
-       chan->func->intr(chan, false);
-       return 0;
-}
-
-static int
-nv50_disp_chan_init(struct nvkm_object *object)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       chan->func->intr(chan, true);
-       return chan->func->init(chan);
-}
-
-static void *
-nv50_disp_chan_dtor(struct nvkm_object *object)
-{
-       struct nv50_disp_chan *chan = nv50_disp_chan(object);
-       struct nv50_disp *disp = chan->disp;
-       if (chan->chid.user >= 0)
-               disp->chan[chan->chid.user] = NULL;
-       nvkm_memory_unref(&chan->memory);
-       return chan;
-}
-
-static const struct nvkm_object_func
-nv50_disp_chan = {
-       .dtor = nv50_disp_chan_dtor,
-       .init = nv50_disp_chan_init,
-       .fini = nv50_disp_chan_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
-       .ntfy = nv50_disp_chan_ntfy,
-       .map = nv50_disp_chan_map,
-       .sclass = nv50_disp_chan_child_get,
-};
-
-int
-nv50_disp_chan_new_(const struct nv50_disp_chan_func *func,
-                   const struct nv50_disp_chan_mthd *mthd,
-                   struct nv50_disp *disp, int ctrl, int user, int head,
-                   const struct nvkm_oclass *oclass,
-                   struct nvkm_object **pobject)
-{
-       struct nv50_disp_chan *chan;
-
-       if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
-               return -ENOMEM;
-       *pobject = &chan->object;
-
-       nvkm_object_ctor(&nv50_disp_chan, oclass, &chan->object);
-       chan->func = func;
-       chan->mthd = mthd;
-       chan->disp = disp;
-       chan->chid.ctrl = ctrl;
-       chan->chid.user = user;
-       chan->head = head;
-
-       if (disp->chan[chan->chid.user]) {
-               chan->chid.user = -1;
-               return -EBUSY;
-       }
-       disp->chan[chan->chid.user] = chan;
-       return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h
deleted file mode 100644 (file)
index 9cf2cfe..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NV50_DISP_CHAN_H__
-#define __NV50_DISP_CHAN_H__
-#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;
-       const struct nv50_disp_chan_mthd *mthd;
-       struct nv50_disp *disp;
-
-       struct {
-               int ctrl;
-               int user;
-       } chid;
-       int head;
-
-       struct nvkm_object object;
-
-       struct nvkm_memory *memory;
-       u64 push;
-
-       u32 suspend_put;
-};
-
-struct nv50_disp_chan_func {
-       int (*init)(struct nv50_disp_chan *);
-       void (*fini)(struct nv50_disp_chan *);
-       void (*intr)(struct nv50_disp_chan *, bool en);
-       u64 (*user)(struct nv50_disp_chan *, u64 *size);
-       int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle);
-};
-
-int nv50_disp_chan_new_(const struct nv50_disp_chan_func *,
-                       const struct nv50_disp_chan_mthd *,
-                       struct nv50_disp *, int ctrl, int user, int head,
-                       const struct nvkm_oclass *, struct nvkm_object **);
-int nv50_disp_dmac_new_(const struct nv50_disp_chan_func *,
-                       const struct nv50_disp_chan_mthd *,
-                       struct nv50_disp *, int chid, int head, u64 push,
-                       const struct nvkm_oclass *, struct nvkm_object **);
-
-void nv50_disp_chan_intr(struct nv50_disp_chan *, bool);
-u64 nv50_disp_chan_user(struct nv50_disp_chan *, u64 *);
-extern const struct nv50_disp_chan_func nv50_disp_pioc_func;
-extern const struct nv50_disp_chan_func nv50_disp_dmac_func;
-int nv50_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32);
-extern const struct nv50_disp_chan_func nv50_disp_core_func;
-
-void gf119_disp_chan_intr(struct nv50_disp_chan *, bool);
-extern const struct nv50_disp_chan_func gf119_disp_pioc_func;
-extern const struct nv50_disp_chan_func gf119_disp_dmac_func;
-void gf119_disp_dmac_fini(struct nv50_disp_chan *);
-int gf119_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32);
-extern const struct nv50_disp_chan_func gf119_disp_core_func;
-void gf119_disp_core_fini(struct nv50_disp_chan *);
-
-extern const struct nv50_disp_chan_func gp102_disp_dmac_func;
-
-u64 gv100_disp_chan_user(struct nv50_disp_chan *, u64 *);
-int gv100_disp_dmac_init(struct nv50_disp_chan *);
-void gv100_disp_dmac_fini(struct nv50_disp_chan *);
-int gv100_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32);
-
-int nv50_disp_curs_new_(const struct nv50_disp_chan_func *,
-                       struct nv50_disp *, int ctrl, int user,
-                       const struct nvkm_oclass *, void *argv, u32 argc,
-                       struct nvkm_object **);
-int nv50_disp_oimm_new_(const struct nv50_disp_chan_func *,
-                       struct nv50_disp *, int ctrl, int user,
-                       const struct nvkm_oclass *, void *argv, u32 argc,
-                       struct nvkm_object **);
-int nv50_disp_base_new_(const struct nv50_disp_chan_func *,
-                       const struct nv50_disp_chan_mthd *,
-                       struct nv50_disp *, int chid,
-                       const struct nvkm_oclass *, void *argv, u32 argc,
-                       struct nvkm_object **);
-int nv50_disp_core_new_(const struct nv50_disp_chan_func *,
-                       const struct nv50_disp_chan_mthd *,
-                       struct nv50_disp *, int chid,
-                       const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                       struct nvkm_object **);
-int nv50_disp_ovly_new_(const struct nv50_disp_chan_func *,
-                       const struct nv50_disp_chan_mthd *,
-                       struct nv50_disp *, int chid,
-                       const struct nvkm_oclass *, void *argv, u32 argc,
-                       struct nvkm_object **);
-
-int nv50_disp_curs_new(const struct nvkm_oclass *, void *, u32,
-                      struct nv50_disp *, struct nvkm_object **);
-int nv50_disp_oimm_new(const struct nvkm_oclass *, void *, u32,
-                      struct nv50_disp *, struct nvkm_object **);
-int nv50_disp_base_new(const struct nvkm_oclass *, void *, u32,
-                      struct nv50_disp *, struct nvkm_object **);
-int nv50_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                      struct nv50_disp *, struct nvkm_object **);
-int nv50_disp_ovly_new(const struct nvkm_oclass *, void *, u32,
-                      struct nv50_disp *, struct nvkm_object **);
-
-int g84_disp_base_new(const struct nvkm_oclass *, void *, u32,
-                     struct nv50_disp *, struct nvkm_object **);
-int g84_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                     struct nv50_disp *, struct nvkm_object **);
-int g84_disp_ovly_new(const struct nvkm_oclass *, void *, u32,
-                     struct nv50_disp *, struct nvkm_object **);
-
-int g94_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                     struct nv50_disp *, struct nvkm_object **);
-
-int gt200_disp_ovly_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-
-int gf119_disp_curs_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gf119_disp_oimm_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gf119_disp_base_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gf119_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gf119_disp_ovly_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-
-int gk104_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gk104_disp_ovly_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-
-int gp102_disp_curs_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gp102_disp_oimm_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gp102_disp_base_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gp102_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gp102_disp_ovly_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-
-int gv100_disp_curs_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gv100_disp_wimm_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gv100_disp_core_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-int gv100_disp_wndw_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-
-struct nv50_disp_mthd_list {
-       u32 mthd;
-       u32 addr;
-       struct {
-               u32 mthd;
-               u32 addr;
-               const char *name;
-       } data[];
-};
-
-struct nv50_disp_chan_mthd {
-       const char *name;
-       u32 addr;
-       s32 prev;
-       struct {
-               const char *name;
-               int nr;
-               const struct nv50_disp_mthd_list *mthd;
-       } data[];
-};
-
-void nv50_disp_chan_mthd(struct nv50_disp_chan *, int debug);
-
-extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_base;
-extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_sor;
-extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_pior;
-extern const struct nv50_disp_mthd_list nv50_disp_base_mthd_image;
-
-extern const struct nv50_disp_chan_mthd g84_disp_core_mthd;
-extern const struct nv50_disp_mthd_list g84_disp_core_mthd_dac;
-extern const struct nv50_disp_mthd_list g84_disp_core_mthd_head;
-
-extern const struct nv50_disp_chan_mthd g94_disp_core_mthd;
-
-extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_base;
-extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_dac;
-extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_sor;
-extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_pior;
-extern const struct nv50_disp_chan_mthd gf119_disp_base_mthd;
-
-extern const struct nv50_disp_chan_mthd gk104_disp_core_mthd;
-extern const struct nv50_disp_chan_mthd gk104_disp_ovly_mthd;
-#endif
index febc5c2..7ed1180 100644 (file)
@@ -86,6 +86,7 @@ nvkm_conn_ctor(struct nvkm_disp *disp, int index, struct nvbios_connE *info,
        conn->disp = disp;
        conn->index = index;
        conn->info = *info;
+       conn->info.hpd = DCB_GPIO_UNUSED;
 
        CONN_DBG(conn, "type %02x loc %d hpd %02x dp %x di %x sr %x lcdid %x",
                 info->type, info->location, info->hpd, info->dp,
@@ -100,11 +101,12 @@ nvkm_conn_ctor(struct nvkm_disp *disp, int index, struct nvbios_connE *info,
 
                ret = nvkm_gpio_find(gpio, 0, info->hpd, DCB_GPIO_UNUSED, &func);
                if (ret) {
-                       CONN_ERR(conn, "func %02x lookup failed, %d",
-                                info->hpd, ret);
+                       CONN_ERR(conn, "func %02x lookup failed, %d", info->hpd, ret);
                        return;
                }
 
+               conn->info.hpd = func.line;
+
                ret = nvkm_notify_init(NULL, &gpio->event, nvkm_conn_hpd,
                                       true, &(struct nvkm_gpio_ntfy_req) {
                                        .mask = NVKM_GPIO_TOGGLED,
index dcbe60a..f109634 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVKM_DISP_CONN_H__
 #define __NVKM_DISP_CONN_H__
-#include <engine/disp.h>
+#include "priv.h"
 
 #include <core/notify.h>
 #include <subdev/bios.h>
@@ -15,6 +15,8 @@ struct nvkm_conn {
        struct nvkm_notify hpd;
 
        struct list_head head;
+
+       struct nvkm_object object;
 };
 
 int nvkm_conn_new(struct nvkm_disp *, int index, struct nvbios_connE *,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c
deleted file mode 100644 (file)
index cfc54aa..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-const struct nv50_disp_mthd_list
-g84_disp_core_mthd_dac = {
-       .mthd = 0x0080,
-       .addr = 0x000008,
-       .data = {
-               { 0x0400, 0x610b58 },
-               { 0x0404, 0x610bdc },
-               { 0x0420, 0x610bc4 },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-g84_disp_core_mthd_head = {
-       .mthd = 0x0400,
-       .addr = 0x000540,
-       .data = {
-               { 0x0800, 0x610ad8 },
-               { 0x0804, 0x610ad0 },
-               { 0x0808, 0x610a48 },
-               { 0x080c, 0x610a78 },
-               { 0x0810, 0x610ac0 },
-               { 0x0814, 0x610af8 },
-               { 0x0818, 0x610b00 },
-               { 0x081c, 0x610ae8 },
-               { 0x0820, 0x610af0 },
-               { 0x0824, 0x610b08 },
-               { 0x0828, 0x610b10 },
-               { 0x082c, 0x610a68 },
-               { 0x0830, 0x610a60 },
-               { 0x0834, 0x000000 },
-               { 0x0838, 0x610a40 },
-               { 0x0840, 0x610a24 },
-               { 0x0844, 0x610a2c },
-               { 0x0848, 0x610aa8 },
-               { 0x084c, 0x610ab0 },
-               { 0x085c, 0x610c5c },
-               { 0x0860, 0x610a84 },
-               { 0x0864, 0x610a90 },
-               { 0x0868, 0x610b18 },
-               { 0x086c, 0x610b20 },
-               { 0x0870, 0x610ac8 },
-               { 0x0874, 0x610a38 },
-               { 0x0878, 0x610c50 },
-               { 0x0880, 0x610a58 },
-               { 0x0884, 0x610a9c },
-               { 0x089c, 0x610c68 },
-               { 0x08a0, 0x610a70 },
-               { 0x08a4, 0x610a50 },
-               { 0x08a8, 0x610ae0 },
-               { 0x08c0, 0x610b28 },
-               { 0x08c4, 0x610b30 },
-               { 0x08c8, 0x610b40 },
-               { 0x08d4, 0x610b38 },
-               { 0x08d8, 0x610b48 },
-               { 0x08dc, 0x610b50 },
-               { 0x0900, 0x610a18 },
-               { 0x0904, 0x610ab8 },
-               { 0x0910, 0x610c70 },
-               { 0x0914, 0x610c78 },
-               {}
-       }
-};
-
-const struct nv50_disp_chan_mthd
-g84_disp_core_mthd = {
-       .name = "Core",
-       .addr = 0x000000,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &nv50_disp_core_mthd_base },
-               {    "DAC", 3, &g84_disp_core_mthd_dac  },
-               {    "SOR", 2, &nv50_disp_core_mthd_sor  },
-               {   "PIOR", 3, &nv50_disp_core_mthd_pior },
-               {   "HEAD", 2, &g84_disp_core_mthd_head },
-               {}
-       }
-};
-
-int
-g84_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                 struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&nv50_disp_core_func, &g84_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c
deleted file mode 100644 (file)
index e911925..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-g94_disp_core_mthd_sor = {
-       .mthd = 0x0040,
-       .addr = 0x000008,
-       .data = {
-               { 0x0600, 0x610794 },
-               {}
-       }
-};
-
-const struct nv50_disp_chan_mthd
-g94_disp_core_mthd = {
-       .name = "Core",
-       .addr = 0x000000,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &nv50_disp_core_mthd_base },
-               {    "DAC", 3, &g84_disp_core_mthd_dac },
-               {    "SOR", 4, &g94_disp_core_mthd_sor },
-               {   "PIOR", 3, &nv50_disp_core_mthd_pior },
-               {   "HEAD", 2, &g84_disp_core_mthd_head },
-               {}
-       }
-};
-
-int
-g94_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                 struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&nv50_disp_core_func, &g94_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c
deleted file mode 100644 (file)
index 689e3cd..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-#include <subdev/timer.h>
-
-const struct nv50_disp_mthd_list
-gf119_disp_core_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x660080 },
-               { 0x0084, 0x660084 },
-               { 0x0088, 0x660088 },
-               { 0x008c, 0x000000 },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-gf119_disp_core_mthd_dac = {
-       .mthd = 0x0020,
-       .addr = 0x000020,
-       .data = {
-               { 0x0180, 0x660180 },
-               { 0x0184, 0x660184 },
-               { 0x0188, 0x660188 },
-               { 0x0190, 0x660190 },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-gf119_disp_core_mthd_sor = {
-       .mthd = 0x0020,
-       .addr = 0x000020,
-       .data = {
-               { 0x0200, 0x660200 },
-               { 0x0204, 0x660204 },
-               { 0x0208, 0x660208 },
-               { 0x0210, 0x660210 },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-gf119_disp_core_mthd_pior = {
-       .mthd = 0x0020,
-       .addr = 0x000020,
-       .data = {
-               { 0x0300, 0x660300 },
-               { 0x0304, 0x660304 },
-               { 0x0308, 0x660308 },
-               { 0x0310, 0x660310 },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-gf119_disp_core_mthd_head = {
-       .mthd = 0x0300,
-       .addr = 0x000300,
-       .data = {
-               { 0x0400, 0x660400 },
-               { 0x0404, 0x660404 },
-               { 0x0408, 0x660408 },
-               { 0x040c, 0x66040c },
-               { 0x0410, 0x660410 },
-               { 0x0414, 0x660414 },
-               { 0x0418, 0x660418 },
-               { 0x041c, 0x66041c },
-               { 0x0420, 0x660420 },
-               { 0x0424, 0x660424 },
-               { 0x0428, 0x660428 },
-               { 0x042c, 0x66042c },
-               { 0x0430, 0x660430 },
-               { 0x0434, 0x660434 },
-               { 0x0438, 0x660438 },
-               { 0x0440, 0x660440 },
-               { 0x0444, 0x660444 },
-               { 0x0448, 0x660448 },
-               { 0x044c, 0x66044c },
-               { 0x0450, 0x660450 },
-               { 0x0454, 0x660454 },
-               { 0x0458, 0x660458 },
-               { 0x045c, 0x66045c },
-               { 0x0460, 0x660460 },
-               { 0x0468, 0x660468 },
-               { 0x046c, 0x66046c },
-               { 0x0470, 0x660470 },
-               { 0x0474, 0x660474 },
-               { 0x0480, 0x660480 },
-               { 0x0484, 0x660484 },
-               { 0x048c, 0x66048c },
-               { 0x0490, 0x660490 },
-               { 0x0494, 0x660494 },
-               { 0x0498, 0x660498 },
-               { 0x04b0, 0x6604b0 },
-               { 0x04b8, 0x6604b8 },
-               { 0x04bc, 0x6604bc },
-               { 0x04c0, 0x6604c0 },
-               { 0x04c4, 0x6604c4 },
-               { 0x04c8, 0x6604c8 },
-               { 0x04d0, 0x6604d0 },
-               { 0x04d4, 0x6604d4 },
-               { 0x04e0, 0x6604e0 },
-               { 0x04e4, 0x6604e4 },
-               { 0x04e8, 0x6604e8 },
-               { 0x04ec, 0x6604ec },
-               { 0x04f0, 0x6604f0 },
-               { 0x04f4, 0x6604f4 },
-               { 0x04f8, 0x6604f8 },
-               { 0x04fc, 0x6604fc },
-               { 0x0500, 0x660500 },
-               { 0x0504, 0x660504 },
-               { 0x0508, 0x660508 },
-               { 0x050c, 0x66050c },
-               { 0x0510, 0x660510 },
-               { 0x0514, 0x660514 },
-               { 0x0518, 0x660518 },
-               { 0x051c, 0x66051c },
-               { 0x052c, 0x66052c },
-               { 0x0530, 0x660530 },
-               { 0x054c, 0x66054c },
-               { 0x0550, 0x660550 },
-               { 0x0554, 0x660554 },
-               { 0x0558, 0x660558 },
-               { 0x055c, 0x66055c },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-gf119_disp_core_mthd = {
-       .name = "Core",
-       .addr = 0x000000,
-       .prev = -0x020000,
-       .data = {
-               { "Global", 1, &gf119_disp_core_mthd_base },
-               {    "DAC", 3, &gf119_disp_core_mthd_dac  },
-               {    "SOR", 8, &gf119_disp_core_mthd_sor  },
-               {   "PIOR", 4, &gf119_disp_core_mthd_pior },
-               {   "HEAD", 4, &gf119_disp_core_mthd_head },
-               {}
-       }
-};
-
-void
-gf119_disp_core_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-
-       /* deactivate channel */
-       nvkm_mask(device, 0x610490, 0x00000010, 0x00000000);
-       nvkm_mask(device, 0x610490, 0x00000003, 0x00000000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490) & 0x001e0000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "core fini: %08x\n",
-                          nvkm_rd32(device, 0x610490));
-       }
-
-       chan->suspend_put = nvkm_rd32(device, 0x640000);
-}
-
-static int
-gf119_disp_core_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-
-       /* initialise channel for dma command submission */
-       nvkm_wr32(device, 0x610494, chan->push);
-       nvkm_wr32(device, 0x610498, 0x00010000);
-       nvkm_wr32(device, 0x61049c, 0x00000001);
-       nvkm_mask(device, 0x610490, 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x640000, chan->suspend_put);
-       nvkm_wr32(device, 0x610490, 0x01000013);
-
-       /* wait for it to go inactive */
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490) & 0x80000000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "core init: %08x\n",
-                          nvkm_rd32(device, 0x610490));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-gf119_disp_core_func = {
-       .init = gf119_disp_core_init,
-       .fini = gf119_disp_core_fini,
-       .intr = gf119_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-       .bind = gf119_disp_dmac_bind,
-};
-
-int
-gf119_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&gf119_disp_core_func, &gf119_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c
deleted file mode 100644 (file)
index 5c80017..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-gk104_disp_core_mthd_head = {
-       .mthd = 0x0300,
-       .addr = 0x000300,
-       .data = {
-               { 0x0400, 0x660400 },
-               { 0x0404, 0x660404 },
-               { 0x0408, 0x660408 },
-               { 0x040c, 0x66040c },
-               { 0x0410, 0x660410 },
-               { 0x0414, 0x660414 },
-               { 0x0418, 0x660418 },
-               { 0x041c, 0x66041c },
-               { 0x0420, 0x660420 },
-               { 0x0424, 0x660424 },
-               { 0x0428, 0x660428 },
-               { 0x042c, 0x66042c },
-               { 0x0430, 0x660430 },
-               { 0x0434, 0x660434 },
-               { 0x0438, 0x660438 },
-               { 0x0440, 0x660440 },
-               { 0x0444, 0x660444 },
-               { 0x0448, 0x660448 },
-               { 0x044c, 0x66044c },
-               { 0x0450, 0x660450 },
-               { 0x0454, 0x660454 },
-               { 0x0458, 0x660458 },
-               { 0x045c, 0x66045c },
-               { 0x0460, 0x660460 },
-               { 0x0468, 0x660468 },
-               { 0x046c, 0x66046c },
-               { 0x0470, 0x660470 },
-               { 0x0474, 0x660474 },
-               { 0x047c, 0x66047c },
-               { 0x0480, 0x660480 },
-               { 0x0484, 0x660484 },
-               { 0x0488, 0x660488 },
-               { 0x048c, 0x66048c },
-               { 0x0490, 0x660490 },
-               { 0x0494, 0x660494 },
-               { 0x0498, 0x660498 },
-               { 0x04a0, 0x6604a0 },
-               { 0x04b0, 0x6604b0 },
-               { 0x04b8, 0x6604b8 },
-               { 0x04bc, 0x6604bc },
-               { 0x04c0, 0x6604c0 },
-               { 0x04c4, 0x6604c4 },
-               { 0x04c8, 0x6604c8 },
-               { 0x04d0, 0x6604d0 },
-               { 0x04d4, 0x6604d4 },
-               { 0x04e0, 0x6604e0 },
-               { 0x04e4, 0x6604e4 },
-               { 0x04e8, 0x6604e8 },
-               { 0x04ec, 0x6604ec },
-               { 0x04f0, 0x6604f0 },
-               { 0x04f4, 0x6604f4 },
-               { 0x04f8, 0x6604f8 },
-               { 0x04fc, 0x6604fc },
-               { 0x0500, 0x660500 },
-               { 0x0504, 0x660504 },
-               { 0x0508, 0x660508 },
-               { 0x050c, 0x66050c },
-               { 0x0510, 0x660510 },
-               { 0x0514, 0x660514 },
-               { 0x0518, 0x660518 },
-               { 0x051c, 0x66051c },
-               { 0x0520, 0x660520 },
-               { 0x0524, 0x660524 },
-               { 0x052c, 0x66052c },
-               { 0x0530, 0x660530 },
-               { 0x054c, 0x66054c },
-               { 0x0550, 0x660550 },
-               { 0x0554, 0x660554 },
-               { 0x0558, 0x660558 },
-               { 0x055c, 0x66055c },
-               {}
-       }
-};
-
-const struct nv50_disp_chan_mthd
-gk104_disp_core_mthd = {
-       .name = "Core",
-       .addr = 0x000000,
-       .prev = -0x020000,
-       .data = {
-               { "Global", 1, &gf119_disp_core_mthd_base },
-               {    "DAC", 3, &gf119_disp_core_mthd_dac  },
-               {    "SOR", 8, &gf119_disp_core_mthd_sor  },
-               {   "PIOR", 4, &gf119_disp_core_mthd_pior },
-               {   "HEAD", 4, &gk104_disp_core_mthd_head },
-               {}
-       }
-};
-
-int
-gk104_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&gf119_disp_core_func, &gk104_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c
deleted file mode 100644 (file)
index 1b435be..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "channv50.h"
-
-#include <subdev/timer.h>
-
-static int
-gp102_disp_core_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-
-       /* initialise channel for dma command submission */
-       nvkm_wr32(device, 0x611494, chan->push);
-       nvkm_wr32(device, 0x611498, 0x00010000);
-       nvkm_wr32(device, 0x61149c, 0x00000001);
-       nvkm_mask(device, 0x610490, 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x640000, chan->suspend_put);
-       nvkm_wr32(device, 0x610490, 0x01000013);
-
-       /* wait for it to go inactive */
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490) & 0x80000000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "core init: %08x\n",
-                          nvkm_rd32(device, 0x610490));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-static const struct nv50_disp_chan_func
-gp102_disp_core_func = {
-       .init = gp102_disp_core_init,
-       .fini = gf119_disp_core_fini,
-       .intr = gf119_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-       .bind = gf119_disp_dmac_bind,
-};
-
-int
-gp102_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&gp102_disp_core_func, &gk104_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c
deleted file mode 100644 (file)
index 1d333c4..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "channv50.h"
-
-#include <subdev/timer.h>
-
-static const struct nv50_disp_mthd_list
-gv100_disp_core_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0200, 0x680200 },
-               { 0x0208, 0x680208 },
-               { 0x020c, 0x68020c },
-               { 0x0210, 0x680210 },
-               { 0x0214, 0x680214 },
-               { 0x0218, 0x680218 },
-               { 0x021c, 0x68021c },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-gv100_disp_core_mthd_sor = {
-       .mthd = 0x0020,
-       .addr = 0x000020,
-       .data = {
-               { 0x0300, 0x680300 },
-               { 0x0304, 0x680304 },
-               { 0x0308, 0x680308 },
-               { 0x030c, 0x68030c },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-gv100_disp_core_mthd_wndw = {
-       .mthd = 0x0080,
-       .addr = 0x000080,
-       .data = {
-               { 0x1000, 0x681000 },
-               { 0x1004, 0x681004 },
-               { 0x1008, 0x681008 },
-               { 0x100c, 0x68100c },
-               { 0x1010, 0x681010 },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-gv100_disp_core_mthd_head = {
-       .mthd = 0x0400,
-       .addr = 0x000400,
-       .data = {
-               { 0x2000, 0x682000 },
-               { 0x2004, 0x682004 },
-               { 0x2008, 0x682008 },
-               { 0x200c, 0x68200c },
-               { 0x2014, 0x682014 },
-               { 0x2018, 0x682018 },
-               { 0x201c, 0x68201c },
-               { 0x2020, 0x682020 },
-               { 0x2028, 0x682028 },
-               { 0x202c, 0x68202c },
-               { 0x2030, 0x682030 },
-               { 0x2038, 0x682038 },
-               { 0x203c, 0x68203c },
-               { 0x2048, 0x682048 },
-               { 0x204c, 0x68204c },
-               { 0x2050, 0x682050 },
-               { 0x2054, 0x682054 },
-               { 0x2058, 0x682058 },
-               { 0x205c, 0x68205c },
-               { 0x2060, 0x682060 },
-               { 0x2064, 0x682064 },
-               { 0x2068, 0x682068 },
-               { 0x206c, 0x68206c },
-               { 0x2070, 0x682070 },
-               { 0x2074, 0x682074 },
-               { 0x2078, 0x682078 },
-               { 0x207c, 0x68207c },
-               { 0x2080, 0x682080 },
-               { 0x2088, 0x682088 },
-               { 0x2090, 0x682090 },
-               { 0x209c, 0x68209c },
-               { 0x20a0, 0x6820a0 },
-               { 0x20a4, 0x6820a4 },
-               { 0x20a8, 0x6820a8 },
-               { 0x20ac, 0x6820ac },
-               { 0x2180, 0x682180 },
-               { 0x2184, 0x682184 },
-               { 0x218c, 0x68218c },
-               { 0x2194, 0x682194 },
-               { 0x2198, 0x682198 },
-               { 0x219c, 0x68219c },
-               { 0x21a0, 0x6821a0 },
-               { 0x21a4, 0x6821a4 },
-               { 0x2214, 0x682214 },
-               { 0x2218, 0x682218 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-gv100_disp_core_mthd = {
-       .name = "Core",
-       .addr = 0x000000,
-       .prev = 0x008000,
-       .data = {
-               { "Global", 1, &gv100_disp_core_mthd_base },
-               {    "SOR", 4, &gv100_disp_core_mthd_sor  },
-               { "WINDOW", 8, &gv100_disp_core_mthd_wndw },
-               {   "HEAD", 4, &gv100_disp_core_mthd_head },
-               {}
-       }
-};
-
-static int
-gv100_disp_core_idle(struct nv50_disp_chan *chan)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       nvkm_msec(device, 2000,
-               u32 stat = nvkm_rd32(device, 0x610630);
-               if ((stat & 0x001f0000) == 0x000b0000)
-                       return 0;
-       );
-       return -EBUSY;
-}
-
-static u64
-gv100_disp_core_user(struct nv50_disp_chan *chan, u64 *psize)
-{
-       *psize = 0x10000;
-       return 0x680000;
-}
-
-static void
-gv100_disp_core_intr(struct nv50_disp_chan *chan, bool en)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 mask = 0x00000001;
-       const u32 data = en ? mask : 0;
-       nvkm_mask(device, 0x611dac, mask, data);
-}
-
-static void
-gv100_disp_core_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       nvkm_mask(device, 0x6104e0, 0x00000010, 0x00000000);
-       gv100_disp_core_idle(chan);
-       nvkm_mask(device, 0x6104e0, 0x00000002, 0x00000000);
-       chan->suspend_put = nvkm_rd32(device, 0x680000);
-}
-
-static int
-gv100_disp_core_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-
-       nvkm_wr32(device, 0x610b24, lower_32_bits(chan->push));
-       nvkm_wr32(device, 0x610b20, upper_32_bits(chan->push));
-       nvkm_wr32(device, 0x610b28, 0x00000001);
-       nvkm_wr32(device, 0x610b2c, 0x00000040);
-
-       nvkm_mask(device, 0x6104e0, 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x680000, chan->suspend_put);
-       nvkm_wr32(device, 0x6104e0, 0x00000013);
-       return gv100_disp_core_idle(chan);
-}
-
-static const struct nv50_disp_chan_func
-gv100_disp_core = {
-       .init = gv100_disp_core_init,
-       .fini = gv100_disp_core_fini,
-       .intr = gv100_disp_core_intr,
-       .user = gv100_disp_core_user,
-       .bind = gv100_disp_dmac_bind,
-};
-
-int
-gv100_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&gv100_disp_core, &gv100_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c
deleted file mode 100644 (file)
index 660310b..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-#include <core/client.h>
-#include <subdev/timer.h>
-
-#include <nvif/cl507d.h>
-#include <nvif/unpack.h>
-
-int
-nv50_disp_core_new_(const struct nv50_disp_chan_func *func,
-                   const struct nv50_disp_chan_mthd *mthd,
-                   struct nv50_disp *disp, int chid,
-                   const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nvkm_object **pobject)
-{
-       union {
-               struct nv50_disp_core_channel_dma_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       u64 push;
-       int ret = -ENOSYS;
-
-       nvif_ioctl(parent, "create disp core channel dma size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create disp core channel dma vers %d "
-                                  "pushbuf %016llx\n",
-                          args->v0.version, args->v0.pushbuf);
-               push = args->v0.pushbuf;
-       } else
-               return ret;
-
-       return nv50_disp_dmac_new_(func, mthd, disp, chid, 0,
-                                  push, oclass, pobject);
-}
-
-const struct nv50_disp_mthd_list
-nv50_disp_core_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x000000 },
-               { 0x0084, 0x610bb8 },
-               { 0x0088, 0x610b9c },
-               { 0x008c, 0x000000 },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-nv50_disp_core_mthd_dac = {
-       .mthd = 0x0080,
-       .addr = 0x000008,
-       .data = {
-               { 0x0400, 0x610b58 },
-               { 0x0404, 0x610bdc },
-               { 0x0420, 0x610828 },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-nv50_disp_core_mthd_sor = {
-       .mthd = 0x0040,
-       .addr = 0x000008,
-       .data = {
-               { 0x0600, 0x610b70 },
-               {}
-       }
-};
-
-const struct nv50_disp_mthd_list
-nv50_disp_core_mthd_pior = {
-       .mthd = 0x0040,
-       .addr = 0x000008,
-       .data = {
-               { 0x0700, 0x610b80 },
-               {}
-       }
-};
-
-static const struct nv50_disp_mthd_list
-nv50_disp_core_mthd_head = {
-       .mthd = 0x0400,
-       .addr = 0x000540,
-       .data = {
-               { 0x0800, 0x610ad8 },
-               { 0x0804, 0x610ad0 },
-               { 0x0808, 0x610a48 },
-               { 0x080c, 0x610a78 },
-               { 0x0810, 0x610ac0 },
-               { 0x0814, 0x610af8 },
-               { 0x0818, 0x610b00 },
-               { 0x081c, 0x610ae8 },
-               { 0x0820, 0x610af0 },
-               { 0x0824, 0x610b08 },
-               { 0x0828, 0x610b10 },
-               { 0x082c, 0x610a68 },
-               { 0x0830, 0x610a60 },
-               { 0x0834, 0x000000 },
-               { 0x0838, 0x610a40 },
-               { 0x0840, 0x610a24 },
-               { 0x0844, 0x610a2c },
-               { 0x0848, 0x610aa8 },
-               { 0x084c, 0x610ab0 },
-               { 0x0860, 0x610a84 },
-               { 0x0864, 0x610a90 },
-               { 0x0868, 0x610b18 },
-               { 0x086c, 0x610b20 },
-               { 0x0870, 0x610ac8 },
-               { 0x0874, 0x610a38 },
-               { 0x0880, 0x610a58 },
-               { 0x0884, 0x610a9c },
-               { 0x08a0, 0x610a70 },
-               { 0x08a4, 0x610a50 },
-               { 0x08a8, 0x610ae0 },
-               { 0x08c0, 0x610b28 },
-               { 0x08c4, 0x610b30 },
-               { 0x08c8, 0x610b40 },
-               { 0x08d4, 0x610b38 },
-               { 0x08d8, 0x610b48 },
-               { 0x08dc, 0x610b50 },
-               { 0x0900, 0x610a18 },
-               { 0x0904, 0x610ab8 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-nv50_disp_core_mthd = {
-       .name = "Core",
-       .addr = 0x000000,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &nv50_disp_core_mthd_base },
-               {    "DAC", 3, &nv50_disp_core_mthd_dac  },
-               {    "SOR", 2, &nv50_disp_core_mthd_sor  },
-               {   "PIOR", 3, &nv50_disp_core_mthd_pior },
-               {   "HEAD", 2, &nv50_disp_core_mthd_head },
-               {}
-       }
-};
-
-static void
-nv50_disp_core_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-
-       /* deactivate channel */
-       nvkm_mask(device, 0x610200, 0x00000010, 0x00000000);
-       nvkm_mask(device, 0x610200, 0x00000003, 0x00000000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610200) & 0x001e0000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "core fini: %08x\n",
-                          nvkm_rd32(device, 0x610200));
-       }
-
-       chan->suspend_put = nvkm_rd32(device, 0x640000);
-}
-
-static int
-nv50_disp_core_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-
-       /* attempt to unstick channel from some unknown state */
-       if ((nvkm_rd32(device, 0x610200) & 0x009f0000) == 0x00020000)
-               nvkm_mask(device, 0x610200, 0x00800000, 0x00800000);
-       if ((nvkm_rd32(device, 0x610200) & 0x003f0000) == 0x00030000)
-               nvkm_mask(device, 0x610200, 0x00600000, 0x00600000);
-
-       /* initialise channel for dma command submission */
-       nvkm_wr32(device, 0x610204, chan->push);
-       nvkm_wr32(device, 0x610208, 0x00010000);
-       nvkm_wr32(device, 0x61020c, 0x00000000);
-       nvkm_mask(device, 0x610200, 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x640000, chan->suspend_put);
-       nvkm_wr32(device, 0x610200, 0x01000013);
-
-       /* wait for it to go inactive */
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610200) & 0x80000000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "core init: %08x\n",
-                          nvkm_rd32(device, 0x610200));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-nv50_disp_core_func = {
-       .init = nv50_disp_core_init,
-       .fini = nv50_disp_core_fini,
-       .intr = nv50_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-       .bind = nv50_disp_dmac_bind,
-};
-
-int
-nv50_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                  struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_core_new_(&nv50_disp_core_func, &nv50_disp_core_mthd,
-                                  disp, 0, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c
deleted file mode 100644 (file)
index cdda365..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-int
-gf119_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_curs_new_(&gf119_disp_pioc_func, disp, 13, 13,
-                                  oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c
deleted file mode 100644 (file)
index 1a4601f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "channv50.h"
-
-int
-gp102_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_curs_new_(&gf119_disp_pioc_func, disp, 13, 17,
-                                  oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c
deleted file mode 100644 (file)
index a3e4f69..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "channv50.h"
-
-#include <subdev/timer.h>
-
-static int
-gv100_disp_curs_idle(struct nv50_disp_chan *chan)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 soff = (chan->chid.ctrl - 1) * 0x04;
-       nvkm_msec(device, 2000,
-               u32 stat = nvkm_rd32(device, 0x610664 + soff);
-               if ((stat & 0x00070000) == 0x00040000)
-                       return 0;
-       );
-       return -EBUSY;
-}
-
-static void
-gv100_disp_curs_intr(struct nv50_disp_chan *chan, bool en)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 mask = 0x00010000 << chan->head;
-       const u32 data = en ? mask : 0;
-       nvkm_mask(device, 0x611dac, mask, data);
-}
-
-static void
-gv100_disp_curs_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 hoff = chan->chid.ctrl * 4;
-       nvkm_mask(device, 0x6104e0 + hoff, 0x00000010, 0x00000010);
-       gv100_disp_curs_idle(chan);
-       nvkm_mask(device, 0x6104e0 + hoff, 0x00000001, 0x00000000);
-}
-
-static int
-gv100_disp_curs_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       nvkm_wr32(device, 0x6104e0 + chan->chid.ctrl * 4, 0x00000001);
-       return gv100_disp_curs_idle(chan);
-}
-
-static const struct nv50_disp_chan_func
-gv100_disp_curs = {
-       .init = gv100_disp_curs_init,
-       .fini = gv100_disp_curs_fini,
-       .intr = gv100_disp_curs_intr,
-       .user = gv100_disp_chan_user,
-};
-
-int
-gv100_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_curs_new_(&gv100_disp_curs, disp, 73, 73,
-                                  oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c
deleted file mode 100644 (file)
index d297585..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "head.h"
-
-#include <core/client.h>
-
-#include <nvif/cl507a.h>
-#include <nvif/unpack.h>
-
-int
-nv50_disp_curs_new_(const struct nv50_disp_chan_func *func,
-                   struct nv50_disp *disp, int ctrl, int user,
-                   const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nvkm_object **pobject)
-{
-       union {
-               struct nv50_disp_cursor_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       int head, ret = -ENOSYS;
-
-       nvif_ioctl(parent, "create disp cursor size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create disp cursor vers %d head %d\n",
-                          args->v0.version, args->v0.head);
-               if (!nvkm_head_find(&disp->base, args->v0.head))
-                       return -EINVAL;
-               head = args->v0.head;
-       } else
-               return ret;
-
-       return nv50_disp_chan_new_(func, NULL, disp, ctrl + head, user + head,
-                                  head, oclass, pobject);
-}
-
-int
-nv50_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                  struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_curs_new_(&nv50_disp_pioc_func, disp, 7, 7,
-                                  oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c
deleted file mode 100644 (file)
index 71a9477..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-static void
-gf119_dac_clock(struct nvkm_ior *dac)
-{
-       struct nvkm_device *device = dac->disp->engine.subdev.device;
-       const u32 doff = nv50_ior_base(dac);
-       nvkm_mask(device, 0x612280 + doff, 0x07070707, 0x00000000);
-}
-
-static void
-gf119_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = dac->disp->engine.subdev.device;
-       const u32 coff = (state == &dac->asy) * 0x20000 + dac->id * 0x20;
-       u32 ctrl = nvkm_rd32(device, 0x640180 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       switch (state->proto_evo) {
-       case 0: state->proto = CRT; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x0000000f;
-}
-
-static const struct nvkm_ior_func
-gf119_dac = {
-       .state = gf119_dac_state,
-       .power = nv50_dac_power,
-       .sense = nv50_dac_sense,
-       .clock = gf119_dac_clock,
-};
-
-int
-gf119_dac_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&gf119_dac, disp, DAC, id);
-}
-
-int
-gf119_dac_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x612004) & 0x000000f0) >> 4;
-       return 4;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c
deleted file mode 100644 (file)
index 558012d..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-static void
-nv50_dac_clock(struct nvkm_ior *dac)
-{
-       struct nvkm_device *device = dac->disp->engine.subdev.device;
-       const u32 doff = nv50_ior_base(dac);
-       nvkm_mask(device, 0x614280 + doff, 0x07070707, 0x00000000);
-}
-
-int
-nv50_dac_sense(struct nvkm_ior *dac, u32 loadval)
-{
-       struct nvkm_device *device = dac->disp->engine.subdev.device;
-       const u32 doff = nv50_ior_base(dac);
-
-       dac->func->power(dac, false, true, false, false, false);
-
-       nvkm_wr32(device, 0x61a00c + doff, 0x00100000 | loadval);
-       mdelay(9);
-       udelay(500);
-       loadval = nvkm_mask(device, 0x61a00c + doff, 0xffffffff, 0x00000000);
-
-       dac->func->power(dac, false, false, false, false, false);
-       if (!(loadval & 0x80000000))
-               return -ETIMEDOUT;
-
-       return (loadval & 0x38000000) >> 27;
-}
-
-static void
-nv50_dac_power_wait(struct nvkm_device *device, const u32 doff)
-{
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000))
-                       break;
-       );
-}
-
-void
-nv50_dac_power(struct nvkm_ior *dac, bool normal, bool pu,
-              bool data, bool vsync, bool hsync)
-{
-       struct nvkm_device *device = dac->disp->engine.subdev.device;
-       const u32  doff = nv50_ior_base(dac);
-       const u32 shift = normal ? 0 : 16;
-       const u32 state = 0x80000000 | (0x00000040 * !    pu |
-                                       0x00000010 * !  data |
-                                       0x00000004 * ! vsync |
-                                       0x00000001 * ! hsync) << shift;
-       const u32 field = 0xc0000000 | (0x00000055 << shift);
-
-       nv50_dac_power_wait(device, doff);
-       nvkm_mask(device, 0x61a004 + doff, field, state);
-       nv50_dac_power_wait(device, doff);
-}
-
-static void
-nv50_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = dac->disp->engine.subdev.device;
-       const u32 coff = dac->id * 8 + (state == &dac->arm) * 4;
-       u32 ctrl = nvkm_rd32(device, 0x610b58 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       switch (state->proto_evo) {
-       case 0: state->proto = CRT; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x00000003;
-}
-
-static const struct nvkm_ior_func
-nv50_dac = {
-       .state = nv50_dac_state,
-       .power = nv50_dac_power,
-       .sense = nv50_dac_sense,
-       .clock = nv50_dac_clock,
-};
-
-int
-nv50_dac_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&nv50_dac, disp, DAC, id);
-}
-
-int
-nv50_dac_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x610184) & 0x00700000) >> 20;
-       return 3;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c
deleted file mode 100644 (file)
index 76425e8..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-#include <core/ramht.h>
-#include <subdev/timer.h>
-
-int
-gf119_disp_dmac_bind(struct nv50_disp_chan *chan,
-                    struct nvkm_object *object, u32 handle)
-{
-       return nvkm_ramht_insert(chan->disp->ramht, object,
-                                chan->chid.user, -9, handle,
-                                chan->chid.user << 27 | 0x00000001);
-}
-
-void
-gf119_disp_dmac_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       /* deactivate channel */
-       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000);
-       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000003, 0x00000000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x001e0000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d fini: %08x\n", user,
-                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
-       }
-
-       chan->suspend_put = nvkm_rd32(device, 0x640000 + (ctrl * 0x1000));
-}
-
-static int
-gf119_disp_dmac_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       /* initialise channel for dma command submission */
-       nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
-       nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
-       nvkm_wr32(device, 0x61049c + (ctrl * 0x0010), 0x00000001);
-       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), chan->suspend_put);
-       nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
-
-       /* wait for it to go inactive */
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d init: %08x\n", user,
-                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-gf119_disp_dmac_func = {
-       .init = gf119_disp_dmac_init,
-       .fini = gf119_disp_dmac_fini,
-       .intr = gf119_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-       .bind = gf119_disp_dmac_bind,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c
deleted file mode 100644 (file)
index da258df..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "channv50.h"
-
-#include <subdev/timer.h>
-
-static int
-gp102_disp_dmac_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       /* initialise channel for dma command submission */
-       nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
-       nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
-       nvkm_wr32(device, 0x61149c + (ctrl * 0x0010), 0x00000001);
-       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), chan->suspend_put);
-       nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
-
-       /* wait for it to go inactive */
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d init: %08x\n", user,
-                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-gp102_disp_dmac_func = {
-       .init = gp102_disp_dmac_init,
-       .fini = gf119_disp_dmac_fini,
-       .intr = gf119_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-       .bind = gf119_disp_dmac_bind,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c
deleted file mode 100644 (file)
index fdb624a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "channv50.h"
-
-#include <core/ramht.h>
-#include <subdev/timer.h>
-
-static int
-gv100_disp_dmac_idle(struct nv50_disp_chan *chan)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 soff = (chan->chid.ctrl - 1) * 0x04;
-       nvkm_msec(device, 2000,
-               u32 stat = nvkm_rd32(device, 0x610664 + soff);
-               if ((stat & 0x000f0000) == 0x00040000)
-                       return 0;
-       );
-       return -EBUSY;
-}
-
-int
-gv100_disp_dmac_bind(struct nv50_disp_chan *chan,
-                    struct nvkm_object *object, u32 handle)
-{
-       return nvkm_ramht_insert(chan->disp->ramht, object,
-                                chan->chid.user, -9, handle,
-                                chan->chid.user << 25 | 0x00000040);
-}
-
-void
-gv100_disp_dmac_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 uoff = (chan->chid.ctrl - 1) * 0x1000;
-       const u32 coff = chan->chid.ctrl * 0x04;
-       nvkm_mask(device, 0x6104e0 + coff, 0x00000010, 0x00000000);
-       gv100_disp_dmac_idle(chan);
-       nvkm_mask(device, 0x6104e0 + coff, 0x00000002, 0x00000000);
-       chan->suspend_put = nvkm_rd32(device, 0x690000 + uoff);
-}
-
-int
-gv100_disp_dmac_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       const u32 uoff = (chan->chid.ctrl - 1) * 0x1000;
-       const u32 poff = chan->chid.ctrl * 0x10;
-       const u32 coff = chan->chid.ctrl * 0x04;
-
-       nvkm_wr32(device, 0x610b24 + poff, lower_32_bits(chan->push));
-       nvkm_wr32(device, 0x610b20 + poff, upper_32_bits(chan->push));
-       nvkm_wr32(device, 0x610b28 + poff, 0x00000001);
-       nvkm_wr32(device, 0x610b2c + poff, 0x00000040);
-
-       nvkm_mask(device, 0x6104e0 + coff, 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x690000 + uoff, chan->suspend_put);
-       nvkm_wr32(device, 0x6104e0 + coff, 0x00000013);
-       return gv100_disp_dmac_idle(chan);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
deleted file mode 100644 (file)
index d0a7da9..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-#include <core/client.h>
-#include <core/ramht.h>
-#include <subdev/fb.h>
-#include <subdev/mmu.h>
-#include <subdev/timer.h>
-#include <engine/dma.h>
-
-int
-nv50_disp_dmac_new_(const struct nv50_disp_chan_func *func,
-                   const struct nv50_disp_chan_mthd *mthd,
-                   struct nv50_disp *disp, int chid, int head, u64 push,
-                   const struct nvkm_oclass *oclass,
-                   struct nvkm_object **pobject)
-{
-       struct nvkm_client *client = oclass->client;
-       struct nv50_disp_chan *chan;
-       int ret;
-
-       ret = nv50_disp_chan_new_(func, mthd, disp, chid, chid, head, oclass,
-                                 pobject);
-       chan = nv50_disp_chan(*pobject);
-       if (ret)
-               return ret;
-
-       chan->memory = nvkm_umem_search(client, push);
-       if (IS_ERR(chan->memory))
-               return PTR_ERR(chan->memory);
-
-       if (nvkm_memory_size(chan->memory) < 0x1000)
-               return -EINVAL;
-
-       switch (nvkm_memory_target(chan->memory)) {
-       case NVKM_MEM_TARGET_VRAM: chan->push = 0x00000001; break;
-       case NVKM_MEM_TARGET_NCOH: chan->push = 0x00000002; break;
-       case NVKM_MEM_TARGET_HOST: chan->push = 0x00000003; break;
-       default:
-               return -EINVAL;
-       }
-
-       chan->push |= nvkm_memory_addr(chan->memory) >> 8;
-       return 0;
-}
-
-int
-nv50_disp_dmac_bind(struct nv50_disp_chan *chan,
-                   struct nvkm_object *object, u32 handle)
-{
-       return nvkm_ramht_insert(chan->disp->ramht, object,
-                                chan->chid.user, -10, handle,
-                                chan->chid.user << 28 |
-                                chan->chid.user);
-}
-
-static void
-nv50_disp_dmac_fini(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       /* deactivate channel */
-       nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000);
-       nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000003, 0x00000000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x001e0000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
-                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
-       }
-
-       chan->suspend_put = nvkm_rd32(device, 0x640000 + (ctrl * 0x1000));
-}
-
-static int
-nv50_disp_dmac_init(struct nv50_disp_chan *chan)
-{
-       struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       /* initialise channel for dma command submission */
-       nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
-       nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
-       nvkm_wr32(device, 0x61020c + (ctrl * 0x0010), ctrl);
-       nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000010, 0x00000010);
-       nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), chan->suspend_put);
-       nvkm_wr32(device, 0x610200 + (ctrl * 0x0010), 0x00000013);
-
-       /* wait for it to go inactive */
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x80000000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d init timeout, %08x\n", user,
-                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-nv50_disp_dmac_func = {
-       .init = nv50_disp_dmac_init,
-       .fini = nv50_disp_dmac_fini,
-       .intr = nv50_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-       .bind = nv50_disp_dmac_bind,
-};
index 8e09315..c1b3206 100644 (file)
@@ -40,7 +40,7 @@
 #define AMPERE_IED_HACK(disp) ((disp)->engine.subdev.device->card_type >= GA100)
 
 struct lt_state {
-       struct nvkm_dp *dp;
+       struct nvkm_outp *outp;
 
        int repeaters;
        int repeater;
@@ -55,7 +55,7 @@ struct lt_state {
 static int
 nvkm_dp_train_sense(struct lt_state *lt, bool pc, u32 delay)
 {
-       struct nvkm_dp *dp = lt->dp;
+       struct nvkm_outp *outp = lt->outp;
        u32 addr;
        int ret;
 
@@ -66,7 +66,7 @@ nvkm_dp_train_sense(struct lt_state *lt, bool pc, u32 delay)
        else
                addr = DPCD_LS02;
 
-       ret = nvkm_rdaux(dp->aux, addr, &lt->stat[0], 3);
+       ret = nvkm_rdaux(outp->dp.aux, addr, &lt->stat[0], 3);
        if (ret)
                return ret;
 
@@ -75,18 +75,18 @@ nvkm_dp_train_sense(struct lt_state *lt, bool pc, u32 delay)
        else
                addr = DPCD_LS06;
 
-       ret = nvkm_rdaux(dp->aux, addr, &lt->stat[4], 2);
+       ret = nvkm_rdaux(outp->dp.aux, addr, &lt->stat[4], 2);
        if (ret)
                return ret;
 
        if (pc) {
-               ret = nvkm_rdaux(dp->aux, DPCD_LS0C, &lt->pc2stat, 1);
+               ret = nvkm_rdaux(outp->dp.aux, DPCD_LS0C, &lt->pc2stat, 1);
                if (ret)
                        lt->pc2stat = 0x00;
-               OUTP_TRACE(&dp->outp, "status %6ph pc2 %02x",
-                          lt->stat, lt->pc2stat);
+
+               OUTP_TRACE(outp, "status %6ph pc2 %02x", lt->stat, lt->pc2stat);
        } else {
-               OUTP_TRACE(&dp->outp, "status %6ph", lt->stat);
+               OUTP_TRACE(outp, "status %6ph", lt->stat);
        }
 
        return 0;
@@ -95,8 +95,8 @@ nvkm_dp_train_sense(struct lt_state *lt, bool pc, u32 delay)
 static int
 nvkm_dp_train_drive(struct lt_state *lt, bool pc)
 {
-       struct nvkm_dp *dp = lt->dp;
-       struct nvkm_ior *ior = dp->outp.ior;
+       struct nvkm_outp *outp = lt->outp;
+       struct nvkm_ior *ior = outp->ior;
        struct nvkm_bios *bios = ior->disp->engine.subdev.device->bios;
        struct nvbios_dpout info;
        struct nvbios_dpcfg ocfg;
@@ -127,26 +127,22 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc)
                lt->conf[i] = (lpre << 3) | lvsw;
                lt->pc2conf[i >> 1] |= lpc2 << ((i & 1) * 4);
 
-               OUTP_TRACE(&dp->outp, "config lane %d %02x %02x",
-                          i, lt->conf[i], lpc2);
+               OUTP_TRACE(outp, "config lane %d %02x %02x", i, lt->conf[i], lpc2);
 
                if (lt->repeater != lt->repeaters)
                        continue;
 
-               data = nvbios_dpout_match(bios, dp->outp.info.hasht,
-                                               dp->outp.info.hashm,
+               data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm,
                                          &ver, &hdr, &cnt, &len, &info);
                if (!data)
                        continue;
 
-               data = nvbios_dpcfg_match(bios, data, lpc2 & 3, lvsw & 3,
-                                         lpre & 3, &ver, &hdr, &cnt, &len,
-                                         &ocfg);
+               data = nvbios_dpcfg_match(bios, data, lpc2 & 3, lvsw & 3, lpre & 3,
+                                         &ver, &hdr, &cnt, &len, &ocfg);
                if (!data)
                        continue;
 
-               ior->func->dp.drive(ior, i, ocfg.pc, ocfg.dc,
-                                           ocfg.pe, ocfg.tx_pu);
+               ior->func->dp->drive(ior, i, ocfg.pc, ocfg.dc, ocfg.pe, ocfg.tx_pu);
        }
 
        if (lt->repeater)
@@ -154,12 +150,12 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc)
        else
                addr = DPCD_LC03(0);
 
-       ret = nvkm_wraux(dp->aux, addr, lt->conf, 4);
+       ret = nvkm_wraux(outp->dp.aux, addr, lt->conf, 4);
        if (ret)
                return ret;
 
        if (pc) {
-               ret = nvkm_wraux(dp->aux, DPCD_LC0F, lt->pc2conf, 2);
+               ret = nvkm_wraux(outp->dp.aux, DPCD_LC0F, lt->pc2conf, 2);
                if (ret)
                        return ret;
        }
@@ -170,19 +166,19 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc)
 static void
 nvkm_dp_train_pattern(struct lt_state *lt, u8 pattern)
 {
-       struct nvkm_dp *dp = lt->dp;
+       struct nvkm_outp *outp = lt->outp;
        u32 addr;
        u8 sink_tp;
 
-       OUTP_TRACE(&dp->outp, "training pattern %d", pattern);
-       dp->outp.ior->func->dp.pattern(dp->outp.ior, pattern);
+       OUTP_TRACE(outp, "training pattern %d", pattern);
+       outp->ior->func->dp->pattern(outp->ior, pattern);
 
        if (lt->repeater)
                addr = DPCD_LTTPR_PATTERN_SET(lt->repeater);
        else
                addr = DPCD_LC02;
 
-       nvkm_rdaux(dp->aux, addr, &sink_tp, 1);
+       nvkm_rdaux(outp->dp.aux, addr, &sink_tp, 1);
        sink_tp &= ~DPCD_LC02_TRAINING_PATTERN_SET;
        sink_tp |= (pattern != 4) ? pattern : 7;
 
@@ -190,13 +186,13 @@ nvkm_dp_train_pattern(struct lt_state *lt, u8 pattern)
                sink_tp |=  DPCD_LC02_SCRAMBLING_DISABLE;
        else
                sink_tp &= ~DPCD_LC02_SCRAMBLING_DISABLE;
-       nvkm_wraux(dp->aux, addr, &sink_tp, 1);
+       nvkm_wraux(outp->dp.aux, addr, &sink_tp, 1);
 }
 
 static int
 nvkm_dp_train_eq(struct lt_state *lt)
 {
-       struct nvkm_i2c_aux *aux = lt->dp->aux;
+       struct nvkm_i2c_aux *aux = lt->outp->dp.aux;
        bool eq_done = false, cr_done = true;
        int tries = 0, usec = 0, i;
        u8 data;
@@ -207,17 +203,17 @@ nvkm_dp_train_eq(struct lt_state *lt)
 
                nvkm_dp_train_pattern(lt, 4);
        } else {
-               if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] >= 0x14 &&
-                   lt->dp->dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED)
+               if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x14 &&
+                   lt->outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED)
                        nvkm_dp_train_pattern(lt, 4);
                else
-               if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] >= 0x12 &&
-                   lt->dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED)
+               if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x12 &&
+                   lt->outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED)
                        nvkm_dp_train_pattern(lt, 3);
                else
                        nvkm_dp_train_pattern(lt, 2);
 
-               usec = (lt->dp->dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
+               usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
        }
 
        do {
@@ -227,7 +223,7 @@ nvkm_dp_train_eq(struct lt_state *lt)
                        break;
 
                eq_done = !!(lt->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE);
-               for (i = 0; i < lt->dp->outp.ior->dp.nr && eq_done; i++) {
+               for (i = 0; i < lt->outp->ior->dp.nr && eq_done; i++) {
                        u8 lane = (lt->stat[i >> 1] >> ((i & 1) * 4)) & 0xf;
                        if (!(lane & DPCD_LS02_LANE0_CR_DONE))
                                cr_done = false;
@@ -249,8 +245,8 @@ nvkm_dp_train_cr(struct lt_state *lt)
 
        nvkm_dp_train_pattern(lt, 1);
 
-       if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] < 0x14 && !lt->repeater)
-               usec = (lt->dp->dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
+       if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x14 && !lt->repeater)
+               usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
 
        do {
                if (nvkm_dp_train_drive(lt, false) ||
@@ -258,7 +254,7 @@ nvkm_dp_train_cr(struct lt_state *lt)
                        break;
 
                cr_done = true;
-               for (i = 0; i < lt->dp->outp.ior->dp.nr; i++) {
+               for (i = 0; i < lt->outp->ior->dp.nr; i++) {
                        u8 lane = (lt->stat[i >> 1] >> ((i & 1) * 4)) & 0xf;
                        if (!(lane & DPCD_LS02_LANE0_CR_DONE)) {
                                cr_done = false;
@@ -278,45 +274,44 @@ nvkm_dp_train_cr(struct lt_state *lt)
 }
 
 static int
-nvkm_dp_train_links(struct nvkm_dp *dp, int rate)
+nvkm_dp_train_links(struct nvkm_outp *outp, int rate)
 {
-       struct nvkm_ior *ior = dp->outp.ior;
-       struct nvkm_disp *disp = dp->outp.disp;
+       struct nvkm_ior *ior = outp->ior;
+       struct nvkm_disp *disp = outp->disp;
        struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_bios *bios = subdev->device->bios;
        struct lt_state lt = {
-               .dp = dp,
+               .outp = outp,
        };
        u32 lnkcmp;
        u8 sink[2], data;
        int ret;
 
-       OUTP_DBG(&dp->outp, "training %d x %d MB/s",
-                ior->dp.nr, ior->dp.bw * 27);
+       OUTP_DBG(outp, "training %d x %d MB/s", ior->dp.nr, ior->dp.bw * 27);
 
        /* Intersect misc. capabilities of the OR and sink. */
        if (disp->engine.subdev.device->chipset < 0x110)
-               dp->dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED;
+               outp->dp.dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED;
        if (disp->engine.subdev.device->chipset < 0xd0)
-               dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED;
-       lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED;
+               outp->dp.dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED;
+       lt.pc2 = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED;
 
-       if (AMPERE_IED_HACK(disp) && (lnkcmp = lt.dp->info.script[0])) {
+       if (AMPERE_IED_HACK(disp) && (lnkcmp = lt.outp->dp.info.script[0])) {
                /* Execute BeforeLinkTraining script from DP Info table. */
                while (ior->dp.bw < nvbios_rd08(bios, lnkcmp))
                        lnkcmp += 3;
                lnkcmp = nvbios_rd16(bios, lnkcmp + 1);
 
-               nvbios_init(&dp->outp.disp->engine.subdev, lnkcmp,
-                       init.outp = &dp->outp.info;
+               nvbios_init(&outp->disp->engine.subdev, lnkcmp,
+                       init.outp = &outp->info;
                        init.or   = ior->id;
                        init.link = ior->asy.link;
                );
        }
 
        /* Set desired link configuration on the source. */
-       if ((lnkcmp = lt.dp->info.lnkcmp)) {
-               if (dp->version < 0x30) {
+       if ((lnkcmp = lt.outp->dp.info.lnkcmp)) {
+               if (outp->dp.version < 0x30) {
                        while ((ior->dp.bw * 2700) < nvbios_rd16(bios, lnkcmp))
                                lnkcmp += 4;
                        lnkcmp = nvbios_rd16(bios, lnkcmp + 2);
@@ -327,56 +322,56 @@ nvkm_dp_train_links(struct nvkm_dp *dp, int rate)
                }
 
                nvbios_init(subdev, lnkcmp,
-                       init.outp = &dp->outp.info;
+                       init.outp = &outp->info;
                        init.or   = ior->id;
                        init.link = ior->asy.link;
                );
        }
 
-       ret = ior->func->dp.links(ior, dp->aux);
+       ret = ior->func->dp->links(ior, outp->dp.aux);
        if (ret) {
                if (ret < 0) {
-                       OUTP_ERR(&dp->outp, "train failed with %d", ret);
+                       OUTP_ERR(outp, "train failed with %d", ret);
                        return ret;
                }
                return 0;
        }
 
-       ior->func->dp.power(ior, ior->dp.nr);
+       ior->func->dp->power(ior, ior->dp.nr);
 
        /* Select LTTPR non-transparent mode if we have a valid configuration,
         * use transparent mode otherwise.
         */
-       if (dp->lttpr[0] >= 0x14) {
+       if (outp->dp.lttpr[0] >= 0x14) {
                data = DPCD_LTTPR_MODE_TRANSPARENT;
-               nvkm_wraux(dp->aux, DPCD_LTTPR_MODE, &data, sizeof(data));
+               nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data));
 
-               if (dp->lttprs) {
+               if (outp->dp.lttprs) {
                        data = DPCD_LTTPR_MODE_NON_TRANSPARENT;
-                       nvkm_wraux(dp->aux, DPCD_LTTPR_MODE, &data, sizeof(data));
-                       lt.repeaters = dp->lttprs;
+                       nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data));
+                       lt.repeaters = outp->dp.lttprs;
                }
        }
 
        /* Set desired link configuration on the sink. */
-       sink[0] = (dp->rate[rate].dpcd < 0) ? ior->dp.bw : 0;
+       sink[0] = (outp->dp.rate[rate].dpcd < 0) ? ior->dp.bw : 0;
        sink[1] = ior->dp.nr;
        if (ior->dp.ef)
                sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
 
-       ret = nvkm_wraux(dp->aux, DPCD_LC00_LINK_BW_SET, sink, 2);
+       ret = nvkm_wraux(outp->dp.aux, DPCD_LC00_LINK_BW_SET, sink, 2);
        if (ret)
                return ret;
 
-       if (dp->rate[rate].dpcd >= 0) {
-               ret = nvkm_rdaux(dp->aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0]));
+       if (outp->dp.rate[rate].dpcd >= 0) {
+               ret = nvkm_rdaux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0]));
                if (ret)
                        return ret;
 
                sink[0] &= ~DPCD_LC15_LINK_RATE_SET_MASK;
-               sink[0] |= dp->rate[rate].dpcd;
+               sink[0] |= outp->dp.rate[rate].dpcd;
 
-               ret = nvkm_wraux(dp->aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0]));
+               ret = nvkm_wraux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0]));
                if (ret)
                        return ret;
        }
@@ -384,9 +379,9 @@ nvkm_dp_train_links(struct nvkm_dp *dp, int rate)
        /* Attempt to train the link in this configuration. */
        for (lt.repeater = lt.repeaters; lt.repeater >= 0; lt.repeater--) {
                if (lt.repeater)
-                       OUTP_DBG(&dp->outp, "training LTTPR%d", lt.repeater);
+                       OUTP_DBG(outp, "training LTTPR%d", lt.repeater);
                else
-                       OUTP_DBG(&dp->outp, "training sink");
+                       OUTP_DBG(outp, "training sink");
 
                memset(lt.stat, 0x00, sizeof(lt.stat));
                ret = nvkm_dp_train_cr(&lt);
@@ -399,94 +394,92 @@ nvkm_dp_train_links(struct nvkm_dp *dp, int rate)
 }
 
 static void
-nvkm_dp_train_fini(struct nvkm_dp *dp)
+nvkm_dp_train_fini(struct nvkm_outp *outp)
 {
        /* Execute AfterLinkTraining script from DP Info table. */
-       nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[1],
-               init.outp = &dp->outp.info;
-               init.or   = dp->outp.ior->id;
-               init.link = dp->outp.ior->asy.link;
+       nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[1],
+               init.outp = &outp->info;
+               init.or   = outp->ior->id;
+               init.link = outp->ior->asy.link;
        );
 }
 
 static void
-nvkm_dp_train_init(struct nvkm_dp *dp)
+nvkm_dp_train_init(struct nvkm_outp *outp)
 {
        /* Execute EnableSpread/DisableSpread script from DP Info table. */
-       if (dp->dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) {
-               nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[2],
-                       init.outp = &dp->outp.info;
-                       init.or   = dp->outp.ior->id;
-                       init.link = dp->outp.ior->asy.link;
+       if (outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) {
+               nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[2],
+                       init.outp = &outp->info;
+                       init.or   = outp->ior->id;
+                       init.link = outp->ior->asy.link;
                );
        } else {
-               nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[3],
-                       init.outp = &dp->outp.info;
-                       init.or   = dp->outp.ior->id;
-                       init.link = dp->outp.ior->asy.link;
+               nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[3],
+                       init.outp = &outp->info;
+                       init.or   = outp->ior->id;
+                       init.link = outp->ior->asy.link;
                );
        }
 
-       if (!AMPERE_IED_HACK(dp->outp.disp)) {
+       if (!AMPERE_IED_HACK(outp->disp)) {
                /* Execute BeforeLinkTraining script from DP Info table. */
-               nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0],
-                       init.outp = &dp->outp.info;
-                       init.or   = dp->outp.ior->id;
-                       init.link = dp->outp.ior->asy.link;
+               nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[0],
+                       init.outp = &outp->info;
+                       init.or   = outp->ior->id;
+                       init.link = outp->ior->asy.link;
                );
        }
 }
 
 static int
-nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
+nvkm_dp_train(struct nvkm_outp *outp, u32 dataKBps)
 {
-       struct nvkm_ior *ior = dp->outp.ior;
+       struct nvkm_ior *ior = outp->ior;
        int ret = -EINVAL, nr, rate;
        u8  pwr;
 
        /* Ensure sink is not in a low-power state. */
-       if (!nvkm_rdaux(dp->aux, DPCD_SC00, &pwr, 1)) {
+       if (!nvkm_rdaux(outp->dp.aux, DPCD_SC00, &pwr, 1)) {
                if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
                        pwr &= ~DPCD_SC00_SET_POWER;
                        pwr |=  DPCD_SC00_SET_POWER_D0;
-                       nvkm_wraux(dp->aux, DPCD_SC00, &pwr, 1);
+                       nvkm_wraux(outp->dp.aux, DPCD_SC00, &pwr, 1);
                }
        }
 
-       ior->dp.mst = dp->lt.mst;
-       ior->dp.ef = dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP;
+       ior->dp.mst = outp->dp.lt.mst;
+       ior->dp.ef = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP;
        ior->dp.nr = 0;
 
        /* Link training. */
-       OUTP_DBG(&dp->outp, "training");
-       nvkm_dp_train_init(dp);
-       for (nr = dp->links; ret < 0 && nr; nr >>= 1) {
-               for (rate = 0; ret < 0 && rate < dp->rates; rate++) {
-                       if (dp->rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) {
+       OUTP_DBG(outp, "training");
+       nvkm_dp_train_init(outp);
+       for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) {
+               for (rate = 0; ret < 0 && rate < outp->dp.rates; rate++) {
+                       if (outp->dp.rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) {
                                /* Program selected link configuration. */
-                               ior->dp.bw = dp->rate[rate].rate / 27000;
+                               ior->dp.bw = outp->dp.rate[rate].rate / 27000;
                                ior->dp.nr = nr;
-                               ret = nvkm_dp_train_links(dp, rate);
+                               ret = nvkm_dp_train_links(outp, rate);
                        }
                }
        }
-       nvkm_dp_train_fini(dp);
+       nvkm_dp_train_fini(outp);
        if (ret < 0)
-               OUTP_ERR(&dp->outp, "training failed");
+               OUTP_ERR(outp, "training failed");
        else
-               OUTP_DBG(&dp->outp, "training done");
-       atomic_set(&dp->lt.done, 1);
+               OUTP_DBG(outp, "training done");
+       atomic_set(&outp->dp.lt.done, 1);
        return ret;
 }
 
 void
 nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior)
 {
-       struct nvkm_dp *dp = nvkm_dp(outp);
-
        /* Execute DisableLT script from DP Info Table. */
-       nvbios_init(&ior->disp->engine.subdev, dp->info.script[4],
-               init.outp = &dp->outp.info;
+       nvbios_init(&ior->disp->engine.subdev, outp->dp.info.script[4],
+               init.outp = &outp->info;
                init.or   = ior->id;
                init.link = ior->arm.link;
        );
@@ -495,18 +488,15 @@ nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior)
 static void
 nvkm_dp_release(struct nvkm_outp *outp)
 {
-       struct nvkm_dp *dp = nvkm_dp(outp);
-
        /* Prevent link from being retrained if sink sends an IRQ. */
-       atomic_set(&dp->lt.done, 0);
-       dp->outp.ior->dp.nr = 0;
+       atomic_set(&outp->dp.lt.done, 0);
+       outp->ior->dp.nr = 0;
 }
 
 static int
 nvkm_dp_acquire(struct nvkm_outp *outp)
 {
-       struct nvkm_dp *dp = nvkm_dp(outp);
-       struct nvkm_ior *ior = dp->outp.ior;
+       struct nvkm_ior *ior = outp->ior;
        struct nvkm_head *head;
        bool retrain = true;
        u32 datakbps = 0;
@@ -515,10 +505,10 @@ nvkm_dp_acquire(struct nvkm_outp *outp)
        u8  stat[3];
        int ret, i;
 
-       mutex_lock(&dp->mutex);
+       mutex_lock(&outp->dp.mutex);
 
        /* Check that link configuration meets current requirements. */
-       list_for_each_entry(head, &outp->disp->head, head) {
+       list_for_each_entry(head, &outp->disp->heads, head) {
                if (ior->asy.head & (1 << head->id)) {
                        u32 khz = (head->asy.hz >> ior->asy.rgdiv) / 1000;
                        datakbps += khz * head->asy.or.depth;
@@ -527,18 +517,17 @@ nvkm_dp_acquire(struct nvkm_outp *outp)
 
        linkKBps = ior->dp.bw * 27000 * ior->dp.nr;
        dataKBps = DIV_ROUND_UP(datakbps, 8);
-       OUTP_DBG(&dp->outp, "data %d KB/s link %d KB/s mst %d->%d",
-                dataKBps, linkKBps, ior->dp.mst, dp->lt.mst);
-       if (linkKBps < dataKBps || ior->dp.mst != dp->lt.mst) {
-               OUTP_DBG(&dp->outp, "link requirements changed");
+       OUTP_DBG(outp, "data %d KB/s link %d KB/s mst %d->%d",
+                dataKBps, linkKBps, ior->dp.mst, outp->dp.lt.mst);
+       if (linkKBps < dataKBps || ior->dp.mst != outp->dp.lt.mst) {
+               OUTP_DBG(outp, "link requirements changed");
                goto done;
        }
 
        /* Check that link is still trained. */
-       ret = nvkm_rdaux(dp->aux, DPCD_LS02, stat, 3);
+       ret = nvkm_rdaux(outp->dp.aux, DPCD_LS02, stat, 3);
        if (ret) {
-               OUTP_DBG(&dp->outp,
-                        "failed to read link status, assuming no sink");
+               OUTP_DBG(outp, "failed to read link status, assuming no sink");
                goto done;
        }
 
@@ -548,125 +537,126 @@ nvkm_dp_acquire(struct nvkm_outp *outp)
                        if (!(lane & DPCD_LS02_LANE0_CR_DONE) ||
                            !(lane & DPCD_LS02_LANE0_CHANNEL_EQ_DONE) ||
                            !(lane & DPCD_LS02_LANE0_SYMBOL_LOCKED)) {
-                               OUTP_DBG(&dp->outp,
-                                        "lane %d not equalised", lane);
+                               OUTP_DBG(outp, "lane %d not equalised", lane);
                                goto done;
                        }
                }
                retrain = false;
        } else {
-               OUTP_DBG(&dp->outp, "no inter-lane alignment");
+               OUTP_DBG(outp, "no inter-lane alignment");
        }
 
 done:
-       if (retrain || !atomic_read(&dp->lt.done))
-               ret = nvkm_dp_train(dp, dataKBps);
-       mutex_unlock(&dp->mutex);
+       if (retrain || !atomic_read(&outp->dp.lt.done))
+               ret = nvkm_dp_train(outp, dataKBps);
+       mutex_unlock(&outp->dp.mutex);
        return ret;
 }
 
 static bool
-nvkm_dp_enable_supported_link_rates(struct nvkm_dp *dp)
+nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp)
 {
        u8 sink_rates[DPCD_RC10_SUPPORTED_LINK_RATES__SIZE];
        int i, j, k;
 
-       if (dp->outp.conn->info.type != DCB_CONNECTOR_eDP ||
-           dp->dpcd[DPCD_RC00_DPCD_REV] < 0x13 ||
-           nvkm_rdaux(dp->aux, DPCD_RC10_SUPPORTED_LINK_RATES(0), sink_rates, sizeof(sink_rates)))
+       if (outp->conn->info.type != DCB_CONNECTOR_eDP ||
+           outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x13 ||
+           nvkm_rdaux(outp->dp.aux, DPCD_RC10_SUPPORTED_LINK_RATES(0),
+                      sink_rates, sizeof(sink_rates)))
                return false;
 
        for (i = 0; i < ARRAY_SIZE(sink_rates); i += 2) {
                const u32 rate = ((sink_rates[i + 1] << 8) | sink_rates[i]) * 200 / 10;
 
-               if (!rate || WARN_ON(dp->rates == ARRAY_SIZE(dp->rate)))
+               if (!rate || WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate)))
                        break;
 
-               if (rate > dp->outp.info.dpconf.link_bw * 27000) {
-                       OUTP_DBG(&dp->outp, "rate %d !outp", rate);
+               if (rate > outp->info.dpconf.link_bw * 27000) {
+                       OUTP_DBG(outp, "rate %d !outp", rate);
                        continue;
                }
 
-               for (j = 0; j < dp->rates; j++) {
-                       if (rate > dp->rate[j].rate) {
-                               for (k = dp->rates; k > j; k--)
-                                       dp->rate[k] = dp->rate[k - 1];
+               for (j = 0; j < outp->dp.rates; j++) {
+                       if (rate > outp->dp.rate[j].rate) {
+                               for (k = outp->dp.rates; k > j; k--)
+                                       outp->dp.rate[k] = outp->dp.rate[k - 1];
                                break;
                        }
                }
 
-               dp->rate[j].dpcd = i / 2;
-               dp->rate[j].rate = rate;
-               dp->rates++;
+               outp->dp.rate[j].dpcd = i / 2;
+               outp->dp.rate[j].rate = rate;
+               outp->dp.rates++;
        }
 
-       for (i = 0; i < dp->rates; i++)
-               OUTP_DBG(&dp->outp, "link_rate[%d] = %d", dp->rate[i].dpcd, dp->rate[i].rate);
+       for (i = 0; i < outp->dp.rates; i++)
+               OUTP_DBG(outp, "link_rate[%d] = %d", outp->dp.rate[i].dpcd, outp->dp.rate[i].rate);
 
-       return dp->rates != 0;
+       return outp->dp.rates != 0;
 }
 
 static bool
-nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
+nvkm_dp_enable(struct nvkm_outp *outp, bool enable)
 {
-       struct nvkm_i2c_aux *aux = dp->aux;
+       struct nvkm_i2c_aux *aux = outp->dp.aux;
 
        if (enable) {
-               if (!dp->present) {
-                       OUTP_DBG(&dp->outp, "aux power -> always");
+               if (!outp->dp.present) {
+                       OUTP_DBG(outp, "aux power -> always");
                        nvkm_i2c_aux_monitor(aux, true);
-                       dp->present = true;
+                       outp->dp.present = true;
                }
 
                /* Detect any LTTPRs before reading DPCD receiver caps. */
-               if (!nvkm_rdaux(aux, DPCD_LTTPR_REV, dp->lttpr, sizeof(dp->lttpr)) &&
-                   dp->lttpr[0] >= 0x14 && dp->lttpr[2]) {
-                       switch (dp->lttpr[2]) {
-                       case 0x80: dp->lttprs = 1; break;
-                       case 0x40: dp->lttprs = 2; break;
-                       case 0x20: dp->lttprs = 3; break;
-                       case 0x10: dp->lttprs = 4; break;
-                       case 0x08: dp->lttprs = 5; break;
-                       case 0x04: dp->lttprs = 6; break;
-                       case 0x02: dp->lttprs = 7; break;
-                       case 0x01: dp->lttprs = 8; break;
+               if (!nvkm_rdaux(aux, DPCD_LTTPR_REV, outp->dp.lttpr, sizeof(outp->dp.lttpr)) &&
+                   outp->dp.lttpr[0] >= 0x14 && outp->dp.lttpr[2]) {
+                       switch (outp->dp.lttpr[2]) {
+                       case 0x80: outp->dp.lttprs = 1; break;
+                       case 0x40: outp->dp.lttprs = 2; break;
+                       case 0x20: outp->dp.lttprs = 3; break;
+                       case 0x10: outp->dp.lttprs = 4; break;
+                       case 0x08: outp->dp.lttprs = 5; break;
+                       case 0x04: outp->dp.lttprs = 6; break;
+                       case 0x02: outp->dp.lttprs = 7; break;
+                       case 0x01: outp->dp.lttprs = 8; break;
                        default:
                                /* Unknown LTTPR count, we'll switch to transparent mode. */
                                WARN_ON(1);
-                               dp->lttprs = 0;
+                               outp->dp.lttprs = 0;
                                break;
                        }
                } else {
                        /* No LTTPR support, or zero LTTPR count - don't touch it at all. */
-                       memset(dp->lttpr, 0x00, sizeof(dp->lttpr));
+                       memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr));
                }
 
-               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, dp->dpcd, sizeof(dp->dpcd))) {
+               if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) {
                        const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
                        const u8 *rate;
                        int rate_max;
 
-                       dp->rates = 0;
-                       dp->links = dp->dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT;
-                       dp->links = min(dp->links, dp->outp.info.dpconf.link_nr);
-                       if (dp->lttprs && dp->lttpr[4])
-                               dp->links = min_t(int, dp->links, dp->lttpr[4]);
+                       outp->dp.rates = 0;
+                       outp->dp.links = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT;
+                       outp->dp.links = min(outp->dp.links, outp->info.dpconf.link_nr);
+                       if (outp->dp.lttprs && outp->dp.lttpr[4])
+                               outp->dp.links = min_t(int, outp->dp.links, outp->dp.lttpr[4]);
 
-                       rate_max = dp->dpcd[DPCD_RC01_MAX_LINK_RATE];
-                       rate_max = min(rate_max, dp->outp.info.dpconf.link_bw);
-                       if (dp->lttprs && dp->lttpr[1])
-                               rate_max = min_t(int, rate_max, dp->lttpr[1]);
+                       rate_max = outp->dp.dpcd[DPCD_RC01_MAX_LINK_RATE];
+                       rate_max = min(rate_max, outp->info.dpconf.link_bw);
+                       if (outp->dp.lttprs && outp->dp.lttpr[1])
+                               rate_max = min_t(int, rate_max, outp->dp.lttpr[1]);
 
-                       if (!nvkm_dp_enable_supported_link_rates(dp)) {
+                       if (!nvkm_dp_enable_supported_link_rates(outp)) {
                                for (rate = rates; *rate; rate++) {
-                                       if (*rate <= rate_max) {
-                                               if (WARN_ON(dp->rates == ARRAY_SIZE(dp->rate)))
-                                                       break;
-
-                                               dp->rate[dp->rates].dpcd = -1;
-                                               dp->rate[dp->rates].rate = *rate * 27000;
-                                               dp->rates++;
-                                       }
+                                       if (*rate > rate_max)
+                                               continue;
+
+                                       if (WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate)))
+                                               break;
+
+                                       outp->dp.rate[outp->dp.rates].dpcd = -1;
+                                       outp->dp.rate[outp->dp.rates].rate = *rate * 27000;
+                                       outp->dp.rates++;
                                }
                        }
 
@@ -674,13 +664,13 @@ nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
                }
        }
 
-       if (dp->present) {
-               OUTP_DBG(&dp->outp, "aux power -> demand");
+       if (outp->dp.present) {
+               OUTP_DBG(outp, "aux power -> demand");
                nvkm_i2c_aux_monitor(aux, false);
-               dp->present = false;
+               outp->dp.present = false;
        }
 
-       atomic_set(&dp->lt.done, 0);
+       atomic_set(&outp->dp.lt.done, 0);
        return false;
 }
 
@@ -688,18 +678,18 @@ static int
 nvkm_dp_hpd(struct nvkm_notify *notify)
 {
        const struct nvkm_i2c_ntfy_rep *line = notify->data;
-       struct nvkm_dp *dp = container_of(notify, typeof(*dp), hpd);
-       struct nvkm_conn *conn = dp->outp.conn;
-       struct nvkm_disp *disp = dp->outp.disp;
+       struct nvkm_outp *outp = container_of(notify, typeof(*outp), dp.hpd);
+       struct nvkm_conn *conn = outp->conn;
+       struct nvkm_disp *disp = outp->disp;
        struct nvif_notify_conn_rep_v0 rep = {};
 
-       OUTP_DBG(&dp->outp, "HPD: %d", line->mask);
+       OUTP_DBG(outp, "HPD: %d", line->mask);
        if (line->mask & NVKM_I2C_IRQ) {
-               if (atomic_read(&dp->lt.done))
-                       dp->outp.func->acquire(&dp->outp);
+               if (atomic_read(&outp->dp.lt.done))
+                       outp->func->acquire(outp);
                rep.mask |= NVIF_NOTIFY_CONN_V0_IRQ;
        } else {
-               nvkm_dp_enable(dp, true);
+               nvkm_dp_enable(outp, true);
        }
 
        if (line->mask & NVKM_I2C_UNPLUG)
@@ -714,24 +704,22 @@ nvkm_dp_hpd(struct nvkm_notify *notify)
 static void
 nvkm_dp_fini(struct nvkm_outp *outp)
 {
-       struct nvkm_dp *dp = nvkm_dp(outp);
-       nvkm_notify_put(&dp->hpd);
-       nvkm_dp_enable(dp, false);
+       nvkm_notify_put(&outp->dp.hpd);
+       nvkm_dp_enable(outp, false);
 }
 
 static void
 nvkm_dp_init(struct nvkm_outp *outp)
 {
        struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio;
-       struct nvkm_dp *dp = nvkm_dp(outp);
 
-       nvkm_notify_put(&dp->outp.conn->hpd);
+       nvkm_notify_put(&outp->conn->hpd);
 
        /* eDP panels need powering on by us (if the VBIOS doesn't default it
         * to on) before doing any AUX channel transactions.  LVDS panel power
         * is handled by the SOR itself, and not required for LVDS DDC.
         */
-       if (dp->outp.conn->info.type == DCB_CONNECTOR_eDP) {
+       if (outp->conn->info.type == DCB_CONNECTOR_eDP) {
                int power = nvkm_gpio_get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
                if (power == 0)
                        nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
@@ -748,21 +736,20 @@ nvkm_dp_init(struct nvkm_outp *outp)
                /* If the eDP panel can't be detected, we need to restore
                 * the panel power GPIO to avoid breaking another output.
                 */
-               if (!nvkm_dp_enable(dp, true) && power == 0)
+               if (!nvkm_dp_enable(outp, true) && power == 0)
                        nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 0);
        } else {
-               nvkm_dp_enable(dp, true);
+               nvkm_dp_enable(outp, true);
        }
 
-       nvkm_notify_get(&dp->hpd);
+       nvkm_notify_get(&outp->dp.hpd);
 }
 
 static void *
 nvkm_dp_dtor(struct nvkm_outp *outp)
 {
-       struct nvkm_dp *dp = nvkm_dp(outp);
-       nvkm_notify_fini(&dp->hpd);
-       return dp;
+       nvkm_notify_fini(&outp->dp.hpd);
+       return outp;
 }
 
 static const struct nvkm_outp_func
@@ -775,75 +762,57 @@ nvkm_dp_func = {
        .disable = nvkm_dp_disable,
 };
 
-static int
-nvkm_dp_ctor(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
-            struct nvkm_i2c_aux *aux, struct nvkm_dp *dp)
+int
+nvkm_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE, struct nvkm_outp **poutp)
 {
        struct nvkm_device *device = disp->engine.subdev.device;
        struct nvkm_bios *bios = device->bios;
        struct nvkm_i2c *i2c = device->i2c;
+       struct nvkm_outp *outp;
        u8  hdr, cnt, len;
        u32 data;
        int ret;
 
-       ret = nvkm_outp_ctor(&nvkm_dp_func, disp, index, dcbE, &dp->outp);
+       ret = nvkm_outp_new_(&nvkm_dp_func, disp, index, dcbE, poutp);
+       outp = *poutp;
        if (ret)
                return ret;
 
-       dp->aux = aux;
-       if (!dp->aux) {
-               OUTP_ERR(&dp->outp, "no aux");
+       if (dcbE->location == 0)
+               outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_CCB(dcbE->i2c_index));
+       else
+               outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev));
+       if (!outp->dp.aux) {
+               OUTP_ERR(outp, "no aux");
                return -EINVAL;
        }
 
        /* bios data is not optional */
-       data = nvbios_dpout_match(bios, dp->outp.info.hasht,
-                                 dp->outp.info.hashm, &dp->version,
-                                 &hdr, &cnt, &len, &dp->info);
+       data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm,
+                                 &outp->dp.version, &hdr, &cnt, &len, &outp->dp.info);
        if (!data) {
-               OUTP_ERR(&dp->outp, "no bios dp data");
+               OUTP_ERR(outp, "no bios dp data");
                return -EINVAL;
        }
 
-       OUTP_DBG(&dp->outp, "bios dp %02x %02x %02x %02x",
-                dp->version, hdr, cnt, len);
+       OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len);
 
        /* hotplug detect, replaces gpio-based mechanism with aux events */
        ret = nvkm_notify_init(NULL, &i2c->event, nvkm_dp_hpd, true,
                               &(struct nvkm_i2c_ntfy_req) {
                                .mask = NVKM_I2C_PLUG | NVKM_I2C_UNPLUG |
                                        NVKM_I2C_IRQ,
-                               .port = dp->aux->id,
+                               .port = outp->dp.aux->id,
                               },
                               sizeof(struct nvkm_i2c_ntfy_req),
                               sizeof(struct nvkm_i2c_ntfy_rep),
-                              &dp->hpd);
+                              &outp->dp.hpd);
        if (ret) {
-               OUTP_ERR(&dp->outp, "error monitoring aux hpd: %d", ret);
+               OUTP_ERR(outp, "error monitoring aux hpd: %d", ret);
                return ret;
        }
 
-       mutex_init(&dp->mutex);
-       atomic_set(&dp->lt.done, 0);
+       mutex_init(&outp->dp.mutex);
+       atomic_set(&outp->dp.lt.done, 0);
        return 0;
 }
-
-int
-nvkm_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
-           struct nvkm_outp **poutp)
-{
-       struct nvkm_i2c *i2c = disp->engine.subdev.device->i2c;
-       struct nvkm_i2c_aux *aux;
-       struct nvkm_dp *dp;
-
-       if (dcbE->location == 0)
-               aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_CCB(dcbE->i2c_index));
-       else
-               aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev));
-
-       if (!(dp = kzalloc(sizeof(*dp), GFP_KERNEL)))
-               return -ENOMEM;
-       *poutp = &dp->outp;
-
-       return nvkm_dp_ctor(disp, index, dcbE, aux, dp);
-}
index 8e59dd4..1d86baa 100644 (file)
@@ -1,41 +1,8 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVKM_DISP_DP_H__
 #define __NVKM_DISP_DP_H__
-#define nvkm_dp(p) container_of((p), struct nvkm_dp, outp)
 #include "outp.h"
 
-#include <core/notify.h>
-#include <subdev/bios.h>
-#include <subdev/bios/dp.h>
-
-struct nvkm_dp {
-       struct nvkm_outp outp;
-
-       struct nvbios_dpout info;
-       u8 version;
-
-       struct nvkm_i2c_aux *aux;
-
-       struct nvkm_notify hpd;
-       bool present;
-       u8 lttpr[6];
-       u8 lttprs;
-       u8 dpcd[16];
-
-       struct {
-               int dpcd; /* -1, or index into SUPPORTED_LINK_RATES table */
-               u32 rate;
-       } rate[8];
-       int rates;
-       int links;
-
-       struct mutex mutex;
-       struct {
-               atomic_t done;
-               bool mst;
-       } lt;
-};
-
 int nvkm_dp_new(struct nvkm_disp *, int index, struct dcb_output *,
                struct nvkm_outp **);
 void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *);
index 156bbe8..4966a51 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
+#include "hdmi.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+void
+g84_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
+                 u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 ctrl = 0x40000000 * enable |
+                        0x1f000000 /* ??? */ |
+                        max_ac_packet << 16 |
+                        rekey;
+       const u32 hoff = head * 0x800;
+       struct packed_hdmi_infoframe avi_infoframe;
+       struct packed_hdmi_infoframe vendor_infoframe;
+
+       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
+       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
+
+       if (!(ctrl & 0x40000000)) {
+               nvkm_mask(device, 0x6165a4 + hoff, 0x40000000, 0x00000000);
+               nvkm_mask(device, 0x61653c + hoff, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000000);
+               return;
+       }
+
+       /* AVI InfoFrame */
+       nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
+       if (avi_size) {
+               nvkm_wr32(device, 0x616528 + hoff, avi_infoframe.header);
+               nvkm_wr32(device, 0x61652c + hoff, avi_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x616530 + hoff, avi_infoframe.subpack0_high);
+               nvkm_wr32(device, 0x616534 + hoff, avi_infoframe.subpack1_low);
+               nvkm_wr32(device, 0x616538 + hoff, avi_infoframe.subpack1_high);
+               nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000001);
+       }
+
+       /* Audio InfoFrame */
+       nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000000);
+       nvkm_wr32(device, 0x616508 + hoff, 0x000a0184);
+       nvkm_wr32(device, 0x61650c + hoff, 0x00000071);
+       nvkm_wr32(device, 0x616510 + hoff, 0x00000000);
+       nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000001);
+
+       /* Vendor InfoFrame */
+       nvkm_mask(device, 0x61653c + hoff, 0x00010001, 0x00010000);
+       if (vendor_size) {
+               nvkm_wr32(device, 0x616544 + hoff, vendor_infoframe.header);
+               nvkm_wr32(device, 0x616548 + hoff, vendor_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x61654c + hoff, vendor_infoframe.subpack0_high);
+               /* Is there a second (or up to fourth?) set of subpack registers here? */
+               /* nvkm_wr32(device, 0x616550 + hoff, vendor_infoframe->subpack1_low); */
+               /* nvkm_wr32(device, 0x616554 + hoff, vendor_infoframe->subpack1_high); */
+               nvkm_mask(device, 0x61653c + hoff, 0x00010001, 0x00010001);
+       }
+
+       nvkm_mask(device, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
+       nvkm_mask(device, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
+       nvkm_mask(device, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
+
+       /* ??? */
+       nvkm_mask(device, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
+       nvkm_mask(device, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
+       nvkm_mask(device, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
+
+       /* HDMI_CTRL */
+       nvkm_mask(device, 0x6165a4 + hoff, 0x5f1f007f, ctrl);
+}
+
+static const struct nvkm_ior_func
+g84_sor = {
+       .state = nv50_sor_state,
+       .power = nv50_sor_power,
+       .clock = nv50_sor_clock,
+       .hdmi = {
+               .ctrl = g84_sor_hdmi_ctrl,
+       },
+};
+
+int
+g84_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&g84_sor, disp, SOR, id, false);
+}
+
+static const struct nvkm_disp_mthd_list
+g84_disp_ovly_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x000000 },
+               { 0x0084, 0x6109a0 },
+               { 0x0088, 0x6109c0 },
+               { 0x008c, 0x6109c8 },
+               { 0x0090, 0x6109b4 },
+               { 0x0094, 0x610970 },
+               { 0x00a0, 0x610998 },
+               { 0x00a4, 0x610964 },
+               { 0x00c0, 0x610958 },
+               { 0x00e0, 0x6109a8 },
+               { 0x00e4, 0x6109d0 },
+               { 0x00e8, 0x6109d8 },
+               { 0x0100, 0x61094c },
+               { 0x0104, 0x610984 },
+               { 0x0108, 0x61098c },
+               { 0x0800, 0x6109f8 },
+               { 0x0808, 0x610a08 },
+               { 0x080c, 0x610a10 },
+               { 0x0810, 0x610a00 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+g84_disp_ovly_mthd = {
+       .name = "Overlay",
+       .addr = 0x000540,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &g84_disp_ovly_mthd_base },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+g84_disp_ovly = {
+       .func = &nv50_disp_dmac_func,
+       .ctrl = 3,
+       .user = 3,
+       .mthd = &g84_disp_ovly_mthd,
+};
+
+static const struct nvkm_disp_mthd_list
+g84_disp_base_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x000000 },
+               { 0x0084, 0x0008c4 },
+               { 0x0088, 0x0008d0 },
+               { 0x008c, 0x0008dc },
+               { 0x0090, 0x0008e4 },
+               { 0x0094, 0x610884 },
+               { 0x00a0, 0x6108a0 },
+               { 0x00a4, 0x610878 },
+               { 0x00c0, 0x61086c },
+               { 0x00c4, 0x610800 },
+               { 0x00c8, 0x61080c },
+               { 0x00cc, 0x610818 },
+               { 0x00e0, 0x610858 },
+               { 0x00e4, 0x610860 },
+               { 0x00e8, 0x6108ac },
+               { 0x00ec, 0x6108b4 },
+               { 0x00fc, 0x610824 },
+               { 0x0100, 0x610894 },
+               { 0x0104, 0x61082c },
+               { 0x0110, 0x6108bc },
+               { 0x0114, 0x61088c },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+g84_disp_base_mthd = {
+       .name = "Base",
+       .addr = 0x000540,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &g84_disp_base_mthd_base },
+               {  "Image", 2, &nv50_disp_base_mthd_image },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+g84_disp_base = {
+       .func = &nv50_disp_dmac_func,
+       .ctrl = 1,
+       .user = 1,
+       .mthd = &g84_disp_base_mthd,
+};
+
+const struct nvkm_disp_mthd_list
+g84_disp_core_mthd_dac = {
+       .mthd = 0x0080,
+       .addr = 0x000008,
+       .data = {
+               { 0x0400, 0x610b58 },
+               { 0x0404, 0x610bdc },
+               { 0x0420, 0x610bc4 },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+g84_disp_core_mthd_head = {
+       .mthd = 0x0400,
+       .addr = 0x000540,
+       .data = {
+               { 0x0800, 0x610ad8 },
+               { 0x0804, 0x610ad0 },
+               { 0x0808, 0x610a48 },
+               { 0x080c, 0x610a78 },
+               { 0x0810, 0x610ac0 },
+               { 0x0814, 0x610af8 },
+               { 0x0818, 0x610b00 },
+               { 0x081c, 0x610ae8 },
+               { 0x0820, 0x610af0 },
+               { 0x0824, 0x610b08 },
+               { 0x0828, 0x610b10 },
+               { 0x082c, 0x610a68 },
+               { 0x0830, 0x610a60 },
+               { 0x0834, 0x000000 },
+               { 0x0838, 0x610a40 },
+               { 0x0840, 0x610a24 },
+               { 0x0844, 0x610a2c },
+               { 0x0848, 0x610aa8 },
+               { 0x084c, 0x610ab0 },
+               { 0x085c, 0x610c5c },
+               { 0x0860, 0x610a84 },
+               { 0x0864, 0x610a90 },
+               { 0x0868, 0x610b18 },
+               { 0x086c, 0x610b20 },
+               { 0x0870, 0x610ac8 },
+               { 0x0874, 0x610a38 },
+               { 0x0878, 0x610c50 },
+               { 0x0880, 0x610a58 },
+               { 0x0884, 0x610a9c },
+               { 0x089c, 0x610c68 },
+               { 0x08a0, 0x610a70 },
+               { 0x08a4, 0x610a50 },
+               { 0x08a8, 0x610ae0 },
+               { 0x08c0, 0x610b28 },
+               { 0x08c4, 0x610b30 },
+               { 0x08c8, 0x610b40 },
+               { 0x08d4, 0x610b38 },
+               { 0x08d8, 0x610b48 },
+               { 0x08dc, 0x610b50 },
+               { 0x0900, 0x610a18 },
+               { 0x0904, 0x610ab8 },
+               { 0x0910, 0x610c70 },
+               { 0x0914, 0x610c78 },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_mthd
+g84_disp_core_mthd = {
+       .name = "Core",
+       .addr = 0x000000,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &nv50_disp_core_mthd_base },
+               {    "DAC", 3, &g84_disp_core_mthd_dac  },
+               {    "SOR", 2, &nv50_disp_core_mthd_sor  },
+               {   "PIOR", 3, &nv50_disp_core_mthd_pior },
+               {   "HEAD", 2, &g84_disp_core_mthd_head },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+g84_disp_core = {
+       .func = &nv50_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &g84_disp_core_mthd,
+};
+
+static const struct nvkm_disp_func
 g84_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &g84_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = nv50_sor_cnt, .new = g84_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0,0,G82_DISP },
+       .user = {
+               {{0,0,G82_DISP_CURSOR             }, nvkm_disp_chan_new, &nv50_disp_curs },
+               {{0,0,G82_DISP_OVERLAY            }, nvkm_disp_chan_new, &nv50_disp_oimm },
+               {{0,0,G82_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, & g84_disp_base },
+               {{0,0,G82_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, & g84_disp_core },
+               {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, & g84_disp_ovly },
+               {}
+       },
 };
 
 int
 g84_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
             struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&g84_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&g84_disp, device, type, inst, pdisp);
 }
index 3425b5d..a4853c4 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
+
+void
+g94_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 loff = nv50_sor_link(sor);
+
+       nvkm_mask(device, 0x61c128 + loff, 0x0000003f, watermark);
+}
+
+void
+g94_sor_dp_activesym(struct nvkm_ior *sor, int head,
+                    u8 TU, u8 VTUa, u8 VTUf, u8 VTUi)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 loff = nv50_sor_link(sor);
+
+       nvkm_mask(device, 0x61c10c + loff, 0x000001fc, TU << 2);
+       nvkm_mask(device, 0x61c128 + loff, 0x010f7f00, VTUa << 24 | VTUf << 16 | VTUi << 8);
+}
+
+void
+g94_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+
+       nvkm_mask(device, 0x61c1e8 + soff, 0x0000ffff, h);
+       nvkm_mask(device, 0x61c1ec + soff, 0x00ffffff, v);
+}
+
+void
+g94_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  loff = nv50_sor_link(sor);
+       const u32 shift = sor->func->dp->lanes[ln] * 8;
+       u32 data[3];
+
+       data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
+       data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
+       data[2] = nvkm_rd32(device, 0x61c130 + loff);
+       if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
+               data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
+
+       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
+       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
+       nvkm_wr32(device, 0x61c130 + loff, data[2]);
+}
+
+void
+g94_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 loff = nv50_sor_link(sor);
+       u32 data;
+
+       switch (pattern) {
+       case 0: data = 0x00001000; break;
+       case 1: data = 0x01000000; break;
+       case 2: data = 0x02000000; break;
+       default:
+               WARN_ON(1);
+               return;
+       }
+
+       nvkm_mask(device, 0x61c10c + loff, 0x0f001000, data);
+}
+
+void
+g94_sor_dp_power(struct nvkm_ior *sor, int nr)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       const u32 loff = nv50_sor_link(sor);
+       u32 mask = 0, i;
+
+       for (i = 0; i < nr; i++)
+               mask |= 1 << sor->func->dp->lanes[i];
+
+       nvkm_mask(device, 0x61c130 + loff, 0x0000000f, mask);
+       nvkm_mask(device, 0x61c034 + soff, 0x80000000, 0x80000000);
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x61c034 + soff) & 0x80000000))
+                       break;
+       );
+}
+
+int
+g94_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       const u32 loff = nv50_sor_link(sor);
+       u32 dpctrl = 0x00000000;
+       u32 clksor = 0x00000000;
+
+       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
+       if (sor->dp.ef)
+               dpctrl |= 0x00004000;
+       if (sor->dp.bw > 0x06)
+               clksor |= 0x00040000;
+
+       nvkm_mask(device, 0x614300 + soff, 0x000c0000, clksor);
+       nvkm_mask(device, 0x61c10c + loff, 0x001f4000, dpctrl);
+       return 0;
+}
+
+const struct nvkm_ior_func_dp
+g94_sor_dp = {
+       .lanes = { 2, 1, 0, 3},
+       .links = g94_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = g94_sor_dp_pattern,
+       .drive = g94_sor_dp_drive,
+       .audio_sym = g94_sor_dp_audio_sym,
+       .activesym = g94_sor_dp_activesym,
+       .watermark = g94_sor_dp_watermark,
+};
+
+static bool
+g94_sor_war_needed(struct nvkm_ior *sor)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+
+       if (sor->asy.proto == TMDS) {
+               switch (nvkm_rd32(device, 0x614300 + soff) & 0x00030000) {
+               case 0x00000000:
+               case 0x00030000:
+                       return true;
+               default:
+                       break;
+               }
+       }
+
+       return false;
+}
+
+static void
+g94_sor_war_update_sppll1(struct nvkm_disp *disp)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       struct nvkm_ior *ior;
+       bool used = false;
+       u32 clksor;
+
+       list_for_each_entry(ior, &disp->iors, head) {
+               if (ior->type != SOR)
+                       continue;
+
+               clksor = nvkm_rd32(device, 0x614300 + nv50_ior_base(ior));
+               switch (clksor & 0x03000000) {
+               case 0x02000000:
+               case 0x03000000:
+                       used = true;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (used)
+               return;
+
+       nvkm_mask(device, 0x00e840, 0x80000000, 0x00000000);
+}
+
+static void
+g94_sor_war_3(struct nvkm_ior *sor)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       u32 sorpwr;
+
+       if (!g94_sor_war_needed(sor))
+               return;
+
+       sorpwr = nvkm_rd32(device, 0x61c004 + soff);
+       if (sorpwr & 0x00000001) {
+               u32 seqctl = nvkm_rd32(device, 0x61c030 + soff);
+               u32  pd_pc = (seqctl & 0x00000f00) >> 8;
+               u32  pu_pc =  seqctl & 0x0000000f;
+
+               nvkm_wr32(device, 0x61c040 + soff + pd_pc * 4, 0x1f008000);
+
+               nvkm_msec(device, 2000,
+                       if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
+                               break;
+               );
+               nvkm_mask(device, 0x61c004 + soff, 0x80000001, 0x80000000);
+               nvkm_msec(device, 2000,
+                       if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
+                               break;
+               );
+
+               nvkm_wr32(device, 0x61c040 + soff + pd_pc * 4, 0x00002000);
+               nvkm_wr32(device, 0x61c040 + soff + pu_pc * 4, 0x1f000000);
+       }
+
+       nvkm_mask(device, 0x61c10c + soff, 0x00000001, 0x00000000);
+       nvkm_mask(device, 0x614300 + soff, 0x03000000, 0x00000000);
+
+       if (sorpwr & 0x00000001)
+               nvkm_mask(device, 0x61c004 + soff, 0x80000001, 0x80000001);
+
+       g94_sor_war_update_sppll1(sor->disp);
+}
+
+static void
+g94_sor_war_2(struct nvkm_ior *sor)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+
+       if (!g94_sor_war_needed(sor))
+               return;
+
+       nvkm_mask(device, 0x00e840, 0x80000000, 0x80000000);
+       nvkm_mask(device, 0x614300 + soff, 0x03000000, 0x03000000);
+       nvkm_mask(device, 0x61c10c + soff, 0x00000001, 0x00000001);
+
+       nvkm_mask(device, 0x61c00c + soff, 0x0f000000, 0x00000000);
+       nvkm_mask(device, 0x61c008 + soff, 0xff000000, 0x14000000);
+       nvkm_usec(device, 400, NVKM_DELAY);
+       nvkm_mask(device, 0x61c008 + soff, 0xff000000, 0x00000000);
+       nvkm_mask(device, 0x61c00c + soff, 0x0f000000, 0x01000000);
+
+       if (nvkm_rd32(device, 0x61c004 + soff) & 0x00000001) {
+               u32 seqctl = nvkm_rd32(device, 0x61c030 + soff);
+               u32  pu_pc = seqctl & 0x0000000f;
+               nvkm_wr32(device, 0x61c040 + soff + pu_pc * 4, 0x1f008000);
+       }
+}
+
+void
+g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = sor->id * 8 + (state == &sor->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610794 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       case 8: state->proto =   DP; state->link = 1; break;
+       case 9: state->proto =   DP; state->link = 2; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x00000003;
+       nv50_pior_depth(sor, state, ctrl);
+}
+
+static const struct nvkm_ior_func
+g94_sor = {
+       .state = g94_sor_state,
+       .power = nv50_sor_power,
+       .clock = nv50_sor_clock,
+       .war_2 = g94_sor_war_2,
+       .war_3 = g94_sor_war_3,
+       .dp = &g94_sor_dp,
+};
+
+static int
+g94_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&g94_sor, disp, SOR, id, false);
+}
+
+int
+g94_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+
+       *pmask = (nvkm_rd32(device, 0x610184) & 0x0f000000) >> 24;
+       return 4;
+}
+
+static const struct nvkm_disp_mthd_list
+g94_disp_core_mthd_sor = {
+       .mthd = 0x0040,
+       .addr = 0x000008,
+       .data = {
+               { 0x0600, 0x610794 },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_mthd
+g94_disp_core_mthd = {
+       .name = "Core",
+       .addr = 0x000000,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &nv50_disp_core_mthd_base },
+               {    "DAC", 3, &g84_disp_core_mthd_dac },
+               {    "SOR", 4, &g94_disp_core_mthd_sor },
+               {   "PIOR", 3, &nv50_disp_core_mthd_pior },
+               {   "HEAD", 2, &g84_disp_core_mthd_head },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+g94_disp_core = {
+       .func = &nv50_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &g94_disp_core_mthd,
+};
+
+static const struct nvkm_disp_func
 g94_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &g94_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = g94_sor_cnt, .new = g94_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0,0,GT206_DISP },
+       .user = {
+               {{0,0,  G82_DISP_CURSOR             }, nvkm_disp_chan_new, & nv50_disp_curs },
+               {{0,0,  G82_DISP_OVERLAY            }, nvkm_disp_chan_new, & nv50_disp_oimm },
+               {{0,0,GT200_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &  g84_disp_base },
+               {{0,0,GT206_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &  g94_disp_core },
+               {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, &gt200_disp_ovly },
+               {}
+       },
 };
 
 int
 g94_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
             struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&g94_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&g94_disp, device, type, inst, pdisp);
 }
index 68aa525..7489d0d 100644 (file)
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "channv50.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
+
+static int
+ga102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       const u32 loff = nv50_sor_link(sor);
+       u32 dpctrl = 0x00000000;
+       u32 clksor = 0x00000000;
+
+       switch (sor->dp.bw) {
+       case 0x06: clksor |= 0x00000000; break;
+       case 0x0a: clksor |= 0x00040000; break;
+       case 0x14: clksor |= 0x00080000; break;
+       case 0x1e: clksor |= 0x000c0000; break;
+       case 0x08: clksor |= 0x00100000; break;
+       case 0x09: clksor |= 0x00140000; break;
+       case 0x0c: clksor |= 0x00180000; break;
+       case 0x10: clksor |= 0x001c0000; break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
+       if (sor->dp.mst)
+               dpctrl |= 0x40000000;
+       if (sor->dp.ef)
+               dpctrl |= 0x00004000;
+
+       nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
+
+       /*XXX*/
+       nvkm_msec(device, 40, NVKM_DELAY);
+       nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000);
+       nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001);
+
+       nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
+       return 0;
+}
+
+static const struct nvkm_ior_func_dp
+ga102_sor_dp = {
+       .lanes = { 0, 1, 2, 3 },
+       .links = ga102_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = gm107_sor_dp_pattern,
+       .drive = gm200_sor_dp_drive,
+       .vcpi = tu102_sor_dp_vcpi,
+       .audio = gv100_sor_dp_audio,
+       .audio_sym = gv100_sor_dp_audio_sym,
+       .watermark = gv100_sor_dp_watermark,
+};
+
+static void
+ga102_sor_clock(struct nvkm_ior *sor)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       u32 div2 = 0;
+
+       if (sor->asy.proto == TMDS) {
+               if (sor->tmds.high_speed)
+                       div2 = 1;
+       }
+
+       nvkm_wr32(device, 0x00ec08 + (sor->id * 0x10), 0x00000000);
+       nvkm_wr32(device, 0x00ec04 + (sor->id * 0x10), div2);
+}
+
+static const struct nvkm_ior_func
+ga102_sor = {
+       .route = {
+               .get = gm200_sor_route_get,
+               .set = gm200_sor_route_set,
+       },
+       .state = gv100_sor_state,
+       .power = nv50_sor_power,
+       .clock = ga102_sor_clock,
+       .hdmi = {
+               .ctrl = gv100_sor_hdmi_ctrl,
+               .scdc = gm200_sor_hdmi_scdc,
+       },
+       .dp = &ga102_sor_dp,
+       .hda = &gv100_sor_hda,
+};
+
+static int
+ga102_sor_new(struct nvkm_disp *disp, int id)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       u32 hda = nvkm_rd32(device, 0x08a15c);
+
+       return nvkm_ior_new_(&ga102_sor, disp, SOR, id, hda & BIT(id));
+}
+
+static const struct nvkm_disp_func
 ga102_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = tu102_disp_init,
        .fini = gv100_disp_fini,
        .intr = gv100_disp_intr,
-       .uevent = &gv100_disp_chan_uevent,
        .super = gv100_disp_super,
-       .root = &ga102_disp_root_oclass,
+       .uevent = &gv100_disp_chan_uevent,
        .wndw = { .cnt = gv100_disp_wndw_cnt },
        .head = { .cnt = gv100_head_cnt, .new = gv100_head_new },
        .sor = { .cnt = gv100_sor_cnt, .new = ga102_sor_new },
        .ramht_size = 0x2000,
+       .root = {  0, 0,GA102_DISP },
+       .user = {
+               {{-1,-1,GV100_DISP_CAPS                  }, gv100_disp_caps_new },
+               {{ 0, 0,GA102_DISP_CURSOR                }, nvkm_disp_chan_new, &gv100_disp_curs },
+               {{ 0, 0,GA102_DISP_WINDOW_IMM_CHANNEL_DMA}, nvkm_disp_wndw_new, &gv100_disp_wimm },
+               {{ 0, 0,GA102_DISP_CORE_CHANNEL_DMA      }, nvkm_disp_core_new, &gv100_disp_core },
+               {{ 0, 0,GA102_DISP_WINDOW_CHANNEL_DMA    }, nvkm_disp_wndw_new, &gv100_disp_wndw },
+               {}
+       },
 };
 
 int
 ga102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&ga102_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&ga102_disp, device, type, inst, pdisp);
 }
index a6bafe7..39822f1 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
+#include "hdmi.h"
 #include "head.h"
 #include "ior.h"
-#include "channv50.h"
-#include "rootnv50.h"
+#include "outp.h"
 
 #include <core/ramht.h>
 #include <subdev/timer.h>
 
+#include <nvif/class.h>
+
+static void
+gf119_sor_hda_device_entry(struct nvkm_ior *ior, int head)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 hoff = 0x800 * head;
+
+       nvkm_mask(device, 0x616548 + hoff, 0x00000070, head << 4);
+}
+
+void
+gf119_sor_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = 0x030 * ior->id + (head * 0x04);
+       int i;
+
+       for (i = 0; i < size; i++)
+               nvkm_wr32(device, 0x10ec00 + soff, (i << 8) | data[i]);
+       for (; i < 0x60; i++)
+               nvkm_wr32(device, 0x10ec00 + soff, (i << 8));
+       nvkm_mask(device, 0x10ec10 + soff, 0x80000002, 0x80000002);
+}
+
+void
+gf119_sor_hda_hpd(struct nvkm_ior *ior, int head, bool present)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = 0x030 * ior->id + (head * 0x04);
+       u32 data = 0x80000000;
+       u32 mask = 0x80000001;
+
+       if (present) {
+               ior->func->hda->device_entry(ior, head);
+               data |= 0x00000001;
+       } else {
+               mask |= 0x00000002;
+       }
+
+       nvkm_mask(device, 0x10ec10 + soff, mask, data);
+}
+
+const struct nvkm_ior_func_hda
+gf119_sor_hda = {
+       .hpd = gf119_sor_hda_hpd,
+       .eld = gf119_sor_hda_eld,
+       .device_entry = gf119_sor_hda_device_entry,
+};
+
+void
+gf119_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = head * 0x800;
+
+       nvkm_mask(device, 0x616610 + hoff, 0x0800003f, 0x08000000 | watermark);
+}
+
+void
+gf119_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = head * 0x800;
+
+       nvkm_mask(device, 0x616620 + hoff, 0x0000ffff, h);
+       nvkm_mask(device, 0x616624 + hoff, 0x00ffffff, v);
+}
+
+void
+gf119_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = 0x800 * head;
+       const u32 data = 0x80000000 | (0x00000001 * enable);
+       const u32 mask = 0x8000000d;
+
+       nvkm_mask(device, 0x616618 + hoff, mask, data);
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x616618 + hoff) & 0x80000000))
+                       break;
+       );
+}
+
+void
+gf119_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = head * 0x800;
+
+       nvkm_mask(device, 0x616588 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
+       nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn);
+}
+
+void
+gf119_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  loff = nv50_sor_link(sor);
+       const u32 shift = sor->func->dp->lanes[ln] * 8;
+       u32 data[4];
+
+       data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
+       data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
+       data[2] = nvkm_rd32(device, 0x61c130 + loff);
+       if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
+               data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
+
+       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
+       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
+       nvkm_wr32(device, 0x61c130 + loff, data[2]);
+
+       data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
+       nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
+}
+
+static void
+gf119_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       u32 data;
+
+       switch (pattern) {
+       case 0: data = 0x10101010; break;
+       case 1: data = 0x01010101; break;
+       case 2: data = 0x02020202; break;
+       case 3: data = 0x03030303; break;
+       default:
+               WARN_ON(1);
+               return;
+       }
+
+       nvkm_mask(device, 0x61c110 + soff, 0x1f1f1f1f, data);
+}
+
+int
+gf119_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       const u32 loff = nv50_sor_link(sor);
+       u32 dpctrl = 0x00000000;
+       u32 clksor = 0x00000000;
+
+       clksor |= sor->dp.bw << 18;
+       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
+       if (sor->dp.mst)
+               dpctrl |= 0x40000000;
+       if (sor->dp.ef)
+               dpctrl |= 0x00004000;
+
+       nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
+       nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
+       return 0;
+}
+
+const struct nvkm_ior_func_dp
+gf119_sor_dp = {
+       .lanes = { 2, 1, 0, 3 },
+       .links = gf119_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = gf119_sor_dp_pattern,
+       .drive = gf119_sor_dp_drive,
+       .vcpi = gf119_sor_dp_vcpi,
+       .audio = gf119_sor_dp_audio,
+       .audio_sym = gf119_sor_dp_audio_sym,
+       .watermark = gf119_sor_dp_watermark,
+};
+
+static void
+gf119_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
+                   u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 ctrl = 0x40000000 * enable |
+                        max_ac_packet << 16 |
+                        rekey;
+       const u32 hoff = head * 0x800;
+       struct packed_hdmi_infoframe avi_infoframe;
+       struct packed_hdmi_infoframe vendor_infoframe;
+
+       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
+       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
+
+       if (!(ctrl & 0x40000000)) {
+               nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
+               nvkm_mask(device, 0x616730 + hoff, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x616714 + hoff, 0x00000001, 0x00000000);
+               return;
+       }
+
+       /* AVI InfoFrame */
+       nvkm_mask(device, 0x616714 + hoff, 0x00000001, 0x00000000);
+       if (avi_size) {
+               nvkm_wr32(device, 0x61671c + hoff, avi_infoframe.header);
+               nvkm_wr32(device, 0x616720 + hoff, avi_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x616724 + hoff, avi_infoframe.subpack0_high);
+               nvkm_wr32(device, 0x616728 + hoff, avi_infoframe.subpack1_low);
+               nvkm_wr32(device, 0x61672c + hoff, avi_infoframe.subpack1_high);
+               nvkm_mask(device, 0x616714 + hoff, 0x00000001, 0x00000001);
+       }
+
+       /* GENERIC(?) / Vendor InfoFrame? */
+       nvkm_mask(device, 0x616730 + hoff, 0x00010001, 0x00010000);
+       if (vendor_size) {
+               /*
+                * These appear to be the audio infoframe registers,
+                * but no other set of infoframe registers has yet
+                * been found.
+                */
+               nvkm_wr32(device, 0x616738 + hoff, vendor_infoframe.header);
+               nvkm_wr32(device, 0x61673c + hoff, vendor_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x616740 + hoff, vendor_infoframe.subpack0_high);
+               /* Is there a second (or further?) set of subpack registers here? */
+               nvkm_mask(device, 0x616730 + hoff, 0x00000001, 0x00000001);
+       }
+
+       /* ??? InfoFrame? */
+       nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000000);
+       nvkm_wr32(device, 0x6167ac + hoff, 0x00000010);
+       nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000001);
+
+       /* HDMI_CTRL */
+       nvkm_mask(device, 0x616798 + hoff, 0x401f007f, ctrl);
+}
+
+void
+gf119_sor_clock(struct nvkm_ior *sor)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       u32 div1 = sor->asy.link == 3;
+       u32 div2 = sor->asy.link == 3;
+
+       if (sor->asy.proto == TMDS) {
+               const u32 speed = sor->tmds.high_speed ? 0x14 : 0x0a;
+               nvkm_mask(device, 0x612300 + soff, 0x007c0000, speed << 18);
+               if (sor->tmds.high_speed)
+                       div2 = 1;
+       }
+
+       nvkm_mask(device, 0x612300 + soff, 0x00000707, (div2 << 8) | div1);
+}
+
+void
+gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = (state == &sor->asy) * 0x20000 + sor->id * 0x20;
+       u32 ctrl = nvkm_rd32(device, 0x640200 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       case 8: state->proto =   DP; state->link = 1; break;
+       case 9: state->proto =   DP; state->link = 2; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x0000000f;
+}
+
+static const struct nvkm_ior_func
+gf119_sor = {
+       .state = gf119_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gf119_sor_hdmi_ctrl,
+       },
+       .dp = &gf119_sor_dp,
+       .hda = &gf119_sor_hda,
+};
+
+static int
+gf119_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&gf119_sor, disp, SOR, id, true);
+}
+
+int
+gf119_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       *pmask = (nvkm_rd32(device, 0x612004) & 0x0000ff00) >> 8;
+       return 8;
+}
+
+static void
+gf119_dac_clock(struct nvkm_ior *dac)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 doff = nv50_ior_base(dac);
+       nvkm_mask(device, 0x612280 + doff, 0x07070707, 0x00000000);
+}
+
+static void
+gf119_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 coff = (state == &dac->asy) * 0x20000 + dac->id * 0x20;
+       u32 ctrl = nvkm_rd32(device, 0x640180 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = CRT; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x0000000f;
+}
+
+static const struct nvkm_ior_func
+gf119_dac = {
+       .state = gf119_dac_state,
+       .power = nv50_dac_power,
+       .sense = nv50_dac_sense,
+       .clock = gf119_dac_clock,
+};
+
+int
+gf119_dac_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&gf119_dac, disp, DAC, id, false);
+}
+
+int
+gf119_dac_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       *pmask = (nvkm_rd32(device, 0x612004) & 0x000000f0) >> 4;
+       return 4;
+}
+
+static void
+gf119_head_vblank_put(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = head->id * 0x800;
+       nvkm_mask(device, 0x6100c0 + hoff, 0x00000001, 0x00000000);
+}
+
+static void
+gf119_head_vblank_get(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = head->id * 0x800;
+       nvkm_mask(device, 0x6100c0 + hoff, 0x00000001, 0x00000001);
+}
+
+void
+gf119_head_rgclk(struct nvkm_head *head, int div)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       nvkm_mask(device, 0x612200 + (head->id * 0x800), 0x0000000f, div);
+}
+
+static void
+gf119_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = (state == &head->asy) * 0x20000 + head->id * 0x300;
+       u32 data;
+
+       data = nvkm_rd32(device, 0x640414 + hoff);
+       state->vtotal = (data & 0xffff0000) >> 16;
+       state->htotal = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x640418 + hoff);
+       state->vsynce = (data & 0xffff0000) >> 16;
+       state->hsynce = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x64041c + hoff);
+       state->vblanke = (data & 0xffff0000) >> 16;
+       state->hblanke = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x640420 + hoff);
+       state->vblanks = (data & 0xffff0000) >> 16;
+       state->hblanks = (data & 0x0000ffff);
+       state->hz = nvkm_rd32(device, 0x640450 + hoff);
+
+       data = nvkm_rd32(device, 0x640404 + hoff);
+       switch ((data & 0x000003c0) >> 6) {
+       case 6: state->or.depth = 30; break;
+       case 5: state->or.depth = 24; break;
+       case 2: state->or.depth = 18; break;
+       case 0: state->or.depth = 18; break; /*XXX: "default" */
+       default:
+               state->or.depth = 18;
+               WARN_ON(1);
+               break;
+       }
+}
+
+static const struct nvkm_head_func
+gf119_head = {
+       .state = gf119_head_state,
+       .rgpos = nv50_head_rgpos,
+       .rgclk = gf119_head_rgclk,
+       .vblank_get = gf119_head_vblank_get,
+       .vblank_put = gf119_head_vblank_put,
+};
+
+int
+gf119_head_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_head_new_(&gf119_head, disp, id);
+}
+
+int
+gf119_head_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       *pmask = nvkm_rd32(device, 0x612004) & 0x0000000f;
+       return nvkm_rd32(device, 0x022448);
+}
+
+static void
+gf119_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
+{
+       struct nvkm_disp *disp = container_of(event, typeof(*disp), uevent);
+       struct nvkm_device *device = disp->engine.subdev.device;
+       nvkm_mask(device, 0x610090, 0x00000001 << index, 0x00000000 << index);
+       nvkm_wr32(device, 0x61008c, 0x00000001 << index);
+}
+
+static void
+gf119_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
+{
+       struct nvkm_disp *disp = container_of(event, typeof(*disp), uevent);
+       struct nvkm_device *device = disp->engine.subdev.device;
+       nvkm_wr32(device, 0x61008c, 0x00000001 << index);
+       nvkm_mask(device, 0x610090, 0x00000001 << index, 0x00000001 << index);
+}
+
+const struct nvkm_event_func
+gf119_disp_chan_uevent = {
+       .init = gf119_disp_chan_uevent_init,
+       .fini = gf119_disp_chan_uevent_fini,
+};
+
+void
+gf119_disp_chan_intr(struct nvkm_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 mask = 0x00000001 << chan->chid.user;
+       if (!en) {
+               nvkm_mask(device, 0x610090, mask, 0x00000000);
+               nvkm_mask(device, 0x6100a0, mask, 0x00000000);
+       } else {
+               nvkm_mask(device, 0x6100a0, mask, mask);
+       }
+}
+
+static void
+gf119_disp_pioc_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_disp *disp = chan->disp;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       nvkm_mask(device, 0x610490 + (ctrl * 0x10), 0x00000001, 0x00000000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x00030000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d fini: %08x\n", user,
+                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
+       }
+}
+
+static int
+gf119_disp_pioc_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_disp *disp = chan->disp;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       /* activate channel */
+       nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001);
+       if (nvkm_msec(device, 2000,
+               u32 tmp = nvkm_rd32(device, 0x610490 + (ctrl * 0x10));
+               if ((tmp & 0x00030000) == 0x00010000)
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d init: %08x\n", user,
+                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+const struct nvkm_disp_chan_func
+gf119_disp_pioc_func = {
+       .init = gf119_disp_pioc_init,
+       .fini = gf119_disp_pioc_fini,
+       .intr = gf119_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+};
+
+int
+gf119_disp_dmac_bind(struct nvkm_disp_chan *chan, struct nvkm_object *object, u32 handle)
+{
+       return nvkm_ramht_insert(chan->disp->ramht, object, chan->chid.user, -9, handle,
+                                chan->chid.user << 27 | 0x00000001);
+}
+
+void
+gf119_disp_dmac_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       /* deactivate channel */
+       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000);
+       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000003, 0x00000000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x001e0000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d fini: %08x\n", user,
+                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
+       }
+
+       chan->suspend_put = nvkm_rd32(device, 0x640000 + (ctrl * 0x1000));
+}
+
+static int
+gf119_disp_dmac_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       /* initialise channel for dma command submission */
+       nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
+       nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
+       nvkm_wr32(device, 0x61049c + (ctrl * 0x0010), 0x00000001);
+       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), chan->suspend_put);
+       nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
+
+       /* wait for it to go inactive */
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d init: %08x\n", user,
+                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+const struct nvkm_disp_chan_func
+gf119_disp_dmac_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gf119_disp_dmac_init,
+       .fini = gf119_disp_dmac_fini,
+       .intr = gf119_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+       .bind = gf119_disp_dmac_bind,
+};
+
+const struct nvkm_disp_chan_user
+gf119_disp_curs = {
+       .func = &gf119_disp_pioc_func,
+       .ctrl = 13,
+       .user = 13,
+};
+
+const struct nvkm_disp_chan_user
+gf119_disp_oimm = {
+       .func = &gf119_disp_pioc_func,
+       .ctrl = 9,
+       .user = 9,
+};
+
+static const struct nvkm_disp_mthd_list
+gf119_disp_ovly_mthd_base = {
+       .mthd = 0x0000,
+       .data = {
+               { 0x0080, 0x665080 },
+               { 0x0084, 0x665084 },
+               { 0x0088, 0x665088 },
+               { 0x008c, 0x66508c },
+               { 0x0090, 0x665090 },
+               { 0x0094, 0x665094 },
+               { 0x00a0, 0x6650a0 },
+               { 0x00a4, 0x6650a4 },
+               { 0x00b0, 0x6650b0 },
+               { 0x00b4, 0x6650b4 },
+               { 0x00b8, 0x6650b8 },
+               { 0x00c0, 0x6650c0 },
+               { 0x00e0, 0x6650e0 },
+               { 0x00e4, 0x6650e4 },
+               { 0x00e8, 0x6650e8 },
+               { 0x0100, 0x665100 },
+               { 0x0104, 0x665104 },
+               { 0x0108, 0x665108 },
+               { 0x010c, 0x66510c },
+               { 0x0110, 0x665110 },
+               { 0x0118, 0x665118 },
+               { 0x011c, 0x66511c },
+               { 0x0120, 0x665120 },
+               { 0x0124, 0x665124 },
+               { 0x0130, 0x665130 },
+               { 0x0134, 0x665134 },
+               { 0x0138, 0x665138 },
+               { 0x013c, 0x66513c },
+               { 0x0140, 0x665140 },
+               { 0x0144, 0x665144 },
+               { 0x0148, 0x665148 },
+               { 0x014c, 0x66514c },
+               { 0x0150, 0x665150 },
+               { 0x0154, 0x665154 },
+               { 0x0158, 0x665158 },
+               { 0x015c, 0x66515c },
+               { 0x0160, 0x665160 },
+               { 0x0164, 0x665164 },
+               { 0x0168, 0x665168 },
+               { 0x016c, 0x66516c },
+               { 0x0400, 0x665400 },
+               { 0x0408, 0x665408 },
+               { 0x040c, 0x66540c },
+               { 0x0410, 0x665410 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+gf119_disp_ovly_mthd = {
+       .name = "Overlay",
+       .addr = 0x001000,
+       .prev = -0x020000,
+       .data = {
+               { "Global", 1, &gf119_disp_ovly_mthd_base },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_user
+gf119_disp_ovly = {
+       .func = &gf119_disp_dmac_func,
+       .ctrl = 5,
+       .user = 5,
+       .mthd = &gf119_disp_ovly_mthd,
+};
+
+static const struct nvkm_disp_mthd_list
+gf119_disp_base_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x661080 },
+               { 0x0084, 0x661084 },
+               { 0x0088, 0x661088 },
+               { 0x008c, 0x66108c },
+               { 0x0090, 0x661090 },
+               { 0x0094, 0x661094 },
+               { 0x00a0, 0x6610a0 },
+               { 0x00a4, 0x6610a4 },
+               { 0x00c0, 0x6610c0 },
+               { 0x00c4, 0x6610c4 },
+               { 0x00c8, 0x6610c8 },
+               { 0x00cc, 0x6610cc },
+               { 0x00e0, 0x6610e0 },
+               { 0x00e4, 0x6610e4 },
+               { 0x00e8, 0x6610e8 },
+               { 0x00ec, 0x6610ec },
+               { 0x00fc, 0x6610fc },
+               { 0x0100, 0x661100 },
+               { 0x0104, 0x661104 },
+               { 0x0108, 0x661108 },
+               { 0x010c, 0x66110c },
+               { 0x0110, 0x661110 },
+               { 0x0114, 0x661114 },
+               { 0x0118, 0x661118 },
+               { 0x011c, 0x66111c },
+               { 0x0130, 0x661130 },
+               { 0x0134, 0x661134 },
+               { 0x0138, 0x661138 },
+               { 0x013c, 0x66113c },
+               { 0x0140, 0x661140 },
+               { 0x0144, 0x661144 },
+               { 0x0148, 0x661148 },
+               { 0x014c, 0x66114c },
+               { 0x0150, 0x661150 },
+               { 0x0154, 0x661154 },
+               { 0x0158, 0x661158 },
+               { 0x015c, 0x66115c },
+               { 0x0160, 0x661160 },
+               { 0x0164, 0x661164 },
+               { 0x0168, 0x661168 },
+               { 0x016c, 0x66116c },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+gf119_disp_base_mthd_image = {
+       .mthd = 0x0020,
+       .addr = 0x000020,
+       .data = {
+               { 0x0400, 0x661400 },
+               { 0x0404, 0x661404 },
+               { 0x0408, 0x661408 },
+               { 0x040c, 0x66140c },
+               { 0x0410, 0x661410 },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_mthd
+gf119_disp_base_mthd = {
+       .name = "Base",
+       .addr = 0x001000,
+       .prev = -0x020000,
+       .data = {
+               { "Global", 1, &gf119_disp_base_mthd_base },
+               {  "Image", 2, &gf119_disp_base_mthd_image },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+gf119_disp_base = {
+       .func = &gf119_disp_dmac_func,
+       .ctrl = 1,
+       .user = 1,
+       .mthd = &gf119_disp_base_mthd,
+};
+
+const struct nvkm_disp_mthd_list
+gf119_disp_core_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x660080 },
+               { 0x0084, 0x660084 },
+               { 0x0088, 0x660088 },
+               { 0x008c, 0x000000 },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+gf119_disp_core_mthd_dac = {
+       .mthd = 0x0020,
+       .addr = 0x000020,
+       .data = {
+               { 0x0180, 0x660180 },
+               { 0x0184, 0x660184 },
+               { 0x0188, 0x660188 },
+               { 0x0190, 0x660190 },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+gf119_disp_core_mthd_sor = {
+       .mthd = 0x0020,
+       .addr = 0x000020,
+       .data = {
+               { 0x0200, 0x660200 },
+               { 0x0204, 0x660204 },
+               { 0x0208, 0x660208 },
+               { 0x0210, 0x660210 },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+gf119_disp_core_mthd_pior = {
+       .mthd = 0x0020,
+       .addr = 0x000020,
+       .data = {
+               { 0x0300, 0x660300 },
+               { 0x0304, 0x660304 },
+               { 0x0308, 0x660308 },
+               { 0x0310, 0x660310 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+gf119_disp_core_mthd_head = {
+       .mthd = 0x0300,
+       .addr = 0x000300,
+       .data = {
+               { 0x0400, 0x660400 },
+               { 0x0404, 0x660404 },
+               { 0x0408, 0x660408 },
+               { 0x040c, 0x66040c },
+               { 0x0410, 0x660410 },
+               { 0x0414, 0x660414 },
+               { 0x0418, 0x660418 },
+               { 0x041c, 0x66041c },
+               { 0x0420, 0x660420 },
+               { 0x0424, 0x660424 },
+               { 0x0428, 0x660428 },
+               { 0x042c, 0x66042c },
+               { 0x0430, 0x660430 },
+               { 0x0434, 0x660434 },
+               { 0x0438, 0x660438 },
+               { 0x0440, 0x660440 },
+               { 0x0444, 0x660444 },
+               { 0x0448, 0x660448 },
+               { 0x044c, 0x66044c },
+               { 0x0450, 0x660450 },
+               { 0x0454, 0x660454 },
+               { 0x0458, 0x660458 },
+               { 0x045c, 0x66045c },
+               { 0x0460, 0x660460 },
+               { 0x0468, 0x660468 },
+               { 0x046c, 0x66046c },
+               { 0x0470, 0x660470 },
+               { 0x0474, 0x660474 },
+               { 0x0480, 0x660480 },
+               { 0x0484, 0x660484 },
+               { 0x048c, 0x66048c },
+               { 0x0490, 0x660490 },
+               { 0x0494, 0x660494 },
+               { 0x0498, 0x660498 },
+               { 0x04b0, 0x6604b0 },
+               { 0x04b8, 0x6604b8 },
+               { 0x04bc, 0x6604bc },
+               { 0x04c0, 0x6604c0 },
+               { 0x04c4, 0x6604c4 },
+               { 0x04c8, 0x6604c8 },
+               { 0x04d0, 0x6604d0 },
+               { 0x04d4, 0x6604d4 },
+               { 0x04e0, 0x6604e0 },
+               { 0x04e4, 0x6604e4 },
+               { 0x04e8, 0x6604e8 },
+               { 0x04ec, 0x6604ec },
+               { 0x04f0, 0x6604f0 },
+               { 0x04f4, 0x6604f4 },
+               { 0x04f8, 0x6604f8 },
+               { 0x04fc, 0x6604fc },
+               { 0x0500, 0x660500 },
+               { 0x0504, 0x660504 },
+               { 0x0508, 0x660508 },
+               { 0x050c, 0x66050c },
+               { 0x0510, 0x660510 },
+               { 0x0514, 0x660514 },
+               { 0x0518, 0x660518 },
+               { 0x051c, 0x66051c },
+               { 0x052c, 0x66052c },
+               { 0x0530, 0x660530 },
+               { 0x054c, 0x66054c },
+               { 0x0550, 0x660550 },
+               { 0x0554, 0x660554 },
+               { 0x0558, 0x660558 },
+               { 0x055c, 0x66055c },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+gf119_disp_core_mthd = {
+       .name = "Core",
+       .addr = 0x000000,
+       .prev = -0x020000,
+       .data = {
+               { "Global", 1, &gf119_disp_core_mthd_base },
+               {    "DAC", 3, &gf119_disp_core_mthd_dac  },
+               {    "SOR", 8, &gf119_disp_core_mthd_sor  },
+               {   "PIOR", 4, &gf119_disp_core_mthd_pior },
+               {   "HEAD", 4, &gf119_disp_core_mthd_head },
+               {}
+       }
+};
+
+void
+gf119_disp_core_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       /* deactivate channel */
+       nvkm_mask(device, 0x610490, 0x00000010, 0x00000000);
+       nvkm_mask(device, 0x610490, 0x00000003, 0x00000000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490) & 0x001e0000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "core fini: %08x\n",
+                          nvkm_rd32(device, 0x610490));
+       }
+
+       chan->suspend_put = nvkm_rd32(device, 0x640000);
+}
+
+static int
+gf119_disp_core_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       /* initialise channel for dma command submission */
+       nvkm_wr32(device, 0x610494, chan->push);
+       nvkm_wr32(device, 0x610498, 0x00010000);
+       nvkm_wr32(device, 0x61049c, 0x00000001);
+       nvkm_mask(device, 0x610490, 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x640000, chan->suspend_put);
+       nvkm_wr32(device, 0x610490, 0x01000013);
+
+       /* wait for it to go inactive */
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490) & 0x80000000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "core init: %08x\n",
+                          nvkm_rd32(device, 0x610490));
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+const struct nvkm_disp_chan_func
+gf119_disp_core_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gf119_disp_core_init,
+       .fini = gf119_disp_core_fini,
+       .intr = gf119_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+       .bind = gf119_disp_dmac_bind,
+};
+
+static const struct nvkm_disp_chan_user
+gf119_disp_core = {
+       .func = &gf119_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &gf119_disp_core_mthd,
+};
+
 void
 gf119_disp_super(struct work_struct *work)
 {
-       struct nv50_disp *disp =
-               container_of(work, struct nv50_disp, supervisor);
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_disp *disp = container_of(work, struct nvkm_disp, super.work);
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        struct nvkm_head *head;
        u32 mask[4];
 
-       nvkm_debug(subdev, "supervisor %d\n", ffs(disp->super));
-       list_for_each_entry(head, &disp->base.head, head) {
+       nvkm_debug(subdev, "supervisor %d\n", ffs(disp->super.pending));
+       mutex_lock(&disp->super.mutex);
+
+       list_for_each_entry(head, &disp->heads, head) {
                mask[head->id] = nvkm_rd32(device, 0x6101d4 + (head->id * 0x800));
                HEAD_DBG(head, "%08x", mask[head->id]);
        }
 
-       if (disp->super & 0x00000001) {
+       if (disp->super.pending & 0x00000001) {
                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
                nv50_disp_super_1(disp);
-               list_for_each_entry(head, &disp->base.head, head) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_1_0(disp, head);
                }
        } else
-       if (disp->super & 0x00000002) {
-               list_for_each_entry(head, &disp->base.head, head) {
+       if (disp->super.pending & 0x00000002) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_2_0(disp, head);
                }
-               nvkm_outp_route(&disp->base);
-               list_for_each_entry(head, &disp->base.head, head) {
+               nvkm_outp_route(disp);
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00010000))
                                continue;
                        nv50_disp_super_2_1(disp, head);
                }
-               list_for_each_entry(head, &disp->base.head, head) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_2_2(disp, head);
                }
        } else
-       if (disp->super & 0x00000004) {
-               list_for_each_entry(head, &disp->base.head, head) {
+       if (disp->super.pending & 0x00000004) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_3_0(disp, head);
                }
        }
 
-       list_for_each_entry(head, &disp->base.head, head)
+       list_for_each_entry(head, &disp->heads, head)
                nvkm_wr32(device, 0x6101d4 + (head->id * 0x800), 0x00000000);
+
        nvkm_wr32(device, 0x6101d0, 0x80000000);
+       mutex_unlock(&disp->super.mutex);
 }
 
 void
-gf119_disp_intr_error(struct nv50_disp *disp, int chid)
+gf119_disp_intr_error(struct nvkm_disp *disp, int chid)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 stat = nvkm_rd32(device, 0x6101f0 + (chid * 12));
        u32 type = (stat & 0x00007000) >> 12;
@@ -119,9 +1077,9 @@ gf119_disp_intr_error(struct nv50_disp *disp, int chid)
 }
 
 void
-gf119_disp_intr(struct nv50_disp *disp)
+gf119_disp_intr(struct nvkm_disp *disp)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        struct nvkm_head *head;
        u32 intr = nvkm_rd32(device, 0x610088);
@@ -147,9 +1105,9 @@ gf119_disp_intr(struct nv50_disp *disp)
        if (intr & 0x00100000) {
                u32 stat = nvkm_rd32(device, 0x6100ac);
                if (stat & 0x00000007) {
-                       disp->super = (stat & 0x00000007);
-                       queue_work(disp->wq, &disp->supervisor);
-                       nvkm_wr32(device, 0x6100ac, disp->super);
+                       disp->super.pending = (stat & 0x00000007);
+                       queue_work(disp->super.wq, &disp->super.work);
+                       nvkm_wr32(device, 0x6100ac, disp->super.pending);
                        stat &= ~0x00000007;
                }
 
@@ -161,13 +1119,13 @@ gf119_disp_intr(struct nv50_disp *disp)
                intr &= ~0x00100000;
        }
 
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                const u32 hoff = head->id * 0x800;
                u32 mask = 0x01000000 << head->id;
                if (mask & intr) {
                        u32 stat = nvkm_rd32(device, 0x6100bc + hoff);
                        if (stat & 0x00000001)
-                               nvkm_disp_vblank(&disp->base, head->id);
+                               nvkm_disp_vblank(disp, head->id);
                        nvkm_mask(device, 0x6100bc + hoff, 0, 0);
                        nvkm_rd32(device, 0x6100c0 + hoff);
                }
@@ -175,17 +1133,17 @@ gf119_disp_intr(struct nv50_disp *disp)
 }
 
 void
-gf119_disp_fini(struct nv50_disp *disp)
+gf119_disp_fini(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        /* disable all interrupts */
        nvkm_wr32(device, 0x6100b0, 0x00000000);
 }
 
 int
-gf119_disp_init(struct nv50_disp *disp)
+gf119_disp_init(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        struct nvkm_head *head;
        u32 tmp;
        int i;
@@ -196,7 +1154,7 @@ gf119_disp_init(struct nv50_disp *disp)
         */
 
        /* ... CRTC caps */
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                const u32 hoff = head->id * 0x800;
                tmp = nvkm_rd32(device, 0x616104 + hoff);
                nvkm_wr32(device, 0x6101b4 + hoff, tmp);
@@ -243,7 +1201,7 @@ gf119_disp_init(struct nv50_disp *disp)
         *
         * 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) {
+       list_for_each_entry(head, &disp->heads, head) {
                const u32 hoff = head->id * 0x800;
                nvkm_mask(device, 0x616308 + hoff, 0x00000111, 0x00000010);
        }
@@ -251,23 +1209,32 @@ gf119_disp_init(struct nv50_disp *disp)
        return 0;
 }
 
-static const struct nv50_disp_func
+static const struct nvkm_disp_func
 gf119_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gf119_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gf119_sor_new },
+       .root = { 0,0,GF110_DISP },
+       .user = {
+               {{0,0,GF110_DISP_CURSOR             }, nvkm_disp_chan_new, &gf119_disp_curs },
+               {{0,0,GF110_DISP_OVERLAY            }, nvkm_disp_chan_new, &gf119_disp_oimm },
+               {{0,0,GF110_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gf119_disp_base },
+               {{0,0,GF110_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gf119_disp_core },
+               {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gf119_disp_ovly },
+               {}
+       },
 };
 
 int
 gf119_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gf119_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gf119_disp, device, type, inst, pdisp);
 }
index 3b79cf2..7248e9e 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
+#include "hdmi.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+void
+gk104_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
+                   u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 ctrl = 0x40000000 * enable |
+                        max_ac_packet << 16 |
+                        rekey;
+       const u32 hoff = head * 0x800;
+       const u32 hdmi = head * 0x400;
+       struct packed_hdmi_infoframe avi_infoframe;
+       struct packed_hdmi_infoframe vendor_infoframe;
+
+       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
+       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
+
+       if (!(ctrl & 0x40000000)) {
+               nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
+               nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
+               return;
+       }
+
+       /* AVI InfoFrame */
+       nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
+       if (avi_size) {
+               nvkm_wr32(device, 0x690008 + hdmi, avi_infoframe.header);
+               nvkm_wr32(device, 0x69000c + hdmi, avi_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x690010 + hdmi, avi_infoframe.subpack0_high);
+               nvkm_wr32(device, 0x690014 + hdmi, avi_infoframe.subpack1_low);
+               nvkm_wr32(device, 0x690018 + hdmi, avi_infoframe.subpack1_high);
+               nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000001);
+       }
+
+       /* GENERIC(?) / Vendor InfoFrame? */
+       nvkm_mask(device, 0x690100 + hdmi, 0x00010001, 0x00000000);
+       if (vendor_size) {
+               nvkm_wr32(device, 0x690108 + hdmi, vendor_infoframe.header);
+               nvkm_wr32(device, 0x69010c + hdmi, vendor_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x690110 + hdmi, vendor_infoframe.subpack0_high);
+               /* Is there a second (or further?) set of subpack registers here? */
+               nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000001);
+       }
+
+
+       /* ??? InfoFrame? */
+       nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
+       nvkm_wr32(device, 0x6900cc + hdmi, 0x00000010);
+       nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000001);
+
+       /* ??? */
+       nvkm_wr32(device, 0x690080 + hdmi, 0x82000000);
+
+       /* HDMI_CTRL */
+       nvkm_mask(device, 0x616798 + hoff, 0x401f007f, ctrl);
+}
+
+static const struct nvkm_ior_func
+gk104_sor = {
+       .state = gf119_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gk104_sor_hdmi_ctrl,
+       },
+       .dp = &gf119_sor_dp,
+       .hda = &gf119_sor_hda,
+};
+
+int
+gk104_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&gk104_sor, disp, SOR, id, true);
+}
+
+static const struct nvkm_disp_mthd_list
+gk104_disp_ovly_mthd_base = {
+       .mthd = 0x0000,
+       .data = {
+               { 0x0080, 0x665080 },
+               { 0x0084, 0x665084 },
+               { 0x0088, 0x665088 },
+               { 0x008c, 0x66508c },
+               { 0x0090, 0x665090 },
+               { 0x0094, 0x665094 },
+               { 0x00a0, 0x6650a0 },
+               { 0x00a4, 0x6650a4 },
+               { 0x00b0, 0x6650b0 },
+               { 0x00b4, 0x6650b4 },
+               { 0x00b8, 0x6650b8 },
+               { 0x00c0, 0x6650c0 },
+               { 0x00c4, 0x6650c4 },
+               { 0x00e0, 0x6650e0 },
+               { 0x00e4, 0x6650e4 },
+               { 0x00e8, 0x6650e8 },
+               { 0x0100, 0x665100 },
+               { 0x0104, 0x665104 },
+               { 0x0108, 0x665108 },
+               { 0x010c, 0x66510c },
+               { 0x0110, 0x665110 },
+               { 0x0118, 0x665118 },
+               { 0x011c, 0x66511c },
+               { 0x0120, 0x665120 },
+               { 0x0124, 0x665124 },
+               { 0x0130, 0x665130 },
+               { 0x0134, 0x665134 },
+               { 0x0138, 0x665138 },
+               { 0x013c, 0x66513c },
+               { 0x0140, 0x665140 },
+               { 0x0144, 0x665144 },
+               { 0x0148, 0x665148 },
+               { 0x014c, 0x66514c },
+               { 0x0150, 0x665150 },
+               { 0x0154, 0x665154 },
+               { 0x0158, 0x665158 },
+               { 0x015c, 0x66515c },
+               { 0x0160, 0x665160 },
+               { 0x0164, 0x665164 },
+               { 0x0168, 0x665168 },
+               { 0x016c, 0x66516c },
+               { 0x0400, 0x665400 },
+               { 0x0404, 0x665404 },
+               { 0x0408, 0x665408 },
+               { 0x040c, 0x66540c },
+               { 0x0410, 0x665410 },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_mthd
+gk104_disp_ovly_mthd = {
+       .name = "Overlay",
+       .addr = 0x001000,
+       .prev = -0x020000,
+       .data = {
+               { "Global", 1, &gk104_disp_ovly_mthd_base },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+gk104_disp_ovly = {
+       .func = &gf119_disp_dmac_func,
+       .ctrl = 5,
+       .user = 5,
+       .mthd = &gk104_disp_ovly_mthd,
+};
+
+static const struct nvkm_disp_mthd_list
+gk104_disp_core_mthd_head = {
+       .mthd = 0x0300,
+       .addr = 0x000300,
+       .data = {
+               { 0x0400, 0x660400 },
+               { 0x0404, 0x660404 },
+               { 0x0408, 0x660408 },
+               { 0x040c, 0x66040c },
+               { 0x0410, 0x660410 },
+               { 0x0414, 0x660414 },
+               { 0x0418, 0x660418 },
+               { 0x041c, 0x66041c },
+               { 0x0420, 0x660420 },
+               { 0x0424, 0x660424 },
+               { 0x0428, 0x660428 },
+               { 0x042c, 0x66042c },
+               { 0x0430, 0x660430 },
+               { 0x0434, 0x660434 },
+               { 0x0438, 0x660438 },
+               { 0x0440, 0x660440 },
+               { 0x0444, 0x660444 },
+               { 0x0448, 0x660448 },
+               { 0x044c, 0x66044c },
+               { 0x0450, 0x660450 },
+               { 0x0454, 0x660454 },
+               { 0x0458, 0x660458 },
+               { 0x045c, 0x66045c },
+               { 0x0460, 0x660460 },
+               { 0x0468, 0x660468 },
+               { 0x046c, 0x66046c },
+               { 0x0470, 0x660470 },
+               { 0x0474, 0x660474 },
+               { 0x047c, 0x66047c },
+               { 0x0480, 0x660480 },
+               { 0x0484, 0x660484 },
+               { 0x0488, 0x660488 },
+               { 0x048c, 0x66048c },
+               { 0x0490, 0x660490 },
+               { 0x0494, 0x660494 },
+               { 0x0498, 0x660498 },
+               { 0x04a0, 0x6604a0 },
+               { 0x04b0, 0x6604b0 },
+               { 0x04b8, 0x6604b8 },
+               { 0x04bc, 0x6604bc },
+               { 0x04c0, 0x6604c0 },
+               { 0x04c4, 0x6604c4 },
+               { 0x04c8, 0x6604c8 },
+               { 0x04d0, 0x6604d0 },
+               { 0x04d4, 0x6604d4 },
+               { 0x04e0, 0x6604e0 },
+               { 0x04e4, 0x6604e4 },
+               { 0x04e8, 0x6604e8 },
+               { 0x04ec, 0x6604ec },
+               { 0x04f0, 0x6604f0 },
+               { 0x04f4, 0x6604f4 },
+               { 0x04f8, 0x6604f8 },
+               { 0x04fc, 0x6604fc },
+               { 0x0500, 0x660500 },
+               { 0x0504, 0x660504 },
+               { 0x0508, 0x660508 },
+               { 0x050c, 0x66050c },
+               { 0x0510, 0x660510 },
+               { 0x0514, 0x660514 },
+               { 0x0518, 0x660518 },
+               { 0x051c, 0x66051c },
+               { 0x0520, 0x660520 },
+               { 0x0524, 0x660524 },
+               { 0x052c, 0x66052c },
+               { 0x0530, 0x660530 },
+               { 0x054c, 0x66054c },
+               { 0x0550, 0x660550 },
+               { 0x0554, 0x660554 },
+               { 0x0558, 0x660558 },
+               { 0x055c, 0x66055c },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_mthd
+gk104_disp_core_mthd = {
+       .name = "Core",
+       .addr = 0x000000,
+       .prev = -0x020000,
+       .data = {
+               { "Global", 1, &gf119_disp_core_mthd_base },
+               {    "DAC", 3, &gf119_disp_core_mthd_dac  },
+               {    "SOR", 8, &gf119_disp_core_mthd_sor  },
+               {   "PIOR", 4, &gf119_disp_core_mthd_pior },
+               {   "HEAD", 4, &gk104_disp_core_mthd_head },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+gk104_disp_core = {
+       .func = &gf119_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &gk104_disp_core_mthd,
+};
+
+static const struct nvkm_disp_func
 gk104_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gk104_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gk104_sor_new },
+       .root = { 0,0,GK104_DISP },
+       .user = {
+               {{0,0,GK104_DISP_CURSOR             }, nvkm_disp_chan_new, &gf119_disp_curs },
+               {{0,0,GK104_DISP_OVERLAY            }, nvkm_disp_chan_new, &gf119_disp_oimm },
+               {{0,0,GK104_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gf119_disp_base },
+               {{0,0,GK104_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gk104_disp_core },
+               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gk104_disp_ovly },
+               {}
+       },
 };
 
 int
 gk104_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gk104_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gk104_disp, device, type, inst, pdisp);
 }
index 988eb12..1704aa3 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+static const struct nvkm_disp_func
 gk110_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gk110_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gk104_sor_new },
+       .root = { 0,0,GK110_DISP },
+       .user = {
+               {{0,0,GK104_DISP_CURSOR             }, nvkm_disp_chan_new, &gf119_disp_curs },
+               {{0,0,GK104_DISP_OVERLAY            }, nvkm_disp_chan_new, &gf119_disp_oimm },
+               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gf119_disp_base },
+               {{0,0,GK110_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gk104_disp_core },
+               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gk104_disp_ovly },
+               {}
+       },
 };
 
 int
 gk110_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gk110_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gk110_disp, device, type, inst, pdisp);
 }
index 5d8108f..9e9ef49 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+void
+gm107_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       u32 mask = 0x1f1f1f1f, data;
+
+       switch (pattern) {
+       case 0: data = 0x10101010; break;
+       case 1: data = 0x01010101; break;
+       case 2: data = 0x02020202; break;
+       case 3: data = 0x03030303; break;
+       case 4: data = 0x1b1b1b1b; break;
+       default:
+               WARN_ON(1);
+               return;
+       }
+
+       if (sor->asy.link & 1)
+               nvkm_mask(device, 0x61c110 + soff, mask, data);
+       else
+               nvkm_mask(device, 0x61c12c + soff, mask, data);
+}
+
+static const struct nvkm_ior_func_dp
+gm107_sor_dp = {
+       .lanes = { 0, 1, 2, 3 },
+       .links = gf119_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = gm107_sor_dp_pattern,
+       .drive = gf119_sor_dp_drive,
+       .vcpi = gf119_sor_dp_vcpi,
+       .audio = gf119_sor_dp_audio,
+       .audio_sym = gf119_sor_dp_audio_sym,
+       .watermark = gf119_sor_dp_watermark,
+};
+
+static const struct nvkm_ior_func
+gm107_sor = {
+       .state = gf119_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gk104_sor_hdmi_ctrl,
+       },
+       .dp = &gm107_sor_dp,
+       .hda = &gf119_sor_hda,
+};
+
+static int
+gm107_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&gm107_sor, disp, SOR, id, true);
+}
+
+static const struct nvkm_disp_func
 gm107_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gm107_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gm107_sor_new },
+       .root = { 0,0,GM107_DISP },
+       .user = {
+               {{0,0,GK104_DISP_CURSOR             }, nvkm_disp_chan_new, &gf119_disp_curs },
+               {{0,0,GK104_DISP_OVERLAY            }, nvkm_disp_chan_new, &gf119_disp_oimm },
+               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gf119_disp_base },
+               {{0,0,GM107_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gk104_disp_core },
+               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gk104_disp_ovly },
+               {}
+       },
 };
 
 int
 gm107_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gm107_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gm107_disp, device, type, inst, pdisp);
 }
index f7bb660..4ecc8f9 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
+#include "hdmi.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
+#include "outp.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+void
+gm200_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  loff = nv50_sor_link(sor);
+       const u32 shift = sor->func->dp->lanes[ln] * 8;
+       u32 data[4];
+
+       pu &= 0x0f;
+
+       data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
+       data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
+       data[2] = nvkm_rd32(device, 0x61c130 + loff);
+       if ((data[2] & 0x00000f00) < (pu << 8) || ln == 0)
+               data[2] = (data[2] & ~0x00000f00) | (pu << 8);
+
+       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
+       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
+       nvkm_wr32(device, 0x61c130 + loff, data[2]);
+
+       data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
+       nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
+}
+
+const struct nvkm_ior_func_dp
+gm200_sor_dp = {
+       .lanes = { 0, 1, 2, 3 },
+       .links = gf119_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = gm107_sor_dp_pattern,
+       .drive = gm200_sor_dp_drive,
+       .vcpi = gf119_sor_dp_vcpi,
+       .audio = gf119_sor_dp_audio,
+       .audio_sym = gf119_sor_dp_audio_sym,
+       .watermark = gf119_sor_dp_watermark,
+};
+
+void
+gm200_sor_hdmi_scdc(struct nvkm_ior *ior, u8 scdc)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(ior);
+       const u32 ctrl = scdc & 0x3;
+
+       nvkm_mask(device, 0x61c5bc + soff, 0x00000003, ctrl);
+
+       ior->tmds.high_speed = !!(scdc & 0x2);
+}
+
+void
+gm200_sor_route_set(struct nvkm_outp *outp, struct nvkm_ior *ior)
+{
+       struct nvkm_device *device = outp->disp->engine.subdev.device;
+       const u32 moff = __ffs(outp->info.or) * 0x100;
+       const u32  sor = ior ? ior->id + 1 : 0;
+       u32 link = ior ? (ior->asy.link == 2) : 0;
+
+       if (outp->info.sorconf.link & 1) {
+               nvkm_mask(device, 0x612308 + moff, 0x0000001f, link << 4 | sor);
+               link++;
+       }
+
+       if (outp->info.sorconf.link & 2)
+               nvkm_mask(device, 0x612388 + moff, 0x0000001f, link << 4 | sor);
+}
+
+int
+gm200_sor_route_get(struct nvkm_outp *outp, int *link)
+{
+       struct nvkm_device *device = outp->disp->engine.subdev.device;
+       const int sublinks = outp->info.sorconf.link;
+       int lnk[2], sor[2], m, s;
+
+       for (*link = 0, m = __ffs(outp->info.or) * 2, s = 0; s < 2; m++, s++) {
+               if (sublinks & BIT(s)) {
+                       u32 data = nvkm_rd32(device, 0x612308 + (m * 0x80));
+                       lnk[s] = (data & 0x00000010) >> 4;
+                       sor[s] = (data & 0x0000000f);
+                       if (!sor[s])
+                               return -1;
+                       *link |= lnk[s];
+               }
+       }
+
+       if (sublinks == 3) {
+               if (sor[0] != sor[1] || WARN_ON(lnk[0] || !lnk[1]))
+                       return -1;
+       }
+
+       return ((sublinks & 1) ? sor[0] : sor[1]) - 1;
+}
+
+static const struct nvkm_ior_func
+gm200_sor = {
+       .route = {
+               .get = gm200_sor_route_get,
+               .set = gm200_sor_route_set,
+       },
+       .state = gf119_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gk104_sor_hdmi_ctrl,
+               .scdc = gm200_sor_hdmi_scdc,
+       },
+       .dp = &gm200_sor_dp,
+       .hda = &gf119_sor_hda,
+};
+
+static int
+gm200_sor_new(struct nvkm_disp *disp, int id)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       u32 hda;
+
+       if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+               hda = nvkm_rd32(device, 0x101034);
+
+       return nvkm_ior_new_(&gm200_sor, disp, SOR, id, hda & BIT(id));
+}
+
+static const struct nvkm_disp_func
 gm200_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gm200_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gm200_sor_new },
+       .root = { 0,0,GM200_DISP },
+       .user = {
+               {{0,0,GK104_DISP_CURSOR             }, nvkm_disp_chan_new, &gf119_disp_curs },
+               {{0,0,GK104_DISP_OVERLAY            }, nvkm_disp_chan_new, &gf119_disp_oimm },
+               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gf119_disp_base },
+               {{0,0,GM200_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gk104_disp_core },
+               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gk104_disp_ovly },
+               {}
+       },
 };
 
 int
 gm200_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gm200_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gm200_disp, device, type, inst, pdisp);
 }
index af0ca81..7172a9d 100644 (file)
  *
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+static const struct nvkm_ior_func
+gp100_sor = {
+       .route = {
+               .get = gm200_sor_route_get,
+               .set = gm200_sor_route_set,
+       },
+       .state = gf119_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gk104_sor_hdmi_ctrl,
+               .scdc = gm200_sor_hdmi_scdc,
+       },
+       .dp = &gm200_sor_dp,
+       .hda = &gf119_sor_hda,
+};
+
+int
+gp100_sor_new(struct nvkm_disp *disp, int id)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       u32 hda;
+
+       if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+               hda = nvkm_rd32(device, 0x10ebb0) >> 8;
+
+       return nvkm_ior_new_(&gp100_sor, disp, SOR, id, hda & BIT(id));
+}
+
+static const struct nvkm_disp_func
 gp100_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gf119_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gp100_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gp100_sor_new },
+       .root = { 0,0,GP100_DISP },
+       .user = {
+               {{0,0,GK104_DISP_CURSOR             }, nvkm_disp_chan_new, &gf119_disp_curs },
+               {{0,0,GK104_DISP_OVERLAY            }, nvkm_disp_chan_new, &gf119_disp_oimm },
+               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gf119_disp_base },
+               {{0,0,GP100_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gk104_disp_core },
+               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gk104_disp_ovly },
+               {}
+       },
 };
 
 int
 gp100_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gp100_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gp100_disp, device, type, inst, pdisp);
 }
index 065fea1..07e9aee 100644 (file)
  *
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "channv50.h"
-#include "rootnv50.h"
+
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
+
+static int
+gp102_disp_dmac_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       /* initialise channel for dma command submission */
+       nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
+       nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
+       nvkm_wr32(device, 0x61149c + (ctrl * 0x0010), 0x00000001);
+       nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), chan->suspend_put);
+       nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
+
+       /* wait for it to go inactive */
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d init: %08x\n", user,
+                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+const struct nvkm_disp_chan_func
+gp102_disp_dmac_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gp102_disp_dmac_init,
+       .fini = gf119_disp_dmac_fini,
+       .intr = gf119_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+       .bind = gf119_disp_dmac_bind,
+};
+
+static const struct nvkm_disp_chan_user
+gp102_disp_curs = {
+       .func = &gf119_disp_pioc_func,
+       .ctrl = 13,
+       .user = 17,
+};
+
+static const struct nvkm_disp_chan_user
+gp102_disp_oimm = {
+       .func = &gf119_disp_pioc_func,
+       .ctrl = 9,
+       .user = 13,
+};
+
+static const struct nvkm_disp_chan_user
+gp102_disp_ovly = {
+       .func = &gp102_disp_dmac_func,
+       .ctrl = 5,
+       .user = 5,
+       .mthd = &gk104_disp_ovly_mthd,
+};
+
+static const struct nvkm_disp_chan_user
+gp102_disp_base = {
+       .func = &gp102_disp_dmac_func,
+       .ctrl = 1,
+       .user = 1,
+       .mthd = &gf119_disp_base_mthd,
+};
+
+static int
+gp102_disp_core_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       /* initialise channel for dma command submission */
+       nvkm_wr32(device, 0x611494, chan->push);
+       nvkm_wr32(device, 0x611498, 0x00010000);
+       nvkm_wr32(device, 0x61149c, 0x00000001);
+       nvkm_mask(device, 0x610490, 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x640000, chan->suspend_put);
+       nvkm_wr32(device, 0x610490, 0x01000013);
+
+       /* wait for it to go inactive */
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610490) & 0x80000000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "core init: %08x\n",
+                          nvkm_rd32(device, 0x610490));
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static const struct nvkm_disp_chan_func
+gp102_disp_core_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gp102_disp_core_init,
+       .fini = gf119_disp_core_fini,
+       .intr = gf119_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+       .bind = gf119_disp_dmac_bind,
+};
+
+static const struct nvkm_disp_chan_user
+gp102_disp_core = {
+       .func = &gp102_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &gk104_disp_core_mthd,
+};
 
 static void
-gp102_disp_intr_error(struct nv50_disp *disp, int chid)
+gp102_disp_intr_error(struct nvkm_disp *disp, int chid)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 mthd = nvkm_rd32(device, 0x6111f0 + (chid * 12));
        u32 data = nvkm_rd32(device, 0x6111f4 + (chid * 12));
@@ -53,22 +170,31 @@ gp102_disp_intr_error(struct nv50_disp *disp, int chid)
        nvkm_wr32(device, 0x6111f0 + (chid * 12), 0x90000000);
 }
 
-static const struct nv50_disp_func
+static const struct nvkm_disp_func
 gp102_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gf119_disp_init,
        .fini = gf119_disp_fini,
        .intr = gf119_disp_intr,
        .intr_error = gp102_disp_intr_error,
-       .uevent = &gf119_disp_chan_uevent,
        .super = gf119_disp_super,
-       .root = &gp102_disp_root_oclass,
+       .uevent = &gf119_disp_chan_uevent,
        .head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
        .sor = { .cnt = gf119_sor_cnt, .new = gp100_sor_new },
+       .root = { 0,0,GP102_DISP },
+       .user = {
+               {{0,0,GK104_DISP_CURSOR             }, nvkm_disp_chan_new, &gp102_disp_curs },
+               {{0,0,GK104_DISP_OVERLAY            }, nvkm_disp_chan_new, &gp102_disp_oimm },
+               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &gp102_disp_base },
+               {{0,0,GP102_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &gp102_disp_core },
+               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, nvkm_disp_chan_new, &gp102_disp_ovly },
+               {}
+       },
 };
 
 int
 gp102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gp102_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gp102_disp, device, type, inst, pdisp);
 }
index 22bc269..6f69c4e 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+static const struct nvkm_disp_mthd_list
+gt200_disp_ovly_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x000000 },
+               { 0x0084, 0x6109a0 },
+               { 0x0088, 0x6109c0 },
+               { 0x008c, 0x6109c8 },
+               { 0x0090, 0x6109b4 },
+               { 0x0094, 0x610970 },
+               { 0x00a0, 0x610998 },
+               { 0x00a4, 0x610964 },
+               { 0x00b0, 0x610c98 },
+               { 0x00b4, 0x610ca4 },
+               { 0x00b8, 0x610cac },
+               { 0x00c0, 0x610958 },
+               { 0x00e0, 0x6109a8 },
+               { 0x00e4, 0x6109d0 },
+               { 0x00e8, 0x6109d8 },
+               { 0x0100, 0x61094c },
+               { 0x0104, 0x610984 },
+               { 0x0108, 0x61098c },
+               { 0x0800, 0x6109f8 },
+               { 0x0808, 0x610a08 },
+               { 0x080c, 0x610a10 },
+               { 0x0810, 0x610a00 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+gt200_disp_ovly_mthd = {
+       .name = "Overlay",
+       .addr = 0x000540,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &gt200_disp_ovly_mthd_base },
+               {}
+       }
+};
+
+const struct nvkm_disp_chan_user
+gt200_disp_ovly = {
+       .func = &nv50_disp_dmac_func,
+       .ctrl = 3,
+       .user = 3,
+       .mthd = &gt200_disp_ovly_mthd,
+};
+
+static const struct nvkm_disp_func
 gt200_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &gt200_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = nv50_sor_cnt, .new = g84_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0,0,GT200_DISP },
+       .user = {
+               {{0,0,  G82_DISP_CURSOR             }, nvkm_disp_chan_new, & nv50_disp_curs },
+               {{0,0,  G82_DISP_OVERLAY            }, nvkm_disp_chan_new, & nv50_disp_oimm },
+               {{0,0,GT200_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &  g84_disp_base },
+               {{0,0,GT200_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &  g84_disp_core },
+               {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, &gt200_disp_ovly },
+               {}
+       },
 };
 
 int
 gt200_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gt200_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gt200_disp, device, type, inst, pdisp);
 }
index 63a912b..70c49e7 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
+#include "hdmi.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
+
+static void
+gt215_sor_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = ior->id * 0x800;
+       int i;
+
+       for (i = 0; i < size; i++)
+               nvkm_wr32(device, 0x61c440 + soff, (i << 8) | data[i]);
+       for (; i < 0x60; i++)
+               nvkm_wr32(device, 0x61c440 + soff, (i << 8));
+       nvkm_mask(device, 0x61c448 + soff, 0x80000002, 0x80000002);
+}
+
+static void
+gt215_sor_hda_hpd(struct nvkm_ior *ior, int head, bool present)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       u32 data = 0x80000000;
+       u32 mask = 0x80000001;
+       if (present)
+               data |= 0x00000001;
+       else
+               mask |= 0x00000002;
+       nvkm_mask(device, 0x61c448 + ior->id * 0x800, mask, data);
+}
+
+const struct nvkm_ior_func_hda
+gt215_sor_hda = {
+       .hpd = gt215_sor_hda_hpd,
+       .eld = gt215_sor_hda_eld,
+};
+
+void
+gt215_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       const u32 data = 0x80000000 | (0x00000001 * enable);
+       const u32 mask = 0x8000000d;
+
+       nvkm_mask(device, 0x61c1e0 + soff, mask, data);
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x61c1e0 + soff) & 0x80000000))
+                       break;
+       );
+}
+
+static const struct nvkm_ior_func_dp
+gt215_sor_dp = {
+       .lanes = { 2, 1, 0, 3 },
+       .links = g94_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = g94_sor_dp_pattern,
+       .drive = g94_sor_dp_drive,
+       .audio = gt215_sor_dp_audio,
+       .audio_sym = g94_sor_dp_audio_sym,
+       .activesym = g94_sor_dp_activesym,
+       .watermark = g94_sor_dp_watermark,
+};
+
+void
+gt215_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
+                   u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 ctrl = 0x40000000 * enable |
+                        0x1f000000 /* ??? */ |
+                        max_ac_packet << 16 |
+                        rekey;
+       const u32 soff = nv50_ior_base(ior);
+       struct packed_hdmi_infoframe avi_infoframe;
+       struct packed_hdmi_infoframe vendor_infoframe;
+
+       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
+       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
+
+       if (!(ctrl & 0x40000000)) {
+               nvkm_mask(device, 0x61c5a4 + soff, 0x40000000, 0x00000000);
+               nvkm_mask(device, 0x61c53c + soff, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x61c500 + soff, 0x00000001, 0x00000000);
+               return;
+       }
+
+       /* AVI InfoFrame */
+       nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000000);
+       if (avi_size) {
+               nvkm_wr32(device, 0x61c528 + soff, avi_infoframe.header);
+               nvkm_wr32(device, 0x61c52c + soff, avi_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x61c530 + soff, avi_infoframe.subpack0_high);
+               nvkm_wr32(device, 0x61c534 + soff, avi_infoframe.subpack1_low);
+               nvkm_wr32(device, 0x61c538 + soff, avi_infoframe.subpack1_high);
+               nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000001);
+       }
+
+       /* Audio InfoFrame */
+       nvkm_mask(device, 0x61c500 + soff, 0x00000001, 0x00000000);
+       nvkm_wr32(device, 0x61c508 + soff, 0x000a0184);
+       nvkm_wr32(device, 0x61c50c + soff, 0x00000071);
+       nvkm_wr32(device, 0x61c510 + soff, 0x00000000);
+       nvkm_mask(device, 0x61c500 + soff, 0x00000001, 0x00000001);
+
+       /* Vendor InfoFrame */
+       nvkm_mask(device, 0x61c53c + soff, 0x00010001, 0x00010000);
+       if (vendor_size) {
+               nvkm_wr32(device, 0x61c544 + soff, vendor_infoframe.header);
+               nvkm_wr32(device, 0x61c548 + soff, vendor_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x61c54c + soff, vendor_infoframe.subpack0_high);
+               /* Is there a second (or up to fourth?) set of subpack registers here? */
+               /* nvkm_wr32(device, 0x61c550 + soff, vendor_infoframe.subpack1_low); */
+               /* nvkm_wr32(device, 0x61c554 + soff, vendor_infoframe.subpack1_high); */
+               nvkm_mask(device, 0x61c53c + soff, 0x00010001, 0x00010001);
+       }
+
+       nvkm_mask(device, 0x61c5d0 + soff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
+       nvkm_mask(device, 0x61c568 + soff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
+       nvkm_mask(device, 0x61c578 + soff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
+
+       /* ??? */
+       nvkm_mask(device, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
+       nvkm_mask(device, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
+       nvkm_mask(device, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
+
+       /* HDMI_CTRL */
+       nvkm_mask(device, 0x61c5a4 + soff, 0x5f1f007f, ctrl);
+}
+
+static const struct nvkm_ior_func
+gt215_sor = {
+       .state = g94_sor_state,
+       .power = nv50_sor_power,
+       .clock = nv50_sor_clock,
+       .hdmi = {
+               .ctrl = gt215_sor_hdmi_ctrl,
+       },
+       .dp = &gt215_sor_dp,
+       .hda = &gt215_sor_hda,
+};
+
+static int
+gt215_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&gt215_sor, disp, SOR, id, true);
+}
+
+static const struct nvkm_disp_func
 gt215_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &gt215_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = g94_sor_cnt, .new = gt215_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0,0,GT214_DISP },
+       .user = {
+               {{0,0,GT214_DISP_CURSOR             }, nvkm_disp_chan_new, & nv50_disp_curs },
+               {{0,0,GT214_DISP_OVERLAY            }, nvkm_disp_chan_new, & nv50_disp_oimm },
+               {{0,0,GT214_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &  g84_disp_base },
+               {{0,0,GT214_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &  g94_disp_core },
+               {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, &  g84_disp_ovly },
+               {}
+       },
 };
 
 int
 gt215_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gt215_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gt215_disp, device, type, inst, pdisp);
 }
index 53879d5..6b9d492 100644 (file)
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
+#include "hdmi.h"
 #include "head.h"
 #include "ior.h"
-#include "channv50.h"
-#include "rootnv50.h"
+#include "outp.h"
 
+#include <core/client.h>
 #include <core/gpuobj.h>
+#include <core/ramht.h>
 #include <subdev/timer.h>
 
+#include <nvif/class.h>
+#include <nvif/unpack.h>
+
+static void
+gv100_sor_hda_device_entry(struct nvkm_ior *ior, int head)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 hoff = 0x800 * head;
+
+       nvkm_mask(device, 0x616528 + hoff, 0x00000070, head << 4);
+}
+
+const struct nvkm_ior_func_hda
+gv100_sor_hda = {
+       .hpd = gf119_sor_hda_hpd,
+       .eld = gf119_sor_hda_eld,
+       .device_entry = gv100_sor_hda_device_entry,
+};
+
+void
+gv100_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = head * 0x800;
+
+       nvkm_mask(device, 0x616550 + hoff, 0x0c00003f, 0x08000000 | watermark);
+}
+
+void
+gv100_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = head * 0x800;
+
+       nvkm_mask(device, 0x616568 + hoff, 0x0000ffff, h);
+       nvkm_mask(device, 0x61656c + hoff, 0x00ffffff, v);
+}
+
+void
+gv100_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = 0x800 * head;
+       const u32 data = 0x80000000 | (0x00000001 * enable);
+       const u32 mask = 0x8000000d;
+
+       nvkm_mask(device, 0x616560 + hoff, mask, data);
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x616560 + hoff) & 0x80000000))
+                       break;
+       );
+}
+
+static const struct nvkm_ior_func_dp
+gv100_sor_dp = {
+       .lanes = { 0, 1, 2, 3 },
+       .links = gf119_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = gm107_sor_dp_pattern,
+       .drive = gm200_sor_dp_drive,
+       .audio = gv100_sor_dp_audio,
+       .audio_sym = gv100_sor_dp_audio_sym,
+       .watermark = gv100_sor_dp_watermark,
+};
+
+void
+gv100_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
+                   u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 ctrl = 0x40000000 * enable |
+                        max_ac_packet << 16 |
+                        rekey;
+       const u32 hoff = head * 0x800;
+       const u32 hdmi = head * 0x400;
+       struct packed_hdmi_infoframe avi_infoframe;
+       struct packed_hdmi_infoframe vendor_infoframe;
+
+       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
+       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
+
+       if (!(ctrl & 0x40000000)) {
+               nvkm_mask(device, 0x6165c0 + hoff, 0x40000000, 0x00000000);
+               nvkm_mask(device, 0x6f0100 + hdmi, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
+               nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000000);
+               return;
+       }
+
+       /* AVI InfoFrame (AVI). */
+       nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000000);
+       if (avi_size) {
+               nvkm_wr32(device, 0x6f0008 + hdmi, avi_infoframe.header);
+               nvkm_wr32(device, 0x6f000c + hdmi, avi_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x6f0010 + hdmi, avi_infoframe.subpack0_high);
+               nvkm_wr32(device, 0x6f0014 + hdmi, avi_infoframe.subpack1_low);
+               nvkm_wr32(device, 0x6f0018 + hdmi, avi_infoframe.subpack1_high);
+               nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000001);
+       }
+
+       /* Vendor-specific InfoFrame (VSI). */
+       nvkm_mask(device, 0x6f0100 + hdmi, 0x00010001, 0x00000000);
+       if (vendor_size) {
+               nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header);
+               nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low);
+               nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high);
+               nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000);
+               nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000);
+               nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000);
+               nvkm_wr32(device, 0x6f0120 + hdmi, 0x00000000);
+               nvkm_wr32(device, 0x6f0124 + hdmi, 0x00000000);
+               nvkm_mask(device, 0x6f0100 + hdmi, 0x00000001, 0x00000001);
+       }
+
+
+       /* General Control (GCP). */
+       nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
+       nvkm_wr32(device, 0x6f00cc + hdmi, 0x00000010);
+       nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001);
+
+       /* Audio Clock Regeneration (ACR). */
+       nvkm_wr32(device, 0x6f0080 + hdmi, 0x82000000);
+
+       /* NV_PDISP_SF_HDMI_CTRL. */
+       nvkm_mask(device, 0x6165c0 + hoff, 0x401f007f, ctrl);
+}
+
+void
+gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = (state == &sor->arm) * 0x8000 + sor->id * 0x20;
+       u32 ctrl = nvkm_rd32(device, 0x680300 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       case 8: state->proto =   DP; state->link = 1; break;
+       case 9: state->proto =   DP; state->link = 2; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x000000ff;
+}
+
+static const struct nvkm_ior_func
+gv100_sor = {
+       .route = {
+               .get = gm200_sor_route_get,
+               .set = gm200_sor_route_set,
+       },
+       .state = gv100_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gv100_sor_hdmi_ctrl,
+               .scdc = gm200_sor_hdmi_scdc,
+       },
+       .dp = &gv100_sor_dp,
+       .hda = &gv100_sor_hda,
+};
+
+static int
+gv100_sor_new(struct nvkm_disp *disp, int id)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       u32 hda;
+
+       if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+               hda = nvkm_rd32(device, 0x118fb0) >> 8;
+
+       return nvkm_ior_new_(&gv100_sor, disp, SOR, id, hda & BIT(id));
+}
+
+int
+gv100_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+
+       *pmask = (nvkm_rd32(device, 0x610060) & 0x0000ff00) >> 8;
+       return (nvkm_rd32(device, 0x610074) & 0x00000f00) >> 8;
+}
+
+static void
+gv100_head_vblank_put(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000000);
+}
+
+static void
+gv100_head_vblank_get(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000004);
+}
+
+static void
+gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = head->id * 0x800;
+       /* vline read locks hline. */
+       *vline = nvkm_rd32(device, 0x616330 + hoff) & 0x0000ffff;
+       *hline = nvkm_rd32(device, 0x616334 + hoff) & 0x0000ffff;
+}
+
+static void
+gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = (state == &head->arm) * 0x8000 + head->id * 0x400;
+       u32 data;
+
+       data = nvkm_rd32(device, 0x682064 + hoff);
+       state->vtotal = (data & 0xffff0000) >> 16;
+       state->htotal = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x682068 + hoff);
+       state->vsynce = (data & 0xffff0000) >> 16;
+       state->hsynce = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x68206c + hoff);
+       state->vblanke = (data & 0xffff0000) >> 16;
+       state->hblanke = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x682070 + hoff);
+       state->vblanks = (data & 0xffff0000) >> 16;
+       state->hblanks = (data & 0x0000ffff);
+       state->hz = nvkm_rd32(device, 0x68200c + hoff);
+
+       data = nvkm_rd32(device, 0x682004 + hoff);
+       switch ((data & 0x000000f0) >> 4) {
+       case 5: state->or.depth = 30; break;
+       case 4: state->or.depth = 24; break;
+       case 1: state->or.depth = 18; break;
+       default:
+               state->or.depth = 18;
+               WARN_ON(1);
+               break;
+       }
+}
+
+static const struct nvkm_head_func
+gv100_head = {
+       .state = gv100_head_state,
+       .rgpos = gv100_head_rgpos,
+       .rgclk = gf119_head_rgclk,
+       .vblank_get = gv100_head_vblank_get,
+       .vblank_put = gv100_head_vblank_put,
+};
+
+int
+gv100_head_new(struct nvkm_disp *disp, int id)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+
+       if (!(nvkm_rd32(device, 0x610060) & (0x00000001 << id)))
+               return 0;
+
+       return nvkm_head_new_(&gv100_head, disp, id);
+}
+
+int
+gv100_head_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+
+       *pmask = nvkm_rd32(device, 0x610060) & 0x000000ff;
+       return nvkm_rd32(device, 0x610074) & 0x0000000f;
+}
+
+const struct nvkm_event_func
+gv100_disp_chan_uevent = {
+};
+
+u64
+gv100_disp_chan_user(struct nvkm_disp_chan *chan, u64 *psize)
+{
+       *psize = 0x1000;
+       return 0x690000 + ((chan->chid.user - 1) * 0x1000);
+}
+
+static int
+gv100_disp_dmac_idle(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 soff = (chan->chid.ctrl - 1) * 0x04;
+       nvkm_msec(device, 2000,
+               u32 stat = nvkm_rd32(device, 0x610664 + soff);
+               if ((stat & 0x000f0000) == 0x00040000)
+                       return 0;
+       );
+       return -EBUSY;
+}
+
+int
+gv100_disp_dmac_bind(struct nvkm_disp_chan *chan,
+                    struct nvkm_object *object, u32 handle)
+{
+       return nvkm_ramht_insert(chan->disp->ramht, object, chan->chid.user, -9, handle,
+                                chan->chid.user << 25 | 0x00000040);
+}
+
+void
+gv100_disp_dmac_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 uoff = (chan->chid.ctrl - 1) * 0x1000;
+       const u32 coff = chan->chid.ctrl * 0x04;
+       nvkm_mask(device, 0x6104e0 + coff, 0x00000010, 0x00000000);
+       gv100_disp_dmac_idle(chan);
+       nvkm_mask(device, 0x6104e0 + coff, 0x00000002, 0x00000000);
+       chan->suspend_put = nvkm_rd32(device, 0x690000 + uoff);
+}
+
+int
+gv100_disp_dmac_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       const u32 uoff = (chan->chid.ctrl - 1) * 0x1000;
+       const u32 poff = chan->chid.ctrl * 0x10;
+       const u32 coff = chan->chid.ctrl * 0x04;
+
+       nvkm_wr32(device, 0x610b24 + poff, lower_32_bits(chan->push));
+       nvkm_wr32(device, 0x610b20 + poff, upper_32_bits(chan->push));
+       nvkm_wr32(device, 0x610b28 + poff, 0x00000001);
+       nvkm_wr32(device, 0x610b2c + poff, 0x00000040);
+
+       nvkm_mask(device, 0x6104e0 + coff, 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x690000 + uoff, chan->suspend_put);
+       nvkm_wr32(device, 0x6104e0 + coff, 0x00000013);
+       return gv100_disp_dmac_idle(chan);
+}
+
+static void
+gv100_disp_wimm_intr(struct nvkm_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 mask = 0x00000001 << chan->head;
+       const u32 data = en ? mask : 0;
+       nvkm_mask(device, 0x611da8, mask, data);
+}
+
+static const struct nvkm_disp_chan_func
+gv100_disp_wimm_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gv100_disp_dmac_init,
+       .fini = gv100_disp_dmac_fini,
+       .intr = gv100_disp_wimm_intr,
+       .user = gv100_disp_chan_user,
+};
+
+const struct nvkm_disp_chan_user
+gv100_disp_wimm = {
+       .func = &gv100_disp_wimm_func,
+       .ctrl = 33,
+       .user = 33,
+};
+
+static const struct nvkm_disp_mthd_list
+gv100_disp_wndw_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0200, 0x690200 },
+               { 0x020c, 0x69020c },
+               { 0x0210, 0x690210 },
+               { 0x0214, 0x690214 },
+               { 0x0218, 0x690218 },
+               { 0x021c, 0x69021c },
+               { 0x0220, 0x690220 },
+               { 0x0224, 0x690224 },
+               { 0x0228, 0x690228 },
+               { 0x022c, 0x69022c },
+               { 0x0230, 0x690230 },
+               { 0x0234, 0x690234 },
+               { 0x0238, 0x690238 },
+               { 0x0240, 0x690240 },
+               { 0x0244, 0x690244 },
+               { 0x0248, 0x690248 },
+               { 0x024c, 0x69024c },
+               { 0x0250, 0x690250 },
+               { 0x0254, 0x690254 },
+               { 0x0260, 0x690260 },
+               { 0x0264, 0x690264 },
+               { 0x0268, 0x690268 },
+               { 0x026c, 0x69026c },
+               { 0x0270, 0x690270 },
+               { 0x0274, 0x690274 },
+               { 0x0280, 0x690280 },
+               { 0x0284, 0x690284 },
+               { 0x0288, 0x690288 },
+               { 0x028c, 0x69028c },
+               { 0x0290, 0x690290 },
+               { 0x0298, 0x690298 },
+               { 0x029c, 0x69029c },
+               { 0x02a0, 0x6902a0 },
+               { 0x02a4, 0x6902a4 },
+               { 0x02a8, 0x6902a8 },
+               { 0x02ac, 0x6902ac },
+               { 0x02b0, 0x6902b0 },
+               { 0x02b4, 0x6902b4 },
+               { 0x02b8, 0x6902b8 },
+               { 0x02bc, 0x6902bc },
+               { 0x02c0, 0x6902c0 },
+               { 0x02c4, 0x6902c4 },
+               { 0x02c8, 0x6902c8 },
+               { 0x02cc, 0x6902cc },
+               { 0x02d0, 0x6902d0 },
+               { 0x02d4, 0x6902d4 },
+               { 0x02d8, 0x6902d8 },
+               { 0x02dc, 0x6902dc },
+               { 0x02e0, 0x6902e0 },
+               { 0x02e4, 0x6902e4 },
+               { 0x02e8, 0x6902e8 },
+               { 0x02ec, 0x6902ec },
+               { 0x02f0, 0x6902f0 },
+               { 0x02f4, 0x6902f4 },
+               { 0x02f8, 0x6902f8 },
+               { 0x02fc, 0x6902fc },
+               { 0x0300, 0x690300 },
+               { 0x0304, 0x690304 },
+               { 0x0308, 0x690308 },
+               { 0x0310, 0x690310 },
+               { 0x0314, 0x690314 },
+               { 0x0318, 0x690318 },
+               { 0x031c, 0x69031c },
+               { 0x0320, 0x690320 },
+               { 0x0324, 0x690324 },
+               { 0x0328, 0x690328 },
+               { 0x032c, 0x69032c },
+               { 0x033c, 0x69033c },
+               { 0x0340, 0x690340 },
+               { 0x0344, 0x690344 },
+               { 0x0348, 0x690348 },
+               { 0x034c, 0x69034c },
+               { 0x0350, 0x690350 },
+               { 0x0354, 0x690354 },
+               { 0x0358, 0x690358 },
+               { 0x0364, 0x690364 },
+               { 0x0368, 0x690368 },
+               { 0x036c, 0x69036c },
+               { 0x0370, 0x690370 },
+               { 0x0374, 0x690374 },
+               { 0x0380, 0x690380 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+gv100_disp_wndw_mthd = {
+       .name = "Window",
+       .addr = 0x001000,
+       .prev = 0x000800,
+       .data = {
+               { "Global", 1, &gv100_disp_wndw_mthd_base },
+               {}
+       }
+};
+
+static void
+gv100_disp_wndw_intr(struct nvkm_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 mask = 0x00000001 << chan->head;
+       const u32 data = en ? mask : 0;
+       nvkm_mask(device, 0x611da4, mask, data);
+}
+
+static const struct nvkm_disp_chan_func
+gv100_disp_wndw_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gv100_disp_dmac_init,
+       .fini = gv100_disp_dmac_fini,
+       .intr = gv100_disp_wndw_intr,
+       .user = gv100_disp_chan_user,
+       .bind = gv100_disp_dmac_bind,
+};
+
+const struct nvkm_disp_chan_user
+gv100_disp_wndw = {
+       .func = &gv100_disp_wndw_func,
+       .ctrl = 1,
+       .user = 1,
+       .mthd = &gv100_disp_wndw_mthd,
+};
+
 int
 gv100_disp_wndw_cnt(struct nvkm_disp *disp, unsigned long *pmask)
 {
        struct nvkm_device *device = disp->engine.subdev.device;
+
        *pmask = nvkm_rd32(device, 0x610064);
        return (nvkm_rd32(device, 0x610074) & 0x03f00000) >> 20;
 }
 
+static int
+gv100_disp_curs_idle(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 soff = (chan->chid.ctrl - 1) * 0x04;
+       nvkm_msec(device, 2000,
+               u32 stat = nvkm_rd32(device, 0x610664 + soff);
+               if ((stat & 0x00070000) == 0x00040000)
+                       return 0;
+       );
+       return -EBUSY;
+}
+
+static void
+gv100_disp_curs_intr(struct nvkm_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 mask = 0x00010000 << chan->head;
+       const u32 data = en ? mask : 0;
+       nvkm_mask(device, 0x611dac, mask, data);
+}
+
+static void
+gv100_disp_curs_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 hoff = chan->chid.ctrl * 4;
+       nvkm_mask(device, 0x6104e0 + hoff, 0x00000010, 0x00000010);
+       gv100_disp_curs_idle(chan);
+       nvkm_mask(device, 0x6104e0 + hoff, 0x00000001, 0x00000000);
+}
+
+static int
+gv100_disp_curs_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       nvkm_wr32(device, 0x6104e0 + chan->chid.ctrl * 4, 0x00000001);
+       return gv100_disp_curs_idle(chan);
+}
+
+static const struct nvkm_disp_chan_func
+gv100_disp_curs_func = {
+       .init = gv100_disp_curs_init,
+       .fini = gv100_disp_curs_fini,
+       .intr = gv100_disp_curs_intr,
+       .user = gv100_disp_chan_user,
+};
+
+const struct nvkm_disp_chan_user
+gv100_disp_curs = {
+       .func = &gv100_disp_curs_func,
+       .ctrl = 73,
+       .user = 73,
+};
+
+const struct nvkm_disp_mthd_list
+gv100_disp_core_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0200, 0x680200 },
+               { 0x0208, 0x680208 },
+               { 0x020c, 0x68020c },
+               { 0x0210, 0x680210 },
+               { 0x0214, 0x680214 },
+               { 0x0218, 0x680218 },
+               { 0x021c, 0x68021c },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+gv100_disp_core_mthd_sor = {
+       .mthd = 0x0020,
+       .addr = 0x000020,
+       .data = {
+               { 0x0300, 0x680300 },
+               { 0x0304, 0x680304 },
+               { 0x0308, 0x680308 },
+               { 0x030c, 0x68030c },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+gv100_disp_core_mthd_wndw = {
+       .mthd = 0x0080,
+       .addr = 0x000080,
+       .data = {
+               { 0x1000, 0x681000 },
+               { 0x1004, 0x681004 },
+               { 0x1008, 0x681008 },
+               { 0x100c, 0x68100c },
+               { 0x1010, 0x681010 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+gv100_disp_core_mthd_head = {
+       .mthd = 0x0400,
+       .addr = 0x000400,
+       .data = {
+               { 0x2000, 0x682000 },
+               { 0x2004, 0x682004 },
+               { 0x2008, 0x682008 },
+               { 0x200c, 0x68200c },
+               { 0x2014, 0x682014 },
+               { 0x2018, 0x682018 },
+               { 0x201c, 0x68201c },
+               { 0x2020, 0x682020 },
+               { 0x2028, 0x682028 },
+               { 0x202c, 0x68202c },
+               { 0x2030, 0x682030 },
+               { 0x2038, 0x682038 },
+               { 0x203c, 0x68203c },
+               { 0x2048, 0x682048 },
+               { 0x204c, 0x68204c },
+               { 0x2050, 0x682050 },
+               { 0x2054, 0x682054 },
+               { 0x2058, 0x682058 },
+               { 0x205c, 0x68205c },
+               { 0x2060, 0x682060 },
+               { 0x2064, 0x682064 },
+               { 0x2068, 0x682068 },
+               { 0x206c, 0x68206c },
+               { 0x2070, 0x682070 },
+               { 0x2074, 0x682074 },
+               { 0x2078, 0x682078 },
+               { 0x207c, 0x68207c },
+               { 0x2080, 0x682080 },
+               { 0x2088, 0x682088 },
+               { 0x2090, 0x682090 },
+               { 0x209c, 0x68209c },
+               { 0x20a0, 0x6820a0 },
+               { 0x20a4, 0x6820a4 },
+               { 0x20a8, 0x6820a8 },
+               { 0x20ac, 0x6820ac },
+               { 0x2180, 0x682180 },
+               { 0x2184, 0x682184 },
+               { 0x218c, 0x68218c },
+               { 0x2194, 0x682194 },
+               { 0x2198, 0x682198 },
+               { 0x219c, 0x68219c },
+               { 0x21a0, 0x6821a0 },
+               { 0x21a4, 0x6821a4 },
+               { 0x2214, 0x682214 },
+               { 0x2218, 0x682218 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+gv100_disp_core_mthd = {
+       .name = "Core",
+       .addr = 0x000000,
+       .prev = 0x008000,
+       .data = {
+               { "Global", 1, &gv100_disp_core_mthd_base },
+               {    "SOR", 4, &gv100_disp_core_mthd_sor  },
+               { "WINDOW", 8, &gv100_disp_core_mthd_wndw },
+               {   "HEAD", 4, &gv100_disp_core_mthd_head },
+               {}
+       }
+};
+
+static int
+gv100_disp_core_idle(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       nvkm_msec(device, 2000,
+               u32 stat = nvkm_rd32(device, 0x610630);
+               if ((stat & 0x001f0000) == 0x000b0000)
+                       return 0;
+       );
+       return -EBUSY;
+}
+
+static u64
+gv100_disp_core_user(struct nvkm_disp_chan *chan, u64 *psize)
+{
+       *psize = 0x10000;
+       return 0x680000;
+}
+
+static void
+gv100_disp_core_intr(struct nvkm_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 mask = 0x00000001;
+       const u32 data = en ? mask : 0;
+       nvkm_mask(device, 0x611dac, mask, data);
+}
+
+static void
+gv100_disp_core_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       nvkm_mask(device, 0x6104e0, 0x00000010, 0x00000000);
+       gv100_disp_core_idle(chan);
+       nvkm_mask(device, 0x6104e0, 0x00000002, 0x00000000);
+       chan->suspend_put = nvkm_rd32(device, 0x680000);
+}
+
+static int
+gv100_disp_core_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       nvkm_wr32(device, 0x610b24, lower_32_bits(chan->push));
+       nvkm_wr32(device, 0x610b20, upper_32_bits(chan->push));
+       nvkm_wr32(device, 0x610b28, 0x00000001);
+       nvkm_wr32(device, 0x610b2c, 0x00000040);
+
+       nvkm_mask(device, 0x6104e0, 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x680000, chan->suspend_put);
+       nvkm_wr32(device, 0x6104e0, 0x00000013);
+       return gv100_disp_core_idle(chan);
+}
+
+static const struct nvkm_disp_chan_func
+gv100_disp_core_func = {
+       .push = nv50_disp_dmac_push,
+       .init = gv100_disp_core_init,
+       .fini = gv100_disp_core_fini,
+       .intr = gv100_disp_core_intr,
+       .user = gv100_disp_core_user,
+       .bind = gv100_disp_dmac_bind,
+};
+
+const struct nvkm_disp_chan_user
+gv100_disp_core = {
+       .func = &gv100_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &gv100_disp_core_mthd,
+};
+
+#define gv100_disp_caps(p) container_of((p), struct gv100_disp_caps, object)
+
+struct gv100_disp_caps {
+       struct nvkm_object object;
+       struct nvkm_disp *disp;
+};
+
+static int
+gv100_disp_caps_map(struct nvkm_object *object, void *argv, u32 argc,
+                   enum nvkm_object_map *type, u64 *addr, u64 *size)
+{
+       struct gv100_disp_caps *caps = gv100_disp_caps(object);
+       struct nvkm_device *device = caps->disp->engine.subdev.device;
+       *type = NVKM_OBJECT_MAP_IO;
+       *addr = 0x640000 + device->func->resource_addr(device, 0);
+       *size = 0x1000;
+       return 0;
+}
+
+static const struct nvkm_object_func
+gv100_disp_caps = {
+       .map = gv100_disp_caps_map,
+};
+
+int
+gv100_disp_caps_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
+                   struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+       struct gv100_disp_caps *caps;
+
+       if (!(caps = kzalloc(sizeof(*caps), GFP_KERNEL)))
+               return -ENOMEM;
+       *pobject = &caps->object;
+
+       nvkm_object_ctor(&gv100_disp_caps, oclass, &caps->object);
+       caps->disp = disp;
+       return 0;
+}
+
 void
 gv100_disp_super(struct work_struct *work)
 {
-       struct nv50_disp *disp =
-               container_of(work, struct nv50_disp, supervisor);
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_disp *disp = container_of(work, struct nvkm_disp, super.work);
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        struct nvkm_head *head;
-       u32 stat = nvkm_rd32(device, 0x6107a8);
-       u32 mask[4];
+       u32 stat, mask[4];
+
+       mutex_lock(&disp->super.mutex);
+       stat = nvkm_rd32(device, 0x6107a8);
 
-       nvkm_debug(subdev, "supervisor %d: %08x\n", ffs(disp->super), stat);
-       list_for_each_entry(head, &disp->base.head, head) {
+       nvkm_debug(subdev, "supervisor %d: %08x\n", ffs(disp->super.pending), stat);
+       list_for_each_entry(head, &disp->heads, head) {
                mask[head->id] = nvkm_rd32(device, 0x6107ac + (head->id * 4));
                HEAD_DBG(head, "%08x", mask[head->id]);
        }
 
-       if (disp->super & 0x00000001) {
+       if (disp->super.pending & 0x00000001) {
                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
                nv50_disp_super_1(disp);
-               list_for_each_entry(head, &disp->base.head, head) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_1_0(disp, head);
                }
        } else
-       if (disp->super & 0x00000002) {
-               list_for_each_entry(head, &disp->base.head, head) {
+       if (disp->super.pending & 0x00000002) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_2_0(disp, head);
                }
-               nvkm_outp_route(&disp->base);
-               list_for_each_entry(head, &disp->base.head, head) {
+               nvkm_outp_route(disp);
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00010000))
                                continue;
                        nv50_disp_super_2_1(disp, head);
                }
-               list_for_each_entry(head, &disp->base.head, head) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_2_2(disp, head);
                }
        } else
-       if (disp->super & 0x00000004) {
-               list_for_each_entry(head, &disp->base.head, head) {
+       if (disp->super.pending & 0x00000004) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
                        nv50_disp_super_3_0(disp, head);
                }
        }
 
-       list_for_each_entry(head, &disp->base.head, head)
+       list_for_each_entry(head, &disp->heads, head)
                nvkm_wr32(device, 0x6107ac + (head->id * 4), 0x00000000);
+
        nvkm_wr32(device, 0x6107a8, 0x80000000);
+       mutex_unlock(&disp->super.mutex);
 }
 
 static void
-gv100_disp_exception(struct nv50_disp *disp, int chid)
+gv100_disp_exception(struct nvkm_disp *disp, int chid)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 stat = nvkm_rd32(device, 0x611020 + (chid * 12));
        u32 type = (stat & 0x00007000) >> 12;
@@ -136,16 +914,16 @@ gv100_disp_exception(struct nv50_disp *disp, int chid)
 }
 
 static void
-gv100_disp_intr_ctrl_disp(struct nv50_disp *disp)
+gv100_disp_intr_ctrl_disp(struct nvkm_disp *disp)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 stat = nvkm_rd32(device, 0x611c30);
 
        if (stat & 0x00000007) {
-               disp->super = (stat & 0x00000007);
-               queue_work(disp->wq, &disp->supervisor);
-               nvkm_wr32(device, 0x611860, disp->super);
+               disp->super.pending = (stat & 0x00000007);
+               queue_work(disp->super.wq, &disp->super.work);
+               nvkm_wr32(device, 0x611860, disp->super.pending);
                stat &= ~0x00000007;
        }
 
@@ -184,9 +962,9 @@ gv100_disp_intr_ctrl_disp(struct nv50_disp *disp)
 }
 
 static void
-gv100_disp_intr_exc_other(struct nv50_disp *disp)
+gv100_disp_intr_exc_other(struct nvkm_disp *disp)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 stat = nvkm_rd32(device, 0x611854);
        unsigned long mask;
@@ -213,9 +991,9 @@ gv100_disp_intr_exc_other(struct nv50_disp *disp)
 }
 
 static void
-gv100_disp_intr_exc_winim(struct nv50_disp *disp)
+gv100_disp_intr_exc_winim(struct nvkm_disp *disp)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        unsigned long stat = nvkm_rd32(device, 0x611850);
        int wndw;
@@ -233,9 +1011,9 @@ gv100_disp_intr_exc_winim(struct nv50_disp *disp)
 }
 
 static void
-gv100_disp_intr_exc_win(struct nv50_disp *disp)
+gv100_disp_intr_exc_win(struct nvkm_disp *disp)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        unsigned long stat = nvkm_rd32(device, 0x61184c);
        int wndw;
@@ -253,9 +1031,9 @@ gv100_disp_intr_exc_win(struct nv50_disp *disp)
 }
 
 static void
-gv100_disp_intr_head_timing(struct nv50_disp *disp, int head)
+gv100_disp_intr_head_timing(struct nvkm_disp *disp, int head)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 stat = nvkm_rd32(device, 0x611800 + (head * 0x04));
 
@@ -266,7 +1044,7 @@ gv100_disp_intr_head_timing(struct nv50_disp *disp, int head)
        }
 
        if (stat & 0x00000004) {
-               nvkm_disp_vblank(&disp->base, head);
+               nvkm_disp_vblank(disp, head);
                nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000004);
                stat &= ~0x00000004;
        }
@@ -278,9 +1056,9 @@ gv100_disp_intr_head_timing(struct nv50_disp *disp, int head)
 }
 
 void
-gv100_disp_intr(struct nv50_disp *disp)
+gv100_disp_intr(struct nvkm_disp *disp)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 stat = nvkm_rd32(device, 0x611ec0);
        unsigned long mask;
@@ -318,16 +1096,16 @@ gv100_disp_intr(struct nv50_disp *disp)
 }
 
 void
-gv100_disp_fini(struct nv50_disp *disp)
+gv100_disp_fini(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        nvkm_wr32(device, 0x611db0, 0x00000000);
 }
 
 static int
-gv100_disp_init(struct nv50_disp *disp)
+gv100_disp_init(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        struct nvkm_head *head;
        int i, j;
        u32 tmp;
@@ -354,7 +1132,7 @@ gv100_disp_init(struct nv50_disp *disp)
        }
 
        /* Head capabilities. */
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                const int id = head->id;
 
                /* RG. */
@@ -414,7 +1192,7 @@ gv100_disp_init(struct nv50_disp *disp)
        nvkm_wr32(device, 0x611da4, 0x00000000); /* EN. */
 
        /* HEAD_TIMING(n): VBLANK. */
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                const u32 hoff = head->id * 4;
                nvkm_wr32(device, 0x611cc0 + hoff, 0x00000004); /* MSK. */
                nvkm_wr32(device, 0x611d80 + hoff, 0x00000000); /* EN. */
@@ -426,23 +1204,32 @@ gv100_disp_init(struct nv50_disp *disp)
        return 0;
 }
 
-static const struct nv50_disp_func
+static const struct nvkm_disp_func
 gv100_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = gv100_disp_init,
        .fini = gv100_disp_fini,
        .intr = gv100_disp_intr,
-       .uevent = &gv100_disp_chan_uevent,
        .super = gv100_disp_super,
-       .root = &gv100_disp_root_oclass,
+       .uevent = &gv100_disp_chan_uevent,
        .wndw = { .cnt = gv100_disp_wndw_cnt },
        .head = { .cnt = gv100_head_cnt, .new = gv100_head_new },
        .sor = { .cnt = gv100_sor_cnt, .new = gv100_sor_new },
        .ramht_size = 0x2000,
+       .root = {  0, 0,GV100_DISP },
+       .user = {
+               {{-1,-1,GV100_DISP_CAPS                  }, gv100_disp_caps_new },
+               {{ 0, 0,GV100_DISP_CURSOR                },  nvkm_disp_chan_new, &gv100_disp_curs },
+               {{ 0, 0,GV100_DISP_WINDOW_IMM_CHANNEL_DMA},  nvkm_disp_wndw_new, &gv100_disp_wimm },
+               {{ 0, 0,GV100_DISP_CORE_CHANNEL_DMA      },  nvkm_disp_core_new, &gv100_disp_core },
+               {{ 0, 0,GV100_DISP_WINDOW_CHANNEL_DMA    },  nvkm_disp_wndw_new, &gv100_disp_wndw },
+               {}
+       },
 };
 
 int
 gv100_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&gv100_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&gv100_disp, device, type, inst, pdisp);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c
deleted file mode 100644 (file)
index 19d2d58..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-void
-gf119_hda_device_entry(struct nvkm_ior *ior, int head)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 hoff = 0x800 * head;
-       nvkm_mask(device, 0x616548 + hoff, 0x00000070, head << 4);
-}
-
-void
-gf119_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 soff = 0x030 * ior->id + (head * 0x04);
-       int i;
-
-       for (i = 0; i < size; i++)
-               nvkm_wr32(device, 0x10ec00 + soff, (i << 8) | data[i]);
-       for (; i < 0x60; i++)
-               nvkm_wr32(device, 0x10ec00 + soff, (i << 8));
-       nvkm_mask(device, 0x10ec10 + soff, 0x80000002, 0x80000002);
-}
-
-void
-gf119_hda_hpd(struct nvkm_ior *ior, int head, bool present)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 soff = 0x030 * ior->id + (head * 0x04);
-       u32 data = 0x80000000;
-       u32 mask = 0x80000001;
-       if (present) {
-               ior->func->hda.device_entry(ior, head);
-               data |= 0x00000001;
-       } else {
-               mask |= 0x00000002;
-       }
-       nvkm_mask(device, 0x10ec10 + soff, mask, data);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c
deleted file mode 100644 (file)
index 0d1b81f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-void
-gt215_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 soff = ior->id * 0x800;
-       int i;
-
-       for (i = 0; i < size; i++)
-               nvkm_wr32(device, 0x61c440 + soff, (i << 8) | data[i]);
-       for (; i < 0x60; i++)
-               nvkm_wr32(device, 0x61c440 + soff, (i << 8));
-       nvkm_mask(device, 0x61c448 + soff, 0x80000002, 0x80000002);
-}
-
-void
-gt215_hda_hpd(struct nvkm_ior *ior, int head, bool present)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       u32 data = 0x80000000;
-       u32 mask = 0x80000001;
-       if (present)
-               data |= 0x00000001;
-       else
-               mask |= 0x00000002;
-       nvkm_mask(device, 0x61c448 + ior->id * 0x800, mask, data);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c
deleted file mode 100644 (file)
index 57d374e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2020 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-void
-gv100_hda_device_entry(struct nvkm_ior *ior, int head)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 hoff = 0x800 * head;
-       nvkm_mask(device, 0x616528 + hoff, 0x00000070, head << 4);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
deleted file mode 100644 (file)
index 661410f..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "hdmi.h"
-
-void
-g84_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
-             u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 ctrl = 0x40000000 * enable |
-                        0x1f000000 /* ??? */ |
-                        max_ac_packet << 16 |
-                        rekey;
-       const u32 hoff = head * 0x800;
-       struct packed_hdmi_infoframe avi_infoframe;
-       struct packed_hdmi_infoframe vendor_infoframe;
-
-       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
-       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
-
-       if (!(ctrl & 0x40000000)) {
-               nvkm_mask(device, 0x6165a4 + hoff, 0x40000000, 0x00000000);
-               nvkm_mask(device, 0x61653c + hoff, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000000);
-               return;
-       }
-
-       /* AVI InfoFrame */
-       nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000000);
-       if (avi_size) {
-               nvkm_wr32(device, 0x616528 + hoff, avi_infoframe.header);
-               nvkm_wr32(device, 0x61652c + hoff, avi_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x616530 + hoff, avi_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x616534 + hoff, avi_infoframe.subpack1_low);
-               nvkm_wr32(device, 0x616538 + hoff, avi_infoframe.subpack1_high);
-               nvkm_mask(device, 0x616520 + hoff, 0x00000001, 0x00000001);
-       }
-
-       /* Audio InfoFrame */
-       nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000000);
-       nvkm_wr32(device, 0x616508 + hoff, 0x000a0184);
-       nvkm_wr32(device, 0x61650c + hoff, 0x00000071);
-       nvkm_wr32(device, 0x616510 + hoff, 0x00000000);
-       nvkm_mask(device, 0x616500 + hoff, 0x00000001, 0x00000001);
-
-       /* Vendor InfoFrame */
-       nvkm_mask(device, 0x61653c + hoff, 0x00010001, 0x00010000);
-       if (vendor_size) {
-               nvkm_wr32(device, 0x616544 + hoff, vendor_infoframe.header);
-               nvkm_wr32(device, 0x616548 + hoff, vendor_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x61654c + hoff, vendor_infoframe.subpack0_high);
-               /* Is there a second (or up to fourth?) set of subpack registers here? */
-               /* nvkm_wr32(device, 0x616550 + hoff, vendor_infoframe->subpack1_low); */
-               /* nvkm_wr32(device, 0x616554 + hoff, vendor_infoframe->subpack1_high); */
-               nvkm_mask(device, 0x61653c + hoff, 0x00010001, 0x00010001);
-       }
-
-       nvkm_mask(device, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
-       nvkm_mask(device, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
-       nvkm_mask(device, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
-
-       /* ??? */
-       nvkm_mask(device, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
-       nvkm_mask(device, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
-       nvkm_mask(device, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
-
-       /* HDMI_CTRL */
-       nvkm_mask(device, 0x6165a4 + hoff, 0x5f1f007f, ctrl);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf119.c
deleted file mode 100644 (file)
index 6cac0e7..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "hdmi.h"
-
-void
-gf119_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
-               u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 ctrl = 0x40000000 * enable |
-                        max_ac_packet << 16 |
-                        rekey;
-       const u32 hoff = head * 0x800;
-       struct packed_hdmi_infoframe avi_infoframe;
-       struct packed_hdmi_infoframe vendor_infoframe;
-
-       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
-       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
-
-       if (!(ctrl & 0x40000000)) {
-               nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
-               nvkm_mask(device, 0x616730 + hoff, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x616714 + hoff, 0x00000001, 0x00000000);
-               return;
-       }
-
-       /* AVI InfoFrame */
-       nvkm_mask(device, 0x616714 + hoff, 0x00000001, 0x00000000);
-       if (avi_size) {
-               nvkm_wr32(device, 0x61671c + hoff, avi_infoframe.header);
-               nvkm_wr32(device, 0x616720 + hoff, avi_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x616724 + hoff, avi_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x616728 + hoff, avi_infoframe.subpack1_low);
-               nvkm_wr32(device, 0x61672c + hoff, avi_infoframe.subpack1_high);
-               nvkm_mask(device, 0x616714 + hoff, 0x00000001, 0x00000001);
-       }
-
-       /* GENERIC(?) / Vendor InfoFrame? */
-       nvkm_mask(device, 0x616730 + hoff, 0x00010001, 0x00010000);
-       if (vendor_size) {
-               /*
-                * These appear to be the audio infoframe registers,
-                * but no other set of infoframe registers has yet
-                * been found.
-                */
-               nvkm_wr32(device, 0x616738 + hoff, vendor_infoframe.header);
-               nvkm_wr32(device, 0x61673c + hoff, vendor_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x616740 + hoff, vendor_infoframe.subpack0_high);
-               /* Is there a second (or further?) set of subpack registers here? */
-               nvkm_mask(device, 0x616730 + hoff, 0x00000001, 0x00000001);
-       }
-
-       /* ??? InfoFrame? */
-       nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000000);
-       nvkm_wr32(device, 0x6167ac + hoff, 0x00000010);
-       nvkm_mask(device, 0x6167a4 + hoff, 0x00000001, 0x00000001);
-
-       /* HDMI_CTRL */
-       nvkm_mask(device, 0x616798 + hoff, 0x401f007f, ctrl);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
deleted file mode 100644 (file)
index ed0a610..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2014 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "hdmi.h"
-
-void
-gk104_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
-               u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 ctrl = 0x40000000 * enable |
-                        max_ac_packet << 16 |
-                        rekey;
-       const u32 hoff = head * 0x800;
-       const u32 hdmi = head * 0x400;
-       struct packed_hdmi_infoframe avi_infoframe;
-       struct packed_hdmi_infoframe vendor_infoframe;
-
-       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
-       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
-
-       if (!(ctrl & 0x40000000)) {
-               nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000);
-               nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
-               return;
-       }
-
-       /* AVI InfoFrame */
-       nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000);
-       if (avi_size) {
-               nvkm_wr32(device, 0x690008 + hdmi, avi_infoframe.header);
-               nvkm_wr32(device, 0x69000c + hdmi, avi_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x690010 + hdmi, avi_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x690014 + hdmi, avi_infoframe.subpack1_low);
-               nvkm_wr32(device, 0x690018 + hdmi, avi_infoframe.subpack1_high);
-               nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000001);
-       }
-
-       /* GENERIC(?) / Vendor InfoFrame? */
-       nvkm_mask(device, 0x690100 + hdmi, 0x00010001, 0x00000000);
-       if (vendor_size) {
-               nvkm_wr32(device, 0x690108 + hdmi, vendor_infoframe.header);
-               nvkm_wr32(device, 0x69010c + hdmi, vendor_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x690110 + hdmi, vendor_infoframe.subpack0_high);
-               /* Is there a second (or further?) set of subpack registers here? */
-               nvkm_mask(device, 0x690100 + hdmi, 0x00000001, 0x00000001);
-       }
-
-
-       /* ??? InfoFrame? */
-       nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000);
-       nvkm_wr32(device, 0x6900cc + hdmi, 0x00000010);
-       nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000001);
-
-       /* ??? */
-       nvkm_wr32(device, 0x690080 + hdmi, 0x82000000);
-
-       /* HDMI_CTRL */
-       nvkm_mask(device, 0x616798 + hoff, 0x401f007f, ctrl);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
deleted file mode 100644 (file)
index bb32bef..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2018 Ilia Mirkin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ilia Mirkin
- */
-#include "hdmi.h"
-
-void
-gm200_hdmi_scdc(struct nvkm_ior *ior, u8 scdc)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(ior);
-       const u32 ctrl = scdc & 0x3;
-
-       nvkm_mask(device, 0x61c5bc + soff, 0x00000003, ctrl);
-
-       ior->tmds.high_speed = !!(scdc & 0x2);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c
deleted file mode 100644 (file)
index 0993d22..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "hdmi.h"
-
-void
-gt215_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
-               u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 ctrl = 0x40000000 * enable |
-                        0x1f000000 /* ??? */ |
-                        max_ac_packet << 16 |
-                        rekey;
-       const u32 soff = nv50_ior_base(ior);
-       struct packed_hdmi_infoframe avi_infoframe;
-       struct packed_hdmi_infoframe vendor_infoframe;
-
-       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
-       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
-
-       if (!(ctrl & 0x40000000)) {
-               nvkm_mask(device, 0x61c5a4 + soff, 0x40000000, 0x00000000);
-               nvkm_mask(device, 0x61c53c + soff, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x61c500 + soff, 0x00000001, 0x00000000);
-               return;
-       }
-
-       /* AVI InfoFrame */
-       nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000000);
-       if (avi_size) {
-               nvkm_wr32(device, 0x61c528 + soff, avi_infoframe.header);
-               nvkm_wr32(device, 0x61c52c + soff, avi_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x61c530 + soff, avi_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x61c534 + soff, avi_infoframe.subpack1_low);
-               nvkm_wr32(device, 0x61c538 + soff, avi_infoframe.subpack1_high);
-               nvkm_mask(device, 0x61c520 + soff, 0x00000001, 0x00000001);
-       }
-
-       /* Audio InfoFrame */
-       nvkm_mask(device, 0x61c500 + soff, 0x00000001, 0x00000000);
-       nvkm_wr32(device, 0x61c508 + soff, 0x000a0184);
-       nvkm_wr32(device, 0x61c50c + soff, 0x00000071);
-       nvkm_wr32(device, 0x61c510 + soff, 0x00000000);
-       nvkm_mask(device, 0x61c500 + soff, 0x00000001, 0x00000001);
-
-       /* Vendor InfoFrame */
-       nvkm_mask(device, 0x61c53c + soff, 0x00010001, 0x00010000);
-       if (vendor_size) {
-               nvkm_wr32(device, 0x61c544 + soff, vendor_infoframe.header);
-               nvkm_wr32(device, 0x61c548 + soff, vendor_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x61c54c + soff, vendor_infoframe.subpack0_high);
-               /* Is there a second (or up to fourth?) set of subpack registers here? */
-               /* nvkm_wr32(device, 0x61c550 + soff, vendor_infoframe.subpack1_low); */
-               /* nvkm_wr32(device, 0x61c554 + soff, vendor_infoframe.subpack1_high); */
-               nvkm_mask(device, 0x61c53c + soff, 0x00010001, 0x00010001);
-       }
-
-       nvkm_mask(device, 0x61c5d0 + soff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
-       nvkm_mask(device, 0x61c568 + soff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
-       nvkm_mask(device, 0x61c578 + soff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
-
-       /* ??? */
-       nvkm_mask(device, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
-       nvkm_mask(device, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
-       nvkm_mask(device, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
-
-       /* HDMI_CTRL */
-       nvkm_mask(device, 0x61c5a4 + soff, 0x5f1f007f, ctrl);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c
deleted file mode 100644 (file)
index 3ff4934..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "hdmi.h"
-
-void
-gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
-               u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
-{
-       struct nvkm_device *device = ior->disp->engine.subdev.device;
-       const u32 ctrl = 0x40000000 * enable |
-                        max_ac_packet << 16 |
-                        rekey;
-       const u32 hoff = head * 0x800;
-       const u32 hdmi = head * 0x400;
-       struct packed_hdmi_infoframe avi_infoframe;
-       struct packed_hdmi_infoframe vendor_infoframe;
-
-       pack_hdmi_infoframe(&avi_infoframe, avi, avi_size);
-       pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size);
-
-       if (!(ctrl & 0x40000000)) {
-               nvkm_mask(device, 0x6165c0 + hoff, 0x40000000, 0x00000000);
-               nvkm_mask(device, 0x6f0100 + hdmi, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
-               nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000000);
-               return;
-       }
-
-       /* AVI InfoFrame (AVI). */
-       nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000000);
-       if (avi_size) {
-               nvkm_wr32(device, 0x6f0008 + hdmi, avi_infoframe.header);
-               nvkm_wr32(device, 0x6f000c + hdmi, avi_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x6f0010 + hdmi, avi_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x6f0014 + hdmi, avi_infoframe.subpack1_low);
-               nvkm_wr32(device, 0x6f0018 + hdmi, avi_infoframe.subpack1_high);
-               nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000001);
-       }
-
-       /* Vendor-specific InfoFrame (VSI). */
-       nvkm_mask(device, 0x6f0100 + hdmi, 0x00010001, 0x00000000);
-       if (vendor_size) {
-               nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header);
-               nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low);
-               nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high);
-               nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000);
-               nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000);
-               nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000);
-               nvkm_wr32(device, 0x6f0120 + hdmi, 0x00000000);
-               nvkm_wr32(device, 0x6f0124 + hdmi, 0x00000000);
-               nvkm_mask(device, 0x6f0100 + hdmi, 0x00000001, 0x00000001);
-       }
-
-
-       /* General Control (GCP). */
-       nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
-       nvkm_wr32(device, 0x6f00cc + hdmi, 0x00000010);
-       nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001);
-
-       /* Audio Clock Regeneration (ACR). */
-       nvkm_wr32(device, 0x6f0080 + hdmi, 0x82000000);
-
-       /* NV_PDISP_SF_HDMI_CTRL. */
-       nvkm_mask(device, 0x6165c0 + hoff, 0x401f007f, ctrl);
-}
index 5c557f3..83152c2 100644 (file)
@@ -32,7 +32,7 @@ struct nvkm_head *
 nvkm_head_find(struct nvkm_disp *disp, int id)
 {
        struct nvkm_head *head;
-       list_for_each_entry(head, &disp->head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                if (head->id == id)
                        return head;
        }
@@ -99,7 +99,7 @@ nvkm_head_new_(const struct nvkm_head_func *func,
        head->func = func;
        head->disp = disp;
        head->id = id;
-       list_add_tail(&head->head, &disp->head);
+       list_add_tail(&head->head, &disp->heads);
        HEAD_DBG(head, "ctor");
        return 0;
 }
index 7dde623..84a2989 100644 (file)
@@ -42,19 +42,9 @@ struct nvkm_head_func {
        void (*vblank_put)(struct nvkm_head *);
 };
 
-void nv50_head_rgpos(struct nvkm_head *, u16 *, u16 *);
-
-#define HEAD_MSG(h,l,f,a...) do {                                              \
-       struct nvkm_head *_h = (h);                                            \
-       nvkm_##l(&_h->disp->engine.subdev, "head-%d: "f"\n", _h->id, ##a);     \
-} while(0)
-#define HEAD_WARN(h,f,a...) HEAD_MSG((h), warn, f, ##a)
-#define HEAD_DBG(h,f,a...) HEAD_MSG((h), debug, f, ##a)
-
-int nv04_head_new(struct nvkm_disp *, int id);
-
 int nv50_head_cnt(struct nvkm_disp *, unsigned long *);
 int nv50_head_new(struct nvkm_disp *, int id);
+void nv50_head_rgpos(struct nvkm_head *, u16 *, u16 *);
 
 int gf119_head_cnt(struct nvkm_disp *, unsigned long *);
 int gf119_head_new(struct nvkm_disp *, int id);
@@ -62,4 +52,11 @@ void gf119_head_rgclk(struct nvkm_head *, int);
 
 int gv100_head_cnt(struct nvkm_disp *, unsigned long *);
 int gv100_head_new(struct nvkm_disp *, int id);
+
+#define HEAD_MSG(h,l,f,a...) do {                                              \
+       struct nvkm_head *_h = (h);                                            \
+       nvkm_##l(&_h->disp->engine.subdev, "head-%d: "f"\n", _h->id, ##a);     \
+} while(0)
+#define HEAD_WARN(h,f,a...) HEAD_MSG((h), warn, f, ##a)
+#define HEAD_DBG(h,f,a...) HEAD_MSG((h), debug, f, ##a)
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
deleted file mode 100644 (file)
index e86298b..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "head.h"
-
-static void
-gf119_head_vblank_put(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = head->id * 0x800;
-       nvkm_mask(device, 0x6100c0 + hoff, 0x00000001, 0x00000000);
-}
-
-static void
-gf119_head_vblank_get(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = head->id * 0x800;
-       nvkm_mask(device, 0x6100c0 + hoff, 0x00000001, 0x00000001);
-}
-
-void
-gf119_head_rgclk(struct nvkm_head *head, int div)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_mask(device, 0x612200 + (head->id * 0x800), 0x0000000f, div);
-}
-
-static void
-gf119_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = (state == &head->asy) * 0x20000 + head->id * 0x300;
-       u32 data;
-
-       data = nvkm_rd32(device, 0x640414 + hoff);
-       state->vtotal = (data & 0xffff0000) >> 16;
-       state->htotal = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x640418 + hoff);
-       state->vsynce = (data & 0xffff0000) >> 16;
-       state->hsynce = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x64041c + hoff);
-       state->vblanke = (data & 0xffff0000) >> 16;
-       state->hblanke = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x640420 + hoff);
-       state->vblanks = (data & 0xffff0000) >> 16;
-       state->hblanks = (data & 0x0000ffff);
-       state->hz = nvkm_rd32(device, 0x640450 + hoff);
-
-       data = nvkm_rd32(device, 0x640404 + hoff);
-       switch ((data & 0x000003c0) >> 6) {
-       case 6: state->or.depth = 30; break;
-       case 5: state->or.depth = 24; break;
-       case 2: state->or.depth = 18; break;
-       case 0: state->or.depth = 18; break; /*XXX: "default" */
-       default:
-               state->or.depth = 18;
-               WARN_ON(1);
-               break;
-       }
-}
-
-static const struct nvkm_head_func
-gf119_head = {
-       .state = gf119_head_state,
-       .rgpos = nv50_head_rgpos,
-       .rgclk = gf119_head_rgclk,
-       .vblank_get = gf119_head_vblank_get,
-       .vblank_put = gf119_head_vblank_put,
-};
-
-int
-gf119_head_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_head_new_(&gf119_head, disp, id);
-}
-
-int
-gf119_head_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = nvkm_rd32(device, 0x612004) & 0x0000000f;
-       return nvkm_rd32(device, 0x022448);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c
deleted file mode 100644 (file)
index 1a061b4..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "head.h"
-
-static void
-gv100_head_vblank_put(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000000);
-}
-
-static void
-gv100_head_vblank_get(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000004);
-}
-
-static void
-gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = head->id * 0x800;
-       /* vline read locks hline. */
-       *vline = nvkm_rd32(device, 0x616330 + hoff) & 0x0000ffff;
-       *hline = nvkm_rd32(device, 0x616334 + hoff) & 0x0000ffff;
-}
-
-static void
-gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = (state == &head->arm) * 0x8000 + head->id * 0x400;
-       u32 data;
-
-       data = nvkm_rd32(device, 0x682064 + hoff);
-       state->vtotal = (data & 0xffff0000) >> 16;
-       state->htotal = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x682068 + hoff);
-       state->vsynce = (data & 0xffff0000) >> 16;
-       state->hsynce = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x68206c + hoff);
-       state->vblanke = (data & 0xffff0000) >> 16;
-       state->hblanke = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x682070 + hoff);
-       state->vblanks = (data & 0xffff0000) >> 16;
-       state->hblanks = (data & 0x0000ffff);
-       state->hz = nvkm_rd32(device, 0x68200c + hoff);
-
-       data = nvkm_rd32(device, 0x682004 + hoff);
-       switch ((data & 0x000000f0) >> 4) {
-       case 5: state->or.depth = 30; break;
-       case 4: state->or.depth = 24; break;
-       case 1: state->or.depth = 18; break;
-       default:
-               state->or.depth = 18;
-               WARN_ON(1);
-               break;
-       }
-}
-
-static const struct nvkm_head_func
-gv100_head = {
-       .state = gv100_head_state,
-       .rgpos = gv100_head_rgpos,
-       .rgclk = gf119_head_rgclk,
-       .vblank_get = gv100_head_vblank_get,
-       .vblank_put = gv100_head_vblank_put,
-};
-
-int
-gv100_head_new(struct nvkm_disp *disp, int id)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       if (!(nvkm_rd32(device, 0x610060) & (0x00000001 << id)))
-               return 0;
-       return nvkm_head_new_(&gv100_head, disp, id);
-}
-
-int
-gv100_head_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = nvkm_rd32(device, 0x610060) & 0x000000ff;
-       return nvkm_rd32(device, 0x610074) & 0x0000000f;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv04.c
deleted file mode 100644 (file)
index dcf4592..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "head.h"
-
-static void
-nv04_head_vblank_put(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_wr32(device, 0x600140 + (head->id * 0x2000) , 0x00000000);
-}
-
-static void
-nv04_head_vblank_get(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_wr32(device, 0x600140 + (head->id * 0x2000) , 0x00000001);
-}
-
-static void
-nv04_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       u32 data = nvkm_rd32(device, 0x600868 + (head->id * 0x2000));
-       *hline = (data & 0xffff0000) >> 16;
-       *vline = (data & 0x0000ffff);
-}
-
-static void
-nv04_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = head->id * 0x0200;
-       state->vblanks = nvkm_rd32(device, 0x680800 + hoff) & 0x0000ffff;
-       state->vtotal  = nvkm_rd32(device, 0x680804 + hoff) & 0x0000ffff;
-       state->vblanke = state->vtotal - 1;
-       state->hblanks = nvkm_rd32(device, 0x680820 + hoff) & 0x0000ffff;
-       state->htotal  = nvkm_rd32(device, 0x680824 + hoff) & 0x0000ffff;
-       state->hblanke = state->htotal - 1;
-}
-
-static const struct nvkm_head_func
-nv04_head = {
-       .state = nv04_head_state,
-       .rgpos = nv04_head_rgpos,
-       .vblank_get = nv04_head_vblank_get,
-       .vblank_put = nv04_head_vblank_put,
-};
-
-int
-nv04_head_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_head_new_(&nv04_head, disp, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c
deleted file mode 100644 (file)
index e7d5c39..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "head.h"
-
-static void
-nv50_head_vblank_put(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_mask(device, 0x61002c, (4 << head->id), 0);
-}
-
-static void
-nv50_head_vblank_get(struct nvkm_head *head)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_mask(device, 0x61002c, (4 << head->id), (4 << head->id));
-}
-
-static void
-nv50_head_rgclk(struct nvkm_head *head, int div)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       nvkm_mask(device, 0x614200 + (head->id * 0x800), 0x0000000f, div);
-}
-
-void
-nv50_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = head->id * 0x800;
-       /* vline read locks hline. */
-       *vline = nvkm_rd32(device, 0x616340 + hoff) & 0x0000ffff;
-       *hline = nvkm_rd32(device, 0x616344 + hoff) & 0x0000ffff;
-}
-
-static void
-nv50_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-       struct nvkm_device *device = head->disp->engine.subdev.device;
-       const u32 hoff = head->id * 0x540 + (state == &head->arm) * 4;
-       u32 data;
-
-       data = nvkm_rd32(device, 0x610ae8 + hoff);
-       state->vblanke = (data & 0xffff0000) >> 16;
-       state->hblanke = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x610af0 + hoff);
-       state->vblanks = (data & 0xffff0000) >> 16;
-       state->hblanks = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x610af8 + hoff);
-       state->vtotal = (data & 0xffff0000) >> 16;
-       state->htotal = (data & 0x0000ffff);
-       data = nvkm_rd32(device, 0x610b00 + hoff);
-       state->vsynce = (data & 0xffff0000) >> 16;
-       state->hsynce = (data & 0x0000ffff);
-       state->hz = (nvkm_rd32(device, 0x610ad0 + hoff) & 0x003fffff) * 1000;
-}
-
-static const struct nvkm_head_func
-nv50_head = {
-       .state = nv50_head_state,
-       .rgpos = nv50_head_rgpos,
-       .rgclk = nv50_head_rgclk,
-       .vblank_get = nv50_head_vblank_get,
-       .vblank_put = nv50_head_vblank_put,
-};
-
-int
-nv50_head_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_head_new_(&nv50_head, disp, id);
-}
-
-int
-nv50_head_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       *pmask = 3;
-       return 2;
-}
index a475ea5..e420bf2 100644 (file)
@@ -34,7 +34,7 @@ struct nvkm_ior *
 nvkm_ior_find(struct nvkm_disp *disp, enum nvkm_ior_type type, int id)
 {
        struct nvkm_ior *ior;
-       list_for_each_entry(ior, &disp->ior, head) {
+       list_for_each_entry(ior, &disp->iors, head) {
                if (ior->type == type && (id < 0 || ior->id == id))
                        return ior;
        }
@@ -55,7 +55,7 @@ nvkm_ior_del(struct nvkm_ior **pior)
 
 int
 nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp,
-             enum nvkm_ior_type type, int id)
+             enum nvkm_ior_type type, int id, bool hda)
 {
        struct nvkm_ior *ior;
        if (!(ior = kzalloc(sizeof(*ior), GFP_KERNEL)))
@@ -64,9 +64,9 @@ nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp,
        ior->disp = disp;
        ior->type = type;
        ior->id = id;
-       snprintf(ior->name, sizeof(ior->name), "%s-%d",
-                nvkm_ior_name[ior->type], ior->id);
-       list_add_tail(&ior->head, &disp->ior);
+       ior->hda = hda;
+       snprintf(ior->name, sizeof(ior->name), "%s-%d", nvkm_ior_name[ior->type], ior->id);
+       list_add_tail(&ior->head, &disp->iors);
        IOR_DBG(ior, "ctor");
        return 0;
 }
index 9f0bb7c..671c467 100644 (file)
@@ -13,6 +13,7 @@ struct nvkm_ior {
                PIOR,
        } type;
        int id;
+       bool hda;
        char name[8];
 
        struct list_head head;
@@ -69,7 +70,7 @@ struct nvkm_ior_func {
                void (*scdc)(struct nvkm_ior *, u8 scdc);
        } hdmi;
 
-       struct {
+       const struct nvkm_ior_func_dp {
                u8 lanes[4];
                int (*links)(struct nvkm_ior *, struct nvkm_i2c_aux *);
                void (*power)(struct nvkm_ior *, int nr);
@@ -83,17 +84,17 @@ struct nvkm_ior_func {
                void (*activesym)(struct nvkm_ior *, int head,
                                  u8 TU, u8 VTUa, u8 VTUf, u8 VTUi);
                void (*watermark)(struct nvkm_ior *, int head, u8 watermark);
-       } dp;
+       } *dp;
 
-       struct {
+       const struct nvkm_ior_func_hda {
                void (*hpd)(struct nvkm_ior *, int head, bool present);
                void (*eld)(struct nvkm_ior *, int head, u8 *data, u8 size);
                void (*device_entry)(struct nvkm_ior *, int head);
-       } hda;
+       } *hda;
 };
 
 int nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *,
-                 enum nvkm_ior_type type, int id);
+                 enum nvkm_ior_type type, int id, bool hda);
 void nvkm_ior_del(struct nvkm_ior **);
 struct nvkm_ior *nvkm_ior_find(struct nvkm_disp *, enum nvkm_ior_type, int id);
 
@@ -103,10 +104,13 @@ nv50_ior_base(struct nvkm_ior *ior)
        return ior->id * 0x800;
 }
 
+int nv50_dac_cnt(struct nvkm_disp *, unsigned long *);
+int nv50_dac_new(struct nvkm_disp *, int);
 void nv50_dac_power(struct nvkm_ior *, bool, bool, bool, bool, bool);
 int nv50_dac_sense(struct nvkm_ior *, u32);
 
-void nv50_pior_depth(struct nvkm_ior *, struct nvkm_ior_state *, u32 ctrl);
+int gf119_dac_cnt(struct nvkm_disp *, unsigned long *);
+int gf119_dac_new(struct nvkm_disp *, int);
 
 static inline u32
 nv50_sor_link(struct nvkm_ior *ior)
@@ -114,11 +118,17 @@ nv50_sor_link(struct nvkm_ior *ior)
        return nv50_ior_base(ior) + ((ior->asy.link == 2) * 0x80);
 }
 
+int nv50_sor_cnt(struct nvkm_disp *, unsigned long *);
 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 *);
 
+int g84_sor_new(struct nvkm_disp *, int);
+void g84_sor_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
+
+int g94_sor_cnt(struct nvkm_disp *, unsigned long *);
 void g94_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
+extern const struct nvkm_ior_func_dp g94_sor_dp;
 int g94_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
 void g94_sor_dp_power(struct nvkm_ior *, int);
 void g94_sor_dp_pattern(struct nvkm_ior *, int);
@@ -127,47 +137,50 @@ void g94_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32);
 void g94_sor_dp_activesym(struct nvkm_ior *, int, u8, u8, u8, u8);
 void g94_sor_dp_watermark(struct nvkm_ior *, int, u8);
 
+void gt215_sor_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
 void gt215_sor_dp_audio(struct nvkm_ior *, int, bool);
+extern const struct nvkm_ior_func_hda gt215_sor_hda;
 
+int gf119_sor_cnt(struct nvkm_disp *, unsigned long *);
 void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
 void gf119_sor_clock(struct nvkm_ior *);
+extern const struct nvkm_ior_func_dp gf119_sor_dp;
 int gf119_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
-void gf119_sor_dp_pattern(struct nvkm_ior *, int);
 void gf119_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
 void gf119_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16);
 void gf119_sor_dp_audio(struct nvkm_ior *, int, bool);
 void gf119_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32);
 void gf119_sor_dp_watermark(struct nvkm_ior *, int, u8);
+extern const struct nvkm_ior_func_hda gf119_sor_hda;
+void gf119_sor_hda_hpd(struct nvkm_ior *, int, bool);
+void gf119_sor_hda_eld(struct nvkm_ior *, int, u8 *, u8);
+
+int gk104_sor_new(struct nvkm_disp *, int);
+void gk104_sor_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
 
 void gm107_sor_dp_pattern(struct nvkm_ior *, int);
 
 void gm200_sor_route_set(struct nvkm_outp *, struct nvkm_ior *);
 int gm200_sor_route_get(struct nvkm_outp *, int *);
+void gm200_sor_hdmi_scdc(struct nvkm_ior *, u8);
+extern const struct nvkm_ior_func_dp gm200_sor_dp;
 void gm200_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
 
+int gp100_sor_new(struct nvkm_disp *, int);
+
+int gv100_sor_cnt(struct nvkm_disp *, unsigned long *);
 void gv100_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
+void gv100_sor_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
 void gv100_sor_dp_audio(struct nvkm_ior *, int, bool);
 void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32);
 void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8);
+extern const struct nvkm_ior_func_hda gv100_sor_hda;
 
 void tu102_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16);
 
-void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
-void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
-void gf119_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
-void gk104_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
-void gv100_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
-
-void gm200_hdmi_scdc(struct nvkm_ior *, u8);
-
-void gt215_hda_hpd(struct nvkm_ior *, int, bool);
-void gt215_hda_eld(struct nvkm_ior *, int, u8 *, u8);
-
-void gf119_hda_hpd(struct nvkm_ior *, int, bool);
-void gf119_hda_eld(struct nvkm_ior *, int, u8 *, u8);
-void gf119_hda_device_entry(struct nvkm_ior *, int);
-
-void gv100_hda_device_entry(struct nvkm_ior *, int);
+int nv50_pior_cnt(struct nvkm_disp *, unsigned long *);
+int nv50_pior_new(struct nvkm_disp *, int);
+void nv50_pior_depth(struct nvkm_ior *, struct nvkm_ior_state *, u32 ctrl);
 
 #define IOR_MSG(i,l,f,a...) do {                                               \
        struct nvkm_ior *_ior = (i);                                           \
@@ -175,40 +188,4 @@ void gv100_hda_device_entry(struct nvkm_ior *, int);
 } while(0)
 #define IOR_WARN(i,f,a...) IOR_MSG((i), warn, f, ##a)
 #define IOR_DBG(i,f,a...) IOR_MSG((i), debug, f, ##a)
-
-int nv50_dac_cnt(struct nvkm_disp *, unsigned long *);
-int nv50_dac_new(struct nvkm_disp *, int);
-
-int gf119_dac_cnt(struct nvkm_disp *, unsigned long *);
-int gf119_dac_new(struct nvkm_disp *, int);
-
-int nv50_pior_cnt(struct nvkm_disp *, unsigned long *);
-int nv50_pior_new(struct nvkm_disp *, int);
-
-int nv50_sor_cnt(struct nvkm_disp *, unsigned long *);
-int nv50_sor_new(struct nvkm_disp *, int);
-
-int g84_sor_new(struct nvkm_disp *, int);
-
-int g94_sor_cnt(struct nvkm_disp *, unsigned long *);
-int g94_sor_new(struct nvkm_disp *, int);
-
-int mcp77_sor_new(struct nvkm_disp *, int);
-int gt215_sor_new(struct nvkm_disp *, int);
-int mcp89_sor_new(struct nvkm_disp *, int);
-
-int gf119_sor_cnt(struct nvkm_disp *, unsigned long *);
-int gf119_sor_new(struct nvkm_disp *, int);
-
-int gk104_sor_new(struct nvkm_disp *, int);
-int gm107_sor_new(struct nvkm_disp *, int);
-int gm200_sor_new(struct nvkm_disp *, int);
-int gp100_sor_new(struct nvkm_disp *, int);
-
-int gv100_sor_cnt(struct nvkm_disp *, unsigned long *);
-int gv100_sor_new(struct nvkm_disp *, int);
-
-int tu102_sor_new(struct nvkm_disp *, int);
-
-int ga102_sor_new(struct nvkm_disp *, int);
 #endif
index 762a59f..916b1d4 100644 (file)
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+static const struct nvkm_ior_func
+mcp77_sor = {
+       .state = g94_sor_state,
+       .power = nv50_sor_power,
+       .clock = nv50_sor_clock,
+       .hdmi = {
+               .ctrl = g84_sor_hdmi_ctrl,
+       },
+       .dp = &g94_sor_dp,
+};
+
+static int
+mcp77_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&mcp77_sor, disp, SOR, id, false);
+}
+
+static const struct nvkm_disp_func
 mcp77_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &g94_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = g94_sor_cnt, .new = mcp77_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0,0,GT206_DISP },
+       .user = {
+               {{0,0,  G82_DISP_CURSOR             }, nvkm_disp_chan_new, & nv50_disp_curs },
+               {{0,0,  G82_DISP_OVERLAY            }, nvkm_disp_chan_new, & nv50_disp_oimm },
+               {{0,0,GT200_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &  g84_disp_base },
+               {{0,0,GT206_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &  g94_disp_core },
+               {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, &gt200_disp_ovly },
+               {}
+       },
 };
 
 int
 mcp77_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&mcp77_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&mcp77_disp, device, type, inst, pdisp);
 }
index e5c58aa..a5a0b94 100644 (file)
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "rootnv50.h"
 
-static const struct nv50_disp_func
+#include <nvif/class.h>
+
+static const struct nvkm_ior_func_dp
+mcp89_sor_dp = {
+       .lanes = { 3, 2, 1, 0 },
+       .links = g94_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = g94_sor_dp_pattern,
+       .drive = g94_sor_dp_drive,
+       .audio = gt215_sor_dp_audio,
+       .audio_sym = g94_sor_dp_audio_sym,
+       .activesym = g94_sor_dp_activesym,
+       .watermark = g94_sor_dp_watermark,
+};
+
+static const struct nvkm_ior_func
+mcp89_sor = {
+       .state = g94_sor_state,
+       .power = nv50_sor_power,
+       .clock = nv50_sor_clock,
+       .hdmi = {
+               .ctrl = gt215_sor_hdmi_ctrl,
+       },
+       .dp = &mcp89_sor_dp,
+       .hda = &gt215_sor_hda,
+};
+
+static int
+mcp89_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&mcp89_sor, disp, SOR, id, true);
+}
+
+static const struct nvkm_disp_func
 mcp89_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &gt215_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = g94_sor_cnt, .new = mcp89_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0,0,GT214_DISP },
+       .user = {
+               {{0,0,GT214_DISP_CURSOR             }, nvkm_disp_chan_new, &nv50_disp_curs },
+               {{0,0,GT214_DISP_OVERLAY            }, nvkm_disp_chan_new, &nv50_disp_oimm },
+               {{0,0,GT214_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, & g84_disp_base },
+               {{0,0,GT214_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, & g94_disp_core },
+               {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, & g84_disp_ovly },
+               {}
+       },
 };
 
 int
 mcp89_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&mcp89_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&mcp89_disp, device, type, inst, pdisp);
 }
index a12097d..e4cf11a 100644 (file)
 #include "priv.h"
 #include "head.h"
 
-static const struct nvkm_disp_oclass *
-nv04_disp_root(struct nvkm_disp *disp)
+#include <nvif/class.h>
+
+static void
+nv04_head_vblank_put(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       nvkm_wr32(device, 0x600140 + (head->id * 0x2000) , 0x00000000);
+}
+
+static void
+nv04_head_vblank_get(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       nvkm_wr32(device, 0x600140 + (head->id * 0x2000) , 0x00000001);
+}
+
+static void
+nv04_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       u32 data = nvkm_rd32(device, 0x600868 + (head->id * 0x2000));
+       *hline = (data & 0xffff0000) >> 16;
+       *vline = (data & 0x0000ffff);
+}
+
+static void
+nv04_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = head->id * 0x0200;
+       state->vblanks = nvkm_rd32(device, 0x680800 + hoff) & 0x0000ffff;
+       state->vtotal  = nvkm_rd32(device, 0x680804 + hoff) & 0x0000ffff;
+       state->vblanke = state->vtotal - 1;
+       state->hblanks = nvkm_rd32(device, 0x680820 + hoff) & 0x0000ffff;
+       state->htotal  = nvkm_rd32(device, 0x680824 + hoff) & 0x0000ffff;
+       state->hblanke = state->htotal - 1;
+}
+
+static const struct nvkm_head_func
+nv04_head = {
+       .state = nv04_head_state,
+       .rgpos = nv04_head_rgpos,
+       .vblank_get = nv04_head_vblank_get,
+       .vblank_put = nv04_head_vblank_put,
+};
+
+static int
+nv04_head_new(struct nvkm_disp *disp, int id)
 {
-       return &nv04_disp_root_oclass;
+       return nvkm_head_new_(&nv04_head, disp, id);
 }
 
 static void
@@ -60,7 +106,8 @@ nv04_disp_intr(struct nvkm_disp *disp)
 static const struct nvkm_disp_func
 nv04_disp = {
        .intr = nv04_disp_intr,
-       .root = nv04_disp_root,
+       .root = { 0, 0, NV04_DISP },
+       .user = { {} },
 };
 
 int
index 3f20e49..a46e13c 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "nv50.h"
+#include "priv.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
-#include "channv50.h"
-#include "rootnv50.h"
+#include "outp.h"
 
 #include <core/client.h>
 #include <core/ramht.h>
 #include <subdev/bios/init.h>
 #include <subdev/bios/pll.h>
 #include <subdev/devinit.h>
+#include <subdev/i2c.h>
+#include <subdev/mmu.h>
 #include <subdev/timer.h>
 
-static const struct nvkm_disp_oclass *
-nv50_disp_root_(struct nvkm_disp *base)
+#include <nvif/class.h>
+#include <nvif/unpack.h>
+
+static void
+nv50_pior_clock(struct nvkm_ior *pior)
 {
-       return nv50_disp(base)->func->root;
+       struct nvkm_device *device = pior->disp->engine.subdev.device;
+       const u32 poff = nv50_ior_base(pior);
+
+       nvkm_mask(device, 0x614380 + poff, 0x00000707, 0x00000001);
 }
 
+static int
+nv50_pior_dp_links(struct nvkm_ior *pior, struct nvkm_i2c_aux *aux)
+{
+       int ret = nvkm_i2c_aux_lnk_ctl(aux, pior->dp.nr, pior->dp.bw, pior->dp.ef);
+       if (ret)
+               return ret;
+
+       return 1;
+}
+
+static const struct nvkm_ior_func_dp
+nv50_pior_dp = {
+       .links = nv50_pior_dp_links,
+};
+
 static void
-nv50_disp_intr_(struct nvkm_disp *base)
+nv50_pior_power_wait(struct nvkm_device *device, u32 poff)
 {
-       struct nv50_disp *disp = nv50_disp(base);
-       disp->func->intr(disp);
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x61e004 + poff) & 0x80000000))
+                       break;
+       );
 }
 
 static void
-nv50_disp_fini_(struct nvkm_disp *base)
+nv50_pior_power(struct nvkm_ior *pior, bool normal, bool pu, bool data, bool vsync, bool hsync)
 {
-       struct nv50_disp *disp = nv50_disp(base);
-       disp->func->fini(disp);
+       struct nvkm_device *device = pior->disp->engine.subdev.device;
+       const u32  poff = nv50_ior_base(pior);
+       const u32 shift = normal ? 0 : 16;
+       const u32 state = 0x80000000 | (0x00000001 * !!pu) << shift;
+       const u32 field = 0x80000000 | (0x00000101 << shift);
+
+       nv50_pior_power_wait(device, poff);
+       nvkm_mask(device, 0x61e004 + poff, field, state);
+       nv50_pior_power_wait(device, poff);
 }
 
-static int
-nv50_disp_init_(struct nvkm_disp *base)
+void
+nv50_pior_depth(struct nvkm_ior *ior, struct nvkm_ior_state *state, u32 ctrl)
 {
-       struct nv50_disp *disp = nv50_disp(base);
-       return disp->func->init(disp);
+       /* GF119 moves this information to per-head methods, which is
+        * a lot more convenient, and where our shared code expect it.
+        */
+       if (state->head && state == &ior->asy) {
+               struct nvkm_head *head = nvkm_head_find(ior->disp, __ffs(state->head));
+
+               if (!WARN_ON(!head)) {
+                       struct nvkm_head_state *state = &head->asy;
+                       switch ((ctrl & 0x000f0000) >> 16) {
+                       case 6: state->or.depth = 30; break;
+                       case 5: state->or.depth = 24; break;
+                       case 2: state->or.depth = 18; break;
+                       case 0: state->or.depth = 18; break; /*XXX*/
+                       default:
+                               state->or.depth = 18;
+                               WARN_ON(1);
+                               break;
+                       }
+               }
+       }
 }
 
-static void *
-nv50_disp_dtor_(struct nvkm_disp *base)
+static void
+nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state)
 {
-       struct nv50_disp *disp = nv50_disp(base);
+       struct nvkm_device *device = pior->disp->engine.subdev.device;
+       const u32 coff = pior->id * 8 + (state == &pior->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610b80 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       state->rgdiv = 1;
+       switch (state->proto_evo) {
+       case 0: state->proto = TMDS; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
 
-       nvkm_ramht_del(&disp->ramht);
-       nvkm_gpuobj_del(&disp->inst);
+       state->head = ctrl & 0x00000003;
+       nv50_pior_depth(pior, state, ctrl);
+}
 
-       nvkm_event_fini(&disp->uevent);
-       if (disp->wq)
-               destroy_workqueue(disp->wq);
+static const struct nvkm_ior_func
+nv50_pior = {
+       .state = nv50_pior_state,
+       .power = nv50_pior_power,
+       .clock = nv50_pior_clock,
+       .dp = &nv50_pior_dp,
+};
 
-       return disp;
+int
+nv50_pior_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&nv50_pior, disp, PIOR, id, false);
 }
 
-static int
-nv50_disp_oneinit_(struct nvkm_disp *base)
+int
+nv50_pior_cnt(struct nvkm_disp *disp, unsigned long *pmask)
 {
-       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;
+       struct nvkm_device *device = disp->engine.subdev.device;
 
-       if (func->wndw.cnt) {
-               disp->wndw.nr = func->wndw.cnt(&disp->base, &disp->wndw.mask);
-               nvkm_debug(subdev, "Window(s): %d (%08lx)\n",
-                          disp->wndw.nr, disp->wndw.mask);
+       *pmask = (nvkm_rd32(device, 0x610184) & 0x70000000) >> 28;
+       return 3;
+}
+
+void
+nv50_sor_clock(struct nvkm_ior *sor)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const int  div = sor->asy.link == 3;
+       const u32 soff = nv50_ior_base(sor);
+
+       nvkm_mask(device, 0x614300 + soff, 0x00000707, (div << 8) | div);
+}
+
+static void
+nv50_sor_power_wait(struct nvkm_device *device, u32 soff)
+{
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x61c004 + soff) & 0x80000000))
+                       break;
+       );
+}
+
+void
+nv50_sor_power(struct nvkm_ior *sor, bool normal, bool pu, bool data, bool vsync, bool hsync)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  soff = nv50_ior_base(sor);
+       const u32 shift = normal ? 0 : 16;
+       const u32 state = 0x80000000 | (0x00000001 * !!pu) << shift;
+       const u32 field = 0x80000000 | (0x00000001 << shift);
+
+       nv50_sor_power_wait(device, soff);
+       nvkm_mask(device, 0x61c004 + soff, field, state);
+       nv50_sor_power_wait(device, soff);
+
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
+                       break;
+       );
+}
+
+void
+nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = sor->id * 8 + (state == &sor->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610b70 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
        }
 
-       disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask);
-       nvkm_debug(subdev, "  Head(s): %d (%02lx)\n",
-                  disp->head.nr, disp->head.mask);
-       for_each_set_bit(i, &disp->head.mask, disp->head.nr) {
-               ret = func->head.new(&disp->base, i);
-               if (ret)
-                       return ret;
+       state->head = ctrl & 0x00000003;
+}
+
+static const struct nvkm_ior_func
+nv50_sor = {
+       .state = nv50_sor_state,
+       .power = nv50_sor_power,
+       .clock = nv50_sor_clock,
+};
+
+static int
+nv50_sor_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&nv50_sor, disp, SOR, id, false);
+}
+
+int
+nv50_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+
+       *pmask = (nvkm_rd32(device, 0x610184) & 0x03000000) >> 24;
+       return 2;
+}
+
+static void
+nv50_dac_clock(struct nvkm_ior *dac)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 doff = nv50_ior_base(dac);
+
+       nvkm_mask(device, 0x614280 + doff, 0x07070707, 0x00000000);
+}
+
+int
+nv50_dac_sense(struct nvkm_ior *dac, u32 loadval)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 doff = nv50_ior_base(dac);
+
+       dac->func->power(dac, false, true, false, false, false);
+
+       nvkm_wr32(device, 0x61a00c + doff, 0x00100000 | loadval);
+       mdelay(9);
+       udelay(500);
+       loadval = nvkm_mask(device, 0x61a00c + doff, 0xffffffff, 0x00000000);
+
+       dac->func->power(dac, false, false, false, false, false);
+       if (!(loadval & 0x80000000))
+               return -ETIMEDOUT;
+
+       return (loadval & 0x38000000) >> 27;
+}
+
+static void
+nv50_dac_power_wait(struct nvkm_device *device, const u32 doff)
+{
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000))
+                       break;
+       );
+}
+
+void
+nv50_dac_power(struct nvkm_ior *dac, bool normal, bool pu, bool data, bool vsync, bool hsync)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32  doff = nv50_ior_base(dac);
+       const u32 shift = normal ? 0 : 16;
+       const u32 state = 0x80000000 | (0x00000040 * !    pu |
+                                       0x00000010 * !  data |
+                                       0x00000004 * ! vsync |
+                                       0x00000001 * ! hsync) << shift;
+       const u32 field = 0xc0000000 | (0x00000055 << shift);
+
+       nv50_dac_power_wait(device, doff);
+       nvkm_mask(device, 0x61a004 + doff, field, state);
+       nv50_dac_power_wait(device, doff);
+}
+
+static void
+nv50_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 coff = dac->id * 8 + (state == &dac->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610b58 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = CRT; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
        }
 
-       if (func->dac.cnt) {
-               disp->dac.nr = func->dac.cnt(&disp->base, &disp->dac.mask);
-               nvkm_debug(subdev, "   DAC(s): %d (%02lx)\n",
-                          disp->dac.nr, disp->dac.mask);
-               for_each_set_bit(i, &disp->dac.mask, disp->dac.nr) {
-                       ret = func->dac.new(&disp->base, i);
-                       if (ret)
-                               return ret;
+       state->head = ctrl & 0x00000003;
+}
+
+static const struct nvkm_ior_func
+nv50_dac = {
+       .state = nv50_dac_state,
+       .power = nv50_dac_power,
+       .sense = nv50_dac_sense,
+       .clock = nv50_dac_clock,
+};
+
+int
+nv50_dac_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_ior_new_(&nv50_dac, disp, DAC, id, false);
+}
+
+int
+nv50_dac_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+
+       *pmask = (nvkm_rd32(device, 0x610184) & 0x00700000) >> 20;
+       return 3;
+}
+
+static void
+nv50_head_vblank_put(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+
+       nvkm_mask(device, 0x61002c, (4 << head->id), 0);
+}
+
+static void
+nv50_head_vblank_get(struct nvkm_head *head)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+
+       nvkm_mask(device, 0x61002c, (4 << head->id), (4 << head->id));
+}
+
+static void
+nv50_head_rgclk(struct nvkm_head *head, int div)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+
+       nvkm_mask(device, 0x614200 + (head->id * 0x800), 0x0000000f, div);
+}
+
+void
+nv50_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = head->id * 0x800;
+
+       /* vline read locks hline. */
+       *vline = nvkm_rd32(device, 0x616340 + hoff) & 0x0000ffff;
+       *hline = nvkm_rd32(device, 0x616344 + hoff) & 0x0000ffff;
+}
+
+static void
+nv50_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
+{
+       struct nvkm_device *device = head->disp->engine.subdev.device;
+       const u32 hoff = head->id * 0x540 + (state == &head->arm) * 4;
+       u32 data;
+
+       data = nvkm_rd32(device, 0x610ae8 + hoff);
+       state->vblanke = (data & 0xffff0000) >> 16;
+       state->hblanke = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x610af0 + hoff);
+       state->vblanks = (data & 0xffff0000) >> 16;
+       state->hblanks = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x610af8 + hoff);
+       state->vtotal = (data & 0xffff0000) >> 16;
+       state->htotal = (data & 0x0000ffff);
+       data = nvkm_rd32(device, 0x610b00 + hoff);
+       state->vsynce = (data & 0xffff0000) >> 16;
+       state->hsynce = (data & 0x0000ffff);
+       state->hz = (nvkm_rd32(device, 0x610ad0 + hoff) & 0x003fffff) * 1000;
+}
+
+static const struct nvkm_head_func
+nv50_head = {
+       .state = nv50_head_state,
+       .rgpos = nv50_head_rgpos,
+       .rgclk = nv50_head_rgclk,
+       .vblank_get = nv50_head_vblank_get,
+       .vblank_put = nv50_head_vblank_put,
+};
+
+int
+nv50_head_new(struct nvkm_disp *disp, int id)
+{
+       return nvkm_head_new_(&nv50_head, disp, id);
+}
+
+int
+nv50_head_cnt(struct nvkm_disp *disp, unsigned long *pmask)
+{
+       *pmask = 3;
+       return 2;
+}
+
+
+static void
+nv50_disp_mthd_list(struct nvkm_disp *disp, int debug, u32 base, int c,
+                   const struct nvkm_disp_mthd_list *list, int inst)
+{
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int i;
+
+       for (i = 0; list->data[i].mthd; i++) {
+               if (list->data[i].addr) {
+                       u32 next = nvkm_rd32(device, list->data[i].addr + base + 0);
+                       u32 prev = nvkm_rd32(device, list->data[i].addr + base + c);
+                       u32 mthd = list->data[i].mthd + (list->mthd * inst);
+                       const char *name = list->data[i].name;
+                       char mods[16];
+
+                       if (prev != next)
+                               snprintf(mods, sizeof(mods), "-> %08x", next);
+                       else
+                               snprintf(mods, sizeof(mods), "%13c", ' ');
+
+                       nvkm_printk_(subdev, debug, info,
+                                    "\t%04x: %08x %s%s%s\n",
+                                    mthd, prev, mods, name ? " // " : "",
+                                    name ? name : "");
                }
        }
+}
 
-       if (func->pior.cnt) {
-               disp->pior.nr = func->pior.cnt(&disp->base, &disp->pior.mask);
-               nvkm_debug(subdev, "  PIOR(s): %d (%02lx)\n",
-                          disp->pior.nr, disp->pior.mask);
-               for_each_set_bit(i, &disp->pior.mask, disp->pior.nr) {
-                       ret = func->pior.new(&disp->base, i);
-                       if (ret)
-                               return ret;
+void
+nv50_disp_chan_mthd(struct nvkm_disp_chan *chan, int debug)
+{
+       struct nvkm_disp *disp = chan->disp;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       const struct nvkm_disp_chan_mthd *mthd = chan->mthd;
+       const struct nvkm_disp_mthd_list *list;
+       int i, j;
+
+       if (debug > subdev->debug)
+               return;
+       if (!mthd)
+               return;
+
+       for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) {
+               u32 base = chan->head * mthd->addr;
+               for (j = 0; j < mthd->data[i].nr; j++, base += list->addr) {
+                       const char *cname = mthd->name;
+                       const char *sname = "";
+                       char cname_[16], sname_[16];
+
+                       if (mthd->addr) {
+                               snprintf(cname_, sizeof(cname_), "%s %d",
+                                        mthd->name, chan->chid.user);
+                               cname = cname_;
+                       }
+
+                       if (mthd->data[i].nr > 1) {
+                               snprintf(sname_, sizeof(sname_), " - %s %d",
+                                        mthd->data[i].name, j);
+                               sname = sname_;
+                       }
+
+                       nvkm_printk_(subdev, debug, info, "%s%s:\n", cname, sname);
+                       nv50_disp_mthd_list(disp, debug, base, mthd->prev,
+                                           list, j);
                }
        }
+}
 
-       disp->sor.nr = func->sor.cnt(&disp->base, &disp->sor.mask);
-       nvkm_debug(subdev, "   SOR(s): %d (%02lx)\n",
-                  disp->sor.nr, disp->sor.mask);
-       for_each_set_bit(i, &disp->sor.mask, disp->sor.nr) {
-               ret = func->sor.new(&disp->base, i);
-               if (ret)
-                       return ret;
+static void
+nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
+{
+       struct nvkm_disp *disp = container_of(event, typeof(*disp), uevent);
+       struct nvkm_device *device = disp->engine.subdev.device;
+       nvkm_mask(device, 0x610028, 0x00000001 << index, 0x00000000 << index);
+       nvkm_wr32(device, 0x610020, 0x00000001 << index);
+}
+
+static void
+nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
+{
+       struct nvkm_disp *disp = container_of(event, typeof(*disp), uevent);
+       struct nvkm_device *device = disp->engine.subdev.device;
+       nvkm_wr32(device, 0x610020, 0x00000001 << index);
+       nvkm_mask(device, 0x610028, 0x00000001 << index, 0x00000001 << index);
+}
+
+void
+nv50_disp_chan_uevent_send(struct nvkm_disp *disp, int chid)
+{
+       nvkm_event_send(&disp->uevent, NVKM_DISP_EVENT_CHAN_AWAKEN, chid, NULL, 0);
+}
+
+const struct nvkm_event_func
+nv50_disp_chan_uevent = {
+       .init = nv50_disp_chan_uevent_init,
+       .fini = nv50_disp_chan_uevent_fini,
+};
+
+u64
+nv50_disp_chan_user(struct nvkm_disp_chan *chan, u64 *psize)
+{
+       *psize = 0x1000;
+       return 0x640000 + (chan->chid.user * 0x1000);
+}
+
+void
+nv50_disp_chan_intr(struct nvkm_disp_chan *chan, bool en)
+{
+       struct nvkm_device *device = chan->disp->engine.subdev.device;
+       const u32 mask = 0x00010001 << chan->chid.user;
+       const u32 data = en ? 0x00010000 << chan->chid.user : 0x00000000;
+       nvkm_mask(device, 0x610028, mask, data);
+}
+
+static void
+nv50_disp_pioc_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_disp *disp = chan->disp;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       nvkm_mask(device, 0x610200 + (ctrl * 0x10), 0x00000001, 0x00000000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d timeout: %08x\n", user,
+                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
        }
+}
 
-       ret = nvkm_gpuobj_new(device, 0x10000, 0x10000, false, NULL,
-                             &disp->inst);
-       if (ret)
-               return ret;
+static int
+nv50_disp_pioc_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_disp *disp = chan->disp;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
 
-       return nvkm_ramht_new(device, func->ramht_size ? func->ramht_size :
-                             0x1000, 0, disp->inst, &disp->ramht);
+       nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00002000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d timeout0: %08x\n", user,
+                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
+               return -EBUSY;
+       }
+
+       nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00000001);
+       if (nvkm_msec(device, 2000,
+               u32 tmp = nvkm_rd32(device, 0x610200 + (ctrl * 0x10));
+               if ((tmp & 0x00030000) == 0x00010000)
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d timeout1: %08x\n", user,
+                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
-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_,
+const struct nvkm_disp_chan_func
+nv50_disp_pioc_func = {
+       .init = nv50_disp_pioc_init,
+       .fini = nv50_disp_pioc_fini,
+       .intr = nv50_disp_chan_intr,
+       .user = nv50_disp_chan_user,
 };
 
 int
-nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
-              enum nvkm_subdev_type type, int inst, struct nvkm_disp **pdisp)
+nv50_disp_dmac_bind(struct nvkm_disp_chan *chan, struct nvkm_object *object, u32 handle)
 {
-       struct nv50_disp *disp;
-       int ret;
+       return nvkm_ramht_insert(chan->disp->ramht, object, chan->chid.user, -10, handle,
+                                chan->chid.user << 28 | chan->chid.user);
+}
 
-       if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL)))
-               return -ENOMEM;
-       disp->func = func;
-       *pdisp = &disp->base;
+static void
+nv50_disp_dmac_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       /* deactivate channel */
+       nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000);
+       nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000003, 0x00000000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x001e0000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
+                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
+       }
 
-       ret = nvkm_disp_ctor(&nv50_disp_, device, type, inst, &disp->base);
-       if (ret)
-               return ret;
+       chan->suspend_put = nvkm_rd32(device, 0x640000 + (ctrl * 0x1000));
+}
+
+static int
+nv50_disp_dmac_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ctrl = chan->chid.ctrl;
+       int user = chan->chid.user;
+
+       /* initialise channel for dma command submission */
+       nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
+       nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
+       nvkm_wr32(device, 0x61020c + (ctrl * 0x0010), ctrl);
+       nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), chan->suspend_put);
+       nvkm_wr32(device, 0x610200 + (ctrl * 0x0010), 0x00000013);
+
+       /* wait for it to go inactive */
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x80000000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "ch %d init timeout, %08x\n", user,
+                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
+               return -EBUSY;
+       }
 
-       disp->wq = create_singlethread_workqueue("nvkm-disp");
-       if (!disp->wq)
-               return -ENOMEM;
+       return 0;
+}
 
-       INIT_WORK(&disp->supervisor, func->super);
+int
+nv50_disp_dmac_push(struct nvkm_disp_chan *chan, u64 object)
+{
+       chan->memory = nvkm_umem_search(chan->object.client, object);
+       if (IS_ERR(chan->memory))
+               return PTR_ERR(chan->memory);
+
+       if (nvkm_memory_size(chan->memory) < 0x1000)
+               return -EINVAL;
+
+       switch (nvkm_memory_target(chan->memory)) {
+       case NVKM_MEM_TARGET_VRAM: chan->push = 0x00000001; break;
+       case NVKM_MEM_TARGET_NCOH: chan->push = 0x00000002; break;
+       case NVKM_MEM_TARGET_HOST: chan->push = 0x00000003; break;
+       default:
+               return -EINVAL;
+       }
 
-       return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan),
-                              &disp->uevent);
+       chan->push |= nvkm_memory_addr(chan->memory) >> 8;
+       return 0;
 }
 
+const struct nvkm_disp_chan_func
+nv50_disp_dmac_func = {
+       .push = nv50_disp_dmac_push,
+       .init = nv50_disp_dmac_init,
+       .fini = nv50_disp_dmac_fini,
+       .intr = nv50_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+       .bind = nv50_disp_dmac_bind,
+};
+
+const struct nvkm_disp_chan_user
+nv50_disp_curs = {
+       .func = &nv50_disp_pioc_func,
+       .ctrl = 7,
+       .user = 7,
+};
+
+const struct nvkm_disp_chan_user
+nv50_disp_oimm = {
+       .func = &nv50_disp_pioc_func,
+       .ctrl = 5,
+       .user = 5,
+};
+
+static const struct nvkm_disp_mthd_list
+nv50_disp_ovly_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x000000 },
+               { 0x0084, 0x0009a0 },
+               { 0x0088, 0x0009c0 },
+               { 0x008c, 0x0009c8 },
+               { 0x0090, 0x6109b4 },
+               { 0x0094, 0x610970 },
+               { 0x00a0, 0x610998 },
+               { 0x00a4, 0x610964 },
+               { 0x00c0, 0x610958 },
+               { 0x00e0, 0x6109a8 },
+               { 0x00e4, 0x6109d0 },
+               { 0x00e8, 0x6109d8 },
+               { 0x0100, 0x61094c },
+               { 0x0104, 0x610984 },
+               { 0x0108, 0x61098c },
+               { 0x0800, 0x6109f8 },
+               { 0x0808, 0x610a08 },
+               { 0x080c, 0x610a10 },
+               { 0x0810, 0x610a00 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+nv50_disp_ovly_mthd = {
+       .name = "Overlay",
+       .addr = 0x000540,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &nv50_disp_ovly_mthd_base },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_user
+nv50_disp_ovly = {
+       .func = &nv50_disp_dmac_func,
+       .ctrl = 3,
+       .user = 3,
+       .mthd = &nv50_disp_ovly_mthd,
+};
+
+static const struct nvkm_disp_mthd_list
+nv50_disp_base_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x000000 },
+               { 0x0084, 0x0008c4 },
+               { 0x0088, 0x0008d0 },
+               { 0x008c, 0x0008dc },
+               { 0x0090, 0x0008e4 },
+               { 0x0094, 0x610884 },
+               { 0x00a0, 0x6108a0 },
+               { 0x00a4, 0x610878 },
+               { 0x00c0, 0x61086c },
+               { 0x00e0, 0x610858 },
+               { 0x00e4, 0x610860 },
+               { 0x00e8, 0x6108ac },
+               { 0x00ec, 0x6108b4 },
+               { 0x0100, 0x610894 },
+               { 0x0110, 0x6108bc },
+               { 0x0114, 0x61088c },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+nv50_disp_base_mthd_image = {
+       .mthd = 0x0400,
+       .addr = 0x000000,
+       .data = {
+               { 0x0800, 0x6108f0 },
+               { 0x0804, 0x6108fc },
+               { 0x0808, 0x61090c },
+               { 0x080c, 0x610914 },
+               { 0x0810, 0x610904 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+nv50_disp_base_mthd = {
+       .name = "Base",
+       .addr = 0x000540,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &nv50_disp_base_mthd_base },
+               {  "Image", 2, &nv50_disp_base_mthd_image },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_user
+nv50_disp_base = {
+       .func = &nv50_disp_dmac_func,
+       .ctrl = 1,
+       .user = 1,
+       .mthd = &nv50_disp_base_mthd,
+};
+
+const struct nvkm_disp_mthd_list
+nv50_disp_core_mthd_base = {
+       .mthd = 0x0000,
+       .addr = 0x000000,
+       .data = {
+               { 0x0080, 0x000000 },
+               { 0x0084, 0x610bb8 },
+               { 0x0088, 0x610b9c },
+               { 0x008c, 0x000000 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+nv50_disp_core_mthd_dac = {
+       .mthd = 0x0080,
+       .addr = 0x000008,
+       .data = {
+               { 0x0400, 0x610b58 },
+               { 0x0404, 0x610bdc },
+               { 0x0420, 0x610828 },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+nv50_disp_core_mthd_sor = {
+       .mthd = 0x0040,
+       .addr = 0x000008,
+       .data = {
+               { 0x0600, 0x610b70 },
+               {}
+       }
+};
+
+const struct nvkm_disp_mthd_list
+nv50_disp_core_mthd_pior = {
+       .mthd = 0x0040,
+       .addr = 0x000008,
+       .data = {
+               { 0x0700, 0x610b80 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_mthd_list
+nv50_disp_core_mthd_head = {
+       .mthd = 0x0400,
+       .addr = 0x000540,
+       .data = {
+               { 0x0800, 0x610ad8 },
+               { 0x0804, 0x610ad0 },
+               { 0x0808, 0x610a48 },
+               { 0x080c, 0x610a78 },
+               { 0x0810, 0x610ac0 },
+               { 0x0814, 0x610af8 },
+               { 0x0818, 0x610b00 },
+               { 0x081c, 0x610ae8 },
+               { 0x0820, 0x610af0 },
+               { 0x0824, 0x610b08 },
+               { 0x0828, 0x610b10 },
+               { 0x082c, 0x610a68 },
+               { 0x0830, 0x610a60 },
+               { 0x0834, 0x000000 },
+               { 0x0838, 0x610a40 },
+               { 0x0840, 0x610a24 },
+               { 0x0844, 0x610a2c },
+               { 0x0848, 0x610aa8 },
+               { 0x084c, 0x610ab0 },
+               { 0x0860, 0x610a84 },
+               { 0x0864, 0x610a90 },
+               { 0x0868, 0x610b18 },
+               { 0x086c, 0x610b20 },
+               { 0x0870, 0x610ac8 },
+               { 0x0874, 0x610a38 },
+               { 0x0880, 0x610a58 },
+               { 0x0884, 0x610a9c },
+               { 0x08a0, 0x610a70 },
+               { 0x08a4, 0x610a50 },
+               { 0x08a8, 0x610ae0 },
+               { 0x08c0, 0x610b28 },
+               { 0x08c4, 0x610b30 },
+               { 0x08c8, 0x610b40 },
+               { 0x08d4, 0x610b38 },
+               { 0x08d8, 0x610b48 },
+               { 0x08dc, 0x610b50 },
+               { 0x0900, 0x610a18 },
+               { 0x0904, 0x610ab8 },
+               {}
+       }
+};
+
+static const struct nvkm_disp_chan_mthd
+nv50_disp_core_mthd = {
+       .name = "Core",
+       .addr = 0x000000,
+       .prev = 0x000004,
+       .data = {
+               { "Global", 1, &nv50_disp_core_mthd_base },
+               {    "DAC", 3, &nv50_disp_core_mthd_dac  },
+               {    "SOR", 2, &nv50_disp_core_mthd_sor  },
+               {   "PIOR", 3, &nv50_disp_core_mthd_pior },
+               {   "HEAD", 2, &nv50_disp_core_mthd_head },
+               {}
+       }
+};
+
+static void
+nv50_disp_core_fini(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       /* deactivate channel */
+       nvkm_mask(device, 0x610200, 0x00000010, 0x00000000);
+       nvkm_mask(device, 0x610200, 0x00000003, 0x00000000);
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610200) & 0x001e0000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "core fini: %08x\n",
+                          nvkm_rd32(device, 0x610200));
+       }
+
+       chan->suspend_put = nvkm_rd32(device, 0x640000);
+}
+
+static int
+nv50_disp_core_init(struct nvkm_disp_chan *chan)
+{
+       struct nvkm_subdev *subdev = &chan->disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+
+       /* attempt to unstick channel from some unknown state */
+       if ((nvkm_rd32(device, 0x610200) & 0x009f0000) == 0x00020000)
+               nvkm_mask(device, 0x610200, 0x00800000, 0x00800000);
+       if ((nvkm_rd32(device, 0x610200) & 0x003f0000) == 0x00030000)
+               nvkm_mask(device, 0x610200, 0x00600000, 0x00600000);
+
+       /* initialise channel for dma command submission */
+       nvkm_wr32(device, 0x610204, chan->push);
+       nvkm_wr32(device, 0x610208, 0x00010000);
+       nvkm_wr32(device, 0x61020c, 0x00000000);
+       nvkm_mask(device, 0x610200, 0x00000010, 0x00000010);
+       nvkm_wr32(device, 0x640000, chan->suspend_put);
+       nvkm_wr32(device, 0x610200, 0x01000013);
+
+       /* wait for it to go inactive */
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x610200) & 0x80000000))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "core init: %08x\n",
+                          nvkm_rd32(device, 0x610200));
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+const struct nvkm_disp_chan_func
+nv50_disp_core_func = {
+       .push = nv50_disp_dmac_push,
+       .init = nv50_disp_core_init,
+       .fini = nv50_disp_core_fini,
+       .intr = nv50_disp_chan_intr,
+       .user = nv50_disp_chan_user,
+       .bind = nv50_disp_dmac_bind,
+};
+
+static const struct nvkm_disp_chan_user
+nv50_disp_core = {
+       .func = &nv50_disp_core_func,
+       .ctrl = 0,
+       .user = 0,
+       .mthd = &nv50_disp_core_mthd,
+};
+
 static u32
 nv50_disp_super_iedt(struct nvkm_head *head, struct nvkm_outp *outp,
                     u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
@@ -278,7 +1076,7 @@ static struct nvkm_ior *
 nv50_disp_super_ior_asy(struct nvkm_head *head)
 {
        struct nvkm_ior *ior;
-       list_for_each_entry(ior, &head->disp->ior, head) {
+       list_for_each_entry(ior, &head->disp->iors, head) {
                if (ior->asy.head & (1 << head->id)) {
                        HEAD_DBG(head, "to %s", ior->name);
                        return ior;
@@ -292,7 +1090,7 @@ static struct nvkm_ior *
 nv50_disp_super_ior_arm(struct nvkm_head *head)
 {
        struct nvkm_ior *ior;
-       list_for_each_entry(ior, &head->disp->ior, head) {
+       list_for_each_entry(ior, &head->disp->iors, head) {
                if (ior->arm.head & (1 << head->id)) {
                        HEAD_DBG(head, "on %s", ior->name);
                        return ior;
@@ -303,7 +1101,7 @@ nv50_disp_super_ior_arm(struct nvkm_head *head)
 }
 
 void
-nv50_disp_super_3_0(struct nv50_disp *disp, struct nvkm_head *head)
+nv50_disp_super_3_0(struct nvkm_disp *disp, struct nvkm_head *head)
 {
        struct nvkm_ior *ior;
 
@@ -346,7 +1144,7 @@ nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior)
        do_div(v, khz);
        v = v - ((36 / ior->dp.nr) + 3) - 1;
 
-       ior->func->dp.audio_sym(ior, head->id, h, v);
+       ior->func->dp->audio_sym(ior, head->id, h, v);
 
        /* watermark / activesym */
        link_data_rate = (khz * head->asy.or.depth / 8) / ior->dp.nr;
@@ -355,7 +1153,7 @@ nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior)
        link_ratio = link_data_rate * symbol;
        do_div(link_ratio, linkKBps);
 
-       for (TU = 64; ior->func->dp.activesym && TU >= 32; TU--) {
+       for (TU = 64; ior->func->dp->activesym && TU >= 32; TU--) {
                /* calculate average number of valid symbols in each TU */
                u32 tu_valid = link_ratio * TU;
                u32 calc, diff;
@@ -406,13 +1204,13 @@ nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior)
                }
        }
 
-       if (ior->func->dp.activesym) {
+       if (ior->func->dp->activesym) {
                if (!bestTU) {
                        nvkm_error(subdev, "unable to determine dp config\n");
                        return;
                }
-               ior->func->dp.activesym(ior, head->id, bestTU,
-                                       bestVTUa, bestVTUf, bestVTUi);
+
+               ior->func->dp->activesym(ior, head->id, bestTU, bestVTUa, bestVTUf, bestVTUi);
        } else {
                bestTU = 64;
        }
@@ -424,11 +1222,11 @@ nv50_disp_super_2_2_dp(struct nvkm_head *head, struct nvkm_ior *ior)
        do_div(unk, symbol);
        unk += 6;
 
-       ior->func->dp.watermark(ior, head->id, unk);
+       ior->func->dp->watermark(ior, head->id, unk);
 }
 
 void
-nv50_disp_super_2_2(struct nv50_disp *disp, struct nvkm_head *head)
+nv50_disp_super_2_2(struct nvkm_disp *disp, struct nvkm_head *head)
 {
        const u32 khz = head->asy.hz / 1000;
        struct nvkm_outp *outp;
@@ -475,9 +1273,9 @@ nv50_disp_super_2_2(struct nv50_disp *disp, struct nvkm_head *head)
 }
 
 void
-nv50_disp_super_2_1(struct nv50_disp *disp, struct nvkm_head *head)
+nv50_disp_super_2_1(struct nvkm_disp *disp, struct nvkm_head *head)
 {
-       struct nvkm_devinit *devinit = disp->base.engine.subdev.device->devinit;
+       struct nvkm_devinit *devinit = disp->engine.subdev.device->devinit;
        const u32 khz = head->asy.hz / 1000;
        HEAD_DBG(head, "supervisor 2.1 - %d khz", khz);
        if (khz)
@@ -485,7 +1283,7 @@ nv50_disp_super_2_1(struct nv50_disp *disp, struct nvkm_head *head)
 }
 
 void
-nv50_disp_super_2_0(struct nv50_disp *disp, struct nvkm_head *head)
+nv50_disp_super_2_0(struct nvkm_disp *disp, struct nvkm_head *head)
 {
        struct nvkm_outp *outp;
        struct nvkm_ior *ior;
@@ -509,7 +1307,7 @@ nv50_disp_super_2_0(struct nv50_disp *disp, struct nvkm_head *head)
 }
 
 void
-nv50_disp_super_1_0(struct nv50_disp *disp, struct nvkm_head *head)
+nv50_disp_super_1_0(struct nvkm_disp *disp, struct nvkm_head *head)
 {
        struct nvkm_ior *ior;
 
@@ -524,17 +1322,17 @@ nv50_disp_super_1_0(struct nv50_disp *disp, struct nvkm_head *head)
 }
 
 void
-nv50_disp_super_1(struct nv50_disp *disp)
+nv50_disp_super_1(struct nvkm_disp *disp)
 {
        struct nvkm_head *head;
        struct nvkm_ior *ior;
 
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                head->func->state(head, &head->arm);
                head->func->state(head, &head->asy);
        }
 
-       list_for_each_entry(ior, &disp->base.ior, head) {
+       list_for_each_entry(ior, &disp->iors, head) {
                ior->func->state(ior, &ior->arm);
                ior->func->state(ior, &ior->asy);
        }
@@ -543,19 +1341,21 @@ nv50_disp_super_1(struct nv50_disp *disp)
 void
 nv50_disp_super(struct work_struct *work)
 {
-       struct nv50_disp *disp =
-               container_of(work, struct nv50_disp, supervisor);
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_disp *disp = container_of(work, struct nvkm_disp, super.work);
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        struct nvkm_head *head;
-       u32 super = nvkm_rd32(device, 0x610030);
+       u32 super;
+
+       mutex_lock(&disp->super.mutex);
+       super = nvkm_rd32(device, 0x610030);
 
-       nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super, super);
+       nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super.pending, super);
 
-       if (disp->super & 0x00000010) {
+       if (disp->super.pending & 0x00000010) {
                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
                nv50_disp_super_1(disp);
-               list_for_each_entry(head, &disp->base.head, head) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(super & (0x00000020 << head->id)))
                                continue;
                        if (!(super & (0x00000080 << head->id)))
@@ -563,26 +1363,26 @@ nv50_disp_super(struct work_struct *work)
                        nv50_disp_super_1_0(disp, head);
                }
        } else
-       if (disp->super & 0x00000020) {
-               list_for_each_entry(head, &disp->base.head, head) {
+       if (disp->super.pending & 0x00000020) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(super & (0x00000080 << head->id)))
                                continue;
                        nv50_disp_super_2_0(disp, head);
                }
-               nvkm_outp_route(&disp->base);
-               list_for_each_entry(head, &disp->base.head, head) {
+               nvkm_outp_route(disp);
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(super & (0x00000200 << head->id)))
                                continue;
                        nv50_disp_super_2_1(disp, head);
                }
-               list_for_each_entry(head, &disp->base.head, head) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(super & (0x00000080 << head->id)))
                                continue;
                        nv50_disp_super_2_2(disp, head);
                }
        } else
-       if (disp->super & 0x00000040) {
-               list_for_each_entry(head, &disp->base.head, head) {
+       if (disp->super.pending & 0x00000040) {
+               list_for_each_entry(head, &disp->heads, head) {
                        if (!(super & (0x00000080 << head->id)))
                                continue;
                        nv50_disp_super_3_0(disp, head);
@@ -590,6 +1390,7 @@ nv50_disp_super(struct work_struct *work)
        }
 
        nvkm_wr32(device, 0x610030, 0x80000000);
+       mutex_unlock(&disp->super.mutex);
 }
 
 const struct nvkm_enum
@@ -611,9 +1412,9 @@ nv50_disp_intr_error_code[] = {
 };
 
 static void
-nv50_disp_intr_error(struct nv50_disp *disp, int chid)
+nv50_disp_intr_error(struct nvkm_disp *disp, int chid)
 {
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
        struct nvkm_device *device = subdev->device;
        u32 data = nvkm_rd32(device, 0x610084 + (chid * 0x08));
        u32 addr = nvkm_rd32(device, 0x610080 + (chid * 0x08));
@@ -645,9 +1446,9 @@ nv50_disp_intr_error(struct nv50_disp *disp, int chid)
 }
 
 void
-nv50_disp_intr(struct nv50_disp *disp)
+nv50_disp_intr(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        u32 intr0 = nvkm_rd32(device, 0x610020);
        u32 intr1 = nvkm_rd32(device, 0x610024);
 
@@ -664,35 +1465,35 @@ nv50_disp_intr(struct nv50_disp *disp)
        }
 
        if (intr1 & 0x00000004) {
-               nvkm_disp_vblank(&disp->base, 0);
+               nvkm_disp_vblank(disp, 0);
                nvkm_wr32(device, 0x610024, 0x00000004);
        }
 
        if (intr1 & 0x00000008) {
-               nvkm_disp_vblank(&disp->base, 1);
+               nvkm_disp_vblank(disp, 1);
                nvkm_wr32(device, 0x610024, 0x00000008);
        }
 
        if (intr1 & 0x00000070) {
-               disp->super = (intr1 & 0x00000070);
-               queue_work(disp->wq, &disp->supervisor);
-               nvkm_wr32(device, 0x610024, disp->super);
+               disp->super.pending = (intr1 & 0x00000070);
+               queue_work(disp->super.wq, &disp->super.work);
+               nvkm_wr32(device, 0x610024, disp->super.pending);
        }
 }
 
 void
-nv50_disp_fini(struct nv50_disp *disp)
+nv50_disp_fini(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        /* disable all interrupts */
        nvkm_wr32(device, 0x610024, 0x00000000);
        nvkm_wr32(device, 0x610020, 0x00000000);
 }
 
 int
-nv50_disp_init(struct nv50_disp *disp)
+nv50_disp_init(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        struct nvkm_head *head;
        u32 tmp;
        int i;
@@ -705,7 +1506,7 @@ nv50_disp_init(struct nv50_disp *disp)
        nvkm_wr32(device, 0x610184, tmp);
 
        /* ... CRTC caps */
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, 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));
@@ -754,23 +1555,89 @@ nv50_disp_init(struct nv50_disp *disp)
        return 0;
 }
 
-static const struct nv50_disp_func
+int
+nv50_disp_oneinit(struct nvkm_disp *disp)
+{
+       const struct nvkm_disp_func *func = disp->func;
+       struct nvkm_subdev *subdev = &disp->engine.subdev;
+       struct nvkm_device *device = subdev->device;
+       int ret, i;
+
+       if (func->wndw.cnt) {
+               disp->wndw.nr = func->wndw.cnt(disp, &disp->wndw.mask);
+               nvkm_debug(subdev, "Window(s): %d (%08lx)\n", disp->wndw.nr, disp->wndw.mask);
+       }
+
+       disp->head.nr = func->head.cnt(disp, &disp->head.mask);
+       nvkm_debug(subdev, "  Head(s): %d (%02lx)\n", disp->head.nr, disp->head.mask);
+       for_each_set_bit(i, &disp->head.mask, disp->head.nr) {
+               ret = func->head.new(disp, i);
+               if (ret)
+                       return ret;
+       }
+
+       if (func->dac.cnt) {
+               disp->dac.nr = func->dac.cnt(disp, &disp->dac.mask);
+               nvkm_debug(subdev, "   DAC(s): %d (%02lx)\n", disp->dac.nr, disp->dac.mask);
+               for_each_set_bit(i, &disp->dac.mask, disp->dac.nr) {
+                       ret = func->dac.new(disp, i);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       if (func->pior.cnt) {
+               disp->pior.nr = func->pior.cnt(disp, &disp->pior.mask);
+               nvkm_debug(subdev, "  PIOR(s): %d (%02lx)\n", disp->pior.nr, disp->pior.mask);
+               for_each_set_bit(i, &disp->pior.mask, disp->pior.nr) {
+                       ret = func->pior.new(disp, i);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       disp->sor.nr = func->sor.cnt(disp, &disp->sor.mask);
+       nvkm_debug(subdev, "   SOR(s): %d (%02lx)\n", disp->sor.nr, disp->sor.mask);
+       for_each_set_bit(i, &disp->sor.mask, disp->sor.nr) {
+               ret = func->sor.new(disp, i);
+               if (ret)
+                       return ret;
+       }
+
+       ret = nvkm_gpuobj_new(device, 0x10000, 0x10000, false, NULL, &disp->inst);
+       if (ret)
+               return ret;
+
+       return nvkm_ramht_new(device, func->ramht_size ? func->ramht_size :
+                             0x1000, 0, disp->inst, &disp->ramht);
+}
+
+static const struct nvkm_disp_func
 nv50_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = nv50_disp_init,
        .fini = nv50_disp_fini,
        .intr = nv50_disp_intr,
-       .uevent = &nv50_disp_chan_uevent,
        .super = nv50_disp_super,
-       .root = &nv50_disp_root_oclass,
+       .uevent = &nv50_disp_chan_uevent,
        .head = { .cnt = nv50_head_cnt, .new = nv50_head_new },
        .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new },
        .sor = { .cnt = nv50_sor_cnt, .new = nv50_sor_new },
        .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new },
+       .root = { 0, 0, NV50_DISP },
+       .user = {
+               {{0,0,NV50_DISP_CURSOR             }, nvkm_disp_chan_new, &nv50_disp_curs },
+               {{0,0,NV50_DISP_OVERLAY            }, nvkm_disp_chan_new, &nv50_disp_oimm },
+               {{0,0,NV50_DISP_BASE_CHANNEL_DMA   }, nvkm_disp_chan_new, &nv50_disp_base },
+               {{0,0,NV50_DISP_CORE_CHANNEL_DMA   }, nvkm_disp_core_new, &nv50_disp_core },
+               {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nvkm_disp_chan_new, &nv50_disp_ovly },
+               {}
+       }
 };
 
 int
 nv50_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
              struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&nv50_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&nv50_disp, device, type, inst, pdisp);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
deleted file mode 100644 (file)
index 025cacd..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NV50_DISP_H__
-#define __NV50_DISP_H__
-#define nv50_disp(p) container_of((p), struct nv50_disp, base)
-#include "priv.h"
-struct nvkm_head;
-
-#include <core/enum.h>
-
-struct nv50_disp {
-       const struct nv50_disp_func *func;
-       struct nvkm_disp base;
-
-       struct workqueue_struct *wq;
-       struct work_struct supervisor;
-       u32 super;
-
-       struct nvkm_event uevent;
-
-       struct {
-               unsigned long mask;
-               int nr;
-       } wndw, head, dac;
-
-       struct {
-               unsigned long mask;
-               int nr;
-               u32 lvdsconf;
-       } sor;
-
-       struct {
-               unsigned long mask;
-               int nr;
-               u8 type[3];
-       } pior;
-
-       struct nvkm_gpuobj *inst;
-       struct nvkm_ramht *ramht;
-
-       struct nv50_disp_chan *chan[81];
-};
-
-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 *);
-void nv50_disp_super_2_2(struct nv50_disp *, struct nvkm_head *);
-void nv50_disp_super_3_0(struct nv50_disp *, struct nvkm_head *);
-
-int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
-                  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);
-
-       const struct nvkm_event_func *uevent;
-       void (*super)(struct work_struct *);
-
-       const struct nvkm_disp_oclass *root;
-
-       struct {
-               int (*cnt)(struct nvkm_disp *, unsigned long *mask);
-               int (*new)(struct nvkm_disp *, int id);
-       } wndw, head, dac, sor, pior;
-
-       u16 ramht_size;
-};
-
-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 *);
-extern const struct nvkm_enum nv50_disp_intr_error_type[];
-
-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);
-
-void gv100_disp_fini(struct nv50_disp *);
-void gv100_disp_intr(struct nv50_disp *);
-void gv100_disp_super(struct work_struct *);
-int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *);
-
-int tu102_disp_init(struct nv50_disp *);
-
-void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *);
-void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *);
-void nv50_disp_update_sppll1(struct nv50_disp *);
-
-extern const struct nvkm_event_func nv50_disp_chan_uevent;
-int  nv50_disp_chan_uevent_ctor(struct nvkm_object *, void *, u32,
-                               struct nvkm_notify *);
-void nv50_disp_chan_uevent_send(struct nv50_disp *, int);
-
-extern const struct nvkm_event_func gf119_disp_chan_uevent;
-extern const struct nvkm_event_func gv100_disp_chan_uevent;
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c
deleted file mode 100644 (file)
index 1ae0bcf..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-int
-gf119_disp_oimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_oimm_new_(&gf119_disp_pioc_func, disp, 9, 9,
-                                  oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c
deleted file mode 100644 (file)
index 30ffb10..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "channv50.h"
-
-int
-gp102_disp_oimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_oimm_new_(&gf119_disp_pioc_func, disp, 9, 13,
-                                  oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c
deleted file mode 100644 (file)
index 0db99bf..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "head.h"
-
-#include <core/client.h>
-
-#include <nvif/cl507b.h>
-#include <nvif/unpack.h>
-
-int
-nv50_disp_oimm_new_(const struct nv50_disp_chan_func *func,
-                   struct nv50_disp *disp, int ctrl, int user,
-                   const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nvkm_object **pobject)
-{
-       union {
-               struct nv50_disp_overlay_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       int head, ret = -ENOSYS;
-
-       nvif_ioctl(parent, "create disp overlay size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create disp overlay vers %d head %d\n",
-                          args->v0.version, args->v0.head);
-               if (!nvkm_head_find(&disp->base, args->v0.head))
-                       return -EINVAL;
-               head = args->v0.head;
-       } else
-               return ret;
-
-       return nv50_disp_chan_new_(func, NULL, disp, ctrl + head, user + head,
-                                  head, oclass, pobject);
-}
-
-int
-nv50_disp_oimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                  struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_oimm_new_(&nv50_disp_pioc_func, disp, 5, 5,
-                                  oclass, argv, argc, pobject);
-}
index 129982f..6094805 100644 (file)
@@ -35,7 +35,7 @@ nvkm_outp_route(struct nvkm_disp *disp)
        struct nvkm_outp *outp;
        struct nvkm_ior *ior;
 
-       list_for_each_entry(ior, &disp->ior, head) {
+       list_for_each_entry(ior, &disp->iors, head) {
                if ((outp = ior->arm.outp) && ior->arm.outp != ior->asy.outp) {
                        OUTP_DBG(outp, "release %s", ior->name);
                        if (ior->func->route.set)
@@ -44,7 +44,7 @@ nvkm_outp_route(struct nvkm_disp *disp)
                }
        }
 
-       list_for_each_entry(ior, &disp->ior, head) {
+       list_for_each_entry(ior, &disp->iors, head) {
                if ((outp = ior->asy.outp)) {
                        OUTP_DBG(outp, "acquire %s", ior->name);
                        if (ior->asy.outp != ior->arm.outp) {
@@ -119,8 +119,8 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
        struct nvkm_ior *ior;
 
        /* Failing that, a completely unused OR is the next best thing. */
-       list_for_each_entry(ior, &outp->disp->ior, head) {
-               if (!ior->identity && !!ior->func->hda.hpd == hda &&
+       list_for_each_entry(ior, &outp->disp->iors, head) {
+               if (!ior->identity && ior->hda == hda &&
                    !ior->asy.outp && ior->type == type && !ior->arm.outp &&
                    (ior->func->route.set || ior->id == __ffs(outp->info.or)))
                        return nvkm_outp_acquire_ior(outp, user, ior);
@@ -129,8 +129,8 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
        /* Last resort is to assign an OR that's already active on HW,
         * but will be released during the next modeset.
         */
-       list_for_each_entry(ior, &outp->disp->ior, head) {
-               if (!ior->identity && !!ior->func->hda.hpd == hda &&
+       list_for_each_entry(ior, &outp->disp->iors, head) {
+               if (!ior->identity && ior->hda == hda &&
                    !ior->asy.outp && ior->type == type &&
                    (ior->func->route.set || ior->id == __ffs(outp->info.or)))
                        return nvkm_outp_acquire_ior(outp, user, ior);
@@ -168,7 +168,7 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
        /* First preference is to reuse the OR that is currently armed
         * on HW, if any, in order to prevent unnecessary switching.
         */
-       list_for_each_entry(ior, &outp->disp->ior, head) {
+       list_for_each_entry(ior, &outp->disp->iors, head) {
                if (!ior->identity && !ior->asy.outp && ior->arm.outp == outp) {
                        /*XXX: For various complicated reasons, we can't outright switch
                         *     the boot-time OR on the first modeset without some fairly
@@ -181,7 +181,7 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
                         *
                         *     This warning is to make it obvious if that proves wrong.
                         */
-                       WARN_ON(hda && !ior->func->hda.hpd);
+                       WARN_ON(hda && !ior->hda);
                        return nvkm_outp_acquire_ior(outp, user, ior);
                }
        }
@@ -294,13 +294,17 @@ nvkm_outp_del(struct nvkm_outp **poutp)
 }
 
 int
-nvkm_outp_ctor(const struct nvkm_outp_func *func, struct nvkm_disp *disp,
-              int index, struct dcb_output *dcbE, struct nvkm_outp *outp)
+nvkm_outp_new_(const struct nvkm_outp_func *func, struct nvkm_disp *disp,
+              int index, struct dcb_output *dcbE, struct nvkm_outp **poutp)
 {
        struct nvkm_i2c *i2c = disp->engine.subdev.device->i2c;
+       struct nvkm_outp *outp;
        enum nvkm_ior_proto proto;
        enum nvkm_ior_type type;
 
+       if (!(outp = *poutp = kzalloc(sizeof(*outp), GFP_KERNEL)))
+               return -ENOMEM;
+
        outp->func = func;
        outp->disp = disp;
        outp->index = index;
@@ -330,7 +334,5 @@ int
 nvkm_outp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
              struct nvkm_outp **poutp)
 {
-       if (!(*poutp = kzalloc(sizeof(**poutp), GFP_KERNEL)))
-               return -ENOMEM;
-       return nvkm_outp_ctor(&nvkm_outp, disp, index, dcbE, *poutp);
+       return nvkm_outp_new_(&nvkm_outp, disp, index, dcbE, poutp);
 }
index ee028d3..3f3924c 100644 (file)
@@ -1,10 +1,12 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVKM_DISP_OUTP_H__
 #define __NVKM_DISP_OUTP_H__
-#include <engine/disp.h>
+#include "priv.h"
+#include <core/notify.h>
 
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
+#include <subdev/bios/dp.h>
 
 struct nvkm_outp {
        const struct nvkm_outp_func *func;
@@ -23,12 +25,41 @@ struct nvkm_outp {
 #define NVKM_OUTP_USER 2
        u8 acquired:2;
        struct nvkm_ior *ior;
+
+       union {
+               struct {
+                       struct nvbios_dpout info;
+                       u8 version;
+
+                       struct nvkm_i2c_aux *aux;
+
+                       struct nvkm_notify hpd;
+                       bool present;
+                       u8 lttpr[6];
+                       u8 lttprs;
+                       u8 dpcd[16];
+
+                       struct {
+                               int dpcd; /* -1, or index into SUPPORTED_LINK_RATES table */
+                               u32 rate;
+                       } rate[8];
+                       int rates;
+                       int links;
+
+                       struct mutex mutex;
+                       struct {
+                               atomic_t done;
+                               bool mst;
+                       } lt;
+               } dp;
+       };
+
+       struct nvkm_object object;
 };
 
-int nvkm_outp_ctor(const struct nvkm_outp_func *, struct nvkm_disp *,
-                  int index, struct dcb_output *, struct nvkm_outp *);
-int nvkm_outp_new(struct nvkm_disp *, int index, struct dcb_output *,
-                 struct nvkm_outp **);
+int nvkm_outp_new_(const struct nvkm_outp_func *, struct nvkm_disp *, int index,
+                  struct dcb_output *, struct nvkm_outp **);
+int nvkm_outp_new(struct nvkm_disp *, int index, struct dcb_output *, struct nvkm_outp **);
 void nvkm_outp_del(struct nvkm_outp **);
 void nvkm_outp_init(struct nvkm_outp *);
 void nvkm_outp_fini(struct nvkm_outp *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c
deleted file mode 100644 (file)
index 31b915d..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-g84_disp_ovly_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x000000 },
-               { 0x0084, 0x6109a0 },
-               { 0x0088, 0x6109c0 },
-               { 0x008c, 0x6109c8 },
-               { 0x0090, 0x6109b4 },
-               { 0x0094, 0x610970 },
-               { 0x00a0, 0x610998 },
-               { 0x00a4, 0x610964 },
-               { 0x00c0, 0x610958 },
-               { 0x00e0, 0x6109a8 },
-               { 0x00e4, 0x6109d0 },
-               { 0x00e8, 0x6109d8 },
-               { 0x0100, 0x61094c },
-               { 0x0104, 0x610984 },
-               { 0x0108, 0x61098c },
-               { 0x0800, 0x6109f8 },
-               { 0x0808, 0x610a08 },
-               { 0x080c, 0x610a10 },
-               { 0x0810, 0x610a00 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-g84_disp_ovly_mthd = {
-       .name = "Overlay",
-       .addr = 0x000540,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &g84_disp_ovly_mthd_base },
-               {}
-       }
-};
-
-int
-g84_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                 struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_ovly_new_(&nv50_disp_dmac_func, &g84_disp_ovly_mthd,
-                                  disp, 3, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c
deleted file mode 100644 (file)
index 83fd534..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-gf119_disp_ovly_mthd_base = {
-       .mthd = 0x0000,
-       .data = {
-               { 0x0080, 0x665080 },
-               { 0x0084, 0x665084 },
-               { 0x0088, 0x665088 },
-               { 0x008c, 0x66508c },
-               { 0x0090, 0x665090 },
-               { 0x0094, 0x665094 },
-               { 0x00a0, 0x6650a0 },
-               { 0x00a4, 0x6650a4 },
-               { 0x00b0, 0x6650b0 },
-               { 0x00b4, 0x6650b4 },
-               { 0x00b8, 0x6650b8 },
-               { 0x00c0, 0x6650c0 },
-               { 0x00e0, 0x6650e0 },
-               { 0x00e4, 0x6650e4 },
-               { 0x00e8, 0x6650e8 },
-               { 0x0100, 0x665100 },
-               { 0x0104, 0x665104 },
-               { 0x0108, 0x665108 },
-               { 0x010c, 0x66510c },
-               { 0x0110, 0x665110 },
-               { 0x0118, 0x665118 },
-               { 0x011c, 0x66511c },
-               { 0x0120, 0x665120 },
-               { 0x0124, 0x665124 },
-               { 0x0130, 0x665130 },
-               { 0x0134, 0x665134 },
-               { 0x0138, 0x665138 },
-               { 0x013c, 0x66513c },
-               { 0x0140, 0x665140 },
-               { 0x0144, 0x665144 },
-               { 0x0148, 0x665148 },
-               { 0x014c, 0x66514c },
-               { 0x0150, 0x665150 },
-               { 0x0154, 0x665154 },
-               { 0x0158, 0x665158 },
-               { 0x015c, 0x66515c },
-               { 0x0160, 0x665160 },
-               { 0x0164, 0x665164 },
-               { 0x0168, 0x665168 },
-               { 0x016c, 0x66516c },
-               { 0x0400, 0x665400 },
-               { 0x0408, 0x665408 },
-               { 0x040c, 0x66540c },
-               { 0x0410, 0x665410 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-gf119_disp_ovly_mthd = {
-       .name = "Overlay",
-       .addr = 0x001000,
-       .prev = -0x020000,
-       .data = {
-               { "Global", 1, &gf119_disp_ovly_mthd_base },
-               {}
-       }
-};
-
-int
-gf119_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_ovly_new_(&gf119_disp_dmac_func, &gf119_disp_ovly_mthd,
-                                  disp, 5, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c
deleted file mode 100644 (file)
index a7acacb..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-gk104_disp_ovly_mthd_base = {
-       .mthd = 0x0000,
-       .data = {
-               { 0x0080, 0x665080 },
-               { 0x0084, 0x665084 },
-               { 0x0088, 0x665088 },
-               { 0x008c, 0x66508c },
-               { 0x0090, 0x665090 },
-               { 0x0094, 0x665094 },
-               { 0x00a0, 0x6650a0 },
-               { 0x00a4, 0x6650a4 },
-               { 0x00b0, 0x6650b0 },
-               { 0x00b4, 0x6650b4 },
-               { 0x00b8, 0x6650b8 },
-               { 0x00c0, 0x6650c0 },
-               { 0x00c4, 0x6650c4 },
-               { 0x00e0, 0x6650e0 },
-               { 0x00e4, 0x6650e4 },
-               { 0x00e8, 0x6650e8 },
-               { 0x0100, 0x665100 },
-               { 0x0104, 0x665104 },
-               { 0x0108, 0x665108 },
-               { 0x010c, 0x66510c },
-               { 0x0110, 0x665110 },
-               { 0x0118, 0x665118 },
-               { 0x011c, 0x66511c },
-               { 0x0120, 0x665120 },
-               { 0x0124, 0x665124 },
-               { 0x0130, 0x665130 },
-               { 0x0134, 0x665134 },
-               { 0x0138, 0x665138 },
-               { 0x013c, 0x66513c },
-               { 0x0140, 0x665140 },
-               { 0x0144, 0x665144 },
-               { 0x0148, 0x665148 },
-               { 0x014c, 0x66514c },
-               { 0x0150, 0x665150 },
-               { 0x0154, 0x665154 },
-               { 0x0158, 0x665158 },
-               { 0x015c, 0x66515c },
-               { 0x0160, 0x665160 },
-               { 0x0164, 0x665164 },
-               { 0x0168, 0x665168 },
-               { 0x016c, 0x66516c },
-               { 0x0400, 0x665400 },
-               { 0x0404, 0x665404 },
-               { 0x0408, 0x665408 },
-               { 0x040c, 0x66540c },
-               { 0x0410, 0x665410 },
-               {}
-       }
-};
-
-const struct nv50_disp_chan_mthd
-gk104_disp_ovly_mthd = {
-       .name = "Overlay",
-       .addr = 0x001000,
-       .prev = -0x020000,
-       .data = {
-               { "Global", 1, &gk104_disp_ovly_mthd_base },
-               {}
-       }
-};
-
-int
-gk104_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_ovly_new_(&gf119_disp_dmac_func, &gk104_disp_ovly_mthd,
-                                  disp, 5, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c
deleted file mode 100644 (file)
index e0eca6e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-int
-gp102_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_ovly_new_(&gp102_disp_dmac_func, &gk104_disp_ovly_mthd,
-                                  disp, 5, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c
deleted file mode 100644 (file)
index dc60cd0..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-
-static const struct nv50_disp_mthd_list
-gt200_disp_ovly_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x000000 },
-               { 0x0084, 0x6109a0 },
-               { 0x0088, 0x6109c0 },
-               { 0x008c, 0x6109c8 },
-               { 0x0090, 0x6109b4 },
-               { 0x0094, 0x610970 },
-               { 0x00a0, 0x610998 },
-               { 0x00a4, 0x610964 },
-               { 0x00b0, 0x610c98 },
-               { 0x00b4, 0x610ca4 },
-               { 0x00b8, 0x610cac },
-               { 0x00c0, 0x610958 },
-               { 0x00e0, 0x6109a8 },
-               { 0x00e4, 0x6109d0 },
-               { 0x00e8, 0x6109d8 },
-               { 0x0100, 0x61094c },
-               { 0x0104, 0x610984 },
-               { 0x0108, 0x61098c },
-               { 0x0800, 0x6109f8 },
-               { 0x0808, 0x610a08 },
-               { 0x080c, 0x610a10 },
-               { 0x0810, 0x610a00 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-gt200_disp_ovly_mthd = {
-       .name = "Overlay",
-       .addr = 0x000540,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &gt200_disp_ovly_mthd_base },
-               {}
-       }
-};
-
-int
-gt200_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_ovly_new_(&nv50_disp_dmac_func, &gt200_disp_ovly_mthd,
-                                  disp, 3, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c
deleted file mode 100644 (file)
index 6974c12..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "head.h"
-
-#include <core/client.h>
-
-#include <nvif/cl507e.h>
-#include <nvif/unpack.h>
-
-int
-nv50_disp_ovly_new_(const struct nv50_disp_chan_func *func,
-                   const struct nv50_disp_chan_mthd *mthd,
-                   struct nv50_disp *disp, int chid,
-                   const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nvkm_object **pobject)
-{
-       union {
-               struct nv50_disp_overlay_channel_dma_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       int head, ret = -ENOSYS;
-       u64 push;
-
-       nvif_ioctl(parent, "create disp overlay channel dma size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create disp overlay channel dma vers %d "
-                                  "pushbuf %016llx head %d\n",
-                          args->v0.version, args->v0.pushbuf, args->v0.head);
-               if (!nvkm_head_find(&disp->base, args->v0.head))
-                       return -EINVAL;
-               push = args->v0.pushbuf;
-               head = args->v0.head;
-       } else
-               return ret;
-
-       return nv50_disp_dmac_new_(func, mthd, disp, chid + head,
-                                  head, push, oclass, pobject);
-}
-
-static const struct nv50_disp_mthd_list
-nv50_disp_ovly_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0080, 0x000000 },
-               { 0x0084, 0x0009a0 },
-               { 0x0088, 0x0009c0 },
-               { 0x008c, 0x0009c8 },
-               { 0x0090, 0x6109b4 },
-               { 0x0094, 0x610970 },
-               { 0x00a0, 0x610998 },
-               { 0x00a4, 0x610964 },
-               { 0x00c0, 0x610958 },
-               { 0x00e0, 0x6109a8 },
-               { 0x00e4, 0x6109d0 },
-               { 0x00e8, 0x6109d8 },
-               { 0x0100, 0x61094c },
-               { 0x0104, 0x610984 },
-               { 0x0108, 0x61098c },
-               { 0x0800, 0x6109f8 },
-               { 0x0808, 0x610a08 },
-               { 0x080c, 0x610a10 },
-               { 0x0810, 0x610a00 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-nv50_disp_ovly_mthd = {
-       .name = "Overlay",
-       .addr = 0x000540,
-       .prev = 0x000004,
-       .data = {
-               { "Global", 1, &nv50_disp_ovly_mthd_base },
-               {}
-       }
-};
-
-int
-nv50_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                  struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return nv50_disp_ovly_new_(&nv50_disp_dmac_func, &nv50_disp_ovly_mthd,
-                                  disp, 3, oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c
deleted file mode 100644 (file)
index 5296e7b..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "rootnv50.h"
-
-#include <subdev/timer.h>
-
-static void
-gf119_disp_pioc_fini(struct nv50_disp_chan *chan)
-{
-       struct nv50_disp *disp = chan->disp;
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       nvkm_mask(device, 0x610490 + (ctrl * 0x10), 0x00000001, 0x00000000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x00030000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d fini: %08x\n", user,
-                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
-       }
-}
-
-static int
-gf119_disp_pioc_init(struct nv50_disp_chan *chan)
-{
-       struct nv50_disp *disp = chan->disp;
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       /* activate channel */
-       nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001);
-       if (nvkm_msec(device, 2000,
-               u32 tmp = nvkm_rd32(device, 0x610490 + (ctrl * 0x10));
-               if ((tmp & 0x00030000) == 0x00010000)
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d init: %08x\n", user,
-                          nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-gf119_disp_pioc_func = {
-       .init = gf119_disp_pioc_init,
-       .fini = gf119_disp_pioc_fini,
-       .intr = gf119_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c
deleted file mode 100644 (file)
index 4faed6f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "channv50.h"
-#include "rootnv50.h"
-
-#include <subdev/timer.h>
-
-static void
-nv50_disp_pioc_fini(struct nv50_disp_chan *chan)
-{
-       struct nv50_disp *disp = chan->disp;
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       nvkm_mask(device, 0x610200 + (ctrl * 0x10), 0x00000001, 0x00000000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d timeout: %08x\n", user,
-                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
-       }
-}
-
-static int
-nv50_disp_pioc_init(struct nv50_disp_chan *chan)
-{
-       struct nv50_disp *disp = chan->disp;
-       struct nvkm_subdev *subdev = &disp->base.engine.subdev;
-       struct nvkm_device *device = subdev->device;
-       int ctrl = chan->chid.ctrl;
-       int user = chan->chid.user;
-
-       nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00002000);
-       if (nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d timeout0: %08x\n", user,
-                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
-               return -EBUSY;
-       }
-
-       nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00000001);
-       if (nvkm_msec(device, 2000,
-               u32 tmp = nvkm_rd32(device, 0x610200 + (ctrl * 0x10));
-               if ((tmp & 0x00030000) == 0x00010000)
-                       break;
-       ) < 0) {
-               nvkm_error(subdev, "ch %d timeout1: %08x\n", user,
-                          nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-const struct nv50_disp_chan_func
-nv50_disp_pioc_func = {
-       .init = nv50_disp_pioc_init,
-       .fini = nv50_disp_pioc_fini,
-       .intr = nv50_disp_chan_intr,
-       .user = nv50_disp_chan_user,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
deleted file mode 100644 (file)
index e997a20..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-#include "head.h"
-
-#include <subdev/i2c.h>
-#include <subdev/timer.h>
-
-static void
-nv50_pior_clock(struct nvkm_ior *pior)
-{
-       struct nvkm_device *device = pior->disp->engine.subdev.device;
-       const u32 poff = nv50_ior_base(pior);
-       nvkm_mask(device, 0x614380 + poff, 0x00000707, 0x00000001);
-}
-
-static int
-nv50_pior_dp_links(struct nvkm_ior *pior, struct nvkm_i2c_aux *aux)
-{
-       int ret = nvkm_i2c_aux_lnk_ctl(aux, pior->dp.nr, pior->dp.bw,
-                                           pior->dp.ef);
-       if (ret)
-               return ret;
-       return 1;
-}
-
-static void
-nv50_pior_power_wait(struct nvkm_device *device, u32 poff)
-{
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x61e004 + poff) & 0x80000000))
-                       break;
-       );
-}
-
-static void
-nv50_pior_power(struct nvkm_ior *pior, bool normal, bool pu,
-              bool data, bool vsync, bool hsync)
-{
-       struct nvkm_device *device = pior->disp->engine.subdev.device;
-       const u32  poff = nv50_ior_base(pior);
-       const u32 shift = normal ? 0 : 16;
-       const u32 state = 0x80000000 | (0x00000001 * !!pu) << shift;
-       const u32 field = 0x80000000 | (0x00000101 << shift);
-
-       nv50_pior_power_wait(device, poff);
-       nvkm_mask(device, 0x61e004 + poff, field, state);
-       nv50_pior_power_wait(device, poff);
-}
-
-void
-nv50_pior_depth(struct nvkm_ior *ior, struct nvkm_ior_state *state, u32 ctrl)
-{
-       /* GF119 moves this information to per-head methods, which is
-        * a lot more convenient, and where our shared code expect it.
-        */
-       if (state->head && state == &ior->asy) {
-               struct nvkm_head *head =
-                       nvkm_head_find(ior->disp, __ffs(state->head));
-               if (!WARN_ON(!head)) {
-                       struct nvkm_head_state *state = &head->asy;
-                       switch ((ctrl & 0x000f0000) >> 16) {
-                       case 6: state->or.depth = 30; break;
-                       case 5: state->or.depth = 24; break;
-                       case 2: state->or.depth = 18; break;
-                       case 0: state->or.depth = 18; break; /*XXX*/
-                       default:
-                               state->or.depth = 18;
-                               WARN_ON(1);
-                               break;
-                       }
-               }
-       }
-}
-
-static void
-nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = pior->disp->engine.subdev.device;
-       const u32 coff = pior->id * 8 + (state == &pior->arm) * 4;
-       u32 ctrl = nvkm_rd32(device, 0x610b80 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       state->rgdiv = 1;
-       switch (state->proto_evo) {
-       case 0: state->proto = TMDS; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x00000003;
-       nv50_pior_depth(pior, state, ctrl);
-}
-
-static const struct nvkm_ior_func
-nv50_pior = {
-       .state = nv50_pior_state,
-       .power = nv50_pior_power,
-       .clock = nv50_pior_clock,
-       .dp = {
-               .links = nv50_pior_dp_links,
-       },
-};
-
-int
-nv50_pior_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&nv50_pior, disp, PIOR, id);
-}
-
-int
-nv50_pior_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x610184) & 0x70000000) >> 28;
-       return 3;
-}
index ec57d8b..cb25dfe 100644 (file)
@@ -1,8 +1,12 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVKM_DISP_PRIV_H__
 #define __NVKM_DISP_PRIV_H__
+#define nvkm_udisp(p) container_of((p), struct nvkm_disp, client.object)
 #include <engine/disp.h>
-#include "outp.h"
+#include <core/enum.h>
+struct nvkm_head;
+struct nvkm_outp;
+struct dcb_output;
 
 int nvkm_disp_ctor(const struct nvkm_disp_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
                   struct nvkm_disp *);
@@ -11,22 +15,75 @@ int nvkm_disp_new_(const struct nvkm_disp_func *, struct nvkm_device *, enum nvk
 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 *);
+       void (*intr_error)(struct nvkm_disp *, int chid);
 
-       const struct nvkm_disp_oclass *(*root)(struct nvkm_disp *);
+       void (*super)(struct work_struct *);
+
+       const struct nvkm_event_func *uevent;
+
+       struct {
+               int (*cnt)(struct nvkm_disp *, unsigned long *mask);
+               int (*new)(struct nvkm_disp *, int id);
+       } wndw, head, dac, sor, pior;
+
+       u16 ramht_size;
+
+       const struct nvkm_sclass root;
+
+       struct nvkm_disp_user {
+               struct nvkm_sclass base;
+               int (*ctor)(const struct nvkm_oclass *, void *argv, u32 argc,
+                           struct nvkm_object **);
+               const struct nvkm_disp_chan_user *chan;
+       } user[];
 };
 
 int  nvkm_disp_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
+int nv04_disp_mthd(struct nvkm_object *, u32, void *, u32);
+int nv50_disp_root_mthd_(struct nvkm_object *, u32, void *, u32);
 
-extern const struct nvkm_disp_oclass nv04_disp_root_oclass;
+int nv50_disp_oneinit(struct nvkm_disp *);
+int nv50_disp_init(struct nvkm_disp *);
+void nv50_disp_fini(struct nvkm_disp *);
+void nv50_disp_intr(struct nvkm_disp *);
+extern const struct nvkm_enum nv50_disp_intr_error_type[];
+void nv50_disp_super(struct work_struct *);
+void nv50_disp_super_1(struct nvkm_disp *);
+void nv50_disp_super_1_0(struct nvkm_disp *, struct nvkm_head *);
+void nv50_disp_super_2_0(struct nvkm_disp *, struct nvkm_head *);
+void nv50_disp_super_2_1(struct nvkm_disp *, struct nvkm_head *);
+void nv50_disp_super_2_2(struct nvkm_disp *, struct nvkm_head *);
+void nv50_disp_super_3_0(struct nvkm_disp *, struct nvkm_head *);
 
-struct nvkm_disp_oclass {
-       int (*ctor)(struct nvkm_disp *, const struct nvkm_oclass *,
-                   void *data, u32 size, struct nvkm_object **);
-       struct nvkm_sclass base;
-};
+int gf119_disp_init(struct nvkm_disp *);
+void gf119_disp_fini(struct nvkm_disp *);
+void gf119_disp_intr(struct nvkm_disp *);
+void gf119_disp_super(struct work_struct *);
+void gf119_disp_intr_error(struct nvkm_disp *, int);
+
+void gv100_disp_fini(struct nvkm_disp *);
+void gv100_disp_intr(struct nvkm_disp *);
+void gv100_disp_super(struct work_struct *);
+int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *);
+int gv100_disp_caps_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
+
+int tu102_disp_init(struct nvkm_disp *);
+
+void nv50_disp_dptmds_war_2(struct nvkm_disp *, struct dcb_output *);
+void nv50_disp_dptmds_war_3(struct nvkm_disp *, struct dcb_output *);
+void nv50_disp_update_sppll1(struct nvkm_disp *);
+
+extern const struct nvkm_event_func nv50_disp_chan_uevent;
+void nv50_disp_chan_uevent_send(struct nvkm_disp *, int);
+
+extern const struct nvkm_event_func gf119_disp_chan_uevent;
+extern const struct nvkm_event_func gv100_disp_chan_uevent;
+
+int nvkm_udisp_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
+int nvkm_uconn_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
+int nvkm_uoutp_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c
deleted file mode 100644 (file)
index 1ed371f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-g84_disp_root = {
-       .user = {
-               {{0,0,G82_DISP_CURSOR             }, nv50_disp_curs_new },
-               {{0,0,G82_DISP_OVERLAY            }, nv50_disp_oimm_new },
-               {{0,0,G82_DISP_BASE_CHANNEL_DMA   },  g84_disp_base_new },
-               {{0,0,G82_DISP_CORE_CHANNEL_DMA   },  g84_disp_core_new },
-               {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA},  g84_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-g84_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                 void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&g84_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-g84_disp_root_oclass = {
-       .base.oclass = G82_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = g84_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c
deleted file mode 100644 (file)
index fe01116..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gf119_disp_root = {
-       .user = {
-               {{0,0,GF110_DISP_CURSOR             }, gf119_disp_curs_new },
-               {{0,0,GF110_DISP_OVERLAY            }, gf119_disp_oimm_new },
-               {{0,0,GF110_DISP_BASE_CHANNEL_DMA   }, gf119_disp_base_new },
-               {{0,0,GF110_DISP_CORE_CHANNEL_DMA   }, gf119_disp_core_new },
-               {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, gf119_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gf119_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gf119_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gf119_disp_root_oclass = {
-       .base.oclass = GF110_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gf119_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c
deleted file mode 100644 (file)
index 9e8ffd3..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gk104_disp_root = {
-       .user = {
-               {{0,0,GK104_DISP_CURSOR             }, gf119_disp_curs_new },
-               {{0,0,GK104_DISP_OVERLAY            }, gf119_disp_oimm_new },
-               {{0,0,GK104_DISP_BASE_CHANNEL_DMA   }, gf119_disp_base_new },
-               {{0,0,GK104_DISP_CORE_CHANNEL_DMA   }, gk104_disp_core_new },
-               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gk104_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gk104_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gk104_disp_root_oclass = {
-       .base.oclass = GK104_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gk104_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c
deleted file mode 100644 (file)
index dc85cc1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gk110_disp_root = {
-       .user = {
-               {{0,0,GK104_DISP_CURSOR             }, gf119_disp_curs_new },
-               {{0,0,GK104_DISP_OVERLAY            }, gf119_disp_oimm_new },
-               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, gf119_disp_base_new },
-               {{0,0,GK110_DISP_CORE_CHANNEL_DMA   }, gk104_disp_core_new },
-               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gk110_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gk110_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gk110_disp_root_oclass = {
-       .base.oclass = GK110_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gk110_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c
deleted file mode 100644 (file)
index e0181ca..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gm107_disp_root = {
-       .user = {
-               {{0,0,GK104_DISP_CURSOR             }, gf119_disp_curs_new },
-               {{0,0,GK104_DISP_OVERLAY            }, gf119_disp_oimm_new },
-               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, gf119_disp_base_new },
-               {{0,0,GM107_DISP_CORE_CHANNEL_DMA   }, gk104_disp_core_new },
-               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gm107_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gm107_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gm107_disp_root_oclass = {
-       .base.oclass = GM107_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gm107_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c
deleted file mode 100644 (file)
index e5e590e..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gm200_disp_root = {
-       .user = {
-               {{0,0,GK104_DISP_CURSOR             }, gf119_disp_curs_new },
-               {{0,0,GK104_DISP_OVERLAY            }, gf119_disp_oimm_new },
-               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, gf119_disp_base_new },
-               {{0,0,GM200_DISP_CORE_CHANNEL_DMA   }, gk104_disp_core_new },
-               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gm200_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gm200_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gm200_disp_root_oclass = {
-       .base.oclass = GM200_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gm200_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c
deleted file mode 100644 (file)
index 762a1a9..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gp100_disp_root = {
-       .user = {
-               {{0,0,GK104_DISP_CURSOR             }, gf119_disp_curs_new },
-               {{0,0,GK104_DISP_OVERLAY            }, gf119_disp_oimm_new },
-               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, gf119_disp_base_new },
-               {{0,0,GP100_DISP_CORE_CHANNEL_DMA   }, gk104_disp_core_new },
-               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gp100_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gp100_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gp100_disp_root_oclass = {
-       .base.oclass = GP100_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gp100_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c
deleted file mode 100644 (file)
index c7f0094..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gp102_disp_root = {
-       .user = {
-               {{0,0,GK104_DISP_CURSOR             }, gp102_disp_curs_new },
-               {{0,0,GK104_DISP_OVERLAY            }, gp102_disp_oimm_new },
-               {{0,0,GK110_DISP_BASE_CHANNEL_DMA   }, gp102_disp_base_new },
-               {{0,0,GP102_DISP_CORE_CHANNEL_DMA   }, gp102_disp_core_new },
-               {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gp102_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gp102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gp102_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gp102_disp_root_oclass = {
-       .base.oclass = GP102_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gp102_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c
deleted file mode 100644 (file)
index a696365..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gt200_disp_root = {
-       .user = {
-               {{0,0,  G82_DISP_CURSOR             },  nv50_disp_curs_new },
-               {{0,0,  G82_DISP_OVERLAY            },  nv50_disp_oimm_new },
-               {{0,0,GT200_DISP_BASE_CHANNEL_DMA   },   g84_disp_base_new },
-               {{0,0,GT200_DISP_CORE_CHANNEL_DMA   },   g84_disp_core_new },
-               {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gt200_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gt200_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gt200_disp_root_oclass = {
-       .base.oclass = GT200_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gt200_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c
deleted file mode 100644 (file)
index 4fe0a3a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gt215_disp_root = {
-       .user = {
-               {{0,0,GT214_DISP_CURSOR             },  nv50_disp_curs_new },
-               {{0,0,GT214_DISP_OVERLAY            },  nv50_disp_oimm_new },
-               {{0,0,GT214_DISP_BASE_CHANNEL_DMA   },   g84_disp_base_new },
-               {{0,0,GT214_DISP_CORE_CHANNEL_DMA   },   g94_disp_core_new },
-               {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA},   g84_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-gt215_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gt215_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gt215_disp_root_oclass = {
-       .base.oclass = GT214_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gt215_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c
deleted file mode 100644 (file)
index 47efb48..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-gv100_disp_root = {
-       .user = {
-               {{-1,-1,GV100_DISP_CAPS                }, gv100_disp_caps_new },
-               {{0,0,GV100_DISP_CURSOR                }, gv100_disp_curs_new },
-               {{0,0,GV100_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new },
-               {{0,0,GV100_DISP_CORE_CHANNEL_DMA      }, gv100_disp_core_new },
-               {{0,0,GV100_DISP_WINDOW_CHANNEL_DMA    }, gv100_disp_wndw_new },
-               {}
-       },
-};
-
-static int
-gv100_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&gv100_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-gv100_disp_root_oclass = {
-       .base.oclass = GV100_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = gv100_disp_root_new,
-};
index 7f3e255..9acaec5 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#define nv04_disp_root(p) container_of((p), struct nv04_disp_root, object)
 #include "priv.h"
 #include "head.h"
 
 #include <core/client.h>
 
-#include <nvif/class.h>
 #include <nvif/cl0046.h>
 #include <nvif/unpack.h>
 
-struct nv04_disp_root {
-       struct nvkm_object object;
-       struct nvkm_disp *disp;
-};
-
-static int
+int
 nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 {
-       struct nv04_disp_root *root = nv04_disp_root(object);
+       struct nvkm_disp *disp = nvkm_disp(object->engine);
        union {
                struct nv04_disp_mthd_v0 v0;
        } *args = data;
@@ -55,7 +48,7 @@ nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
        } else
                return ret;
 
-       if (!(head = nvkm_head_find(root->disp, id)))
+       if (!(head = nvkm_head_find(disp, id)))
                return -ENXIO;
 
        switch (mthd) {
@@ -67,32 +60,3 @@ nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 
        return -EINVAL;
 }
-
-static const struct nvkm_object_func
-nv04_disp_root = {
-       .mthd = nv04_disp_mthd,
-       .ntfy = nvkm_disp_ntfy,
-};
-
-static int
-nv04_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                  void *data, u32 size, struct nvkm_object **pobject)
-{
-       struct nv04_disp_root *root;
-
-       if (!(root = kzalloc(sizeof(*root), GFP_KERNEL)))
-               return -ENOMEM;
-       root->disp = disp;
-       *pobject = &root->object;
-
-       nvkm_object_ctor(&nv04_disp_root, oclass, &root->object);
-       return 0;
-}
-
-const struct nvkm_disp_oclass
-nv04_disp_root_oclass = {
-       .base.oclass = NV04_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = nv04_disp_root_new,
-};
index ecde98d..0af45cc 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include "rootnv50.h"
-#include "channv50.h"
-#include "dp.h"
+#include "chan.h"
 #include "head.h"
 #include "ior.h"
+#include "outp.h"
 
 #include <core/client.h>
 
 #include <nvif/cl5070.h>
 #include <nvif/unpack.h>
 
-static int
+int
 nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 {
        union {
                struct nv50_disp_mthd_v0 v0;
                struct nv50_disp_mthd_v1 v1;
        } *args = data;
-       struct nv50_disp_root *root = nv50_disp_root(object);
-       struct nv50_disp *disp = root->disp;
+       struct nvkm_disp *disp = nvkm_udisp(object);
        struct nvkm_outp *temp, *outp = NULL;
        struct nvkm_head *head;
        u16 type, mask = 0;
@@ -69,11 +67,11 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
        } else
                return ret;
 
-       if (!(head = nvkm_head_find(&disp->base, hidx)))
+       if (!(head = nvkm_head_find(disp, hidx)))
                return -ENXIO;
 
        if (mask) {
-               list_for_each_entry(temp, &disp->base.outp, head) {
+               list_for_each_entry(temp, &disp->outps, head) {
                        if ((temp->info.hasht         == type) &&
                            (temp->info.hashm & mask) == mask) {
                                outp = temp;
@@ -111,27 +109,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
        case NV50_DISP_MTHD_V1_RELEASE:
                nvkm_outp_release(outp, NVKM_OUTP_USER);
                return 0;
-       case NV50_DISP_MTHD_V1_DAC_LOAD: {
-               union {
-                       struct nv50_disp_dac_load_v0 v0;
-               } *args = data;
-               int ret = -ENOSYS;
-               if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
-                       if (args->v0.data & 0xfff00000)
-                               return -EINVAL;
-                       ret = nvkm_outp_acquire(outp, NVKM_OUTP_PRIV, false);
-                       if (ret)
-                               return ret;
-                       ret = outp->ior->func->sense(outp->ior, args->v0.data);
-                       nvkm_outp_release(outp, NVKM_OUTP_PRIV);
-                       if (ret < 0)
-                               return ret;
-                       args->v0.load = ret;
-                       return 0;
-               } else
-                       return ret;
-       }
-               break;
        case NV50_DISP_MTHD_V1_SOR_HDA_ELD: {
                union {
                        struct nv50_disp_sor_hda_eld_v0 v0;
@@ -148,18 +125,18 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
                } else
                        return ret;
 
-               if (!ior->func->hda.hpd)
+               if (!ior->hda)
                        return -ENODEV;
 
                if (size && args->v0.data[0]) {
                        if (outp->info.type == DCB_OUTPUT_DP)
-                               ior->func->dp.audio(ior, hidx, true);
-                       ior->func->hda.hpd(ior, hidx, true);
-                       ior->func->hda.eld(ior, hidx, data, size);
+                               ior->func->dp->audio(ior, hidx, true);
+                       ior->func->hda->hpd(ior, hidx, true);
+                       ior->func->hda->eld(ior, hidx, data, size);
                } else {
                        if (outp->info.type == DCB_OUTPUT_DP)
-                               ior->func->dp.audio(ior, hidx, false);
-                       ior->func->hda.hpd(ior, hidx, false);
+                               ior->func->dp->audio(ior, hidx, false);
+                       ior->func->hda->hpd(ior, hidx, false);
                }
 
                return 0;
@@ -227,7 +204,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
        }
                break;
        case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
-               struct nvkm_dp *dp = nvkm_dp(outp);
                union {
                        struct nv50_disp_sor_dp_mst_link_v0 v0;
                } *args = data;
@@ -236,7 +212,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
                if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
                        nvif_ioctl(object, "disp sor dp mst link vers %d state %d\n",
                                   args->v0.version, args->v0.state);
-                       dp->lt.mst = !!args->v0.state;
+                       outp->dp.lt.mst = !!args->v0.state;
                        return 0;
                } else
                        return ret;
@@ -254,9 +230,9 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
                                   args->v0.version, args->v0.start_slot,
                                   args->v0.num_slots, args->v0.pbn,
                                   args->v0.aligned_pbn);
-                       if (!outp->ior->func->dp.vcpi)
+                       if (!outp->ior->func->dp->vcpi)
                                return -ENODEV;
-                       outp->ior->func->dp.vcpi(outp->ior, hidx,
+                       outp->ior->func->dp->vcpi(outp->ior, hidx,
                                                 args->v0.start_slot,
                                                 args->v0.num_slots,
                                                 args->v0.pbn,
@@ -272,89 +248,3 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 
        return -EINVAL;
 }
-
-static int
-nv50_disp_root_child_new_(const struct nvkm_oclass *oclass,
-                         void *argv, u32 argc, struct nvkm_object **pobject)
-{
-       struct nv50_disp *disp = nv50_disp_root(oclass->parent)->disp;
-       const struct nv50_disp_user *user = oclass->priv;
-       return user->ctor(oclass, argv, argc, disp, pobject);
-}
-
-static int
-nv50_disp_root_child_get_(struct nvkm_object *object, int index,
-                         struct nvkm_oclass *sclass)
-{
-       struct nv50_disp_root *root = nv50_disp_root(object);
-
-       if (root->func->user[index].ctor) {
-               sclass->base = root->func->user[index].base;
-               sclass->priv = root->func->user + index;
-               sclass->ctor = nv50_disp_root_child_new_;
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
-static void *
-nv50_disp_root_dtor_(struct nvkm_object *object)
-{
-       struct nv50_disp_root *root = nv50_disp_root(object);
-       return root;
-}
-
-static const struct nvkm_object_func
-nv50_disp_root_ = {
-       .dtor = nv50_disp_root_dtor_,
-       .mthd = nv50_disp_root_mthd_,
-       .ntfy = nvkm_disp_ntfy,
-       .sclass = nv50_disp_root_child_get_,
-};
-
-int
-nv50_disp_root_new_(const struct nv50_disp_root_func *func,
-                   struct nvkm_disp *base, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       struct nv50_disp *disp = nv50_disp(base);
-       struct nv50_disp_root *root;
-
-       if (!(root = kzalloc(sizeof(*root), GFP_KERNEL)))
-               return -ENOMEM;
-       *pobject = &root->object;
-
-       nvkm_object_ctor(&nv50_disp_root_, oclass, &root->object);
-       root->func = func;
-       root->disp = disp;
-       return 0;
-}
-
-static const struct nv50_disp_root_func
-nv50_disp_root = {
-       .user = {
-               {{0,0,NV50_DISP_CURSOR             }, nv50_disp_curs_new },
-               {{0,0,NV50_DISP_OVERLAY            }, nv50_disp_oimm_new },
-               {{0,0,NV50_DISP_BASE_CHANNEL_DMA   }, nv50_disp_base_new },
-               {{0,0,NV50_DISP_CORE_CHANNEL_DMA   }, nv50_disp_core_new },
-               {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nv50_disp_ovly_new },
-               {}
-       },
-};
-
-static int
-nv50_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                  void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&nv50_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-nv50_disp_root_oclass = {
-       .base.oclass = NV50_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = nv50_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h
deleted file mode 100644 (file)
index 27bb170..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NV50_DISP_ROOT_H__
-#define __NV50_DISP_ROOT_H__
-#define nv50_disp_root(p) container_of((p), struct nv50_disp_root, object)
-#include <core/object.h>
-#include "nv50.h"
-
-struct nv50_disp_root {
-       const struct nv50_disp_root_func *func;
-       struct nv50_disp *disp;
-       struct nvkm_object object;
-};
-
-struct nv50_disp_root_func {
-       int blah;
-       struct nv50_disp_user {
-               struct nvkm_sclass base;
-               int (*ctor)(const struct nvkm_oclass *, void *argv, u32 argc,
-                           struct nv50_disp *, struct nvkm_object **);
-       } user[];
-};
-
-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 gv100_disp_caps_new(const struct nvkm_oclass *, void *, u32,
-                       struct nv50_disp *, struct nvkm_object **);
-
-extern const struct nvkm_disp_oclass nv50_disp_root_oclass;
-extern const struct nvkm_disp_oclass g84_disp_root_oclass;
-extern const struct nvkm_disp_oclass g94_disp_root_oclass;
-extern const struct nvkm_disp_oclass gt200_disp_root_oclass;
-extern const struct nvkm_disp_oclass gt215_disp_root_oclass;
-extern const struct nvkm_disp_oclass gf119_disp_root_oclass;
-extern const struct nvkm_disp_oclass gk104_disp_root_oclass;
-extern const struct nvkm_disp_oclass gk110_disp_root_oclass;
-extern const struct nvkm_disp_oclass gm107_disp_root_oclass;
-extern const struct nvkm_disp_oclass gm200_disp_root_oclass;
-extern const struct nvkm_disp_oclass gp100_disp_root_oclass;
-extern const struct nvkm_disp_oclass gp102_disp_root_oclass;
-extern const struct nvkm_disp_oclass gv100_disp_root_oclass;
-extern const struct nvkm_disp_oclass tu102_disp_root_oclass;
-extern const struct nvkm_disp_oclass ga102_disp_root_oclass;
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c
deleted file mode 100644 (file)
index d8719d3..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "rootnv50.h"
-#include "channv50.h"
-
-#include <nvif/class.h>
-
-static const struct nv50_disp_root_func
-tu102_disp_root = {
-       .user = {
-               {{-1,-1,GV100_DISP_CAPS                }, gv100_disp_caps_new },
-               {{0,0,TU102_DISP_CURSOR                }, gv100_disp_curs_new },
-               {{0,0,TU102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new },
-               {{0,0,TU102_DISP_CORE_CHANNEL_DMA      }, gv100_disp_core_new },
-               {{0,0,TU102_DISP_WINDOW_CHANNEL_DMA    }, gv100_disp_wndw_new },
-               {}
-       },
-};
-
-static int
-tu102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
-                   void *data, u32 size, struct nvkm_object **pobject)
-{
-       return nv50_disp_root_new_(&tu102_disp_root, disp, oclass,
-                                  data, size, pobject);
-}
-
-const struct nvkm_disp_oclass
-tu102_disp_root_oclass = {
-       .base.oclass = TU102_DISP,
-       .base.minver = -1,
-       .base.maxver = -1,
-       .ctor = tu102_disp_root_new,
-};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c
deleted file mode 100644 (file)
index ec3a7db..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-static const struct nvkm_ior_func
-g84_sor = {
-       .state = nv50_sor_state,
-       .power = nv50_sor_power,
-       .clock = nv50_sor_clock,
-       .hdmi = {
-               .ctrl = g84_hdmi_ctrl,
-       },
-};
-
-int
-g84_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&g84_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
deleted file mode 100644 (file)
index 56b8f44..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-void
-g94_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 loff = nv50_sor_link(sor);
-       nvkm_mask(device, 0x61c128 + loff, 0x0000003f, watermark);
-}
-
-void
-g94_sor_dp_activesym(struct nvkm_ior *sor, int head,
-                    u8 TU, u8 VTUa, u8 VTUf, u8 VTUi)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 loff = nv50_sor_link(sor);
-       nvkm_mask(device, 0x61c10c + loff, 0x000001fc, TU << 2);
-       nvkm_mask(device, 0x61c128 + loff, 0x010f7f00, VTUa << 24 |
-                                                      VTUf << 16 |
-                                                      VTUi << 8);
-}
-
-void
-g94_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       nvkm_mask(device, 0x61c1e8 + soff, 0x0000ffff, h);
-       nvkm_mask(device, 0x61c1ec + soff, 0x00ffffff, v);
-}
-
-void
-g94_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32  loff = nv50_sor_link(sor);
-       const u32 shift = sor->func->dp.lanes[ln] * 8;
-       u32 data[3];
-
-       data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
-       data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
-       data[2] = nvkm_rd32(device, 0x61c130 + loff);
-       if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
-               data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
-       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
-       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
-       nvkm_wr32(device, 0x61c130 + loff, data[2]);
-}
-
-void
-g94_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 loff = nv50_sor_link(sor);
-       u32 data;
-
-       switch (pattern) {
-       case 0: data = 0x00001000; break;
-       case 1: data = 0x01000000; break;
-       case 2: data = 0x02000000; break;
-       default:
-               WARN_ON(1);
-               return;
-       }
-
-       nvkm_mask(device, 0x61c10c + loff, 0x0f001000, data);
-}
-
-void
-g94_sor_dp_power(struct nvkm_ior *sor, int nr)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       const u32 loff = nv50_sor_link(sor);
-       u32 mask = 0, i;
-
-       for (i = 0; i < nr; i++)
-               mask |= 1 << sor->func->dp.lanes[i];
-
-       nvkm_mask(device, 0x61c130 + loff, 0x0000000f, mask);
-       nvkm_mask(device, 0x61c034 + soff, 0x80000000, 0x80000000);
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x61c034 + soff) & 0x80000000))
-                       break;
-       );
-}
-
-int
-g94_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       const u32 loff = nv50_sor_link(sor);
-       u32 dpctrl = 0x00000000;
-       u32 clksor = 0x00000000;
-
-       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
-       if (sor->dp.ef)
-               dpctrl |= 0x00004000;
-       if (sor->dp.bw > 0x06)
-               clksor |= 0x00040000;
-
-       nvkm_mask(device, 0x614300 + soff, 0x000c0000, clksor);
-       nvkm_mask(device, 0x61c10c + loff, 0x001f4000, dpctrl);
-       return 0;
-}
-
-static bool
-g94_sor_war_needed(struct nvkm_ior *sor)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       if (sor->asy.proto == TMDS) {
-               switch (nvkm_rd32(device, 0x614300 + soff) & 0x00030000) {
-               case 0x00000000:
-               case 0x00030000:
-                       return true;
-               default:
-                       break;
-               }
-       }
-       return false;
-}
-
-static void
-g94_sor_war_update_sppll1(struct nvkm_disp *disp)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       struct nvkm_ior *ior;
-       bool used = false;
-       u32 clksor;
-
-       list_for_each_entry(ior, &disp->ior, head) {
-               if (ior->type != SOR)
-                       continue;
-
-               clksor = nvkm_rd32(device, 0x614300 + nv50_ior_base(ior));
-               switch (clksor & 0x03000000) {
-               case 0x02000000:
-               case 0x03000000:
-                       used = true;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if (used)
-               return;
-
-       nvkm_mask(device, 0x00e840, 0x80000000, 0x00000000);
-}
-
-static void
-g94_sor_war_3(struct nvkm_ior *sor)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       u32 sorpwr;
-
-       if (!g94_sor_war_needed(sor))
-               return;
-
-       sorpwr = nvkm_rd32(device, 0x61c004 + soff);
-       if (sorpwr & 0x00000001) {
-               u32 seqctl = nvkm_rd32(device, 0x61c030 + soff);
-               u32  pd_pc = (seqctl & 0x00000f00) >> 8;
-               u32  pu_pc =  seqctl & 0x0000000f;
-
-               nvkm_wr32(device, 0x61c040 + soff + pd_pc * 4, 0x1f008000);
-
-               nvkm_msec(device, 2000,
-                       if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
-                               break;
-               );
-               nvkm_mask(device, 0x61c004 + soff, 0x80000001, 0x80000000);
-               nvkm_msec(device, 2000,
-                       if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
-                               break;
-               );
-
-               nvkm_wr32(device, 0x61c040 + soff + pd_pc * 4, 0x00002000);
-               nvkm_wr32(device, 0x61c040 + soff + pu_pc * 4, 0x1f000000);
-       }
-
-       nvkm_mask(device, 0x61c10c + soff, 0x00000001, 0x00000000);
-       nvkm_mask(device, 0x614300 + soff, 0x03000000, 0x00000000);
-
-       if (sorpwr & 0x00000001) {
-               nvkm_mask(device, 0x61c004 + soff, 0x80000001, 0x80000001);
-       }
-
-       g94_sor_war_update_sppll1(sor->disp);
-}
-
-static void
-g94_sor_war_2(struct nvkm_ior *sor)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-
-       if (!g94_sor_war_needed(sor))
-               return;
-
-       nvkm_mask(device, 0x00e840, 0x80000000, 0x80000000);
-       nvkm_mask(device, 0x614300 + soff, 0x03000000, 0x03000000);
-       nvkm_mask(device, 0x61c10c + soff, 0x00000001, 0x00000001);
-
-       nvkm_mask(device, 0x61c00c + soff, 0x0f000000, 0x00000000);
-       nvkm_mask(device, 0x61c008 + soff, 0xff000000, 0x14000000);
-       nvkm_usec(device, 400, NVKM_DELAY);
-       nvkm_mask(device, 0x61c008 + soff, 0xff000000, 0x00000000);
-       nvkm_mask(device, 0x61c00c + soff, 0x0f000000, 0x01000000);
-
-       if (nvkm_rd32(device, 0x61c004 + soff) & 0x00000001) {
-               u32 seqctl = nvkm_rd32(device, 0x61c030 + soff);
-               u32  pu_pc = seqctl & 0x0000000f;
-               nvkm_wr32(device, 0x61c040 + soff + pu_pc * 4, 0x1f008000);
-       }
-}
-
-void
-g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 coff = sor->id * 8 + (state == &sor->arm) * 4;
-       u32 ctrl = nvkm_rd32(device, 0x610794 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       switch (state->proto_evo) {
-       case 0: state->proto = LVDS; state->link = 1; break;
-       case 1: state->proto = TMDS; state->link = 1; break;
-       case 2: state->proto = TMDS; state->link = 2; break;
-       case 5: state->proto = TMDS; state->link = 3; break;
-       case 8: state->proto =   DP; state->link = 1; break;
-       case 9: state->proto =   DP; state->link = 2; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x00000003;
-       nv50_pior_depth(sor, state, ctrl);
-}
-
-static const struct nvkm_ior_func
-g94_sor = {
-       .state = g94_sor_state,
-       .power = nv50_sor_power,
-       .clock = nv50_sor_clock,
-       .war_2 = g94_sor_war_2,
-       .war_3 = g94_sor_war_3,
-       .dp = {
-               .lanes = { 2, 1, 0, 3},
-               .links = g94_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = g94_sor_dp_pattern,
-               .drive = g94_sor_dp_drive,
-               .audio_sym = g94_sor_dp_audio_sym,
-               .activesym = g94_sor_dp_activesym,
-               .watermark = g94_sor_dp_watermark,
-       },
-};
-
-int
-g94_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&g94_sor, disp, SOR, id);
-}
-
-int
-g94_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x610184) & 0x0f000000) >> 24;
-       return 4;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c
deleted file mode 100644 (file)
index d2c05f5..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2021 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-static int
-ga102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       const u32 loff = nv50_sor_link(sor);
-       u32 dpctrl = 0x00000000;
-       u32 clksor = 0x00000000;
-
-       switch (sor->dp.bw) {
-       case 0x06: clksor |= 0x00000000; break;
-       case 0x0a: clksor |= 0x00040000; break;
-       case 0x14: clksor |= 0x00080000; break;
-       case 0x1e: clksor |= 0x000c0000; break;
-       case 0x08: clksor |= 0x00100000; break;
-       case 0x09: clksor |= 0x00140000; break;
-       case 0x0c: clksor |= 0x00180000; break;
-       case 0x10: clksor |= 0x001c0000; break;
-       default:
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
-       if (sor->dp.mst)
-               dpctrl |= 0x40000000;
-       if (sor->dp.ef)
-               dpctrl |= 0x00004000;
-
-       nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
-
-       /*XXX*/
-       nvkm_msec(device, 40, NVKM_DELAY);
-       nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000);
-       nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001);
-
-       nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
-       return 0;
-}
-
-static void
-ga102_sor_clock(struct nvkm_ior *sor)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       u32 div2 = 0;
-       if (sor->asy.proto == TMDS) {
-               if (sor->tmds.high_speed)
-                       div2 = 1;
-       }
-       nvkm_wr32(device, 0x00ec08 + (sor->id * 0x10), 0x00000000);
-       nvkm_wr32(device, 0x00ec04 + (sor->id * 0x10), div2);
-}
-
-static const struct nvkm_ior_func
-ga102_sor_hda = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gv100_sor_state,
-       .power = nv50_sor_power,
-       .clock = ga102_sor_clock,
-       .hdmi = {
-               .ctrl = gv100_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = ga102_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = tu102_sor_dp_vcpi,
-               .audio = gv100_sor_dp_audio,
-               .audio_sym = gv100_sor_dp_audio_sym,
-               .watermark = gv100_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gv100_hda_device_entry,
-       },
-};
-
-static const struct nvkm_ior_func
-ga102_sor = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gv100_sor_state,
-       .power = nv50_sor_power,
-       .clock = ga102_sor_clock,
-       .hdmi = {
-               .ctrl = gv100_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = ga102_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = tu102_sor_dp_vcpi,
-               .audio = gv100_sor_dp_audio,
-               .audio_sym = gv100_sor_dp_audio_sym,
-               .watermark = gv100_sor_dp_watermark,
-       },
-};
-
-int
-ga102_sor_new(struct nvkm_disp *disp, int id)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       u32 hda = nvkm_rd32(device, 0x08a15c);
-       if (hda & BIT(id))
-               return nvkm_ior_new_(&ga102_sor_hda, disp, SOR, id);
-       return nvkm_ior_new_(&ga102_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
deleted file mode 100644 (file)
index c431e0b..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-void
-gf119_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = head * 0x800;
-       nvkm_mask(device, 0x616610 + hoff, 0x0800003f, 0x08000000 | watermark);
-}
-
-void
-gf119_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = head * 0x800;
-       nvkm_mask(device, 0x616620 + hoff, 0x0000ffff, h);
-       nvkm_mask(device, 0x616624 + hoff, 0x00ffffff, v);
-}
-
-void
-gf119_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = 0x800 * head;
-       const u32 data = 0x80000000 | (0x00000001 * enable);
-       const u32 mask = 0x8000000d;
-       nvkm_mask(device, 0x616618 + hoff, mask, data);
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x616618 + hoff) & 0x80000000))
-                       break;
-       );
-}
-
-void
-gf119_sor_dp_vcpi(struct nvkm_ior *sor, int head,
-                 u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = head * 0x800;
-
-       nvkm_mask(device, 0x616588 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
-       nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn);
-}
-
-void
-gf119_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32  loff = nv50_sor_link(sor);
-       const u32 shift = sor->func->dp.lanes[ln] * 8;
-       u32 data[4];
-
-       data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
-       data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
-       data[2] = nvkm_rd32(device, 0x61c130 + loff);
-       if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
-               data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
-       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
-       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
-       nvkm_wr32(device, 0x61c130 + loff, data[2]);
-       data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
-       nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
-}
-
-void
-gf119_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       u32 data;
-
-       switch (pattern) {
-       case 0: data = 0x10101010; break;
-       case 1: data = 0x01010101; break;
-       case 2: data = 0x02020202; break;
-       case 3: data = 0x03030303; break;
-       default:
-               WARN_ON(1);
-               return;
-       }
-
-       nvkm_mask(device, 0x61c110 + soff, 0x1f1f1f1f, data);
-}
-
-int
-gf119_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       const u32 loff = nv50_sor_link(sor);
-       u32 dpctrl = 0x00000000;
-       u32 clksor = 0x00000000;
-
-       clksor |= sor->dp.bw << 18;
-       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
-       if (sor->dp.mst)
-               dpctrl |= 0x40000000;
-       if (sor->dp.ef)
-               dpctrl |= 0x00004000;
-
-       nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
-       nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
-       return 0;
-}
-
-void
-gf119_sor_clock(struct nvkm_ior *sor)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       u32 div1 = sor->asy.link == 3;
-       u32 div2 = sor->asy.link == 3;
-       if (sor->asy.proto == TMDS) {
-               const u32 speed = sor->tmds.high_speed ? 0x14 : 0x0a;
-               nvkm_mask(device, 0x612300 + soff, 0x007c0000, speed << 18);
-               if (sor->tmds.high_speed)
-                       div2 = 1;
-       }
-       nvkm_mask(device, 0x612300 + soff, 0x00000707, (div2 << 8) | div1);
-}
-
-void
-gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 coff = (state == &sor->asy) * 0x20000 + sor->id * 0x20;
-       u32 ctrl = nvkm_rd32(device, 0x640200 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       switch (state->proto_evo) {
-       case 0: state->proto = LVDS; state->link = 1; break;
-       case 1: state->proto = TMDS; state->link = 1; break;
-       case 2: state->proto = TMDS; state->link = 2; break;
-       case 5: state->proto = TMDS; state->link = 3; break;
-       case 8: state->proto =   DP; state->link = 1; break;
-       case 9: state->proto =   DP; state->link = 2; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x0000000f;
-}
-
-static const struct nvkm_ior_func
-gf119_sor = {
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gf119_hdmi_ctrl,
-       },
-       .dp = {
-               .lanes = { 2, 1, 0, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gf119_sor_dp_pattern,
-               .drive = gf119_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gf119_hda_device_entry,
-       },
-};
-
-int
-gf119_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&gf119_sor, disp, SOR, id);
-}
-
-int
-gf119_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x612004) & 0x0000ff00) >> 8;
-       return 8;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c
deleted file mode 100644 (file)
index 0c09256..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-static const struct nvkm_ior_func
-gk104_sor = {
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gk104_hdmi_ctrl,
-       },
-       .dp = {
-               .lanes = { 2, 1, 0, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gf119_sor_dp_pattern,
-               .drive = gf119_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gf119_hda_device_entry,
-       },
-};
-
-int
-gk104_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&gk104_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
deleted file mode 100644 (file)
index 3696bfd..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2016 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
- */
-#include "ior.h"
-
-void
-gm107_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       u32 mask = 0x1f1f1f1f, data;
-
-       switch (pattern) {
-       case 0: data = 0x10101010; break;
-       case 1: data = 0x01010101; break;
-       case 2: data = 0x02020202; break;
-       case 3: data = 0x03030303; break;
-       case 4: data = 0x1b1b1b1b; break;
-       default:
-               WARN_ON(1);
-               return;
-       }
-
-       if (sor->asy.link & 1)
-               nvkm_mask(device, 0x61c110 + soff, mask, data);
-       else
-               nvkm_mask(device, 0x61c12c + soff, mask, data);
-}
-
-static const struct nvkm_ior_func
-gm107_sor = {
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gk104_hdmi_ctrl,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gf119_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gf119_hda_device_entry,
-       },
-};
-
-int
-gm107_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&gm107_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
deleted file mode 100644 (file)
index 4dd7f38..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-void
-gm200_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32  loff = nv50_sor_link(sor);
-       const u32 shift = sor->func->dp.lanes[ln] * 8;
-       u32 data[4];
-
-       pu &= 0x0f;
-
-       data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
-       data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
-       data[2] = nvkm_rd32(device, 0x61c130 + loff);
-       if ((data[2] & 0x00000f00) < (pu << 8) || ln == 0)
-               data[2] = (data[2] & ~0x00000f00) | (pu << 8);
-       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
-       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
-       nvkm_wr32(device, 0x61c130 + loff, data[2]);
-       data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
-       nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
-}
-
-void
-gm200_sor_route_set(struct nvkm_outp *outp, struct nvkm_ior *ior)
-{
-       struct nvkm_device *device = outp->disp->engine.subdev.device;
-       const u32 moff = __ffs(outp->info.or) * 0x100;
-       const u32  sor = ior ? ior->id + 1 : 0;
-       u32 link = ior ? (ior->asy.link == 2) : 0;
-
-       if (outp->info.sorconf.link & 1) {
-               nvkm_mask(device, 0x612308 + moff, 0x0000001f, link << 4 | sor);
-               link++;
-       }
-
-       if (outp->info.sorconf.link & 2)
-               nvkm_mask(device, 0x612388 + moff, 0x0000001f, link << 4 | sor);
-}
-
-int
-gm200_sor_route_get(struct nvkm_outp *outp, int *link)
-{
-       struct nvkm_device *device = outp->disp->engine.subdev.device;
-       const int sublinks = outp->info.sorconf.link;
-       int lnk[2], sor[2], m, s;
-
-       for (*link = 0, m = __ffs(outp->info.or) * 2, s = 0; s < 2; m++, s++) {
-               if (sublinks & BIT(s)) {
-                       u32 data = nvkm_rd32(device, 0x612308 + (m * 0x80));
-                       lnk[s] = (data & 0x00000010) >> 4;
-                       sor[s] = (data & 0x0000000f);
-                       if (!sor[s])
-                               return -1;
-                       *link |= lnk[s];
-               }
-       }
-
-       if (sublinks == 3) {
-               if (sor[0] != sor[1] || WARN_ON(lnk[0] || !lnk[1]))
-                       return -1;
-       }
-
-       return ((sublinks & 1) ? sor[0] : sor[1]) - 1;
-}
-
-static const struct nvkm_ior_func
-gm200_sor_hda = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gk104_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gf119_hda_device_entry,
-       },
-};
-
-static const struct nvkm_ior_func
-gm200_sor = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gk104_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-};
-
-int
-gm200_sor_new(struct nvkm_disp *disp, int id)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       u32 hda;
-
-       if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
-               hda = nvkm_rd32(device, 0x101034);
-
-       if (hda & BIT(id))
-               return nvkm_ior_new_(&gm200_sor_hda, disp, SOR, id);
-       return nvkm_ior_new_(&gm200_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c
deleted file mode 100644 (file)
index c54f883..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2020 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-static const struct nvkm_ior_func
-gp100_sor_hda = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gk104_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gf119_hda_device_entry,
-       },
-};
-
-static const struct nvkm_ior_func
-gp100_sor = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gf119_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gk104_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = gf119_sor_dp_vcpi,
-               .audio = gf119_sor_dp_audio,
-               .audio_sym = gf119_sor_dp_audio_sym,
-               .watermark = gf119_sor_dp_watermark,
-       },
-};
-
-int
-gp100_sor_new(struct nvkm_disp *disp, int id)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       u32 hda;
-
-       if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
-               hda = nvkm_rd32(device, 0x10ebb0) >> 8;
-
-       if (hda & BIT(id))
-               return nvkm_ior_new_(&gp100_sor_hda, disp, SOR, id);
-       return nvkm_ior_new_(&gp100_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c
deleted file mode 100644 (file)
index 54d134d..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-void
-gt215_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       const u32 data = 0x80000000 | (0x00000001 * enable);
-       const u32 mask = 0x8000000d;
-       nvkm_mask(device, 0x61c1e0 + soff, mask, data);
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x61c1e0 + soff) & 0x80000000))
-                       break;
-       );
-}
-
-static const struct nvkm_ior_func
-gt215_sor = {
-       .state = g94_sor_state,
-       .power = nv50_sor_power,
-       .clock = nv50_sor_clock,
-       .hdmi = {
-               .ctrl = gt215_hdmi_ctrl,
-       },
-       .dp = {
-               .lanes = { 2, 1, 0, 3 },
-               .links = g94_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = g94_sor_dp_pattern,
-               .drive = g94_sor_dp_drive,
-               .audio = gt215_sor_dp_audio,
-               .audio_sym = g94_sor_dp_audio_sym,
-               .activesym = g94_sor_dp_activesym,
-               .watermark = g94_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gt215_hda_hpd,
-               .eld = gt215_hda_eld,
-       },
-};
-
-int
-gt215_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&gt215_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
deleted file mode 100644 (file)
index 4441187..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-void
-gv100_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = head * 0x800;
-       nvkm_mask(device, 0x616550 + hoff, 0x0c00003f, 0x08000000 | watermark);
-}
-
-void
-gv100_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = head * 0x800;
-       nvkm_mask(device, 0x616568 + hoff, 0x0000ffff, h);
-       nvkm_mask(device, 0x61656c + hoff, 0x00ffffff, v);
-}
-
-void
-gv100_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = 0x800 * head;
-       const u32 data = 0x80000000 | (0x00000001 * enable);
-       const u32 mask = 0x8000000d;
-       nvkm_mask(device, 0x616560 + hoff, mask, data);
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x616560 + hoff) & 0x80000000))
-                       break;
-       );
-}
-
-void
-gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 coff = (state == &sor->arm) * 0x8000 + sor->id * 0x20;
-       u32 ctrl = nvkm_rd32(device, 0x680300 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       switch (state->proto_evo) {
-       case 0: state->proto = LVDS; state->link = 1; break;
-       case 1: state->proto = TMDS; state->link = 1; break;
-       case 2: state->proto = TMDS; state->link = 2; break;
-       case 5: state->proto = TMDS; state->link = 3; break;
-       case 8: state->proto =   DP; state->link = 1; break;
-       case 9: state->proto =   DP; state->link = 2; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x000000ff;
-}
-
-static const struct nvkm_ior_func
-gv100_sor_hda = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gv100_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gv100_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .audio = gv100_sor_dp_audio,
-               .audio_sym = gv100_sor_dp_audio_sym,
-               .watermark = gv100_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gv100_hda_device_entry,
-       },
-};
-
-static const struct nvkm_ior_func
-gv100_sor = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gv100_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gv100_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = gf119_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .audio = gv100_sor_dp_audio,
-               .audio_sym = gv100_sor_dp_audio_sym,
-               .watermark = gv100_sor_dp_watermark,
-       },
-};
-
-int
-gv100_sor_new(struct nvkm_disp *disp, int id)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       u32 hda;
-
-       if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
-               hda = nvkm_rd32(device, 0x118fb0) >> 8;
-
-       if (hda & BIT(id))
-               return nvkm_ior_new_(&gv100_sor_hda, disp, SOR, id);
-       return nvkm_ior_new_(&gv100_sor, disp, SOR, id);
-}
-
-int
-gv100_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x610060) & 0x0000ff00) >> 8;
-       return (nvkm_rd32(device, 0x610074) & 0x00000f00) >> 8;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c
deleted file mode 100644 (file)
index 8a70dd2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-static const struct nvkm_ior_func
-mcp77_sor = {
-       .state = g94_sor_state,
-       .power = nv50_sor_power,
-       .clock = nv50_sor_clock,
-       .hdmi = {
-               .ctrl = g84_hdmi_ctrl,
-       },
-       .dp = {
-               .lanes = { 2, 1, 0, 3},
-               .links = g94_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = g94_sor_dp_pattern,
-               .drive = g94_sor_dp_drive,
-               .audio_sym = g94_sor_dp_audio_sym,
-               .activesym = g94_sor_dp_activesym,
-               .watermark = g94_sor_dp_watermark,
-       },
-};
-
-int
-mcp77_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&mcp77_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c
deleted file mode 100644 (file)
index eac9c5b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-static const struct nvkm_ior_func
-mcp89_sor = {
-       .state = g94_sor_state,
-       .power = nv50_sor_power,
-       .clock = nv50_sor_clock,
-       .hdmi = {
-               .ctrl = gt215_hdmi_ctrl,
-       },
-       .dp = {
-               .lanes = { 3, 2, 1, 0 },
-               .links = g94_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = g94_sor_dp_pattern,
-               .drive = g94_sor_dp_drive,
-               .audio = gt215_sor_dp_audio,
-               .audio_sym = g94_sor_dp_audio_sym,
-               .activesym = g94_sor_dp_activesym,
-               .watermark = g94_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gt215_hda_hpd,
-               .eld = gt215_hda_eld,
-       },
-};
-
-int
-mcp89_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&mcp89_sor, disp, SOR, id);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c
deleted file mode 100644 (file)
index b4729f8..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-void
-nv50_sor_clock(struct nvkm_ior *sor)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const int  div = sor->asy.link == 3;
-       const u32 soff = nv50_ior_base(sor);
-       nvkm_mask(device, 0x614300 + soff, 0x00000707, (div << 8) | div);
-}
-
-static void
-nv50_sor_power_wait(struct nvkm_device *device, u32 soff)
-{
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x61c004 + soff) & 0x80000000))
-                       break;
-       );
-}
-
-void
-nv50_sor_power(struct nvkm_ior *sor, bool normal, bool pu,
-              bool data, bool vsync, bool hsync)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32  soff = nv50_ior_base(sor);
-       const u32 shift = normal ? 0 : 16;
-       const u32 state = 0x80000000 | (0x00000001 * !!pu) << shift;
-       const u32 field = 0x80000000 | (0x00000001 << shift);
-
-       nv50_sor_power_wait(device, soff);
-       nvkm_mask(device, 0x61c004 + soff, field, state);
-       nv50_sor_power_wait(device, soff);
-
-       nvkm_msec(device, 2000,
-               if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
-                       break;
-       );
-}
-
-void
-nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 coff = sor->id * 8 + (state == &sor->arm) * 4;
-       u32 ctrl = nvkm_rd32(device, 0x610b70 + coff);
-
-       state->proto_evo = (ctrl & 0x00000f00) >> 8;
-       switch (state->proto_evo) {
-       case 0: state->proto = LVDS; state->link = 1; break;
-       case 1: state->proto = TMDS; state->link = 1; break;
-       case 2: state->proto = TMDS; state->link = 2; break;
-       case 5: state->proto = TMDS; state->link = 3; break;
-       default:
-               state->proto = UNKNOWN;
-               break;
-       }
-
-       state->head = ctrl & 0x00000003;
-}
-
-static const struct nvkm_ior_func
-nv50_sor = {
-       .state = nv50_sor_state,
-       .power = nv50_sor_power,
-       .clock = nv50_sor_clock,
-};
-
-int
-nv50_sor_new(struct nvkm_disp *disp, int id)
-{
-       return nvkm_ior_new_(&nv50_sor, disp, SOR, id);
-}
-
-int
-nv50_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       *pmask = (nvkm_rd32(device, 0x610184) & 0x03000000) >> 24;
-       return 2;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
deleted file mode 100644 (file)
index 0cf9e87..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "ior.h"
-
-#include <subdev/timer.h>
-
-void
-tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head,
-                 u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 hoff = head * 0x800;
-
-       nvkm_mask(device, 0x61657c + hoff, 0xffffffff, (aligned << 16) | pbn);
-       nvkm_mask(device, 0x616578 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
-}
-
-static int
-tu102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
-{
-       struct nvkm_device *device = sor->disp->engine.subdev.device;
-       const u32 soff = nv50_ior_base(sor);
-       const u32 loff = nv50_sor_link(sor);
-       u32 dpctrl = 0x00000000;
-       u32 clksor = 0x00000000;
-
-       clksor |= sor->dp.bw << 18;
-       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
-       if (sor->dp.mst)
-               dpctrl |= 0x40000000;
-       if (sor->dp.ef)
-               dpctrl |= 0x00004000;
-
-       nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
-
-       /*XXX*/
-       nvkm_msec(device, 40, NVKM_DELAY);
-       nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000);
-       nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001);
-
-       nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
-       return 0;
-}
-
-static const struct nvkm_ior_func
-tu102_sor_hda = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gv100_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gv100_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = tu102_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = tu102_sor_dp_vcpi,
-               .audio = gv100_sor_dp_audio,
-               .audio_sym = gv100_sor_dp_audio_sym,
-               .watermark = gv100_sor_dp_watermark,
-       },
-       .hda = {
-               .hpd = gf119_hda_hpd,
-               .eld = gf119_hda_eld,
-               .device_entry = gv100_hda_device_entry,
-       },
-};
-
-static const struct nvkm_ior_func
-tu102_sor = {
-       .route = {
-               .get = gm200_sor_route_get,
-               .set = gm200_sor_route_set,
-       },
-       .state = gv100_sor_state,
-       .power = nv50_sor_power,
-       .clock = gf119_sor_clock,
-       .hdmi = {
-               .ctrl = gv100_hdmi_ctrl,
-               .scdc = gm200_hdmi_scdc,
-       },
-       .dp = {
-               .lanes = { 0, 1, 2, 3 },
-               .links = tu102_sor_dp_links,
-               .power = g94_sor_dp_power,
-               .pattern = gm107_sor_dp_pattern,
-               .drive = gm200_sor_dp_drive,
-               .vcpi = tu102_sor_dp_vcpi,
-               .audio = gv100_sor_dp_audio,
-               .audio_sym = gv100_sor_dp_audio_sym,
-               .watermark = gv100_sor_dp_watermark,
-       },
-};
-
-int
-tu102_sor_new(struct nvkm_disp *disp, int id)
-{
-       struct nvkm_device *device = disp->engine.subdev.device;
-       u32 hda = nvkm_rd32(device, 0x08a15c);
-       if (hda & BIT(id))
-               return nvkm_ior_new_(&tu102_sor_hda, disp, SOR, id);
-       return nvkm_ior_new_(&tu102_sor, disp, SOR, id);
-}
index f5f8dc8..e4ad1a6 100644 (file)
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "nv50.h"
+#include "chan.h"
+#include "priv.h"
 #include "head.h"
 #include "ior.h"
-#include "channv50.h"
-#include "rootnv50.h"
 
 #include <core/gpuobj.h>
 #include <subdev/timer.h>
 
+#include <nvif/class.h>
+
+void
+tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 hoff = head * 0x800;
+
+       nvkm_mask(device, 0x61657c + hoff, 0xffffffff, (aligned << 16) | pbn);
+       nvkm_mask(device, 0x616578 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
+}
+
+static int
+tu102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(sor);
+       const u32 loff = nv50_sor_link(sor);
+       u32 dpctrl = 0x00000000;
+       u32 clksor = 0x00000000;
+
+       clksor |= sor->dp.bw << 18;
+       dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
+       if (sor->dp.mst)
+               dpctrl |= 0x40000000;
+       if (sor->dp.ef)
+               dpctrl |= 0x00004000;
+
+       nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
+
+       /*XXX*/
+       nvkm_msec(device, 40, NVKM_DELAY);
+       nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000);
+       nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001);
+
+       nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
+       return 0;
+}
+
+static const struct nvkm_ior_func_dp
+tu102_sor_dp = {
+       .lanes = { 0, 1, 2, 3 },
+       .links = tu102_sor_dp_links,
+       .power = g94_sor_dp_power,
+       .pattern = gm107_sor_dp_pattern,
+       .drive = gm200_sor_dp_drive,
+       .vcpi = tu102_sor_dp_vcpi,
+       .audio = gv100_sor_dp_audio,
+       .audio_sym = gv100_sor_dp_audio_sym,
+       .watermark = gv100_sor_dp_watermark,
+};
+
+static const struct nvkm_ior_func
+tu102_sor = {
+       .route = {
+               .get = gm200_sor_route_get,
+               .set = gm200_sor_route_set,
+       },
+       .state = gv100_sor_state,
+       .power = nv50_sor_power,
+       .clock = gf119_sor_clock,
+       .hdmi = {
+               .ctrl = gv100_sor_hdmi_ctrl,
+               .scdc = gm200_sor_hdmi_scdc,
+       },
+       .dp = &tu102_sor_dp,
+       .hda = &gv100_sor_hda,
+};
+
+static int
+tu102_sor_new(struct nvkm_disp *disp, int id)
+{
+       struct nvkm_device *device = disp->engine.subdev.device;
+       u32 hda = nvkm_rd32(device, 0x08a15c);
+
+       return nvkm_ior_new_(&tu102_sor, disp, SOR, id, hda & BIT(id));
+}
+
 int
-tu102_disp_init(struct nv50_disp *disp)
+tu102_disp_init(struct nvkm_disp *disp)
 {
-       struct nvkm_device *device = disp->base.engine.subdev.device;
+       struct nvkm_device *device = disp->engine.subdev.device;
        struct nvkm_head *head;
        int i, j;
        u32 tmp;
@@ -58,7 +135,7 @@ tu102_disp_init(struct nv50_disp *disp)
        }
 
        /* Head capabilities. */
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                const int id = head->id;
 
                /* RG. */
@@ -119,7 +196,7 @@ tu102_disp_init(struct nv50_disp *disp)
        nvkm_wr32(device, 0x611da4, 0x00000000); /* EN. */
 
        /* HEAD_TIMING(n): VBLANK. */
-       list_for_each_entry(head, &disp->base.head, head) {
+       list_for_each_entry(head, &disp->heads, head) {
                const u32 hoff = head->id * 4;
                nvkm_wr32(device, 0x611cc0 + hoff, 0x00000004); /* MSK. */
                nvkm_wr32(device, 0x611d80 + hoff, 0x00000000); /* EN. */
@@ -131,23 +208,32 @@ tu102_disp_init(struct nv50_disp *disp)
        return 0;
 }
 
-static const struct nv50_disp_func
+static const struct nvkm_disp_func
 tu102_disp = {
+       .oneinit = nv50_disp_oneinit,
        .init = tu102_disp_init,
        .fini = gv100_disp_fini,
        .intr = gv100_disp_intr,
-       .uevent = &gv100_disp_chan_uevent,
        .super = gv100_disp_super,
-       .root = &tu102_disp_root_oclass,
+       .uevent = &gv100_disp_chan_uevent,
        .wndw = { .cnt = gv100_disp_wndw_cnt },
        .head = { .cnt = gv100_head_cnt, .new = gv100_head_new },
        .sor = { .cnt = gv100_sor_cnt, .new = tu102_sor_new },
        .ramht_size = 0x2000,
+       .root = {  0, 0,TU102_DISP },
+       .user = {
+               {{-1,-1,GV100_DISP_CAPS                  }, gv100_disp_caps_new },
+               {{ 0, 0,TU102_DISP_CURSOR                },  nvkm_disp_chan_new, &gv100_disp_curs },
+               {{ 0, 0,TU102_DISP_WINDOW_IMM_CHANNEL_DMA},  nvkm_disp_wndw_new, &gv100_disp_wimm },
+               {{ 0, 0,TU102_DISP_CORE_CHANNEL_DMA      },  nvkm_disp_core_new, &gv100_disp_core },
+               {{ 0, 0,TU102_DISP_WINDOW_CHANNEL_DMA    },  nvkm_disp_wndw_new, &gv100_disp_wndw },
+               {}
+       },
 };
 
 int
 tu102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
               struct nvkm_disp **pdisp)
 {
-       return nv50_disp_new_(&tu102_disp, device, type, inst, pdisp);
+       return nvkm_disp_new_(&tu102_disp, device, type, inst, pdisp);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
new file mode 100644 (file)
index 0000000..fd9f181
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2021 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#define nvkm_uconn(p) container_of((p), struct nvkm_conn, object)
+#include "conn.h"
+
+#include <subdev/gpio.h>
+
+#include <nvif/if0011.h>
+
+static int
+nvkm_uconn_mthd_hpd_status(struct nvkm_conn *conn, void *argv, u32 argc)
+{
+       struct nvkm_gpio *gpio = conn->disp->engine.subdev.device->gpio;
+       union nvif_conn_hpd_status_args *args = argv;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       args->v0.support = gpio && conn->info.hpd != DCB_GPIO_UNUSED;
+       args->v0.present = 0;
+
+       if (args->v0.support) {
+               int ret = nvkm_gpio_get(gpio, 0, DCB_GPIO_UNUSED, conn->info.hpd);
+
+               if (WARN_ON(ret < 0)) {
+                       args->v0.support = false;
+                       return 0;
+               }
+
+               args->v0.present = ret;
+       }
+
+       return 0;
+}
+
+static int
+nvkm_uconn_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
+{
+       struct nvkm_conn *conn = nvkm_uconn(object);
+
+       switch (mthd) {
+       case NVIF_CONN_V0_HPD_STATUS: return nvkm_uconn_mthd_hpd_status(conn, argv, argc);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static void *
+nvkm_uconn_dtor(struct nvkm_object *object)
+{
+       struct nvkm_conn *conn = nvkm_uconn(object);
+       struct nvkm_disp *disp = conn->disp;
+
+       spin_lock(&disp->client.lock);
+       conn->object.func = NULL;
+       spin_unlock(&disp->client.lock);
+       return NULL;
+}
+
+static const struct nvkm_object_func
+nvkm_uconn = {
+       .dtor = nvkm_uconn_dtor,
+       .mthd = nvkm_uconn_mthd,
+};
+
+int
+nvkm_uconn_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+       struct nvkm_conn *cont, *conn = NULL;
+       union nvif_conn_args *args = argv;
+       int ret;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       list_for_each_entry(cont, &disp->conns, head) {
+               if (cont->index == args->v0.id) {
+                       conn = cont;
+                       break;
+               }
+       }
+
+       if (!conn)
+               return -EINVAL;
+
+       ret = -EBUSY;
+       spin_lock(&disp->client.lock);
+       if (!conn->object.func) {
+               nvkm_object_ctor(&nvkm_uconn, oclass, &conn->object);
+               *pobject = &conn->object;
+               ret = 0;
+       }
+       spin_unlock(&disp->client.lock);
+       return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
new file mode 100644 (file)
index 0000000..0841e7c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2021 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "priv.h"
+#include "conn.h"
+#include "outp.h"
+
+#include <nvif/class.h>
+#include <nvif/if0010.h>
+
+static int
+nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *sclass)
+{
+       struct nvkm_disp *disp = nvkm_udisp(object);
+
+       if (index-- == 0) {
+               sclass->base = (struct nvkm_sclass) { 0, 0, NVIF_CLASS_CONN };
+               sclass->ctor = nvkm_uconn_new;
+               return 0;
+       }
+
+       if (index-- == 0) {
+               sclass->base = (struct nvkm_sclass) { 0, 0, NVIF_CLASS_OUTP };
+               sclass->ctor = nvkm_uoutp_new;
+               return 0;
+       }
+
+       if (disp->func->user[index].ctor) {
+               sclass->base = disp->func->user[index].base;
+               sclass->ctor = disp->func->user[index].ctor;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int
+nvkm_udisp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
+{
+       struct nvkm_disp *disp = nvkm_udisp(object);
+
+       if (disp->engine.subdev.device->card_type >= NV_50)
+               return nv50_disp_root_mthd_(object, mthd, argv, argc);
+
+       return nv04_disp_mthd(object, mthd, argv, argc);
+}
+
+static void *
+nvkm_udisp_dtor(struct nvkm_object *object)
+{
+       struct nvkm_disp *disp = nvkm_udisp(object);
+
+       spin_lock(&disp->client.lock);
+       if (object == &disp->client.object)
+               disp->client.object.func = NULL;
+       spin_unlock(&disp->client.lock);
+       return NULL;
+}
+
+static const struct nvkm_object_func
+nvkm_udisp = {
+       .dtor = nvkm_udisp_dtor,
+       .mthd = nvkm_udisp_mthd,
+       .ntfy = nvkm_disp_ntfy,
+       .sclass = nvkm_udisp_sclass,
+};
+
+int
+nvkm_udisp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_disp(oclass->engine);
+       struct nvkm_conn *conn;
+       struct nvkm_outp *outp;
+       union nvif_disp_args *args = argv;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       spin_lock(&disp->client.lock);
+       if (disp->client.object.func) {
+               spin_unlock(&disp->client.lock);
+               return -EBUSY;
+       }
+       nvkm_object_ctor(&nvkm_udisp, oclass, &disp->client.object);
+       *pobject = &disp->client.object;
+       spin_unlock(&disp->client.lock);
+
+       args->v0.conn_mask = 0;
+       list_for_each_entry(conn, &disp->conns, head)
+               args->v0.conn_mask |= BIT(conn->index);
+
+       args->v0.outp_mask = 0;
+       list_for_each_entry(outp, &disp->outps, head)
+               args->v0.outp_mask |= BIT(outp->index);
+
+       return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
new file mode 100644 (file)
index 0000000..abedb3e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2021 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#define nvkm_uoutp(p) container_of((p), struct nvkm_outp, object)
+#include "outp.h"
+#include "ior.h"
+
+#include <nvif/if0012.h>
+
+static int
+nvkm_uoutp_mthd_load_detect(struct nvkm_outp *outp, void *argv, u32 argc)
+{
+       union nvif_outp_load_detect_args *args = argv;
+       int ret;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       ret = nvkm_outp_acquire(outp, NVKM_OUTP_PRIV, false);
+       if (ret == 0) {
+               if (outp->ior->func->sense) {
+                       ret = outp->ior->func->sense(outp->ior, args->v0.data);
+                       args->v0.load = ret < 0 ? 0 : ret;
+               } else {
+                       ret = -EINVAL;
+               }
+               nvkm_outp_release(outp, NVKM_OUTP_PRIV);
+       }
+
+       return ret;
+}
+
+static int
+nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc)
+{
+       switch (mthd) {
+       case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, argv, argc);
+       default:
+               break;
+       }
+
+       return 1;
+}
+
+static int
+nvkm_uoutp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
+{
+       struct nvkm_outp *outp = nvkm_uoutp(object);
+       struct nvkm_disp *disp = outp->disp;
+       int ret;
+
+       mutex_lock(&disp->super.mutex);
+
+       ret = nvkm_uoutp_mthd_noacquire(outp, mthd, argv, argc);
+       if (ret <= 0)
+               goto done;
+
+done:
+       mutex_unlock(&disp->super.mutex);
+       return ret;
+}
+
+static void *
+nvkm_uoutp_dtor(struct nvkm_object *object)
+{
+       struct nvkm_outp *outp = nvkm_uoutp(object);
+       struct nvkm_disp *disp = outp->disp;
+
+       spin_lock(&disp->client.lock);
+       outp->object.func = NULL;
+       spin_unlock(&disp->client.lock);
+       return NULL;
+}
+
+static const struct nvkm_object_func
+nvkm_uoutp = {
+       .dtor = nvkm_uoutp_dtor,
+       .mthd = nvkm_uoutp_mthd,
+};
+
+int
+nvkm_uoutp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
+{
+       struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+       struct nvkm_outp *outt, *outp = NULL;
+       union nvif_outp_args *args = argv;
+       int ret;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       list_for_each_entry(outt, &disp->outps, head) {
+               if (outt->index == args->v0.id) {
+                       outp = outt;
+                       break;
+               }
+       }
+
+       if (!outp)
+               return -EINVAL;
+
+       ret = -EBUSY;
+       spin_lock(&disp->client.lock);
+       if (!outp->object.func) {
+               nvkm_object_ctor(&nvkm_uoutp, oclass, &outp->object);
+               *pobject = &outp->object;
+               ret = 0;
+       }
+       spin_unlock(&disp->client.lock);
+       return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c
deleted file mode 100644 (file)
index bb4db63..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "channv50.h"
-
-#include <core/client.h>
-
-#include <nvif/clc37b.h>
-#include <nvif/unpack.h>
-
-static void
-gv100_disp_wimm_intr(struct nv50_disp_chan *chan, bool en)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 mask = 0x00000001 << chan->head;
-       const u32 data = en ? mask : 0;
-       nvkm_mask(device, 0x611da8, mask, data);
-}
-
-static const struct nv50_disp_chan_func
-gv100_disp_wimm = {
-       .init = gv100_disp_dmac_init,
-       .fini = gv100_disp_dmac_fini,
-       .intr = gv100_disp_wimm_intr,
-       .user = gv100_disp_chan_user,
-};
-
-static int
-gv100_disp_wimm_new_(const struct nv50_disp_chan_func *func,
-                    const struct nv50_disp_chan_mthd *mthd,
-                    struct nv50_disp *disp, int chid,
-                    const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                    struct nvkm_object **pobject)
-{
-       union {
-               struct nvc37b_window_imm_channel_dma_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       int wndw, ret = -ENOSYS;
-       u64 push;
-
-       nvif_ioctl(parent, "create window imm channel dma size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create window imm channel dma vers %d "
-                                  "pushbuf %016llx index %d\n",
-                          args->v0.version, args->v0.pushbuf, args->v0.index);
-               if (!(disp->wndw.mask & BIT(args->v0.index)))
-                       return -EINVAL;
-               push = args->v0.pushbuf;
-               wndw = args->v0.index;
-       } else
-               return ret;
-
-       return nv50_disp_dmac_new_(func, mthd, disp, chid + wndw,
-                                  wndw, push, oclass, pobject);
-}
-
-int
-gv100_disp_wimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return gv100_disp_wimm_new_(&gv100_disp_wimm, NULL, disp, 33,
-                                   oclass, argv, argc, pobject);
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c
deleted file mode 100644 (file)
index e635247..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2018 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "channv50.h"
-
-#include <core/client.h>
-
-#include <nvif/clc37e.h>
-#include <nvif/unpack.h>
-
-static const struct nv50_disp_mthd_list
-gv100_disp_wndw_mthd_base = {
-       .mthd = 0x0000,
-       .addr = 0x000000,
-       .data = {
-               { 0x0200, 0x690200 },
-               { 0x020c, 0x69020c },
-               { 0x0210, 0x690210 },
-               { 0x0214, 0x690214 },
-               { 0x0218, 0x690218 },
-               { 0x021c, 0x69021c },
-               { 0x0220, 0x690220 },
-               { 0x0224, 0x690224 },
-               { 0x0228, 0x690228 },
-               { 0x022c, 0x69022c },
-               { 0x0230, 0x690230 },
-               { 0x0234, 0x690234 },
-               { 0x0238, 0x690238 },
-               { 0x0240, 0x690240 },
-               { 0x0244, 0x690244 },
-               { 0x0248, 0x690248 },
-               { 0x024c, 0x69024c },
-               { 0x0250, 0x690250 },
-               { 0x0254, 0x690254 },
-               { 0x0260, 0x690260 },
-               { 0x0264, 0x690264 },
-               { 0x0268, 0x690268 },
-               { 0x026c, 0x69026c },
-               { 0x0270, 0x690270 },
-               { 0x0274, 0x690274 },
-               { 0x0280, 0x690280 },
-               { 0x0284, 0x690284 },
-               { 0x0288, 0x690288 },
-               { 0x028c, 0x69028c },
-               { 0x0290, 0x690290 },
-               { 0x0298, 0x690298 },
-               { 0x029c, 0x69029c },
-               { 0x02a0, 0x6902a0 },
-               { 0x02a4, 0x6902a4 },
-               { 0x02a8, 0x6902a8 },
-               { 0x02ac, 0x6902ac },
-               { 0x02b0, 0x6902b0 },
-               { 0x02b4, 0x6902b4 },
-               { 0x02b8, 0x6902b8 },
-               { 0x02bc, 0x6902bc },
-               { 0x02c0, 0x6902c0 },
-               { 0x02c4, 0x6902c4 },
-               { 0x02c8, 0x6902c8 },
-               { 0x02cc, 0x6902cc },
-               { 0x02d0, 0x6902d0 },
-               { 0x02d4, 0x6902d4 },
-               { 0x02d8, 0x6902d8 },
-               { 0x02dc, 0x6902dc },
-               { 0x02e0, 0x6902e0 },
-               { 0x02e4, 0x6902e4 },
-               { 0x02e8, 0x6902e8 },
-               { 0x02ec, 0x6902ec },
-               { 0x02f0, 0x6902f0 },
-               { 0x02f4, 0x6902f4 },
-               { 0x02f8, 0x6902f8 },
-               { 0x02fc, 0x6902fc },
-               { 0x0300, 0x690300 },
-               { 0x0304, 0x690304 },
-               { 0x0308, 0x690308 },
-               { 0x0310, 0x690310 },
-               { 0x0314, 0x690314 },
-               { 0x0318, 0x690318 },
-               { 0x031c, 0x69031c },
-               { 0x0320, 0x690320 },
-               { 0x0324, 0x690324 },
-               { 0x0328, 0x690328 },
-               { 0x032c, 0x69032c },
-               { 0x033c, 0x69033c },
-               { 0x0340, 0x690340 },
-               { 0x0344, 0x690344 },
-               { 0x0348, 0x690348 },
-               { 0x034c, 0x69034c },
-               { 0x0350, 0x690350 },
-               { 0x0354, 0x690354 },
-               { 0x0358, 0x690358 },
-               { 0x0364, 0x690364 },
-               { 0x0368, 0x690368 },
-               { 0x036c, 0x69036c },
-               { 0x0370, 0x690370 },
-               { 0x0374, 0x690374 },
-               { 0x0380, 0x690380 },
-               {}
-       }
-};
-
-static const struct nv50_disp_chan_mthd
-gv100_disp_wndw_mthd = {
-       .name = "Window",
-       .addr = 0x001000,
-       .prev = 0x000800,
-       .data = {
-               { "Global", 1, &gv100_disp_wndw_mthd_base },
-               {}
-       }
-};
-
-static void
-gv100_disp_wndw_intr(struct nv50_disp_chan *chan, bool en)
-{
-       struct nvkm_device *device = chan->disp->base.engine.subdev.device;
-       const u32 mask = 0x00000001 << chan->head;
-       const u32 data = en ? mask : 0;
-       nvkm_mask(device, 0x611da4, mask, data);
-}
-
-static const struct nv50_disp_chan_func
-gv100_disp_wndw = {
-       .init = gv100_disp_dmac_init,
-       .fini = gv100_disp_dmac_fini,
-       .intr = gv100_disp_wndw_intr,
-       .user = gv100_disp_chan_user,
-       .bind = gv100_disp_dmac_bind,
-};
-
-static int
-gv100_disp_wndw_new_(const struct nv50_disp_chan_func *func,
-                    const struct nv50_disp_chan_mthd *mthd,
-                    struct nv50_disp *disp, int chid,
-                    const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                    struct nvkm_object **pobject)
-{
-       union {
-               struct nvc37e_window_channel_dma_v0 v0;
-       } *args = argv;
-       struct nvkm_object *parent = oclass->parent;
-       int wndw, ret = -ENOSYS;
-       u64 push;
-
-       nvif_ioctl(parent, "create window channel dma size %d\n", argc);
-       if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-               nvif_ioctl(parent, "create window channel dma vers %d "
-                                  "pushbuf %016llx index %d\n",
-                          args->v0.version, args->v0.pushbuf, args->v0.index);
-               if (!(disp->wndw.mask & BIT(args->v0.index)))
-                       return -EINVAL;
-               push = args->v0.pushbuf;
-               wndw = args->v0.index;
-       } else
-               return ret;
-
-       return nv50_disp_dmac_new_(func, mthd, disp, chid + wndw,
-                                  wndw, push, oclass, pobject);
-}
-
-int
-gv100_disp_wndw_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
-                   struct nv50_disp *disp, struct nvkm_object **pobject)
-{
-       return gv100_disp_wndw_new_(&gv100_disp_wndw, &gv100_disp_wndw_mthd,
-                                   disp, 1, oclass, argv, argc, pobject);
-}