On Tue, Oct 13, 2020 at 8:01 AM Karol Herbst <kher...@redhat.com> wrote: > > With this we try to detect if the endianess switch works and assume LE if > not. Suggested by Ben. > > Fixes: 51c05340e407 ("drm/nouveau/device: detect if changing endianness > failed") > --- > .../gpu/drm/nouveau/nvkm/engine/device/base.c | 39 ++++++++++++------- > 1 file changed, 26 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > index dcb70677d0acc..7851bec5f0e5f 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c > @@ -2924,17 +2924,34 @@ nvkm_device_del(struct nvkm_device **pdevice) > } > } > > +/* returns true if the GPU is in the CPU native byte order */ > static inline bool > nvkm_device_endianness(struct nvkm_device *device) > { > - u32 boot1 = nvkm_rd32(device, 0x000004) & 0x01000001; > #ifdef __BIG_ENDIAN > - if (!boot1) > - return false; > + const bool big_endian = true; > #else > - if (boot1) > - return false; > + const bool big_endian = false; > #endif > + > + /* Read NV_PMC_BOOT_1, and assume non-functional endian switch if it > + * doesn't contain the expected values. > + */ > + u32 pmc_boot_1 = nvkm_rd32(device, 0x000004); > + if (pmc_boot_1 && pmc_boot_1 != 0x01000001)
Are you sure there are no other bits in there, esp on newer GPUs? > + return !big_endian; /* Assume GPU is LE in this case. */ > + > + /* 0 means LE and 0x01000001 means BE GPU. Condition is true when > + * GPU/CPU endianness don't match. > + */ > + if (big_endian == !pmc_boot_1) { > + nvkm_wr32(device, 0x000004, 0x01000001); > + nvkm_rd32(device, 0x000000); > + if (nvkm_rd32(device, 0x000004) != (big_endian ? 0x01000001 : > 0x00000000)) > + return !big_endian; /* Assume GPU is LE on any > unexpected read-back. */ > + } > + > + /* CPU/GPU endianness should (hopefully) match. */ > return true; > } > > @@ -2987,14 +3004,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, > if (detect) { > /* switch mmio to cpu's native endianness */ > 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; > - } > + nvdev_error(device, > + "Couldn't switch GPU to CPUs > endianess\n"); > + ret = -ENOSYS; > + goto done; > } > > boot0 = nvkm_rd32(device, 0x000000); > -- > 2.26.2 > > _______________________________________________ > Nouveau mailing list > Nouveau@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/nouveau _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/nouveau