Skip to content

Commit

Permalink
drm/nv50: implement BAR1/BAR3 management on top of new VM code
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Dec 8, 2010
1 parent a11c319 commit f869ef8
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 153 deletions.
46 changes: 43 additions & 3 deletions drivers/gpu/drm/nouveau/nouveau_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "nouveau_drm.h"
#include "nouveau_drv.h"
#include "nouveau_dma.h"
#include "nouveau_mm.h"
#include "nouveau_vm.h"

#include <linux/log2.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -386,10 +388,13 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
man->default_caching = TTM_PL_FLAG_CACHED;
break;
case TTM_PL_VRAM:
if (dev_priv->card_type == NV_50)
if (dev_priv->card_type == NV_50) {
man->func = &nouveau_vram_manager;
else
man->io_reserve_fastpath = false;
man->use_io_reserve_lru = true;
} else {
man->func = &ttm_bo_manager_func;
}
man->flags = TTM_MEMTYPE_FLAG_FIXED |
TTM_MEMTYPE_FLAG_MAPPABLE;
man->available_caching = TTM_PL_FLAG_UNCACHED |
Expand Down Expand Up @@ -858,6 +863,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
struct drm_device *dev = dev_priv->dev;
int ret;

mem->bus.addr = NULL;
mem->bus.offset = 0;
Expand All @@ -880,9 +886,32 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
#endif
break;
case TTM_PL_VRAM:
mem->bus.offset = mem->start << PAGE_SHIFT;
{
struct nouveau_vram *vram = mem->mm_node;

if (!dev_priv->bar1_vm) {
mem->bus.offset = mem->start << PAGE_SHIFT;
mem->bus.base = pci_resource_start(dev->pdev, 1);
mem->bus.is_iomem = true;
break;
}

ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, 12,
NV_MEM_ACCESS_RW, &vram->bar_vma);
if (ret)
return ret;

nouveau_vm_map(&vram->bar_vma, vram);
if (ret) {
nouveau_vm_put(&vram->bar_vma);
return ret;
}

mem->bus.offset = vram->bar_vma.offset;
mem->bus.offset -= 0x0020000000ULL;
mem->bus.base = pci_resource_start(dev->pdev, 1);
mem->bus.is_iomem = true;
}
break;
default:
return -EINVAL;
Expand All @@ -893,6 +922,17 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
static void
nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
struct nouveau_vram *vram = mem->mm_node;

if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM)
return;

if (!vram->bar_vma.node)
return;

nouveau_vm_unmap(&vram->bar_vma);
nouveau_vm_put(&vram->bar_vma);
}

static int
Expand Down
10 changes: 10 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ struct nouveau_fpriv {
#include "nouveau_reg.h"
#include "nouveau_bios.h"
#include "nouveau_util.h"

struct nouveau_grctx;
struct nouveau_vram;
#include "nouveau_vm.h"

#define MAX_NUM_DCB_ENTRIES 16

Expand All @@ -69,6 +72,8 @@ struct nouveau_grctx;
struct nouveau_vram {
struct drm_device *dev;

struct nouveau_vma bar_vma;

struct list_head regions;
u32 memtype;
u64 offset;
Expand Down Expand Up @@ -244,6 +249,7 @@ struct nouveau_channel {
void *pgraph_ctx;

/* NV50 VM */
struct nouveau_vm *vm;
struct nouveau_gpuobj *vm_pd;
struct nouveau_gpuobj *vm_gart_pt;
struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
Expand Down Expand Up @@ -701,6 +707,10 @@ struct drm_nouveau_private {
uint64_t fb_aper_free;
int fb_mtrr;

/* BAR control (NV50-) */
struct nouveau_vm *bar1_vm;
struct nouveau_vm *bar3_vm;

/* G8x/G9x virtual address space */
uint64_t vm_gart_base;
uint64_t vm_gart_size;
Expand Down
Loading

0 comments on commit f869ef8

Please sign in to comment.