提交 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) ...@@ -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_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
#define NV_MEM_ACCESS_SYS 4 #define NV_MEM_ACCESS_SYS 4
#define NV_MEM_ACCESS_VM 8 #define NV_MEM_ACCESS_VM 8
#define NV_MEM_ACCESS_NOSNOOP 16
#define NV_MEM_TARGET_VRAM 0 #define NV_MEM_TARGET_VRAM 0
#define NV_MEM_TARGET_PCI 1 #define NV_MEM_TARGET_PCI 1
......
...@@ -57,27 +57,15 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, ...@@ -57,27 +57,15 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
} }
static inline u64 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 |= 1; /* present */
phys |= (u64)memtype << 40; 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; phys |= target << 4;
if (vma->access & NV_MEM_ACCESS_SYS) if (vma->access & NV_MEM_ACCESS_SYS)
phys |= (1 << 6); phys |= (1 << 6);
if (!(vma->access & NV_MEM_ACCESS_WO)) if (!(vma->access & NV_MEM_ACCESS_WO))
phys |= (1 << 3); phys |= (1 << 3);
return phys; return phys;
} }
...@@ -85,11 +73,19 @@ void ...@@ -85,11 +73,19 @@ void
nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) 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 comp = (mem->memtype & 0x180) >> 7;
u32 block; u32 block, target;
int i; 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; pte <<= 3;
cnt <<= 3; cnt <<= 3;
...@@ -125,9 +121,10 @@ void ...@@ -125,9 +121,10 @@ void
nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{ {
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2;
pte <<= 3; pte <<= 3;
while (cnt--) { 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 + 0, lower_32_bits(phys));
nv_wo32(pgt, pte + 4, upper_32_bits(phys)); nv_wo32(pgt, pte + 4, upper_32_bits(phys));
pte += 8; pte += 8;
......
...@@ -77,9 +77,11 @@ void ...@@ -77,9 +77,11 @@ void
nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{ {
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
pte <<= 3; pte <<= 3;
while (cnt--) { 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 + 0, lower_32_bits(phys));
nv_wo32(pgt, pte + 4, upper_32_bits(phys)); nv_wo32(pgt, pte + 4, upper_32_bits(phys));
pte += 8; pte += 8;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册