drm/nouveau/disp/nv50-: merge handling of pio and dma channels
Unnecessarily complicated, and a barrier to cleanly supporting Volta. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
这个提交包含在:
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
g84_disp_base_mthd_base = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
gf119_disp_base_mthd_base = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs <bskeggs@redhat.com>
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
int
|
||||
gp102_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
#include "head.h"
|
||||
|
||||
#include <core/client.h>
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <nvif/unpack.h>
|
||||
|
||||
int
|
||||
nv50_disp_base_new_(const struct nv50_disp_dmac_func *func,
|
||||
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,
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <core/client.h>
|
||||
#include <core/notify.h>
|
||||
#include <core/oproxy.h>
|
||||
#include <core/ramht.h>
|
||||
#include <engine/dma.h>
|
||||
|
||||
@@ -204,25 +205,76 @@ nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc,
|
||||
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 *data, u32 size, struct nvkm_object **pobject)
|
||||
void *argv, u32 argc, struct nvkm_object **pobject)
|
||||
{
|
||||
struct nv50_disp_chan *chan = nv50_disp_chan(oclass->parent);
|
||||
return chan->func->child_new(chan, oclass, data, size, pobject);
|
||||
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 *oclass)
|
||||
struct nvkm_oclass *sclass)
|
||||
{
|
||||
struct nv50_disp_chan *chan = nv50_disp_chan(object);
|
||||
if (chan->func->child_get) {
|
||||
int ret = chan->func->child_get(chan, index, oclass);
|
||||
if (ret == 0)
|
||||
oclass->ctor = nv50_disp_chan_child_new;
|
||||
return ret;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -248,7 +300,7 @@ nv50_disp_chan_dtor(struct nvkm_object *object)
|
||||
struct nv50_disp *disp = chan->disp;
|
||||
if (chan->chid.user >= 0)
|
||||
disp->chan[chan->chid.user] = NULL;
|
||||
return chan->func->dtor ? chan->func->dtor(chan) : chan;
|
||||
return chan;
|
||||
}
|
||||
|
||||
static const struct nvkm_object_func
|
||||
@@ -264,12 +316,18 @@ nv50_disp_chan = {
|
||||
};
|
||||
|
||||
int
|
||||
nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
|
||||
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 nv50_disp_chan *chan)
|
||||
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;
|
||||
@@ -285,20 +343,3 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
|
||||
disp->chan[chan->chid.user] = chan;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return nv50_disp_chan_ctor(func, mthd, disp, ctrl, user,
|
||||
head, oclass, chan);
|
||||
}
|
||||
|
@@ -5,7 +5,6 @@
|
||||
#include <core/object.h>
|
||||
#include "nv50.h"
|
||||
struct nv50_disp_root;
|
||||
struct nv50_disp_dmac_func;
|
||||
|
||||
struct nv50_disp_chan {
|
||||
const struct nv50_disp_chan_func *func;
|
||||
@@ -19,36 +18,38 @@ struct nv50_disp_chan {
|
||||
int head;
|
||||
|
||||
struct nvkm_object object;
|
||||
|
||||
u64 push;
|
||||
};
|
||||
|
||||
struct nv50_disp_chan_func {
|
||||
void *(*dtor)(struct nv50_disp_chan *);
|
||||
int (*init)(struct nv50_disp_chan *);
|
||||
void (*fini)(struct nv50_disp_chan *);
|
||||
int (*child_get)(struct nv50_disp_chan *, int index,
|
||||
struct nvkm_oclass *);
|
||||
int (*child_new)(struct nv50_disp_chan *, const struct nvkm_oclass *,
|
||||
void *data, u32 size, struct nvkm_object **);
|
||||
int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle);
|
||||
};
|
||||
|
||||
int nv50_disp_chan_ctor(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 nv50_disp_chan *);
|
||||
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 **);
|
||||
|
||||
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;
|
||||
|
||||
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 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 nv50_disp_chan_func gp102_disp_dmac_func;
|
||||
|
||||
int nv50_disp_curs_new_(const struct nv50_disp_chan_func *,
|
||||
struct nv50_disp *, int ctrl, int user,
|
||||
@@ -58,17 +59,17 @@ 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_dmac_func *,
|
||||
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_dmac_func *,
|
||||
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_dmac_func *,
|
||||
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,
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
const struct nv50_disp_mthd_list
|
||||
g84_disp_core_mthd_dac = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
g94_disp_core_mthd_sor = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <subdev/timer.h>
|
||||
|
||||
@@ -167,10 +167,9 @@ gf119_disp_core_mthd = {
|
||||
};
|
||||
|
||||
void
|
||||
gf119_disp_core_fini(struct nv50_disp_dmac *chan)
|
||||
gf119_disp_core_fini(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
||||
/* deactivate channel */
|
||||
@@ -190,10 +189,9 @@ gf119_disp_core_fini(struct nv50_disp_dmac *chan)
|
||||
}
|
||||
|
||||
static int
|
||||
gf119_disp_core_init(struct nv50_disp_dmac *chan)
|
||||
gf119_disp_core_init(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
||||
/* enable error reporting */
|
||||
@@ -220,7 +218,7 @@ gf119_disp_core_init(struct nv50_disp_dmac *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct nv50_disp_dmac_func
|
||||
const struct nv50_disp_chan_func
|
||||
gf119_disp_core_func = {
|
||||
.init = gf119_disp_core_init,
|
||||
.fini = gf119_disp_core_fini,
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
gk104_disp_core_mthd_head = {
|
||||
|
@@ -21,15 +21,14 @@
|
||||
*
|
||||
* Authors: Ben Skeggs <bskeggs@redhat.com>
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static int
|
||||
gp102_disp_core_init(struct nv50_disp_dmac *chan)
|
||||
gp102_disp_core_init(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
||||
/* enable error reporting */
|
||||
@@ -56,7 +55,7 @@ gp102_disp_core_init(struct nv50_disp_dmac *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nv50_disp_dmac_func
|
||||
static const struct nv50_disp_chan_func
|
||||
gp102_disp_core_func = {
|
||||
.init = gp102_disp_core_init,
|
||||
.fini = gf119_disp_core_fini,
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <core/client.h>
|
||||
#include <subdev/timer.h>
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <nvif/unpack.h>
|
||||
|
||||
int
|
||||
nv50_disp_core_new_(const struct nv50_disp_dmac_func *func,
|
||||
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,
|
||||
@@ -164,10 +164,9 @@ nv50_disp_core_mthd = {
|
||||
};
|
||||
|
||||
static void
|
||||
nv50_disp_core_fini(struct nv50_disp_dmac *chan)
|
||||
nv50_disp_core_fini(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
||||
/* deactivate channel */
|
||||
@@ -186,10 +185,9 @@ nv50_disp_core_fini(struct nv50_disp_dmac *chan)
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_disp_core_init(struct nv50_disp_dmac *chan)
|
||||
nv50_disp_core_init(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
|
||||
/* enable error reporting */
|
||||
@@ -222,7 +220,7 @@ nv50_disp_core_init(struct nv50_disp_dmac *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct nv50_disp_dmac_func
|
||||
const struct nv50_disp_chan_func
|
||||
nv50_disp_core_func = {
|
||||
.init = nv50_disp_core_init,
|
||||
.fini = nv50_disp_core_fini,
|
||||
|
@@ -21,29 +21,27 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "rootnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <core/ramht.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
int
|
||||
gf119_disp_dmac_bind(struct nv50_disp_dmac *chan,
|
||||
gf119_disp_dmac_bind(struct nv50_disp_chan *chan,
|
||||
struct nvkm_object *object, u32 handle)
|
||||
{
|
||||
return nvkm_ramht_insert(chan->base.disp->ramht, object,
|
||||
chan->base.chid.user, -9, handle,
|
||||
chan->base.chid.user << 27 | 0x00000001);
|
||||
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_dmac *chan)
|
||||
gf119_disp_dmac_fini(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
int ctrl = chan->chid.ctrl;
|
||||
int user = chan->chid.user;
|
||||
|
||||
/* deactivate channel */
|
||||
nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000);
|
||||
@@ -62,13 +60,12 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan)
|
||||
}
|
||||
|
||||
static int
|
||||
gf119_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
gf119_disp_dmac_init(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
int ctrl = chan->chid.ctrl;
|
||||
int user = chan->chid.user;
|
||||
|
||||
/* enable error reporting */
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
|
||||
@@ -94,7 +91,7 @@ gf119_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct nv50_disp_dmac_func
|
||||
const struct nv50_disp_chan_func
|
||||
gf119_disp_dmac_func = {
|
||||
.init = gf119_disp_dmac_init,
|
||||
.fini = gf119_disp_dmac_fini,
|
||||
|
@@ -21,19 +21,17 @@
|
||||
*
|
||||
* Authors: Ben Skeggs <bskeggs@redhat.com>
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "rootnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static int
|
||||
gp102_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
gp102_disp_dmac_init(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
int ctrl = chan->chid.ctrl;
|
||||
int user = chan->chid.user;
|
||||
|
||||
/* enable error reporting */
|
||||
nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
|
||||
@@ -59,7 +57,7 @@ gp102_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct nv50_disp_dmac_func
|
||||
const struct nv50_disp_chan_func
|
||||
gp102_disp_dmac_func = {
|
||||
.init = gp102_disp_dmac_init,
|
||||
.fini = gf119_disp_dmac_fini,
|
||||
|
@@ -21,117 +21,16 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "rootnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <core/client.h>
|
||||
#include <core/oproxy.h>
|
||||
#include <core/ramht.h>
|
||||
#include <subdev/fb.h>
|
||||
#include <subdev/timer.h>
|
||||
#include <engine/dma.h>
|
||||
|
||||
struct nv50_disp_dmac_object {
|
||||
struct nvkm_oproxy oproxy;
|
||||
struct nv50_disp *disp;
|
||||
int hash;
|
||||
};
|
||||
|
||||
static void
|
||||
nv50_disp_dmac_child_del_(struct nvkm_oproxy *base)
|
||||
{
|
||||
struct nv50_disp_dmac_object *object =
|
||||
container_of(base, typeof(*object), oproxy);
|
||||
nvkm_ramht_remove(object->disp->ramht, object->hash);
|
||||
}
|
||||
|
||||
static const struct nvkm_oproxy_func
|
||||
nv50_disp_dmac_child_func_ = {
|
||||
.dtor[0] = nv50_disp_dmac_child_del_,
|
||||
};
|
||||
|
||||
static int
|
||||
nv50_disp_dmac_child_new_(struct nv50_disp_chan *base,
|
||||
const struct nvkm_oclass *oclass,
|
||||
void *data, u32 size, struct nvkm_object **pobject)
|
||||
{
|
||||
struct nv50_disp_dmac *chan = nv50_disp_dmac(base);
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
const struct nvkm_device_oclass *sclass = oclass->priv;
|
||||
struct nv50_disp_dmac_object *object;
|
||||
int ret;
|
||||
|
||||
if (!(object = kzalloc(sizeof(*object), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
nvkm_oproxy_ctor(&nv50_disp_dmac_child_func_, oclass, &object->oproxy);
|
||||
object->disp = disp;
|
||||
*pobject = &object->oproxy.base;
|
||||
|
||||
ret = sclass->ctor(device, oclass, data, size, &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_dmac_child_get_(struct nv50_disp_chan *base, int index,
|
||||
struct nvkm_oclass *sclass)
|
||||
{
|
||||
struct nv50_disp_dmac *chan = nv50_disp_dmac(base);
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
const struct nvkm_device_oclass *oclass = NULL;
|
||||
|
||||
sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ);
|
||||
if (sclass->engine && sclass->engine->func->base.sclass) {
|
||||
sclass->engine->func->base.sclass(sclass, index, &oclass);
|
||||
if (oclass) {
|
||||
sclass->priv = oclass;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_disp_dmac_fini_(struct nv50_disp_chan *base)
|
||||
{
|
||||
struct nv50_disp_dmac *chan = nv50_disp_dmac(base);
|
||||
chan->func->fini(chan);
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_disp_dmac_init_(struct nv50_disp_chan *base)
|
||||
{
|
||||
struct nv50_disp_dmac *chan = nv50_disp_dmac(base);
|
||||
return chan->func->init(chan);
|
||||
}
|
||||
|
||||
static void *
|
||||
nv50_disp_dmac_dtor_(struct nv50_disp_chan *base)
|
||||
{
|
||||
return nv50_disp_dmac(base);
|
||||
}
|
||||
|
||||
static const struct nv50_disp_chan_func
|
||||
nv50_disp_dmac_func_ = {
|
||||
.dtor = nv50_disp_dmac_dtor_,
|
||||
.init = nv50_disp_dmac_init_,
|
||||
.fini = nv50_disp_dmac_fini_,
|
||||
.child_get = nv50_disp_dmac_child_get_,
|
||||
.child_new = nv50_disp_dmac_child_new_,
|
||||
};
|
||||
|
||||
int
|
||||
nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func,
|
||||
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,
|
||||
@@ -139,16 +38,12 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func,
|
||||
{
|
||||
struct nvkm_client *client = oclass->client;
|
||||
struct nvkm_dmaobj *dmaobj;
|
||||
struct nv50_disp_dmac *chan;
|
||||
struct nv50_disp_chan *chan;
|
||||
int ret;
|
||||
|
||||
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
*pobject = &chan->base.object;
|
||||
chan->func = func;
|
||||
|
||||
ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, disp,
|
||||
chid, chid, head, oclass, &chan->base);
|
||||
ret = nv50_disp_chan_new_(func, mthd, disp, chid, chid, head, oclass,
|
||||
pobject);
|
||||
chan = nv50_disp_chan(*pobject);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -174,23 +69,22 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func,
|
||||
}
|
||||
|
||||
int
|
||||
nv50_disp_dmac_bind(struct nv50_disp_dmac *chan,
|
||||
nv50_disp_dmac_bind(struct nv50_disp_chan *chan,
|
||||
struct nvkm_object *object, u32 handle)
|
||||
{
|
||||
return nvkm_ramht_insert(chan->base.disp->ramht, object,
|
||||
chan->base.chid.user, -10, handle,
|
||||
chan->base.chid.user << 28 |
|
||||
chan->base.chid.user);
|
||||
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_dmac *chan)
|
||||
nv50_disp_dmac_fini(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
int ctrl = chan->chid.ctrl;
|
||||
int user = chan->chid.user;
|
||||
|
||||
/* deactivate channel */
|
||||
nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000);
|
||||
@@ -208,13 +102,12 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan)
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
nv50_disp_dmac_init(struct nv50_disp_chan *chan)
|
||||
{
|
||||
struct nv50_disp *disp = chan->base.disp;
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int ctrl = chan->base.chid.ctrl;
|
||||
int user = chan->base.chid.user;
|
||||
int ctrl = chan->chid.ctrl;
|
||||
int user = chan->chid.user;
|
||||
|
||||
/* enable error reporting */
|
||||
nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user);
|
||||
@@ -240,7 +133,7 @@ nv50_disp_dmac_init(struct nv50_disp_dmac *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct nv50_disp_dmac_func
|
||||
const struct nv50_disp_chan_func
|
||||
nv50_disp_dmac_func = {
|
||||
.init = nv50_disp_dmac_init,
|
||||
.fini = nv50_disp_dmac_fini,
|
||||
|
@@ -1,35 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __NV50_DISP_DMAC_H__
|
||||
#define __NV50_DISP_DMAC_H__
|
||||
#define nv50_disp_dmac(p) container_of((p), struct nv50_disp_dmac, base)
|
||||
#include "channv50.h"
|
||||
|
||||
struct nv50_disp_dmac {
|
||||
const struct nv50_disp_dmac_func *func;
|
||||
struct nv50_disp_chan base;
|
||||
u32 push;
|
||||
};
|
||||
|
||||
struct nv50_disp_dmac_func {
|
||||
int (*init)(struct nv50_disp_dmac *);
|
||||
void (*fini)(struct nv50_disp_dmac *);
|
||||
int (*bind)(struct nv50_disp_dmac *, struct nvkm_object *, u32 handle);
|
||||
};
|
||||
|
||||
int nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *,
|
||||
const struct nv50_disp_chan_mthd *,
|
||||
struct nv50_disp *, int chid, int head, u64 push,
|
||||
const struct nvkm_oclass *, struct nvkm_object **);
|
||||
|
||||
extern const struct nv50_disp_dmac_func nv50_disp_dmac_func;
|
||||
int nv50_disp_dmac_bind(struct nv50_disp_dmac *, struct nvkm_object *, u32);
|
||||
extern const struct nv50_disp_dmac_func nv50_disp_core_func;
|
||||
|
||||
extern const struct nv50_disp_dmac_func gf119_disp_dmac_func;
|
||||
void gf119_disp_dmac_fini(struct nv50_disp_dmac *);
|
||||
int gf119_disp_dmac_bind(struct nv50_disp_dmac *, struct nvkm_object *, u32);
|
||||
extern const struct nv50_disp_dmac_func gf119_disp_core_func;
|
||||
void gf119_disp_core_fini(struct nv50_disp_dmac *);
|
||||
|
||||
extern const struct nv50_disp_dmac_func gp102_disp_dmac_func;
|
||||
#endif
|
@@ -24,6 +24,7 @@
|
||||
#include "nv50.h"
|
||||
#include "head.h"
|
||||
#include "ior.h"
|
||||
#include "channv50.h"
|
||||
#include "rootnv50.h"
|
||||
|
||||
#include <core/ramht.h>
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "nv50.h"
|
||||
#include "head.h"
|
||||
#include "ior.h"
|
||||
#include "channv50.h"
|
||||
#include "rootnv50.h"
|
||||
|
||||
static void
|
||||
|
@@ -79,4 +79,11 @@ void gf119_disp_intr_error(struct nv50_disp *, int);
|
||||
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;
|
||||
#endif
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
g84_disp_ovly_mthd_base = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
gf119_disp_ovly_mthd_base = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
gk104_disp_ovly_mthd_base = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
int
|
||||
gp102_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
static const struct nv50_disp_mthd_list
|
||||
gt200_disp_ovly_mthd_base = {
|
||||
|
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
#include "head.h"
|
||||
|
||||
#include <core/client.h>
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <nvif/unpack.h>
|
||||
|
||||
int
|
||||
nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *func,
|
||||
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,
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs <bskeggs@redhat.com>
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs <bskeggs@redhat.com>
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
#include "rootnv50.h"
|
||||
#include "dmacnv50.h"
|
||||
#include "channv50.h"
|
||||
#include "dp.h"
|
||||
#include "head.h"
|
||||
#include "ior.h"
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#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"
|
||||
#include "dmacnv50.h"
|
||||
|
||||
struct nv50_disp_root {
|
||||
const struct nv50_disp_root_func *func;
|
||||
|
在新工单中引用
屏蔽一个用户