mirror of https://gitee.com/openkylin/linux.git
drm/nouveau/kms/nv50-: modify base allocation so the code can be split
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
b97ace4072
commit
d7c6e97a32
|
@ -468,28 +468,6 @@ struct nv50_sync {
|
||||||
u32 data;
|
u32 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
|
||||||
nv50_base_create(struct nvif_device *device, struct nvif_object *disp,
|
|
||||||
int head, u64 syncbuf, struct nv50_sync *base)
|
|
||||||
{
|
|
||||||
struct nv50_disp_base_channel_dma_v0 args = {
|
|
||||||
.head = head,
|
|
||||||
};
|
|
||||||
static const s32 oclass[] = {
|
|
||||||
GK110_DISP_BASE_CHANNEL_DMA,
|
|
||||||
GK104_DISP_BASE_CHANNEL_DMA,
|
|
||||||
GF110_DISP_BASE_CHANNEL_DMA,
|
|
||||||
GT214_DISP_BASE_CHANNEL_DMA,
|
|
||||||
GT200_DISP_BASE_CHANNEL_DMA,
|
|
||||||
G82_DISP_BASE_CHANNEL_DMA,
|
|
||||||
NV50_DISP_BASE_CHANNEL_DMA,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
return nv50_dmac_create(device, disp, oclass, head, &args, sizeof(args),
|
|
||||||
syncbuf, &base->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nv50_head {
|
struct nv50_head {
|
||||||
struct nouveau_crtc base;
|
struct nouveau_crtc base;
|
||||||
struct {
|
struct {
|
||||||
|
@ -581,7 +559,6 @@ evo_kick(u32 *push, void *evoc)
|
||||||
struct nv50_wndw {
|
struct nv50_wndw {
|
||||||
const struct nv50_wndw_func *func;
|
const struct nv50_wndw_func *func;
|
||||||
const struct nv50_wimm_func *immd;
|
const struct nv50_wimm_func *immd;
|
||||||
struct nv50_dmac *dmac;
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -601,7 +578,6 @@ struct nv50_wndw {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nv50_wndw_func {
|
struct nv50_wndw_func {
|
||||||
void *(*dtor)(struct nv50_wndw *);
|
|
||||||
int (*acquire)(struct nv50_wndw *, struct nv50_wndw_atom *asyw,
|
int (*acquire)(struct nv50_wndw *, struct nv50_wndw_atom *asyw,
|
||||||
struct nv50_head_atom *asyh);
|
struct nv50_head_atom *asyh);
|
||||||
void (*release)(struct nv50_wndw *, struct nv50_wndw_atom *asyw,
|
void (*release)(struct nv50_wndw *, struct nv50_wndw_atom *asyw,
|
||||||
|
@ -959,19 +935,16 @@ nv50_wndw_destroy(struct drm_plane *plane)
|
||||||
{
|
{
|
||||||
struct nv50_wndw *wndw = nv50_wndw(plane);
|
struct nv50_wndw *wndw = nv50_wndw(plane);
|
||||||
struct nv50_wndw_ctxdma *ctxdma, *ctxtmp;
|
struct nv50_wndw_ctxdma *ctxdma, *ctxtmp;
|
||||||
void *data = wndw;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) {
|
list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) {
|
||||||
nv50_wndw_ctxdma_del(ctxdma);
|
nv50_wndw_ctxdma_del(ctxdma);
|
||||||
}
|
}
|
||||||
|
|
||||||
nvif_notify_fini(&wndw->notify);
|
nvif_notify_fini(&wndw->notify);
|
||||||
if (wndw->func->dtor)
|
|
||||||
data = wndw->func->dtor(wndw);
|
|
||||||
nv50_dmac_destroy(&wndw->wimm);
|
nv50_dmac_destroy(&wndw->wimm);
|
||||||
nv50_dmac_destroy(&wndw->wndw);
|
nv50_dmac_destroy(&wndw->wndw);
|
||||||
drm_plane_cleanup(&wndw->plane);
|
drm_plane_cleanup(&wndw->plane);
|
||||||
kfree(data);
|
kfree(wndw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_plane_funcs
|
static const struct drm_plane_funcs
|
||||||
|
@ -984,6 +957,12 @@ nv50_wndw = {
|
||||||
.atomic_destroy_state = nv50_wndw_atomic_destroy_state,
|
.atomic_destroy_state = nv50_wndw_atomic_destroy_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
nv50_wndw_notify(struct nvif_notify *notify)
|
||||||
|
{
|
||||||
|
return NVIF_NOTIFY_KEEP;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_wndw_fini(struct nv50_wndw *wndw)
|
nv50_wndw_fini(struct nv50_wndw *wndw)
|
||||||
{
|
{
|
||||||
|
@ -996,29 +975,6 @@ nv50_wndw_init(struct nv50_wndw *wndw)
|
||||||
nvif_notify_get(&wndw->notify);
|
nvif_notify_get(&wndw->notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev,
|
|
||||||
enum drm_plane_type type, const char *name, int index,
|
|
||||||
struct nv50_dmac *dmac, const u32 *format, int nformat,
|
|
||||||
struct nv50_wndw *wndw)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
wndw->func = func;
|
|
||||||
wndw->dmac = dmac;
|
|
||||||
wndw->ctxdma.parent = &dmac->base.user;
|
|
||||||
|
|
||||||
ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw,
|
|
||||||
format, nformat, NULL,
|
|
||||||
type, "%s-%d", name, index);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper);
|
|
||||||
INIT_LIST_HEAD(&wndw->ctxdma.list);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
|
nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
|
||||||
enum drm_plane_type type, const char *name, int index,
|
enum drm_plane_type type, const char *name, int index,
|
||||||
|
@ -1030,18 +986,27 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
|
||||||
|
|
||||||
if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL)))
|
if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
wndw->func = func;
|
||||||
wndw->id = index;
|
wndw->id = index;
|
||||||
|
|
||||||
|
wndw->ctxdma.parent = &wndw->wndw.base.user;
|
||||||
|
INIT_LIST_HEAD(&wndw->ctxdma.list);
|
||||||
|
|
||||||
for (nformat = 0; format[nformat]; nformat++);
|
for (nformat = 0; format[nformat]; nformat++);
|
||||||
|
|
||||||
ret = nv50_wndw_ctor(func, dev, type, name, index,
|
ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw,
|
||||||
&wndw->wndw, format, nformat, wndw);
|
format, nformat, NULL,
|
||||||
|
type, "%s-%d", name, index);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(*pwndw);
|
kfree(*pwndw);
|
||||||
*pwndw = NULL;
|
*pwndw = NULL;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper);
|
||||||
|
|
||||||
|
wndw->notify.func = nv50_wndw_notify;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -1339,53 +1304,36 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Primary plane
|
* Primary plane
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define nv50_base(p) container_of((p), struct nv50_base, wndw)
|
|
||||||
|
|
||||||
struct nv50_base {
|
|
||||||
struct nv50_wndw wndw;
|
|
||||||
struct nv50_sync chan;
|
|
||||||
int id;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
nv50_base_notify(struct nvif_notify *notify)
|
|
||||||
{
|
|
||||||
return NVIF_NOTIFY_KEEP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
nv50_base_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 2))) {
|
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||||
evo_mthd(push, 0x00e0, 1);
|
evo_mthd(push, 0x00e0, 1);
|
||||||
evo_data(push, asyw->lut.enable << 30);
|
evo_data(push, asyw->lut.enable << 30);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_image_clr(struct nv50_wndw *wndw)
|
nv50_base_image_clr(struct nv50_wndw *wndw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 4))) {
|
if ((push = evo_wait(&wndw->wndw, 4))) {
|
||||||
evo_mthd(push, 0x0084, 1);
|
evo_mthd(push, 0x0084, 1);
|
||||||
evo_data(push, 0x00000000);
|
evo_data(push, 0x00000000);
|
||||||
evo_mthd(push, 0x00c0, 1);
|
evo_mthd(push, 0x00c0, 1);
|
||||||
evo_data(push, 0x00000000);
|
evo_data(push, 0x00000000);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
const s32 oclass = wndw->wndw.base.user.oclass;
|
||||||
const s32 oclass = base->chan.base.base.user.oclass;
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 10))) {
|
if ((push = evo_wait(&wndw->wndw, 10))) {
|
||||||
evo_mthd(push, 0x0084, 1);
|
evo_mthd(push, 0x0084, 1);
|
||||||
evo_data(push, (asyw->image.mode << 8) |
|
evo_data(push, (asyw->image.mode << 8) |
|
||||||
(asyw->image.interval << 4));
|
(asyw->image.interval << 4));
|
||||||
|
@ -1421,77 +1369,72 @@ nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
asyw->image.block);
|
asyw->image.block);
|
||||||
evo_data(push, asyw->image.format << 8);
|
evo_data(push, asyw->image.format << 8);
|
||||||
}
|
}
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_ntfy_clr(struct nv50_wndw *wndw)
|
nv50_base_ntfy_clr(struct nv50_wndw *wndw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 2))) {
|
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||||
evo_mthd(push, 0x00a4, 1);
|
evo_mthd(push, 0x00a4, 1);
|
||||||
evo_data(push, 0x00000000);
|
evo_data(push, 0x00000000);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
nv50_base_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 3))) {
|
if ((push = evo_wait(&wndw->wndw, 3))) {
|
||||||
evo_mthd(push, 0x00a0, 2);
|
evo_mthd(push, 0x00a0, 2);
|
||||||
evo_data(push, (asyw->ntfy.awaken << 30) | asyw->ntfy.offset);
|
evo_data(push, (asyw->ntfy.awaken << 30) | asyw->ntfy.offset);
|
||||||
evo_data(push, asyw->ntfy.handle);
|
evo_data(push, asyw->ntfy.handle);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_sema_clr(struct nv50_wndw *wndw)
|
nv50_base_sema_clr(struct nv50_wndw *wndw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 2))) {
|
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||||
evo_mthd(push, 0x0094, 1);
|
evo_mthd(push, 0x0094, 1);
|
||||||
evo_data(push, 0x00000000);
|
evo_data(push, 0x00000000);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv50_base_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
nv50_base_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&base->chan, 5))) {
|
if ((push = evo_wait(&wndw->wndw, 5))) {
|
||||||
evo_mthd(push, 0x0088, 4);
|
evo_mthd(push, 0x0088, 4);
|
||||||
evo_data(push, asyw->sema.offset);
|
evo_data(push, asyw->sema.offset);
|
||||||
evo_data(push, asyw->sema.acquire);
|
evo_data(push, asyw->sema.acquire);
|
||||||
evo_data(push, asyw->sema.release);
|
evo_data(push, asyw->sema.release);
|
||||||
evo_data(push, asyw->sema.handle);
|
evo_data(push, asyw->sema.handle);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
nv50_base_update(struct nv50_wndw *wndw, u32 interlock)
|
nv50_base_update(struct nv50_wndw *wndw, u32 interlock)
|
||||||
{
|
{
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
u32 *push;
|
u32 *push;
|
||||||
|
|
||||||
if (!(push = evo_wait(&base->chan, 2)))
|
if (!(push = evo_wait(&wndw->wndw, 2)))
|
||||||
return 0;
|
return 0;
|
||||||
evo_mthd(push, 0x0080, 1);
|
evo_mthd(push, 0x0080, 1);
|
||||||
evo_data(push, interlock);
|
evo_data(push, interlock);
|
||||||
evo_kick(push, &base->chan);
|
evo_kick(push, &wndw->wndw);
|
||||||
|
|
||||||
if (base->chan.base.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA)
|
if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA)
|
||||||
return interlock ? 2 << (base->id * 8) : 0;
|
return interlock ? 2 << (wndw->id * 8) : 0;
|
||||||
return interlock ? 2 << (base->id * 4) : 0;
|
return interlock ? 2 << (wndw->id * 4) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1561,14 +1504,6 @@ nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
|
||||||
nv50_base_dtor(struct nv50_wndw *wndw)
|
|
||||||
{
|
|
||||||
struct nv50_base *base = nv50_base(wndw);
|
|
||||||
nv50_dmac_destroy(&base->chan.base);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const u32
|
static const u32
|
||||||
nv50_base_format[] = {
|
nv50_base_format[] = {
|
||||||
DRM_FORMAT_C8,
|
DRM_FORMAT_C8,
|
||||||
|
@ -1581,11 +1516,11 @@ nv50_base_format[] = {
|
||||||
DRM_FORMAT_ABGR2101010,
|
DRM_FORMAT_ABGR2101010,
|
||||||
DRM_FORMAT_XBGR8888,
|
DRM_FORMAT_XBGR8888,
|
||||||
DRM_FORMAT_ABGR8888,
|
DRM_FORMAT_ABGR8888,
|
||||||
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct nv50_wndw_func
|
static const struct nv50_wndw_func
|
||||||
nv50_base = {
|
nv50_base = {
|
||||||
.dtor = nv50_base_dtor,
|
|
||||||
.acquire = nv50_base_acquire,
|
.acquire = nv50_base_acquire,
|
||||||
.release = nv50_base_release,
|
.release = nv50_base_release,
|
||||||
.sema_set = nv50_base_sema_set,
|
.sema_set = nv50_base_sema_set,
|
||||||
|
@ -1600,41 +1535,79 @@ nv50_base = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_base_new(struct nouveau_drm *drm, struct nv50_head *head,
|
base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
|
||||||
struct nv50_base **pbase)
|
struct nouveau_drm *drm, int head, s32 oclass,
|
||||||
|
struct nv50_wndw **pwndw)
|
||||||
{
|
{
|
||||||
|
struct nv50_disp_base_channel_dma_v0 args = {
|
||||||
|
.head = head,
|
||||||
|
};
|
||||||
struct nv50_disp *disp = nv50_disp(drm->dev);
|
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||||
struct nv50_base *base;
|
struct nv50_wndw *wndw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!(base = *pbase = kzalloc(sizeof(*base), GFP_KERNEL)))
|
ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY,
|
||||||
return -ENOMEM;
|
"base", head, format, &wndw);
|
||||||
base->id = head->base.index;
|
if (*pwndw = wndw, ret)
|
||||||
base->wndw.ntfy = EVO_FLIP_NTFY0(base->id);
|
return ret;
|
||||||
base->wndw.sema = EVO_FLIP_SEM0(base->id);
|
|
||||||
base->wndw.data = 0x00000000;
|
|
||||||
|
|
||||||
ret = nv50_wndw_ctor(&nv50_base, drm->dev, DRM_PLANE_TYPE_PRIMARY,
|
ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
|
||||||
"base", base->id, &base->chan.base,
|
&oclass, head, &args, sizeof(args),
|
||||||
nv50_base_format, ARRAY_SIZE(nv50_base_format),
|
disp->sync->bo.offset, &wndw->wndw);
|
||||||
&base->wndw);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(base);
|
NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nv50_base_create(&drm->client.device, &disp->disp->object,
|
ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func,
|
||||||
base->id, disp->sync->bo.offset, &base->chan);
|
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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return nvif_notify_init(&base->chan.base.base.user, nv50_base_notify,
|
wndw->ntfy = EVO_FLIP_NTFY0(wndw->id);
|
||||||
false,
|
wndw->sema = EVO_FLIP_SEM0(wndw->id);
|
||||||
NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT,
|
wndw->data = 0x00000000;
|
||||||
&(struct nvif_notify_uevent_req) {},
|
return 0;
|
||||||
sizeof(struct nvif_notify_uevent_req),
|
}
|
||||||
sizeof(struct nvif_notify_uevent_rep),
|
|
||||||
&base->wndw.notify);
|
static int
|
||||||
|
base507c_new(struct nouveau_drm *drm, int head, s32 oclass,
|
||||||
|
struct nv50_wndw **pwndw)
|
||||||
|
{
|
||||||
|
return base507c_new_(&nv50_base, nv50_base_format, drm, head, oclass, pwndw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
s32 oclass;
|
||||||
|
int version;
|
||||||
|
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
|
} bases[] = {
|
||||||
|
{ GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{ GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{ GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{ GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{ GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{ G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{ NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||||
|
int cid;
|
||||||
|
|
||||||
|
cid = nvif_mclass(&disp->disp->object, bases);
|
||||||
|
if (cid < 0) {
|
||||||
|
NV_ERROR(drm, "No supported base class\n");
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bases[cid].new(drm, head, bases[cid].oclass, pwndw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -2471,7 +2444,6 @@ nv50_head_create(struct drm_device *dev, int index)
|
||||||
{
|
{
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nv50_head *head;
|
struct nv50_head *head;
|
||||||
struct nv50_base *base;
|
|
||||||
struct nv50_wndw *curs, *wndw;
|
struct nv50_wndw *curs, *wndw;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
@ -2481,7 +2453,7 @@ nv50_head_create(struct drm_device *dev, int index)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
head->base.index = index;
|
head->base.index = index;
|
||||||
ret = nv50_base_new(drm, head, &base);
|
ret = nv50_base_new(drm, head->base.index, &wndw);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = nv50_curs_new(drm, head->base.index, &curs);
|
ret = nv50_curs_new(drm, head->base.index, &curs);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -2490,7 +2462,7 @@ nv50_head_create(struct drm_device *dev, int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
crtc = &head->base.base;
|
crtc = &head->base.base;
|
||||||
drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, &curs->plane,
|
drm_crtc_init_with_planes(dev, crtc, &wndw->plane, &curs->plane,
|
||||||
&nv50_head_func, "head-%d", head->base.index);
|
&nv50_head_func, "head-%d", head->base.index);
|
||||||
drm_crtc_helper_add(crtc, &nv50_head_help);
|
drm_crtc_helper_add(crtc, &nv50_head_help);
|
||||||
drm_mode_crtc_set_gamma_size(crtc, 256);
|
drm_mode_crtc_set_gamma_size(crtc, 256);
|
||||||
|
@ -4256,7 +4228,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
|
||||||
struct nv50_wndw *wndw = nv50_wndw(plane);
|
struct nv50_wndw *wndw = nv50_wndw(plane);
|
||||||
|
|
||||||
if (asyw->set.image) {
|
if (asyw->set.image) {
|
||||||
asyw->ntfy.handle = wndw->dmac->sync.handle;
|
asyw->ntfy.handle = wndw->wndw.sync.handle;
|
||||||
asyw->ntfy.offset = wndw->ntfy;
|
asyw->ntfy.offset = wndw->ntfy;
|
||||||
asyw->ntfy.awaken = false;
|
asyw->ntfy.awaken = false;
|
||||||
asyw->set.ntfy = true;
|
asyw->set.ntfy = true;
|
||||||
|
|
Loading…
Reference in New Issue