diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c | 110 |
1 files changed, 51 insertions, 59 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c index 624b79510175..db4a9b3e0e09 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" +#include "rootnv50.h" #include <core/client.h> #include <subdev/timer.h> @@ -29,6 +30,33 @@ #include <nvif/class.h> #include <nvif/unpack.h> +int +nv50_disp_core_new(const struct nv50_disp_dmac_func *func, + const struct nv50_disp_chan_mthd *mthd, + struct nv50_disp_root *root, int chid, + const struct nvkm_oclass *oclass, void *data, u32 size, + struct nvkm_object **pobject) +{ + union { + struct nv50_disp_core_channel_dma_v0 v0; + } *args = data; + struct nvkm_object *parent = oclass->parent; + u64 push; + int ret; + + nvif_ioctl(parent, "create disp core channel dma size %d\n", size); + if (nvif_unpack(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, root, chid, 0, + push, oclass, pobject); +} + const struct nv50_disp_mthd_list nv50_disp_core_mthd_base = { .mthd = 0x0000, @@ -121,10 +149,11 @@ nv50_disp_core_mthd_head = { } }; -const struct nv50_disp_mthd_chan -nv50_disp_core_mthd_chan = { +static const struct nv50_disp_chan_mthd +nv50_disp_core_chan_mthd = { .name = "Core", .addr = 0x000000, + .prev = 0x000004, .data = { { "Global", 1, &nv50_disp_core_mthd_base }, { "DAC", 3, &nv50_disp_core_mthd_dac }, @@ -135,11 +164,10 @@ nv50_disp_core_mthd_chan = { } }; -static int -nv50_disp_core_fini(struct nvkm_object *object, bool suspend) +static void +nv50_disp_core_fini(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = (void *)object->engine; - struct nv50_disp_dmac *mast = (void *)object; + struct nv50_disp *disp = chan->base.root->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; @@ -152,28 +180,18 @@ nv50_disp_core_fini(struct nvkm_object *object, bool suspend) ) < 0) { nvkm_error(subdev, "core fini: %08x\n", nvkm_rd32(device, 0x610200)); - if (suspend) - return -EBUSY; } /* disable error reporting and completion notifications */ nvkm_mask(device, 0x610028, 0x00010001, 0x00000000); - - return nv50_disp_chan_fini(&mast->base, suspend); } static int -nv50_disp_core_init(struct nvkm_object *object) +nv50_disp_core_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = (void *)object->engine; - struct nv50_disp_dmac *mast = (void *)object; + struct nv50_disp *disp = chan->base.root->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ret; - - ret = nv50_disp_chan_init(&mast->base); - if (ret) - return ret; /* enable error reporting */ nvkm_mask(device, 0x610028, 0x00010000, 0x00010000); @@ -185,7 +203,7 @@ nv50_disp_core_init(struct nvkm_object *object) nvkm_mask(device, 0x610200, 0x00600000, 0x00600000); /* initialise channel for dma command submission */ - nvkm_wr32(device, 0x610204, mast->push); + nvkm_wr32(device, 0x610204, chan->push); nvkm_wr32(device, 0x610208, 0x00010000); nvkm_wr32(device, 0x61020c, 0x00000000); nvkm_mask(device, 0x610200, 0x00000010, 0x00000010); @@ -205,46 +223,20 @@ nv50_disp_core_init(struct nvkm_object *object) return 0; } -int -nv50_disp_core_ctor(struct nvkm_object *parent, - struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) -{ - union { - struct nv50_disp_core_channel_dma_v0 v0; - } *args = data; - struct nv50_disp_dmac *mast; - int ret; - - nvif_ioctl(parent, "create disp core channel dma size %d\n", size); - if (nvif_unpack(args->v0, 0, 0, false)) { - nvif_ioctl(parent, "create disp core channel dma vers %d " - "pushbuf %016llx\n", - args->v0.version, args->v0.pushbuf); - } else - return ret; - - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, - 0, sizeof(*mast), (void **)&mast); - *pobject = nv_object(mast); - if (ret) - return ret; - - return 0; -} +const struct nv50_disp_dmac_func +nv50_disp_core_func = { + .init = nv50_disp_core_init, + .fini = nv50_disp_core_fini, + .bind = nv50_disp_dmac_bind, +}; -struct nv50_disp_chan_impl -nv50_disp_core_ofuncs = { - .base.ctor = nv50_disp_core_ctor, - .base.dtor = nv50_disp_dmac_dtor, - .base.init = nv50_disp_core_init, - .base.fini = nv50_disp_core_fini, - .base.map = nv50_disp_chan_map, - .base.ntfy = nv50_disp_chan_ntfy, - .base.rd32 = nv50_disp_chan_rd32, - .base.wr32 = nv50_disp_chan_wr32, +const struct nv50_disp_dmac_oclass +nv50_disp_core_oclass = { + .base.oclass = NV50_DISP_CORE_CHANNEL_DMA, + .base.minver = 0, + .base.maxver = 0, + .ctor = nv50_disp_core_new, + .func = &nv50_disp_core_func, + .mthd = &nv50_disp_core_chan_mthd, .chid = 0, - .attach = nv50_disp_dmac_object_attach, - .detach = nv50_disp_dmac_object_detach, }; |