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 {
|
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 **);
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue