mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-09 02:51:20 +00:00
drm/nouveau: use alternate memory type for system-memory buffers with kind != 0
Fixes bug on Tegra where we'd strip kind information from system memory
(ie. all) buffers, resulting in misrendering.
Behaviour on dGPU should be unchanged.
Reported-by: Thierry Reding <treding@nvidia.com>
Fixes: d7722134b8
("drm/nouveau: switch over to new memory and vmm interfaces")
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Tested-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
f29f18eb95
commit
74a39954a4
@ -224,7 +224,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align,
|
|||||||
/* Determine if we can get a cache-coherent map, forcing
|
/* Determine if we can get a cache-coherent map, forcing
|
||||||
* uncached mapping if we can't.
|
* uncached mapping if we can't.
|
||||||
*/
|
*/
|
||||||
if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED)
|
if (!nouveau_drm_use_coherent_gpu_mapping(drm))
|
||||||
nvbo->force_coherent = true;
|
nvbo->force_coherent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,8 +156,8 @@ struct nouveau_drm {
|
|||||||
struct nvif_object copy;
|
struct nvif_object copy;
|
||||||
int mtrr;
|
int mtrr;
|
||||||
int type_vram;
|
int type_vram;
|
||||||
int type_host;
|
int type_host[2];
|
||||||
int type_ncoh;
|
int type_ncoh[2];
|
||||||
} ttm;
|
} ttm;
|
||||||
|
|
||||||
/* GEM interface support */
|
/* GEM interface support */
|
||||||
@ -216,6 +216,13 @@ nouveau_drm(struct drm_device *dev)
|
|||||||
return dev->dev_private;
|
return dev->dev_private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm)
|
||||||
|
{
|
||||||
|
struct nvif_mmu *mmu = &drm->client.mmu;
|
||||||
|
return !(mmu->type[drm->ttm.type_host[0]].type & NVIF_MEM_UNCACHED);
|
||||||
|
}
|
||||||
|
|
||||||
int nouveau_pmops_suspend(struct device *);
|
int nouveau_pmops_suspend(struct device *);
|
||||||
int nouveau_pmops_resume(struct device *);
|
int nouveau_pmops_resume(struct device *);
|
||||||
bool nouveau_pmops_runtime(void);
|
bool nouveau_pmops_runtime(void);
|
||||||
|
@ -103,10 +103,10 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt)
|
|||||||
u8 type;
|
u8 type;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED)
|
if (!nouveau_drm_use_coherent_gpu_mapping(drm))
|
||||||
type = drm->ttm.type_ncoh;
|
type = drm->ttm.type_ncoh[!!mem->kind];
|
||||||
else
|
else
|
||||||
type = drm->ttm.type_host;
|
type = drm->ttm.type_host[0];
|
||||||
|
|
||||||
if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND))
|
if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND))
|
||||||
mem->comp = mem->kind = 0;
|
mem->comp = mem->kind = 0;
|
||||||
|
@ -235,6 +235,27 @@ nouveau_ttm_global_release(struct nouveau_drm *drm)
|
|||||||
drm->ttm.mem_global_ref.release = NULL;
|
drm->ttm.mem_global_ref.release = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind)
|
||||||
|
{
|
||||||
|
struct nvif_mmu *mmu = &drm->client.mmu;
|
||||||
|
int typei;
|
||||||
|
|
||||||
|
typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE |
|
||||||
|
kind | NVIF_MEM_COHERENT);
|
||||||
|
if (typei < 0)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
drm->ttm.type_host[!!kind] = typei;
|
||||||
|
|
||||||
|
typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | kind);
|
||||||
|
if (typei < 0)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
drm->ttm.type_ncoh[!!kind] = typei;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nouveau_ttm_init(struct nouveau_drm *drm)
|
nouveau_ttm_init(struct nouveau_drm *drm)
|
||||||
{
|
{
|
||||||
@ -244,18 +265,16 @@ nouveau_ttm_init(struct nouveau_drm *drm)
|
|||||||
struct drm_device *dev = drm->dev;
|
struct drm_device *dev = drm->dev;
|
||||||
int typei, ret;
|
int typei, ret;
|
||||||
|
|
||||||
typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE |
|
ret = nouveau_ttm_init_host(drm, 0);
|
||||||
NVIF_MEM_COHERENT);
|
if (ret)
|
||||||
if (typei < 0)
|
return ret;
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
drm->ttm.type_host = typei;
|
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA &&
|
||||||
|
drm->client.device.info.chipset != 0x50) {
|
||||||
typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE);
|
ret = nouveau_ttm_init_host(drm, NVIF_MEM_KIND);
|
||||||
if (typei < 0)
|
if (ret)
|
||||||
return -ENOSYS;
|
return ret;
|
||||||
|
}
|
||||||
drm->ttm.type_ncoh = typei;
|
|
||||||
|
|
||||||
if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC &&
|
if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC &&
|
||||||
drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
|
drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
|
||||||
|
Loading…
Reference in New Issue
Block a user