static int nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine; u32 data = *(u32 *)args; switch (mthd) { case 0x600: nv_wr32(priv, 0x419e00, data); /* MP.PM_UNK000 */ break; case 0x644: if (data & ~0x1ffffe) return -EINVAL; nv_wr32(priv, 0x419e44, data); /* MP.TRAP_WARP_ERROR_EN */ break; case 0x6ac: nv_wr32(priv, 0x419eac, data); /* MP.PM_UNK0AC */ break; default: return -EINVAL; } return 0; }
static int nv04_sw_flip(struct nvkm_object *object, u32 mthd, void *args, u32 size) { struct nv04_sw_chan *chan = (void *)nv_engctx(object->parent); if (chan->base.flip) return chan->base.flip(chan->base.flip_data); return -EINVAL; }
static int nv04_sw_set_ref(struct nvkm_object *object, u32 mthd, void *data, u32 size) { struct nvkm_object *channel = (void *)nv_engctx(object->parent); struct nvkm_fifo_chan *fifo = (void *)channel->parent; atomic_set(&fifo->refcnt, *(u32*)data); return 0; }
static int nvc0_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); chan->base.vblank.value = *(u32 *)args; return 0; }
static int nv50_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); chan->vblank.offset = *(u32 *)args; return 0; }
static int nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); if (chan->base.flip) return chan->base.flip(chan->base.flip_data); return -EINVAL; }
int nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); u32 head = *(u32 *)args; if (head >= chan->vblank.nr_event) return -EINVAL; nouveau_event_get(chan->vblank.event[head]); return 0; }
static int nvc0_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); struct nouveau_disp *disp = nouveau_disp(object); u32 crtc = *(u32 *)args; if ((nv_device(object)->card_type < NV_E0 && crtc > 1) || crtc > 3) return -EINVAL; nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event); return 0; }
static int nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); u64 data = *(u32 *)args; if (mthd == 0x0400) { chan->base.vblank.offset &= 0x00ffffffffULL; chan->base.vblank.offset |= data << 32; } else { chan->base.vblank.offset &= 0xff00000000ULL; chan->base.vblank.offset |= data; } return 0; }
static int nv50_software_mthd_dma_vblsem(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); struct nouveau_fifo_chan *fifo = (void *)nv_object(chan)->parent; struct nouveau_handle *handle; int ret = -EINVAL; handle = nouveau_namedb_get(nv_namedb(fifo), *(u32 *)args); if (!handle) return -ENOENT; if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) { struct nouveau_gpuobj *gpuobj = nv_gpuobj(handle->object); chan->vblank.ctxdma = gpuobj->node->offset >> 4; ret = 0; } nouveau_namedb_put(handle); return ret; }