nouveau: Allow GART notifiers when using sgdma code.

This commit is contained in:
Ben Skeggs 2007-08-15 13:36:54 +10:00
parent ee01d3755a
commit c3faa589b0
3 changed files with 39 additions and 9 deletions

View file

@ -316,3 +316,20 @@ nouveau_sgdma_nottm_hack_takedown(struct drm_device *dev)
{ {
} }
int
nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
int pte;
pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
if (dev_priv->card_type < NV_50) {
*page = INSTANCE_RD(gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
return 0;
}
DRM_ERROR("Unimplemented on NV50\n");
return -EINVAL;
}

View file

@ -421,6 +421,8 @@ extern void nouveau_irq_uninstall(struct drm_device *);
/* nouveau_sgdma.c */ /* nouveau_sgdma.c */
extern int nouveau_sgdma_init(struct drm_device *); extern int nouveau_sgdma_init(struct drm_device *);
extern void nouveau_sgdma_takedown(struct drm_device *); extern void nouveau_sgdma_takedown(struct drm_device *);
extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
uint32_t *page);
extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
extern int nouveau_sgdma_nottm_hack_init(struct drm_device *); extern int nouveau_sgdma_nottm_hack_init(struct drm_device *);
extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *); extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);

View file

@ -37,14 +37,13 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
int flags, ret; int flags, ret;
/*TODO: PCI notifier blocks */ /*TODO: PCI notifier blocks */
if (dev_priv->agp_heap && if (dev_priv->agp_heap)
dev_priv->gart_info.type != NOUVEAU_GART_SGDMA) flags = NOUVEAU_MEM_AGP;
flags = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE; else if (dev_priv->pci_heap)
else if ( dev_priv->pci_heap )
flags = NOUVEAU_MEM_PCI; flags = NOUVEAU_MEM_PCI;
else else
flags = NOUVEAU_MEM_FB; flags = NOUVEAU_MEM_FB;
flags |= NOUVEAU_MEM_MAPPED; flags |= (NOUVEAU_MEM_MAPPED | NOUVEAU_MEM_FB_ACCEPTABLE);
DRM_DEBUG("Allocating notifier block in %d\n", flags); DRM_DEBUG("Allocating notifier block in %d\n", flags);
chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags, chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags,
@ -88,6 +87,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
int count, uint32_t *b_offset) int count, uint32_t *b_offset)
{ {
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *nobj = NULL; struct nouveau_gpuobj *nobj = NULL;
struct mem_block *mem; struct mem_block *mem;
uint32_t offset; uint32_t offset;
@ -107,18 +107,29 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
} }
mem->flags = NOUVEAU_MEM_NOTIFIER; mem->flags = NOUVEAU_MEM_NOTIFIER;
offset = chan->notifier_block->start + mem->start; offset = chan->notifier_block->start;
if (chan->notifier_block->flags & NOUVEAU_MEM_FB) { if (chan->notifier_block->flags & NOUVEAU_MEM_FB) {
target = NV_DMA_TARGET_VIDMEM; target = NV_DMA_TARGET_VIDMEM;
} else if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) { } else
if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) {
if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA &&
dev_priv->card_type < NV_50) {
ret = nouveau_sgdma_get_page(dev, offset, &offset);
if (ret)
return ret;
target = NV_DMA_TARGET_PCI;
} else {
target = NV_DMA_TARGET_AGP; target = NV_DMA_TARGET_AGP;
} else if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) { }
} else
if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) {
target = NV_DMA_TARGET_PCI_NONLINEAR; target = NV_DMA_TARGET_PCI_NONLINEAR;
} else { } else {
DRM_ERROR("Bad DMA target, flags 0x%08x!\n", DRM_ERROR("Bad DMA target, flags 0x%08x!\n",
chan->notifier_block->flags); chan->notifier_block->flags);
return -EINVAL; return -EINVAL;
} }
offset += mem->start;
if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
offset, mem->size, offset, mem->size,