diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:52:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:52:35 -0400 |
| commit | 5335a40be6867eff986a31bcd8fc82a5cb1e16bb (patch) | |
| tree | b32be59c2a2679a5cc3fef172006886f7dcd2466 | |
| parent | 393bfca19ecdce60a8d9a4d2577cac11ca924a25 (diff) | |
| parent | ef68d295508d52e792abf70d4f84461104d33b9d (diff) | |
Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6:
via: Make sure we flush write-combining using a follow-up read.
via: Try to improve command-buffer chaining.
drm: remove old taskqueue remnant
drm: rename badly named define and cleanup ioctl code spacing
radeon: Don't mess up page flipping when a file descriptor is closed.
drm/radeon: upgrade to 1.27 - make PCI GART more flexible
| -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 { |
