提交 990449c7 编写于 作者: B Ben Skeggs

drm/nv50-nvc0/vm: support unsnooped system memory

v2 (Emil Velikov <emil.l.velikov@gmail.com>):
- Fixed a regression on certain nv50 IGP due to not passing the correct
  target type to nv50_vm_addr()
Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
Signed-off-by: NEmil Velikov <emil.l.velikov@gmail.com>
Tested-by: NJohannes Obermayr <johannesobermayr@gmx.de>
上级 4abb410a
......@@ -1759,6 +1759,7 @@ nv44_graph_class(struct drm_device *dev)
#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
#define NV_MEM_ACCESS_SYS 4
#define NV_MEM_ACCESS_VM 8
#define NV_MEM_ACCESS_NOSNOOP 16
#define NV_MEM_TARGET_VRAM 0
#define NV_MEM_TARGET_PCI 1
......
......@@ -57,27 +57,15 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
}
static inline u64
nv50_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
{
struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private;
phys |= 1; /* present */
phys |= (u64)memtype << 40;
/* IGPs don't have real VRAM, re-target to stolen system memory */
if (target == 0 && dev_priv->vram_sys_base) {
phys += dev_priv->vram_sys_base;
target = 3;
}
phys |= target << 4;
if (vma->access & NV_MEM_ACCESS_SYS)
phys |= (1 << 6);
if (!(vma->access & NV_MEM_ACCESS_WO))
phys |= (1 << 3);
return phys;
}
......@@ -85,11 +73,19 @@ void
nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
{
struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private;
u32 comp = (mem->memtype & 0x180) >> 7;
u32 block;
u32 block, target;
int i;
phys = nv50_vm_addr(vma, phys, mem->memtype, 0);
/* IGPs don't have real VRAM, re-target to stolen system memory */
target = 0;
if (dev_priv->vram_sys_base) {
phys += dev_priv->vram_sys_base;
target = 3;
}
phys = vm_addr(vma, phys, mem->memtype, target);
pte <<= 3;
cnt <<= 3;
......@@ -125,9 +121,10 @@ void
nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2;
pte <<= 3;
while (cnt--) {
u64 phys = nv50_vm_addr(vma, (u64)*list++, mem->memtype, 2);
u64 phys = vm_addr(vma, (u64)*list++, mem->memtype, target);
nv_wo32(pgt, pte + 0, lower_32_bits(phys));
nv_wo32(pgt, pte + 4, upper_32_bits(phys));
pte += 8;
......
......@@ -77,9 +77,11 @@ void
nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
pte <<= 3;
while (cnt--) {
u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, 5);
u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, target);
nv_wo32(pgt, pte + 0, lower_32_bits(phys));
nv_wo32(pgt, pte + 4, upper_32_bits(phys));
pte += 8;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册