Karol Herbst
2020-Apr-28 16:54 UTC
[Nouveau] [PATCH v3 1/3] device: rework mmio mapping code to get rid of second map
Fixes warnings on GPUs with smaller a smaller mmio region like vGPUs.
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
drm/nouveau/nvkm/engine/device/base.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/drm/nouveau/nvkm/engine/device/base.c
b/drm/nouveau/nvkm/engine/device/base.c
index 8ebbe1656..37589f365 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -2935,7 +2935,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;
+ void __iomem *map = NULL;
int ret = -EEXIST, i;
unsigned chipset;
@@ -2961,12 +2961,17 @@ 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) {
+ map = ioremap(mmio_base, mmio_size);
+ if (map == 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) {
@@ -2980,7 +2985,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
/* read boot0 and strapping information */
boot0 = ioread32_native(map + 0x000000);
strap = ioread32_native(map + 0x101000);
- iounmap(map);
/* chipset can be overridden for devel/testing purposes */
chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0);
@@ -3159,12 +3163,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
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;
- }
+ device->pri = map;
}
mutex_init(&device->mutex);
@@ -3254,6 +3253,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
ret = 0;
done:
+ if (map && (!mmio || ret)) {
+ device->pri = NULL;
+ iounmap(map);
+ }
mutex_unlock(&nv_devices_mutex);
return ret;
}
--
2.25.3
Karol Herbst
2020-Apr-28 16:54 UTC
[Nouveau] [PATCH v3 2/3] device: detect if changing endianness failed
v2: relax the checks a little
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
drm/nouveau/nvkm/engine/device/base.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/drm/nouveau/nvkm/engine/device/base.c
b/drm/nouveau/nvkm/engine/device/base.c
index 37589f365..c732074bf 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -2924,6 +2924,20 @@ nvkm_device_del(struct nvkm_device **pdevice)
}
}
+static inline bool
+nvkm_device_endianness(void __iomem *pri)
+{
+ u32 boot1 = ioread32_native(pri + 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,
@@ -2973,13 +2987,15 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
/* 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
+ if (!nvkm_device_endianness(map)) {
iowrite32_native(0x01000001, map + 0x000004);
ioread32_native(map);
+ if (!nvkm_device_endianness(map)) {
+ nvdev_error(device,
+ "GPU not supported on big-endian\n");
+ ret = -ENOSYS;
+ goto done;
+ }
}
/* read boot0 and strapping information */
--
2.25.3
Using ENODEV as this prevents probe failed errors in dmesg.
v2: move check further down
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
drm/nouveau/nvkm/engine/device/base.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drm/nouveau/nvkm/engine/device/base.c
b/drm/nouveau/nvkm/engine/device/base.c
index c732074bf..f977dddcd 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -2948,7 +2948,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
{
struct nvkm_subdev *subdev;
u64 mmio_base, mmio_size;
- u32 boot0, strap;
+ u32 boot0, boot1, strap;
void __iomem *map = NULL;
int ret = -EEXIST, i;
unsigned chipset;
@@ -2998,9 +2998,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
}
}
- /* read boot0 and strapping information */
boot0 = ioread32_native(map + 0x000000);
- strap = ioread32_native(map + 0x101000);
/* chipset can be overridden for devel/testing purposes */
chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0);
@@ -3158,6 +3156,17 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
nvdev_info(device, "NVIDIA %s (%08x)\n",
device->chip->name, boot0);
+ /* vGPU detection */
+ boot1 = ioread32_native(map + 0x000004);
+ if (device->card_type >= TU100 && (boot1 & 0x00030000)) {
+ nvdev_info(device, "vGPUs are not supported\n");
+ ret = -ENODEV;
+ goto done;
+ }
+
+ /* read strapping information */
+ strap = ioread32_native(map + 0x101000);
+
/* determine frequency of timing crystal */
if ( device->card_type <= NV_10 || device->chipset < 0x17 ||
(device->chipset >= 0x20 && device->chipset < 0x25))
--
2.25.3
Ben Skeggs
2020-Apr-30 04:10 UTC
[Nouveau] [PATCH v3 1/3] device: rework mmio mapping code to get rid of second map
Merged all 3 patches. Thanks! On Wed, 29 Apr 2020 at 02:55, Karol Herbst <kherbst at redhat.com> wrote:> > Fixes warnings on GPUs with smaller a smaller mmio region like vGPUs. > > Signed-off-by: Karol Herbst <kherbst at redhat.com> > --- > drm/nouveau/nvkm/engine/device/base.c | 27 +++++++++++++++------------ > 1 file changed, 15 insertions(+), 12 deletions(-) > > diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c > index 8ebbe1656..37589f365 100644 > --- a/drm/nouveau/nvkm/engine/device/base.c > +++ b/drm/nouveau/nvkm/engine/device/base.c > @@ -2935,7 +2935,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; > + void __iomem *map = NULL; > int ret = -EEXIST, i; > unsigned chipset; > > @@ -2961,12 +2961,17 @@ 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) { > + map = ioremap(mmio_base, mmio_size); > + if (map == 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) { > @@ -2980,7 +2985,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func, > /* read boot0 and strapping information */ > boot0 = ioread32_native(map + 0x000000); > strap = ioread32_native(map + 0x101000); > - iounmap(map); > > /* chipset can be overridden for devel/testing purposes */ > chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); > @@ -3159,12 +3163,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, > 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; > - } > + device->pri = map; > } > > mutex_init(&device->mutex); > @@ -3254,6 +3253,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, > > ret = 0; > done: > + if (map && (!mmio || ret)) { > + device->pri = NULL; > + iounmap(map); > + } > mutex_unlock(&nv_devices_mutex); > return ret; > } > -- > 2.25.3 > > _______________________________________________ > Nouveau mailing list > Nouveau at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/nouveau
Apparently Analagous Threads
- [PATCH v3 1/3] device: rework mmio mapping code to get rid of second map
- [PATCH] drm/nouveau/device: fix changing endianess code to work on older GPUs
- [PATCH] drm/nouveau/device: fix changing endianess code to work on older GPUs
- [PATCH 1/3] device: use the correct mmio size when mapping
- [PATCH v2 1/3] device: use the correct mmio size when mapping