Commit 1590700d authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/kms/nv50-: split each resource type into their own source files

There should be no code changes here, just shuffling stuff around.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 0a368771
nouveau-y += dispnv50/disp.o
nouveau-y += dispnv50/core.o
nouveau-y += dispnv50/core507d.o
nouveau-y += dispnv50/dac507d.o
nouveau-y += dispnv50/pior507d.o
nouveau-y += dispnv50/sor507d.o
nouveau-y += dispnv50/head.o
nouveau-y += dispnv50/head507d.o
nouveau-y += dispnv50/wndw.o
nouveau-y += dispnv50/base.o
nouveau-y += dispnv50/base507c.o
nouveau-y += dispnv50/curs.o
nouveau-y += dispnv50/curs507a.o
nouveau-y += dispnv50/oimm.o
nouveau-y += dispnv50/oimm507b.o
nouveau-y += dispnv50/ovly.o
nouveau-y += dispnv50/ovly507e.o
#ifndef __NV50_KMS_ATOM_H__
#define __NV50_KMS_ATOM_H__
#define nv50_atom(p) container_of((p), struct nv50_atom, state)
#include <drm/drm_atomic.h>
struct nv50_atom {
struct drm_atomic_state state;
struct list_head outp;
bool lock_core;
bool flush_disable;
};
#define nv50_head_atom(p) container_of((p), struct nv50_head_atom, state)
struct nv50_head_atom {
struct drm_crtc_state state;
struct {
u16 iW;
u16 iH;
u16 oW;
u16 oH;
} view;
struct nv50_head_mode {
bool interlace;
u32 clock;
struct {
u16 active;
u16 synce;
u16 blanke;
u16 blanks;
} h;
struct {
u32 active;
u16 synce;
u16 blanke;
u16 blanks;
u16 blank2s;
u16 blank2e;
u16 blankus;
} v;
} mode;
struct {
bool visible;
u32 handle;
u64 offset:40;
u8 mode:4;
} ilut;
struct {
bool visible;
u32 handle;
u64 offset:40;
u8 format;
u8 kind:7;
u8 layout:1;
u8 block:4;
u32 pitch:20;
u16 x;
u16 y;
u16 w;
u16 h;
} core;
struct {
bool visible;
u32 handle;
u64 offset:40;
u8 layout:1;
u8 format:1;
} curs;
struct {
u8 depth;
u8 cpp;
u16 x;
u16 y;
u16 w;
u16 h;
} base;
struct {
u8 cpp;
} ovly;
struct {
bool enable:1;
u8 bits:2;
u8 mode:4;
} dither;
struct {
struct {
u16 cos:12;
u16 sin:12;
} sat;
} procamp;
struct {
u8 nhsync:1;
u8 nvsync:1;
u8 depth:4;
} or;
union {
struct {
bool ilut:1;
bool core:1;
bool curs:1;
};
u8 mask;
} clr;
union {
struct {
bool ilut:1;
bool core:1;
bool curs:1;
bool view:1;
bool mode:1;
bool base:1;
bool ovly:1;
bool dither:1;
bool procamp:1;
bool or:1;
};
u16 mask;
} set;
};
static inline struct nv50_head_atom *
nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc)
{
struct drm_crtc_state *statec = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(statec))
return (void *)statec;
return nv50_head_atom(statec);
}
#define nv50_wndw_atom(p) container_of((p), struct nv50_wndw_atom, state)
struct nv50_wndw_atom {
struct drm_plane_state state;
u8 interval;
struct {
u32 handle;
u16 offset:12;
bool awaken:1;
} ntfy;
struct {
u32 handle;
u16 offset:12;
u32 acquire;
u32 release;
} sema;
struct {
u8 enable:2;
} lut;
struct {
u8 mode:2;
u8 interval:4;
u8 format;
u8 kind:7;
u8 layout:1;
u8 block:4;
u32 pitch:20;
u16 w;
u16 h;
u32 handle;
u64 offset;
} image;
struct {
u16 x;
u16 y;
} point;
union {
struct {
bool ntfy:1;
bool sema:1;
bool image:1;
};
u8 mask;
} clr;
union {
struct {
bool ntfy:1;
bool sema:1;
bool image:1;
bool lut:1;
bool point:1;
};
u8 mask;
} set;
};
#endif
/*
* 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 "base.h"
#include <nvif/class.h>
int
nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
{
struct {
s32 oclass;
int version;
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
} bases[] = {
{ GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{ GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{ GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{ GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{ GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{ G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{ NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
{}
};
struct nv50_disp *disp = nv50_disp(drm->dev);
int cid;
cid = nvif_mclass(&disp->disp->object, bases);
if (cid < 0) {
NV_ERROR(drm, "No supported base class\n");
return cid;
}
return bases[cid].new(drm, head, bases[cid].oclass, pwndw);
}
#ifndef __NV50_KMS_BASE_H__
#define __NV50_KMS_BASE_H__
#include "wndw.h"
int base507c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
int nv50_base_new(struct nouveau_drm *, int head, struct nv50_wndw **);
#endif
/*
* 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 "base.h"
#include <nvif/class.h>
#include <nvif/cl507c.h>
#include <nvif/event.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h>
#include "nouveau_bo.h"
static u32
base507c_update(struct nv50_wndw *wndw, u32 interlock)
{
u32 *push;
if (!(push = evo_wait(&wndw->wndw, 2)))
return 0;
evo_mthd(push, 0x0080, 1);
evo_data(push, interlock);
evo_kick(push, &wndw->wndw);
if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA)
return interlock ? 2 << (wndw->id * 8) : 0;
return interlock ? 2 << (wndw->id * 4) : 0;
}
static void
base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00e0, 1);
evo_data(push, asyw->lut.enable << 30);
evo_kick(push, &wndw->wndw);
}
}
static void
base507c_image_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 4))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, 0x00000000);
evo_mthd(push, 0x00c0, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
}
static void
base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
const s32 oclass = wndw->wndw.base.user.oclass;
u32 *push;
if ((push = evo_wait(&wndw->wndw, 10))) {
evo_mthd(push, 0x0084, 1);
evo_data(push, asyw->image.mode << 8 |
asyw->image.interval << 4);
evo_mthd(push, 0x00c0, 1);
evo_data(push, asyw->image.handle);
if (oclass < G82_DISP_BASE_CHANNEL_DMA) {
evo_mthd(push, 0x0800, 5);
evo_data(push, asyw->image.offset >> 8);
evo_data(push, 0x00000000);
evo_data(push, (asyw->image.h << 16) | asyw->image.w);
evo_data(push, (asyw->image.layout << 20) |
asyw->image.pitch |
asyw->image.block);
evo_data(push, (asyw->image.kind << 16) |
(asyw->image.format << 8));
} else
if (oclass < GF110_DISP_BASE_CHANNEL_DMA) {
evo_mthd(push, 0x0800, 5);
evo_data(push, asyw->image.offset >> 8);
evo_data(push, 0x00000000);
evo_data(push, (asyw->image.h << 16) | asyw->image.w);
evo_data(push, (asyw->image.layout << 20) |
asyw->image.pitch |
asyw->image.block);
evo_data(push, asyw->image.format << 8);
} else {
evo_mthd(push, 0x0400, 5);
evo_data(push, asyw->image.offset >> 8);
evo_data(push, 0x00000000);
evo_data(push, (asyw->image.h << 16) | asyw->image.w);
evo_data(push, (asyw->image.layout << 24) |
asyw->image.pitch |
asyw->image.block);
evo_data(push, asyw->image.format << 8);
}
evo_kick(push, &wndw->wndw);
}
}
static int
base507c_ntfy_wait_begun(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev);
struct nv50_disp *disp = nv50_disp(wndw->plane.dev);
if (nvif_msec(&drm->client.device, 2000ULL,
u32 data = nouveau_bo_rd32(disp->sync, asyw->ntfy.offset / 4);
if ((data & 0xc0000000) == 0x40000000)
break;
usleep_range(1, 2);
) < 0)
return -ETIMEDOUT;
return 0;
}
static void
base507c_ntfy_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x00a4, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
}
static void
base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 3))) {
evo_mthd(push, 0x00a0, 2);
evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset);
evo_data(push, asyw->ntfy.handle);
evo_kick(push, &wndw->wndw);
}
}
static void
base507c_sema_clr(struct nv50_wndw *wndw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 2))) {
evo_mthd(push, 0x0094, 1);
evo_data(push, 0x00000000);
evo_kick(push, &wndw->wndw);
}
}
static void
base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
u32 *push;
if ((push = evo_wait(&wndw->wndw, 5))) {
evo_mthd(push, 0x0088, 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
base507c_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh)
{
asyh->base.cpp = 0;
}
static int
base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh)
{
const struct drm_framebuffer *fb = asyw->state.fb;
int ret;
if (!fb->format->depth)
return -EINVAL;
ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
DRM_PLANE_HELPER_NO_SCALING,
DRM_PLANE_HELPER_NO_SCALING,
false, true);
if (ret)
return ret;
asyh->base.depth = fb->format->depth;
asyh->base.cpp = fb->format->cpp[0];
asyh->base.x = asyw->state.src.x1 >> 16;
asyh->base.y = asyw->state.src.y1 >> 16;
asyh->base.w = asyw->state.fb->width;
asyh->base.h = asyw->state.fb->height;
switch (fb->format->format) {
case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break;
case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break;
case DRM_FORMAT_XRGB1555 :
case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break;
case DRM_FORMAT_XRGB8888 :
case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break;
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break;
case DRM_FORMAT_XBGR8888 :
case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break;
default:
WARN_ON(1);
return -EINVAL;
}
asyw->lut.enable = 1;
asyw->set.image = true;
return 0;
}
static const u32
base507c_format[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
DRM_FORMAT_XRGB1555,
DRM_FORMAT_ARGB1555,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR2101010,
DRM_FORMAT_ABGR2101010,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR8888,
0
};
static const struct nv50_wndw_func
base507c = {
.acquire = base507c_acquire,
.release = base507c_release,
.sema_set = base507c_sema_set,
.sema_clr = base507c_sema_clr,
.ntfy_set = base507c_ntfy_set,
.ntfy_clr = base507c_ntfy_clr,
.ntfy_wait_begun = base507c_ntfy_wait_begun,
.image_set = base507c_image_set,
.image_clr = base507c_image_clr,
.lut = base507c_lut,
.update = base507c_update,
};
static int
base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
struct nouveau_drm *drm, int head, s32 oclass,
struct nv50_wndw **pwndw)
{
struct nv50_disp_base_channel_dma_v0 args = {
.head = head,
};
struct nv50_disp *disp = nv50_disp(drm->dev);
struct nv50_wndw *wndw;
int ret;
ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY,
"base", head, format, &wndw);
if (*pwndw = wndw, ret)
return ret;
ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
&oclass, head, &args, sizeof(args),
disp->sync->bo.offset, &wndw->wndw);
if (ret) {
NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret);
return ret;
}
ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func,
false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT,
&(struct nvif_notify_uevent_req) {},
sizeof(struct nvif_notify_uevent_req),
sizeof(struct nvif_notify_uevent_rep),
&wndw->notify);
if (ret)
return ret;
wndw->ntfy = NV50_DISP_BASE_NTFY(wndw->id);
wndw->sema = NV50_DISP_BASE_SEM0(wndw->id);
wndw->data = 0x00000000;
return 0;
}
int
base507c_new(struct nouveau_drm *drm, int head, s32 oclass,
struct nv50_wndw **pwndw)
{
return base507c_new_(&base507c, base507c_format, drm, head, oclass, pwndw);
}
/*
* 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>
void
nv50_core_del(struct nv50_core **pcore)
{
struct nv50_core *core = *pcore;
if (core) {
nv50_dmac_destroy(&core->chan);
kfree(*pcore);
*pcore = NULL;
}
}
int
nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore)
{
struct {
s32 oclass;
int version;
int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
} cores[] = {
{ GP102_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GP100_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GM200_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GM107_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GK110_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GK104_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GF110_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GT214_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GT206_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ GT200_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ G82_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{ NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new },
{}
};
struct nv50_disp *disp = nv50_disp(drm->dev);
int cid;
cid = nvif_mclass(&disp->disp->object, cores);
if (cid < 0) {
NV_ERROR(drm, "No supported core channel class\n");
return cid;
}
return cores[cid].new(drm, cores[cid].oclass, pcore);
}
#ifndef __NV50_KMS_CORE_H__
#define __NV50_KMS_CORE_H__
#include "disp.h"
#include "atom.h"
struct nv50_core {
const struct nv50_core_func *func;
struct nv50_dmac chan;
};
int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
void nv50_core_del(struct nv50_core **);
struct nv50_core_func {
const struct nv50_head_func *head;
const struct nv50_outp_func {
void (*ctrl)(struct nv50_core *, int or, u32 ctrl,
struct nv50_head_atom *);
} *dac, *pior, *sor;
};
int core507d_new(struct nouveau_drm *, s32, struct nv50_core **);
extern const struct nv50_outp_func dac507d;
extern const struct nv50_outp_func sor507d;
extern const struct nv50_outp_func pior507d;
#endif
/*
* 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 <nvif/cl507d.h>
#include "nouveau_bo.h"
static const struct nv50_core_func
core507d = {
.head = &head507d,
.dac = &dac507d,
.sor = &sor507d,
.pior = &pior507d,
};
static int
core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm,
s32 oclass, struct nv50_core **pcore)
{
struct nv50_disp_core_channel_dma_v0 args = {};
struct nv50_disp *disp = nv50_disp(drm->dev);
struct nv50_core *core;
int ret;
if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL)))
return -ENOMEM;
core->func = func;
ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
&oclass, 0, &args, sizeof(args),
disp->sync->bo.offset, &core->chan);
if (ret) {
NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret);
return ret;
}
return 0;
}
int
core507d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
{
return core507d_new_(&core507d, drm, oclass, pcore);
}
/*
* 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 <nvif/class.h>
int
nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
{
struct {
s32 oclass;
int version;
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
} curses[] = {
{ GK104_DISP_CURSOR, 0, curs507a_new },
{ GF110_DISP_CURSOR, 0, curs507a_new },
{ GT214_DISP_CURSOR, 0, curs507a_new },
{ G82_DISP_CURSOR, 0, curs507a_new },
{ NV50_DISP_CURSOR, 0, curs507a_new },
{}
};
struct nv50_disp *disp = nv50_disp(drm->dev);
int cid;
cid = nvif_mclass(&disp->disp->object, curses);
if (cid < 0) {
NV_ERROR(drm, "No supported cursor immediate class\n");
return cid;
}
return curses[cid].new(drm, head, curses[cid].oclass, pwndw);
}
#ifndef __NV50_KMS_CURS_H__
#define __NV50_KMS_CURS_H__
#include "wndw.h"
int curs507a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
int nv50_curs_new(struct nouveau_drm *, int head, struct nv50_wndw **);
#endif
/*
* 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 "core.h"
#include <nvif/cl507a.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h>
static u32
curs507a_update(struct nv50_wndw *wndw, u32 interlock)
{
nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000);
return 0;
}
static void
curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 |
asyw->point.x);
}
static const struct nv50_wimm_func
curs507a = {
.point = curs507a_point,
.update = curs507a_update,
};
static void
curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh,
struct nv50_wndw_atom *asyw)
{
u32 handle = nv50_disp(wndw->plane.dev)->core->chan.vram.handle;
u32 offset = asyw->image.offset;
if (asyh->curs.handle != handle || asyh->curs.offset != offset) {
asyh->curs.handle = handle;
asyh->curs.offset = offset;
asyh->set.curs = asyh->curs.visible;
}
}
static void
curs507a_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh)
{
asyh->curs.visible = false;
}
static int
curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
struct nv50_head_atom *asyh)
{
int ret;
ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
DRM_PLANE_HELPER_NO_SCALING,
DRM_PLANE_HELPER_NO_SCALING,
true, true);
asyh->curs.visible = asyw->state.visible;
if (ret || !asyh->curs.visible)
return ret;
switch (asyw->state.fb->width) {
case 32: asyh->curs.layout = 0; break;
case 64: asyh->curs.layout = 1; break;
default:
return -EINVAL;
}
if (asyw->state.fb->width != asyw->state.fb->height)
return -EINVAL;
switch (asyw->state.fb->format->format) {
case DRM_FORMAT_ARGB8888: asyh->curs.format = 1; break;
default:
WARN_ON(1);
return -EINVAL;
}
return 0;
}
static const u32
curs507a_format[] = {
DRM_FORMAT_ARGB8888,
0
};
static const struct nv50_wndw_func
curs507a_wndw = {
.acquire = curs507a_acquire,
.release = curs507a_release,
.prepare = curs507a_prepare,
};
static int
curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
int head, s32 oclass, struct nv50_wndw **pwndw)
{
struct nv50_disp_cursor_v0 args = {
.head = head,
};
struct nv50_disp *disp = nv50_disp(drm->dev);
struct nv50_wndw *wndw;
int ret;
ret = nv50_wndw_new_(&curs507a_wndw, drm->dev, DRM_PLANE_TYPE_CURSOR,
"curs", head, curs507a_format, &wndw);
if (*pwndw = wndw, ret)
return ret;
ret = nvif_object_init(&disp->disp->object, 0, oclass, &args,
sizeof(args), &wndw->wimm.base.user);
if (ret) {
NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret);
return ret;
}
nvif_object_map(&wndw->wimm.base.user, NULL, 0);
wndw->immd = func;
wndw->ctxdma.parent = &disp->core->chan.base.user;
return 0;
}
int
curs507a_new(struct nouveau_drm *drm, int head, s32 oclass,
struct nv50_wndw **pwndw)
{
return curs507a_new_(&curs507a, drm, head, oclass, pwndw);
}
/*
* 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
dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl,
struct nv50_head_atom *asyh)
{
u32 *push, sync = 0;
if ((push = evo_wait(&core->chan, 3))) {
if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
if (asyh) {
sync |= asyh->or.nvsync << 1;
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_kick(push, &core->chan);
}
}
const struct nv50_outp_func
dac507d = {
.ctrl = dac507d_ctrl,
};
This diff is collapsed.
#ifndef __NV50_KMS_H__
#define __NV50_KMS_H__
#include <nvif/mem.h>
#include "nouveau_display.h"
struct nv50_disp {
struct nvif_disp *disp;
struct nv50_core *core;
#define NV50_DISP_SYNC(c, o) ((c) * 0x040 + (o))
#define NV50_DISP_CORE_NTFY NV50_DISP_SYNC(0 , 0x00)
#define NV50_DISP_WNDW_SEM0(c) NV50_DISP_SYNC(1 + (c), 0x00)
#define NV50_DISP_WNDW_SEM1(c) NV50_DISP_SYNC(1 + (c), 0x10)
#define NV50_DISP_WNDW_NTFY(c) NV50_DISP_SYNC(1 + (c), 0x20)
#define NV50_DISP_BASE_SEM0(c) NV50_DISP_WNDW_SEM0(0 + (c))
#define NV50_DISP_BASE_SEM1(c) NV50_DISP_WNDW_SEM1(0 + (c))
#define NV50_DISP_BASE_NTFY(c) NV50_DISP_WNDW_NTFY(0 + (c))
struct nouveau_bo *sync;
struct mutex mutex;
};
static inline struct nv50_disp *
nv50_disp(struct drm_device *dev)
{
return nouveau_display(dev)->priv;
}
struct nv50_chan {
struct nvif_object user;
struct nvif_device *device;
};
struct nv50_dmac {
struct nv50_chan base;
struct nvif_mem push;
u32 *ptr;
struct nvif_object sync;
struct nvif_object vram;
/* Protects against concurrent pushbuf access to this channel, lock is
* grabbed by evo_wait (if the pushbuf reservation is successful) and
* dropped again by evo_kick. */
struct mutex lock;
};
int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
const s32 *oclass, u8 head, void *data, u32 size,
u64 syncbuf, struct nv50_dmac *dmac);
void nv50_dmac_destroy(struct nv50_dmac *);
u32 *evo_wait(struct nv50_dmac *, int nr);
void evo_kick(u32 *, struct nv50_dmac *);
#define evo_mthd(p, m, s) do { \
const u32 _m = (m), _s = (s); \
if (drm_debug & DRM_UT_KMS) \
pr_err("%04x %d %s\n", _m, _s, __func__); \
*((p)++) = ((_s << 18) | _m); \
} while(0)
#define evo_data(p, d) do { \
const u32 _d = (d); \
if (drm_debug & DRM_UT_KMS) \
pr_err("\t%08x\n", _d); \
*((p)++) = _d; \
} while(0)
#endif
This diff is collapsed.
#ifndef __NV50_KMS_HEAD_H__
#define __NV50_KMS_HEAD_H__
#define nv50_head(c) container_of((c), struct nv50_head, base.base)
#include "disp.h"
#include "atom.h"
#include "nouveau_crtc.h"
struct nv50_head {
const struct nv50_head_func *func;
struct nouveau_crtc base;
struct {
struct nouveau_bo *nvbo[2];
int next;
} ilut;
};
int nv50_head_create(struct drm_device *, int index);
void nv50_head_flush_set(struct nv50_head *, struct nv50_head_atom *);
void nv50_head_flush_clr(struct nv50_head *, struct nv50_head_atom *, bool y);
struct nv50_head_func {
void (*view)(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_clr)(struct nv50_head *);
void (*core_set)(struct nv50_head *, struct nv50_head_atom *);
void (*core_clr)(struct nv50_head *);
void (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
void (*curs_clr)(struct nv50_head *);
void (*base)(struct nv50_head *, struct nv50_head_atom *);
void (*ovly)(struct nv50_head *, struct nv50_head_atom *);
void (*dither)(struct nv50_head *, struct nv50_head_atom *);
void (*procamp)(struct nv50_head *, struct nv50_head_atom *);
void (*or)(struct nv50_head *, struct nv50_head_atom *);
};
extern const struct nv50_head_func head507d;
#endif
This diff is collapsed.
/*
* 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 "oimm.h"
#include <nvif/class.h>
int
nv50_oimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw)
{
static const struct {
s32 oclass;
int version;
int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *);
} oimms[] = {
{ GK104_DISP_OVERLAY, 0, oimm507b_init },
{ GF110_DISP_OVERLAY, 0, oimm507b_init },
{ GT214_DISP_OVERLAY, 0, oimm507b_init },
{ G82_DISP_OVERLAY, 0, oimm507b_init },
{ NV50_DISP_OVERLAY, 0, oimm507b_init },
{}
};
struct nv50_disp *disp = nv50_disp(drm->dev);
int cid;
cid = nvif_mclass(&disp->disp->object, oimms);
if (cid < 0) {
NV_ERROR(drm, "No supported overlay immediate class\n");
return cid;
}
return oimms[cid].init(drm, oimms[cid].oclass, wndw);
}
#ifndef __NV50_KMS_OIMM_H__
#define __NV50_KMS_OIMM_H__
#include "wndw.h"
int oimm507b_init(struct nouveau_drm *, s32, struct nv50_wndw *);
int nv50_oimm_init(struct nouveau_drm *, struct nv50_wndw *);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment