Merge branch 'linux-4.21' of git://github.com/skeggsb/linux into drm-next
Mostly just initial support for Turing TU104/TU106 chipsets. Support for TU102 is missing as I don't yet have HW, but it should be trivial to add in later in the merge window (in theory). It's a bit of a rough first pass that'll get improved in future releases as a finish figuring out some of the other HW changes, but it's good enough as it stands for modesetting and suspend/resume etc. Acceleration bring-up is incomplete due to NVIDIA not yet having provided FW images for me to use, though command submission and copy engines are functional already. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Ben Skeggs <skeggsb@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv7KmfcQqZcx+wh_1UKjTovp4PH_5UVMfeyxUu-M9WLZfw@mail.gmail.com
This commit is contained in:
commit
02c4fb0210
@ -67,7 +67,7 @@ nv04_display_create(struct drm_device *dev)
|
||||
for (i = 0; i < dcb->entries; i++) {
|
||||
struct dcb_output *dcbent = &dcb->entry[i];
|
||||
|
||||
connector = nouveau_connector_create(dev, dcbent->connector);
|
||||
connector = nouveau_connector_create(dev, dcbent);
|
||||
if (IS_ERR(connector))
|
||||
continue;
|
||||
|
||||
|
@ -7,6 +7,7 @@ nouveau-y += dispnv50/core827d.o
|
||||
nouveau-y += dispnv50/core907d.o
|
||||
nouveau-y += dispnv50/core917d.o
|
||||
nouveau-y += dispnv50/corec37d.o
|
||||
nouveau-y += dispnv50/corec57d.o
|
||||
|
||||
nouveau-y += dispnv50/dac507d.o
|
||||
nouveau-y += dispnv50/dac907d.o
|
||||
@ -23,12 +24,14 @@ nouveau-y += dispnv50/head827d.o
|
||||
nouveau-y += dispnv50/head907d.o
|
||||
nouveau-y += dispnv50/head917d.o
|
||||
nouveau-y += dispnv50/headc37d.o
|
||||
nouveau-y += dispnv50/headc57d.o
|
||||
|
||||
nouveau-y += dispnv50/wimm.o
|
||||
nouveau-y += dispnv50/wimmc37b.o
|
||||
|
||||
nouveau-y += dispnv50/wndw.o
|
||||
nouveau-y += dispnv50/wndwc37e.o
|
||||
nouveau-y += dispnv50/wndwc57e.o
|
||||
|
||||
nouveau-y += dispnv50/base.o
|
||||
nouveau-y += dispnv50/base507c.o
|
||||
|
@ -54,9 +54,10 @@ struct nv50_head_atom {
|
||||
u64 offset:40;
|
||||
u8 buffer:1;
|
||||
u8 mode:4;
|
||||
u8 size:2;
|
||||
u16 size:11;
|
||||
u8 range:2;
|
||||
u8 output_mode:2;
|
||||
void (*load)(struct drm_color_lut *, int size, void __iomem *);
|
||||
} olut;
|
||||
|
||||
struct {
|
||||
@ -169,9 +170,11 @@ struct nv50_wndw_atom {
|
||||
u8 buffer:1;
|
||||
u8 enable:2;
|
||||
u8 mode:4;
|
||||
u8 size:2;
|
||||
u16 size:11;
|
||||
u8 range:2;
|
||||
u8 output_mode:2;
|
||||
void (*load)(struct drm_color_lut *, int size,
|
||||
void __iomem *);
|
||||
} i;
|
||||
} xlut;
|
||||
|
||||
|
@ -80,6 +80,7 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
asyw->xlut.i.mode = 7;
|
||||
asyw->xlut.i.enable = 2;
|
||||
asyw->xlut.i.load = head907d_olut_load;
|
||||
}
|
||||
|
||||
const struct nv50_wndw_func
|
||||
|
@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore)
|
||||
int version;
|
||||
int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
} cores[] = {
|
||||
{ TU104_DISP_CORE_CHANNEL_DMA, 0, corec57d_new },
|
||||
{ GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new },
|
||||
{ GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||
{ GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
|
||||
|
@ -46,5 +46,9 @@ extern const struct nv50_outp_func sor907d;
|
||||
int core917d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
|
||||
int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
|
||||
void corec37d_update(struct nv50_core *, u32 *, bool);
|
||||
extern const struct nv50_outp_func sorc37d;
|
||||
|
||||
int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **);
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <nouveau_bo.h>
|
||||
|
||||
static void
|
||||
void
|
||||
corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
|
||||
{
|
||||
u32 *push;
|
||||
@ -71,7 +71,7 @@ corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset)
|
||||
nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
corec37d_init(struct nv50_core *core)
|
||||
{
|
||||
const u32 windows = 8; /*XXX*/
|
||||
|
61
drivers/gpu/drm/nouveau/dispnv50/corec57d.c
Normal file
61
drivers/gpu/drm/nouveau/dispnv50/corec57d.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 void
|
||||
corec57d_init(struct nv50_core *core)
|
||||
{
|
||||
const u32 windows = 8; /*XXX*/
|
||||
u32 *push, i;
|
||||
if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) {
|
||||
evo_mthd(push, 0x0208, 1);
|
||||
evo_data(push, core->chan.sync.handle);
|
||||
for (i = 0; i < windows; i++) {
|
||||
evo_mthd(push, 0x1000 + (i * 0x080), 3);
|
||||
evo_data(push, i >> 1);
|
||||
evo_data(push, 0x0000000f);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_mthd(push, 0x1010 + (i * 0x080), 1);
|
||||
evo_data(push, 0x00117fff);
|
||||
}
|
||||
evo_mthd(push, 0x0200, 1);
|
||||
evo_data(push, 0x00000001);
|
||||
evo_kick(push, &core->chan);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct nv50_core_func
|
||||
corec57d = {
|
||||
.init = corec57d_init,
|
||||
.ntfy_init = corec37d_ntfy_init,
|
||||
.ntfy_wait_done = corec37d_ntfy_wait_done,
|
||||
.update = corec37d_update,
|
||||
.head = &headc57d,
|
||||
.sor = &sorc37d,
|
||||
};
|
||||
|
||||
int
|
||||
corec57d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
|
||||
{
|
||||
return core507d_new_(&corec57d, drm, oclass, pcore);
|
||||
}
|
@ -31,6 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
|
||||
int version;
|
||||
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||
} curses[] = {
|
||||
{ TU104_DISP_CURSOR, 0, cursc37a_new },
|
||||
{ GV100_DISP_CURSOR, 0, cursc37a_new },
|
||||
{ GK104_DISP_CURSOR, 0, curs907a_new },
|
||||
{ GF110_DISP_CURSOR, 0, curs907a_new },
|
||||
|
@ -1255,8 +1255,16 @@ nv50_mstm_fini(struct nv50_mstm *mstm)
|
||||
static void
|
||||
nv50_mstm_init(struct nv50_mstm *mstm)
|
||||
{
|
||||
if (mstm && mstm->mgr.mst_state)
|
||||
drm_dp_mst_topology_mgr_resume(&mstm->mgr);
|
||||
int ret;
|
||||
|
||||
if (!mstm || !mstm->mgr.mst_state)
|
||||
return;
|
||||
|
||||
ret = drm_dp_mst_topology_mgr_resume(&mstm->mgr);
|
||||
if (ret == -1) {
|
||||
drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false);
|
||||
drm_kms_helper_hotplug_event(mstm->mgr.dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2293,7 +2301,7 @@ nv50_display_create(struct drm_device *dev)
|
||||
|
||||
/* create encoder/connector objects based on VBIOS DCB table */
|
||||
for (i = 0, dcbe = &dcb->entry[0]; i < dcb->entries; i++, dcbe++) {
|
||||
connector = nouveau_connector_create(dev, dcbe->connector);
|
||||
connector = nouveau_connector_create(dev, dcbe);
|
||||
if (IS_ERR(connector))
|
||||
continue;
|
||||
|
||||
|
@ -45,6 +45,8 @@ struct nv50_disp_interlock {
|
||||
|
||||
void corec37d_ntfy_init(struct nouveau_bo *, u32);
|
||||
|
||||
void head907d_olut_load(struct drm_color_lut *, int size, void __iomem *);
|
||||
|
||||
struct nv50_chan {
|
||||
struct nvif_object user;
|
||||
struct nvif_device *device;
|
||||
|
@ -50,9 +50,9 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
if (asyh->set.core ) head->func->core_set(head, asyh);
|
||||
if (asyh->set.olut ) {
|
||||
asyh->olut.offset = nv50_lut_load(&head->olut,
|
||||
asyh->olut.mode <= 1,
|
||||
asyh->olut.buffer,
|
||||
asyh->state.gamma_lut);
|
||||
asyh->state.gamma_lut,
|
||||
asyh->olut.load);
|
||||
head->func->olut_set(head, asyh);
|
||||
}
|
||||
if (asyh->set.curs ) head->func->curs_set(head, asyh);
|
||||
@ -210,7 +210,7 @@ nv50_head_atomic_check_lut(struct nv50_head *head,
|
||||
}
|
||||
}
|
||||
|
||||
if (!olut) {
|
||||
if (!olut && !head->func->olut_identity) {
|
||||
asyh->olut.handle = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ struct nv50_head_func {
|
||||
void (*view)(struct nv50_head *, struct nv50_head_atom *);
|
||||
void (*mode)(struct nv50_head *, struct nv50_head_atom *);
|
||||
void (*olut)(struct nv50_head *, struct nv50_head_atom *);
|
||||
bool olut_identity;
|
||||
void (*olut_set)(struct nv50_head *, struct nv50_head_atom *);
|
||||
void (*olut_clr)(struct nv50_head *);
|
||||
void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
|
||||
@ -75,4 +76,14 @@ int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
|
||||
struct nv50_head_atom *);
|
||||
|
||||
extern const struct nv50_head_func headc37d;
|
||||
void headc37d_view(struct nv50_head *, struct nv50_head_atom *);
|
||||
void headc37d_core_set(struct nv50_head *, struct nv50_head_atom *);
|
||||
void headc37d_core_clr(struct nv50_head *);
|
||||
int headc37d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
|
||||
struct nv50_head_atom *);
|
||||
void headc37d_curs_set(struct nv50_head *, struct nv50_head_atom *);
|
||||
void headc37d_curs_clr(struct nv50_head *);
|
||||
void headc37d_dither(struct nv50_head *, struct nv50_head_atom *);
|
||||
|
||||
extern const struct nv50_head_func headc57d;
|
||||
#endif
|
||||
|
@ -254,6 +254,23 @@ head507d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
head507d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
|
||||
{
|
||||
for (; size--; in++, mem += 8) {
|
||||
writew(drm_color_lut_extract(in-> red, 11) << 3, mem + 0);
|
||||
writew(drm_color_lut_extract(in->green, 11) << 3, mem + 2);
|
||||
writew(drm_color_lut_extract(in-> blue, 11) << 3, mem + 4);
|
||||
}
|
||||
|
||||
/* INTERPOLATE modes require a "next" entry to interpolate with,
|
||||
* so we replicate the last entry to deal with this for now.
|
||||
*/
|
||||
writew(readw(mem - 8), mem + 0);
|
||||
writew(readw(mem - 6), mem + 2);
|
||||
writew(readw(mem - 4), mem + 4);
|
||||
}
|
||||
|
||||
void
|
||||
head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
@ -261,6 +278,8 @@ head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
asyh->olut.mode = 0;
|
||||
else
|
||||
asyh->olut.mode = 1;
|
||||
|
||||
asyh->olut.load = head507d_olut_load;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -213,10 +213,28 @@ head907d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
head907d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
|
||||
{
|
||||
for (; size--; in++, mem += 8) {
|
||||
writew(drm_color_lut_extract(in-> red, 14) + 0x6000, mem + 0);
|
||||
writew(drm_color_lut_extract(in->green, 14) + 0x6000, mem + 2);
|
||||
writew(drm_color_lut_extract(in-> blue, 14) + 0x6000, mem + 4);
|
||||
}
|
||||
|
||||
/* INTERPOLATE modes require a "next" entry to interpolate with,
|
||||
* so we replicate the last entry to deal with this for now.
|
||||
*/
|
||||
writew(readw(mem - 8), mem + 0);
|
||||
writew(readw(mem - 6), mem + 2);
|
||||
writew(readw(mem - 4), mem + 4);
|
||||
}
|
||||
|
||||
void
|
||||
head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
asyh->olut.mode = 7;
|
||||
asyh->olut.load = head907d_olut_load;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -65,7 +65,7 @@ headc37d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
headc37d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
@ -79,7 +79,7 @@ headc37d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
headc37d_curs_clr(struct nv50_head *head)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
@ -93,7 +93,7 @@ headc37d_curs_clr(struct nv50_head *head)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
headc37d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
@ -112,7 +112,7 @@ headc37d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
headc37d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
@ -155,6 +155,7 @@ headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
asyh->olut.size = 0;
|
||||
asyh->olut.range = 0;
|
||||
asyh->olut.output_mode = 1;
|
||||
asyh->olut.load = head907d_olut_load;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -181,7 +182,7 @@ headc37d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
headc37d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
|
206
drivers/gpu/drm/nouveau/dispnv50/headc57d.c
Normal file
206
drivers/gpu/drm/nouveau/dispnv50/headc57d.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "head.h"
|
||||
#include "atom.h"
|
||||
#include "core.h"
|
||||
|
||||
static void
|
||||
headc57d_or(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
/*XXX: This is a dirty hack until OR depth handling is
|
||||
* improved later for deep colour etc.
|
||||
*/
|
||||
switch (asyh->or.depth) {
|
||||
case 6: asyh->or.depth = 5; break;
|
||||
case 5: asyh->or.depth = 4; break;
|
||||
case 2: asyh->or.depth = 1; break;
|
||||
case 0: asyh->or.depth = 4; break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
|
||||
evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0xfc000001 |
|
||||
asyh->or.depth << 4 |
|
||||
asyh->or.nvsync << 3 |
|
||||
asyh->or.nhsync << 2);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc57d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1);
|
||||
#if 0
|
||||
evo_data(push, 0x80000000 |
|
||||
asyh->procamp.sat.sin << 16 |
|
||||
asyh->procamp.sat.cos << 4);
|
||||
#else
|
||||
evo_data(push, 0);
|
||||
#endif
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
headc57d_olut_clr(struct nv50_head *head)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 2))) {
|
||||
evo_mthd(push, 0x2288 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
headc57d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 4))) {
|
||||
evo_mthd(push, 0x2280 + (head->base.index * 0x400), 4);
|
||||
evo_data(push, asyh->olut.size << 8 |
|
||||
asyh->olut.mode << 2 |
|
||||
asyh->olut.output_mode);
|
||||
evo_data(push, 0xffffffff); /* FP_NORM_SCALE. */
|
||||
evo_data(push, asyh->olut.handle);
|
||||
evo_data(push, asyh->olut.offset >> 8);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
headc57d_olut_load_8(struct drm_color_lut *in, int size, void __iomem *mem)
|
||||
{
|
||||
memset_io(mem, 0x00, 0x20); /* VSS header. */
|
||||
mem += 0x20;
|
||||
|
||||
while (size--) {
|
||||
u16 r = drm_color_lut_extract(in-> red + 0, 16);
|
||||
u16 g = drm_color_lut_extract(in->green + 0, 16);
|
||||
u16 b = drm_color_lut_extract(in-> blue + 0, 16);
|
||||
u16 ri = 0, gi = 0, bi = 0, i;
|
||||
|
||||
if (in++, size) {
|
||||
ri = (drm_color_lut_extract(in-> red, 16) - r) / 4;
|
||||
gi = (drm_color_lut_extract(in->green, 16) - g) / 4;
|
||||
bi = (drm_color_lut_extract(in-> blue, 16) - b) / 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++, mem += 8) {
|
||||
writew(r + ri * i, mem + 0);
|
||||
writew(g + gi * i, mem + 2);
|
||||
writew(b + bi * i, mem + 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* INTERPOLATE modes require a "next" entry to interpolate with,
|
||||
* so we replicate the last entry to deal with this for now.
|
||||
*/
|
||||
writew(readw(mem - 8), mem + 0);
|
||||
writew(readw(mem - 6), mem + 2);
|
||||
writew(readw(mem - 4), mem + 4);
|
||||
}
|
||||
|
||||
static void
|
||||
headc57d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
|
||||
{
|
||||
memset_io(mem, 0x00, 0x20); /* VSS header. */
|
||||
mem += 0x20;
|
||||
|
||||
for (; size--; in++, mem += 0x08) {
|
||||
writew(drm_color_lut_extract(in-> red, 16), mem + 0);
|
||||
writew(drm_color_lut_extract(in->green, 16), mem + 2);
|
||||
writew(drm_color_lut_extract(in-> blue, 16), mem + 4);
|
||||
}
|
||||
|
||||
/* INTERPOLATE modes require a "next" entry to interpolate with,
|
||||
* so we replicate the last entry to deal with this for now.
|
||||
*/
|
||||
writew(readw(mem - 8), mem + 0);
|
||||
writew(readw(mem - 6), mem + 2);
|
||||
writew(readw(mem - 4), mem + 4);
|
||||
}
|
||||
|
||||
void
|
||||
headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
asyh->olut.mode = 2; /* DIRECT10 */
|
||||
asyh->olut.size = 4 /* VSS header. */ + 1024 + 1 /* Entries. */;
|
||||
asyh->olut.output_mode = 1; /* INTERPOLATE_ENABLE. */
|
||||
if (asyh->state.gamma_lut &&
|
||||
asyh->state.gamma_lut->length / sizeof(struct drm_color_lut) == 256)
|
||||
asyh->olut.load = headc57d_olut_load_8;
|
||||
else
|
||||
asyh->olut.load = headc57d_olut_load;
|
||||
}
|
||||
|
||||
static void
|
||||
headc57d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||
{
|
||||
struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan;
|
||||
struct nv50_head_mode *m = &asyh->mode;
|
||||
u32 *push;
|
||||
if ((push = evo_wait(core, 12))) {
|
||||
evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5);
|
||||
evo_data(push, (m->v.active << 16) | m->h.active );
|
||||
evo_data(push, (m->v.synce << 16) | m->h.synce );
|
||||
evo_data(push, (m->v.blanke << 16) | m->h.blanke );
|
||||
evo_data(push, (m->v.blanks << 16) | m->h.blanks );
|
||||
evo_data(push, (m->v.blank2e << 16) | m->v.blank2s);
|
||||
evo_mthd(push, 0x200c + (head->base.index * 0x400), 1);
|
||||
evo_data(push, m->clock * 1000);
|
||||
evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, m->clock * 1000);
|
||||
/*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */
|
||||
evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1);
|
||||
evo_data(push, 0x00001014);
|
||||
evo_kick(push, core);
|
||||
}
|
||||
}
|
||||
|
||||
const struct nv50_head_func
|
||||
headc57d = {
|
||||
.view = headc37d_view,
|
||||
.mode = headc57d_mode,
|
||||
.olut = headc57d_olut,
|
||||
.olut_identity = true,
|
||||
.olut_set = headc57d_olut_set,
|
||||
.olut_clr = headc57d_olut_clr,
|
||||
.curs_layout = head917d_curs_layout,
|
||||
.curs_format = headc37d_curs_format,
|
||||
.curs_set = headc37d_curs_set,
|
||||
.curs_clr = headc37d_curs_clr,
|
||||
.dither = headc37d_dither,
|
||||
.procamp = headc57d_procamp,
|
||||
.or = headc57d_or,
|
||||
};
|
@ -29,45 +29,29 @@
|
||||
#include <nvif/class.h>
|
||||
|
||||
u32
|
||||
nv50_lut_load(struct nv50_lut *lut, bool legacy, int buffer,
|
||||
struct drm_property_blob *blob)
|
||||
nv50_lut_load(struct nv50_lut *lut, int buffer, struct drm_property_blob *blob,
|
||||
void (*load)(struct drm_color_lut *, int, void __iomem *))
|
||||
{
|
||||
struct drm_color_lut *in = (struct drm_color_lut *)blob->data;
|
||||
struct drm_color_lut *in = blob ? blob->data : NULL;
|
||||
void __iomem *mem = lut->mem[buffer].object.map.ptr;
|
||||
const int size = blob->length / sizeof(*in);
|
||||
int bits, shift, i;
|
||||
u16 zero, r, g, b;
|
||||
u32 addr = lut->mem[buffer].addr;
|
||||
const u32 addr = lut->mem[buffer].addr;
|
||||
int i;
|
||||
|
||||
/* This can't happen.. But it shuts the compiler up. */
|
||||
if (WARN_ON(size != 256))
|
||||
return 0;
|
||||
|
||||
if (legacy) {
|
||||
bits = 11;
|
||||
shift = 3;
|
||||
zero = 0x0000;
|
||||
if (!in) {
|
||||
in = kvmalloc_array(1024, sizeof(*in), GFP_KERNEL);
|
||||
if (!WARN_ON(!in)) {
|
||||
for (i = 0; i < 1024; i++) {
|
||||
in[i].red =
|
||||
in[i].green =
|
||||
in[i].blue = (i << 16) >> 10;
|
||||
}
|
||||
load(in, 1024, mem);
|
||||
kvfree(in);
|
||||
}
|
||||
} else {
|
||||
bits = 14;
|
||||
shift = 0;
|
||||
zero = 0x6000;
|
||||
load(in, blob->length / sizeof(*in), mem);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift;
|
||||
g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift;
|
||||
b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift;
|
||||
writew(r, mem + (i * 0x08) + 0);
|
||||
writew(g, mem + (i * 0x08) + 2);
|
||||
writew(b, mem + (i * 0x08) + 4);
|
||||
}
|
||||
|
||||
/* INTERPOLATE modes require a "next" entry to interpolate with,
|
||||
* so we replicate the last entry to deal with this for now.
|
||||
*/
|
||||
writew(r, mem + (i * 0x08) + 0);
|
||||
writew(g, mem + (i * 0x08) + 2);
|
||||
writew(b, mem + (i * 0x08) + 4);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __NV50_KMS_LUT_H__
|
||||
#include <nvif/mem.h>
|
||||
struct drm_property_blob;
|
||||
struct drm_color_lut;
|
||||
struct nv50_disp;
|
||||
|
||||
struct nv50_lut {
|
||||
@ -10,6 +11,6 @@ struct nv50_lut {
|
||||
|
||||
int nv50_lut_init(struct nv50_disp *, struct nvif_mmu *, struct nv50_lut *);
|
||||
void nv50_lut_fini(struct nv50_lut *);
|
||||
u32 nv50_lut_load(struct nv50_lut *, bool legacy, int buffer,
|
||||
struct drm_property_blob *);
|
||||
u32 nv50_lut_load(struct nv50_lut *, int buffer, struct drm_property_blob *,
|
||||
void (*)(struct drm_color_lut *, int size, void __iomem *));
|
||||
#endif
|
||||
|
@ -31,6 +31,7 @@ nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw)
|
||||
int version;
|
||||
int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *);
|
||||
} wimms[] = {
|
||||
{ TU104_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init },
|
||||
{ GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init },
|
||||
{}
|
||||
};
|
||||
|
@ -139,10 +139,8 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
|
||||
if (asyw->set.xlut ) {
|
||||
if (asyw->ilut) {
|
||||
asyw->xlut.i.offset =
|
||||
nv50_lut_load(&wndw->ilut,
|
||||
asyw->xlut.i.mode <= 1,
|
||||
asyw->xlut.i.buffer,
|
||||
asyw->ilut);
|
||||
nv50_lut_load(&wndw->ilut, asyw->xlut.i.buffer,
|
||||
asyw->ilut, asyw->xlut.i.load);
|
||||
}
|
||||
wndw->func->xlut_set(wndw, asyw);
|
||||
}
|
||||
@ -322,6 +320,11 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
|
||||
asyh->wndw.olut &= ~BIT(wndw->id);
|
||||
}
|
||||
|
||||
if (!ilut && wndw->func->ilut_identity) {
|
||||
static struct drm_property_blob dummy = {};
|
||||
ilut = &dummy;
|
||||
}
|
||||
|
||||
/* Recalculate LUT state. */
|
||||
memset(&asyw->xlut, 0x00, sizeof(asyw->xlut));
|
||||
if ((asyw->ilut = wndw->func->ilut ? ilut : NULL)) {
|
||||
@ -623,6 +626,7 @@ nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
|
||||
int (*new)(struct nouveau_drm *, enum drm_plane_type,
|
||||
int, s32, struct nv50_wndw **);
|
||||
} wndws[] = {
|
||||
{ TU104_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new },
|
||||
{ GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new },
|
||||
{}
|
||||
};
|
||||
|
@ -65,6 +65,7 @@ struct nv50_wndw_func {
|
||||
int (*ntfy_wait_begun)(struct nouveau_bo *, u32 offset,
|
||||
struct nvif_device *);
|
||||
void (*ilut)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
bool ilut_identity;
|
||||
bool olut_core;
|
||||
void (*xlut_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void (*xlut_clr)(struct nv50_wndw *);
|
||||
@ -90,6 +91,23 @@ extern const struct nv50_wimm_func curs507a;
|
||||
|
||||
int wndwc37e_new(struct nouveau_drm *, enum drm_plane_type, int, s32,
|
||||
struct nv50_wndw **);
|
||||
int wndwc37e_new_(const struct nv50_wndw_func *, struct nouveau_drm *,
|
||||
enum drm_plane_type type, int index, s32 oclass, u32 heads,
|
||||
struct nv50_wndw **);
|
||||
int wndwc37e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||
struct nv50_head_atom *);
|
||||
void wndwc37e_release(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||
struct nv50_head_atom *);
|
||||
void wndwc37e_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_sema_clr(struct nv50_wndw *);
|
||||
void wndwc37e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_ntfy_clr(struct nv50_wndw *);
|
||||
void wndwc37e_image_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_image_clr(struct nv50_wndw *);
|
||||
void wndwc37e_update(struct nv50_wndw *, u32 *);
|
||||
|
||||
int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32,
|
||||
struct nv50_wndw **);
|
||||
|
||||
int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index,
|
||||
struct nv50_wndw **);
|
||||
|
@ -61,9 +61,10 @@ wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
asyw->xlut.i.size = 0;
|
||||
asyw->xlut.i.range = 0;
|
||||
asyw->xlut.i.output_mode = 1;
|
||||
asyw->xlut.i.load = head907d_olut_load;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_image_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
@ -76,7 +77,7 @@ wndwc37e_image_clr(struct nv50_wndw *wndw)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
@ -117,7 +118,7 @@ wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_ntfy_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
@ -128,7 +129,7 @@ wndwc37e_ntfy_clr(struct nv50_wndw *wndw)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
@ -140,7 +141,7 @@ wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_sema_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
@ -151,7 +152,7 @@ wndwc37e_sema_clr(struct nv50_wndw *wndw)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
@ -165,7 +166,7 @@ wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock)
|
||||
{
|
||||
u32 *push;
|
||||
@ -183,13 +184,13 @@ wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
wndwc37e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
wndwc37e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
struct nv50_head_atom *asyh)
|
||||
{
|
||||
@ -236,7 +237,7 @@ wndwc37e = {
|
||||
.update = wndwc37e_update,
|
||||
};
|
||||
|
||||
static int
|
||||
int
|
||||
wndwc37e_new_(const struct nv50_wndw_func *func, struct nouveau_drm *drm,
|
||||
enum drm_plane_type type, int index, s32 oclass, u32 heads,
|
||||
struct nv50_wndw **pwndw)
|
||||
|
133
drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
Normal file
133
drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2018 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "wndw.h"
|
||||
#include "atom.h"
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <nouveau_bo.h>
|
||||
|
||||
#include <nvif/clc37e.h>
|
||||
|
||||
static void
|
||||
wndwc57e_ilut_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||
evo_mthd(push, 0x0444, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 4))) {
|
||||
evo_mthd(push, 0x0440, 3);
|
||||
evo_data(push, asyw->xlut.i.size << 8 |
|
||||
asyw->xlut.i.mode << 2 |
|
||||
asyw->xlut.i.output_mode);
|
||||
evo_data(push, asyw->xlut.handle);
|
||||
evo_data(push, asyw->xlut.i.offset >> 8);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static u16
|
||||
fixedU0_16_FP16(u16 fixed)
|
||||
{
|
||||
int sign = 0, exp = 0, man = 0;
|
||||
if (fixed) {
|
||||
while (--exp && !(fixed & 0x8000))
|
||||
fixed <<= 1;
|
||||
man = ((fixed << 1) & 0xffc0) >> 6;
|
||||
exp += 15;
|
||||
}
|
||||
return (sign << 15) | (exp << 10) | man;
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc57e_ilut_load(struct drm_color_lut *in, int size, void __iomem *mem)
|
||||
{
|
||||
memset_io(mem, 0x00, 0x20); /* VSS header. */
|
||||
mem += 0x20;
|
||||
|
||||
for (; size--; in++, mem += 0x08) {
|
||||
u16 r = fixedU0_16_FP16(drm_color_lut_extract(in-> red, 16));
|
||||
u16 g = fixedU0_16_FP16(drm_color_lut_extract(in->green, 16));
|
||||
u16 b = fixedU0_16_FP16(drm_color_lut_extract(in-> blue, 16));
|
||||
writew(r, mem + 0);
|
||||
writew(g, mem + 2);
|
||||
writew(b, mem + 4);
|
||||
}
|
||||
|
||||
/* INTERPOLATE modes require a "next" entry to interpolate with,
|
||||
* so we replicate the last entry to deal with this for now.
|
||||
*/
|
||||
writew(readw(mem - 8), mem + 0);
|
||||
writew(readw(mem - 6), mem + 2);
|
||||
writew(readw(mem - 4), mem + 4);
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u16 size = asyw->ilut->length / sizeof(struct drm_color_lut);
|
||||
if (size == 256) {
|
||||
asyw->xlut.i.mode = 1; /* DIRECT8. */
|
||||
} else {
|
||||
asyw->xlut.i.mode = 2; /* DIRECT10. */
|
||||
size = 1024;
|
||||
}
|
||||
asyw->xlut.i.size = 4 /* VSS header. */ + size + 1 /* Entries. */;
|
||||
asyw->xlut.i.output_mode = 0; /* INTERPOLATE_DISABLE. */
|
||||
asyw->xlut.i.load = wndwc57e_ilut_load;
|
||||
}
|
||||
|
||||
static const struct nv50_wndw_func
|
||||
wndwc57e = {
|
||||
.acquire = wndwc37e_acquire,
|
||||
.release = wndwc37e_release,
|
||||
.sema_set = wndwc37e_sema_set,
|
||||
.sema_clr = wndwc37e_sema_clr,
|
||||
.ntfy_set = wndwc37e_ntfy_set,
|
||||
.ntfy_clr = wndwc37e_ntfy_clr,
|
||||
.ntfy_reset = corec37d_ntfy_init,
|
||||
.ntfy_wait_begun = base507c_ntfy_wait_begun,
|
||||
.ilut = wndwc57e_ilut,
|
||||
.ilut_identity = true,
|
||||
.xlut_set = wndwc57e_ilut_set,
|
||||
.xlut_clr = wndwc57e_ilut_clr,
|
||||
.image_set = wndwc37e_image_set,
|
||||
.image_clr = wndwc37e_image_clr,
|
||||
.update = wndwc37e_update,
|
||||
};
|
||||
|
||||
int
|
||||
wndwc57e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
|
||||
s32 oclass, struct nv50_wndw **pwndw)
|
||||
{
|
||||
return wndwc37e_new_(&wndwc57e, drm, type, index, oclass,
|
||||
BIT(index >> 1), pwndw);
|
||||
}
|
@ -32,6 +32,7 @@ struct nv_device_info_v0 {
|
||||
#define NV_DEVICE_INFO_V0_MAXWELL 0x09
|
||||
#define NV_DEVICE_INFO_V0_PASCAL 0x0a
|
||||
#define NV_DEVICE_INFO_V0_VOLTA 0x0b
|
||||
#define NV_DEVICE_INFO_V0_TURING 0x0c
|
||||
__u8 family;
|
||||
__u8 pad06[2];
|
||||
__u64 ram_size;
|
||||
|
@ -4,12 +4,13 @@
|
||||
|
||||
struct kepler_channel_gpfifo_a_v0 {
|
||||
__u8 version;
|
||||
__u8 pad01[1];
|
||||
__u8 priv;
|
||||
__u16 chid;
|
||||
__u32 ilength;
|
||||
__u64 ioffset;
|
||||
__u64 runlist;
|
||||
__u64 vmm;
|
||||
__u64 inst;
|
||||
};
|
||||
|
||||
#define NVA06F_V0_NTFY_NON_STALL_INTERRUPT 0x00
|
||||
|
@ -68,7 +68,8 @@
|
||||
#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f
|
||||
#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
|
||||
#define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f
|
||||
#define VOLTA_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c36f
|
||||
#define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f
|
||||
#define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c46f
|
||||
|
||||
#define NV50_DISP /* cl5070.h */ 0x00005070
|
||||
#define G82_DISP /* cl5070.h */ 0x00008270
|
||||
@ -83,6 +84,7 @@
|
||||
#define GP100_DISP /* cl5070.h */ 0x00009770
|
||||
#define GP102_DISP /* cl5070.h */ 0x00009870
|
||||
#define GV100_DISP /* cl5070.h */ 0x0000c370
|
||||
#define TU104_DISP /* cl5070.h */ 0x0000c570
|
||||
|
||||
#define NV31_MPEG 0x00003174
|
||||
#define G82_MPEG 0x00008274
|
||||
@ -95,6 +97,7 @@
|
||||
#define GF110_DISP_CURSOR /* cl507a.h */ 0x0000907a
|
||||
#define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a
|
||||
#define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a
|
||||
#define TU104_DISP_CURSOR /* cl507a.h */ 0x0000c57a
|
||||
|
||||
#define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b
|
||||
#define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b
|
||||
@ -103,6 +106,7 @@
|
||||
#define GK104_DISP_OVERLAY /* cl507b.h */ 0x0000917b
|
||||
|
||||
#define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b
|
||||
#define TU104_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c57b
|
||||
|
||||
#define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c
|
||||
#define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c
|
||||
@ -125,6 +129,7 @@
|
||||
#define GP100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000977d
|
||||
#define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d
|
||||
#define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d
|
||||
#define TU104_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d
|
||||
|
||||
#define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e
|
||||
#define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e
|
||||
@ -134,6 +139,7 @@
|
||||
#define GK104_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000917e
|
||||
|
||||
#define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e
|
||||
#define TU104_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e
|
||||
|
||||
#define NV50_TESLA 0x00005097
|
||||
#define G82_TESLA 0x00008297
|
||||
@ -183,6 +189,7 @@
|
||||
#define PASCAL_DMA_COPY_A 0x0000c0b5
|
||||
#define PASCAL_DMA_COPY_B 0x0000c1b5
|
||||
#define VOLTA_DMA_COPY_A 0x0000c3b5
|
||||
#define TURING_DMA_COPY_A 0x0000c5b5
|
||||
|
||||
#define FERMI_DECOMPRESS 0x000090b8
|
||||
|
||||
|
19
drivers/gpu/drm/nouveau/include/nvif/clc36f.h
Normal file
19
drivers/gpu/drm/nouveau/include/nvif/clc36f.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __NVIF_CLC36F_H__
|
||||
#define __NVIF_CLC36F_H__
|
||||
|
||||
struct volta_channel_gpfifo_a_v0 {
|
||||
__u8 version;
|
||||
__u8 priv;
|
||||
__u16 chid;
|
||||
__u32 ilength;
|
||||
__u64 ioffset;
|
||||
__u64 runlist;
|
||||
__u64 vmm;
|
||||
__u64 inst;
|
||||
__u32 token;
|
||||
};
|
||||
|
||||
#define NVC36F_V0_NTFY_NON_STALL_INTERRUPT 0x00
|
||||
#define NVC36F_V0_NTFY_KILLED 0x01
|
||||
#endif
|
@ -61,7 +61,11 @@ enum nvkm_devidx {
|
||||
NVKM_ENGINE_NVENC2,
|
||||
NVKM_ENGINE_NVENC_LAST = NVKM_ENGINE_NVENC2,
|
||||
|
||||
NVKM_ENGINE_NVDEC,
|
||||
NVKM_ENGINE_NVDEC0,
|
||||
NVKM_ENGINE_NVDEC1,
|
||||
NVKM_ENGINE_NVDEC2,
|
||||
NVKM_ENGINE_NVDEC_LAST = NVKM_ENGINE_NVDEC2,
|
||||
|
||||
NVKM_ENGINE_PM,
|
||||
NVKM_ENGINE_SEC,
|
||||
NVKM_ENGINE_SEC2,
|
||||
@ -114,6 +118,7 @@ struct nvkm_device {
|
||||
GM100 = 0x110,
|
||||
GP100 = 0x130,
|
||||
GV100 = 0x140,
|
||||
TU100 = 0x160,
|
||||
} card_type;
|
||||
u32 chipset;
|
||||
u8 chiprev;
|
||||
@ -163,7 +168,7 @@ struct nvkm_device {
|
||||
struct nvkm_engine *msppp;
|
||||
struct nvkm_engine *msvld;
|
||||
struct nvkm_engine *nvenc[3];
|
||||
struct nvkm_nvdec *nvdec;
|
||||
struct nvkm_nvdec *nvdec[3];
|
||||
struct nvkm_pm *pm;
|
||||
struct nvkm_engine *sec;
|
||||
struct nvkm_sec2 *sec2;
|
||||
@ -235,7 +240,7 @@ struct nvkm_device_chip {
|
||||
int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **);
|
||||
int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **);
|
||||
int (*nvenc[3])(struct nvkm_device *, int idx, struct nvkm_engine **);
|
||||
int (*nvdec )(struct nvkm_device *, int idx, struct nvkm_nvdec **);
|
||||
int (*nvdec[3])(struct nvkm_device *, int idx, struct nvkm_nvdec **);
|
||||
int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **);
|
||||
int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **);
|
||||
int (*sec2 )(struct nvkm_device *, int idx, struct nvkm_sec2 **);
|
||||
|
@ -29,6 +29,7 @@ struct nvkm_memory_func {
|
||||
void *(*dtor)(struct nvkm_memory *);
|
||||
enum nvkm_memory_target (*target)(struct nvkm_memory *);
|
||||
u8 (*page)(struct nvkm_memory *);
|
||||
u64 (*bar2)(struct nvkm_memory *);
|
||||
u64 (*addr)(struct nvkm_memory *);
|
||||
u64 (*size)(struct nvkm_memory *);
|
||||
void (*boot)(struct nvkm_memory *, struct nvkm_vmm *);
|
||||
@ -56,6 +57,7 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *,
|
||||
|
||||
#define nvkm_memory_target(p) (p)->func->target(p)
|
||||
#define nvkm_memory_page(p) (p)->func->page(p)
|
||||
#define nvkm_memory_bar2(p) (p)->func->bar2(p)
|
||||
#define nvkm_memory_addr(p) (p)->func->addr(p)
|
||||
#define nvkm_memory_size(p) (p)->func->size(p)
|
||||
#define nvkm_memory_boot(p,v) (p)->func->boot((p),(v))
|
||||
|
@ -11,4 +11,5 @@ int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
|
||||
int gp100_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
|
||||
int gp102_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
|
||||
int gv100_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
|
||||
int tu104_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
|
||||
#endif
|
||||
|
@ -36,4 +36,5 @@ int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
|
||||
int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
|
||||
int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
|
||||
int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
|
||||
int tu104_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
|
||||
#endif
|
||||
|
@ -74,4 +74,5 @@ int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||
int gp100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||
int gp10b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||
int gv100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||
int tu104_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||
#endif
|
||||
|
@ -16,8 +16,10 @@ struct nvkm_bar {
|
||||
};
|
||||
|
||||
struct nvkm_vmm *nvkm_bar_bar1_vmm(struct nvkm_device *);
|
||||
void nvkm_bar_bar1_reset(struct nvkm_device *);
|
||||
void nvkm_bar_bar2_init(struct nvkm_device *);
|
||||
void nvkm_bar_bar2_fini(struct nvkm_device *);
|
||||
void nvkm_bar_bar2_reset(struct nvkm_device *);
|
||||
struct nvkm_vmm *nvkm_bar_bar2_vmm(struct nvkm_device *);
|
||||
void nvkm_bar_flush(struct nvkm_bar *);
|
||||
|
||||
@ -27,4 +29,5 @@ int gf100_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
|
||||
int gk20a_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
|
||||
int gm107_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
|
||||
int gm20b_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
|
||||
int tu104_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
|
||||
#endif
|
||||
|
@ -12,11 +12,14 @@ u32 nvbios_M0203Tp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
|
||||
struct nvbios_M0203T *);
|
||||
|
||||
struct nvbios_M0203E {
|
||||
#define M0203E_TYPE_DDR2 0x0
|
||||
#define M0203E_TYPE_DDR3 0x1
|
||||
#define M0203E_TYPE_GDDR3 0x2
|
||||
#define M0203E_TYPE_GDDR5 0x3
|
||||
#define M0203E_TYPE_SKIP 0xf
|
||||
#define M0203E_TYPE_DDR2 0x0
|
||||
#define M0203E_TYPE_DDR3 0x1
|
||||
#define M0203E_TYPE_GDDR3 0x2
|
||||
#define M0203E_TYPE_GDDR5 0x3
|
||||
#define M0203E_TYPE_HBM2 0x6
|
||||
#define M0203E_TYPE_GDDR5X 0x8
|
||||
#define M0203E_TYPE_GDDR6 0x9
|
||||
#define M0203E_TYPE_SKIP 0xf
|
||||
u8 type;
|
||||
u8 strap;
|
||||
u8 group;
|
||||
|
@ -20,6 +20,7 @@ enum dcb_connector_type {
|
||||
DCB_CONNECTOR_DMS59_DP0 = 0x64,
|
||||
DCB_CONNECTOR_DMS59_DP1 = 0x65,
|
||||
DCB_CONNECTOR_WFD = 0x70,
|
||||
DCB_CONNECTOR_USB_C = 0x71,
|
||||
DCB_CONNECTOR_NONE = 0xff
|
||||
};
|
||||
|
||||
|
@ -31,4 +31,5 @@ int gf100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
|
||||
int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
|
||||
int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
|
||||
int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
|
||||
int tu104_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
|
||||
#endif
|
||||
|
@ -30,4 +30,5 @@ struct nvkm_fault_data {
|
||||
|
||||
int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
|
||||
int gv100_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
|
||||
int tu104_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
|
||||
#endif
|
||||
|
@ -105,7 +105,10 @@ enum nvkm_ram_type {
|
||||
NVKM_RAM_TYPE_GDDR2,
|
||||
NVKM_RAM_TYPE_GDDR3,
|
||||
NVKM_RAM_TYPE_GDDR4,
|
||||
NVKM_RAM_TYPE_GDDR5
|
||||
NVKM_RAM_TYPE_GDDR5,
|
||||
NVKM_RAM_TYPE_GDDR5X,
|
||||
NVKM_RAM_TYPE_GDDR6,
|
||||
NVKM_RAM_TYPE_HBM2,
|
||||
};
|
||||
|
||||
struct nvkm_ram {
|
||||
|
@ -31,4 +31,5 @@ int gk104_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
|
||||
int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
|
||||
int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
|
||||
int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
|
||||
int tu104_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
|
||||
#endif
|
||||
|
@ -130,4 +130,5 @@ int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
|
||||
int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
|
||||
int gp10b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
|
||||
int gv100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
|
||||
int tu104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
|
||||
#endif
|
||||
|
@ -28,6 +28,18 @@ struct nvkm_timer {
|
||||
u64 nvkm_timer_read(struct nvkm_timer *);
|
||||
void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *);
|
||||
|
||||
struct nvkm_timer_wait {
|
||||
struct nvkm_timer *tmr;
|
||||
u64 limit;
|
||||
u64 time0;
|
||||
u64 time1;
|
||||
int reads;
|
||||
};
|
||||
|
||||
void nvkm_timer_wait_init(struct nvkm_device *, u64 nsec,
|
||||
struct nvkm_timer_wait *);
|
||||
s64 nvkm_timer_wait_test(struct nvkm_timer_wait *);
|
||||
|
||||
/* Delay based on GPU time (ie. PTIMER).
|
||||
*
|
||||
* Will return -ETIMEDOUT unless the loop was terminated with 'break',
|
||||
@ -38,21 +50,17 @@ void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *);
|
||||
*/
|
||||
#define NVKM_DELAY _warn = false;
|
||||
#define nvkm_nsec(d,n,cond...) ({ \
|
||||
struct nvkm_device *_device = (d); \
|
||||
struct nvkm_timer *_tmr = _device->timer; \
|
||||
u64 _nsecs = (n), _time0 = nvkm_timer_read(_tmr); \
|
||||
s64 _taken = 0; \
|
||||
struct nvkm_timer_wait _wait; \
|
||||
bool _warn = true; \
|
||||
s64 _taken = 0; \
|
||||
\
|
||||
nvkm_timer_wait_init((d), (n), &_wait); \
|
||||
do { \
|
||||
cond \
|
||||
} while (_taken = nvkm_timer_read(_tmr) - _time0, _taken < _nsecs); \
|
||||
} while ((_taken = nvkm_timer_wait_test(&_wait)) >= 0); \
|
||||
\
|
||||
if (_taken >= _nsecs) { \
|
||||
if (_warn) \
|
||||
dev_WARN(_device->dev, "timeout\n"); \
|
||||
_taken = -ETIMEDOUT; \
|
||||
} \
|
||||
if (_warn && _taken < 0) \
|
||||
dev_WARN(_wait.tmr->subdev.device->dev, "timeout\n"); \
|
||||
_taken; \
|
||||
})
|
||||
#define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond)
|
||||
|
@ -306,7 +306,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
|
||||
|
||||
/* create channel object and initialise dma and fence management */
|
||||
ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
|
||||
init->tt_ctxdma_handle, &chan->chan);
|
||||
init->tt_ctxdma_handle, false, &chan->chan);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
|
@ -1141,6 +1141,8 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
|
||||
struct ttm_mem_reg *, struct ttm_mem_reg *);
|
||||
int (*init)(struct nouveau_channel *, u32 handle);
|
||||
} _methods[] = {
|
||||
{ "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },
|
||||
{ "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init },
|
||||
{ "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init },
|
||||
{ "GRCE", 0, 0xc3b5, nve0_bo_move_copy, nvc0_bo_move_init },
|
||||
{ "COPY", 4, 0xc1b5, nve0_bo_move_copy, nve0_bo_move_init },
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <nvif/cl506f.h>
|
||||
#include <nvif/cl906f.h>
|
||||
#include <nvif/cla06f.h>
|
||||
#include <nvif/clc36f.h>
|
||||
#include <nvif/ioctl.h>
|
||||
|
||||
/*XXX*/
|
||||
@ -217,10 +218,11 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
|
||||
static int
|
||||
nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
u64 runlist, struct nouveau_channel **pchan)
|
||||
u64 runlist, bool priv, struct nouveau_channel **pchan)
|
||||
{
|
||||
struct nouveau_cli *cli = (void *)device->object.client;
|
||||
static const u16 oclasses[] = { VOLTA_CHANNEL_GPFIFO_A,
|
||||
static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A,
|
||||
VOLTA_CHANNEL_GPFIFO_A,
|
||||
PASCAL_CHANNEL_GPFIFO_A,
|
||||
MAXWELL_CHANNEL_GPFIFO_A,
|
||||
KEPLER_CHANNEL_GPFIFO_B,
|
||||
@ -234,6 +236,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
struct nv50_channel_gpfifo_v0 nv50;
|
||||
struct fermi_channel_gpfifo_v0 fermi;
|
||||
struct kepler_channel_gpfifo_a_v0 kepler;
|
||||
struct volta_channel_gpfifo_a_v0 volta;
|
||||
} args;
|
||||
struct nouveau_channel *chan;
|
||||
u32 size;
|
||||
@ -247,12 +250,22 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
|
||||
/* create channel object */
|
||||
do {
|
||||
if (oclass[0] >= VOLTA_CHANNEL_GPFIFO_A) {
|
||||
args.volta.version = 0;
|
||||
args.volta.ilength = 0x02000;
|
||||
args.volta.ioffset = 0x10000 + chan->push.addr;
|
||||
args.volta.runlist = runlist;
|
||||
args.volta.vmm = nvif_handle(&cli->vmm.vmm.object);
|
||||
args.volta.priv = priv;
|
||||
size = sizeof(args.volta);
|
||||
} else
|
||||
if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) {
|
||||
args.kepler.version = 0;
|
||||
args.kepler.ilength = 0x02000;
|
||||
args.kepler.ioffset = 0x10000 + chan->push.addr;
|
||||
args.kepler.runlist = runlist;
|
||||
args.kepler.vmm = nvif_handle(&cli->vmm.vmm.object);
|
||||
args.kepler.priv = priv;
|
||||
size = sizeof(args.kepler);
|
||||
} else
|
||||
if (oclass[0] >= FERMI_CHANNEL_GPFIFO) {
|
||||
@ -273,13 +286,20 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
ret = nvif_object_init(&device->object, 0, *oclass++,
|
||||
&args, size, &chan->user);
|
||||
if (ret == 0) {
|
||||
if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A)
|
||||
if (chan->user.oclass >= VOLTA_CHANNEL_GPFIFO_A) {
|
||||
chan->chid = args.volta.chid;
|
||||
chan->inst = args.volta.inst;
|
||||
chan->token = args.volta.token;
|
||||
} else
|
||||
if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) {
|
||||
chan->chid = args.kepler.chid;
|
||||
else
|
||||
if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO)
|
||||
chan->inst = args.kepler.inst;
|
||||
} else
|
||||
if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
|
||||
chan->chid = args.fermi.chid;
|
||||
else
|
||||
} else {
|
||||
chan->chid = args.nv50.chid;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} while (*oclass);
|
||||
@ -448,7 +468,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
|
||||
|
||||
int
|
||||
nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
u32 arg0, u32 arg1, struct nouveau_channel **pchan)
|
||||
u32 arg0, u32 arg1, bool priv,
|
||||
struct nouveau_channel **pchan)
|
||||
{
|
||||
struct nouveau_cli *cli = (void *)device->object.client;
|
||||
bool super;
|
||||
@ -458,7 +479,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
super = cli->base.super;
|
||||
cli->base.super = true;
|
||||
|
||||
ret = nouveau_channel_ind(drm, device, arg0, pchan);
|
||||
ret = nouveau_channel_ind(drm, device, arg0, priv, pchan);
|
||||
if (ret) {
|
||||
NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
|
||||
ret = nouveau_channel_dma(drm, device, pchan);
|
||||
|
@ -10,6 +10,8 @@ struct nouveau_channel {
|
||||
struct nouveau_drm *drm;
|
||||
|
||||
int chid;
|
||||
u64 inst;
|
||||
u32 token;
|
||||
|
||||
struct nvif_object vram;
|
||||
struct nvif_object gart;
|
||||
@ -48,7 +50,8 @@ struct nouveau_channel {
|
||||
int nouveau_channels_init(struct nouveau_drm *);
|
||||
|
||||
int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *,
|
||||
u32 arg0, u32 arg1, struct nouveau_channel **);
|
||||
u32 arg0, u32 arg1, bool priv,
|
||||
struct nouveau_channel **);
|
||||
void nouveau_channel_del(struct nouveau_channel **);
|
||||
int nouveau_channel_idle(struct nouveau_channel *);
|
||||
|
||||
|
@ -403,6 +403,7 @@ nouveau_connector_destroy(struct drm_connector *connector)
|
||||
if (nv_connector->aux.transfer) {
|
||||
drm_dp_cec_unregister_connector(&nv_connector->aux);
|
||||
drm_dp_aux_unregister(&nv_connector->aux);
|
||||
kfree(nv_connector->aux.name);
|
||||
}
|
||||
kfree(connector);
|
||||
}
|
||||
@ -1218,7 +1219,8 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb)
|
||||
case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS;
|
||||
case DCB_CONNECTOR_DMS59_DP0:
|
||||
case DCB_CONNECTOR_DMS59_DP1:
|
||||
case DCB_CONNECTOR_DP : return DRM_MODE_CONNECTOR_DisplayPort;
|
||||
case DCB_CONNECTOR_DP :
|
||||
case DCB_CONNECTOR_USB_C : return DRM_MODE_CONNECTOR_DisplayPort;
|
||||
case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP;
|
||||
case DCB_CONNECTOR_HDMI_0 :
|
||||
case DCB_CONNECTOR_HDMI_1 :
|
||||
@ -1232,7 +1234,8 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb)
|
||||
}
|
||||
|
||||
struct drm_connector *
|
||||
nouveau_connector_create(struct drm_device *dev, int index)
|
||||
nouveau_connector_create(struct drm_device *dev,
|
||||
const struct dcb_output *dcbe)
|
||||
{
|
||||
const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
@ -1240,6 +1243,8 @@ nouveau_connector_create(struct drm_device *dev, int index)
|
||||
struct nouveau_connector *nv_connector = NULL;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
char aux_name[48] = {0};
|
||||
int index = dcbe->connector;
|
||||
int type, ret = 0;
|
||||
bool dummy;
|
||||
|
||||
@ -1342,6 +1347,9 @@ nouveau_connector_create(struct drm_device *dev, int index)
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
nv_connector->aux.dev = dev->dev;
|
||||
nv_connector->aux.transfer = nouveau_connector_aux_xfer;
|
||||
snprintf(aux_name, sizeof(aux_name), "sor-%04x-%04x",
|
||||
dcbe->hasht, dcbe->hashm);
|
||||
nv_connector->aux.name = kstrdup(aux_name, GFP_KERNEL);
|
||||
ret = drm_dp_aux_register(&nv_connector->aux);
|
||||
if (ret) {
|
||||
NV_ERROR(drm, "failed to register aux channel\n");
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nouveau_encoder.h"
|
||||
|
||||
struct nvkm_i2c_port;
|
||||
struct dcb_output;
|
||||
|
||||
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
|
||||
struct nouveau_backlight;
|
||||
@ -113,7 +114,7 @@ nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
|
||||
}
|
||||
|
||||
struct drm_connector *
|
||||
nouveau_connector_create(struct drm_device *, int index);
|
||||
nouveau_connector_create(struct drm_device *, const struct dcb_output *);
|
||||
|
||||
extern int nouveau_tv_disable;
|
||||
extern int nouveau_ignorelid;
|
||||
|
@ -46,6 +46,26 @@ nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_debugfs_strap_peek(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = m->private;
|
||||
struct nouveau_drm *drm = nouveau_drm(node->minor->dev);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(drm->dev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
|
||||
seq_printf(m, "0x%08x\n",
|
||||
nvif_rd32(&drm->client.device.object, 0x101000));
|
||||
|
||||
pm_runtime_mark_last_busy(drm->dev->dev);
|
||||
pm_runtime_put_autosuspend(drm->dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
|
||||
{
|
||||
@ -185,7 +205,8 @@ static const struct file_operations nouveau_pstate_fops = {
|
||||
};
|
||||
|
||||
static struct drm_info_list nouveau_debugfs_list[] = {
|
||||
{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
|
||||
{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
|
||||
{ "strap_peek", nouveau_debugfs_strap_peek, 0, NULL },
|
||||
};
|
||||
#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
|
||||
|
||||
@ -199,8 +220,9 @@ static const struct nouveau_debugfs_files {
|
||||
int
|
||||
nouveau_drm_debugfs_init(struct drm_minor *minor)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(minor->dev);
|
||||
struct dentry *dentry;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nouveau_debugfs_files); i++) {
|
||||
dentry = debugfs_create_file(nouveau_debugfs_files[i].name,
|
||||
@ -211,9 +233,23 @@ nouveau_drm_debugfs_init(struct drm_minor *minor)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return drm_debugfs_create_files(nouveau_debugfs_list,
|
||||
NOUVEAU_DEBUGFS_ENTRIES,
|
||||
minor->debugfs_root, minor);
|
||||
ret = drm_debugfs_create_files(nouveau_debugfs_list,
|
||||
NOUVEAU_DEBUGFS_ENTRIES,
|
||||
minor->debugfs_root, minor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set the size of the vbios since we know it, and it's confusing to
|
||||
* userspace if it wants to seek() but the file has a length of 0
|
||||
*/
|
||||
dentry = debugfs_lookup("vbios.rom", minor->debugfs_root);
|
||||
if (!dentry)
|
||||
return 0;
|
||||
|
||||
d_inode(dentry)->i_size = drm->vbios.length;
|
||||
dput(dentry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -101,7 +101,7 @@ nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
|
||||
|
||||
nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put);
|
||||
if (user->func && user->func->doorbell)
|
||||
user->func->doorbell(user, chan->chid);
|
||||
user->func->doorbell(user, chan->token);
|
||||
chan->dma.ib_free--;
|
||||
}
|
||||
|
||||
|
@ -353,6 +353,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
||||
case MAXWELL_CHANNEL_GPFIFO_A:
|
||||
case PASCAL_CHANNEL_GPFIFO_A:
|
||||
case VOLTA_CHANNEL_GPFIFO_A:
|
||||
case TURING_CHANNEL_GPFIFO_A:
|
||||
ret = nvc0_fence_create(drm);
|
||||
break;
|
||||
default:
|
||||
@ -370,7 +371,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
||||
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
|
||||
ret = nouveau_channel_new(drm, &drm->client.device,
|
||||
nvif_fifo_runlist_ce(device), 0,
|
||||
&drm->cechan);
|
||||
true, &drm->cechan);
|
||||
if (ret)
|
||||
NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
|
||||
|
||||
@ -381,7 +382,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
||||
device->info.chipset != 0xaa &&
|
||||
device->info.chipset != 0xac) {
|
||||
ret = nouveau_channel_new(drm, &drm->client.device,
|
||||
NvDmaFB, NvDmaTT, &drm->cechan);
|
||||
NvDmaFB, NvDmaTT, false,
|
||||
&drm->cechan);
|
||||
if (ret)
|
||||
NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
|
||||
|
||||
@ -393,7 +395,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
||||
}
|
||||
|
||||
ret = nouveau_channel_new(drm, &drm->client.device,
|
||||
arg0, arg1, &drm->channel);
|
||||
arg0, arg1, false, &drm->channel);
|
||||
if (ret) {
|
||||
NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
|
||||
nouveau_accel_fini(drm);
|
||||
|
@ -25,7 +25,6 @@ void nouveau_vma_unmap(struct nouveau_vma *);
|
||||
struct nouveau_vmm {
|
||||
struct nouveau_cli *cli;
|
||||
struct nvif_vmm vmm;
|
||||
struct nvkm_vm *vm;
|
||||
};
|
||||
|
||||
int nouveau_vmm_init(struct nouveau_cli *, s32 oclass, struct nouveau_vmm *);
|
||||
|
@ -34,6 +34,7 @@ int
|
||||
nvif_disp_ctor(struct nvif_device *device, s32 oclass, struct nvif_disp *disp)
|
||||
{
|
||||
static const struct nvif_mclass disps[] = {
|
||||
{ TU104_DISP, -1 },
|
||||
{ GV100_DISP, -1 },
|
||||
{ GP102_DISP, -1 },
|
||||
{ GP100_DISP, -1 },
|
||||
|
@ -79,7 +79,9 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = {
|
||||
[NVKM_ENGINE_NVENC0 ] = "nvenc0",
|
||||
[NVKM_ENGINE_NVENC1 ] = "nvenc1",
|
||||
[NVKM_ENGINE_NVENC2 ] = "nvenc2",
|
||||
[NVKM_ENGINE_NVDEC ] = "nvdec",
|
||||
[NVKM_ENGINE_NVDEC0 ] = "nvdec0",
|
||||
[NVKM_ENGINE_NVDEC1 ] = "nvdec1",
|
||||
[NVKM_ENGINE_NVDEC2 ] = "nvdec2",
|
||||
[NVKM_ENGINE_PM ] = "pm",
|
||||
[NVKM_ENGINE_SEC ] = "sec",
|
||||
[NVKM_ENGINE_SEC2 ] = "sec2",
|
||||
|
@ -6,3 +6,4 @@ nvkm-y += nvkm/engine/ce/gm200.o
|
||||
nvkm-y += nvkm/engine/ce/gp100.o
|
||||
nvkm-y += nvkm/engine/ce/gp102.o
|
||||
nvkm-y += nvkm/engine/ce/gv100.o
|
||||
nvkm-y += nvkm/engine/ce/tu104.o
|
||||
|
40
drivers/gpu/drm/nouveau/nvkm/engine/ce/tu104.c
Normal file
40
drivers/gpu/drm/nouveau/nvkm/engine/ce/tu104.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 "priv.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static const struct nvkm_engine_func
|
||||
tu104_ce = {
|
||||
.intr = gp100_ce_intr,
|
||||
.sclass = {
|
||||
{ -1, -1, TURING_DMA_COPY_A },
|
||||
{}
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
tu104_ce_new(struct nvkm_device *device, int index,
|
||||
struct nvkm_engine **pengine)
|
||||
{
|
||||
return nvkm_engine_new_(&tu104_ce, device, index, true, pengine);
|
||||
}
|
@ -2221,7 +2221,7 @@ nv132_chipset = {
|
||||
.dma = gf119_dma_new,
|
||||
.fifo = gp100_fifo_new,
|
||||
.gr = gp102_gr_new,
|
||||
.nvdec = gp102_nvdec_new,
|
||||
.nvdec[0] = gp102_nvdec_new,
|
||||
.sec2 = gp102_sec2_new,
|
||||
.sw = gf100_sw_new,
|
||||
};
|
||||
@ -2257,7 +2257,7 @@ nv134_chipset = {
|
||||
.dma = gf119_dma_new,
|
||||
.fifo = gp100_fifo_new,
|
||||
.gr = gp104_gr_new,
|
||||
.nvdec = gp102_nvdec_new,
|
||||
.nvdec[0] = gp102_nvdec_new,
|
||||
.sec2 = gp102_sec2_new,
|
||||
.sw = gf100_sw_new,
|
||||
};
|
||||
@ -2293,7 +2293,7 @@ nv136_chipset = {
|
||||
.dma = gf119_dma_new,
|
||||
.fifo = gp100_fifo_new,
|
||||
.gr = gp104_gr_new,
|
||||
.nvdec = gp102_nvdec_new,
|
||||
.nvdec[0] = gp102_nvdec_new,
|
||||
.sec2 = gp102_sec2_new,
|
||||
.sw = gf100_sw_new,
|
||||
};
|
||||
@ -2329,7 +2329,7 @@ nv137_chipset = {
|
||||
.dma = gf119_dma_new,
|
||||
.fifo = gp100_fifo_new,
|
||||
.gr = gp107_gr_new,
|
||||
.nvdec = gp102_nvdec_new,
|
||||
.nvdec[0] = gp102_nvdec_new,
|
||||
.sec2 = gp102_sec2_new,
|
||||
.sw = gf100_sw_new,
|
||||
};
|
||||
@ -2365,7 +2365,7 @@ nv138_chipset = {
|
||||
.dma = gf119_dma_new,
|
||||
.fifo = gp100_fifo_new,
|
||||
.gr = gp107_gr_new,
|
||||
.nvdec = gp102_nvdec_new,
|
||||
.nvdec[0] = gp102_nvdec_new,
|
||||
.sec2 = gp102_sec2_new,
|
||||
.sw = gf100_sw_new,
|
||||
};
|
||||
@ -2430,10 +2430,74 @@ nv140_chipset = {
|
||||
.dma = gv100_dma_new,
|
||||
.fifo = gv100_fifo_new,
|
||||
.gr = gv100_gr_new,
|
||||
.nvdec = gp102_nvdec_new,
|
||||
.nvdec[0] = gp102_nvdec_new,
|
||||
.sec2 = gp102_sec2_new,
|
||||
};
|
||||
|
||||
static const struct nvkm_device_chip
|
||||
nv164_chipset = {
|
||||
.name = "TU104",
|
||||
.bar = tu104_bar_new,
|
||||
.bios = nvkm_bios_new,
|
||||
.bus = gf100_bus_new,
|
||||
.devinit = tu104_devinit_new,
|
||||
.fault = tu104_fault_new,
|
||||
.fb = gv100_fb_new,
|
||||
.fuse = gm107_fuse_new,
|
||||
.gpio = gk104_gpio_new,
|
||||
.i2c = gm200_i2c_new,
|
||||
.ibus = gm200_ibus_new,
|
||||
.imem = nv50_instmem_new,
|
||||
.ltc = gp102_ltc_new,
|
||||
.mc = tu104_mc_new,
|
||||
.mmu = tu104_mmu_new,
|
||||
.pci = gp100_pci_new,
|
||||
.pmu = gp102_pmu_new,
|
||||
.therm = gp100_therm_new,
|
||||
.timer = gk20a_timer_new,
|
||||
.top = gk104_top_new,
|
||||
.ce[0] = tu104_ce_new,
|
||||
.ce[1] = tu104_ce_new,
|
||||
.ce[2] = tu104_ce_new,
|
||||
.ce[3] = tu104_ce_new,
|
||||
.ce[4] = tu104_ce_new,
|
||||
.disp = tu104_disp_new,
|
||||
.dma = gv100_dma_new,
|
||||
.fifo = tu104_fifo_new,
|
||||
};
|
||||
|
||||
static const struct nvkm_device_chip
|
||||
nv166_chipset = {
|
||||
.name = "TU106",
|
||||
.bar = tu104_bar_new,
|
||||
.bios = nvkm_bios_new,
|
||||
.bus = gf100_bus_new,
|
||||
.devinit = tu104_devinit_new,
|
||||
.fault = tu104_fault_new,
|
||||
.fb = gv100_fb_new,
|
||||
.fuse = gm107_fuse_new,
|
||||
.gpio = gk104_gpio_new,
|
||||
.i2c = gm200_i2c_new,
|
||||
.ibus = gm200_ibus_new,
|
||||
.imem = nv50_instmem_new,
|
||||
.ltc = gp102_ltc_new,
|
||||
.mc = tu104_mc_new,
|
||||
.mmu = tu104_mmu_new,
|
||||
.pci = gp100_pci_new,
|
||||
.pmu = gp102_pmu_new,
|
||||
.therm = gp100_therm_new,
|
||||
.timer = gk20a_timer_new,
|
||||
.top = gk104_top_new,
|
||||
.ce[0] = tu104_ce_new,
|
||||
.ce[1] = tu104_ce_new,
|
||||
.ce[2] = tu104_ce_new,
|
||||
.ce[3] = tu104_ce_new,
|
||||
.ce[4] = tu104_ce_new,
|
||||
.disp = tu104_disp_new,
|
||||
.dma = gv100_dma_new,
|
||||
.fifo = tu104_fifo_new,
|
||||
};
|
||||
|
||||
static int
|
||||
nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size,
|
||||
struct nvkm_notify *notify)
|
||||
@ -2529,7 +2593,9 @@ nvkm_device_engine(struct nvkm_device *device, int index)
|
||||
_(NVENC0 , device->nvenc[0], device->nvenc[0]);
|
||||
_(NVENC1 , device->nvenc[1], device->nvenc[1]);
|
||||
_(NVENC2 , device->nvenc[2], device->nvenc[2]);
|
||||
_(NVDEC , device->nvdec , &device->nvdec->engine);
|
||||
_(NVDEC0 , device->nvdec[0], &device->nvdec[0]->engine);
|
||||
_(NVDEC1 , device->nvdec[1], &device->nvdec[1]->engine);
|
||||
_(NVDEC2 , device->nvdec[2], &device->nvdec[2]->engine);
|
||||
_(PM , device->pm , &device->pm->engine);
|
||||
_(SEC , device->sec , device->sec);
|
||||
_(SEC2 , device->sec2 , &device->sec2->engine);
|
||||
@ -2791,6 +2857,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
|
||||
case 0x120: device->card_type = GM100; break;
|
||||
case 0x130: device->card_type = GP100; break;
|
||||
case 0x140: device->card_type = GV100; break;
|
||||
case 0x160: device->card_type = TU100; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2883,6 +2950,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
|
||||
case 0x138: device->chip = &nv138_chipset; break;
|
||||
case 0x13b: device->chip = &nv13b_chipset; break;
|
||||
case 0x140: device->chip = &nv140_chipset; break;
|
||||
case 0x164: device->chip = &nv164_chipset; break;
|
||||
case 0x166: device->chip = &nv166_chipset; break;
|
||||
default:
|
||||
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
|
||||
goto done;
|
||||
@ -2988,7 +3057,9 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
|
||||
_(NVKM_ENGINE_NVENC0 , nvenc[0]);
|
||||
_(NVKM_ENGINE_NVENC1 , nvenc[1]);
|
||||
_(NVKM_ENGINE_NVENC2 , nvenc[2]);
|
||||
_(NVKM_ENGINE_NVDEC , nvdec);
|
||||
_(NVKM_ENGINE_NVDEC0 , nvdec[0]);
|
||||
_(NVKM_ENGINE_NVDEC1 , nvdec[1]);
|
||||
_(NVKM_ENGINE_NVDEC2 , nvdec[2]);
|
||||
_(NVKM_ENGINE_PM , pm);
|
||||
_(NVKM_ENGINE_SEC , sec);
|
||||
_(NVKM_ENGINE_SEC2 , sec2);
|
||||
|
@ -91,7 +91,7 @@ nvkm_udevice_info_v1(struct nvkm_device *device,
|
||||
case ENGINE_A(MSENC ); break;
|
||||
case ENGINE_A(VIC ); break;
|
||||
case ENGINE_A(SEC2 ); break;
|
||||
case ENGINE_A(NVDEC ); break;
|
||||
case ENGINE_B(NVDEC ); break;
|
||||
case ENGINE_B(NVENC ); break;
|
||||
default:
|
||||
args->mthd = NV_DEVICE_INFO_INVALID;
|
||||
@ -175,6 +175,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size)
|
||||
case GM100: args->v0.family = NV_DEVICE_INFO_V0_MAXWELL; break;
|
||||
case GP100: args->v0.family = NV_DEVICE_INFO_V0_PASCAL; break;
|
||||
case GV100: args->v0.family = NV_DEVICE_INFO_V0_VOLTA; break;
|
||||
case TU100: args->v0.family = NV_DEVICE_INFO_V0_TURING; break;
|
||||
default:
|
||||
args->v0.family = 0;
|
||||
break;
|
||||
|
@ -15,6 +15,7 @@ nvkm-y += nvkm/engine/disp/gm200.o
|
||||
nvkm-y += nvkm/engine/disp/gp100.o
|
||||
nvkm-y += nvkm/engine/disp/gp102.o
|
||||
nvkm-y += nvkm/engine/disp/gv100.o
|
||||
nvkm-y += nvkm/engine/disp/tu104.o
|
||||
nvkm-y += nvkm/engine/disp/vga.o
|
||||
|
||||
nvkm-y += nvkm/engine/disp/head.o
|
||||
@ -38,6 +39,7 @@ nvkm-y += nvkm/engine/disp/sorgk104.o
|
||||
nvkm-y += nvkm/engine/disp/sorgm107.o
|
||||
nvkm-y += nvkm/engine/disp/sorgm200.o
|
||||
nvkm-y += nvkm/engine/disp/sorgv100.o
|
||||
nvkm-y += nvkm/engine/disp/sortu104.o
|
||||
|
||||
nvkm-y += nvkm/engine/disp/outp.o
|
||||
nvkm-y += nvkm/engine/disp/dp.o
|
||||
@ -69,6 +71,7 @@ nvkm-y += nvkm/engine/disp/rootgm200.o
|
||||
nvkm-y += nvkm/engine/disp/rootgp100.o
|
||||
nvkm-y += nvkm/engine/disp/rootgp102.o
|
||||
nvkm-y += nvkm/engine/disp/rootgv100.o
|
||||
nvkm-y += nvkm/engine/disp/roottu104.o
|
||||
|
||||
nvkm-y += nvkm/engine/disp/channv50.o
|
||||
nvkm-y += nvkm/engine/disp/changf119.o
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <core/gpuobj.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static int
|
||||
int
|
||||
gv100_disp_wndw_cnt(struct nvkm_disp *disp, unsigned long *pmask)
|
||||
{
|
||||
struct nvkm_device *device = disp->engine.subdev.device;
|
||||
@ -36,7 +36,7 @@ gv100_disp_wndw_cnt(struct nvkm_disp *disp, unsigned long *pmask)
|
||||
return (nvkm_rd32(device, 0x610074) & 0x03f00000) >> 20;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_disp_super(struct work_struct *work)
|
||||
{
|
||||
struct nv50_disp *disp =
|
||||
@ -257,7 +257,7 @@ gv100_disp_intr_head_timing(struct nv50_disp *disp, int head)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_disp_intr(struct nv50_disp *disp)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
|
||||
@ -297,7 +297,7 @@ gv100_disp_intr(struct nv50_disp *disp)
|
||||
nvkm_warn(subdev, "intr %08x\n", stat);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_disp_fini(struct nv50_disp *disp)
|
||||
{
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
|
@ -144,6 +144,11 @@ void gm200_sor_route_set(struct nvkm_outp *, struct nvkm_ior *);
|
||||
int gm200_sor_route_get(struct nvkm_outp *, int *);
|
||||
void gm200_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
|
||||
|
||||
void gv100_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
|
||||
void gv100_sor_dp_audio(struct nvkm_ior *, int, bool);
|
||||
void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32);
|
||||
void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8);
|
||||
|
||||
void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
|
||||
void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
|
||||
void gf119_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8);
|
||||
@ -195,4 +200,6 @@ int gm200_sor_new(struct nvkm_disp *, int);
|
||||
|
||||
int gv100_sor_cnt(struct nvkm_disp *, unsigned long *);
|
||||
int gv100_sor_new(struct nvkm_disp *, int);
|
||||
|
||||
int tu104_sor_new(struct nvkm_disp *, int);
|
||||
#endif
|
||||
|
@ -78,6 +78,11 @@ void gf119_disp_intr(struct nv50_disp *);
|
||||
void gf119_disp_super(struct work_struct *);
|
||||
void gf119_disp_intr_error(struct nv50_disp *, int);
|
||||
|
||||
void gv100_disp_fini(struct nv50_disp *);
|
||||
void gv100_disp_intr(struct nv50_disp *);
|
||||
void gv100_disp_super(struct work_struct *);
|
||||
int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *);
|
||||
|
||||
void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *);
|
||||
void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *);
|
||||
void nv50_disp_update_sppll1(struct nv50_disp *);
|
||||
|
@ -37,4 +37,5 @@ extern const struct nvkm_disp_oclass gm200_disp_root_oclass;
|
||||
extern const struct nvkm_disp_oclass gp100_disp_root_oclass;
|
||||
extern const struct nvkm_disp_oclass gp102_disp_root_oclass;
|
||||
extern const struct nvkm_disp_oclass gv100_disp_root_oclass;
|
||||
extern const struct nvkm_disp_oclass tu104_disp_root_oclass;
|
||||
#endif
|
||||
|
52
drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu104.c
Normal file
52
drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu104.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 "rootnv50.h"
|
||||
#include "channv50.h"
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static const struct nv50_disp_root_func
|
||||
tu104_disp_root = {
|
||||
.user = {
|
||||
{{0,0,TU104_DISP_CURSOR }, gv100_disp_curs_new },
|
||||
{{0,0,TU104_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new },
|
||||
{{0,0,TU104_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new },
|
||||
{{0,0,TU104_DISP_WINDOW_CHANNEL_DMA }, gv100_disp_wndw_new },
|
||||
{}
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
tu104_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
|
||||
void *data, u32 size, struct nvkm_object **pobject)
|
||||
{
|
||||
return nv50_disp_root_new_(&tu104_disp_root, disp, oclass,
|
||||
data, size, pobject);
|
||||
}
|
||||
|
||||
const struct nvkm_disp_oclass
|
||||
tu104_disp_root_oclass = {
|
||||
.base.oclass = TU104_DISP,
|
||||
.base.minver = -1,
|
||||
.base.maxver = -1,
|
||||
.ctor = tu104_disp_root_new,
|
||||
};
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
|
||||
{
|
||||
struct nvkm_device *device = sor->disp->engine.subdev.device;
|
||||
@ -31,7 +31,7 @@ gv100_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark)
|
||||
nvkm_mask(device, 0x616550 + hoff, 0x0c00003f, 0x08000000 | watermark);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
|
||||
{
|
||||
struct nvkm_device *device = sor->disp->engine.subdev.device;
|
||||
@ -40,7 +40,7 @@ gv100_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v)
|
||||
nvkm_mask(device, 0x61656c + hoff, 0x00ffffff, v);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
|
||||
{
|
||||
struct nvkm_device *device = sor->disp->engine.subdev.device;
|
||||
@ -54,7 +54,7 @@ gv100_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
|
||||
{
|
||||
struct nvkm_device *device = sor->disp->engine.subdev.device;
|
||||
|
97
drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu104.c
Normal file
97
drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu104.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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 "ior.h"
|
||||
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static void
|
||||
tu104_sor_dp_vcpi(struct nvkm_ior *sor, int head,
|
||||
u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
|
||||
{
|
||||
struct nvkm_device *device = sor->disp->engine.subdev.device;
|
||||
const u32 hoff = head * 0x800;
|
||||
|
||||
nvkm_mask(device, 0x61657c + hoff, 0xffffffff, (aligned << 16) | pbn);
|
||||
nvkm_mask(device, 0x616578 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
|
||||
}
|
||||
|
||||
static int
|
||||
tu104_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
|
||||
{
|
||||
struct nvkm_device *device = sor->disp->engine.subdev.device;
|
||||
const u32 soff = nv50_ior_base(sor);
|
||||
const u32 loff = nv50_sor_link(sor);
|
||||
u32 dpctrl = 0x00000000;
|
||||
u32 clksor = 0x00000000;
|
||||
|
||||
clksor |= sor->dp.bw << 18;
|
||||
dpctrl |= ((1 << sor->dp.nr) - 1) << 16;
|
||||
if (sor->dp.mst)
|
||||
dpctrl |= 0x40000000;
|
||||
if (sor->dp.ef)
|
||||
dpctrl |= 0x00004000;
|
||||
|
||||
nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
|
||||
|
||||
/*XXX*/
|
||||
nvkm_msec(device, 40, NVKM_DELAY);
|
||||
nvkm_mask(device, 0x612300 + soff, 0x00030000, 0x00010000);
|
||||
nvkm_mask(device, 0x61c10c + loff, 0x00000003, 0x00000001);
|
||||
|
||||
nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nvkm_ior_func
|
||||
tu104_sor = {
|
||||
.route = {
|
||||
.get = gm200_sor_route_get,
|
||||
.set = gm200_sor_route_set,
|
||||
},
|
||||
.state = gv100_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.hdmi = {
|
||||
.ctrl = gv100_hdmi_ctrl,
|
||||
},
|
||||
.dp = {
|
||||
.lanes = { 0, 1, 2, 3 },
|
||||
.links = tu104_sor_dp_links,
|
||||
.power = g94_sor_dp_power,
|
||||
.pattern = gm107_sor_dp_pattern,
|
||||
.drive = gm200_sor_dp_drive,
|
||||
.vcpi = tu104_sor_dp_vcpi,
|
||||
.audio = gv100_sor_dp_audio,
|
||||
.audio_sym = gv100_sor_dp_audio_sym,
|
||||
.watermark = gv100_sor_dp_watermark,
|
||||
},
|
||||
.hda = {
|
||||
.hpd = gf119_hda_hpd,
|
||||
.eld = gf119_hda_eld,
|
||||
},
|
||||
};
|
||||
|
||||
int
|
||||
tu104_sor_new(struct nvkm_disp *disp, int id)
|
||||
{
|
||||
return nvkm_ior_new_(&tu104_sor, disp, SOR, id);
|
||||
}
|
152
drivers/gpu/drm/nouveau/nvkm/engine/disp/tu104.c
Normal file
152
drivers/gpu/drm/nouveau/nvkm/engine/disp/tu104.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 "nv50.h"
|
||||
#include "head.h"
|
||||
#include "ior.h"
|
||||
#include "channv50.h"
|
||||
#include "rootnv50.h"
|
||||
|
||||
#include <core/gpuobj.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static int
|
||||
tu104_disp_init(struct nv50_disp *disp)
|
||||
{
|
||||
struct nvkm_device *device = disp->base.engine.subdev.device;
|
||||
struct nvkm_head *head;
|
||||
int i, j;
|
||||
u32 tmp;
|
||||
|
||||
/* Claim ownership of display. */
|
||||
if (nvkm_rd32(device, 0x6254e8) & 0x00000002) {
|
||||
nvkm_mask(device, 0x6254e8, 0x00000001, 0x00000000);
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x6254e8) & 0x00000002))
|
||||
break;
|
||||
) < 0)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Lock pin capabilities. */
|
||||
tmp = 0x00000021; /*XXX*/
|
||||
nvkm_wr32(device, 0x640008, tmp);
|
||||
|
||||
/* SOR capabilities. */
|
||||
for (i = 0; i < disp->sor.nr; i++) {
|
||||
tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
|
||||
nvkm_mask(device, 0x640000, 0x00000100 << i, 0x00000100 << i);
|
||||
nvkm_wr32(device, 0x640144 + (i * 0x08), tmp);
|
||||
}
|
||||
|
||||
/* Head capabilities. */
|
||||
list_for_each_entry(head, &disp->base.head, head) {
|
||||
const int id = head->id;
|
||||
|
||||
/* RG. */
|
||||
tmp = nvkm_rd32(device, 0x616300 + (id * 0x800));
|
||||
nvkm_wr32(device, 0x640048 + (id * 0x020), tmp);
|
||||
|
||||
/* POSTCOMP. */
|
||||
for (j = 0; j < 5 * 4; j += 4) {
|
||||
tmp = nvkm_rd32(device, 0x616140 + (id * 0x800) + j);
|
||||
nvkm_wr32(device, 0x640680 + (id * 0x20) + j, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Window capabilities. */
|
||||
for (i = 0; i < disp->wndw.nr; i++) {
|
||||
nvkm_mask(device, 0x640004, 1 << i, 1 << i);
|
||||
for (j = 0; j < 6 * 4; j += 4) {
|
||||
tmp = nvkm_rd32(device, 0x630100 + (i * 0x800) + j);
|
||||
nvkm_mask(device, 0x640780 + (i * 0x20) + j, 0xffffffff, tmp);
|
||||
}
|
||||
nvkm_mask(device, 0x64000c, 0x00000100, 0x00000100);
|
||||
}
|
||||
|
||||
/* IHUB capabilities. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
tmp = nvkm_rd32(device, 0x62e000 + (i * 0x04));
|
||||
nvkm_wr32(device, 0x640010 + (i * 0x04), tmp);
|
||||
}
|
||||
|
||||
nvkm_mask(device, 0x610078, 0x00000001, 0x00000001);
|
||||
|
||||
/* Setup instance memory. */
|
||||
switch (nvkm_memory_target(disp->inst->memory)) {
|
||||
case NVKM_MEM_TARGET_VRAM: tmp = 0x00000001; break;
|
||||
case NVKM_MEM_TARGET_NCOH: tmp = 0x00000002; break;
|
||||
case NVKM_MEM_TARGET_HOST: tmp = 0x00000003; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nvkm_wr32(device, 0x610010, 0x00000008 | tmp);
|
||||
nvkm_wr32(device, 0x610014, disp->inst->addr >> 16);
|
||||
|
||||
/* CTRL_DISP: AWAKEN, ERROR, SUPERVISOR[1-3]. */
|
||||
nvkm_wr32(device, 0x611cf0, 0x00000187); /* MSK. */
|
||||
nvkm_wr32(device, 0x611db0, 0x00000187); /* EN. */
|
||||
|
||||
/* EXC_OTHER: CURSn, CORE. */
|
||||
nvkm_wr32(device, 0x611cec, disp->head.mask << 16 |
|
||||
0x00000001); /* MSK. */
|
||||
nvkm_wr32(device, 0x611dac, 0x00000000); /* EN. */
|
||||
|
||||
/* EXC_WINIM. */
|
||||
nvkm_wr32(device, 0x611ce8, disp->wndw.mask); /* MSK. */
|
||||
nvkm_wr32(device, 0x611da8, 0x00000000); /* EN. */
|
||||
|
||||
/* EXC_WIN. */
|
||||
nvkm_wr32(device, 0x611ce4, disp->wndw.mask); /* MSK. */
|
||||
nvkm_wr32(device, 0x611da4, 0x00000000); /* EN. */
|
||||
|
||||
/* HEAD_TIMING(n): VBLANK. */
|
||||
list_for_each_entry(head, &disp->base.head, head) {
|
||||
const u32 hoff = head->id * 4;
|
||||
nvkm_wr32(device, 0x611cc0 + hoff, 0x00000004); /* MSK. */
|
||||
nvkm_wr32(device, 0x611d80 + hoff, 0x00000000); /* EN. */
|
||||
}
|
||||
|
||||
/* OR. */
|
||||
nvkm_wr32(device, 0x611cf4, 0x00000000); /* MSK. */
|
||||
nvkm_wr32(device, 0x611db4, 0x00000000); /* EN. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nv50_disp_func
|
||||
tu104_disp = {
|
||||
.init = tu104_disp_init,
|
||||
.fini = gv100_disp_fini,
|
||||
.intr = gv100_disp_intr,
|
||||
.uevent = &gv100_disp_chan_uevent,
|
||||
.super = gv100_disp_super,
|
||||
.root = &tu104_disp_root_oclass,
|
||||
.wndw = { .cnt = gv100_disp_wndw_cnt },
|
||||
.head = { .cnt = gv100_head_cnt, .new = gv100_head_new },
|
||||
.sor = { .cnt = gv100_sor_cnt, .new = tu104_sor_new },
|
||||
.ramht_size = 0x2000,
|
||||
};
|
||||
|
||||
int
|
||||
tu104_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
|
||||
{
|
||||
return nv50_disp_new_(&tu104_disp, device, index, pdisp);
|
||||
}
|
@ -118,7 +118,7 @@ gv100_disp_wndw_mthd_base = {
|
||||
|
||||
const struct nv50_disp_chan_mthd
|
||||
gv100_disp_wndw_mthd = {
|
||||
.name = "Base",
|
||||
.name = "Window",
|
||||
.addr = 0x001000,
|
||||
.prev = 0x000800,
|
||||
.data = {
|
||||
|
@ -16,6 +16,7 @@ nvkm-y += nvkm/engine/fifo/gm20b.o
|
||||
nvkm-y += nvkm/engine/fifo/gp100.o
|
||||
nvkm-y += nvkm/engine/fifo/gp10b.o
|
||||
nvkm-y += nvkm/engine/fifo/gv100.o
|
||||
nvkm-y += nvkm/engine/fifo/tu104.o
|
||||
|
||||
nvkm-y += nvkm/engine/fifo/chan.o
|
||||
nvkm-y += nvkm/engine/fifo/channv50.o
|
||||
@ -33,5 +34,7 @@ nvkm-y += nvkm/engine/fifo/gpfifog84.o
|
||||
nvkm-y += nvkm/engine/fifo/gpfifogf100.o
|
||||
nvkm-y += nvkm/engine/fifo/gpfifogk104.o
|
||||
nvkm-y += nvkm/engine/fifo/gpfifogv100.o
|
||||
nvkm-y += nvkm/engine/fifo/gpfifotu104.o
|
||||
|
||||
nvkm-y += nvkm/engine/fifo/usergv100.o
|
||||
nvkm-y += nvkm/engine/fifo/usertu104.o
|
||||
|
@ -17,6 +17,7 @@ struct nvkm_fifo_chan_func {
|
||||
bool suspend);
|
||||
int (*object_ctor)(struct nvkm_fifo_chan *, struct nvkm_object *);
|
||||
void (*object_dtor)(struct nvkm_fifo_chan *, int);
|
||||
u32 (*submit_token)(struct nvkm_fifo_chan *);
|
||||
};
|
||||
|
||||
int nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *, struct nvkm_fifo *,
|
||||
|
@ -14,6 +14,8 @@ struct gk104_fifo_chan {
|
||||
struct list_head head;
|
||||
bool killed;
|
||||
|
||||
struct nvkm_memory *mthd;
|
||||
|
||||
struct {
|
||||
struct nvkm_gpuobj *inst;
|
||||
struct nvkm_vma *vma;
|
||||
@ -36,4 +38,15 @@ int gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *);
|
||||
|
||||
int gv100_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
|
||||
void *data, u32 size, struct nvkm_object **);
|
||||
int gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func *,
|
||||
struct gk104_fifo *, u64 *, u16 *, u64, u64, u64,
|
||||
u64 *, bool, u32 *, const struct nvkm_oclass *,
|
||||
struct nvkm_object **);
|
||||
int gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *,
|
||||
struct nvkm_engine *);
|
||||
int gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *,
|
||||
struct nvkm_engine *, bool);
|
||||
|
||||
int tu104_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
|
||||
void *data, u32 size, struct nvkm_object **);
|
||||
#endif
|
||||
|
@ -346,10 +346,10 @@ gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit)
|
||||
if (eu && eu->data2) {
|
||||
switch (eu->data2) {
|
||||
case NVKM_SUBDEV_BAR:
|
||||
nvkm_mask(device, 0x001704, 0x00000000, 0x00000000);
|
||||
nvkm_bar_bar1_reset(device);
|
||||
break;
|
||||
case NVKM_SUBDEV_INSTMEM:
|
||||
nvkm_mask(device, 0x001714, 0x00000000, 0x00000000);
|
||||
nvkm_bar_bar2_reset(device);
|
||||
break;
|
||||
case NVKM_ENGINE_IFB:
|
||||
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
|
||||
|
@ -149,16 +149,41 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
|
||||
}
|
||||
|
||||
void
|
||||
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
|
||||
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl,
|
||||
struct nvkm_memory *mem, int nr)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int target;
|
||||
|
||||
switch (nvkm_memory_target(mem)) {
|
||||
case NVKM_MEM_TARGET_VRAM: target = 0; break;
|
||||
case NVKM_MEM_TARGET_NCOH: target = 3; break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
|
||||
(target << 28));
|
||||
nvkm_wr32(device, 0x002274, (runl << 20) | nr);
|
||||
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000))
|
||||
break;
|
||||
) < 0)
|
||||
nvkm_error(subdev, "runlist %d update timeout\n", runl);
|
||||
}
|
||||
|
||||
void
|
||||
gk104_fifo_runlist_update(struct gk104_fifo *fifo, int runl)
|
||||
{
|
||||
const struct gk104_fifo_runlist_func *func = fifo->func->runlist;
|
||||
struct gk104_fifo_chan *chan;
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
struct nvkm_memory *mem;
|
||||
struct nvkm_fifo_cgrp *cgrp;
|
||||
int nr = 0;
|
||||
int target;
|
||||
|
||||
mutex_lock(&subdev->mutex);
|
||||
mem = fifo->runlist[runl].mem[fifo->runlist[runl].next];
|
||||
@ -177,24 +202,7 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
|
||||
}
|
||||
nvkm_done(mem);
|
||||
|
||||
switch (nvkm_memory_target(mem)) {
|
||||
case NVKM_MEM_TARGET_VRAM: target = 0; break;
|
||||
case NVKM_MEM_TARGET_NCOH: target = 3; break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
|
||||
(target << 28));
|
||||
nvkm_wr32(device, 0x002274, (runl << 20) | nr);
|
||||
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000))
|
||||
break;
|
||||
) < 0)
|
||||
nvkm_error(subdev, "runlist %d update timeout\n", runl);
|
||||
unlock:
|
||||
func->commit(fifo, runl, mem, nr);
|
||||
mutex_unlock(&subdev->mutex);
|
||||
}
|
||||
|
||||
@ -238,6 +246,29 @@ const struct gk104_fifo_runlist_func
|
||||
gk104_fifo_runlist = {
|
||||
.size = 8,
|
||||
.chan = gk104_fifo_runlist_chan,
|
||||
.commit = gk104_fifo_runlist_commit,
|
||||
};
|
||||
|
||||
void
|
||||
gk104_fifo_pbdma_init(struct gk104_fifo *fifo)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
nvkm_wr32(device, 0x000204, (1 << fifo->pbdma_nr) - 1);
|
||||
}
|
||||
|
||||
int
|
||||
gk104_fifo_pbdma_nr(struct gk104_fifo *fifo)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
/* Determine number of PBDMAs by checking valid enable bits. */
|
||||
nvkm_wr32(device, 0x000204, 0xffffffff);
|
||||
return hweight32(nvkm_rd32(device, 0x000204));
|
||||
}
|
||||
|
||||
const struct gk104_fifo_pbdma_func
|
||||
gk104_fifo_pbdma = {
|
||||
.nr = gk104_fifo_pbdma_nr,
|
||||
.init = gk104_fifo_pbdma_init,
|
||||
};
|
||||
|
||||
static void
|
||||
@ -267,7 +298,7 @@ gk104_fifo_recover_work(struct work_struct *w)
|
||||
}
|
||||
|
||||
for (todo = runm; runl = __ffs(todo), todo; todo &= ~BIT(runl))
|
||||
gk104_fifo_runlist_commit(fifo, runl);
|
||||
gk104_fifo_runlist_update(fifo, runl);
|
||||
|
||||
nvkm_wr32(device, 0x00262c, runm);
|
||||
nvkm_mask(device, 0x002630, runm, 0x00000000);
|
||||
@ -456,10 +487,10 @@ gk104_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info)
|
||||
if (ee && ee->data2) {
|
||||
switch (ee->data2) {
|
||||
case NVKM_SUBDEV_BAR:
|
||||
nvkm_mask(device, 0x001704, 0x00000000, 0x00000000);
|
||||
nvkm_bar_bar1_reset(device);
|
||||
break;
|
||||
case NVKM_SUBDEV_INSTMEM:
|
||||
nvkm_mask(device, 0x001714, 0x00000000, 0x00000000);
|
||||
nvkm_bar_bar2_reset(device);
|
||||
break;
|
||||
case NVKM_ENGINE_IFB:
|
||||
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
|
||||
@ -904,9 +935,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base)
|
||||
enum nvkm_devidx engidx;
|
||||
u32 *map;
|
||||
|
||||
/* Determine number of PBDMAs by checking valid enable bits. */
|
||||
nvkm_wr32(device, 0x000204, 0xffffffff);
|
||||
fifo->pbdma_nr = hweight32(nvkm_rd32(device, 0x000204));
|
||||
fifo->pbdma_nr = fifo->func->pbdma->nr(fifo);
|
||||
nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr);
|
||||
|
||||
/* Read PBDMA->runlist(s) mapping from HW. */
|
||||
@ -978,7 +1007,7 @@ gk104_fifo_init(struct nvkm_fifo *base)
|
||||
int i;
|
||||
|
||||
/* Enable PBDMAs. */
|
||||
nvkm_wr32(device, 0x000204, (1 << fifo->pbdma_nr) - 1);
|
||||
fifo->func->pbdma->init(fifo);
|
||||
|
||||
/* PBDMA[n] */
|
||||
for (i = 0; i < fifo->pbdma_nr; i++) {
|
||||
@ -995,8 +1024,8 @@ gk104_fifo_init(struct nvkm_fifo *base)
|
||||
|
||||
nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar->addr >> 12);
|
||||
|
||||
if (fifo->func->init_pbdma_timeout)
|
||||
fifo->func->init_pbdma_timeout(fifo);
|
||||
if (fifo->func->pbdma->init_timeout)
|
||||
fifo->func->pbdma->init_timeout(fifo);
|
||||
|
||||
nvkm_wr32(device, 0x002100, 0xffffffff);
|
||||
nvkm_wr32(device, 0x002140, 0x7fffffff);
|
||||
@ -1175,6 +1204,7 @@ gk104_fifo_fault_gpcclient[] = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk104_fifo = {
|
||||
.pbdma = &gk104_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -45,7 +45,11 @@ struct gk104_fifo {
|
||||
};
|
||||
|
||||
struct gk104_fifo_func {
|
||||
void (*init_pbdma_timeout)(struct gk104_fifo *);
|
||||
const struct gk104_fifo_pbdma_func {
|
||||
int (*nr)(struct gk104_fifo *);
|
||||
void (*init)(struct gk104_fifo *);
|
||||
void (*init_timeout)(struct gk104_fifo *);
|
||||
} *pbdma;
|
||||
|
||||
struct {
|
||||
const struct nvkm_enum *access;
|
||||
@ -61,6 +65,8 @@ struct gk104_fifo_func {
|
||||
struct nvkm_memory *, u32 offset);
|
||||
void (*chan)(struct gk104_fifo_chan *,
|
||||
struct nvkm_memory *, u32 offset);
|
||||
void (*commit)(struct gk104_fifo *, int runl,
|
||||
struct nvkm_memory *, int entries);
|
||||
} *runlist;
|
||||
|
||||
struct gk104_fifo_user_user {
|
||||
@ -81,8 +87,11 @@ int gk104_fifo_new_(const struct gk104_fifo_func *, struct nvkm_device *,
|
||||
int index, int nr, struct nvkm_fifo **);
|
||||
void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *);
|
||||
void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *);
|
||||
void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl);
|
||||
void gk104_fifo_runlist_update(struct gk104_fifo *, int runl);
|
||||
|
||||
extern const struct gk104_fifo_pbdma_func gk104_fifo_pbdma;
|
||||
int gk104_fifo_pbdma_nr(struct gk104_fifo *);
|
||||
void gk104_fifo_pbdma_init(struct gk104_fifo *);
|
||||
extern const struct nvkm_enum gk104_fifo_fault_access[];
|
||||
extern const struct nvkm_enum gk104_fifo_fault_engine[];
|
||||
extern const struct nvkm_enum gk104_fifo_fault_reason[];
|
||||
@ -91,15 +100,30 @@ extern const struct nvkm_enum gk104_fifo_fault_gpcclient[];
|
||||
extern const struct gk104_fifo_runlist_func gk104_fifo_runlist;
|
||||
void gk104_fifo_runlist_chan(struct gk104_fifo_chan *,
|
||||
struct nvkm_memory *, u32);
|
||||
void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl,
|
||||
struct nvkm_memory *, int);
|
||||
|
||||
extern const struct gk104_fifo_runlist_func gk110_fifo_runlist;
|
||||
void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *,
|
||||
struct nvkm_memory *, u32);
|
||||
|
||||
void gk208_fifo_init_pbdma_timeout(struct gk104_fifo *);
|
||||
extern const struct gk104_fifo_pbdma_func gk208_fifo_pbdma;
|
||||
void gk208_fifo_pbdma_init_timeout(struct gk104_fifo *);
|
||||
|
||||
extern const struct nvkm_enum gm107_fifo_fault_engine[];
|
||||
extern const struct gk104_fifo_runlist_func gm107_fifo_runlist;
|
||||
|
||||
extern const struct gk104_fifo_pbdma_func gm200_fifo_pbdma;
|
||||
int gm200_fifo_pbdma_nr(struct gk104_fifo *);
|
||||
|
||||
extern const struct nvkm_enum gp100_fifo_fault_engine[];
|
||||
|
||||
extern const struct nvkm_enum gv100_fifo_fault_access[];
|
||||
extern const struct nvkm_enum gv100_fifo_fault_reason[];
|
||||
extern const struct nvkm_enum gv100_fifo_fault_hubclient[];
|
||||
extern const struct nvkm_enum gv100_fifo_fault_gpcclient[];
|
||||
void gv100_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *,
|
||||
struct nvkm_memory *, u32);
|
||||
void gv100_fifo_runlist_chan(struct gk104_fifo_chan *,
|
||||
struct nvkm_memory *, u32);
|
||||
#endif
|
||||
|
@ -43,10 +43,12 @@ gk110_fifo_runlist = {
|
||||
.size = 8,
|
||||
.cgrp = gk110_fifo_runlist_cgrp,
|
||||
.chan = gk104_fifo_runlist_chan,
|
||||
.commit = gk104_fifo_runlist_commit,
|
||||
};
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk110_fifo = {
|
||||
.pbdma = &gk104_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <nvif/class.h>
|
||||
|
||||
void
|
||||
gk208_fifo_init_pbdma_timeout(struct gk104_fifo *fifo)
|
||||
gk208_fifo_pbdma_init_timeout(struct gk104_fifo *fifo)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
int i;
|
||||
@ -36,9 +36,16 @@ gk208_fifo_init_pbdma_timeout(struct gk104_fifo *fifo)
|
||||
nvkm_wr32(device, 0x04012c + (i * 0x2000), 0x0000ffff);
|
||||
}
|
||||
|
||||
const struct gk104_fifo_pbdma_func
|
||||
gk208_fifo_pbdma = {
|
||||
.nr = gk104_fifo_pbdma_nr,
|
||||
.init = gk104_fifo_pbdma_init,
|
||||
.init_timeout = gk208_fifo_pbdma_init_timeout,
|
||||
};
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk208_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gk208_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk20a_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gk208_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -41,6 +41,7 @@ gm107_fifo_runlist = {
|
||||
.size = 8,
|
||||
.cgrp = gk110_fifo_runlist_cgrp,
|
||||
.chan = gm107_fifo_runlist_chan,
|
||||
.commit = gk104_fifo_runlist_commit,
|
||||
};
|
||||
|
||||
const struct nvkm_enum
|
||||
@ -68,7 +69,7 @@ gm107_fifo_fault_engine[] = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gm107_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gk208_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gm107_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -26,9 +26,23 @@
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
int
|
||||
gm200_fifo_pbdma_nr(struct gk104_fifo *fifo)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
return nvkm_rd32(device, 0x002004) & 0x000000ff;
|
||||
}
|
||||
|
||||
const struct gk104_fifo_pbdma_func
|
||||
gm200_fifo_pbdma = {
|
||||
.nr = gm200_fifo_pbdma_nr,
|
||||
.init = gk104_fifo_pbdma_init,
|
||||
.init_timeout = gk208_fifo_pbdma_init_timeout,
|
||||
};
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gm200_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gm107_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gm20b_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gm107_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -52,7 +52,7 @@ gp100_fifo_fault_engine[] = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gp100_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gp100_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gp10b_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gp100_fifo_fault_engine,
|
||||
.fault.reason = gk104_fifo_fault_reason,
|
||||
|
@ -85,7 +85,7 @@ gk104_fifo_gpfifo_engine_addr(struct nvkm_engine *engine)
|
||||
case NVKM_ENGINE_MSVLD : return 0x0270;
|
||||
case NVKM_ENGINE_VIC : return 0x0280;
|
||||
case NVKM_ENGINE_MSENC : return 0x0290;
|
||||
case NVKM_ENGINE_NVDEC : return 0x02100270;
|
||||
case NVKM_ENGINE_NVDEC0: return 0x02100270;
|
||||
case NVKM_ENGINE_NVENC0: return 0x02100290;
|
||||
case NVKM_ENGINE_NVENC1: return 0x0210;
|
||||
default:
|
||||
@ -192,7 +192,7 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
|
||||
gk104_fifo_runlist_remove(fifo, chan);
|
||||
nvkm_mask(device, 0x800004 + coff, 0x00000800, 0x00000800);
|
||||
gk104_fifo_gpfifo_kick(chan);
|
||||
gk104_fifo_runlist_commit(fifo, chan->runl);
|
||||
gk104_fifo_runlist_update(fifo, chan->runl);
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x800000 + coff, 0x00000000);
|
||||
@ -213,7 +213,7 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
|
||||
if (list_empty(&chan->head) && !chan->killed) {
|
||||
gk104_fifo_runlist_insert(fifo, chan);
|
||||
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
|
||||
gk104_fifo_runlist_commit(fifo, chan->runl);
|
||||
gk104_fifo_runlist_update(fifo, chan->runl);
|
||||
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
|
||||
}
|
||||
}
|
||||
@ -222,6 +222,7 @@ void *
|
||||
gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base)
|
||||
{
|
||||
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||
nvkm_memory_unref(&chan->mthd);
|
||||
kfree(chan->cgrp);
|
||||
return chan;
|
||||
}
|
||||
@ -240,7 +241,7 @@ gk104_fifo_gpfifo_func = {
|
||||
|
||||
static int
|
||||
gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
u64 vmm, u64 ioffset, u64 ilength,
|
||||
u64 vmm, u64 ioffset, u64 ilength, u64 *inst, bool priv,
|
||||
const struct nvkm_oclass *oclass,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
@ -279,6 +280,7 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
return ret;
|
||||
|
||||
*chid = chan->base.chid;
|
||||
*inst = chan->base.inst->addr;
|
||||
|
||||
/* Hack to support GPUs where even individual channels should be
|
||||
* part of a channel group.
|
||||
@ -315,6 +317,7 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
nvkm_wo32(chan->base.inst, 0x94, 0x30000001);
|
||||
nvkm_wo32(chan->base.inst, 0x9c, 0x00000100);
|
||||
nvkm_wo32(chan->base.inst, 0xac, 0x0000001f);
|
||||
nvkm_wo32(chan->base.inst, 0xe4, priv ? 0x00000020 : 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0xe8, chan->base.chid);
|
||||
nvkm_wo32(chan->base.inst, 0xb8, 0xf8000000);
|
||||
nvkm_wo32(chan->base.inst, 0xf8, 0x10003080); /* 0x002310 */
|
||||
@ -337,15 +340,19 @@ gk104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
||||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||
nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx "
|
||||
"ioffset %016llx ilength %08x "
|
||||
"runlist %016llx\n",
|
||||
"runlist %016llx priv %d\n",
|
||||
args->v0.version, args->v0.vmm, args->v0.ioffset,
|
||||
args->v0.ilength, args->v0.runlist);
|
||||
args->v0.ilength, args->v0.runlist, args->v0.priv);
|
||||
if (args->v0.priv && !oclass->client->super)
|
||||
return -EINVAL;
|
||||
return gk104_fifo_gpfifo_new_(fifo,
|
||||
&args->v0.runlist,
|
||||
&args->v0.chid,
|
||||
args->v0.vmm,
|
||||
args->v0.ioffset,
|
||||
args->v0.ilength,
|
||||
&args->v0.inst,
|
||||
args->v0.priv,
|
||||
oclass, pobject);
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,15 @@
|
||||
#include <core/client.h>
|
||||
#include <core/gpuobj.h>
|
||||
|
||||
#include <nvif/cla06f.h>
|
||||
#include <nvif/clc36f.h>
|
||||
#include <nvif/unpack.h>
|
||||
|
||||
static u32
|
||||
gv100_fifo_gpfifo_submit_token(struct nvkm_fifo_chan *chan)
|
||||
{
|
||||
return chan->chid;
|
||||
}
|
||||
|
||||
static int
|
||||
gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid)
|
||||
{
|
||||
@ -56,7 +62,7 @@ gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
|
||||
struct nvkm_engine *engine, bool suspend)
|
||||
{
|
||||
@ -79,7 +85,7 @@ gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base,
|
||||
struct nvkm_engine *engine)
|
||||
{
|
||||
@ -100,8 +106,8 @@ gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base,
|
||||
return gv100_fifo_gpfifo_engine_valid(chan, false, true);
|
||||
}
|
||||
|
||||
const struct nvkm_fifo_chan_func
|
||||
gv100_fifo_gpfifo_func = {
|
||||
static const struct nvkm_fifo_chan_func
|
||||
gv100_fifo_gpfifo = {
|
||||
.dtor = gk104_fifo_gpfifo_dtor,
|
||||
.init = gk104_fifo_gpfifo_init,
|
||||
.fini = gk104_fifo_gpfifo_fini,
|
||||
@ -110,19 +116,23 @@ gv100_fifo_gpfifo_func = {
|
||||
.engine_dtor = gk104_fifo_gpfifo_engine_dtor,
|
||||
.engine_init = gv100_fifo_gpfifo_engine_init,
|
||||
.engine_fini = gv100_fifo_gpfifo_engine_fini,
|
||||
.submit_token = gv100_fifo_gpfifo_submit_token,
|
||||
};
|
||||
|
||||
static int
|
||||
gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
u64 vmm, u64 ioffset, u64 ilength,
|
||||
const struct nvkm_oclass *oclass,
|
||||
int
|
||||
gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func *func,
|
||||
struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
u64 vmm, u64 ioffset, u64 ilength, u64 *inst, bool priv,
|
||||
u32 *token, const struct nvkm_oclass *oclass,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
struct gk104_fifo_chan *chan;
|
||||
int runlist = ffs(*runlists) -1, ret, i;
|
||||
unsigned long engm;
|
||||
u64 subdevs = 0;
|
||||
u64 usermem;
|
||||
u64 usermem, mthd;
|
||||
u32 size;
|
||||
|
||||
if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr)
|
||||
return -EINVAL;
|
||||
@ -142,14 +152,15 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
chan->runl = runlist;
|
||||
INIT_LIST_HEAD(&chan->head);
|
||||
|
||||
ret = nvkm_fifo_chan_ctor(&gv100_fifo_gpfifo_func, &fifo->base,
|
||||
0x1000, 0x1000, true, vmm, 0, subdevs,
|
||||
1, fifo->user.bar->addr, 0x200,
|
||||
ret = nvkm_fifo_chan_ctor(func, &fifo->base, 0x1000, 0x1000, true, vmm,
|
||||
0, subdevs, 1, fifo->user.bar->addr, 0x200,
|
||||
oclass, &chan->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*chid = chan->base.chid;
|
||||
*inst = chan->base.inst->addr;
|
||||
*token = chan->base.func->submit_token(&chan->base);
|
||||
|
||||
/* Hack to support GPUs where even individual channels should be
|
||||
* part of a channel group.
|
||||
@ -173,6 +184,20 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
nvkm_done(fifo->user.mem);
|
||||
usermem = nvkm_memory_addr(fifo->user.mem) + usermem;
|
||||
|
||||
/* Allocate fault method buffer (magics come from nvgpu). */
|
||||
size = nvkm_rd32(device, 0x104028); /* NV_PCE_PCE_MAP */
|
||||
size = 27 * 5 * (((9 + 1 + 3) * hweight32(size)) + 2);
|
||||
size = roundup(size, PAGE_SIZE);
|
||||
|
||||
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, true,
|
||||
&chan->mthd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mthd = nvkm_memory_bar2(chan->mthd);
|
||||
if (mthd == ~0ULL)
|
||||
return -EFAULT;
|
||||
|
||||
/* RAMFC */
|
||||
nvkm_kmap(chan->base.inst);
|
||||
nvkm_wo32(chan->base.inst, 0x008, lower_32_bits(usermem));
|
||||
@ -184,13 +209,13 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
(ilength << 16));
|
||||
nvkm_wo32(chan->base.inst, 0x084, 0x20400000);
|
||||
nvkm_wo32(chan->base.inst, 0x094, 0x30000001);
|
||||
nvkm_wo32(chan->base.inst, 0x0e4, 0x00000020);
|
||||
nvkm_wo32(chan->base.inst, 0x0e4, priv ? 0x00000020 : 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0x0e8, chan->base.chid);
|
||||
nvkm_wo32(chan->base.inst, 0x0f4, 0x00001100);
|
||||
nvkm_wo32(chan->base.inst, 0x0f4, 0x00001000);
|
||||
nvkm_wo32(chan->base.inst, 0x0f8, 0x10003080);
|
||||
nvkm_mo32(chan->base.inst, 0x218, 0x00000000, 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0x220, 0x020a1000);
|
||||
nvkm_wo32(chan->base.inst, 0x224, 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0x220, lower_32_bits(mthd));
|
||||
nvkm_wo32(chan->base.inst, 0x224, upper_32_bits(mthd));
|
||||
nvkm_done(chan->base.inst);
|
||||
return gv100_fifo_gpfifo_engine_valid(chan, true, true);
|
||||
}
|
||||
@ -201,7 +226,7 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
||||
{
|
||||
struct nvkm_object *parent = oclass->parent;
|
||||
union {
|
||||
struct kepler_channel_gpfifo_a_v0 v0;
|
||||
struct volta_channel_gpfifo_a_v0 v0;
|
||||
} *args = data;
|
||||
int ret = -ENOSYS;
|
||||
|
||||
@ -209,15 +234,20 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
||||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||
nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx "
|
||||
"ioffset %016llx ilength %08x "
|
||||
"runlist %016llx\n",
|
||||
"runlist %016llx priv %d\n",
|
||||
args->v0.version, args->v0.vmm, args->v0.ioffset,
|
||||
args->v0.ilength, args->v0.runlist);
|
||||
return gv100_fifo_gpfifo_new_(fifo,
|
||||
args->v0.ilength, args->v0.runlist, args->v0.priv);
|
||||
if (args->v0.priv && !oclass->client->super)
|
||||
return -EINVAL;
|
||||
return gv100_fifo_gpfifo_new_(&gv100_fifo_gpfifo, fifo,
|
||||
&args->v0.runlist,
|
||||
&args->v0.chid,
|
||||
args->v0.vmm,
|
||||
args->v0.ioffset,
|
||||
args->v0.ilength,
|
||||
&args->v0.inst,
|
||||
args->v0.priv,
|
||||
&args->v0.token,
|
||||
oclass, pobject);
|
||||
}
|
||||
|
||||
|
83
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifotu104.c
Normal file
83
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifotu104.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 "changk104.h"
|
||||
#include "cgrp.h"
|
||||
|
||||
#include <core/client.h>
|
||||
#include <core/gpuobj.h>
|
||||
|
||||
#include <nvif/clc36f.h>
|
||||
#include <nvif/unpack.h>
|
||||
|
||||
static u32
|
||||
tu104_fifo_gpfifo_submit_token(struct nvkm_fifo_chan *base)
|
||||
{
|
||||
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||
return (chan->runl << 16) | chan->base.chid;
|
||||
}
|
||||
|
||||
static const struct nvkm_fifo_chan_func
|
||||
tu104_fifo_gpfifo = {
|
||||
.dtor = gk104_fifo_gpfifo_dtor,
|
||||
.init = gk104_fifo_gpfifo_init,
|
||||
.fini = gk104_fifo_gpfifo_fini,
|
||||
.ntfy = gf100_fifo_chan_ntfy,
|
||||
.engine_ctor = gk104_fifo_gpfifo_engine_ctor,
|
||||
.engine_dtor = gk104_fifo_gpfifo_engine_dtor,
|
||||
.engine_init = gv100_fifo_gpfifo_engine_init,
|
||||
.engine_fini = gv100_fifo_gpfifo_engine_fini,
|
||||
.submit_token = tu104_fifo_gpfifo_submit_token,
|
||||
};
|
||||
|
||||
int
|
||||
tu104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
||||
void *data, u32 size, struct nvkm_object **pobject)
|
||||
{
|
||||
struct nvkm_object *parent = oclass->parent;
|
||||
union {
|
||||
struct volta_channel_gpfifo_a_v0 v0;
|
||||
} *args = data;
|
||||
int ret = -ENOSYS;
|
||||
|
||||
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
|
||||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||
nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx "
|
||||
"ioffset %016llx ilength %08x "
|
||||
"runlist %016llx priv %d\n",
|
||||
args->v0.version, args->v0.vmm, args->v0.ioffset,
|
||||
args->v0.ilength, args->v0.runlist, args->v0.priv);
|
||||
if (args->v0.priv && !oclass->client->super)
|
||||
return -EINVAL;
|
||||
return gv100_fifo_gpfifo_new_(&tu104_fifo_gpfifo, fifo,
|
||||
&args->v0.runlist,
|
||||
&args->v0.chid,
|
||||
args->v0.vmm,
|
||||
args->v0.ioffset,
|
||||
args->v0.ilength,
|
||||
&args->v0.inst,
|
||||
args->v0.priv,
|
||||
&args->v0.token,
|
||||
oclass, pobject);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_fifo_runlist_chan(struct gk104_fifo_chan *chan,
|
||||
struct nvkm_memory *memory, u32 offset)
|
||||
{
|
||||
@ -42,7 +42,7 @@ gv100_fifo_runlist_chan(struct gk104_fifo_chan *chan,
|
||||
nvkm_wo32(memory, offset + 0xc, upper_32_bits(inst));
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gv100_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *cgrp,
|
||||
struct nvkm_memory *memory, u32 offset)
|
||||
{
|
||||
@ -57,9 +57,10 @@ gv100_fifo_runlist = {
|
||||
.size = 16,
|
||||
.cgrp = gv100_fifo_runlist_cgrp,
|
||||
.chan = gv100_fifo_runlist_chan,
|
||||
.commit = gk104_fifo_runlist_commit,
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
const struct nvkm_enum
|
||||
gv100_fifo_fault_gpcclient[] = {
|
||||
{ 0x00, "T1_0" },
|
||||
{ 0x01, "T1_1" },
|
||||
@ -161,7 +162,7 @@ gv100_fifo_fault_gpcclient[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
const struct nvkm_enum
|
||||
gv100_fifo_fault_hubclient[] = {
|
||||
{ 0x00, "VIP" },
|
||||
{ 0x01, "CE0" },
|
||||
@ -223,7 +224,7 @@ gv100_fifo_fault_hubclient[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
const struct nvkm_enum
|
||||
gv100_fifo_fault_reason[] = {
|
||||
{ 0x00, "PDE" },
|
||||
{ 0x01, "PDE_SIZE" },
|
||||
@ -271,7 +272,7 @@ gv100_fifo_fault_engine[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
const struct nvkm_enum
|
||||
gv100_fifo_fault_access[] = {
|
||||
{ 0x0, "VIRT_READ" },
|
||||
{ 0x1, "VIRT_WRITE" },
|
||||
@ -287,7 +288,7 @@ gv100_fifo_fault_access[] = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gv100_fifo = {
|
||||
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gv100_fifo_fault_access,
|
||||
.fault.engine = gv100_fifo_fault_engine,
|
||||
.fault.reason = gv100_fifo_fault_reason,
|
||||
|
116
drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu104.c
Normal file
116
drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu104.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 "gk104.h"
|
||||
#include "cgrp.h"
|
||||
#include "changk104.h"
|
||||
#include "user.h"
|
||||
|
||||
#include <core/gpuobj.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static void
|
||||
tu104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl,
|
||||
struct nvkm_memory *mem, int nr)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
u64 addr = nvkm_memory_addr(mem);
|
||||
/*XXX: target? */
|
||||
|
||||
nvkm_wr32(device, 0x002b00 + (runl * 0x10), lower_32_bits(addr));
|
||||
nvkm_wr32(device, 0x002b04 + (runl * 0x10), upper_32_bits(addr));
|
||||
nvkm_wr32(device, 0x002b08 + (runl * 0x10), nr);
|
||||
|
||||
/*XXX: how to wait? can you even wait? */
|
||||
}
|
||||
|
||||
const struct gk104_fifo_runlist_func
|
||||
tu104_fifo_runlist = {
|
||||
.size = 16,
|
||||
.cgrp = gv100_fifo_runlist_cgrp,
|
||||
.chan = gv100_fifo_runlist_chan,
|
||||
.commit = tu104_fifo_runlist_commit,
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
tu104_fifo_fault_engine[] = {
|
||||
{ 0x01, "DISPLAY" },
|
||||
{ 0x03, "PTP" },
|
||||
{ 0x06, "PWR_PMU" },
|
||||
{ 0x08, "IFB", NULL, NVKM_ENGINE_IFB },
|
||||
{ 0x09, "PERF" },
|
||||
{ 0x1f, "PHYSICAL" },
|
||||
{ 0x20, "HOST0" },
|
||||
{ 0x21, "HOST1" },
|
||||
{ 0x22, "HOST2" },
|
||||
{ 0x23, "HOST3" },
|
||||
{ 0x24, "HOST4" },
|
||||
{ 0x25, "HOST5" },
|
||||
{ 0x26, "HOST6" },
|
||||
{ 0x27, "HOST7" },
|
||||
{ 0x28, "HOST8" },
|
||||
{ 0x29, "HOST9" },
|
||||
{ 0x2a, "HOST10" },
|
||||
{ 0x2b, "HOST11" },
|
||||
{ 0x2c, "HOST12" },
|
||||
{ 0x2d, "HOST13" },
|
||||
{ 0x2e, "HOST14" },
|
||||
{ 0x80, "BAR1", NULL, NVKM_SUBDEV_BAR },
|
||||
{ 0xc0, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
tu104_fifo_pbdma_init(struct gk104_fifo *fifo)
|
||||
{
|
||||
struct nvkm_device *device = fifo->base.engine.subdev.device;
|
||||
const u32 mask = (1 << fifo->pbdma_nr) - 1;
|
||||
/*XXX: this is a bit of a guess at this point in time. */
|
||||
nvkm_mask(device, 0xb65000, 0x80000fff, 0x80000000 | mask);
|
||||
}
|
||||
|
||||
static const struct gk104_fifo_pbdma_func
|
||||
tu104_fifo_pbdma = {
|
||||
.nr = gm200_fifo_pbdma_nr,
|
||||
.init = tu104_fifo_pbdma_init,
|
||||
.init_timeout = gk208_fifo_pbdma_init_timeout,
|
||||
};
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
tu104_fifo = {
|
||||
.pbdma = &tu104_fifo_pbdma,
|
||||
.fault.access = gv100_fifo_fault_access,
|
||||
.fault.engine = tu104_fifo_fault_engine,
|
||||
.fault.reason = gv100_fifo_fault_reason,
|
||||
.fault.hubclient = gv100_fifo_fault_hubclient,
|
||||
.fault.gpcclient = gv100_fifo_fault_gpcclient,
|
||||
.runlist = &tu104_fifo_runlist,
|
||||
.user = {{-1,-1,VOLTA_USERMODE_A }, tu104_fifo_user_new },
|
||||
.chan = {{ 0, 0,TURING_CHANNEL_GPFIFO_A}, tu104_fifo_gpfifo_new },
|
||||
.cgrp_force = true,
|
||||
};
|
||||
|
||||
int
|
||||
tu104_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
|
||||
{
|
||||
return gk104_fifo_new_(&tu104_fifo, device, index, 4096, pfifo);
|
||||
}
|
@ -3,4 +3,6 @@
|
||||
#include "priv.h"
|
||||
int gv100_fifo_user_new(const struct nvkm_oclass *, void *, u32,
|
||||
struct nvkm_object **);
|
||||
int tu104_fifo_user_new(const struct nvkm_oclass *, void *, u32,
|
||||
struct nvkm_object **);
|
||||
#endif
|
||||
|
45
drivers/gpu/drm/nouveau/nvkm/engine/fifo/usertu104.c
Normal file
45
drivers/gpu/drm/nouveau/nvkm/engine/fifo/usertu104.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 "user.h"
|
||||
|
||||
static int
|
||||
tu104_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc,
|
||||
enum nvkm_object_map *type, u64 *addr, u64 *size)
|
||||
{
|
||||
struct nvkm_device *device = object->engine->subdev.device;
|
||||
*addr = 0xbb0000 + device->func->resource_addr(device, 0);
|
||||
*size = 0x010000;
|
||||
*type = NVKM_OBJECT_MAP_IO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nvkm_object_func
|
||||
tu104_fifo_user = {
|
||||
.map = tu104_fifo_user_map,
|
||||
};
|
||||
|
||||
int
|
||||
tu104_fifo_user_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
return nvkm_object_new_(&tu104_fifo_user, oclass, argv, argc, pobject);
|
||||
}
|
@ -197,7 +197,7 @@ nvkm_falcon_ctor(const struct nvkm_falcon_func *func,
|
||||
case NVKM_SUBDEV_PMU:
|
||||
debug_reg = 0xc08;
|
||||
break;
|
||||
case NVKM_ENGINE_NVDEC:
|
||||
case NVKM_ENGINE_NVDEC0:
|
||||
debug_reg = 0xd00;
|
||||
break;
|
||||
case NVKM_ENGINE_SEC2:
|
||||
|
@ -5,3 +5,4 @@ nvkm-y += nvkm/subdev/bar/gf100.o
|
||||
nvkm-y += nvkm/subdev/bar/gk20a.o
|
||||
nvkm-y += nvkm/subdev/bar/gm107.o
|
||||
nvkm-y += nvkm/subdev/bar/gm20b.o
|
||||
nvkm-y += nvkm/subdev/bar/tu104.o
|
||||
|
@ -36,6 +36,16 @@ nvkm_bar_bar1_vmm(struct nvkm_device *device)
|
||||
return device->bar->func->bar1.vmm(device->bar);
|
||||
}
|
||||
|
||||
void
|
||||
nvkm_bar_bar1_reset(struct nvkm_device *device)
|
||||
{
|
||||
struct nvkm_bar *bar = device->bar;
|
||||
if (bar) {
|
||||
bar->func->bar1.init(bar);
|
||||
bar->func->bar1.wait(bar);
|
||||
}
|
||||
}
|
||||
|
||||
struct nvkm_vmm *
|
||||
nvkm_bar_bar2_vmm(struct nvkm_device *device)
|
||||
{
|
||||
@ -48,6 +58,16 @@ nvkm_bar_bar2_vmm(struct nvkm_device *device)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nvkm_bar_bar2_reset(struct nvkm_device *device)
|
||||
{
|
||||
struct nvkm_bar *bar = device->bar;
|
||||
if (bar && bar->bar2) {
|
||||
bar->func->bar2.init(bar);
|
||||
bar->func->bar2.wait(bar);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nvkm_bar_bar2_fini(struct nvkm_device *device)
|
||||
{
|
||||
|
98
drivers/gpu/drm/nouveau/nvkm/subdev/bar/tu104.c
Normal file
98
drivers/gpu/drm/nouveau/nvkm/subdev/bar/tu104.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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 "gf100.h"
|
||||
|
||||
#include <core/memory.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
static void
|
||||
tu104_bar_bar2_wait(struct nvkm_bar *bar)
|
||||
{
|
||||
struct nvkm_device *device = bar->subdev.device;
|
||||
nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0xb80f50) & 0x0000000c))
|
||||
break;
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
tu104_bar_bar2_fini(struct nvkm_bar *bar)
|
||||
{
|
||||
nvkm_mask(bar->subdev.device, 0xb80f48, 0x80000000, 0x00000000);
|
||||
}
|
||||
|
||||
static void
|
||||
tu104_bar_bar2_init(struct nvkm_bar *base)
|
||||
{
|
||||
struct nvkm_device *device = base->subdev.device;
|
||||
struct gf100_bar *bar = gf100_bar(base);
|
||||
u32 addr = nvkm_memory_addr(bar->bar[0].inst) >> 12;
|
||||
if (bar->bar2_halve)
|
||||
addr |= 0x40000000;
|
||||
nvkm_wr32(device, 0xb80f48, 0x80000000 | addr);
|
||||
}
|
||||
|
||||
static void
|
||||
tu104_bar_bar1_wait(struct nvkm_bar *bar)
|
||||
{
|
||||
struct nvkm_device *device = bar->subdev.device;
|
||||
nvkm_msec(device, 2000,
|
||||
if (!(nvkm_rd32(device, 0xb80f50) & 0x00000003))
|
||||
break;
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
tu104_bar_bar1_fini(struct nvkm_bar *bar)
|
||||
{
|
||||
nvkm_mask(bar->subdev.device, 0xb80f40, 0x80000000, 0x00000000);
|
||||
}
|
||||
|
||||
static void
|
||||
tu104_bar_bar1_init(struct nvkm_bar *base)
|
||||
{
|
||||
struct nvkm_device *device = base->subdev.device;
|
||||
struct gf100_bar *bar = gf100_bar(base);
|
||||
const u32 addr = nvkm_memory_addr(bar->bar[1].inst) >> 12;
|
||||
nvkm_wr32(device, 0xb80f40, 0x80000000 | addr);
|
||||
}
|
||||
|
||||
static const struct nvkm_bar_func
|
||||
tu104_bar = {
|
||||
.dtor = gf100_bar_dtor,
|
||||
.oneinit = gf100_bar_oneinit,
|
||||
.bar1.init = tu104_bar_bar1_init,
|
||||
.bar1.fini = tu104_bar_bar1_fini,
|
||||
.bar1.wait = tu104_bar_bar1_wait,
|
||||
.bar1.vmm = gf100_bar_bar1_vmm,
|
||||
.bar2.init = tu104_bar_bar2_init,
|
||||
.bar2.fini = tu104_bar_bar2_fini,
|
||||
.bar2.wait = tu104_bar_bar2_wait,
|
||||
.bar2.vmm = gf100_bar_bar2_vmm,
|
||||
.flush = g84_bar_flush,
|
||||
};
|
||||
|
||||
int
|
||||
tu104_bar_new(struct nvkm_device *device, int index, struct nvkm_bar **pbar)
|
||||
{
|
||||
return gf100_bar_new_(&tu104_bar, device, index, pbar);
|
||||
}
|
@ -13,3 +13,4 @@ nvkm-y += nvkm/subdev/devinit/gf100.o
|
||||
nvkm-y += nvkm/subdev/devinit/gm107.o
|
||||
nvkm-y += nvkm/subdev/devinit/gm200.o
|
||||
nvkm-y += nvkm/subdev/devinit/gv100.o
|
||||
nvkm-y += nvkm/subdev/devinit/tu104.o
|
||||
|
@ -105,6 +105,15 @@ pmu_load(struct nv50_devinit *init, u8 type, bool post,
|
||||
return pmu_exec(init, pmu.init_addr_pmu), 0;
|
||||
}
|
||||
|
||||
void
|
||||
gm200_devinit_preos(struct nv50_devinit *init, bool post)
|
||||
{
|
||||
/* Optional: Execute PRE_OS application on PMU, which should at
|
||||
* least take care of fans until a full PMU has been loaded.
|
||||
*/
|
||||
pmu_load(init, 0x01, post, NULL, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
gm200_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
{
|
||||
@ -156,10 +165,7 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Optional: Execute PRE_OS application on PMU, which should at
|
||||
* least take care of fans until a full PMU has been loaded.
|
||||
*/
|
||||
pmu_load(init, 0x01, post, NULL, NULL);
|
||||
gm200_devinit_preos(init, post);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -26,4 +26,5 @@ void gf100_devinit_preinit(struct nvkm_devinit *);
|
||||
u64 gm107_devinit_disable(struct nvkm_devinit *);
|
||||
|
||||
int gm200_devinit_post(struct nvkm_devinit *, bool);
|
||||
void gm200_devinit_preos(struct nv50_devinit *, bool);
|
||||
#endif
|
||||
|
89
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu104.c
Normal file
89
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu104.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 "nv50.h"
|
||||
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bios/pll.h>
|
||||
#include <subdev/clk/pll.h>
|
||||
|
||||
static int
|
||||
tu104_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &init->subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
struct nvbios_pll info;
|
||||
int head = type - PLL_VPLL0;
|
||||
int N, fN, M, P;
|
||||
int ret;
|
||||
|
||||
ret = nvbios_pll_parse(device->bios, type, &info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (info.type) {
|
||||
case PLL_VPLL0:
|
||||
case PLL_VPLL1:
|
||||
case PLL_VPLL2:
|
||||
case PLL_VPLL3:
|
||||
nvkm_wr32(device, 0x00ef10 + (head * 0x40), fN << 16);
|
||||
nvkm_wr32(device, 0x00ef04 + (head * 0x40), (P << 16) |
|
||||
(N << 8) |
|
||||
(M << 0));
|
||||
/*XXX*/
|
||||
nvkm_wr32(device, 0x00ef0c + (head * 0x40), 0x00000900);
|
||||
nvkm_wr32(device, 0x00ef00 + (head * 0x40), 0x02000014);
|
||||
break;
|
||||
default:
|
||||
nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
tu104_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
{
|
||||
struct nv50_devinit *init = nv50_devinit(base);
|
||||
gm200_devinit_preos(init, post);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct nvkm_devinit_func
|
||||
tu104_devinit = {
|
||||
.init = nv50_devinit_init,
|
||||
.post = tu104_devinit_post,
|
||||
.pll_set = tu104_devinit_pll_set,
|
||||
.disable = gm107_devinit_disable,
|
||||
};
|
||||
|
||||
int
|
||||
tu104_devinit_new(struct nvkm_device *device, int index,
|
||||
struct nvkm_devinit **pinit)
|
||||
{
|
||||
return nv50_devinit_new_(&tu104_devinit, device, index, pinit);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
nvkm-y += nvkm/subdev/fault/base.o
|
||||
nvkm-y += nvkm/subdev/fault/gp100.o
|
||||
nvkm-y += nvkm/subdev/fault/gv100.o
|
||||
nvkm-y += nvkm/subdev/fault/tu104.o
|
||||
|
@ -23,21 +23,19 @@
|
||||
|
||||
#include <core/memory.h>
|
||||
#include <core/notify.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/mmu.h>
|
||||
|
||||
static void
|
||||
nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index)
|
||||
{
|
||||
struct nvkm_fault *fault = container_of(event, typeof(*fault), event);
|
||||
fault->func->buffer.fini(fault->buffer[index]);
|
||||
fault->func->buffer.intr(fault->buffer[index], false);
|
||||
}
|
||||
|
||||
static void
|
||||
nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index)
|
||||
{
|
||||
struct nvkm_fault *fault = container_of(event, typeof(*fault), event);
|
||||
fault->func->buffer.init(fault->buffer[index]);
|
||||
fault->func->buffer.intr(fault->buffer[index], true);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -91,7 +89,6 @@ nvkm_fault_oneinit_buffer(struct nvkm_fault *fault, int id)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fault->subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
struct nvkm_vmm *bar2 = nvkm_bar_bar2_vmm(device);
|
||||
struct nvkm_fault_buffer *buffer;
|
||||
int ret;
|
||||
|
||||
@ -99,7 +96,7 @@ nvkm_fault_oneinit_buffer(struct nvkm_fault *fault, int id)
|
||||
return -ENOMEM;
|
||||
buffer->fault = fault;
|
||||
buffer->id = id;
|
||||
buffer->entries = fault->func->buffer.entries(buffer);
|
||||
fault->func->buffer.info(buffer);
|
||||
fault->buffer[id] = buffer;
|
||||
|
||||
nvkm_debug(subdev, "buffer %d: %d entries\n", id, buffer->entries);
|
||||
@ -110,12 +107,12 @@ nvkm_fault_oneinit_buffer(struct nvkm_fault *fault, int id)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvkm_vmm_get(bar2, 12, nvkm_memory_size(buffer->mem),
|
||||
&buffer->vma);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Pin fault buffer in BAR2. */
|
||||
buffer->addr = nvkm_memory_bar2(buffer->mem);
|
||||
if (buffer->addr == ~0ULL)
|
||||
return -EFAULT;
|
||||
|
||||
return nvkm_memory_map(buffer->mem, 0, bar2, buffer->vma, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -146,7 +143,6 @@ nvkm_fault_oneinit(struct nvkm_subdev *subdev)
|
||||
static void *
|
||||
nvkm_fault_dtor(struct nvkm_subdev *subdev)
|
||||
{
|
||||
struct nvkm_vmm *bar2 = nvkm_bar_bar2_vmm(subdev->device);
|
||||
struct nvkm_fault *fault = nvkm_fault(subdev);
|
||||
int i;
|
||||
|
||||
@ -154,7 +150,6 @@ nvkm_fault_dtor(struct nvkm_subdev *subdev)
|
||||
|
||||
for (i = 0; i < fault->buffer_nr; i++) {
|
||||
if (fault->buffer[i]) {
|
||||
nvkm_vmm_put(bar2, &fault->buffer[i]->vma);
|
||||
nvkm_memory_unref(&fault->buffer[i]->mem);
|
||||
kfree(fault->buffer[i]);
|
||||
}
|
||||
|
@ -21,7 +21,14 @@
|
||||
*/
|
||||
#include "priv.h"
|
||||
|
||||
#include <subdev/mmu.h>
|
||||
#include <subdev/mc.h>
|
||||
|
||||
static void
|
||||
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
|
||||
{
|
||||
struct nvkm_device *device = buffer->fault->subdev.device;
|
||||
nvkm_mc_intr_mask(device, NVKM_SUBDEV_FAULT, enable);
|
||||
}
|
||||
|
||||
static void
|
||||
gp100_fault_buffer_fini(struct nvkm_fault_buffer *buffer)
|
||||
@ -34,15 +41,17 @@ static void
|
||||
gp100_fault_buffer_init(struct nvkm_fault_buffer *buffer)
|
||||
{
|
||||
struct nvkm_device *device = buffer->fault->subdev.device;
|
||||
nvkm_wr32(device, 0x002a74, upper_32_bits(buffer->vma->addr));
|
||||
nvkm_wr32(device, 0x002a70, lower_32_bits(buffer->vma->addr));
|
||||
nvkm_wr32(device, 0x002a74, upper_32_bits(buffer->addr));
|
||||
nvkm_wr32(device, 0x002a70, lower_32_bits(buffer->addr));
|
||||
nvkm_mask(device, 0x002a70, 0x00000001, 0x00000001);
|
||||
}
|
||||
|
||||
static u32
|
||||
gp100_fault_buffer_entries(struct nvkm_fault_buffer *buffer)
|
||||
static void
|
||||
gp100_fault_buffer_info(struct nvkm_fault_buffer *buffer)
|
||||
{
|
||||
return nvkm_rd32(buffer->fault->subdev.device, 0x002a78);
|
||||
buffer->entries = nvkm_rd32(buffer->fault->subdev.device, 0x002a78);
|
||||
buffer->get = 0x002a7c;
|
||||
buffer->put = 0x002a80;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -56,9 +65,10 @@ gp100_fault = {
|
||||
.intr = gp100_fault_intr,
|
||||
.buffer.nr = 1,
|
||||
.buffer.entry_size = 32,
|
||||
.buffer.entries = gp100_fault_buffer_entries,
|
||||
.buffer.info = gp100_fault_buffer_info,
|
||||
.buffer.init = gp100_fault_buffer_init,
|
||||
.buffer.fini = gp100_fault_buffer_fini,
|
||||
.buffer.intr = gp100_fault_buffer_intr,
|
||||
};
|
||||
|
||||
int
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user