Commit d00ddd9d authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/kms/nv50-: allocate push buffers in vidmem on pascal

Workaround for issues seen on systems with large amounts of RAM, caused
by display not supporting the same physical address limits as the other
parts of the GPU.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent b59fb482
...@@ -136,12 +136,24 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, ...@@ -136,12 +136,24 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
{ {
struct nouveau_cli *cli = (void *)device->object.client; struct nouveau_cli *cli = (void *)device->object.client;
struct nv50_disp_core_channel_dma_v0 *args = data; struct nv50_disp_core_channel_dma_v0 *args = data;
u8 type = NVIF_MEM_COHERENT;
int ret; int ret;
mutex_init(&dmac->lock); mutex_init(&dmac->lock);
ret = nvif_mem_init_map(&cli->mmu, NVIF_MEM_COHERENT, 0x1000, /* Pascal added support for 47-bit physical addresses, but some
&dmac->push); * parts of EVO still only accept 40-bit PAs.
*
* To avoid issues on systems with large amounts of RAM, and on
* systems where an IOMMU maps pages at a high address, we need
* to allocate push buffers in VRAM instead.
*
* This appears to match NVIDIA's behaviour on Pascal.
*/
if (device->info.family == NV_DEVICE_INFO_V0_PASCAL)
type |= NVIF_MEM_VRAM;
ret = nvif_mem_init_map(&cli->mmu, type, 0x1000, &dmac->push);
if (ret) if (ret)
return ret; return ret;
...@@ -216,6 +228,19 @@ void ...@@ -216,6 +228,19 @@ void
evo_kick(u32 *push, struct nv50_dmac *evoc) evo_kick(u32 *push, struct nv50_dmac *evoc)
{ {
struct nv50_dmac *dmac = evoc; struct nv50_dmac *dmac = evoc;
/* Push buffer fetches are not coherent with BAR1, we need to ensure
* writes have been flushed right through to VRAM before writing PUT.
*/
if (dmac->push.type & NVIF_MEM_VRAM) {
struct nvif_device *device = dmac->base.device;
nvif_wr32(&device->object, 0x070000, 0x00000001);
nvif_msec(device, 2000,
if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
break;
);
}
nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2);
mutex_unlock(&dmac->lock); mutex_unlock(&dmac->lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment