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:
commit
a345cc0d39
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue