Commit 49b2dfc0 authored by Ben Skeggs's avatar Ben Skeggs Committed by Maarten Lankhorst
Browse files

drm/nouveau/ga102-: support ttm buffer moves via copy engine



We don't currently have any kind of real acceleration on Ampere GPUs,
but the TTM memcpy() fallback paths aren't really designed to handle
copies between different devices, such as on Optimus systems, and
result in a kernel OOPS.

A few options were investigated to try and fix this, but didn't work
out, and likely would have resulted in a very unpleasant experience
for users anyway.

This commit adds just enough support for setting up a single channel
connected to a copy engine, which the kernel can use to accelerate
the buffer copies between devices.  Userspace has no access to this
incomplete channel support, but it's suitable for TTM's needs.

A more complete implementation of host(fifo) for Ampere GPUs is in
the works, but the required changes are far too invasive that they
would be unsuitable to backport to fix this issue on current kernels.

v2: fix GPFIFO length in RAMFC (reported by Karol)

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Cc: Lyude Paul <lyude@redhat.com>
Cc: Karol Herbst <kherbst@redhat.com>
Cc: <stable@vger.kernel.org> # v5.12+
Reviewed-by: default avatarKarol Herbst <kherbst@redhat.com>
Tested-by: default avatarKarol Herbst <kherbst@redhat.com>
Signed-off-by: default avatarKarol Herbst <kherbst@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210916220406.666454-1-skeggsb@gmail.com


Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
parent f732e2e3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@
#define PASCAL_CHANNEL_GPFIFO_A                       /* cla06f.h */ 0x0000c06f
#define VOLTA_CHANNEL_GPFIFO_A                        /* clc36f.h */ 0x0000c36f
#define TURING_CHANNEL_GPFIFO_A                       /* clc36f.h */ 0x0000c46f
#define AMPERE_CHANNEL_GPFIFO_B                       /* clc36f.h */ 0x0000c76f

#define NV50_DISP                                     /* cl5070.h */ 0x00005070
#define G82_DISP                                      /* cl5070.h */ 0x00008270
@@ -200,6 +201,7 @@
#define PASCAL_DMA_COPY_B                                            0x0000c1b5
#define VOLTA_DMA_COPY_A                                             0x0000c3b5
#define TURING_DMA_COPY_A                                            0x0000c5b5
#define AMPERE_DMA_COPY_B                                            0x0000c7b5

#define FERMI_DECOMPRESS                                             0x000090b8

+1 −0
Original line number Diff line number Diff line
@@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
#endif
+1 −0
Original line number Diff line number Diff line
@@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
			    struct ttm_resource *, struct ttm_resource *);
		int (*init)(struct nouveau_channel *, u32 handle);
	} _methods[] = {
		{  "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init },
		{  "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },
		{  "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init },
		{  "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init },
+4 −2
Original line number Diff line number Diff line
@@ -250,7 +250,8 @@ static int
nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
		    u64 runlist, bool priv, struct nouveau_channel **pchan)
{
	static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A,
	static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B,
					TURING_CHANNEL_GPFIFO_A,
					VOLTA_CHANNEL_GPFIFO_A,
					PASCAL_CHANNEL_GPFIFO_A,
					MAXWELL_CHANNEL_GPFIFO_A,
@@ -386,7 +387,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)

	nvif_object_map(&chan->user, NULL, 0);

	if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
	if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO &&
	    chan->user.oclass < AMPERE_CHANNEL_GPFIFO_B) {
		ret = nvif_notify_ctor(&chan->user, "abi16ChanKilled",
				       nouveau_channel_killed,
				       true, NV906F_V0_NTFY_KILLED,
+4 −0
Original line number Diff line number Diff line
@@ -345,6 +345,9 @@ nouveau_accel_gr_init(struct nouveau_drm *drm)
	u32 arg0, arg1;
	int ret;

	if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
		return;

	/* Allocate channel that has access to the graphics engine. */
	if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
		arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
@@ -469,6 +472,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
		case PASCAL_CHANNEL_GPFIFO_A:
		case VOLTA_CHANNEL_GPFIFO_A:
		case TURING_CHANNEL_GPFIFO_A:
		case AMPERE_CHANNEL_GPFIFO_B:
			ret = nvc0_fence_create(drm);
			break;
		default:
Loading