mirror of https://gitee.com/openkylin/linux.git
drm/nouveau/kms/gv100: initial support
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
290ffeafcc
commit
facaed62b4
|
@ -6,6 +6,7 @@ nouveau-y += dispnv50/core507d.o
|
|||
nouveau-y += dispnv50/core827d.o
|
||||
nouveau-y += dispnv50/core907d.o
|
||||
nouveau-y += dispnv50/core917d.o
|
||||
nouveau-y += dispnv50/corec37d.o
|
||||
|
||||
nouveau-y += dispnv50/dac507d.o
|
||||
nouveau-y += dispnv50/dac907d.o
|
||||
|
@ -14,14 +15,20 @@ nouveau-y += dispnv50/pior507d.o
|
|||
|
||||
nouveau-y += dispnv50/sor507d.o
|
||||
nouveau-y += dispnv50/sor907d.o
|
||||
nouveau-y += dispnv50/sorc37d.o
|
||||
|
||||
nouveau-y += dispnv50/head.o
|
||||
nouveau-y += dispnv50/head507d.o
|
||||
nouveau-y += dispnv50/head827d.o
|
||||
nouveau-y += dispnv50/head907d.o
|
||||
nouveau-y += dispnv50/head917d.o
|
||||
nouveau-y += dispnv50/headc37d.o
|
||||
|
||||
nouveau-y += dispnv50/wimm.o
|
||||
nouveau-y += dispnv50/wimmc37b.o
|
||||
|
||||
nouveau-y += dispnv50/wndw.o
|
||||
nouveau-y += dispnv50/wndwc37e.o
|
||||
|
||||
nouveau-y += dispnv50/base.o
|
||||
nouveau-y += dispnv50/base507c.o
|
||||
|
@ -32,6 +39,7 @@ nouveau-y += dispnv50/base917c.o
|
|||
nouveau-y += dispnv50/curs.o
|
||||
nouveau-y += dispnv50/curs507a.o
|
||||
nouveau-y += dispnv50/curs907a.o
|
||||
nouveau-y += dispnv50/cursc37a.o
|
||||
|
||||
nouveau-y += dispnv50/oimm.o
|
||||
nouveau-y += dispnv50/oimm507b.o
|
||||
|
|
|
@ -54,6 +54,9 @@ struct nv50_head_atom {
|
|||
u64 offset:40;
|
||||
u8 buffer:1;
|
||||
u8 mode:4;
|
||||
u8 size:2;
|
||||
u8 range:2;
|
||||
u8 output_mode:2;
|
||||
} olut;
|
||||
|
||||
struct {
|
||||
|
@ -77,7 +80,7 @@ struct nv50_head_atom {
|
|||
u32 handle;
|
||||
u64 offset:40;
|
||||
u8 layout:2;
|
||||
u8 format:1;
|
||||
u8 format:8;
|
||||
} curs;
|
||||
|
||||
struct {
|
||||
|
@ -166,6 +169,9 @@ struct nv50_wndw_atom {
|
|||
u8 buffer:1;
|
||||
u8 enable:2;
|
||||
u8 mode:4;
|
||||
u8 size:2;
|
||||
u8 range:2;
|
||||
u8 output_mode:2;
|
||||
} i;
|
||||
} xlut;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore)
|
|||
int version;
|
||||
int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
} cores[] = {
|
||||
{ GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new },
|
||||
{ GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||
{ GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||
{ GM200_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||
|
|
|
@ -44,4 +44,7 @@ extern const struct nv50_outp_func dac907d;
|
|||
extern const struct nv50_outp_func sor907d;
|
||||
|
||||
int core917d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
|
||||
int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
extern const struct nv50_outp_func sorc37d;
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "core.h"
|
||||
#include "head.h"
|
||||
|
||||
#include <nouveau_bo.h>
|
||||
|
||||
static void
|
||||
corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&core->chan, 9))) {
|
||||
if (ntfy) {
|
||||
evo_mthd(push, 0x020c, 1);
|
||||
evo_data(push, 0x00001000 | NV50_DISP_CORE_NTFY);
|
||||
}
|
||||
|
||||
evo_mthd(push, 0x0218, 2);
|
||||
evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS]);
|
||||
evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]);
|
||||
evo_mthd(push, 0x0200, 1);
|
||||
evo_data(push, 0x00000001);
|
||||
|
||||
if (ntfy) {
|
||||
evo_mthd(push, 0x020c, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
}
|
||||
evo_kick(push, &core->chan);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
|
||||
struct nvif_device *device)
|
||||
{
|
||||
u32 data;
|
||||
s64 time = nvif_msec(device, 2000ULL,
|
||||
data = nouveau_bo_rd32(bo, offset / 4 + 0);
|
||||
if ((data & 0xc0000000) == 0x80000000)
|
||||
break;
|
||||
usleep_range(1, 2);
|
||||
);
|
||||
return time < 0 ? time : 0;
|
||||
}
|
||||
|
||||
void
|
||||
corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset)
|
||||
{
|
||||
nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000);
|
||||
nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000);
|
||||
nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000);
|
||||
nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000);
|
||||
}
|
||||
|
||||
void
|
||||
corec37d_init(struct nv50_core *core)
|
||||
{
|
||||
const u32 windows = 8; /*XXX*/
|
||||
u32 *push, i;
|
||||
if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) {
|
||||
evo_mthd(push, 0x0208, 1);
|
||||
evo_data(push, core->chan.sync.handle);
|
||||
for (i = 0; i < windows; i++) {
|
||||
evo_mthd(push, 0x1000 + (i * 0x080), 3);
|
||||
evo_data(push, i >> 1);
|
||||
evo_data(push, 0x00000017);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_mthd(push, 0x1010 + (i * 0x080), 1);
|
||||
evo_data(push, 0x00127fff);
|
||||
}
|
||||
evo_mthd(push, 0x0200, 1);
|
||||
evo_data(push, 0x00000001);
|
||||
evo_kick(push, &core->chan);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct nv50_core_func
|
||||
corec37d = {
|
||||
.init = corec37d_init,
|
||||
.ntfy_init = corec37d_ntfy_init,
|
||||
.ntfy_wait_done = corec37d_ntfy_wait_done,
|
||||
.update = corec37d_update,
|
||||
.head = &headc37d,
|
||||
.sor = &sorc37d,
|
||||
};
|
||||
|
||||
int
|
||||
corec37d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
|
||||
{
|
||||
return core507d_new_(&corec37d, drm, oclass, pcore);
|
||||
}
|
|
@ -31,6 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
|
|||
int version;
|
||||
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||
} curses[] = {
|
||||
{ GV100_DISP_CURSOR, 0, cursc37a_new },
|
||||
{ GK104_DISP_CURSOR, 0, curs907a_new },
|
||||
{ GF110_DISP_CURSOR, 0, curs907a_new },
|
||||
{ GT214_DISP_CURSOR, 0, curs507a_new },
|
||||
|
|
|
@ -8,6 +8,7 @@ int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *,
|
|||
struct nv50_wndw **);
|
||||
|
||||
int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||
int cursc37a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||
|
||||
int nv50_curs_new(struct nouveau_drm *, int head, struct nv50_wndw **);
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "curs.h"
|
||||
#include "atom.h"
|
||||
|
||||
static void
|
||||
cursc37a_update(struct nv50_wndw *wndw, u32 *interlock)
|
||||
{
|
||||
nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001);
|
||||
}
|
||||
|
||||
static void
|
||||
cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 |
|
||||
asyw->point.x);
|
||||
}
|
||||
|
||||
static const struct nv50_wimm_func
|
||||
cursc37a = {
|
||||
.point = cursc37a_point,
|
||||
.update = cursc37a_update,
|
||||
};
|
||||
|
||||
int
|
||||
cursc37a_new(struct nouveau_drm *drm, int head, s32 oclass,
|
||||
struct nv50_wndw **pwndw)
|
||||
{
|
||||
return curs507a_new_(&cursc37a, drm, head, oclass,
|
||||
0x00000001 << head, pwndw);
|
||||
}
|
|
@ -154,6 +154,9 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!syncbuf)
|
||||
return 0;
|
||||
|
||||
ret = nvif_object_init(&dmac->base.user, 0xf0000000, NV_DMA_IN_MEMORY,
|
||||
&(struct nv_dma_v0) {
|
||||
.target = NV_DMA_V0_TARGET_VRAM,
|
||||
|
@ -2170,6 +2173,9 @@ nv50_display_create(struct drm_device *dev)
|
|||
goto out;
|
||||
|
||||
/* create crtc objects to represent the hw heads */
|
||||
if (disp->disp->object.oclass >= GV100_DISP)
|
||||
crtcs = nvif_rd32(&device->object, 0x610060) & 0xff;
|
||||
else
|
||||
if (disp->disp->object.oclass >= GF110_DISP)
|
||||
crtcs = nvif_rd32(&device->object, 0x612004) & 0xf;
|
||||
else
|
||||
|
|
|
@ -36,11 +36,15 @@ struct nv50_disp_interlock {
|
|||
NV50_DISP_INTERLOCK_CURS,
|
||||
NV50_DISP_INTERLOCK_BASE,
|
||||
NV50_DISP_INTERLOCK_OVLY,
|
||||
NV50_DISP_INTERLOCK_WNDW,
|
||||
NV50_DISP_INTERLOCK_WIMM,
|
||||
NV50_DISP_INTERLOCK__SIZE
|
||||
} type;
|
||||
u32 data;
|
||||
};
|
||||
|
||||
void corec37d_ntfy_init(struct nouveau_bo *, u32);
|
||||
|
||||
struct nv50_chan {
|
||||
struct nvif_object user;
|
||||
struct nvif_device *device;
|
||||
|
|
|
@ -475,7 +475,16 @@ nv50_head_create(struct drm_device *dev, int index)
|
|||
|
||||
head->func = disp->core->func->head;
|
||||
head->base.index = index;
|
||||
ret = nv50_base_new(drm, head->base.index, &wndw);
|
||||
|
||||
if (disp->disp->object.oclass < GV100_DISP) {
|
||||
ret = nv50_ovly_new(drm, head->base.index, &wndw);
|
||||
ret = nv50_base_new(drm, head->base.index, &wndw);
|
||||
} else {
|
||||
ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_OVERLAY,
|
||||
head->base.index * 2 + 1, &wndw);
|
||||
ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_PRIMARY,
|
||||
head->base.index * 2 + 0, &wndw);
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = nv50_curs_new(drm, head->base.index, &curs);
|
||||
if (ret) {
|
||||
|
@ -495,8 +504,6 @@ nv50_head_create(struct drm_device *dev, int index)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* allocate overlay resources */
|
||||
ret = nv50_ovly_new(drm, head->base.index, &wndw);
|
||||
out:
|
||||
if (ret)
|
||||
nv50_head_destroy(crtc);
|
||||
|
|
|
@ -71,4 +71,8 @@ void head907d_procamp(struct nv50_head *, struct nv50_head_atom *);
|
|||
void head907d_or(struct nv50_head *, struct nv50_head_atom *);
|
||||
|
||||
extern const struct nv50_head_func head917d;
|
||||
int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
|
||||
struct nv50_head_atom *);
|
||||
|
||||
extern const struct nv50_head_func headc37d;
|
||||
#endif
|
||||
|
|
|
@ -63,7 +63,7 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "head.h"
|
||||
#include "atom.h"
|
||||
#include "core.h"
|
||||
|
||||
static void
|
||||
headc37d_or(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
/*XXX: This is a dirty hack until OR depth handling is
|
||||
* improved later for deep colour etc.
|
||||
*/
|
||||
switch (asyh->or.depth) {
|
||||
case 6: asyh->or.depth = 5; break;
|
||||
case 5: asyh->or.depth = 4; break;
|
||||
case 2: asyh->or.depth = 1; break;
|
||||
case 0: asyh->or.depth = 4; break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
|
||||
evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0x00000001 |
|
||||
asyh->or.depth << 4 |
|
||||
asyh->or.nvsync << 3 |
|
||||
asyh->or.nhsync << 2);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0x80000000 |
|
||||
asyh->procamp.sat.sin << 16 |
|
||||
asyh->procamp.sat.cos << 4);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
evo_mthd(push, 0x2018 + (head->base.index * 0x0400), 1);
|
||||
evo_data(push, asyh->dither.mode << 8 |
|
||||
asyh->dither.bits << 4 |
|
||||
asyh->dither.enable);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_curs_clr(struct nv50_head *head)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 4))) {
|
||||
evo_mthd(push, 0x209c + head->base.index * 0x400, 1);
|
||||
evo_data(push, 0x000000cf);
|
||||
evo_mthd(push, 0x2088 + head->base.index * 0x400, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 7))) {
|
||||
evo_mthd(push, 0x209c + head->base.index * 0x400, 2);
|
||||
evo_data(push, 0x80000000 |
|
||||
asyh->curs.layout << 8 |
|
||||
asyh->curs.format << 0);
|
||||
evo_data(push, 0x000072ff);
|
||||
evo_mthd(push, 0x2088 + head->base.index * 0x400, 1);
|
||||
evo_data(push, asyh->curs.handle);
|
||||
evo_mthd(push, 0x2090 + head->base.index * 0x400, 1);
|
||||
evo_data(push, asyh->curs.offset >> 8);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
headc37d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
asyh->curs.format = asyw->image.format;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_olut_clr(struct nv50_head *head)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
evo_mthd(push, 0x20ac + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 4))) {
|
||||
evo_mthd(push, 0x20a4 + (head->base.index * 0x400), 3);
|
||||
evo_data(push, asyh->olut.output_mode << 8 |
|
||||
asyh->olut.range << 4 |
|
||||
asyh->olut.size);
|
||||
evo_data(push, asyh->olut.offset >> 8);
|
||||
evo_data(push, asyh->olut.handle);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
asyh->olut.mode = 2;
|
||||
asyh->olut.size = 0;
|
||||
asyh->olut.range = 0;
|
||||
asyh->olut.output_mode = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
struct nv50_head_mode *m = &asyh->mode;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 12))) {
|
||||
evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5);
|
||||
evo_data(push, (m->v.active << 16) | m->h.active );
|
||||
evo_data(push, (m->v.synce << 16) | m->h.synce );
|
||||
evo_data(push, (m->v.blanke << 16) | m->h.blanke );
|
||||
evo_data(push, (m->v.blanks << 16) | m->h.blanks );
|
||||
evo_data(push, (m->v.blank2e << 16) | m->v.blank2s);
|
||||
evo_mthd(push, 0x200c + (head->base.index * 0x400), 1);
|
||||
evo_data(push, m->clock * 1000);
|
||||
evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, m->clock * 1000);
|
||||
/*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */
|
||||
evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0x00000124);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc37d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 4))) {
|
||||
evo_mthd(push, 0x204c + (head->base.index * 0x400), 1);
|
||||
evo_data(push, (asyh->view.iH << 16) | asyh->view.iW);
|
||||
evo_mthd(push, 0x2058 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, (asyh->view.oH << 16) | asyh->view.oW);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
const struct nv50_head_func
|
||||
headc37d = {
|
||||
.view = headc37d_view,
|
||||
.mode = headc37d_mode,
|
||||
.olut = headc37d_olut,
|
||||
.olut_set = headc37d_olut_set,
|
||||
.olut_clr = headc37d_olut_clr,
|
||||
.curs_layout = head917d_curs_layout,
|
||||
.curs_format = headc37d_curs_format,
|
||||
.curs_set = headc37d_curs_set,
|
||||
.curs_clr = headc37d_curs_clr,
|
||||
.dither = headc37d_dither,
|
||||
.procamp = headc37d_procamp,
|
||||
.or = headc37d_or,
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "core.h"
|
||||
|
||||
static void
|
||||
sorc37d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&core->chan, 2))) {
|
||||
evo_mthd(push, 0x0300 + (or * 0x20), 1);
|
||||
evo_data(push, ctrl);
|
||||
evo_kick(push, &core->chan);
|
||||
}
|
||||
}
|
||||
|
||||
const struct nv50_outp_func
|
||||
sorc37d = {
|
||||
.ctrl = sorc37d_ctrl,
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "wimm.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
int
|
||||
nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw)
|
||||
{
|
||||
struct {
|
||||
s32 oclass;
|
||||
int version;
|
||||
int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *);
|
||||
} wimms[] = {
|
||||
{ GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init },
|
||||
{}
|
||||
};
|
||||
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||
int cid;
|
||||
|
||||
cid = nvif_mclass(&disp->disp->object, wimms);
|
||||
if (cid < 0) {
|
||||
NV_ERROR(drm, "No supported window immediate class\n");
|
||||
return cid;
|
||||
}
|
||||
|
||||
return wimms[cid].init(drm, wimms[cid].oclass, wndw);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef __NV50_KMS_WIMM_H__
|
||||
#define __NV50_KMS_WIMM_H__
|
||||
#include "wndw.h"
|
||||
|
||||
int nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *);
|
||||
|
||||
int wimmc37b_init(struct nouveau_drm *, s32, struct nv50_wndw *);
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "wimm.h"
|
||||
#include "atom.h"
|
||||
#include "wndw.h"
|
||||
|
||||
#include <nvif/clc37b.h>
|
||||
|
||||
static void
|
||||
wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wimm, 2))) {
|
||||
evo_mthd(push, 0x0200, 1);
|
||||
if (interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data)
|
||||
evo_data(push, 0x00000003);
|
||||
else
|
||||
evo_data(push, 0x00000001);
|
||||
evo_kick(push, &wndw->wimm);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wimmc37b_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wimm, 2))) {
|
||||
evo_mthd(push, 0x0208, 1);
|
||||
evo_data(push, asyw->point.y << 16 | asyw->point.x);
|
||||
evo_kick(push, &wndw->wimm);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct nv50_wimm_func
|
||||
wimmc37b = {
|
||||
.point = wimmc37b_point,
|
||||
.update = wimmc37b_update,
|
||||
};
|
||||
|
||||
static int
|
||||
wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
|
||||
s32 oclass, struct nv50_wndw *wndw)
|
||||
{
|
||||
struct nvc37b_window_imm_channel_dma_v0 args = {
|
||||
.pushbuf = 0xb0007b00 | wndw->id,
|
||||
.index = wndw->id,
|
||||
};
|
||||
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||
int ret;
|
||||
|
||||
ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
|
||||
&oclass, 0, &args, sizeof(args), 0,
|
||||
&wndw->wimm);
|
||||
if (ret) {
|
||||
NV_ERROR(drm, "wimm%04x allocation failed: %d\n", oclass, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wndw->immd = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wimmc37b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw)
|
||||
{
|
||||
return wimmc37b_init_(&wimmc37b, drm, oclass, wndw);
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "wndw.h"
|
||||
#include "wimm.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
#include <nvif/cl0002.h>
|
||||
|
@ -148,11 +149,15 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
|
|||
|
||||
if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
|
||||
if (asyw->set.point) {
|
||||
if (asyw->set.point = false, asyw->set.mask)
|
||||
interlock[wndw->interlock.type] |= wndw->interlock.data;
|
||||
interlock[NV50_DISP_INTERLOCK_WIMM] |= wndw->interlock.data;
|
||||
|
||||
wndw->immd->point(wndw, asyw);
|
||||
wndw->immd->update(wndw, interlock);
|
||||
} else {
|
||||
interlock[wndw->interlock.type] |= wndw->interlock.data;
|
||||
}
|
||||
|
||||
interlock[wndw->interlock.type] |= wndw->interlock.data;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -605,3 +610,32 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
|
|||
wndw->notify.func = nv50_wndw_notify;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
|
||||
struct nv50_wndw **pwndw)
|
||||
{
|
||||
struct {
|
||||
s32 oclass;
|
||||
int version;
|
||||
int (*new)(struct nouveau_drm *, enum drm_plane_type,
|
||||
int, s32, struct nv50_wndw **);
|
||||
} wndws[] = {
|
||||
{ GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new },
|
||||
{}
|
||||
};
|
||||
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||
int cid, ret;
|
||||
|
||||
cid = nvif_mclass(&disp->disp->object, wndws);
|
||||
if (cid < 0) {
|
||||
NV_ERROR(drm, "No supported window class\n");
|
||||
return cid;
|
||||
}
|
||||
|
||||
ret = wndws[cid].new(drm, type, index, wndws[cid].oclass, pwndw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return nv50_wimm_init(drm, *pwndw);
|
||||
}
|
||||
|
|
|
@ -87,4 +87,10 @@ struct nv50_wimm_func {
|
|||
};
|
||||
|
||||
extern const struct nv50_wimm_func curs507a;
|
||||
|
||||
int wndwc37e_new(struct nouveau_drm *, enum drm_plane_type, int, s32,
|
||||
struct nv50_wndw **);
|
||||
|
||||
int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index,
|
||||
struct nv50_wndw **);
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "wndw.h"
|
||||
#include "atom.h"
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <nouveau_bo.h>
|
||||
|
||||
#include <nvif/clc37e.h>
|
||||
|
||||
static void
|
||||
wndwc37e_ilut_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||
evo_mthd(push, 0x02b8, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 4))) {
|
||||
evo_mthd(push, 0x02b0, 3);
|
||||
evo_data(push, asyw->xlut.i.output_mode << 8 |
|
||||
asyw->xlut.i.range << 4 |
|
||||
asyw->xlut.i.size);
|
||||
evo_data(push, asyw->xlut.i.offset >> 8);
|
||||
evo_data(push, asyw->xlut.handle);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
asyw->xlut.i.mode = 2;
|
||||
asyw->xlut.i.size = 0;
|
||||
asyw->xlut.i.range = 0;
|
||||
asyw->xlut.i.output_mode = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_image_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 4))) {
|
||||
evo_mthd(push, 0x0308, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_mthd(push, 0x0240, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
|
||||
if (!(push = evo_wait(&wndw->wndw, 25)))
|
||||
return;
|
||||
|
||||
evo_mthd(push, 0x0308, 1);
|
||||
evo_data(push, asyw->image.mode << 4 | asyw->image.interval);
|
||||
evo_mthd(push, 0x0224, 4);
|
||||
evo_data(push, asyw->image.h << 16 | asyw->image.w);
|
||||
evo_data(push, asyw->image.layout << 4 | asyw->image.blockh);
|
||||
evo_data(push, asyw->image.colorspace << 8 | asyw->image.format);
|
||||
evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6));
|
||||
evo_mthd(push, 0x0240, 1);
|
||||
evo_data(push, asyw->image.handle[0]);
|
||||
evo_mthd(push, 0x0260, 1);
|
||||
evo_data(push, asyw->image.offset[0] >> 8);
|
||||
evo_mthd(push, 0x0290, 1);
|
||||
evo_data(push, (asyw->state.src_y >> 16) << 16 |
|
||||
(asyw->state.src_x >> 16));
|
||||
evo_mthd(push, 0x0298, 1);
|
||||
evo_data(push, (asyw->state.src_h >> 16) << 16 |
|
||||
(asyw->state.src_w >> 16));
|
||||
evo_mthd(push, 0x02a4, 1);
|
||||
evo_data(push, asyw->state.crtc_h << 16 |
|
||||
asyw->state.crtc_w);
|
||||
|
||||
/*XXX: Composition-related stuff. Need to implement properly. */
|
||||
evo_mthd(push, 0x02ec, 1);
|
||||
evo_data(push, (2 - (wndw->id & 1)) << 4);
|
||||
evo_mthd(push, 0x02f4, 5);
|
||||
evo_data(push, 0x00000011);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_ntfy_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||
evo_mthd(push, 0x021c, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 3))) {
|
||||
evo_mthd(push, 0x021c, 2);
|
||||
evo_data(push, asyw->ntfy.handle);
|
||||
evo_data(push, asyw->ntfy.offset | asyw->ntfy.awaken);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_sema_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||
evo_mthd(push, 0x0218, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 5))) {
|
||||
evo_mthd(push, 0x020c, 4);
|
||||
evo_data(push, asyw->sema.offset);
|
||||
evo_data(push, asyw->sema.acquire);
|
||||
evo_data(push, asyw->sema.release);
|
||||
evo_data(push, asyw->sema.handle);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 5))) {
|
||||
evo_mthd(push, 0x0370, 2);
|
||||
evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS] << 1 |
|
||||
interlock[NV50_DISP_INTERLOCK_CORE]);
|
||||
evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]);
|
||||
evo_mthd(push, 0x0200, 1);
|
||||
if (interlock[NV50_DISP_INTERLOCK_WIMM] & wndw->interlock.data)
|
||||
evo_data(push, 0x00001001);
|
||||
else
|
||||
evo_data(push, 0x00000001);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
wndwc37e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
return drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
true, true);
|
||||
}
|
||||
|
||||
static const u32
|
||||
wndwc37e_format[] = {
|
||||
DRM_FORMAT_C8,
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_ARGB1555,
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
0
|
||||
};
|
||||
|
||||
static const struct nv50_wndw_func
|
||||
wndwc37e = {
|
||||
.acquire = wndwc37e_acquire,
|
||||
.release = wndwc37e_release,
|
||||
.sema_set = wndwc37e_sema_set,
|
||||
.sema_clr = wndwc37e_sema_clr,
|
||||
.ntfy_set = wndwc37e_ntfy_set,
|
||||
.ntfy_clr = wndwc37e_ntfy_clr,
|
||||
.ntfy_reset = corec37d_ntfy_init,
|
||||
.ntfy_wait_begun = base507c_ntfy_wait_begun,
|
||||
.ilut = wndwc37e_ilut,
|
||||
.xlut_set = wndwc37e_ilut_set,
|
||||
.xlut_clr = wndwc37e_ilut_clr,
|
||||
.image_set = wndwc37e_image_set,
|
||||
.image_clr = wndwc37e_image_clr,
|
||||
.update = wndwc37e_update,
|
||||
};
|
||||
|
||||
static int
|
||||
wndwc37e_new_(const struct nv50_wndw_func *func, struct nouveau_drm *drm,
|
||||
enum drm_plane_type type, int index, s32 oclass, u32 heads,
|
||||
struct nv50_wndw **pwndw)
|
||||
{
|
||||
struct nvc37e_window_channel_dma_v0 args = {
|
||||
.pushbuf = 0xb0007e00 | index,
|
||||
.index = index,
|
||||
};
|
||||
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||
struct nv50_wndw *wndw;
|
||||
int ret;
|
||||
|
||||
ret = nv50_wndw_new_(func, drm->dev, type, "wndw", index,
|
||||
wndwc37e_format, heads, NV50_DISP_INTERLOCK_WNDW,
|
||||
BIT(index), &wndw);
|
||||
if (*pwndw = wndw, ret)
|
||||
return ret;
|
||||
|
||||
ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
|
||||
&oclass, 0, &args, sizeof(args),
|
||||
disp->sync->bo.offset, &wndw->wndw);
|
||||
if (ret) {
|
||||
NV_ERROR(drm, "qndw%04x allocation failed: %d\n", oclass, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wndw->ntfy = NV50_DISP_WNDW_NTFY(wndw->id);
|
||||
wndw->sema = NV50_DISP_WNDW_SEM0(wndw->id);
|
||||
wndw->data = 0x00000000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wndwc37e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
|
||||
s32 oclass, struct nv50_wndw **pwndw)
|
||||
{
|
||||
return wndwc37e_new_(&wndwc37e, drm, type, index, oclass,
|
||||
BIT(index >> 1), pwndw);
|
||||
}
|
Loading…
Reference in New Issue