Skip to content

Commit 76b8f81

Browse files
Ben Skeggsairlied
authored andcommitted
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: Ben Skeggs <[email protected]> Reviewed-by: Dave Airlie <[email protected]> Reviewed-by: Timur Tabi <[email protected]> Tested-by: Timur Tabi <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent b1ca384 commit 76b8f81

File tree

36 files changed

+109
-73
lines changed

36 files changed

+109
-73
lines changed

drivers/gpu/drm/nouveau/include/nvkm/core/device.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ struct nvkm_device {
7777
struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst);
7878
struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst);
7979

80+
enum nvkm_bar_id {
81+
NVKM_BAR_INVALID = 0,
82+
NVKM_BAR0_PRI,
83+
NVKM_BAR1_FB,
84+
NVKM_BAR2_INST,
85+
};
86+
8087
struct nvkm_device_func {
8188
struct nvkm_device_pci *(*pci)(struct nvkm_device *);
8289
struct nvkm_device_tegra *(*tegra)(struct nvkm_device *);
@@ -85,8 +92,8 @@ struct nvkm_device_func {
8592
int (*init)(struct nvkm_device *);
8693
void (*fini)(struct nvkm_device *, bool suspend);
8794
int (*irq)(struct nvkm_device *);
88-
resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar);
89-
resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar);
95+
resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id);
96+
resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id);
9097
bool cpu_coherent;
9198
};
9299

drivers/gpu/drm/nouveau/nouveau_abi16.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
315315
break;
316316
}
317317
case NOUVEAU_GETPARAM_VRAM_BAR_SIZE:
318-
getparam->value = nvkm_device->func->resource_size(nvkm_device, 1);
318+
getparam->value = nvkm_device->func->resource_size(nvkm_device, NVKM_BAR1_FB);
319319
break;
320320
case NOUVEAU_GETPARAM_VRAM_USED: {
321321
struct ttm_resource_manager *vram_mgr = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM);

drivers/gpu/drm/nouveau/nouveau_bo.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *reg)
12041204
fallthrough; /* tiled memory */
12051205
case TTM_PL_VRAM:
12061206
reg->bus.offset = (reg->start << PAGE_SHIFT) +
1207-
device->func->resource_addr(device, 1);
1207+
device->func->resource_addr(device, NVKM_BAR1_FB);
12081208
reg->bus.is_iomem = true;
12091209

12101210
/* 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)
12951295
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
12961296
struct nouveau_bo *nvbo = nouveau_bo(bo);
12971297
struct nvkm_device *device = nvxx_device(drm);
1298-
u32 mappable = device->func->resource_size(device, 1) >> PAGE_SHIFT;
1298+
u32 mappable = device->func->resource_size(device, NVKM_BAR1_FB) >> PAGE_SHIFT;
12991299
int i, ret;
13001300

13011301
/* as long as the bo isn't in vram, and isn't tiled, we've got

drivers/gpu/drm/nouveau/nouveau_chan.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,15 @@ nouveau_channel_prep(struct nouveau_cli *cli,
209209
} else
210210
if (chan->push.buffer->bo.resource->mem_type == TTM_PL_VRAM) {
211211
if (device->info.family == NV_DEVICE_INFO_V0_TNT) {
212+
struct nvkm_device *nvkm_device = nvxx_device(drm);
213+
212214
/* nv04 vram pushbuf hack, retarget to its location in
213215
* the framebuffer bar rather than direct vram access..
214216
* nfi why this exists, it came from the -nv ddx.
215217
*/
216218
args.target = NV_DMA_V0_TARGET_PCI;
217219
args.access = NV_DMA_V0_ACCESS_RDWR;
218-
args.start = nvxx_device(drm)->func->resource_addr(nvxx_device(drm), 1);
220+
args.start = nvkm_device->func->resource_addr(nvkm_device, NVKM_BAR1_FB);
219221
args.limit = args.start + device->info.ram_user - 1;
220222
} else {
221223
args.target = NV_DMA_V0_TARGET_VRAM;

drivers/gpu/drm/nouveau/nouveau_ttm.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,17 +312,17 @@ nouveau_ttm_init(struct nouveau_drm *drm)
312312
/* VRAM init */
313313
drm->gem.vram_available = drm->client.device.info.ram_user;
314314

315-
arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1),
316-
device->func->resource_size(device, 1));
315+
arch_io_reserve_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB),
316+
device->func->resource_size(device, NVKM_BAR1_FB));
317317

318318
ret = nouveau_ttm_init_vram(drm);
319319
if (ret) {
320320
NV_ERROR(drm, "VRAM mm init failed, %d\n", ret);
321321
return ret;
322322
}
323323

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

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

358358
arch_phys_wc_del(drm->ttm.mtrr);
359359
drm->ttm.mtrr = 0;
360-
arch_io_free_memtype_wc(device->func->resource_addr(device, 1),
361-
device->func->resource_size(device, 1));
360+
arch_io_free_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB),
361+
device->func->resource_size(device, NVKM_BAR1_FB));
362362

363363
}

