Merge branch 'linux-5.6' of git://github.com/skeggsb/linux into drm-next

Just a couple of fixes to Volta/Turing modesetting on some systems.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ <CACAvsv7=eP+Ai1ouoMyYyo1xMF0pTQki=owYjJkS=NpvKQd1fg@mail.gmail.com
This commit is contained in:
Dave Airlie 2020-02-07 12:23:24 +10:00
commit a345cc0d39
5 changed files with 50 additions and 10 deletions

View File

@ -6,6 +6,7 @@
struct nv50_core { struct nv50_core {
const struct nv50_core_func *func; const struct nv50_core_func *func;
struct nv50_dmac chan; struct nv50_dmac chan;
bool assign_windows;
}; };
int nv50_core_new(struct nouveau_drm *, struct nv50_core **); int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
@ -18,6 +19,10 @@ struct nv50_core_func {
struct nvif_device *); struct nvif_device *);
void (*update)(struct nv50_core *, u32 *interlock, bool ntfy); void (*update)(struct nv50_core *, u32 *interlock, bool ntfy);
struct {
void (*owner)(struct nv50_core *);
} wndw;
const struct nv50_head_func *head; const struct nv50_head_func *head;
const struct nv50_outp_func { const struct nv50_outp_func {
void (*ctrl)(struct nv50_core *, int or, u32 ctrl, void (*ctrl)(struct nv50_core *, int or, u32 ctrl,
@ -48,6 +53,7 @@ int core917d_new(struct nouveau_drm *, s32, struct nv50_core **);
int corec37d_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 *); int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
void corec37d_update(struct nv50_core *, u32 *, bool); void corec37d_update(struct nv50_core *, u32 *, bool);
void corec37d_wndw_owner(struct nv50_core *);
extern const struct nv50_outp_func sorc37d; extern const struct nv50_outp_func sorc37d;
int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **); int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **);

View File

@ -24,6 +24,20 @@
#include <nouveau_bo.h> #include <nouveau_bo.h>
void
corec37d_wndw_owner(struct nv50_core *core)
{
const u32 windows = 8; /*XXX*/
u32 *push, i;
if ((push = evo_wait(&core->chan, 2 * windows))) {
for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1000 + (i * 0x080), 1);
evo_data(push, i >> 1);
}
evo_kick(push, &core->chan);
}
}
void void
corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy) corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
{ {
@ -76,20 +90,18 @@ corec37d_init(struct nv50_core *core)
{ {
const u32 windows = 8; /*XXX*/ const u32 windows = 8; /*XXX*/
u32 *push, i; u32 *push, i;
if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) { if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
evo_mthd(push, 0x0208, 1); evo_mthd(push, 0x0208, 1);
evo_data(push, core->chan.sync.handle); evo_data(push, core->chan.sync.handle);
for (i = 0; i < windows; i++) { for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1000 + (i * 0x080), 3); evo_mthd(push, 0x1004 + (i * 0x080), 2);
evo_data(push, i >> 1);
evo_data(push, 0x0000001f); evo_data(push, 0x0000001f);
evo_data(push, 0x00000000); evo_data(push, 0x00000000);
evo_mthd(push, 0x1010 + (i * 0x080), 1); evo_mthd(push, 0x1010 + (i * 0x080), 1);
evo_data(push, 0x00127fff); evo_data(push, 0x00127fff);
} }
evo_mthd(push, 0x0200, 1);
evo_data(push, 0x00000001);
evo_kick(push, &core->chan); evo_kick(push, &core->chan);
core->assign_windows = true;
} }
} }
@ -99,6 +111,7 @@ corec37d = {
.ntfy_init = corec37d_ntfy_init, .ntfy_init = corec37d_ntfy_init,
.ntfy_wait_done = corec37d_ntfy_wait_done, .ntfy_wait_done = corec37d_ntfy_wait_done,
.update = corec37d_update, .update = corec37d_update,
.wndw.owner = corec37d_wndw_owner,
.head = &headc37d, .head = &headc37d,
.sor = &sorc37d, .sor = &sorc37d,
}; };

View File

@ -27,20 +27,18 @@ corec57d_init(struct nv50_core *core)
{ {
const u32 windows = 8; /*XXX*/ const u32 windows = 8; /*XXX*/
u32 *push, i; u32 *push, i;
if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) { if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
evo_mthd(push, 0x0208, 1); evo_mthd(push, 0x0208, 1);
evo_data(push, core->chan.sync.handle); evo_data(push, core->chan.sync.handle);
for (i = 0; i < windows; i++) { for (i = 0; i < windows; i++) {
evo_mthd(push, 0x1000 + (i * 0x080), 3); evo_mthd(push, 0x1004 + (i * 0x080), 2);
evo_data(push, i >> 1);
evo_data(push, 0x0000000f); evo_data(push, 0x0000000f);
evo_data(push, 0x00000000); evo_data(push, 0x00000000);
evo_mthd(push, 0x1010 + (i * 0x080), 1); evo_mthd(push, 0x1010 + (i * 0x080), 1);
evo_data(push, 0x00117fff); evo_data(push, 0x00117fff);
} }
evo_mthd(push, 0x0200, 1);
evo_data(push, 0x00000001);
evo_kick(push, &core->chan); evo_kick(push, &core->chan);
core->assign_windows = true;
} }
} }
@ -50,6 +48,7 @@ corec57d = {
.ntfy_init = corec37d_ntfy_init, .ntfy_init = corec37d_ntfy_init,
.ntfy_wait_done = corec37d_ntfy_wait_done, .ntfy_wait_done = corec37d_ntfy_wait_done,
.update = corec37d_update, .update = corec37d_update,
.wndw.owner = corec37d_wndw_owner,
.head = &headc57d, .head = &headc57d,
.sor = &sorc37d, .sor = &sorc37d,
}; };

View File

@ -1933,6 +1933,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev); struct nv50_disp *disp = nv50_disp(dev);
struct nv50_atom *atom = nv50_atom(state); struct nv50_atom *atom = nv50_atom(state);
struct nv50_core *core = disp->core;
struct nv50_outp_atom *outp, *outt; struct nv50_outp_atom *outp, *outt;
u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {}; u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {};
int i; int i;
@ -2051,6 +2052,21 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
} }
} }
/* Update window->head assignment.
*
* This has to happen in an update that's not interlocked with
* any window channels to avoid hitting HW error checks.
*
*TODO: Proper handling of window ownership (Turing apparently
* supports non-fixed mappings).
*/
if (core->assign_windows) {
core->func->wndw.owner(core);
core->func->update(core, interlock, false);
core->assign_windows = false;
interlock[NV50_DISP_INTERLOCK_CORE] = 0;
}
/* Update plane(s). */ /* Update plane(s). */
for_each_new_plane_in_state(state, plane, new_plane_state, i) { for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);

View File

@ -155,6 +155,12 @@ gv100_disp_intr_ctrl_disp(struct nv50_disp *disp)
if (stat & 0x00000008) if (stat & 0x00000008)
stat &= ~0x00000008; stat &= ~0x00000008;
if (stat & 0x00000080) {
u32 error = nvkm_mask(device, 0x611848, 0x00000000, 0x00000000);
nvkm_warn(subdev, "error %08x\n", error);
stat &= ~0x00000080;
}
if (stat & 0x00000100) { if (stat & 0x00000100) {
unsigned long wndws = nvkm_rd32(device, 0x611858); unsigned long wndws = nvkm_rd32(device, 0x611858);
unsigned long other = nvkm_rd32(device, 0x61185c); unsigned long other = nvkm_rd32(device, 0x61185c);