forked from Minki/linux
drm/nouveau/kms/nv50-: split core implementation by hardware class
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
1590700d94
commit
09e1b78aab
@ -2,15 +2,23 @@ nouveau-y += dispnv50/disp.o
|
|||||||
|
|
||||||
nouveau-y += dispnv50/core.o
|
nouveau-y += dispnv50/core.o
|
||||||
nouveau-y += dispnv50/core507d.o
|
nouveau-y += dispnv50/core507d.o
|
||||||
|
nouveau-y += dispnv50/core827d.o
|
||||||
|
nouveau-y += dispnv50/core907d.o
|
||||||
|
nouveau-y += dispnv50/core917d.o
|
||||||
|
|
||||||
nouveau-y += dispnv50/dac507d.o
|
nouveau-y += dispnv50/dac507d.o
|
||||||
|
nouveau-y += dispnv50/dac907d.o
|
||||||
|
|
||||||
nouveau-y += dispnv50/pior507d.o
|
nouveau-y += dispnv50/pior507d.o
|
||||||
|
|
||||||
nouveau-y += dispnv50/sor507d.o
|
nouveau-y += dispnv50/sor507d.o
|
||||||
|
nouveau-y += dispnv50/sor907d.o
|
||||||
|
|
||||||
nouveau-y += dispnv50/head.o
|
nouveau-y += dispnv50/head.o
|
||||||
nouveau-y += dispnv50/head507d.o
|
nouveau-y += dispnv50/head507d.o
|
||||||
|
nouveau-y += dispnv50/head827d.o
|
||||||
|
nouveau-y += dispnv50/head907d.o
|
||||||
|
nouveau-y += dispnv50/head917d.o
|
||||||
|
|
||||||
nouveau-y += dispnv50/wndw.o
|
nouveau-y += dispnv50/wndw.o
|
||||||
|
|
||||||
|
@ -42,17 +42,17 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore)
|
|||||||
int version;
|
int version;
|
||||||
int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
|
int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
|
||||||
} cores[] = {
|
} cores[] = {
|
||||||
{ GP102_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||||
{ GP100_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||||
{ GM200_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GM200_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||||
{ GM107_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GM107_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||||
{ GK110_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GK110_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||||
{ GK104_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GK104_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||||
{ GF110_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GF110_DISP_CORE_CHANNEL_DMA, 0, core907d_new },
|
||||||
{ GT214_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GT214_DISP_CORE_CHANNEL_DMA, 0, core827d_new },
|
||||||
{ GT206_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GT206_DISP_CORE_CHANNEL_DMA, 0, core827d_new },
|
||||||
{ GT200_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ GT200_DISP_CORE_CHANNEL_DMA, 0, core827d_new },
|
||||||
{ G82_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ G82_DISP_CORE_CHANNEL_DMA, 0, core827d_new },
|
||||||
{ NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
{ NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,12 @@ int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
|
|||||||
void nv50_core_del(struct nv50_core **);
|
void nv50_core_del(struct nv50_core **);
|
||||||
|
|
||||||
struct nv50_core_func {
|
struct nv50_core_func {
|
||||||
|
void (*init)(struct nv50_core *);
|
||||||
|
void (*ntfy_init)(struct nouveau_bo *, u32 offset);
|
||||||
|
int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset,
|
||||||
|
struct nvif_device *);
|
||||||
|
void (*update)(struct nv50_core *, u32 interlock, bool ntfy);
|
||||||
|
|
||||||
const struct nv50_head_func *head;
|
const struct nv50_head_func *head;
|
||||||
const struct nv50_outp_func {
|
const struct nv50_outp_func {
|
||||||
void (*ctrl)(struct nv50_core *, int or, u32 ctrl,
|
void (*ctrl)(struct nv50_core *, int or, u32 ctrl,
|
||||||
@ -20,7 +26,21 @@ struct nv50_core_func {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int core507d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
int core507d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||||
|
int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32,
|
||||||
|
struct nv50_core **);
|
||||||
|
void core507d_init(struct nv50_core *);
|
||||||
|
void core507d_ntfy_init(struct nouveau_bo *, u32);
|
||||||
|
int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
|
||||||
|
void core507d_update(struct nv50_core *, u32, bool);
|
||||||
extern const struct nv50_outp_func dac507d;
|
extern const struct nv50_outp_func dac507d;
|
||||||
extern const struct nv50_outp_func sor507d;
|
extern const struct nv50_outp_func sor507d;
|
||||||
extern const struct nv50_outp_func pior507d;
|
extern const struct nv50_outp_func pior507d;
|
||||||
|
|
||||||
|
int core827d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||||
|
|
||||||
|
int core907d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||||
|
extern const struct nv50_outp_func dac907d;
|
||||||
|
extern const struct nv50_outp_func sor907d;
|
||||||
|
|
||||||
|
int core917d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,15 +26,64 @@
|
|||||||
|
|
||||||
#include "nouveau_bo.h"
|
#include "nouveau_bo.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
core507d_update(struct nv50_core *core, u32 interlock, bool ntfy)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&core->chan, 5))) {
|
||||||
|
if (ntfy) {
|
||||||
|
evo_mthd(push, 0x0084, 1);
|
||||||
|
evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY);
|
||||||
|
}
|
||||||
|
evo_mthd(push, 0x0080, 2);
|
||||||
|
evo_data(push, interlock);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, &core->chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
|
||||||
|
struct nvif_device *device)
|
||||||
|
{
|
||||||
|
s64 time = nvif_msec(device, 2000ULL,
|
||||||
|
if (nouveau_bo_rd32(bo, offset / 4))
|
||||||
|
break;
|
||||||
|
usleep_range(1, 2);
|
||||||
|
);
|
||||||
|
return time < 0 ? time : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
core507d_ntfy_init(struct nouveau_bo *bo, u32 offset)
|
||||||
|
{
|
||||||
|
nouveau_bo_wr32(bo, offset / 4, 0x00000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
core507d_init(struct nv50_core *core)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&core->chan, 2))) {
|
||||||
|
evo_mthd(push, 0x0088, 1);
|
||||||
|
evo_data(push, core->chan.sync.handle);
|
||||||
|
evo_kick(push, &core->chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct nv50_core_func
|
static const struct nv50_core_func
|
||||||
core507d = {
|
core507d = {
|
||||||
|
.init = core507d_init,
|
||||||
|
.ntfy_init = core507d_ntfy_init,
|
||||||
|
.ntfy_wait_done = core507d_ntfy_wait_done,
|
||||||
|
.update = core507d_update,
|
||||||
.head = &head507d,
|
.head = &head507d,
|
||||||
.dac = &dac507d,
|
.dac = &dac507d,
|
||||||
.sor = &sor507d,
|
.sor = &sor507d,
|
||||||
.pior = &pior507d,
|
.pior = &pior507d,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
int
|
||||||
core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm,
|
core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm,
|
||||||
s32 oclass, struct nv50_core **pcore)
|
s32 oclass, struct nv50_core **pcore)
|
||||||
{
|
{
|
||||||
|
41
drivers/gpu/drm/nouveau/dispnv50/core827d.c
Normal file
41
drivers/gpu/drm/nouveau/dispnv50/core827d.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
static const struct nv50_core_func
|
||||||
|
core827d = {
|
||||||
|
.init = core507d_init,
|
||||||
|
.ntfy_init = core507d_ntfy_init,
|
||||||
|
.ntfy_wait_done = core507d_ntfy_wait_done,
|
||||||
|
.update = core507d_update,
|
||||||
|
.head = &head827d,
|
||||||
|
.dac = &dac507d,
|
||||||
|
.sor = &sor507d,
|
||||||
|
.pior = &pior507d,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
core827d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
|
||||||
|
{
|
||||||
|
return core507d_new_(&core827d, drm, oclass, pcore);
|
||||||
|
}
|
40
drivers/gpu/drm/nouveau/dispnv50/core907d.c
Normal file
40
drivers/gpu/drm/nouveau/dispnv50/core907d.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
static const struct nv50_core_func
|
||||||
|
core907d = {
|
||||||
|
.init = core507d_init,
|
||||||
|
.ntfy_init = core507d_ntfy_init,
|
||||||
|
.ntfy_wait_done = core507d_ntfy_wait_done,
|
||||||
|
.update = core507d_update,
|
||||||
|
.head = &head907d,
|
||||||
|
.dac = &dac907d,
|
||||||
|
.sor = &sor907d,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
core907d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
|
||||||
|
{
|
||||||
|
return core507d_new_(&core907d, drm, oclass, pcore);
|
||||||
|
}
|
40
drivers/gpu/drm/nouveau/dispnv50/core917d.c
Normal file
40
drivers/gpu/drm/nouveau/dispnv50/core917d.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
static const struct nv50_core_func
|
||||||
|
core917d = {
|
||||||
|
.init = core507d_init,
|
||||||
|
.ntfy_init = core507d_ntfy_init,
|
||||||
|
.ntfy_wait_done = core507d_ntfy_wait_done,
|
||||||
|
.update = core507d_update,
|
||||||
|
.head = &head917d,
|
||||||
|
.dac = &dac907d,
|
||||||
|
.sor = &sor907d,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
core917d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
|
||||||
|
{
|
||||||
|
return core507d_new_(&core917d, drm, oclass, pcore);
|
||||||
|
}
|
@ -21,26 +21,19 @@
|
|||||||
*/
|
*/
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
#include <nvif/class.h>
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
||||||
struct nv50_head_atom *asyh)
|
struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
u32 *push, sync = 0;
|
u32 *push, sync = 0;
|
||||||
if ((push = evo_wait(&core->chan, 3))) {
|
if ((push = evo_wait(&core->chan, 3))) {
|
||||||
if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
if (asyh) {
|
||||||
if (asyh) {
|
sync |= asyh->or.nvsync << 1;
|
||||||
sync |= asyh->or.nvsync << 1;
|
sync |= asyh->or.nhsync;
|
||||||
sync |= asyh->or.nhsync;
|
|
||||||
}
|
|
||||||
evo_mthd(push, 0x0400 + (or * 0x080), 2);
|
|
||||||
evo_data(push, ctrl);
|
|
||||||
evo_data(push, sync);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0180 + (or * 0x020), 1);
|
|
||||||
evo_data(push, ctrl);
|
|
||||||
}
|
}
|
||||||
|
evo_mthd(push, 0x0400 + (or * 0x080), 2);
|
||||||
|
evo_data(push, ctrl);
|
||||||
|
evo_data(push, sync);
|
||||||
evo_kick(push, &core->chan);
|
evo_kick(push, &core->chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
39
drivers/gpu/drm/nouveau/dispnv50/dac907d.c
Normal file
39
drivers/gpu/drm/nouveau/dispnv50/dac907d.c
Normal file
@ -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
|
||||||
|
dac907d_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, 0x0180 + (or * 0x020), 1);
|
||||||
|
evo_data(push, ctrl);
|
||||||
|
evo_kick(push, &core->chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nv50_outp_func
|
||||||
|
dac907d = {
|
||||||
|
.ctrl = dac907d_ctrl,
|
||||||
|
};
|
@ -1587,10 +1587,9 @@ static void
|
|||||||
nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock)
|
nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock)
|
||||||
{
|
{
|
||||||
struct nv50_disp *disp = nv50_disp(drm->dev);
|
struct nv50_disp *disp = nv50_disp(drm->dev);
|
||||||
struct nv50_dmac *core = &disp->core->chan;
|
struct nv50_core *core = disp->core;
|
||||||
struct nv50_mstm *mstm;
|
struct nv50_mstm *mstm;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
u32 *push;
|
|
||||||
|
|
||||||
NV_ATOMIC(drm, "commit core %08x\n", interlock);
|
NV_ATOMIC(drm, "commit core %08x\n", interlock);
|
||||||
|
|
||||||
@ -1602,21 +1601,11 @@ nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((push = evo_wait(core, 5))) {
|
core->func->ntfy_init(disp->sync, NV50_DISP_CORE_NTFY);
|
||||||
evo_mthd(push, 0x0084, 1);
|
core->func->update(core, interlock, true);
|
||||||
evo_data(push, 0x80000000);
|
if (core->func->ntfy_wait_done(disp->sync, NV50_DISP_CORE_NTFY,
|
||||||
evo_mthd(push, 0x0080, 2);
|
disp->core->chan.base.device))
|
||||||
evo_data(push, interlock);
|
NV_ERROR(drm, "core notifier timeout\n");
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
nouveau_bo_wr32(disp->sync, 0, 0x00000000);
|
|
||||||
evo_kick(push, core);
|
|
||||||
if (nvif_msec(&drm->client.device, 2000ULL,
|
|
||||||
if (nouveau_bo_rd32(disp->sync, 0))
|
|
||||||
break;
|
|
||||||
usleep_range(1, 2);
|
|
||||||
) < 0)
|
|
||||||
NV_ERROR(drm, "EVO timeout\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
drm_for_each_encoder(encoder, drm->dev) {
|
drm_for_each_encoder(encoder, drm->dev) {
|
||||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
|
if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
|
||||||
@ -1770,16 +1759,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
|
|||||||
|
|
||||||
/* Flush update. */
|
/* Flush update. */
|
||||||
if (interlock_core) {
|
if (interlock_core) {
|
||||||
if (!interlock_chan && atom->state.legacy_cursor_update) {
|
if (interlock_chan || !atom->state.legacy_cursor_update)
|
||||||
u32 *push = evo_wait(&disp->core->chan, 2);
|
|
||||||
if (push) {
|
|
||||||
evo_mthd(push, 0x0080, 1);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
evo_kick(push, &disp->core->chan);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nv50_disp_atomic_commit_core(drm, interlock_chan);
|
nv50_disp_atomic_commit_core(drm, interlock_chan);
|
||||||
}
|
else
|
||||||
|
disp->core->func->update(disp->core, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atom->lock_core)
|
if (atom->lock_core)
|
||||||
@ -2079,18 +2062,11 @@ nv50_display_fini(struct drm_device *dev)
|
|||||||
int
|
int
|
||||||
nv50_display_init(struct drm_device *dev)
|
nv50_display_init(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(dev)->core->chan;
|
struct nv50_core *core = nv50_disp(dev)->core;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
u32 *push;
|
|
||||||
|
|
||||||
push = evo_wait(core, 32);
|
core->func->init(core);
|
||||||
if (!push)
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
evo_mthd(push, 0x0088, 1);
|
|
||||||
evo_data(push, core->sync.handle);
|
|
||||||
evo_kick(push, core);
|
|
||||||
|
|
||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
|
if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
|
||||||
|
@ -324,7 +324,6 @@ static int
|
|||||||
nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
|
nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
|
||||||
{
|
{
|
||||||
struct nouveau_drm *drm = nouveau_drm(crtc->dev);
|
struct nouveau_drm *drm = nouveau_drm(crtc->dev);
|
||||||
struct nv50_disp *disp = nv50_disp(crtc->dev);
|
|
||||||
struct nv50_head *head = nv50_head(crtc);
|
struct nv50_head *head = nv50_head(crtc);
|
||||||
struct nv50_head_atom *armh = nv50_head_atom(crtc->state);
|
struct nv50_head_atom *armh = nv50_head_atom(crtc->state);
|
||||||
struct nv50_head_atom *asyh = nv50_head_atom(state);
|
struct nv50_head_atom *asyh = nv50_head_atom(state);
|
||||||
@ -373,31 +372,9 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
|
|||||||
nv50_head_atomic_check_procamp(armh, asyh, asyc);
|
nv50_head_atomic_check_procamp(armh, asyh, asyc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((asyh->core.visible = (asyh->base.cpp != 0))) {
|
if (head->func->core_calc)
|
||||||
asyh->core.x = asyh->base.x;
|
head->func->core_calc(head, asyh);
|
||||||
asyh->core.y = asyh->base.y;
|
|
||||||
asyh->core.w = asyh->base.w;
|
|
||||||
asyh->core.h = asyh->base.h;
|
|
||||||
} else
|
|
||||||
if ((asyh->core.visible = asyh->curs.visible) ||
|
|
||||||
(asyh->core.visible = asyh->ilut.visible)) {
|
|
||||||
/*XXX: We need to either find some way of having the
|
|
||||||
* primary base layer appear black, while still
|
|
||||||
* being able to display the other layers, or we
|
|
||||||
* need to allocate a dummy black surface here.
|
|
||||||
*/
|
|
||||||
asyh->core.x = 0;
|
|
||||||
asyh->core.y = 0;
|
|
||||||
asyh->core.w = asyh->state.mode.hdisplay;
|
|
||||||
asyh->core.h = asyh->state.mode.vdisplay;
|
|
||||||
}
|
|
||||||
asyh->core.handle = disp->core->chan.vram.handle;
|
|
||||||
asyh->core.offset = 0;
|
|
||||||
asyh->core.format = 0xcf;
|
|
||||||
asyh->core.kind = 0;
|
|
||||||
asyh->core.layout = 1;
|
|
||||||
asyh->core.block = 0;
|
|
||||||
asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4;
|
|
||||||
asyh->set.base = armh->base.cpp != asyh->base.cpp;
|
asyh->set.base = armh->base.cpp != asyh->base.cpp;
|
||||||
asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp;
|
asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp;
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,6 +24,7 @@ struct nv50_head_func {
|
|||||||
void (*mode)(struct nv50_head *, struct nv50_head_atom *);
|
void (*mode)(struct nv50_head *, struct nv50_head_atom *);
|
||||||
void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *);
|
void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *);
|
||||||
void (*ilut_clr)(struct nv50_head *);
|
void (*ilut_clr)(struct nv50_head *);
|
||||||
|
void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
|
||||||
void (*core_set)(struct nv50_head *, struct nv50_head_atom *);
|
void (*core_set)(struct nv50_head *, struct nv50_head_atom *);
|
||||||
void (*core_clr)(struct nv50_head *);
|
void (*core_clr)(struct nv50_head *);
|
||||||
void (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
|
void (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
|
||||||
@ -36,4 +37,30 @@ struct nv50_head_func {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern const struct nv50_head_func head507d;
|
extern const struct nv50_head_func head507d;
|
||||||
|
void head507d_view(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head507d_mode(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head507d_core_clr(struct nv50_head *);
|
||||||
|
void head507d_base(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head507d_ovly(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head507d_dither(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head507d_procamp(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
|
||||||
|
extern const struct nv50_head_func head827d;
|
||||||
|
|
||||||
|
extern const struct nv50_head_func head907d;
|
||||||
|
void head907d_view(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head907d_mode(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head907d_ilut_set(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head907d_ilut_clr(struct nv50_head *);
|
||||||
|
void head907d_core_set(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head907d_core_clr(struct nv50_head *);
|
||||||
|
void head907d_curs_set(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head907d_curs_clr(struct nv50_head *);
|
||||||
|
void head907d_base(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
void head907d_ovly(struct nv50_head *, struct nv50_head_atom *);
|
||||||
|
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;
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,62 +22,34 @@
|
|||||||
#include "head.h"
|
#include "head.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
#include <nvif/class.h>
|
void
|
||||||
|
|
||||||
static void
|
|
||||||
head907d_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 (core->base.user.oclass >= GF110_DISP_CORE_CHANNEL_DMA &&
|
|
||||||
(push = evo_wait(core, 3))) {
|
|
||||||
evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2);
|
|
||||||
evo_data(push, 0x00000001 | (asyh->or.depth << 6) |
|
|
||||||
(asyh->or.nvsync << 4) |
|
|
||||||
(asyh->or.nhsync << 3));
|
|
||||||
evo_data(push, 0x31ec6000 | (head->base.index << 25) |
|
|
||||||
asyh->mode.interlace);
|
|
||||||
evo_kick(push, core);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
head507d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
|
head507d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA)
|
evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1);
|
||||||
evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1);
|
evo_data(push, asyh->procamp.sat.sin << 20 |
|
||||||
else
|
asyh->procamp.sat.cos << 8);
|
||||||
evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1);
|
|
||||||
evo_data(push, (asyh->procamp.sat.sin << 20) |
|
|
||||||
(asyh->procamp.sat.cos << 8));
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
head507d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
|
head507d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA)
|
evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1);
|
||||||
evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1);
|
evo_data(push, asyh->dither.mode << 3 |
|
||||||
else
|
asyh->dither.bits << 1 |
|
||||||
if (core->base.user.oclass < GK104_DISP_CORE_CHANNEL_DMA)
|
asyh->dither.enable);
|
||||||
evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1);
|
|
||||||
else
|
|
||||||
evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1);
|
|
||||||
evo_data(push, (asyh->dither.mode << 3) |
|
|
||||||
(asyh->dither.bits << 1) |
|
|
||||||
asyh->dither.enable);
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
@ -97,16 +69,13 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA)
|
evo_mthd(push, 0x0904 + head->base.index * 0x400, 1);
|
||||||
evo_mthd(push, 0x0904 + head->base.index * 0x400, 1);
|
|
||||||
else
|
|
||||||
evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, bounds);
|
evo_data(push, bounds);
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
|
head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
@ -127,10 +96,7 @@ head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA)
|
evo_mthd(push, 0x0900 + head->base.index * 0x400, 1);
|
||||||
evo_mthd(push, 0x0900 + head->base.index * 0x400, 1);
|
|
||||||
else
|
|
||||||
evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, bounds);
|
evo_data(push, bounds);
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
@ -141,22 +107,9 @@ head507d_curs_clr(struct nv50_head *head)
|
|||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 4))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) {
|
evo_mthd(push, 0x0880 + head->base.index * 0x400, 1);
|
||||||
evo_mthd(push, 0x0880 + head->base.index * 0x400, 1);
|
evo_data(push, 0x05000000);
|
||||||
evo_data(push, 0x05000000);
|
|
||||||
} else
|
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
|
||||||
evo_mthd(push, 0x0880 + head->base.index * 0x400, 1);
|
|
||||||
evo_data(push, 0x05000000);
|
|
||||||
evo_mthd(push, 0x089c + head->base.index * 0x400, 1);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0480 + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, 0x05000000);
|
|
||||||
evo_mthd(push, 0x048c + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,42 +119,22 @@ head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
|||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 5))) {
|
if ((push = evo_wait(core, 3))) {
|
||||||
if (core->base.user.oclass < G82_DISP_BASE_CHANNEL_DMA) {
|
evo_mthd(push, 0x0880 + head->base.index * 0x400, 2);
|
||||||
evo_mthd(push, 0x0880 + head->base.index * 0x400, 2);
|
evo_data(push, 0x80000000 | asyh->curs.layout << 26 |
|
||||||
evo_data(push, 0x80000000 | (asyh->curs.layout << 26) |
|
asyh->curs.format << 24);
|
||||||
(asyh->curs.format << 24));
|
evo_data(push, asyh->curs.offset >> 8);
|
||||||
evo_data(push, asyh->curs.offset >> 8);
|
|
||||||
} else
|
|
||||||
if (core->base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) {
|
|
||||||
evo_mthd(push, 0x0880 + head->base.index * 0x400, 2);
|
|
||||||
evo_data(push, 0x80000000 | (asyh->curs.layout << 26) |
|
|
||||||
(asyh->curs.format << 24));
|
|
||||||
evo_data(push, asyh->curs.offset >> 8);
|
|
||||||
evo_mthd(push, 0x089c + head->base.index * 0x400, 1);
|
|
||||||
evo_data(push, asyh->curs.handle);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0480 + head->base.index * 0x300, 2);
|
|
||||||
evo_data(push, 0x80000000 | (asyh->curs.layout << 26) |
|
|
||||||
(asyh->curs.format << 24));
|
|
||||||
evo_data(push, asyh->curs.offset >> 8);
|
|
||||||
evo_mthd(push, 0x048c + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, asyh->curs.handle);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
head507d_core_clr(struct nv50_head *head)
|
head507d_core_clr(struct nv50_head *head)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA)
|
evo_mthd(push, 0x0874 + head->base.index * 0x400, 1);
|
||||||
evo_mthd(push, 0x0874 + head->base.index * 0x400, 1);
|
|
||||||
else
|
|
||||||
evo_mthd(push, 0x0474 + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, 0x00000000);
|
evo_data(push, 0x00000000);
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
@ -213,75 +146,67 @@ head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
|||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 9))) {
|
if ((push = evo_wait(core, 9))) {
|
||||||
if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) {
|
evo_mthd(push, 0x0860 + head->base.index * 0x400, 1);
|
||||||
evo_mthd(push, 0x0860 + head->base.index * 0x400, 1);
|
evo_data(push, asyh->core.offset >> 8);
|
||||||
evo_data(push, asyh->core.offset >> 8);
|
evo_mthd(push, 0x0868 + head->base.index * 0x400, 4);
|
||||||
evo_mthd(push, 0x0868 + head->base.index * 0x400, 4);
|
evo_data(push, asyh->core.h << 16 | asyh->core.w);
|
||||||
evo_data(push, (asyh->core.h << 16) | asyh->core.w);
|
evo_data(push, asyh->core.layout << 20 |
|
||||||
evo_data(push, asyh->core.layout << 20 |
|
asyh->core.pitch >> 8 << 8 |
|
||||||
(asyh->core.pitch >> 8) << 8 |
|
asyh->core.block);
|
||||||
asyh->core.block);
|
evo_data(push, asyh->core.kind << 16 |
|
||||||
evo_data(push, asyh->core.kind << 16 |
|
asyh->core.format << 8);
|
||||||
asyh->core.format << 8);
|
evo_data(push, asyh->core.handle);
|
||||||
evo_data(push, asyh->core.handle);
|
evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1);
|
||||||
evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1);
|
evo_data(push, asyh->core.y << 16 | asyh->core.x);
|
||||||
evo_data(push, (asyh->core.y << 16) | asyh->core.x);
|
|
||||||
/* EVO will complain with INVALID_STATE if we have an
|
|
||||||
* active cursor and (re)specify HeadSetContextDmaIso
|
|
||||||
* without also updating HeadSetOffsetCursor.
|
|
||||||
*/
|
|
||||||
asyh->set.curs = asyh->curs.visible;
|
|
||||||
} else
|
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
|
||||||
evo_mthd(push, 0x0860 + head->base.index * 0x400, 1);
|
|
||||||
evo_data(push, asyh->core.offset >> 8);
|
|
||||||
evo_mthd(push, 0x0868 + head->base.index * 0x400, 4);
|
|
||||||
evo_data(push, (asyh->core.h << 16) | asyh->core.w);
|
|
||||||
evo_data(push, asyh->core.layout << 20 |
|
|
||||||
(asyh->core.pitch >> 8) << 8 |
|
|
||||||
asyh->core.block);
|
|
||||||
evo_data(push, asyh->core.format << 8);
|
|
||||||
evo_data(push, asyh->core.handle);
|
|
||||||
evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1);
|
|
||||||
evo_data(push, (asyh->core.y << 16) | asyh->core.x);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0460 + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, asyh->core.offset >> 8);
|
|
||||||
evo_mthd(push, 0x0468 + head->base.index * 0x300, 4);
|
|
||||||
evo_data(push, (asyh->core.h << 16) | asyh->core.w);
|
|
||||||
evo_data(push, asyh->core.layout << 24 |
|
|
||||||
(asyh->core.pitch >> 8) << 8 |
|
|
||||||
asyh->core.block);
|
|
||||||
evo_data(push, asyh->core.format << 8);
|
|
||||||
evo_data(push, asyh->core.handle);
|
|
||||||
evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1);
|
|
||||||
evo_data(push, (asyh->core.y << 16) | asyh->core.x);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
|
|
||||||
|
/* EVO will complain with INVALID_STATE if we have an
|
||||||
|
* active cursor and (re)specify HeadSetContextDmaIso
|
||||||
|
* without also updating HeadSetOffsetCursor.
|
||||||
|
*/
|
||||||
|
asyh->set.curs = asyh->curs.visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
|
{
|
||||||
|
struct nv50_disp *disp = nv50_disp(head->base.base.dev);
|
||||||
|
if ((asyh->core.visible = (asyh->base.cpp != 0))) {
|
||||||
|
asyh->core.x = asyh->base.x;
|
||||||
|
asyh->core.y = asyh->base.y;
|
||||||
|
asyh->core.w = asyh->base.w;
|
||||||
|
asyh->core.h = asyh->base.h;
|
||||||
|
} else
|
||||||
|
if ((asyh->core.visible = asyh->curs.visible) ||
|
||||||
|
(asyh->core.visible = asyh->ilut.visible)) {
|
||||||
|
/*XXX: We need to either find some way of having the
|
||||||
|
* primary base layer appear black, while still
|
||||||
|
* being able to display the other layers, or we
|
||||||
|
* need to allocate a dummy black surface here.
|
||||||
|
*/
|
||||||
|
asyh->core.x = 0;
|
||||||
|
asyh->core.y = 0;
|
||||||
|
asyh->core.w = asyh->state.mode.hdisplay;
|
||||||
|
asyh->core.h = asyh->state.mode.vdisplay;
|
||||||
|
}
|
||||||
|
asyh->core.handle = disp->core->chan.vram.handle;
|
||||||
|
asyh->core.offset = 0;
|
||||||
|
asyh->core.format = 0xcf;
|
||||||
|
asyh->core.kind = 0;
|
||||||
|
asyh->core.layout = 1;
|
||||||
|
asyh->core.block = 0;
|
||||||
|
asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
head507d_ilut_clr(struct nv50_head *head)
|
head507d_ilut_clr(struct nv50_head *head)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 4))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) {
|
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1);
|
||||||
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1);
|
evo_data(push, 0x40000000);
|
||||||
evo_data(push, 0x40000000);
|
|
||||||
} else
|
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
|
||||||
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1);
|
|
||||||
evo_data(push, 0x40000000);
|
|
||||||
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1);
|
|
||||||
evo_data(push, 0x03000000);
|
|
||||||
evo_mthd(push, 0x045c + (head->base.index * 0x300), 1);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,96 +216,51 @@ head507d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
|||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 7))) {
|
if ((push = evo_wait(core, 3))) {
|
||||||
if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) {
|
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
|
||||||
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
|
evo_data(push, 0x80000000 | asyh->ilut.mode << 30);
|
||||||
evo_data(push, 0x80000000 | asyh->ilut.mode << 30);
|
evo_data(push, asyh->ilut.offset >> 8);
|
||||||
evo_data(push, asyh->ilut.offset >> 8);
|
|
||||||
} else
|
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
|
||||||
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
|
|
||||||
evo_data(push, 0x80000000 | asyh->ilut.mode << 30);
|
|
||||||
evo_data(push, asyh->ilut.offset >> 8);
|
|
||||||
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
|
|
||||||
evo_data(push, asyh->ilut.handle);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4);
|
|
||||||
evo_data(push, 0x80000000 | asyh->ilut.mode << 24);
|
|
||||||
evo_data(push, asyh->ilut.offset >> 8);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
evo_mthd(push, 0x045c + (head->base.index * 0x300), 1);
|
|
||||||
evo_data(push, asyh->ilut.handle);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
|
head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
struct nv50_head_mode *m = &asyh->mode;
|
struct nv50_head_mode *m = &asyh->mode;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 14))) {
|
if ((push = evo_wait(core, 13))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2);
|
||||||
evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2);
|
evo_data(push, 0x00800000 | m->clock);
|
||||||
evo_data(push, 0x00800000 | m->clock);
|
evo_data(push, m->interlace ? 0x00000002 : 0x00000000);
|
||||||
evo_data(push, m->interlace ? 0x00000002 : 0x00000000);
|
evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7);
|
||||||
evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7);
|
evo_data(push, 0x00000000);
|
||||||
evo_data(push, 0x00000000);
|
evo_data(push, m->v.active << 16 | m->h.active );
|
||||||
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.synce << 16) | m->h.synce );
|
evo_data(push, m->v.blanke << 16 | m->h.blanke );
|
||||||
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.blanks << 16) | m->h.blanks );
|
evo_data(push, m->v.blank2e << 16 | m->v.blank2s);
|
||||||
evo_data(push, (m->v.blank2e << 16) | m->v.blank2s);
|
evo_data(push, asyh->mode.v.blankus);
|
||||||
evo_data(push, asyh->mode.v.blankus);
|
evo_mthd(push, 0x082c + (head->base.index * 0x400), 1);
|
||||||
evo_mthd(push, 0x082c + (head->base.index * 0x400), 1);
|
evo_data(push, 0x00000000);
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
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, 0x042c + (head->base.index * 0x300), 2);
|
|
||||||
evo_data(push, 0x00000000); /* ??? */
|
|
||||||
evo_data(push, 0xffffff00);
|
|
||||||
evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3);
|
|
||||||
evo_data(push, m->clock * 1000);
|
|
||||||
evo_data(push, 0x00200000); /* ??? */
|
|
||||||
evo_data(push, m->clock * 1000);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
head507d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
|
head507d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(core, 10))) {
|
if ((push = evo_wait(core, 7))) {
|
||||||
if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1);
|
||||||
evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1);
|
evo_data(push, 0x00000000);
|
||||||
evo_data(push, 0x00000000);
|
evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1);
|
||||||
evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1);
|
evo_data(push, asyh->view.iH << 16 | asyh->view.iW);
|
||||||
evo_data(push, (asyh->view.iH << 16) | asyh->view.iW);
|
evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2);
|
||||||
evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2);
|
evo_data(push, asyh->view.oH << 16 | asyh->view.oW);
|
||||||
evo_data(push, (asyh->view.oH << 16) | asyh->view.oW);
|
evo_data(push, asyh->view.oH << 16 | asyh->view.oW);
|
||||||
evo_data(push, (asyh->view.oH << 16) | asyh->view.oW);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1);
|
|
||||||
evo_data(push, 0x00000000);
|
|
||||||
evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1);
|
|
||||||
evo_data(push, (asyh->view.iH << 16) | asyh->view.iW);
|
|
||||||
evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3);
|
|
||||||
evo_data(push, (asyh->view.oH << 16) | asyh->view.oW);
|
|
||||||
evo_data(push, (asyh->view.oH << 16) | asyh->view.oW);
|
|
||||||
evo_data(push, (asyh->view.oH << 16) | asyh->view.oW);
|
|
||||||
}
|
|
||||||
evo_kick(push, core);
|
evo_kick(push, core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,6 +271,7 @@ head507d = {
|
|||||||
.mode = head507d_mode,
|
.mode = head507d_mode,
|
||||||
.ilut_set = head507d_ilut_set,
|
.ilut_set = head507d_ilut_set,
|
||||||
.ilut_clr = head507d_ilut_clr,
|
.ilut_clr = head507d_ilut_clr,
|
||||||
|
.core_calc = head507d_core_calc,
|
||||||
.core_set = head507d_core_set,
|
.core_set = head507d_core_set,
|
||||||
.core_clr = head507d_core_clr,
|
.core_clr = head507d_core_clr,
|
||||||
.curs_set = head507d_curs_set,
|
.curs_set = head507d_curs_set,
|
||||||
@ -399,5 +280,4 @@ head507d = {
|
|||||||
.ovly = head507d_ovly,
|
.ovly = head507d_ovly,
|
||||||
.dither = head507d_dither,
|
.dither = head507d_dither,
|
||||||
.procamp = head507d_procamp,
|
.procamp = head507d_procamp,
|
||||||
.or = head907d_or,
|
|
||||||
};
|
};
|
||||||
|
120
drivers/gpu/drm/nouveau/dispnv50/head827d.c
Normal file
120
drivers/gpu/drm/nouveau/dispnv50/head827d.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* 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 "core.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
head827d_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, 0x0880 + head->base.index * 0x400, 1);
|
||||||
|
evo_data(push, 0x05000000);
|
||||||
|
evo_mthd(push, 0x089c + head->base.index * 0x400, 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
head827d_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, 5))) {
|
||||||
|
evo_mthd(push, 0x0880 + head->base.index * 0x400, 2);
|
||||||
|
evo_data(push, 0x80000000 | asyh->curs.layout << 26 |
|
||||||
|
asyh->curs.format << 24);
|
||||||
|
evo_data(push, asyh->curs.offset >> 8);
|
||||||
|
evo_mthd(push, 0x089c + head->base.index * 0x400, 1);
|
||||||
|
evo_data(push, asyh->curs.handle);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
head827d_core_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, 9))) {
|
||||||
|
evo_mthd(push, 0x0860 + head->base.index * 0x400, 1);
|
||||||
|
evo_data(push, asyh->core.offset >> 8);
|
||||||
|
evo_mthd(push, 0x0868 + head->base.index * 0x400, 4);
|
||||||
|
evo_data(push, asyh->core.h << 16 | asyh->core.w);
|
||||||
|
evo_data(push, asyh->core.layout << 20 |
|
||||||
|
(asyh->core.pitch >> 8) << 8 |
|
||||||
|
asyh->core.block);
|
||||||
|
evo_data(push, asyh->core.format << 8);
|
||||||
|
evo_data(push, asyh->core.handle);
|
||||||
|
evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1);
|
||||||
|
evo_data(push, asyh->core.y << 16 | asyh->core.x);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
head827d_ilut_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, 0x0840 + (head->base.index * 0x400), 1);
|
||||||
|
evo_data(push, 0x40000000);
|
||||||
|
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
head827d_ilut_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, 5))) {
|
||||||
|
evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
|
||||||
|
evo_data(push, 0x80000000 | asyh->ilut.mode << 30);
|
||||||
|
evo_data(push, asyh->ilut.offset >> 8);
|
||||||
|
evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
|
||||||
|
evo_data(push, asyh->ilut.handle);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nv50_head_func
|
||||||
|
head827d = {
|
||||||
|
.view = head507d_view,
|
||||||
|
.mode = head507d_mode,
|
||||||
|
.ilut_set = head827d_ilut_set,
|
||||||
|
.ilut_clr = head827d_ilut_clr,
|
||||||
|
.core_calc = head507d_core_calc,
|
||||||
|
.core_set = head827d_core_set,
|
||||||
|
.core_clr = head507d_core_clr,
|
||||||
|
.curs_set = head827d_curs_set,
|
||||||
|
.curs_clr = head827d_curs_clr,
|
||||||
|
.base = head507d_base,
|
||||||
|
.ovly = head507d_ovly,
|
||||||
|
.dither = head507d_dither,
|
||||||
|
.procamp = head507d_procamp,
|
||||||
|
};
|
274
drivers/gpu/drm/nouveau/dispnv50/head907d.c
Normal file
274
drivers/gpu/drm/nouveau/dispnv50/head907d.c
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/*
|
||||||
|
* 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 "core.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_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, 3))) {
|
||||||
|
evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2);
|
||||||
|
evo_data(push, 0x00000001 | asyh->or.depth << 6 |
|
||||||
|
asyh->or.nvsync << 4 |
|
||||||
|
asyh->or.nhsync << 3);
|
||||||
|
evo_data(push, 0x31ec6000 | head->base.index << 25 |
|
||||||
|
asyh->mode.interlace);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_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, 0x0498 + (head->base.index * 0x300), 1);
|
||||||
|
evo_data(push, asyh->procamp.sat.sin << 20 |
|
||||||
|
asyh->procamp.sat.cos << 8);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
head907d_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, 0x0490 + (head->base.index * 0x0300), 1);
|
||||||
|
evo_data(push, asyh->dither.mode << 3 |
|
||||||
|
asyh->dither.bits << 1 |
|
||||||
|
asyh->dither.enable);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
|
{
|
||||||
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
|
u32 bounds = 0;
|
||||||
|
u32 *push;
|
||||||
|
|
||||||
|
if (asyh->ovly.cpp) {
|
||||||
|
switch (asyh->ovly.cpp) {
|
||||||
|
case 8: bounds |= 0x00000500; break;
|
||||||
|
case 4: bounds |= 0x00000300; break;
|
||||||
|
case 2: bounds |= 0x00000100; break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bounds |= 0x00000001;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((push = evo_wait(core, 2))) {
|
||||||
|
evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, bounds);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
|
{
|
||||||
|
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||||
|
u32 bounds = 0;
|
||||||
|
u32 *push;
|
||||||
|
|
||||||
|
if (asyh->base.cpp) {
|
||||||
|
switch (asyh->base.cpp) {
|
||||||
|
case 8: bounds |= 0x00000500; break;
|
||||||
|
case 4: bounds |= 0x00000300; break;
|
||||||
|
case 2: bounds |= 0x00000100; break;
|
||||||
|
case 1: bounds |= 0x00000000; break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bounds |= 0x00000001;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((push = evo_wait(core, 2))) {
|
||||||
|
evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, bounds);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_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, 0x0480 + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, 0x05000000);
|
||||||
|
evo_mthd(push, 0x048c + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_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, 5))) {
|
||||||
|
evo_mthd(push, 0x0480 + head->base.index * 0x300, 2);
|
||||||
|
evo_data(push, 0x80000000 | asyh->curs.layout << 26 |
|
||||||
|
asyh->curs.format << 24);
|
||||||
|
evo_data(push, asyh->curs.offset >> 8);
|
||||||
|
evo_mthd(push, 0x048c + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, asyh->curs.handle);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_core_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, 0x0474 + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_core_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, 9))) {
|
||||||
|
evo_mthd(push, 0x0460 + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, asyh->core.offset >> 8);
|
||||||
|
evo_mthd(push, 0x0468 + head->base.index * 0x300, 4);
|
||||||
|
evo_data(push, asyh->core.h << 16 | asyh->core.w);
|
||||||
|
evo_data(push, asyh->core.layout << 24 |
|
||||||
|
(asyh->core.pitch >> 8) << 8 |
|
||||||
|
asyh->core.block);
|
||||||
|
evo_data(push, asyh->core.format << 8);
|
||||||
|
evo_data(push, asyh->core.handle);
|
||||||
|
evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1);
|
||||||
|
evo_data(push, asyh->core.y << 16 | asyh->core.x);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_ilut_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, 0x0440 + (head->base.index * 0x300), 1);
|
||||||
|
evo_data(push, 0x03000000);
|
||||||
|
evo_mthd(push, 0x045c + (head->base.index * 0x300), 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_ilut_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, 0x0440 + (head->base.index * 0x300), 4);
|
||||||
|
evo_data(push, 0x80000000 | asyh->ilut.mode << 24);
|
||||||
|
evo_data(push, asyh->ilut.offset >> 8);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_mthd(push, 0x045c + (head->base.index * 0x300), 1);
|
||||||
|
evo_data(push, asyh->ilut.handle);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_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, 14))) {
|
||||||
|
evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
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, 0x042c + (head->base.index * 0x300), 2);
|
||||||
|
evo_data(push, 0x00000000); /* ??? */
|
||||||
|
evo_data(push, 0xffffff00);
|
||||||
|
evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3);
|
||||||
|
evo_data(push, m->clock * 1000);
|
||||||
|
evo_data(push, 0x00200000); /* ??? */
|
||||||
|
evo_data(push, m->clock * 1000);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
head907d_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, 8))) {
|
||||||
|
evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1);
|
||||||
|
evo_data(push, asyh->view.iH << 16 | asyh->view.iW);
|
||||||
|
evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3);
|
||||||
|
evo_data(push, asyh->view.oH << 16 | asyh->view.oW);
|
||||||
|
evo_data(push, asyh->view.oH << 16 | asyh->view.oW);
|
||||||
|
evo_data(push, asyh->view.oH << 16 | asyh->view.oW);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nv50_head_func
|
||||||
|
head907d = {
|
||||||
|
.view = head907d_view,
|
||||||
|
.mode = head907d_mode,
|
||||||
|
.ilut_set = head907d_ilut_set,
|
||||||
|
.ilut_clr = head907d_ilut_clr,
|
||||||
|
.core_calc = head507d_core_calc,
|
||||||
|
.core_set = head907d_core_set,
|
||||||
|
.core_clr = head907d_core_clr,
|
||||||
|
.curs_set = head907d_curs_set,
|
||||||
|
.curs_clr = head907d_curs_clr,
|
||||||
|
.base = head907d_base,
|
||||||
|
.ovly = head907d_ovly,
|
||||||
|
.dither = head907d_dither,
|
||||||
|
.procamp = head907d_procamp,
|
||||||
|
.or = head907d_or,
|
||||||
|
};
|
55
drivers/gpu/drm/nouveau/dispnv50/head917d.c
Normal file
55
drivers/gpu/drm/nouveau/dispnv50/head917d.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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 "core.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
head917d_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, 0x04a0 + (head->base.index * 0x0300), 1);
|
||||||
|
evo_data(push, asyh->dither.mode << 3 |
|
||||||
|
asyh->dither.bits << 1 |
|
||||||
|
asyh->dither.enable);
|
||||||
|
evo_kick(push, core);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nv50_head_func
|
||||||
|
head917d = {
|
||||||
|
.view = head907d_view,
|
||||||
|
.mode = head907d_mode,
|
||||||
|
.ilut_set = head907d_ilut_set,
|
||||||
|
.ilut_clr = head907d_ilut_clr,
|
||||||
|
.core_calc = head507d_core_calc,
|
||||||
|
.core_set = head907d_core_set,
|
||||||
|
.core_clr = head907d_core_clr,
|
||||||
|
.curs_set = head907d_curs_set,
|
||||||
|
.curs_clr = head907d_curs_clr,
|
||||||
|
.base = head907d_base,
|
||||||
|
.ovly = head907d_ovly,
|
||||||
|
.dither = head917d_dither,
|
||||||
|
.procamp = head907d_procamp,
|
||||||
|
.or = head907d_or,
|
||||||
|
};
|
@ -21,23 +21,19 @@
|
|||||||
*/
|
*/
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
#include <nvif/class.h>
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
||||||
struct nv50_head_atom *asyh)
|
struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&core->chan, 8))) {
|
if ((push = evo_wait(&core->chan, 2))) {
|
||||||
if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
if (asyh) {
|
||||||
if (asyh) {
|
ctrl |= asyh->or.depth << 16;
|
||||||
ctrl |= asyh->or.depth << 16;
|
ctrl |= asyh->or.nvsync << 13;
|
||||||
ctrl |= asyh->or.nvsync << 13;
|
ctrl |= asyh->or.nhsync << 12;
|
||||||
ctrl |= asyh->or.nhsync << 12;
|
|
||||||
}
|
|
||||||
evo_mthd(push, 0x0700 + (or * 0x040), 1);
|
|
||||||
evo_data(push, ctrl);
|
|
||||||
}
|
}
|
||||||
|
evo_mthd(push, 0x0700 + (or * 0x040), 1);
|
||||||
|
evo_data(push, ctrl);
|
||||||
evo_kick(push, &core->chan);
|
evo_kick(push, &core->chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,24 +21,18 @@
|
|||||||
*/
|
*/
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
#include <nvif/class.h>
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
|
||||||
struct nv50_head_atom *asyh)
|
struct nv50_head_atom *asyh)
|
||||||
{
|
{
|
||||||
u32 *push;
|
u32 *push;
|
||||||
if ((push = evo_wait(&core->chan, 6))) {
|
if ((push = evo_wait(&core->chan, 2))) {
|
||||||
if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
|
if (asyh) {
|
||||||
if (asyh) {
|
ctrl |= asyh->or.depth << 16;
|
||||||
ctrl |= asyh->or.depth << 16;
|
ctrl |= asyh->or.nvsync << 13;
|
||||||
ctrl |= asyh->or.nvsync << 13;
|
ctrl |= asyh->or.nhsync << 12;
|
||||||
ctrl |= asyh->or.nhsync << 12;
|
|
||||||
}
|
|
||||||
evo_mthd(push, 0x0600 + (or * 0x40), 1);
|
|
||||||
} else {
|
|
||||||
evo_mthd(push, 0x0200 + (or * 0x20), 1);
|
|
||||||
}
|
}
|
||||||
|
evo_mthd(push, 0x0600 + (or * 0x40), 1);
|
||||||
evo_data(push, ctrl);
|
evo_data(push, ctrl);
|
||||||
evo_kick(push, &core->chan);
|
evo_kick(push, &core->chan);
|
||||||
}
|
}
|
||||||
|
41
drivers/gpu/drm/nouveau/dispnv50/sor907d.c
Normal file
41
drivers/gpu/drm/nouveau/dispnv50/sor907d.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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 <nvif/class.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
sor907d_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, 0x0200 + (or * 0x20), 1);
|
||||||
|
evo_data(push, ctrl);
|
||||||
|
evo_kick(push, &core->chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nv50_outp_func
|
||||||
|
sor907d = {
|
||||||
|
.ctrl = sor907d_ctrl,
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user