diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2020-06-11 15:17:57 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-06-11 15:17:57 +0200 |
commit | f77d26a9fc525286bcef3d4f98b52e17482cf49c (patch) | |
tree | 6b179c9aa84787773cb601a14a64255e2912154b /drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |
parent | b6bea24d41519e8c31e4798f1c1a3f67e540c5d0 (diff) | |
parent | f0178fc01fe46bab6a95415f5647d1a74efcad1b (diff) |
Merge branch 'x86/entry' into ras/core
to fixup conflicts in arch/x86/kernel/cpu/mce/core.c so MCE specific follow
up patches can be applied without creating a horrible merge conflict
afterwards.
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/device/base.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 8ebbe1656008..5b90c2a1bf3d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2924,6 +2924,20 @@ nvkm_device_del(struct nvkm_device **pdevice) } } +static inline bool +nvkm_device_endianness(struct nvkm_device *device) +{ + u32 boot1 = nvkm_rd32(device, 0x000004) & 0x01000001; +#ifdef __BIG_ENDIAN + if (!boot1) + return false; +#else + if (boot1) + return false; +#endif + return true; +} + int nvkm_device_ctor(const struct nvkm_device_func *func, const struct nvkm_device_quirk *quirk, @@ -2934,8 +2948,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, { struct nvkm_subdev *subdev; u64 mmio_base, mmio_size; - u32 boot0, strap; - void __iomem *map; + u32 boot0, boot1, strap; int ret = -EEXIST, i; unsigned chipset; @@ -2961,26 +2974,30 @@ nvkm_device_ctor(const struct nvkm_device_func *func, mmio_base = device->func->resource_addr(device, 0); mmio_size = device->func->resource_size(device, 0); - /* identify the chipset, and determine classes of subdev/engines */ - if (detect) { - map = ioremap(mmio_base, 0x102000); - if (ret = -ENOMEM, map == NULL) + if (detect || mmio) { + device->pri = ioremap(mmio_base, mmio_size); + if (device->pri == NULL) { + nvdev_error(device, "unable to map PRI\n"); + ret = -ENOMEM; goto done; + } + } + /* identify the chipset, and determine classes of subdev/engines */ + if (detect) { /* switch mmio to cpu's native endianness */ -#ifndef __BIG_ENDIAN - if (ioread32_native(map + 0x000004) != 0x00000000) { -#else - if (ioread32_native(map + 0x000004) == 0x00000000) { -#endif - iowrite32_native(0x01000001, map + 0x000004); - ioread32_native(map); + if (!nvkm_device_endianness(device)) { + nvkm_wr32(device, 0x000004, 0x01000001); + nvkm_rd32(device, 0x000000); + if (!nvkm_device_endianness(device)) { + nvdev_error(device, + "GPU not supported on big-endian\n"); + ret = -ENOSYS; + goto done; + } } - /* read boot0 and strapping information */ - boot0 = ioread32_native(map + 0x000000); - strap = ioread32_native(map + 0x101000); - iounmap(map); + boot0 = nvkm_rd32(device, 0x000000); /* chipset can be overridden for devel/testing purposes */ chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); @@ -3138,6 +3155,17 @@ nvkm_device_ctor(const struct nvkm_device_func *func, nvdev_info(device, "NVIDIA %s (%08x)\n", device->chip->name, boot0); + /* vGPU detection */ + boot1 = nvkm_rd32(device, 0x0000004); + if (device->card_type >= TU100 && (boot1 & 0x00030000)) { + nvdev_info(device, "vGPUs are not supported\n"); + ret = -ENODEV; + goto done; + } + + /* read strapping information */ + strap = nvkm_rd32(device, 0x101000); + /* determine frequency of timing crystal */ if ( device->card_type <= NV_10 || device->chipset < 0x17 || (device->chipset >= 0x20 && device->chipset < 0x25)) @@ -3158,15 +3186,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func, if (!device->name) device->name = device->chip->name; - if (mmio) { - device->pri = ioremap(mmio_base, mmio_size); - if (!device->pri) { - nvdev_error(device, "unable to map PRI\n"); - ret = -ENOMEM; - goto done; - } - } - mutex_init(&device->mutex); for (i = 0; i < NVKM_SUBDEV_NR; i++) { @@ -3254,6 +3273,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, ret = 0; done: + if (device->pri && (!mmio || ret)) { + iounmap(device->pri); + device->pri = NULL; + } mutex_unlock(&nv_devices_mutex); return ret; } |