diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-19 20:48:51 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-19 20:48:51 -0500 |
| commit | 3a93dc42f56c507d1034273d1e1d6f9b3ad94bb1 (patch) | |
| tree | 3c6823777978ac06bb99a4225b30f10cb7c55938 | |
| parent | cf8c0d1dbcfaba56adde85b63190a8bceda0cd04 (diff) | |
| parent | feac7af508ebdfe1db9920d4e45d0ffd286abe75 (diff) | |
Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm/sis: add pciid for SiS 662/671 chipset
drm: add new rv380 pciid
drm: add support for passing state into the suspend hooks.
drm/i915: Fix hibernate save/restore of VGA attribute regs
drm/i915 more registers for S3 (DSPCLK_GATE_D, CACHE_MODE_0, MI_ARB_STATE)
drm/i915: restore pipeconf regs unconditionally
drm/i915: save/restore interrupt state
drm: convert drm from nopage to fault.
i915: wrap chipset types requiring hw status set ioctl
drm/radeon: add initial rs690 support to drm.
| -rw-r--r-- | drivers/char/drm/drmP.h | 2 | ||||
| -rw-r--r-- | drivers/char/drm/drm_pciids.h | 3 | ||||
| -rw-r--r-- | drivers/char/drm/drm_sysfs.c | 2 | ||||
| -rw-r--r-- | drivers/char/drm/drm_vm.c | 125 | ||||
| -rw-r--r-- | drivers/char/drm/i915_dma.c | 5 | ||||
| -rw-r--r-- | drivers/char/drm/i915_drv.c | 51 | ||||
| -rw-r--r-- | drivers/char/drm/i915_drv.h | 17 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_cp.c | 81 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drv.h | 38 |
9 files changed, 240 insertions, 84 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 19d3be5c4b2d..a6789f25009b 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
| @@ -568,7 +568,7 @@ struct drm_driver { | |||
| 568 | void (*postclose) (struct drm_device *, struct drm_file *); | 568 | void (*postclose) (struct drm_device *, struct drm_file *); |
| 569 | void (*lastclose) (struct drm_device *); | 569 | void (*lastclose) (struct drm_device *); |
| 570 | int (*unload) (struct drm_device *); | 570 | int (*unload) (struct drm_device *); |
| 571 | int (*suspend) (struct drm_device *); | 571 | int (*suspend) (struct drm_device *, pm_message_t state); |
| 572 | int (*resume) (struct drm_device *); | 572 | int (*resume) (struct drm_device *); |
| 573 | int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); | 573 | int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); |
| 574 | void (*dma_ready) (struct drm_device *); | 574 | void (*dma_ready) (struct drm_device *); |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index f52468843678..715b361f0c2b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
| @@ -83,6 +83,7 @@ | |||
| 83 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 83 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
| 84 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 84 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
| 85 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 85 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
| 86 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | ||
| 86 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 87 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
| 87 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 88 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
| 88 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 89 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
| @@ -236,6 +237,7 @@ | |||
| 236 | {0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ | 237 | {0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ |
| 237 | {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ | 238 | {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ |
| 238 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 239 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
| 240 | {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | ||
| 239 | {0, 0, 0} | 241 | {0, 0, 0} |
| 240 | 242 | ||
| 241 | #define r128_PCI_IDS \ | 243 | #define r128_PCI_IDS \ |
| @@ -313,6 +315,7 @@ | |||
| 313 | {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 315 | {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 314 | {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 316 | {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 315 | {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ | 317 | {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ |
| 318 | {0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 316 | {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 319 | {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 317 | {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ | 320 | {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ |
| 318 | {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ | 321 | {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index fa36153619e8..05ed5043254f 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
| @@ -36,7 +36,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
| 36 | printk(KERN_ERR "%s\n", __FUNCTION__); | 36 | printk(KERN_ERR "%s\n", __FUNCTION__); |
| 37 | 37 | ||
| 38 | if (drm_dev->driver->suspend) | 38 | if (drm_dev->driver->suspend) |
| 39 | return drm_dev->driver->suspend(drm_dev); | 39 | return drm_dev->driver->suspend(drm_dev, state); |
| 40 | 40 | ||
| 41 | return 0; | 41 | return 0; |
| 42 | } | 42 | } |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index cea4105374b2..3d65c4dcd0c6 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
| @@ -66,7 +66,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | /** | 68 | /** |
| 69 | * \c nopage method for AGP virtual memory. | 69 | * \c fault method for AGP virtual memory. |
| 70 | * | 70 | * |
| 71 | * \param vma virtual memory area. | 71 | * \param vma virtual memory area. |
| 72 | * \param address access address. | 72 | * \param address access address. |
| @@ -76,8 +76,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) | |||
| 76 | * map, get the page, increment the use count and return it. | 76 | * map, get the page, increment the use count and return it. |
| 77 | */ | 77 | */ |
| 78 | #if __OS_HAS_AGP | 78 | #if __OS_HAS_AGP |
| 79 | static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | 79 | static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 80 | unsigned long address) | ||
| 81 | { | 80 | { |
| 82 | struct drm_file *priv = vma->vm_file->private_data; | 81 | struct drm_file *priv = vma->vm_file->private_data; |
| 83 | struct drm_device *dev = priv->head->dev; | 82 | struct drm_device *dev = priv->head->dev; |
| @@ -89,19 +88,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | |||
| 89 | * Find the right map | 88 | * Find the right map |
| 90 | */ | 89 | */ |
| 91 | if (!drm_core_has_AGP(dev)) | 90 | if (!drm_core_has_AGP(dev)) |
| 92 | goto vm_nopage_error; | 91 | goto vm_fault_error; |
| 93 | 92 | ||
| 94 | if (!dev->agp || !dev->agp->cant_use_aperture) | 93 | if (!dev->agp || !dev->agp->cant_use_aperture) |
| 95 | goto vm_nopage_error; | 94 | goto vm_fault_error; |
| 96 | 95 | ||
| 97 | if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) | 96 | if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) |
| 98 | goto vm_nopage_error; | 97 | goto vm_fault_error; |
| 99 | 98 | ||
| 100 | r_list = drm_hash_entry(hash, struct drm_map_list, hash); | 99 | r_list = drm_hash_entry(hash, struct drm_map_list, hash); |
| 101 | map = r_list->map; | 100 | map = r_list->map; |
| 102 | 101 | ||
| 103 | if (map && map->type == _DRM_AGP) { | 102 | if (map && map->type == _DRM_AGP) { |
| 104 | unsigned long offset = address - vma->vm_start; | 103 | /* |
| 104 | * Using vm_pgoff as a selector forces us to use this unusual | ||
| 105 | * addressing scheme. | ||
| 106 | */ | ||
| 107 | unsigned long offset = (unsigned long)vmf->virtual_address - | ||
| 108 | vma->vm_start; | ||
| 105 | unsigned long baddr = map->offset + offset; | 109 | unsigned long baddr = map->offset + offset; |
| 106 | struct drm_agp_mem *agpmem; | 110 | struct drm_agp_mem *agpmem; |
| 107 | struct page *page; | 111 | struct page *page; |
| @@ -123,7 +127,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | |||
| 123 | } | 127 | } |
| 124 | 128 | ||
| 125 | if (!agpmem) | 129 | if (!agpmem) |
| 126 | goto vm_nopage_error; | 130 | goto vm_fault_error; |
| 127 | 131 | ||
| 128 | /* | 132 | /* |
| 129 | * Get the page, inc the use count, and return it | 133 | * Get the page, inc the use count, and return it |
| @@ -131,22 +135,21 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | |||
| 131 | offset = (baddr - agpmem->bound) >> PAGE_SHIFT; | 135 | offset = (baddr - agpmem->bound) >> PAGE_SHIFT; |
| 132 | page = virt_to_page(__va(agpmem->memory->memory[offset])); | 136 | page = virt_to_page(__va(agpmem->memory->memory[offset])); |
| 133 | get_page(page); | 137 | get_page(page); |
| 138 | vmf->page = page; | ||
| 134 | 139 | ||
| 135 | DRM_DEBUG | 140 | DRM_DEBUG |
| 136 | ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", | 141 | ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", |
| 137 | baddr, __va(agpmem->memory->memory[offset]), offset, | 142 | baddr, __va(agpmem->memory->memory[offset]), offset, |
| 138 | page_count(page)); | 143 | page_count(page)); |
| 139 | 144 | return 0; | |
| 140 | return page; | ||
| 141 | } | 145 | } |
| 142 | vm_nopage_error: | 146 | vm_fault_error: |
| 143 | return NOPAGE_SIGBUS; /* Disallow mremap */ | 147 | return VM_FAULT_SIGBUS; /* Disallow mremap */ |
| 144 | } | 148 | } |
| 145 | #else /* __OS_HAS_AGP */ | 149 | #else /* __OS_HAS_AGP */ |
| 146 | static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | 150 | static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 147 | unsigned long address) | ||
| 148 | { | 151 | { |
| 149 | return NOPAGE_SIGBUS; | 152 | return VM_FAULT_SIGBUS; |
| 150 | } | 153 | } |
| 151 | #endif /* __OS_HAS_AGP */ | 154 | #endif /* __OS_HAS_AGP */ |
| 152 | 155 | ||
| @@ -160,28 +163,26 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, | |||
| 160 | * Get the mapping, find the real physical page to map, get the page, and | 163 | * Get the mapping, find the real physical page to map, get the page, and |
| 161 | * return it. | 164 | * return it. |
| 162 | */ | 165 | */ |
| 163 | static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, | 166 | static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 164 | unsigned long address) | ||
| 165 | { | 167 | { |
| 166 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; | 168 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; |
| 167 | unsigned long offset; | 169 | unsigned long offset; |
| 168 | unsigned long i; | 170 | unsigned long i; |
| 169 | struct page *page; | 171 | struct page *page; |
| 170 | 172 | ||
| 171 | if (address > vma->vm_end) | ||
| 172 | return NOPAGE_SIGBUS; /* Disallow mremap */ | ||
| 173 | if (!map) | 173 | if (!map) |
| 174 | return NOPAGE_SIGBUS; /* Nothing allocated */ | 174 | return VM_FAULT_SIGBUS; /* Nothing allocated */ |
| 175 | 175 | ||
| 176 | offset = address - vma->vm_start; | 176 | offset = (unsigned long)vmf->virtual_address - vma->vm_start; |
| 177 | i = (unsigned long)map->handle + offset; | 177 | i = (unsigned long)map->handle + offset; |
| 178 | page = vmalloc_to_page((void *)i); | 178 | page = vmalloc_to_page((void *)i); |
| 179 | if (!page) | 179 | if (!page) |
| 180 | return NOPAGE_SIGBUS; | 180 | return VM_FAULT_SIGBUS; |
| 181 | get_page(page); | 181 | get_page(page); |
| 182 | vmf->page = page; | ||
| 182 | 183 | ||
| 183 | DRM_DEBUG("0x%lx\n", address); | 184 | DRM_DEBUG("shm_fault 0x%lx\n", offset); |
| 184 | return page; | 185 | return 0; |
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | /** | 188 | /** |
| @@ -263,7 +264,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
| 263 | } | 264 | } |
| 264 | 265 | ||
| 265 | /** | 266 | /** |
| 266 | * \c nopage method for DMA virtual memory. | 267 | * \c fault method for DMA virtual memory. |
| 267 | * | 268 | * |
| 268 | * \param vma virtual memory area. | 269 | * \param vma virtual memory area. |
| 269 | * \param address access address. | 270 | * \param address access address. |
| @@ -271,8 +272,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
| 271 | * | 272 | * |
| 272 | * Determine the page number from the page offset and get it from drm_device_dma::pagelist. | 273 | * Determine the page number from the page offset and get it from drm_device_dma::pagelist. |
| 273 | */ | 274 | */ |
| 274 | static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, | 275 | static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 275 | unsigned long address) | ||
| 276 | { | 276 | { |
| 277 | struct drm_file *priv = vma->vm_file->private_data; | 277 | struct drm_file *priv = vma->vm_file->private_data; |
| 278 | struct drm_device *dev = priv->head->dev; | 278 | struct drm_device *dev = priv->head->dev; |
| @@ -282,24 +282,23 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, | |||
| 282 | struct page *page; | 282 | struct page *page; |
| 283 | 283 | ||
| 284 | if (!dma) | 284 | if (!dma) |
| 285 | return NOPAGE_SIGBUS; /* Error */ | 285 | return VM_FAULT_SIGBUS; /* Error */ |
| 286 | if (address > vma->vm_end) | ||
| 287 | return NOPAGE_SIGBUS; /* Disallow mremap */ | ||
| 288 | if (!dma->pagelist) | 286 | if (!dma->pagelist) |
| 289 | return NOPAGE_SIGBUS; /* Nothing allocated */ | 287 | return VM_FAULT_SIGBUS; /* Nothing allocated */ |
| 290 | 288 | ||
| 291 | offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ | 289 | offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ |
| 292 | page_nr = offset >> PAGE_SHIFT; | 290 | page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */ |
| 293 | page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK)))); | 291 | page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK)))); |
| 294 | 292 | ||
| 295 | get_page(page); | 293 | get_page(page); |
| 294 | vmf->page = page; | ||
| 296 | 295 | ||
| 297 | DRM_DEBUG("0x%lx (page %lu)\n", address, page_nr); | 296 | DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr); |
| 298 | return page; | 297 | return 0; |
| 299 | } | 298 | } |
| 300 | 299 | ||
| 301 | /** | 300 | /** |
| 302 | * \c nopage method for scatter-gather virtual memory. | 301 | * \c fault method for scatter-gather virtual memory. |
| 303 | * | 302 | * |
| 304 | * \param vma virtual memory area. | 303 | * \param vma virtual memory area. |
| 305 | * \param address access address. | 304 | * \param address access address. |
| @@ -307,8 +306,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, | |||
| 307 | * | 306 | * |
| 308 | * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. | 307 | * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. |
| 309 | */ | 308 | */ |
| 310 | static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, | 309 | static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 311 | unsigned long address) | ||
| 312 | { | 310 | { |
| 313 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; | 311 | struct drm_map *map = (struct drm_map *) vma->vm_private_data; |
| 314 | struct drm_file *priv = vma->vm_file->private_data; | 312 | struct drm_file *priv = vma->vm_file->private_data; |
| @@ -320,77 +318,64 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, | |||
| 320 | struct page *page; | 318 | struct page *page; |
| 321 | 319 | ||
| 322 | if (!entry) | 320 | if (!entry) |
| 323 | return NOPAGE_SIGBUS; /* Error */ | 321 | return VM_FAULT_SIGBUS; /* Error */ |
| 324 | if (address > vma->vm_end) | ||
| 325 | return NOPAGE_SIGBUS; /* Disallow mremap */ | ||
| 326 | if (!entry->pagelist) | 322 | if (!entry->pagelist) |
| 327 | return NOPAGE_SIGBUS; /* Nothing allocated */ | 323 | return VM_FAULT_SIGBUS; /* Nothing allocated */ |
| 328 | 324 | ||
| 329 | offset = address - vma->vm_start; | 325 | offset = (unsigned long)vmf->virtual_address - vma->vm_start; |
| 330 | map_offset = map->offset - (unsigned long)dev->sg->virtual; | 326 | map_offset = map->offset - (unsigned long)dev->sg->virtual; |
| 331 | page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); | 327 | page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); |
| 332 | page = entry->pagelist[page_offset]; | 328 | page = entry->pagelist[page_offset]; |
| 333 | get_page(page); | 329 | get_page(page); |
| 330 | vmf->page = page; | ||
| 334 | 331 | ||
| 335 | return page; | 332 | return 0; |
| 336 | } | 333 | } |
| 337 | 334 | ||
| 338 | static struct page *drm_vm_nopage(struct vm_area_struct *vma, | 335 | static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 339 | unsigned long address, int *type) | ||
| 340 | { | 336 | { |
| 341 | if (type) | 337 | return drm_do_vm_fault(vma, vmf); |
| 342 | *type = VM_FAULT_MINOR; | ||
| 343 | return drm_do_vm_nopage(vma, address); | ||
| 344 | } | 338 | } |
| 345 | 339 | ||
| 346 | static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, | 340 | static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 347 | unsigned long address, int *type) | ||
| 348 | { | 341 | { |
| 349 | if (type) | 342 | return drm_do_vm_shm_fault(vma, vmf); |
| 350 | *type = VM_FAULT_MINOR; | ||
| 351 | return drm_do_vm_shm_nopage(vma, address); | ||
| 352 | } | 343 | } |
| 353 | 344 | ||
| 354 | static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, | 345 | static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 355 | unsigned long address, int *type) | ||
| 356 | { | 346 | { |
| 357 | if (type) | 347 | return drm_do_vm_dma_fault(vma, vmf); |
| 358 | *type = VM_FAULT_MINOR; | ||
| 359 | return drm_do_vm_dma_nopage(vma, address); | ||
| 360 | } | 348 | } |
| 361 | 349 | ||
| 362 | static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, | 350 | static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
| 363 | unsigned long address, int *type) | ||
| 364 | { | 351 | { |
| 365 | if (type) | 352 | return drm_do_vm_sg_fault(vma, vmf); |
| 366 | *type = VM_FAULT_MINOR; | ||
| 367 | return drm_do_vm_sg_nopage(vma, address); | ||
| 368 | } | 353 | } |
| 369 | 354 | ||
| 370 | /** AGP virtual memory operations */ | 355 | /** AGP virtual memory operations */ |
| 371 | static struct vm_operations_struct drm_vm_ops = { | 356 | static struct vm_operations_struct drm_vm_ops = { |
| 372 | .nopage = drm_vm_nopage, | 357 | .fault = drm_vm_fault, |
| 373 | .open = drm_vm_open, | 358 | .open = drm_vm_open, |
| 374 | .close = drm_vm_close, | 359 | .close = drm_vm_close, |
| 375 | }; | 360 | }; |
| 376 | 361 | ||
| 377 | /** Shared virtual memory operations */ | 362 | /** Shared virtual memory operations */ |
| 378 | static struct vm_operations_struct drm_vm_shm_ops = { | 363 | static struct vm_operations_struct drm_vm_shm_ops = { |
| 379 | .nopage = drm_vm_shm_nopage, | 364 | .fault = drm_vm_shm_fault, |
| 380 | .open = drm_vm_open, | 365 | .open = drm_vm_open, |
| 381 | .close = drm_vm_shm_close, | 366 | .close = drm_vm_shm_close, |
| 382 | }; | 367 | }; |
| 383 | 368 | ||
| 384 | /** DMA virtual memory operations */ | 369 | /** DMA virtual memory operations */ |
| 385 | static struct vm_operations_struct drm_vm_dma_ops = { | 370 | static struct vm_operations_struct drm_vm_dma_ops = { |
| 386 | .nopage = drm_vm_dma_nopage, | 371 | .fault = drm_vm_dma_fault, |
| 387 | .open = drm_vm_open, | 372 | .open = drm_vm_open, |
| 388 | .close = drm_vm_close, | 373 | .close = drm_vm_close, |
| 389 | }; | 374 | }; |
| 390 | 375 | ||
| 391 | /** Scatter-gather virtual memory operations */ | 376 | /** Scatter-gather virtual memory operations */ |
| 392 | static struct vm_operations_struct drm_vm_sg_ops = { | 377 | static struct vm_operations_struct drm_vm_sg_ops = { |
| 393 | .nopage = drm_vm_sg_nopage, | 378 | .fault = drm_vm_sg_fault, |
| 394 | .open = drm_vm_open, | 379 | .open = drm_vm_open, |
| 395 | .close = drm_vm_close, | 380 | .close = drm_vm_close, |
| 396 | }; | 381 | }; |
| @@ -604,7 +589,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
| 604 | /* | 589 | /* |
| 605 | * On some platforms we can't talk to bus dma address from the CPU, so for | 590 | * On some platforms we can't talk to bus dma address from the CPU, so for |
| 606 | * memory of type DRM_AGP, we'll deal with sorting out the real physical | 591 | * memory of type DRM_AGP, we'll deal with sorting out the real physical |
| 607 | * pages and mappings in nopage() | 592 | * pages and mappings in fault() |
| 608 | */ | 593 | */ |
| 609 | #if defined(__powerpc__) | 594 | #if defined(__powerpc__) |
| 610 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; | 595 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; |
| @@ -634,7 +619,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
| 634 | break; | 619 | break; |
| 635 | case _DRM_CONSISTENT: | 620 | case _DRM_CONSISTENT: |
| 636 | /* Consistent memory is really like shared memory. But | 621 | /* Consistent memory is really like shared memory. But |
| 637 | * it's allocated in a different way, so avoid nopage */ | 622 | * it's allocated in a different way, so avoid fault */ |
| 638 | if (remap_pfn_range(vma, vma->vm_start, | 623 | if (remap_pfn_range(vma, vma->vm_start, |
| 639 | page_to_pfn(virt_to_page(map->handle)), | 624 | page_to_pfn(virt_to_page(map->handle)), |
| 640 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 625 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 43986d81ae34..e9d6663bec73 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
| @@ -171,7 +171,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
| 171 | dev_priv->allow_batchbuffer = 1; | 171 | dev_priv->allow_batchbuffer = 1; |
| 172 | 172 | ||
| 173 | /* Program Hardware Status Page */ | 173 | /* Program Hardware Status Page */ |
| 174 | if (!IS_G33(dev)) { | 174 | if (!I915_NEED_GFX_HWS(dev)) { |
| 175 | dev_priv->status_page_dmah = | 175 | dev_priv->status_page_dmah = |
| 176 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); | 176 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); |
| 177 | 177 | ||
| @@ -720,6 +720,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
| 720 | drm_i915_private_t *dev_priv = dev->dev_private; | 720 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 721 | drm_i915_hws_addr_t *hws = data; | 721 | drm_i915_hws_addr_t *hws = data; |
| 722 | 722 | ||
| 723 | if (!I915_NEED_GFX_HWS(dev)) | ||
| 724 | return -EINVAL; | ||
| 725 | |||
| 723 | if (!dev_priv) { | 726 | if (!dev_priv) { |
| 724 | DRM_ERROR("called with no initialization\n"); | 727 | DRM_ERROR("called with no initialization\n"); |
| 725 | return -EINVAL; | 728 | return -EINVAL; |
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 52e51033d32c..4048f39b7eed 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c | |||
| @@ -160,6 +160,7 @@ static void i915_save_vga(struct drm_device *dev) | |||
| 160 | dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); | 160 | dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); |
| 161 | inb(st01); | 161 | inb(st01); |
| 162 | outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); | 162 | outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); |
| 163 | inb(st01); | ||
| 163 | 164 | ||
| 164 | /* Graphics controller registers */ | 165 | /* Graphics controller registers */ |
| 165 | for (i = 0; i < 9; i++) | 166 | for (i = 0; i < 9; i++) |
| @@ -225,6 +226,7 @@ static void i915_restore_vga(struct drm_device *dev) | |||
| 225 | i915_write_ar(st01, i, dev_priv->saveAR[i], 0); | 226 | i915_write_ar(st01, i, dev_priv->saveAR[i], 0); |
| 226 | inb(st01); /* switch back to index mode */ | 227 | inb(st01); /* switch back to index mode */ |
| 227 | outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); | 228 | outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); |
| 229 | inb(st01); | ||
| 228 | 230 | ||
| 229 | /* VGA color palette registers */ | 231 | /* VGA color palette registers */ |
| 230 | outb(dev_priv->saveDACMASK, VGA_DACMASK); | 232 | outb(dev_priv->saveDACMASK, VGA_DACMASK); |
| @@ -236,7 +238,7 @@ static void i915_restore_vga(struct drm_device *dev) | |||
| 236 | 238 | ||
| 237 | } | 239 | } |
| 238 | 240 | ||
| 239 | static int i915_suspend(struct drm_device *dev) | 241 | static int i915_suspend(struct drm_device *dev, pm_message_t state) |
| 240 | { | 242 | { |
| 241 | struct drm_i915_private *dev_priv = dev->dev_private; | 243 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 242 | int i; | 244 | int i; |
| @@ -247,6 +249,9 @@ static int i915_suspend(struct drm_device *dev) | |||
| 247 | return -ENODEV; | 249 | return -ENODEV; |
| 248 | } | 250 | } |
| 249 | 251 | ||
| 252 | if (state.event == PM_EVENT_PRETHAW) | ||
| 253 | return 0; | ||
| 254 | |||
| 250 | pci_save_state(dev->pdev); | 255 | pci_save_state(dev->pdev); |
| 251 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 256 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
| 252 | 257 | ||
| @@ -276,6 +281,7 @@ static int i915_suspend(struct drm_device *dev) | |||
| 276 | dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); | 281 | dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); |
| 277 | } | 282 | } |
| 278 | i915_save_palette(dev, PIPE_A); | 283 | i915_save_palette(dev, PIPE_A); |
| 284 | dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); | ||
| 279 | 285 | ||
| 280 | /* Pipe & plane B info */ | 286 | /* Pipe & plane B info */ |
| 281 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | 287 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); |
| @@ -303,6 +309,7 @@ static int i915_suspend(struct drm_device *dev) | |||
| 303 | dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); | 309 | dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); |
| 304 | } | 310 | } |
| 305 | i915_save_palette(dev, PIPE_B); | 311 | i915_save_palette(dev, PIPE_B); |
| 312 | dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); | ||
| 306 | 313 | ||
| 307 | /* CRT state */ | 314 | /* CRT state */ |
| 308 | dev_priv->saveADPA = I915_READ(ADPA); | 315 | dev_priv->saveADPA = I915_READ(ADPA); |
| @@ -329,12 +336,26 @@ static int i915_suspend(struct drm_device *dev) | |||
| 329 | dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); | 336 | dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); |
| 330 | dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | 337 | dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); |
| 331 | 338 | ||
| 339 | /* Interrupt state */ | ||
| 340 | dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); | ||
| 341 | dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); | ||
| 342 | dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); | ||
| 343 | |||
| 332 | /* VGA state */ | 344 | /* VGA state */ |
| 333 | dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); | 345 | dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); |
| 334 | dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); | 346 | dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); |
| 335 | dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); | 347 | dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); |
| 336 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 348 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
| 337 | 349 | ||
| 350 | /* Clock gating state */ | ||
| 351 | dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); | ||
| 352 | |||
| 353 | /* Cache mode state */ | ||
| 354 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | ||
| 355 | |||
| 356 | /* Memory Arbitration state */ | ||
| 357 | dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); | ||
| 358 | |||
| 338 | /* Scratch space */ | 359 | /* Scratch space */ |
| 339 | for (i = 0; i < 16; i++) { | 360 | for (i = 0; i < 16; i++) { |
| 340 | dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); | 361 | dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); |
| @@ -345,9 +366,11 @@ static int i915_suspend(struct drm_device *dev) | |||
| 345 | 366 | ||
| 346 | i915_save_vga(dev); | 367 | i915_save_vga(dev); |
| 347 | 368 | ||
| 348 | /* Shut down the device */ | 369 | if (state.event == PM_EVENT_SUSPEND) { |
| 349 | pci_disable_device(dev->pdev); | 370 | /* Shut down the device */ |
| 350 | pci_set_power_state(dev->pdev, PCI_D3hot); | 371 | pci_disable_device(dev->pdev); |
| 372 | pci_set_power_state(dev->pdev, PCI_D3hot); | ||
| 373 | } | ||
| 351 | 374 | ||
| 352 | return 0; | 375 | return 0; |
| 353 | } | 376 | } |
| @@ -400,9 +423,7 @@ static int i915_resume(struct drm_device *dev) | |||
| 400 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | 423 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); |
| 401 | } | 424 | } |
| 402 | 425 | ||
| 403 | if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) && | 426 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); |
| 404 | (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS)) | ||
| 405 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
| 406 | 427 | ||
| 407 | i915_restore_palette(dev, PIPE_A); | 428 | i915_restore_palette(dev, PIPE_A); |
| 408 | /* Enable the plane */ | 429 | /* Enable the plane */ |
| @@ -444,10 +465,9 @@ static int i915_resume(struct drm_device *dev) | |||
| 444 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | 465 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); |
| 445 | } | 466 | } |
| 446 | 467 | ||
| 447 | if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) && | 468 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); |
| 448 | (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS)) | 469 | |
| 449 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | 470 | i915_restore_palette(dev, PIPE_B); |
| 450 | i915_restore_palette(dev, PIPE_A); | ||
| 451 | /* Enable the plane */ | 471 | /* Enable the plane */ |
| 452 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | 472 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); |
| 453 | I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); | 473 | I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); |
| @@ -485,6 +505,15 @@ static int i915_resume(struct drm_device *dev) | |||
| 485 | I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); | 505 | I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); |
| 486 | udelay(150); | 506 | udelay(150); |
| 487 | 507 | ||
| 508 | /* Clock gating state */ | ||
| 509 | I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); | ||
| 510 | |||
| 511 | /* Cache mode state */ | ||
| 512 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | ||
| 513 | |||
| 514 | /* Memory arbitration state */ | ||
| 515 | I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); | ||
| 516 | |||
| 488 | for (i = 0; i < 16; i++) { | 517 | for (i = 0; i < 16; i++) { |
| 489 | I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); | 518 | I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); |
| 490 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | 519 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index f8308bfb2613..c10d128e34db 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
| @@ -134,6 +134,7 @@ typedef struct drm_i915_private { | |||
| 134 | u32 saveVBLANK_A; | 134 | u32 saveVBLANK_A; |
| 135 | u32 saveVSYNC_A; | 135 | u32 saveVSYNC_A; |
| 136 | u32 saveBCLRPAT_A; | 136 | u32 saveBCLRPAT_A; |
| 137 | u32 savePIPEASTAT; | ||
| 137 | u32 saveDSPASTRIDE; | 138 | u32 saveDSPASTRIDE; |
| 138 | u32 saveDSPASIZE; | 139 | u32 saveDSPASIZE; |
| 139 | u32 saveDSPAPOS; | 140 | u32 saveDSPAPOS; |
| @@ -154,6 +155,7 @@ typedef struct drm_i915_private { | |||
| 154 | u32 saveVBLANK_B; | 155 | u32 saveVBLANK_B; |
| 155 | u32 saveVSYNC_B; | 156 | u32 saveVSYNC_B; |
| 156 | u32 saveBCLRPAT_B; | 157 | u32 saveBCLRPAT_B; |
| 158 | u32 savePIPEBSTAT; | ||
| 157 | u32 saveDSPBSTRIDE; | 159 | u32 saveDSPBSTRIDE; |
| 158 | u32 saveDSPBSIZE; | 160 | u32 saveDSPBSIZE; |
| 159 | u32 saveDSPBPOS; | 161 | u32 saveDSPBPOS; |
| @@ -182,6 +184,12 @@ typedef struct drm_i915_private { | |||
| 182 | u32 saveFBC_LL_BASE; | 184 | u32 saveFBC_LL_BASE; |
| 183 | u32 saveFBC_CONTROL; | 185 | u32 saveFBC_CONTROL; |
| 184 | u32 saveFBC_CONTROL2; | 186 | u32 saveFBC_CONTROL2; |
| 187 | u32 saveIER; | ||
| 188 | u32 saveIIR; | ||
| 189 | u32 saveIMR; | ||
| 190 | u32 saveCACHE_MODE_0; | ||
| 191 | u32 saveDSPCLK_GATE_D; | ||
| 192 | u32 saveMI_ARB_STATE; | ||
| 185 | u32 saveSWF0[16]; | 193 | u32 saveSWF0[16]; |
| 186 | u32 saveSWF1[16]; | 194 | u32 saveSWF1[16]; |
| 187 | u32 saveSWF2[3]; | 195 | u32 saveSWF2[3]; |
| @@ -450,6 +458,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
| 450 | */ | 458 | */ |
| 451 | #define DMA_FADD_S 0x20d4 | 459 | #define DMA_FADD_S 0x20d4 |
| 452 | 460 | ||
| 461 | /* Memory Interface Arbitration State | ||
| 462 | */ | ||
| 463 | #define MI_ARB_STATE 0x20e4 | ||
| 464 | |||
| 453 | /* Cache mode 0 reg. | 465 | /* Cache mode 0 reg. |
| 454 | * - Manipulating render cache behaviour is central | 466 | * - Manipulating render cache behaviour is central |
| 455 | * to the concept of zone rendering, tuning this reg can help avoid | 467 | * to the concept of zone rendering, tuning this reg can help avoid |
| @@ -460,6 +472,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
| 460 | * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. | 472 | * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. |
| 461 | */ | 473 | */ |
| 462 | #define Cache_Mode_0 0x2120 | 474 | #define Cache_Mode_0 0x2120 |
| 475 | #define CACHE_MODE_0 0x2120 | ||
| 463 | #define CM0_MASK_SHIFT 16 | 476 | #define CM0_MASK_SHIFT 16 |
| 464 | #define CM0_IZ_OPT_DISABLE (1<<6) | 477 | #define CM0_IZ_OPT_DISABLE (1<<6) |
| 465 | #define CM0_ZR_OPT_DISABLE (1<<5) | 478 | #define CM0_ZR_OPT_DISABLE (1<<5) |
| @@ -655,6 +668,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
| 655 | /** P1 value is 2 greater than this field */ | 668 | /** P1 value is 2 greater than this field */ |
| 656 | # define VGA0_PD_P1_MASK (0x1f << 0) | 669 | # define VGA0_PD_P1_MASK (0x1f << 0) |
| 657 | 670 | ||
| 671 | #define DSPCLK_GATE_D 0x6200 | ||
| 672 | |||
| 658 | /* I830 CRTC registers */ | 673 | /* I830 CRTC registers */ |
| 659 | #define HTOTAL_A 0x60000 | 674 | #define HTOTAL_A 0x60000 |
| 660 | #define HBLANK_A 0x60004 | 675 | #define HBLANK_A 0x60004 |
| @@ -1101,6 +1116,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
| 1101 | #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ | 1116 | #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ |
| 1102 | IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) | 1117 | IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) |
| 1103 | 1118 | ||
| 1119 | #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev)) | ||
| 1120 | |||
| 1104 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 1121 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
| 1105 | 1122 | ||
| 1106 | #endif | 1123 | #endif |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 5dc799ab86b8..833abc7e55fb 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
| @@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | |||
| 825 | return ret; | 825 | return ret; |
| 826 | } | 826 | } |
| 827 | 827 | ||
| 828 | static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | ||
| 829 | { | ||
| 830 | RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); | ||
| 831 | return RADEON_READ(RS690_MC_DATA); | ||
| 832 | } | ||
| 833 | |||
| 828 | u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) | 834 | u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) |
| 829 | { | 835 | { |
| 830 | 836 | ||
| 831 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 837 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) |
| 832 | return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); | 838 | return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); |
| 839 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | ||
| 840 | return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); | ||
| 833 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 841 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
| 834 | return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); | 842 | return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); |
| 835 | else | 843 | else |
| @@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) | |||
| 840 | { | 848 | { |
| 841 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 849 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) |
| 842 | RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); | 850 | RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); |
| 851 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | ||
| 852 | RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); | ||
| 843 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 853 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
| 844 | RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); | 854 | RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); |
| 845 | else | 855 | else |
| @@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo | |||
| 850 | { | 860 | { |
| 851 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 861 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) |
| 852 | RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); | 862 | RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); |
| 863 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) | ||
| 864 | RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); | ||
| 853 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 865 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
| 854 | RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); | 866 | RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); |
| 855 | else | 867 | else |
| @@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) | |||
| 1362 | } | 1374 | } |
| 1363 | } | 1375 | } |
| 1364 | 1376 | ||
| 1377 | /* Enable or disable RS690 GART on the chip */ | ||
| 1378 | static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on) | ||
| 1379 | { | ||
| 1380 | u32 temp; | ||
| 1381 | |||
| 1382 | if (on) { | ||
| 1383 | DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n", | ||
| 1384 | dev_priv->gart_vm_start, | ||
| 1385 | (long)dev_priv->gart_info.bus_addr, | ||
| 1386 | dev_priv->gart_size); | ||
| 1387 | |||
| 1388 | temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL); | ||
| 1389 | RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000); | ||
| 1390 | |||
| 1391 | RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, | ||
| 1392 | RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB); | ||
| 1393 | |||
| 1394 | temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID); | ||
| 1395 | RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800); | ||
| 1396 | |||
| 1397 | RS690_WRITE_MCIND(RS690_MC_GART_BASE, | ||
| 1398 | dev_priv->gart_info.bus_addr); | ||
| 1399 | |||
| 1400 | temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL); | ||
| 1401 | RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000); | ||
| 1402 | |||
| 1403 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE, | ||
| 1404 | (unsigned int)dev_priv->gart_vm_start); | ||
| 1405 | |||
| 1406 | dev_priv->gart_size = 32*1024*1024; | ||
| 1407 | temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & | ||
| 1408 | 0xffff0000) | (dev_priv->gart_vm_start >> 16)); | ||
| 1409 | |||
| 1410 | RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp); | ||
| 1411 | |||
| 1412 | temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE); | ||
| 1413 | RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, | ||
| 1414 | RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB); | ||
| 1415 | |||
| 1416 | do { | ||
| 1417 | temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL); | ||
| 1418 | if ((temp & RS690_MC_GART_CLEAR_STATUS) == | ||
| 1419 | RS690_MC_GART_CLEAR_DONE) | ||
| 1420 | break; | ||
| 1421 | DRM_UDELAY(1); | ||
| 1422 | } while (1); | ||
| 1423 | |||
| 1424 | RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL, | ||
| 1425 | RS690_MC_GART_CC_CLEAR); | ||
| 1426 | do { | ||
| 1427 | temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL); | ||
| 1428 | if ((temp & RS690_MC_GART_CLEAR_STATUS) == | ||
| 1429 | RS690_MC_GART_CLEAR_DONE) | ||
| 1430 | break; | ||
| 1431 | DRM_UDELAY(1); | ||
| 1432 | } while (1); | ||
| 1433 | |||
| 1434 | RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL, | ||
| 1435 | RS690_MC_GART_CC_NO_CHANGE); | ||
| 1436 | } else { | ||
| 1437 | RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS); | ||
| 1438 | } | ||
| 1439 | } | ||
| 1440 | |||
| 1365 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | 1441 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) |
| 1366 | { | 1442 | { |
| 1367 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); | 1443 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); |
| @@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
| 1396 | { | 1472 | { |
| 1397 | u32 tmp; | 1473 | u32 tmp; |
| 1398 | 1474 | ||
| 1475 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { | ||
| 1476 | radeon_set_rs690gart(dev_priv, on); | ||
| 1477 | return; | ||
| 1478 | } | ||
| 1479 | |||
| 1399 | if (dev_priv->flags & RADEON_IS_IGPGART) { | 1480 | if (dev_priv->flags & RADEON_IS_IGPGART) { |
| 1400 | radeon_set_igpgart(dev_priv, on); | 1481 | radeon_set_igpgart(dev_priv, on); |
| 1401 | return; | 1482 | return; |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 4434332c79bc..173ae620223a 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
| @@ -123,6 +123,7 @@ enum radeon_family { | |||
| 123 | CHIP_R420, | 123 | CHIP_R420, |
| 124 | CHIP_RV410, | 124 | CHIP_RV410, |
| 125 | CHIP_RS400, | 125 | CHIP_RS400, |
| 126 | CHIP_RS690, | ||
| 126 | CHIP_RV515, | 127 | CHIP_RV515, |
| 127 | CHIP_R520, | 128 | CHIP_R520, |
| 128 | CHIP_RV530, | 129 | CHIP_RV530, |
| @@ -467,6 +468,36 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
| 467 | #define RADEON_IGPGART_ENABLE 0x38 | 468 | #define RADEON_IGPGART_ENABLE 0x38 |
| 468 | #define RADEON_IGPGART_UNK_39 0x39 | 469 | #define RADEON_IGPGART_UNK_39 0x39 |
| 469 | 470 | ||
| 471 | #define RS690_MC_INDEX 0x78 | ||
| 472 | # define RS690_MC_INDEX_MASK 0x1ff | ||
| 473 | # define RS690_MC_INDEX_WR_EN (1 << 9) | ||
| 474 | # define RS690_MC_INDEX_WR_ACK 0x7f | ||
| 475 | #define RS690_MC_DATA 0x7c | ||
| 476 | |||
| 477 | #define RS690_MC_MISC_CNTL 0x18 | ||
| 478 | #define RS690_MC_GART_FEATURE_ID 0x2b | ||
| 479 | #define RS690_MC_GART_BASE 0x2c | ||
| 480 | #define RS690_MC_GART_CACHE_CNTL 0x2e | ||
| 481 | # define RS690_MC_GART_CC_NO_CHANGE 0x0 | ||
| 482 | # define RS690_MC_GART_CC_CLEAR 0x1 | ||
| 483 | # define RS690_MC_GART_CLEAR_STATUS (1 << 1) | ||
| 484 | # define RS690_MC_GART_CLEAR_DONE (0 << 1) | ||
| 485 | # define RS690_MC_GART_CLEAR_PENDING (1 << 1) | ||
| 486 | #define RS690_MC_AGP_SIZE 0x38 | ||
| 487 | # define RS690_MC_GART_DIS 0x0 | ||
| 488 | # define RS690_MC_GART_EN 0x1 | ||
| 489 | # define RS690_MC_AGP_SIZE_32MB (0 << 1) | ||
| 490 | # define RS690_MC_AGP_SIZE_64MB (1 << 1) | ||
| 491 | # define RS690_MC_AGP_SIZE_128MB (2 << 1) | ||
| 492 | # define RS690_MC_AGP_SIZE_256MB (3 << 1) | ||
| 493 | # define RS690_MC_AGP_SIZE_512MB (4 << 1) | ||
| 494 | # define RS690_MC_AGP_SIZE_1GB (5 << 1) | ||
| 495 | # define RS690_MC_AGP_SIZE_2GB (6 << 1) | ||
| 496 | #define RS690_MC_AGP_MODE_CONTROL 0x39 | ||
| 497 | #define RS690_MC_FB_LOCATION 0x100 | ||
| 498 | #define RS690_MC_AGP_LOCATION 0x101 | ||
| 499 | #define RS690_MC_AGP_BASE 0x102 | ||
| 500 | |||
| 470 | #define R520_MC_IND_INDEX 0x70 | 501 | #define R520_MC_IND_INDEX 0x70 |
| 471 | #define R520_MC_IND_WR_EN (1<<24) | 502 | #define R520_MC_IND_WR_EN (1<<24) |
| 472 | #define R520_MC_IND_DATA 0x74 | 503 | #define R520_MC_IND_DATA 0x74 |
| @@ -1076,6 +1107,13 @@ do { \ | |||
| 1076 | RADEON_WRITE(R520_MC_IND_INDEX, 0); \ | 1107 | RADEON_WRITE(R520_MC_IND_INDEX, 0); \ |
| 1077 | } while (0) | 1108 | } while (0) |
| 1078 | 1109 | ||
| 1110 | #define RS690_WRITE_MCIND( addr, val ) \ | ||
| 1111 | do { \ | ||
| 1112 | RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ | ||
| 1113 | RADEON_WRITE(RS690_MC_DATA, val); \ | ||
| 1114 | RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ | ||
| 1115 | } while (0) | ||
| 1116 | |||
| 1079 | #define CP_PACKET0( reg, n ) \ | 1117 | #define CP_PACKET0( reg, n ) \ |
| 1080 | (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) | 1118 | (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) |
| 1081 | #define CP_PACKET0_TABLE( reg, n ) \ | 1119 | #define CP_PACKET0_TABLE( reg, n ) \ |
