diff options
-rw-r--r-- | drivers/char/drm/ati_pcigart.c | 91 | ||||
-rw-r--r-- | drivers/char/drm/drmP.h | 3 | ||||
-rw-r--r-- | drivers/char/drm/r128_cce.c | 1 | ||||
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 1 |
4 files changed, 27 insertions, 69 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index d352dbb4ccf7..e5a0e97cfdda 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
@@ -35,42 +35,23 @@ | |||
35 | 35 | ||
36 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ | 36 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ |
37 | 37 | ||
38 | static void *drm_ati_alloc_pcigart_table(int order) | 38 | static int drm_ati_alloc_pcigart_table(struct drm_device *dev, |
39 | struct drm_ati_pcigart_info *gart_info) | ||
39 | { | 40 | { |
40 | unsigned long address; | 41 | gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, |
41 | struct page *page; | 42 | PAGE_SIZE, |
42 | int i; | 43 | gart_info->table_mask); |
43 | 44 | if (gart_info->table_handle == NULL) | |
44 | DRM_DEBUG("%d order\n", order); | 45 | return -ENOMEM; |
45 | |||
46 | address = __get_free_pages(GFP_KERNEL | __GFP_COMP, | ||
47 | order); | ||
48 | if (address == 0UL) { | ||
49 | return NULL; | ||
50 | } | ||
51 | |||
52 | page = virt_to_page(address); | ||
53 | 46 | ||
54 | for (i = 0; i < order; i++, page++) | 47 | return 0; |
55 | SetPageReserved(page); | ||
56 | |||
57 | DRM_DEBUG("returning 0x%08lx\n", address); | ||
58 | return (void *)address; | ||
59 | } | 48 | } |
60 | 49 | ||
61 | static void drm_ati_free_pcigart_table(void *address, int order) | 50 | static void drm_ati_free_pcigart_table(struct drm_device *dev, |
51 | struct drm_ati_pcigart_info *gart_info) | ||
62 | { | 52 | { |
63 | struct page *page; | 53 | drm_pci_free(dev, gart_info->table_handle); |
64 | int i; | 54 | gart_info->table_handle = NULL; |
65 | int num_pages = 1 << order; | ||
66 | DRM_DEBUG("\n"); | ||
67 | |||
68 | page = virt_to_page((unsigned long)address); | ||
69 | |||
70 | for (i = 0; i < num_pages; i++, page++) | ||
71 | ClearPageReserved(page); | ||
72 | |||
73 | free_pages((unsigned long)address, order); | ||
74 | } | 55 | } |
75 | 56 | ||
76 | int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) | 57 | int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) |
@@ -78,8 +59,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info | |||
78 | struct drm_sg_mem *entry = dev->sg; | 59 | struct drm_sg_mem *entry = dev->sg; |
79 | unsigned long pages; | 60 | unsigned long pages; |
80 | int i; | 61 | int i; |
81 | int order; | 62 | int max_pages; |
82 | int num_pages, max_pages; | ||
83 | 63 | ||
84 | /* we need to support large memory configurations */ | 64 | /* we need to support large memory configurations */ |
85 | if (!entry) { | 65 | if (!entry) { |
@@ -87,15 +67,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info | |||
87 | return 0; | 67 | return 0; |
88 | } | 68 | } |
89 | 69 | ||
90 | order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE); | ||
91 | num_pages = 1 << order; | ||
92 | |||
93 | if (gart_info->bus_addr) { | 70 | if (gart_info->bus_addr) { |
94 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | ||
95 | pci_unmap_single(dev->pdev, gart_info->bus_addr, | ||
96 | num_pages * PAGE_SIZE, | ||
97 | PCI_DMA_TODEVICE); | ||
98 | } | ||
99 | 71 | ||
100 | max_pages = (gart_info->table_size / sizeof(u32)); | 72 | max_pages = (gart_info->table_size / sizeof(u32)); |
101 | pages = (entry->pages <= max_pages) | 73 | pages = (entry->pages <= max_pages) |
@@ -112,10 +84,9 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info | |||
112 | gart_info->bus_addr = 0; | 84 | gart_info->bus_addr = 0; |
113 | } | 85 | } |
114 | 86 | ||
115 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN | 87 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && |
116 | && gart_info->addr) { | 88 | gart_info->table_handle) { |
117 | drm_ati_free_pcigart_table(gart_info->addr, order); | 89 | drm_ati_free_pcigart_table(dev, gart_info); |
118 | gart_info->addr = NULL; | ||
119 | } | 90 | } |
120 | 91 | ||
121 | return 1; | 92 | return 1; |
@@ -127,11 +98,10 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
127 | struct drm_sg_mem *entry = dev->sg; | 98 | struct drm_sg_mem *entry = dev->sg; |
128 | void *address = NULL; | 99 | void *address = NULL; |
129 | unsigned long pages; | 100 | unsigned long pages; |
130 | u32 *pci_gart, page_base, bus_address = 0; | 101 | u32 *pci_gart, page_base; |
102 | dma_addr_t bus_address = 0; | ||
131 | int i, j, ret = 0; | 103 | int i, j, ret = 0; |
132 | int order; | ||
133 | int max_pages; | 104 | int max_pages; |
134 | int num_pages; | ||
135 | 105 | ||
136 | if (!entry) { | 106 | if (!entry) { |
137 | DRM_ERROR("no scatter/gather memory!\n"); | 107 | DRM_ERROR("no scatter/gather memory!\n"); |
@@ -141,31 +111,14 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
141 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | 111 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { |
142 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); | 112 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); |
143 | 113 | ||
144 | order = drm_order((gart_info->table_size + | 114 | ret = drm_ati_alloc_pcigart_table(dev, gart_info); |
145 | (PAGE_SIZE-1)) / PAGE_SIZE); | 115 | if (ret) { |
146 | num_pages = 1 << order; | ||
147 | address = drm_ati_alloc_pcigart_table(order); | ||
148 | if (!address) { | ||
149 | DRM_ERROR("cannot allocate PCI GART page!\n"); | 116 | DRM_ERROR("cannot allocate PCI GART page!\n"); |
150 | goto done; | 117 | goto done; |
151 | } | 118 | } |
152 | 119 | ||
153 | if (!dev->pdev) { | 120 | address = gart_info->table_handle->vaddr; |
154 | DRM_ERROR("PCI device unknown!\n"); | 121 | bus_address = gart_info->table_handle->busaddr; |
155 | goto done; | ||
156 | } | ||
157 | |||
158 | bus_address = pci_map_single(dev->pdev, address, | ||
159 | num_pages * PAGE_SIZE, | ||
160 | PCI_DMA_TODEVICE); | ||
161 | if (bus_address == 0) { | ||
162 | DRM_ERROR("unable to map PCIGART pages!\n"); | ||
163 | order = drm_order((gart_info->table_size + | ||
164 | (PAGE_SIZE-1)) / PAGE_SIZE); | ||
165 | drm_ati_free_pcigart_table(address, order); | ||
166 | address = NULL; | ||
167 | goto done; | ||
168 | } | ||
169 | } else { | 122 | } else { |
170 | address = gart_info->addr; | 123 | address = gart_info->addr; |
171 | bus_address = gart_info->bus_addr; | 124 | bus_address = gart_info->bus_addr; |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index a6789f25009b..8ea9dd1717a9 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/jiffies.h> | 55 | #include <linux/jiffies.h> |
56 | #include <linux/smp_lock.h> /* For (un)lock_kernel */ | 56 | #include <linux/smp_lock.h> /* For (un)lock_kernel */ |
57 | #include <linux/dma-mapping.h> | ||
57 | #include <linux/mm.h> | 58 | #include <linux/mm.h> |
58 | #include <linux/cdev.h> | 59 | #include <linux/cdev.h> |
59 | #include <linux/mutex.h> | 60 | #include <linux/mutex.h> |
@@ -551,6 +552,8 @@ struct drm_ati_pcigart_info { | |||
551 | int gart_reg_if; | 552 | int gart_reg_if; |
552 | void *addr; | 553 | void *addr; |
553 | dma_addr_t bus_addr; | 554 | dma_addr_t bus_addr; |
555 | dma_addr_t table_mask; | ||
556 | struct drm_dma_handle *table_handle; | ||
554 | drm_local_map_t mapping; | 557 | drm_local_map_t mapping; |
555 | int table_size; | 558 | int table_size; |
556 | }; | 559 | }; |
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index 892e0a589846..f36adbd3aaf5 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c | |||
@@ -558,6 +558,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) | |||
558 | #if __OS_HAS_AGP | 558 | #if __OS_HAS_AGP |
559 | if (dev_priv->is_pci) { | 559 | if (dev_priv->is_pci) { |
560 | #endif | 560 | #endif |
561 | dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); | ||
561 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | 562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; |
562 | dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; | 563 | dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; |
563 | dev_priv->gart_info.addr = NULL; | 564 | dev_priv->gart_info.addr = NULL; |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 833abc7e55fb..9072e4a1894e 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -1807,6 +1807,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) | |||
1807 | } else | 1807 | } else |
1808 | #endif | 1808 | #endif |
1809 | { | 1809 | { |
1810 | dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); | ||
1810 | /* if we have an offset set from userspace */ | 1811 | /* if we have an offset set from userspace */ |
1811 | if (dev_priv->pcigart_offset_set) { | 1812 | if (dev_priv->pcigart_offset_set) { |
1812 | dev_priv->gart_info.bus_addr = | 1813 | dev_priv->gart_info.bus_addr = |