summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/nouveau_drv.h2
-rw-r--r--shared-core/nouveau_notifier.c29
2 files changed, 22 insertions, 9 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index b7459b1b..e96c8fad 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -421,6 +421,8 @@ extern void nouveau_irq_uninstall(struct drm_device *);
/* nouveau_sgdma.c */
extern int nouveau_sgdma_init(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 int nouveau_sgdma_nottm_hack_init(struct drm_device *);
extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);
diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c
index 31547aae..91f605ec 100644
--- a/shared-core/nouveau_notifier.c
+++ b/shared-core/nouveau_notifier.c
@@ -37,14 +37,13 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
int flags, ret;
/*TODO: PCI notifier blocks */
- if (dev_priv->agp_heap &&
- dev_priv->gart_info.type != NOUVEAU_GART_SGDMA)
- flags = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE;
- else if ( dev_priv->pci_heap )
+ if (dev_priv->agp_heap)
+ flags = NOUVEAU_MEM_AGP;
+ else if (dev_priv->pci_heap)
flags = NOUVEAU_MEM_PCI;
else
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);
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)
{
struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *nobj = NULL;
struct mem_block *mem;
uint32_t offset;
@@ -107,18 +107,29 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
}
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) {
target = NV_DMA_TARGET_VIDMEM;
- } else if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) {
- target = NV_DMA_TARGET_AGP;
- } else if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) {
+ } 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;
+ }
+ } else
+ if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) {
target = NV_DMA_TARGET_PCI_NONLINEAR;
} else {
DRM_ERROR("Bad DMA target, flags 0x%08x!\n",
chan->notifier_block->flags);
return -EINVAL;
}
+ offset += mem->start;
if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
offset, mem->size,