aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_sgdma.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-02-22 21:06:39 -0500
committerDave Airlie <airlied@redhat.com>2011-02-22 21:06:39 -0500
commitde1e7cd63a8ec26a3bd3740708cfd72dd76509e2 (patch)
tree52bc82a71f34e92895d22821543a2be011834505 /drivers/gpu/drm/nouveau/nouveau_sgdma.c
parent7811bddb6654337fd85837ef14c1a96a0c264745 (diff)
parent5a893fc28f0393adb7c885a871b8c59e623fd528 (diff)
Merge branch 'stable/ttm.pci-api.v5' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen into drm-next
* 'stable/ttm.pci-api.v5' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: ttm: Include the 'struct dev' when using the DMA API. nouveau/ttm/PCIe: Use dma_addr if TTM has set it. radeon/ttm/PCIe: Use dma_addr if TTM has set it. ttm: Expand (*populate) to support an array of DMA addresses. ttm: Utilize the DMA API for pages that have TTM_PAGE_FLAG_DMA32 set. ttm: Introduce a placeholder for DMA (bus) addresses.
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_sgdma.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sgdma.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 9a250eb53098..07b115184b87 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -12,6 +12,7 @@ struct nouveau_sgdma_be {
12 struct drm_device *dev; 12 struct drm_device *dev;
13 13
14 dma_addr_t *pages; 14 dma_addr_t *pages;
15 bool *ttm_alloced;
15 unsigned nr_pages; 16 unsigned nr_pages;
16 17
17 u64 offset; 18 u64 offset;
@@ -20,7 +21,8 @@ struct nouveau_sgdma_be {
20 21
21static int 22static int
22nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, 23nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
23 struct page **pages, struct page *dummy_read_page) 24 struct page **pages, struct page *dummy_read_page,
25 dma_addr_t *dma_addrs)
24{ 26{
25 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; 27 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
26 struct drm_device *dev = nvbe->dev; 28 struct drm_device *dev = nvbe->dev;
@@ -34,15 +36,25 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
34 if (!nvbe->pages) 36 if (!nvbe->pages)
35 return -ENOMEM; 37 return -ENOMEM;
36 38
39 nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL);
40 if (!nvbe->ttm_alloced)
41 return -ENOMEM;
42
37 nvbe->nr_pages = 0; 43 nvbe->nr_pages = 0;
38 while (num_pages--) { 44 while (num_pages--) {
39 nvbe->pages[nvbe->nr_pages] = 45 if (dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE) {
40 pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0, 46 nvbe->pages[nvbe->nr_pages] =
47 dma_addrs[nvbe->nr_pages];
48 nvbe->ttm_alloced[nvbe->nr_pages] = true;
49 } else {
50 nvbe->pages[nvbe->nr_pages] =
51 pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0,
41 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 52 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
42 if (pci_dma_mapping_error(dev->pdev, 53 if (pci_dma_mapping_error(dev->pdev,
43 nvbe->pages[nvbe->nr_pages])) { 54 nvbe->pages[nvbe->nr_pages])) {
44 be->func->clear(be); 55 be->func->clear(be);
45 return -EFAULT; 56 return -EFAULT;
57 }
46 } 58 }
47 59
48 nvbe->nr_pages++; 60 nvbe->nr_pages++;
@@ -65,11 +77,14 @@ nouveau_sgdma_clear(struct ttm_backend *be)
65 be->func->unbind(be); 77 be->func->unbind(be);
66 78
67 while (nvbe->nr_pages--) { 79 while (nvbe->nr_pages--) {
68 pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], 80 if (!nvbe->ttm_alloced[nvbe->nr_pages])
81 pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
69 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 82 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
70 } 83 }
71 kfree(nvbe->pages); 84 kfree(nvbe->pages);
85 kfree(nvbe->ttm_alloced);
72 nvbe->pages = NULL; 86 nvbe->pages = NULL;
87 nvbe->ttm_alloced = NULL;
73 nvbe->nr_pages = 0; 88 nvbe->nr_pages = 0;
74 } 89 }
75} 90}