Commit a345cc0d authored by Dave Airlie's avatar Dave Airlie

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: default avatarDave 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
parents e139e8ae 137c4ba7
......@@ -6,6 +6,7 @@
struct nv50_core {
const struct nv50_core_func *func;
struct nv50_dmac chan;
bool assign_windows;
};
int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
......@@ -18,6 +19,10 @@ struct nv50_core_func {
struct nvif_device *);
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_outp_func {
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_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
void corec37d_update(struct nv50_core *, u32 *, bool);
void corec37d_wndw_owner(struct nv50_core *);
extern const struct nv50_outp_func sorc37d;
int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **);
......
......@@ -24,6 +24,20 @@
#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
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*/
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_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_mthd(push, 0x1004 + (i * 0x080), 2);
evo_data(push, 0x0000001f);
evo_data(push, 0x00000000);
evo_mthd(push, 0x1010 + (i * 0x080), 1);
evo_data(push, 0x00127fff);
}
evo_mthd(push, 0x0200, 1);
evo_data(push, 0x00000001);
evo_kick(push, &core->chan);
core->assign_windows = true;
}
}
......@@ -99,6 +111,7 @@ corec37d = {
.ntfy_init = corec37d_ntfy_init,
.ntfy_wait_done = corec37d_ntfy_wait_done,
.update = corec37d_update,
.wndw.owner = corec37d_wndw_owner,
.head = &headc37d,
.sor = &sorc37d,
};
......
......@@ -27,20 +27,18 @@ corec57d_init(struct nv50_core *core)
{
const u32 windows = 8; /*XXX*/
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_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_mthd(push, 0x1004 + (i * 0x080), 2);
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);
core->assign_windows = true;
}
}
......@@ -50,6 +48,7 @@ corec57d = {
.ntfy_init = corec37d_ntfy_init,
.ntfy_wait_done = corec37d_ntfy_wait_done,
.update = corec37d_update,
.wndw.owner = corec37d_wndw_owner,
.head = &headc57d,
.sor = &sorc37d,
};
......
......@@ -1933,6 +1933,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev);
struct nv50_atom *atom = nv50_atom(state);
struct nv50_core *core = disp->core;
struct nv50_outp_atom *outp, *outt;
u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {};
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). */
for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
......
......@@ -155,6 +155,12 @@ gv100_disp_intr_ctrl_disp(struct nv50_disp *disp)
if (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) {
unsigned long wndws = nvkm_rd32(device, 0x611858);
unsigned long other = nvkm_rd32(device, 0x61185c);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment