drm/nv50/kms: don't assume same class versions for all channels
One of the next commits will remove some of the class IDs, leaving only the ones used by NVIDIA which, presumably, mark where functionality changes actually happened. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
867920f8c9
commit
410f3ec635
|
@ -68,19 +68,17 @@ struct nv50_chan {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_chan_create(struct nvif_object *disp, u32 bclass, u8 head,
|
nv50_chan_create(struct nvif_object *disp, const u32 *oclass, u8 head,
|
||||||
void *data, u32 size, struct nv50_chan *chan)
|
void *data, u32 size, struct nv50_chan *chan)
|
||||||
{
|
{
|
||||||
const u32 oclass = EVO_CHAN_OCLASS(bclass, disp);
|
while (oclass[0]) {
|
||||||
const u32 handle = EVO_CHAN_HANDLE(bclass, head);
|
int ret = nvif_object_init(disp, NULL, (oclass[0] << 16) | head,
|
||||||
int ret;
|
oclass[0], data, size,
|
||||||
|
&chan->user);
|
||||||
ret = nvif_object_init(disp, NULL, handle, oclass, data, size,
|
if (oclass++, ret == 0)
|
||||||
&chan->user);
|
return ret;
|
||||||
if (ret)
|
}
|
||||||
return ret;
|
return -ENOSYS;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -104,10 +102,72 @@ nv50_pioc_destroy(struct nv50_pioc *pioc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_pioc_create(struct nvif_object *disp, u32 bclass, u8 head,
|
nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head,
|
||||||
void *data, u32 size, struct nv50_pioc *pioc)
|
void *data, u32 size, struct nv50_pioc *pioc)
|
||||||
{
|
{
|
||||||
return nv50_chan_create(disp, bclass, head, data, size, &pioc->base);
|
return nv50_chan_create(disp, oclass, head, data, size, &pioc->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Cursor Immediate
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct nv50_curs {
|
||||||
|
struct nv50_pioc base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
nv50_curs_create(struct nvif_object *disp, int head, struct nv50_curs *curs)
|
||||||
|
{
|
||||||
|
struct nv50_display_curs_class args = {
|
||||||
|
.head = head,
|
||||||
|
};
|
||||||
|
static const u32 oclass[] = {
|
||||||
|
GM107_DISP_CURS_CLASS,
|
||||||
|
NVF0_DISP_CURS_CLASS,
|
||||||
|
NVE0_DISP_CURS_CLASS,
|
||||||
|
NVD0_DISP_CURS_CLASS,
|
||||||
|
NVA3_DISP_CURS_CLASS,
|
||||||
|
NV94_DISP_CURS_CLASS,
|
||||||
|
NVA0_DISP_CURS_CLASS,
|
||||||
|
NV84_DISP_CURS_CLASS,
|
||||||
|
NV50_DISP_CURS_CLASS,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
return nv50_pioc_create(disp, oclass, head, &args, sizeof(args),
|
||||||
|
&curs->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Overlay Immediate
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct nv50_oimm {
|
||||||
|
struct nv50_pioc base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
nv50_oimm_create(struct nvif_object *disp, int head, struct nv50_oimm *oimm)
|
||||||
|
{
|
||||||
|
struct nv50_display_oimm_class args = {
|
||||||
|
.head = head,
|
||||||
|
};
|
||||||
|
static const u32 oclass[] = {
|
||||||
|
GM107_DISP_OIMM_CLASS,
|
||||||
|
NVF0_DISP_OIMM_CLASS,
|
||||||
|
NVE0_DISP_OIMM_CLASS,
|
||||||
|
NVD0_DISP_OIMM_CLASS,
|
||||||
|
NVA3_DISP_OIMM_CLASS,
|
||||||
|
NV94_DISP_OIMM_CLASS,
|
||||||
|
NVA0_DISP_OIMM_CLASS,
|
||||||
|
NV84_DISP_OIMM_CLASS,
|
||||||
|
NV50_DISP_OIMM_CLASS,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
return nv50_pioc_create(disp, oclass, head, &args, sizeof(args),
|
||||||
|
&oimm->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -143,7 +203,7 @@ nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head,
|
nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head,
|
||||||
void *data, u32 size, u64 syncbuf,
|
void *data, u32 size, u64 syncbuf,
|
||||||
struct nv50_dmac *dmac)
|
struct nv50_dmac *dmac)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +230,7 @@ nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = nv50_chan_create(disp, bclass, head, data, size, &dmac->base);
|
ret = nv50_chan_create(disp, oclass, head, data, size, &dmac->base);
|
||||||
nvif_object_fini(&pushbuf);
|
nvif_object_fini(&pushbuf);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -202,13 +262,40 @@ nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Core
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
struct nv50_mast {
|
struct nv50_mast {
|
||||||
struct nv50_dmac base;
|
struct nv50_dmac base;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nv50_curs {
|
static int
|
||||||
struct nv50_pioc base;
|
nv50_core_create(struct nvif_object *disp, u64 syncbuf, struct nv50_mast *core)
|
||||||
};
|
{
|
||||||
|
struct nv50_display_mast_class args = {
|
||||||
|
.pushbuf = EVO_PUSH_HANDLE(MAST, 0),
|
||||||
|
};
|
||||||
|
static const u32 oclass[] = {
|
||||||
|
GM107_DISP_MAST_CLASS,
|
||||||
|
NVF0_DISP_MAST_CLASS,
|
||||||
|
NVE0_DISP_MAST_CLASS,
|
||||||
|
NVD0_DISP_MAST_CLASS,
|
||||||
|
NVA3_DISP_MAST_CLASS,
|
||||||
|
NV94_DISP_MAST_CLASS,
|
||||||
|
NVA0_DISP_MAST_CLASS,
|
||||||
|
NV84_DISP_MAST_CLASS,
|
||||||
|
NV50_DISP_MAST_CLASS,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
return nv50_dmac_create(disp, oclass, 0, &args, sizeof(args), syncbuf,
|
||||||
|
&core->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Base
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
struct nv50_sync {
|
struct nv50_sync {
|
||||||
struct nv50_dmac base;
|
struct nv50_dmac base;
|
||||||
|
@ -216,13 +303,63 @@ struct nv50_sync {
|
||||||
u32 data;
|
u32 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
nv50_base_create(struct nvif_object *disp, int head, u64 syncbuf,
|
||||||
|
struct nv50_sync *base)
|
||||||
|
{
|
||||||
|
struct nv50_display_sync_class args = {
|
||||||
|
.pushbuf = EVO_PUSH_HANDLE(SYNC, head),
|
||||||
|
.head = head,
|
||||||
|
};
|
||||||
|
static const u32 oclass[] = {
|
||||||
|
GM107_DISP_SYNC_CLASS,
|
||||||
|
NVF0_DISP_SYNC_CLASS,
|
||||||
|
NVE0_DISP_SYNC_CLASS,
|
||||||
|
NVD0_DISP_SYNC_CLASS,
|
||||||
|
NVA3_DISP_SYNC_CLASS,
|
||||||
|
NV94_DISP_SYNC_CLASS,
|
||||||
|
NVA0_DISP_SYNC_CLASS,
|
||||||
|
NV84_DISP_SYNC_CLASS,
|
||||||
|
NV50_DISP_SYNC_CLASS,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
return nv50_dmac_create(disp, oclass, head, &args, sizeof(args),
|
||||||
|
syncbuf, &base->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Overlay
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
struct nv50_ovly {
|
struct nv50_ovly {
|
||||||
struct nv50_dmac base;
|
struct nv50_dmac base;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nv50_oimm {
|
static int
|
||||||
struct nv50_pioc base;
|
nv50_ovly_create(struct nvif_object *disp, int head, u64 syncbuf,
|
||||||
};
|
struct nv50_ovly *ovly)
|
||||||
|
{
|
||||||
|
struct nv50_display_ovly_class args = {
|
||||||
|
.pushbuf = EVO_PUSH_HANDLE(OVLY, head),
|
||||||
|
.head = head,
|
||||||
|
};
|
||||||
|
static const u32 oclass[] = {
|
||||||
|
GM107_DISP_OVLY_CLASS,
|
||||||
|
NVF0_DISP_OVLY_CLASS,
|
||||||
|
NVE0_DISP_OVLY_CLASS,
|
||||||
|
NVD0_DISP_OVLY_CLASS,
|
||||||
|
NVA3_DISP_OVLY_CLASS,
|
||||||
|
NV94_DISP_OVLY_CLASS,
|
||||||
|
NVA0_DISP_OVLY_CLASS,
|
||||||
|
NV84_DISP_OVLY_CLASS,
|
||||||
|
NV50_DISP_OVLY_CLASS,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
return nv50_dmac_create(disp, oclass, head, &args, sizeof(args),
|
||||||
|
syncbuf, &ovly->base);
|
||||||
|
}
|
||||||
|
|
||||||
struct nv50_head {
|
struct nv50_head {
|
||||||
struct nouveau_crtc base;
|
struct nouveau_crtc base;
|
||||||
|
@ -1276,11 +1413,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
|
||||||
nv50_crtc_lut_load(crtc);
|
nv50_crtc_lut_load(crtc);
|
||||||
|
|
||||||
/* allocate cursor resources */
|
/* allocate cursor resources */
|
||||||
ret = nv50_pioc_create(disp->disp, NV50_DISP_CURS_CLASS, index,
|
ret = nv50_curs_create(disp->disp, index, &head->curs);
|
||||||
&(struct nv50_display_curs_class) {
|
|
||||||
.head = index,
|
|
||||||
}, sizeof(struct nv50_display_curs_class),
|
|
||||||
&head->curs.base);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1301,12 +1434,8 @@ nv50_crtc_create(struct drm_device *dev, int index)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* allocate page flip / sync resources */
|
/* allocate page flip / sync resources */
|
||||||
ret = nv50_dmac_create(disp->disp, NV50_DISP_SYNC_CLASS, index,
|
ret = nv50_base_create(disp->disp, index, disp->sync->bo.offset,
|
||||||
&(struct nv50_display_sync_class) {
|
&head->sync);
|
||||||
.pushbuf = EVO_PUSH_HANDLE(SYNC, index),
|
|
||||||
.head = index,
|
|
||||||
}, sizeof(struct nv50_display_sync_class),
|
|
||||||
disp->sync->bo.offset, &head->sync.base);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1314,20 +1443,12 @@ nv50_crtc_create(struct drm_device *dev, int index)
|
||||||
head->sync.data = 0x00000000;
|
head->sync.data = 0x00000000;
|
||||||
|
|
||||||
/* allocate overlay resources */
|
/* allocate overlay resources */
|
||||||
ret = nv50_pioc_create(disp->disp, NV50_DISP_OIMM_CLASS, index,
|
ret = nv50_oimm_create(disp->disp, index, &head->oimm);
|
||||||
&(struct nv50_display_oimm_class) {
|
|
||||||
.head = index,
|
|
||||||
}, sizeof(struct nv50_display_oimm_class),
|
|
||||||
&head->oimm.base);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = nv50_dmac_create(disp->disp, NV50_DISP_OVLY_CLASS, index,
|
ret = nv50_ovly_create(disp->disp, index, disp->sync->bo.offset,
|
||||||
&(struct nv50_display_ovly_class) {
|
&head->ovly);
|
||||||
.pushbuf = EVO_PUSH_HANDLE(OVLY, index),
|
|
||||||
.head = index,
|
|
||||||
}, sizeof(struct nv50_display_ovly_class),
|
|
||||||
disp->sync->bo.offset, &head->ovly.base);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -2288,11 +2409,8 @@ nv50_display_create(struct drm_device *dev)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* allocate master evo channel */
|
/* allocate master evo channel */
|
||||||
ret = nv50_dmac_create(disp->disp, NV50_DISP_MAST_CLASS, 0,
|
ret = nv50_core_create(disp->disp, disp->sync->bo.offset,
|
||||||
&(struct nv50_display_mast_class) {
|
&disp->mast);
|
||||||
.pushbuf = EVO_PUSH_HANDLE(MAST, 0),
|
|
||||||
}, sizeof(struct nv50_display_mast_class),
|
|
||||||
disp->sync->bo.offset, &disp->mast.base);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue