Commit 76b8f81a authored by Ben Skeggs's avatar Ben Skeggs Committed by Dave Airlie
Browse files

drm/nouveau: improve handling of 64-bit BARs



GPUs exist now with a 64-bit BAR0, which mean that BAR1 and BAR2's
indices (as passed to pci_resource_len() etc) are bumped up by one.

Modify nvkm_device.resource_addr/size() to take an enum instead of
an integer bar index, and take IORESOURCE_MEM_64 into account when
translating to the "raw" bar id.

[airlied: fixup ERR_PTR]
Signed-off-by: default avatarBen Skeggs <bskeggs@nvidia.com>
Reviewed-by: default avatarDave Airlie <airlied@redhat.com>
Reviewed-by: default avatarTimur Tabi <ttabi@nvidia.com>
Tested-by: default avatarTimur Tabi <ttabi@nvidia.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent b1ca3847
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -77,6 +77,13 @@ struct nvkm_device {
struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst);
struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst);

enum nvkm_bar_id {
	NVKM_BAR_INVALID = 0,
	NVKM_BAR0_PRI,
	NVKM_BAR1_FB,
	NVKM_BAR2_INST,
};

struct nvkm_device_func {
	struct nvkm_device_pci *(*pci)(struct nvkm_device *);
	struct nvkm_device_tegra *(*tegra)(struct nvkm_device *);
@@ -85,8 +92,8 @@ struct nvkm_device_func {
	int (*init)(struct nvkm_device *);
	void (*fini)(struct nvkm_device *, bool suspend);
	int (*irq)(struct nvkm_device *);
	resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar);
	resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar);
	resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id);
	resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id);
	bool cpu_coherent;
};

+1 −1
Original line number Diff line number Diff line
@@ -315,7 +315,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
		break;
	}
	case NOUVEAU_GETPARAM_VRAM_BAR_SIZE:
		getparam->value = nvkm_device->func->resource_size(nvkm_device, 1);
		getparam->value = nvkm_device->func->resource_size(nvkm_device, NVKM_BAR1_FB);
		break;
	case NOUVEAU_GETPARAM_VRAM_USED: {
		struct ttm_resource_manager *vram_mgr = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM);
+2 −2
Original line number Diff line number Diff line
@@ -1204,7 +1204,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *reg)
		fallthrough;	/* tiled memory */
	case TTM_PL_VRAM:
		reg->bus.offset = (reg->start << PAGE_SHIFT) +
			device->func->resource_addr(device, 1);
			device->func->resource_addr(device, NVKM_BAR1_FB);
		reg->bus.is_iomem = true;

		/* Some BARs do not support being ioremapped WC */
@@ -1295,7 +1295,7 @@ vm_fault_t nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
	struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
	struct nouveau_bo *nvbo = nouveau_bo(bo);
	struct nvkm_device *device = nvxx_device(drm);
	u32 mappable = device->func->resource_size(device, 1) >> PAGE_SHIFT;
	u32 mappable = device->func->resource_size(device, NVKM_BAR1_FB) >> PAGE_SHIFT;
	int i, ret;

	/* as long as the bo isn't in vram, and isn't tiled, we've got
+3 −1
Original line number Diff line number Diff line
@@ -209,13 +209,15 @@ nouveau_channel_prep(struct nouveau_cli *cli,
	} else
	if (chan->push.buffer->bo.resource->mem_type == TTM_PL_VRAM) {
		if (device->info.family == NV_DEVICE_INFO_V0_TNT) {
			struct nvkm_device *nvkm_device = nvxx_device(drm);

			/* nv04 vram pushbuf hack, retarget to its location in
			 * the framebuffer bar rather than direct vram access..
			 * nfi why this exists, it came from the -nv ddx.
			 */
			args.target = NV_DMA_V0_TARGET_PCI;
			args.access = NV_DMA_V0_ACCESS_RDWR;
			args.start = nvxx_device(drm)->func->resource_addr(nvxx_device(drm), 1);
			args.start = nvkm_device->func->resource_addr(nvkm_device, NVKM_BAR1_FB);
			args.limit = args.start + device->info.ram_user - 1;
		} else {
			args.target = NV_DMA_V0_TARGET_VRAM;
+6 −6
Original line number Diff line number Diff line
@@ -312,8 +312,8 @@ nouveau_ttm_init(struct nouveau_drm *drm)
	/* VRAM init */
	drm->gem.vram_available = drm->client.device.info.ram_user;

	arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1),
				   device->func->resource_size(device, 1));
	arch_io_reserve_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB),
				   device->func->resource_size(device, NVKM_BAR1_FB));

	ret = nouveau_ttm_init_vram(drm);
	if (ret) {
@@ -321,8 +321,8 @@ nouveau_ttm_init(struct nouveau_drm *drm)
		return ret;
	}

	drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, 1),
					 device->func->resource_size(device, 1));
	drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, NVKM_BAR1_FB),
					 device->func->resource_size(device, NVKM_BAR1_FB));

	/* GART init */
	if (!drm->agp.bridge) {
@@ -357,7 +357,7 @@ nouveau_ttm_fini(struct nouveau_drm *drm)

	arch_phys_wc_del(drm->ttm.mtrr);
	drm->ttm.mtrr = 0;
	arch_io_free_memtype_wc(device->func->resource_addr(device, 1),
				device->func->resource_size(device, 1));
	arch_io_free_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB),
				device->func->resource_size(device, NVKM_BAR1_FB));

}
Loading