drivers/gpu/drm/nouveau/nvkm/engine/device/base.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3027,8 +3027,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
30273027
device->debug = nvkm_dbgopt(device->dbgopt, "device");
30283028
INIT_LIST_HEAD(&device->subdev);
30293029

3030-
mmio_base = device->func->resource_addr(device, 0);
3031-
mmio_size = device->func->resource_size(device, 0);
3030+
mmio_base = device->func->resource_addr(device, NVKM_BAR0_PRI);
3031+
mmio_size = device->func->resource_size(device, NVKM_BAR0_PRI);
30323032

30333033
device->pri = ioremap(mmio_base, mmio_size);
30343034
if (device->pri == NULL) {

drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,18 +1560,42 @@ nvkm_device_pci(struct nvkm_device *device)
15601560
return container_of(device, struct nvkm_device_pci, device);
15611561
}
15621562

1563+
static int
1564+
nvkm_device_pci_resource_idx(struct nvkm_device_pci *pdev, enum nvkm_bar_id bar)
1565+
{
1566+
int idx = 0;
1567+
1568+
if (bar == NVKM_BAR0_PRI)
1569+
return idx;
1570+
1571+
idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1;
1572+
if (bar == NVKM_BAR1_FB)
1573+
return idx;
1574+
1575+
idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1;
1576+
if (bar == NVKM_BAR2_INST)
1577+
return idx;
1578+
1579+
WARN_ON(1);
1580+
return -1;
1581+
}
1582+
15631583
static resource_size_t
1564-
nvkm_device_pci_resource_addr(struct nvkm_device *device, unsigned bar)
1584+
nvkm_device_pci_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar)
15651585
{
15661586
struct nvkm_device_pci *pdev = nvkm_device_pci(device);
1567-
return pci_resource_start(pdev->pdev, bar);
1587+
int idx = nvkm_device_pci_resource_idx(pdev, bar);
1588+
1589+
return idx >= 0 ? pci_resource_start(pdev->pdev, idx) : 0;
15681590
}
15691591

15701592
static resource_size_t
1571-
nvkm_device_pci_resource_size(struct nvkm_device *device, unsigned bar)
1593+
nvkm_device_pci_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar)
15721594
{
15731595
struct nvkm_device_pci *pdev = nvkm_device_pci(device);
1574-
return pci_resource_len(pdev->pdev, bar);
1596+
int idx = nvkm_device_pci_resource_idx(pdev, bar);
1597+
1598+
return idx >= 0 ? pci_resource_len(pdev->pdev, idx) : 0;
15751599
}
15761600

15771601
static int

drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,21 +186,31 @@ nvkm_device_tegra(struct nvkm_device *device)
186186
}
187187

188188
static struct resource *
189-
nvkm_device_tegra_resource(struct nvkm_device *device, unsigned bar)
189+
nvkm_device_tegra_resource(struct nvkm_device *device, enum nvkm_bar_id bar)
190190
{
191191
struct nvkm_device_tegra *tdev = nvkm_device_tegra(device);
192-
return platform_get_resource(tdev->pdev, IORESOURCE_MEM, bar);
192+
int idx;
193+
194+
switch (bar) {
195+
case NVKM_BAR0_PRI: idx = 0; break;
196+
case NVKM_BAR1_FB : idx = 1; break;
197+
default:
198+
WARN_ON(1);
199+
return ERR_PTR(-EINVAL);
200+
}
201+
202+
return platform_get_resource(tdev->pdev, IORESOURCE_MEM, idx);
193203
}
194204

195205
static resource_size_t
196-
nvkm_device_tegra_resource_addr(struct nvkm_device *device, unsigned bar)
206+
nvkm_device_tegra_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar)
197207
{
198208
struct resource *res = nvkm_device_tegra_resource(device, bar);
199209
return res ? res->start : 0;
200210
}
201211

202212
static resource_size_t
203-
nvkm_device_tegra_resource_size(struct nvkm_device *device, unsigned bar)
213+
nvkm_device_tegra_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar)
204214
{
205215
struct resource *res = nvkm_device_tegra_resource(device, bar);
206216
return res ? resource_size(res) : 0;

drivers/gpu/drm/nouveau/nvkm/engine/device/user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc,
209209
struct nvkm_udevice *udev = nvkm_udevice(object);
210210
struct nvkm_device *device = udev->device;
211211
*type = NVKM_OBJECT_MAP_IO;
212-
*addr = device->func->resource_addr(device, 0);
213-
*size = device->func->resource_size(device, 0);
212+
*addr = device->func->resource_addr(device, NVKM_BAR0_PRI);
213+
*size = device->func->resource_size(device, NVKM_BAR0_PRI);
214214
return 0;
215215
}
216216

drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ nvkm_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc,
4949
{
5050
struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
5151
struct nvkm_device *device = chan->disp->engine.subdev.device;
52-
const u64 base = device->func->resource_addr(device, 0);
52+
const u64 base = device->func->resource_addr(device, NVKM_BAR0_PRI);
5353

5454
*type = NVKM_OBJECT_MAP_IO;
5555
*addr = base + chan->func->user(chan, size);

0 commit comments

Comments
 (0)