Commit a345cc0d authored by Dave Airlie's avatar Dave Airlie
Browse files

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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 **);
+18 −5
Original line number Diff line number Diff line
@@ -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,
};
+4 −5
Original line number Diff line number Diff line
@@ -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,
};
+16 −0
Original line number Diff line number Diff line
@@ -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);
+6 −0
Original line number Diff line number Diff line
@@ -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);