diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/drm/ati_pcigart.c | 84 | ||||
-rw-r--r-- | drivers/char/drm/drmP.h | 7 | ||||
-rw-r--r-- | drivers/char/drm/drm_drv.c | 10 | ||||
-rw-r--r-- | drivers/char/drm/drm_os_linux.h | 3 | ||||
-rw-r--r-- | drivers/char/drm/drm_pciids.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/r128_cce.c | 3 | ||||
-rw-r--r-- | drivers/char/drm/r128_drv.h | 2 | ||||
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 71 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drm.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drv.h | 24 | ||||
-rw-r--r-- | drivers/char/drm/radeon_state.c | 52 | ||||
-rw-r--r-- | drivers/char/drm/via_dma.c | 111 | ||||
-rw-r--r-- | drivers/char/drm/via_drv.h | 5 |
13 files changed, 222 insertions, 152 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index bd7be09ea53d..5b91bc04ea4e 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
@@ -33,59 +33,44 @@ | |||
33 | 33 | ||
34 | #include "drmP.h" | 34 | #include "drmP.h" |
35 | 35 | ||
36 | #if PAGE_SIZE == 65536 | ||
37 | # define ATI_PCIGART_TABLE_ORDER 0 | ||
38 | # define ATI_PCIGART_TABLE_PAGES (1 << 0) | ||
39 | #elif PAGE_SIZE == 16384 | ||
40 | # define ATI_PCIGART_TABLE_ORDER 1 | ||
41 | # define ATI_PCIGART_TABLE_PAGES (1 << 1) | ||
42 | #elif PAGE_SIZE == 8192 | ||
43 | # define ATI_PCIGART_TABLE_ORDER 2 | ||
44 | # define ATI_PCIGART_TABLE_PAGES (1 << 2) | ||
45 | #elif PAGE_SIZE == 4096 | ||
46 | # define ATI_PCIGART_TABLE_ORDER 3 | ||
47 | # define ATI_PCIGART_TABLE_PAGES (1 << 3) | ||
48 | #else | ||
49 | # error - PAGE_SIZE not 64K, 16K, 8K or 4K | ||
50 | #endif | ||
51 | |||
52 | # define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ | ||
53 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ | 36 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ |
54 | 37 | ||
55 | static void *drm_ati_alloc_pcigart_table(void) | 38 | static void *drm_ati_alloc_pcigart_table(int order) |
56 | { | 39 | { |
57 | unsigned long address; | 40 | unsigned long address; |
58 | struct page *page; | 41 | struct page *page; |
59 | int i; | 42 | int i; |
60 | DRM_DEBUG("%s\n", __FUNCTION__); | 43 | |
44 | DRM_DEBUG("%s: alloc %d order\n", __FUNCTION__, order); | ||
61 | 45 | ||
62 | address = __get_free_pages(GFP_KERNEL | __GFP_COMP, | 46 | address = __get_free_pages(GFP_KERNEL | __GFP_COMP, |
63 | ATI_PCIGART_TABLE_ORDER); | 47 | order); |
64 | if (address == 0UL) { | 48 | if (address == 0UL) { |
65 | return NULL; | 49 | return NULL; |
66 | } | 50 | } |
67 | 51 | ||
68 | page = virt_to_page(address); | 52 | page = virt_to_page(address); |
69 | 53 | ||
70 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) | 54 | for (i = 0; i < order; i++, page++) |
71 | SetPageReserved(page); | 55 | SetPageReserved(page); |
72 | 56 | ||
73 | DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); | 57 | DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); |
74 | return (void *)address; | 58 | return (void *)address; |
75 | } | 59 | } |
76 | 60 | ||
77 | static void drm_ati_free_pcigart_table(void *address) | 61 | static void drm_ati_free_pcigart_table(void *address, int order) |
78 | { | 62 | { |
79 | struct page *page; | 63 | struct page *page; |
80 | int i; | 64 | int i; |
65 | int num_pages = 1 << order; | ||
81 | DRM_DEBUG("%s\n", __FUNCTION__); | 66 | DRM_DEBUG("%s\n", __FUNCTION__); |
82 | 67 | ||
83 | page = virt_to_page((unsigned long)address); | 68 | page = virt_to_page((unsigned long)address); |
84 | 69 | ||
85 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) | 70 | for (i = 0; i < num_pages; i++, page++) |
86 | ClearPageReserved(page); | 71 | ClearPageReserved(page); |
87 | 72 | ||
88 | free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); | 73 | free_pages((unsigned long)address, order); |
89 | } | 74 | } |
90 | 75 | ||
91 | int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | 76 | int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) |
@@ -93,6 +78,8 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
93 | drm_sg_mem_t *entry = dev->sg; | 78 | drm_sg_mem_t *entry = dev->sg; |
94 | unsigned long pages; | 79 | unsigned long pages; |
95 | int i; | 80 | int i; |
81 | int order; | ||
82 | int num_pages, max_pages; | ||
96 | 83 | ||
97 | /* we need to support large memory configurations */ | 84 | /* we need to support large memory configurations */ |
98 | if (!entry) { | 85 | if (!entry) { |
@@ -100,15 +87,19 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
100 | return 0; | 87 | return 0; |
101 | } | 88 | } |
102 | 89 | ||
90 | order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE); | ||
91 | num_pages = 1 << order; | ||
92 | |||
103 | if (gart_info->bus_addr) { | 93 | if (gart_info->bus_addr) { |
104 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | 94 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { |
105 | pci_unmap_single(dev->pdev, gart_info->bus_addr, | 95 | pci_unmap_single(dev->pdev, gart_info->bus_addr, |
106 | ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, | 96 | num_pages * PAGE_SIZE, |
107 | PCI_DMA_TODEVICE); | 97 | PCI_DMA_TODEVICE); |
108 | } | 98 | } |
109 | 99 | ||
110 | pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) | 100 | max_pages = (gart_info->table_size / sizeof(u32)); |
111 | ? entry->pages : ATI_MAX_PCIGART_PAGES; | 101 | pages = (entry->pages <= max_pages) |
102 | ? entry->pages : max_pages; | ||
112 | 103 | ||
113 | for (i = 0; i < pages; i++) { | 104 | for (i = 0; i < pages; i++) { |
114 | if (!entry->busaddr[i]) | 105 | if (!entry->busaddr[i]) |
@@ -123,13 +114,12 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
123 | 114 | ||
124 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN | 115 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN |
125 | && gart_info->addr) { | 116 | && gart_info->addr) { |
126 | drm_ati_free_pcigart_table(gart_info->addr); | 117 | drm_ati_free_pcigart_table(gart_info->addr, order); |
127 | gart_info->addr = NULL; | 118 | gart_info->addr = NULL; |
128 | } | 119 | } |
129 | 120 | ||
130 | return 1; | 121 | return 1; |
131 | } | 122 | } |
132 | |||
133 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); | 123 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); |
134 | 124 | ||
135 | int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | 125 | int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) |
@@ -139,6 +129,9 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
139 | unsigned long pages; | 129 | unsigned long pages; |
140 | u32 *pci_gart, page_base, bus_address = 0; | 130 | u32 *pci_gart, page_base, bus_address = 0; |
141 | int i, j, ret = 0; | 131 | int i, j, ret = 0; |
132 | int order; | ||
133 | int max_pages; | ||
134 | int num_pages; | ||
142 | 135 | ||
143 | if (!entry) { | 136 | if (!entry) { |
144 | DRM_ERROR("no scatter/gather memory!\n"); | 137 | DRM_ERROR("no scatter/gather memory!\n"); |
@@ -148,7 +141,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
148 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | 141 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { |
149 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); | 142 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); |
150 | 143 | ||
151 | address = drm_ati_alloc_pcigart_table(); | 144 | order = drm_order((gart_info->table_size + |
145 | (PAGE_SIZE-1)) / PAGE_SIZE); | ||
146 | num_pages = 1 << order; | ||
147 | address = drm_ati_alloc_pcigart_table(order); | ||
152 | if (!address) { | 148 | if (!address) { |
153 | DRM_ERROR("cannot allocate PCI GART page!\n"); | 149 | DRM_ERROR("cannot allocate PCI GART page!\n"); |
154 | goto done; | 150 | goto done; |
@@ -160,11 +156,13 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
160 | } | 156 | } |
161 | 157 | ||
162 | bus_address = pci_map_single(dev->pdev, address, | 158 | bus_address = pci_map_single(dev->pdev, address, |
163 | ATI_PCIGART_TABLE_PAGES * | 159 | num_pages * PAGE_SIZE, |
164 | PAGE_SIZE, PCI_DMA_TODEVICE); | 160 | PCI_DMA_TODEVICE); |
165 | if (bus_address == 0) { | 161 | if (bus_address == 0) { |
166 | DRM_ERROR("unable to map PCIGART pages!\n"); | 162 | DRM_ERROR("unable to map PCIGART pages!\n"); |
167 | drm_ati_free_pcigart_table(address); | 163 | order = drm_order((gart_info->table_size + |
164 | (PAGE_SIZE-1)) / PAGE_SIZE); | ||
165 | drm_ati_free_pcigart_table(address, order); | ||
168 | address = NULL; | 166 | address = NULL; |
169 | goto done; | 167 | goto done; |
170 | } | 168 | } |
@@ -177,10 +175,11 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
177 | 175 | ||
178 | pci_gart = (u32 *) address; | 176 | pci_gart = (u32 *) address; |
179 | 177 | ||
180 | pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) | 178 | max_pages = (gart_info->table_size / sizeof(u32)); |
181 | ? entry->pages : ATI_MAX_PCIGART_PAGES; | 179 | pages = (entry->pages <= max_pages) |
180 | ? entry->pages : max_pages; | ||
182 | 181 | ||
183 | memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32)); | 182 | memset(pci_gart, 0, max_pages * sizeof(u32)); |
184 | 183 | ||
185 | for (i = 0; i < pages; i++) { | 184 | for (i = 0; i < pages; i++) { |
186 | /* we need to support large memory configurations */ | 185 | /* we need to support large memory configurations */ |
@@ -198,10 +197,18 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
198 | page_base = (u32) entry->busaddr[i]; | 197 | page_base = (u32) entry->busaddr[i]; |
199 | 198 | ||
200 | for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { | 199 | for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { |
201 | if (gart_info->is_pcie) | 200 | switch(gart_info->gart_reg_if) { |
201 | case DRM_ATI_GART_IGP: | ||
202 | *pci_gart = cpu_to_le32((page_base) | 0xc); | ||
203 | break; | ||
204 | case DRM_ATI_GART_PCIE: | ||
202 | *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); | 205 | *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); |
203 | else | 206 | break; |
207 | default: | ||
208 | case DRM_ATI_GART_PCI: | ||
204 | *pci_gart = cpu_to_le32(page_base); | 209 | *pci_gart = cpu_to_le32(page_base); |
210 | break; | ||
211 | } | ||
205 | pci_gart++; | 212 | pci_gart++; |
206 | page_base += ATI_PCIGART_PAGE_SIZE; | 213 | page_base += ATI_PCIGART_PAGE_SIZE; |
207 | } | 214 | } |
@@ -220,5 +227,4 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
220 | gart_info->bus_addr = bus_address; | 227 | gart_info->bus_addr = bus_address; |
221 | return ret; | 228 | return ret; |
222 | } | 229 | } |
223 | |||
224 | EXPORT_SYMBOL(drm_ati_pcigart_init); | 230 | EXPORT_SYMBOL(drm_ati_pcigart_init); |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 80041d5b792d..d494315752a2 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -519,12 +519,17 @@ typedef struct drm_vbl_sig { | |||
519 | #define DRM_ATI_GART_MAIN 1 | 519 | #define DRM_ATI_GART_MAIN 1 |
520 | #define DRM_ATI_GART_FB 2 | 520 | #define DRM_ATI_GART_FB 2 |
521 | 521 | ||
522 | #define DRM_ATI_GART_PCI 1 | ||
523 | #define DRM_ATI_GART_PCIE 2 | ||
524 | #define DRM_ATI_GART_IGP 3 | ||
525 | |||
522 | typedef struct ati_pcigart_info { | 526 | typedef struct ati_pcigart_info { |
523 | int gart_table_location; | 527 | int gart_table_location; |
524 | int is_pcie; | 528 | int gart_reg_if; |
525 | void *addr; | 529 | void *addr; |
526 | dma_addr_t bus_addr; | 530 | dma_addr_t bus_addr; |
527 | drm_local_map_t mapping; | 531 | drm_local_map_t mapping; |
532 | int table_size; | ||
528 | } drm_ati_pcigart_info; | 533 | } drm_ati_pcigart_info; |
529 | 534 | ||
530 | /* | 535 | /* |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 26bec30ee86e..8e77b7ed0f44 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -15,8 +15,6 @@ | |||
15 | * #define DRIVER_DESC "Matrox G200/G400" | 15 | * #define DRIVER_DESC "Matrox G200/G400" |
16 | * #define DRIVER_DATE "20001127" | 16 | * #define DRIVER_DATE "20001127" |
17 | * | 17 | * |
18 | * #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls ) | ||
19 | * | ||
20 | * #define drm_x mga_##x | 18 | * #define drm_x mga_##x |
21 | * \endcode | 19 | * \endcode |
22 | */ | 20 | */ |
@@ -120,7 +118,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
120 | [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 118 | [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
121 | }; | 119 | }; |
122 | 120 | ||
123 | #define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | 121 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) |
124 | 122 | ||
125 | /** | 123 | /** |
126 | * Take down the DRM device. | 124 | * Take down the DRM device. |
@@ -496,11 +494,11 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
496 | (long)old_encode_dev(priv->head->device), | 494 | (long)old_encode_dev(priv->head->device), |
497 | priv->authenticated); | 495 | priv->authenticated); |
498 | 496 | ||
499 | if ((nr >= DRIVER_IOCTL_COUNT) && | 497 | if ((nr >= DRM_CORE_IOCTL_COUNT) && |
500 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | 498 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
501 | goto err_i1; | 499 | goto err_i1; |
502 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) | 500 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && |
503 | && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) | 501 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) |
504 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | 502 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; |
505 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) | 503 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) |
506 | ioctl = &drm_ioctls[nr]; | 504 | ioctl = &drm_ioctls[nr]; |
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h index 2908b72daa6e..0fe7b4497927 100644 --- a/drivers/char/drm/drm_os_linux.h +++ b/drivers/char/drm/drm_os_linux.h | |||
@@ -70,9 +70,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size) | |||
70 | 70 | ||
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | /** Task queue handler arguments */ | ||
74 | #define DRM_TASKQUEUE_ARGS void *arg | ||
75 | |||
76 | /** For data going into the kernel through the ioctl argument */ | 73 | /** For data going into the kernel through the ioctl argument */ |
77 | #define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ | 74 | #define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ |
78 | if ( copy_from_user(&arg1, arg2, arg3) ) \ | 75 | if ( copy_from_user(&arg1, arg2, arg3) ) \ |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 01cf482d2d00..31cdde83713b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -102,6 +102,7 @@ | |||
102 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 102 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
103 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ | 103 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ |
104 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 104 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
105 | {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | ||
105 | {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 106 | {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
106 | {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 107 | {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
107 | {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 108 | {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index db5a60450e68..1014602c43a7 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c | |||
@@ -560,9 +560,10 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) | |||
560 | if (dev_priv->is_pci) { | 560 | if (dev_priv->is_pci) { |
561 | #endif | 561 | #endif |
562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | 562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; |
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; |
564 | dev_priv->gart_info.bus_addr = 0; | 565 | dev_priv->gart_info.bus_addr = 0; |
565 | dev_priv->gart_info.is_pcie = 0; | 566 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; |
566 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | 567 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { |
567 | DRM_ERROR("failed to init PCI GART!\n"); | 568 | DRM_ERROR("failed to init PCI GART!\n"); |
568 | dev->dev_private = (void *)dev_priv; | 569 | dev->dev_private = (void *)dev_priv; |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index f1efb49de8df..9086835686dc 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -383,6 +383,8 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, | |||
383 | 383 | ||
384 | #define R128_PERFORMANCE_BOXES 0 | 384 | #define R128_PERFORMANCE_BOXES 0 |
385 | 385 | ||
386 | #define R128_PCIGART_TABLE_SIZE 32768 | ||
387 | |||
386 | #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) | 388 | #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) |
387 | #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) | 389 | #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) |
388 | #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) | 390 | #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index c1850ecac302..68338389d836 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -830,6 +830,15 @@ static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) | |||
830 | return RADEON_READ(RADEON_PCIE_DATA); | 830 | return RADEON_READ(RADEON_PCIE_DATA); |
831 | } | 831 | } |
832 | 832 | ||
833 | static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr) | ||
834 | { | ||
835 | u32 ret; | ||
836 | RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f); | ||
837 | ret = RADEON_READ(RADEON_IGPGART_DATA); | ||
838 | RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f); | ||
839 | return ret; | ||
840 | } | ||
841 | |||
833 | #if RADEON_FIFO_DEBUG | 842 | #if RADEON_FIFO_DEBUG |
834 | static void radeon_status(drm_radeon_private_t * dev_priv) | 843 | static void radeon_status(drm_radeon_private_t * dev_priv) |
835 | { | 844 | { |
@@ -1267,7 +1276,44 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) | |||
1267 | } | 1276 | } |
1268 | } | 1277 | } |
1269 | 1278 | ||
1270 | /* Enable or disable PCI-E GART on the chip */ | 1279 | /* Enable or disable IGP GART on the chip */ |
1280 | static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) | ||
1281 | { | ||
1282 | u32 temp, tmp; | ||
1283 | |||
1284 | tmp = RADEON_READ(RADEON_AIC_CNTL); | ||
1285 | if (on) { | ||
1286 | DRM_DEBUG("programming igpgart %08X %08lX %08X\n", | ||
1287 | dev_priv->gart_vm_start, | ||
1288 | (long)dev_priv->gart_info.bus_addr, | ||
1289 | dev_priv->gart_size); | ||
1290 | |||
1291 | RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000); | ||
1292 | RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1); | ||
1293 | RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800); | ||
1294 | RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR, | ||
1295 | dev_priv->gart_info.bus_addr); | ||
1296 | |||
1297 | temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39); | ||
1298 | RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp); | ||
1299 | |||
1300 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start); | ||
1301 | dev_priv->gart_size = 32*1024*1024; | ||
1302 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, | ||
1303 | (((dev_priv->gart_vm_start - 1 + | ||
1304 | dev_priv->gart_size) & 0xffff0000) | | ||
1305 | (dev_priv->gart_vm_start >> 16))); | ||
1306 | |||
1307 | temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE); | ||
1308 | RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp); | ||
1309 | |||
1310 | RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); | ||
1311 | RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1); | ||
1312 | RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); | ||
1313 | RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1271 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | 1317 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) |
1272 | { | 1318 | { |
1273 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); | 1319 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); |
@@ -1302,6 +1348,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
1302 | { | 1348 | { |
1303 | u32 tmp; | 1349 | u32 tmp; |
1304 | 1350 | ||
1351 | if (dev_priv->flags & RADEON_IS_IGPGART) { | ||
1352 | radeon_set_igpgart(dev_priv, on); | ||
1353 | return; | ||
1354 | } | ||
1355 | |||
1305 | if (dev_priv->flags & RADEON_IS_PCIE) { | 1356 | if (dev_priv->flags & RADEON_IS_PCIE) { |
1306 | radeon_set_pciegart(dev_priv, on); | 1357 | radeon_set_pciegart(dev_priv, on); |
1307 | return; | 1358 | return; |
@@ -1620,20 +1671,22 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1620 | #endif | 1671 | #endif |
1621 | { | 1672 | { |
1622 | /* if we have an offset set from userspace */ | 1673 | /* if we have an offset set from userspace */ |
1623 | if (dev_priv->pcigart_offset) { | 1674 | if (dev_priv->pcigart_offset_set) { |
1624 | dev_priv->gart_info.bus_addr = | 1675 | dev_priv->gart_info.bus_addr = |
1625 | dev_priv->pcigart_offset + dev_priv->fb_location; | 1676 | dev_priv->pcigart_offset + dev_priv->fb_location; |
1626 | dev_priv->gart_info.mapping.offset = | 1677 | dev_priv->gart_info.mapping.offset = |
1627 | dev_priv->gart_info.bus_addr; | 1678 | dev_priv->gart_info.bus_addr; |
1628 | dev_priv->gart_info.mapping.size = | 1679 | dev_priv->gart_info.mapping.size = |
1629 | RADEON_PCIGART_TABLE_SIZE; | 1680 | dev_priv->gart_info.table_size; |
1630 | 1681 | ||
1631 | drm_core_ioremap(&dev_priv->gart_info.mapping, dev); | 1682 | drm_core_ioremap(&dev_priv->gart_info.mapping, dev); |
1632 | dev_priv->gart_info.addr = | 1683 | dev_priv->gart_info.addr = |
1633 | dev_priv->gart_info.mapping.handle; | 1684 | dev_priv->gart_info.mapping.handle; |
1634 | 1685 | ||
1635 | dev_priv->gart_info.is_pcie = | 1686 | if (dev_priv->flags & RADEON_IS_PCIE) |
1636 | !!(dev_priv->flags & RADEON_IS_PCIE); | 1687 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; |
1688 | else | ||
1689 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; | ||
1637 | dev_priv->gart_info.gart_table_location = | 1690 | dev_priv->gart_info.gart_table_location = |
1638 | DRM_ATI_GART_FB; | 1691 | DRM_ATI_GART_FB; |
1639 | 1692 | ||
@@ -1641,6 +1694,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1641 | dev_priv->gart_info.addr, | 1694 | dev_priv->gart_info.addr, |
1642 | dev_priv->pcigart_offset); | 1695 | dev_priv->pcigart_offset); |
1643 | } else { | 1696 | } else { |
1697 | if (dev_priv->flags & RADEON_IS_IGPGART) | ||
1698 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; | ||
1699 | else | ||
1700 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; | ||
1644 | dev_priv->gart_info.gart_table_location = | 1701 | dev_priv->gart_info.gart_table_location = |
1645 | DRM_ATI_GART_MAIN; | 1702 | DRM_ATI_GART_MAIN; |
1646 | dev_priv->gart_info.addr = NULL; | 1703 | dev_priv->gart_info.addr = NULL; |
@@ -1714,7 +1771,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) | |||
1714 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) | 1771 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) |
1715 | { | 1772 | { |
1716 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); | 1773 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); |
1717 | dev_priv->gart_info.addr = NULL; | 1774 | dev_priv->gart_info.addr = 0; |
1718 | } | 1775 | } |
1719 | } | 1776 | } |
1720 | /* only clear to the start of flags */ | 1777 | /* only clear to the start of flags */ |
@@ -2222,6 +2279,8 @@ int radeon_driver_firstopen(struct drm_device *dev) | |||
2222 | drm_local_map_t *map; | 2279 | drm_local_map_t *map; |
2223 | drm_radeon_private_t *dev_priv = dev->dev_private; | 2280 | drm_radeon_private_t *dev_priv = dev->dev_private; |
2224 | 2281 | ||
2282 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | ||
2283 | |||
2225 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | 2284 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), |
2226 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | 2285 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, |
2227 | _DRM_READ_ONLY, &dev_priv->mmio); | 2286 | _DRM_READ_ONLY, &dev_priv->mmio); |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 8d6350dd5360..66c4b6fed04f 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
@@ -707,6 +707,7 @@ typedef struct drm_radeon_setparam { | |||
707 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ | 707 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ |
708 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ | 708 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ |
709 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ | 709 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ |
710 | #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ | ||
710 | 711 | ||
711 | /* 1.14: Clients can allocate/free a surface | 712 | /* 1.14: Clients can allocate/free a surface |
712 | */ | 713 | */ |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 8b105f1460a7..54f49ef4bef0 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -95,9 +95,11 @@ | |||
95 | * 1.24- Add general-purpose packet for manipulating scratch registers (r300) | 95 | * 1.24- Add general-purpose packet for manipulating scratch registers (r300) |
96 | * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, | 96 | * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, |
97 | * new packet type) | 97 | * new packet type) |
98 | * 1.26- Add support for variable size PCI(E) gart aperture | ||
99 | * 1.27- Add support for IGP GART | ||
98 | */ | 100 | */ |
99 | #define DRIVER_MAJOR 1 | 101 | #define DRIVER_MAJOR 1 |
100 | #define DRIVER_MINOR 25 | 102 | #define DRIVER_MINOR 27 |
101 | #define DRIVER_PATCHLEVEL 0 | 103 | #define DRIVER_PATCHLEVEL 0 |
102 | 104 | ||
103 | /* | 105 | /* |
@@ -143,6 +145,7 @@ enum radeon_chip_flags { | |||
143 | RADEON_IS_PCIE = 0x00200000UL, | 145 | RADEON_IS_PCIE = 0x00200000UL, |
144 | RADEON_NEW_MEMMAP = 0x00400000UL, | 146 | RADEON_NEW_MEMMAP = 0x00400000UL, |
145 | RADEON_IS_PCI = 0x00800000UL, | 147 | RADEON_IS_PCI = 0x00800000UL, |
148 | RADEON_IS_IGPGART = 0x01000000UL, | ||
146 | }; | 149 | }; |
147 | 150 | ||
148 | #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ | 151 | #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ |
@@ -240,7 +243,6 @@ typedef struct drm_radeon_private { | |||
240 | 243 | ||
241 | int do_boxes; | 244 | int do_boxes; |
242 | int page_flipping; | 245 | int page_flipping; |
243 | int current_page; | ||
244 | 246 | ||
245 | u32 color_fmt; | 247 | u32 color_fmt; |
246 | unsigned int front_offset; | 248 | unsigned int front_offset; |
@@ -280,6 +282,7 @@ typedef struct drm_radeon_private { | |||
280 | struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; | 282 | struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; |
281 | 283 | ||
282 | unsigned long pcigart_offset; | 284 | unsigned long pcigart_offset; |
285 | unsigned int pcigart_offset_set; | ||
283 | drm_ati_pcigart_info gart_info; | 286 | drm_ati_pcigart_info gart_info; |
284 | 287 | ||
285 | u32 scratch_ages[5]; | 288 | u32 scratch_ages[5]; |
@@ -432,6 +435,15 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, | |||
432 | #define RADEON_PCIE_TX_GART_END_LO 0x16 | 435 | #define RADEON_PCIE_TX_GART_END_LO 0x16 |
433 | #define RADEON_PCIE_TX_GART_END_HI 0x17 | 436 | #define RADEON_PCIE_TX_GART_END_HI 0x17 |
434 | 437 | ||
438 | #define RADEON_IGPGART_INDEX 0x168 | ||
439 | #define RADEON_IGPGART_DATA 0x16c | ||
440 | #define RADEON_IGPGART_UNK_18 0x18 | ||
441 | #define RADEON_IGPGART_CTRL 0x2b | ||
442 | #define RADEON_IGPGART_BASE_ADDR 0x2c | ||
443 | #define RADEON_IGPGART_FLUSH 0x2e | ||
444 | #define RADEON_IGPGART_ENABLE 0x38 | ||
445 | #define RADEON_IGPGART_UNK_39 0x39 | ||
446 | |||
435 | #define RADEON_MPP_TB_CONFIG 0x01c0 | 447 | #define RADEON_MPP_TB_CONFIG 0x01c0 |
436 | #define RADEON_MEM_CNTL 0x0140 | 448 | #define RADEON_MEM_CNTL 0x0140 |
437 | #define RADEON_MEM_SDRAM_MODE_REG 0x0158 | 449 | #define RADEON_MEM_SDRAM_MODE_REG 0x0158 |
@@ -964,6 +976,14 @@ do { \ | |||
964 | RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ | 976 | RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ |
965 | } while (0) | 977 | } while (0) |
966 | 978 | ||
979 | #define RADEON_WRITE_IGPGART( addr, val ) \ | ||
980 | do { \ | ||
981 | RADEON_WRITE( RADEON_IGPGART_INDEX, \ | ||
982 | ((addr) & 0x7f) | (1 << 8)); \ | ||
983 | RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \ | ||
984 | RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \ | ||
985 | } while (0) | ||
986 | |||
967 | #define RADEON_WRITE_PCIE( addr, val ) \ | 987 | #define RADEON_WRITE_PCIE( addr, val ) \ |
968 | do { \ | 988 | do { \ |
969 | RADEON_WRITE8( RADEON_PCIE_INDEX, \ | 989 | RADEON_WRITE8( RADEON_PCIE_INDEX, \ |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 938eccb78cc0..98c5f1d3a8e7 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -773,7 +773,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv, | |||
773 | RADEON_GMC_SRC_DATATYPE_COLOR | | 773 | RADEON_GMC_SRC_DATATYPE_COLOR | |
774 | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); | 774 | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); |
775 | 775 | ||
776 | if (dev_priv->page_flipping && dev_priv->current_page == 1) { | 776 | if (dev_priv->sarea_priv->pfCurrentPage == 1) { |
777 | OUT_RING(dev_priv->front_pitch_offset); | 777 | OUT_RING(dev_priv->front_pitch_offset); |
778 | } else { | 778 | } else { |
779 | OUT_RING(dev_priv->back_pitch_offset); | 779 | OUT_RING(dev_priv->back_pitch_offset); |
@@ -861,7 +861,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, | |||
861 | 861 | ||
862 | dev_priv->stats.clears++; | 862 | dev_priv->stats.clears++; |
863 | 863 | ||
864 | if (dev_priv->page_flipping && dev_priv->current_page == 1) { | 864 | if (dev_priv->sarea_priv->pfCurrentPage == 1) { |
865 | unsigned int tmp = flags; | 865 | unsigned int tmp = flags; |
866 | 866 | ||
867 | flags &= ~(RADEON_FRONT | RADEON_BACK); | 867 | flags &= ~(RADEON_FRONT | RADEON_BACK); |
@@ -1382,7 +1382,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) | |||
1382 | /* Make this work even if front & back are flipped: | 1382 | /* Make this work even if front & back are flipped: |
1383 | */ | 1383 | */ |
1384 | OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); | 1384 | OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); |
1385 | if (dev_priv->current_page == 0) { | 1385 | if (dev_priv->sarea_priv->pfCurrentPage == 0) { |
1386 | OUT_RING(dev_priv->back_pitch_offset); | 1386 | OUT_RING(dev_priv->back_pitch_offset); |
1387 | OUT_RING(dev_priv->front_pitch_offset); | 1387 | OUT_RING(dev_priv->front_pitch_offset); |
1388 | } else { | 1388 | } else { |
@@ -1416,12 +1416,12 @@ static void radeon_cp_dispatch_flip(drm_device_t * dev) | |||
1416 | { | 1416 | { |
1417 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1417 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1418 | drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle; | 1418 | drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle; |
1419 | int offset = (dev_priv->current_page == 1) | 1419 | int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) |
1420 | ? dev_priv->front_offset : dev_priv->back_offset; | 1420 | ? dev_priv->front_offset : dev_priv->back_offset; |
1421 | RING_LOCALS; | 1421 | RING_LOCALS; |
1422 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", | 1422 | DRM_DEBUG("%s: pfCurrentPage=%d\n", |
1423 | __FUNCTION__, | 1423 | __FUNCTION__, |
1424 | dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); | 1424 | dev_priv->sarea_priv->pfCurrentPage); |
1425 | 1425 | ||
1426 | /* Do some trivial performance monitoring... | 1426 | /* Do some trivial performance monitoring... |
1427 | */ | 1427 | */ |
@@ -1449,8 +1449,8 @@ static void radeon_cp_dispatch_flip(drm_device_t * dev) | |||
1449 | * performing the swapbuffer ioctl. | 1449 | * performing the swapbuffer ioctl. |
1450 | */ | 1450 | */ |
1451 | dev_priv->sarea_priv->last_frame++; | 1451 | dev_priv->sarea_priv->last_frame++; |
1452 | dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = | 1452 | dev_priv->sarea_priv->pfCurrentPage = |
1453 | 1 - dev_priv->current_page; | 1453 | 1 - dev_priv->sarea_priv->pfCurrentPage; |
1454 | 1454 | ||
1455 | BEGIN_RING(2); | 1455 | BEGIN_RING(2); |
1456 | 1456 | ||
@@ -2152,24 +2152,10 @@ static int radeon_do_init_pageflip(drm_device_t * dev) | |||
2152 | ADVANCE_RING(); | 2152 | ADVANCE_RING(); |
2153 | 2153 | ||
2154 | dev_priv->page_flipping = 1; | 2154 | dev_priv->page_flipping = 1; |
2155 | dev_priv->current_page = 0; | ||
2156 | dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; | ||
2157 | 2155 | ||
2158 | return 0; | 2156 | if (dev_priv->sarea_priv->pfCurrentPage != 1) |
2159 | } | 2157 | dev_priv->sarea_priv->pfCurrentPage = 0; |
2160 | |||
2161 | /* Called whenever a client dies, from drm_release. | ||
2162 | * NOTE: Lock isn't necessarily held when this is called! | ||
2163 | */ | ||
2164 | static int radeon_do_cleanup_pageflip(drm_device_t * dev) | ||
2165 | { | ||
2166 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
2167 | DRM_DEBUG("\n"); | ||
2168 | |||
2169 | if (dev_priv->current_page != 0) | ||
2170 | radeon_cp_dispatch_flip(dev); | ||
2171 | 2158 | ||
2172 | dev_priv->page_flipping = 0; | ||
2173 | return 0; | 2159 | return 0; |
2174 | } | 2160 | } |
2175 | 2161 | ||
@@ -3145,10 +3131,16 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
3145 | break; | 3131 | break; |
3146 | case RADEON_SETPARAM_PCIGART_LOCATION: | 3132 | case RADEON_SETPARAM_PCIGART_LOCATION: |
3147 | dev_priv->pcigart_offset = sp.value; | 3133 | dev_priv->pcigart_offset = sp.value; |
3134 | dev_priv->pcigart_offset_set = 1; | ||
3148 | break; | 3135 | break; |
3149 | case RADEON_SETPARAM_NEW_MEMMAP: | 3136 | case RADEON_SETPARAM_NEW_MEMMAP: |
3150 | dev_priv->new_memmap = sp.value; | 3137 | dev_priv->new_memmap = sp.value; |
3151 | break; | 3138 | break; |
3139 | case RADEON_SETPARAM_PCIGART_TABLE_SIZE: | ||
3140 | dev_priv->gart_info.table_size = sp.value; | ||
3141 | if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) | ||
3142 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | ||
3143 | break; | ||
3152 | default: | 3144 | default: |
3153 | DRM_DEBUG("Invalid parameter %d\n", sp.param); | 3145 | DRM_DEBUG("Invalid parameter %d\n", sp.param); |
3154 | return DRM_ERR(EINVAL); | 3146 | return DRM_ERR(EINVAL); |
@@ -3168,9 +3160,7 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) | |||
3168 | { | 3160 | { |
3169 | if (dev->dev_private) { | 3161 | if (dev->dev_private) { |
3170 | drm_radeon_private_t *dev_priv = dev->dev_private; | 3162 | drm_radeon_private_t *dev_priv = dev->dev_private; |
3171 | if (dev_priv->page_flipping) { | 3163 | dev_priv->page_flipping = 0; |
3172 | radeon_do_cleanup_pageflip(dev); | ||
3173 | } | ||
3174 | radeon_mem_release(filp, dev_priv->gart_heap); | 3164 | radeon_mem_release(filp, dev_priv->gart_heap); |
3175 | radeon_mem_release(filp, dev_priv->fb_heap); | 3165 | radeon_mem_release(filp, dev_priv->fb_heap); |
3176 | radeon_surfaces_release(filp, dev_priv); | 3166 | radeon_surfaces_release(filp, dev_priv); |
@@ -3179,6 +3169,14 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) | |||
3179 | 3169 | ||
3180 | void radeon_driver_lastclose(drm_device_t * dev) | 3170 | void radeon_driver_lastclose(drm_device_t * dev) |
3181 | { | 3171 | { |
3172 | if (dev->dev_private) { | ||
3173 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
3174 | |||
3175 | if (dev_priv->sarea_priv && | ||
3176 | dev_priv->sarea_priv->pfCurrentPage != 0) | ||
3177 | radeon_cp_dispatch_flip(dev); | ||
3178 | } | ||
3179 | |||
3182 | radeon_do_release(dev); | 3180 | radeon_do_release(dev); |
3183 | } | 3181 | } |
3184 | 3182 | ||
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index c0539c6299cf..13a9c5ca4593 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c | |||
@@ -252,7 +252,7 @@ static int via_dma_init(DRM_IOCTL_ARGS) | |||
252 | break; | 252 | break; |
253 | case VIA_DMA_INITIALIZED: | 253 | case VIA_DMA_INITIALIZED: |
254 | retcode = (dev_priv->ring.virtual_start != NULL) ? | 254 | retcode = (dev_priv->ring.virtual_start != NULL) ? |
255 | 0 : DRM_ERR(EFAULT); | 255 | 0 : DRM_ERR(EFAULT); |
256 | break; | 256 | break; |
257 | default: | 257 | default: |
258 | retcode = DRM_ERR(EINVAL); | 258 | retcode = DRM_ERR(EINVAL); |
@@ -432,56 +432,34 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
432 | { | 432 | { |
433 | int paused, count; | 433 | int paused, count; |
434 | volatile uint32_t *paused_at = dev_priv->last_pause_ptr; | 434 | volatile uint32_t *paused_at = dev_priv->last_pause_ptr; |
435 | uint32_t reader,ptr; | ||
435 | 436 | ||
437 | paused = 0; | ||
436 | via_flush_write_combine(); | 438 | via_flush_write_combine(); |
437 | while (!*(via_get_dma(dev_priv) - 1)) ; | 439 | (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); |
438 | *dev_priv->last_pause_ptr = pause_addr_lo; | 440 | *paused_at = pause_addr_lo; |
439 | via_flush_write_combine(); | 441 | via_flush_write_combine(); |
440 | 442 | (void) *paused_at; | |
441 | /* | 443 | reader = *(dev_priv->hw_addr_ptr); |
442 | * The below statement is inserted to really force the flush. | 444 | ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + |
443 | * Not sure it is needed. | 445 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; |
444 | */ | ||
445 | |||
446 | while (!*dev_priv->last_pause_ptr) ; | ||
447 | dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; | 446 | dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; |
448 | while (!*dev_priv->last_pause_ptr) ; | ||
449 | 447 | ||
450 | paused = 0; | 448 | if ((ptr - reader) <= dev_priv->dma_diff ) { |
451 | count = 20; | 449 | count = 10000000; |
452 | 450 | while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--); | |
453 | while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ; | ||
454 | if ((count <= 8) && (count >= 0)) { | ||
455 | uint32_t rgtr, ptr; | ||
456 | rgtr = *(dev_priv->hw_addr_ptr); | ||
457 | ptr = ((volatile char *)dev_priv->last_pause_ptr - | ||
458 | dev_priv->dma_ptr) + dev_priv->dma_offset + | ||
459 | (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE; | ||
460 | if (rgtr <= ptr) { | ||
461 | DRM_ERROR | ||
462 | ("Command regulator\npaused at count %d, address %x, " | ||
463 | "while current pause address is %x.\n" | ||
464 | "Please mail this message to " | ||
465 | "<unichrome-devel@lists.sourceforge.net>\n", count, | ||
466 | rgtr, ptr); | ||
467 | } | ||
468 | } | 451 | } |
469 | 452 | ||
470 | if (paused && !no_pci_fire) { | 453 | if (paused && !no_pci_fire) { |
471 | uint32_t rgtr, ptr; | 454 | reader = *(dev_priv->hw_addr_ptr); |
472 | uint32_t ptr_low; | 455 | if ((ptr - reader) == dev_priv->dma_diff) { |
473 | 456 | ||
474 | count = 1000000; | 457 | /* |
475 | while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) | 458 | * There is a concern that these writes may stall the PCI bus |
476 | && count--) ; | 459 | * if the GPU is not idle. However, idling the GPU first |
460 | * doesn't make a difference. | ||
461 | */ | ||
477 | 462 | ||
478 | rgtr = *(dev_priv->hw_addr_ptr); | ||
479 | ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + | ||
480 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; | ||
481 | |||
482 | ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? | ||
483 | ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0; | ||
484 | if (rgtr <= ptr && rgtr >= ptr_low) { | ||
485 | VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); | 463 | VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); |
486 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); | 464 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); |
487 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); | 465 | VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); |
@@ -494,6 +472,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
494 | static int via_wait_idle(drm_via_private_t * dev_priv) | 472 | static int via_wait_idle(drm_via_private_t * dev_priv) |
495 | { | 473 | { |
496 | int count = 10000000; | 474 | int count = 10000000; |
475 | |||
476 | while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--); | ||
477 | |||
497 | while (count-- && (VIA_READ(VIA_REG_STATUS) & | 478 | while (count-- && (VIA_READ(VIA_REG_STATUS) & |
498 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | | 479 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | |
499 | VIA_3D_ENG_BUSY))) ; | 480 | VIA_3D_ENG_BUSY))) ; |
@@ -537,6 +518,9 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) | |||
537 | uint32_t end_addr, end_addr_lo; | 518 | uint32_t end_addr, end_addr_lo; |
538 | uint32_t command; | 519 | uint32_t command; |
539 | uint32_t agp_base; | 520 | uint32_t agp_base; |
521 | uint32_t ptr; | ||
522 | uint32_t reader; | ||
523 | int count; | ||
540 | 524 | ||
541 | dev_priv->dma_low = 0; | 525 | dev_priv->dma_low = 0; |
542 | 526 | ||
@@ -554,7 +538,7 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) | |||
554 | &pause_addr_hi, &pause_addr_lo, 1) - 1; | 538 | &pause_addr_hi, &pause_addr_lo, 1) - 1; |
555 | 539 | ||
556 | via_flush_write_combine(); | 540 | via_flush_write_combine(); |
557 | while (!*dev_priv->last_pause_ptr) ; | 541 | (void) *(volatile uint32_t *)dev_priv->last_pause_ptr; |
558 | 542 | ||
559 | VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); | 543 | VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); |
560 | VIA_WRITE(VIA_REG_TRANSPACE, command); | 544 | VIA_WRITE(VIA_REG_TRANSPACE, command); |
@@ -566,6 +550,24 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) | |||
566 | DRM_WRITEMEMORYBARRIER(); | 550 | DRM_WRITEMEMORYBARRIER(); |
567 | VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); | 551 | VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); |
568 | VIA_READ(VIA_REG_TRANSPACE); | 552 | VIA_READ(VIA_REG_TRANSPACE); |
553 | |||
554 | dev_priv->dma_diff = 0; | ||
555 | |||
556 | count = 10000000; | ||
557 | while (!(VIA_READ(0x41c) & 0x80000000) && count--); | ||
558 | |||
559 | reader = *(dev_priv->hw_addr_ptr); | ||
560 | ptr = ((volatile char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + | ||
561 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; | ||
562 | |||
563 | /* | ||
564 | * This is the difference between where we tell the | ||
565 | * command reader to pause and where it actually pauses. | ||
566 | * This differs between hw implementation so we need to | ||
567 | * detect it. | ||
568 | */ | ||
569 | |||
570 | dev_priv->dma_diff = ptr - reader; | ||
569 | } | 571 | } |
570 | 572 | ||
571 | static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) | 573 | static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) |
@@ -592,7 +594,6 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | |||
592 | uint32_t pause_addr_lo, pause_addr_hi; | 594 | uint32_t pause_addr_lo, pause_addr_hi; |
593 | uint32_t jump_addr_lo, jump_addr_hi; | 595 | uint32_t jump_addr_lo, jump_addr_hi; |
594 | volatile uint32_t *last_pause_ptr; | 596 | volatile uint32_t *last_pause_ptr; |
595 | uint32_t dma_low_save1, dma_low_save2; | ||
596 | 597 | ||
597 | agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; | 598 | agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; |
598 | via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, | 599 | via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, |
@@ -619,31 +620,11 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | |||
619 | &pause_addr_lo, 0); | 620 | &pause_addr_lo, 0); |
620 | 621 | ||
621 | *last_pause_ptr = pause_addr_lo; | 622 | *last_pause_ptr = pause_addr_lo; |
622 | dma_low_save1 = dev_priv->dma_low; | ||
623 | |||
624 | /* | ||
625 | * Now, set a trap that will pause the regulator if it tries to rerun the old | ||
626 | * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause | ||
627 | * and reissues the jump command over PCI, while the regulator has already taken the jump | ||
628 | * and actually paused at the current buffer end). | ||
629 | * There appears to be no other way to detect this condition, since the hw_addr_pointer | ||
630 | * does not seem to get updated immediately when a jump occurs. | ||
631 | */ | ||
632 | 623 | ||
633 | last_pause_ptr = | 624 | via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0); |
634 | via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, | ||
635 | &pause_addr_lo, 0) - 1; | ||
636 | via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, | ||
637 | &pause_addr_lo, 0); | ||
638 | *last_pause_ptr = pause_addr_lo; | ||
639 | |||
640 | dma_low_save2 = dev_priv->dma_low; | ||
641 | dev_priv->dma_low = dma_low_save1; | ||
642 | via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0); | ||
643 | dev_priv->dma_low = dma_low_save2; | ||
644 | via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); | ||
645 | } | 625 | } |
646 | 626 | ||
627 | |||
647 | static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) | 628 | static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) |
648 | { | 629 | { |
649 | via_cmdbuf_jump(dev_priv); | 630 | via_cmdbuf_jump(dev_priv); |
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index 8b8778d4a423..b46ca8e6306d 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h | |||
@@ -29,11 +29,11 @@ | |||
29 | 29 | ||
30 | #define DRIVER_NAME "via" | 30 | #define DRIVER_NAME "via" |
31 | #define DRIVER_DESC "VIA Unichrome / Pro" | 31 | #define DRIVER_DESC "VIA Unichrome / Pro" |
32 | #define DRIVER_DATE "20061227" | 32 | #define DRIVER_DATE "20070202" |
33 | 33 | ||
34 | #define DRIVER_MAJOR 2 | 34 | #define DRIVER_MAJOR 2 |
35 | #define DRIVER_MINOR 11 | 35 | #define DRIVER_MINOR 11 |
36 | #define DRIVER_PATCHLEVEL 0 | 36 | #define DRIVER_PATCHLEVEL 1 |
37 | 37 | ||
38 | #include "via_verifier.h" | 38 | #include "via_verifier.h" |
39 | 39 | ||
@@ -93,6 +93,7 @@ typedef struct drm_via_private { | |||
93 | unsigned long vram_offset; | 93 | unsigned long vram_offset; |
94 | unsigned long agp_offset; | 94 | unsigned long agp_offset; |
95 | drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; | 95 | drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; |
96 | uint32_t dma_diff; | ||
96 | } drm_via_private_t; | 97 | } drm_via_private_t; |
97 | 98 | ||
98 | enum via_family { | 99 | enum via_family { |