On Tue, Oct 13, 2020 at 3:55 PM Ilia Mirkin <imirkin@xxxxxxxxxxxx> wrote: > > On Tue, Oct 13, 2020 at 8:01 AM Karol Herbst <kherbst@xxxxxxxxxx> 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? > Fairly. Checked on GP107 today, which is nearly the last gen to even support it. I think it's gone with volta or turing. > > + 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@xxxxxxxxxxxxxxxxxxxxx > > https://lists.freedesktop.org/mailman/listinfo/nouveau > _______________________________________________ > Nouveau mailing list > Nouveau@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/nouveau > _______________________________________________ Nouveau mailing list Nouveau@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/nouveau