Commit ff47eaf2 authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Dave Airlie

drm: Update drm_addmap and drm_mmap to use PAT WC instead of MTRRs

Previously, DRM_FRAME_BUFFER mappings, as well as DRM_REGISTERS
mappings with DRM_WRITE_COMBINING set, resulted in an unconditional
MTRR being added but the actual mappings being created as UC-.

Now these mappings have the MTRR added only if needed, but they will
be mapped with pgprot_writecombine.

The non-WC DRM_REGISTERS case now uses pgprot_noncached instead of
hardcoding the bit twiddling.

The DRM_AGP case is unchanged for now.

[airlied: fix ppc build]
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarAndy Lutomirski <luto@amacapital.net>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 247d36d7
...@@ -210,12 +210,16 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, ...@@ -210,12 +210,16 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
if (drm_core_has_MTRR(dev)) { if (drm_core_has_MTRR(dev)) {
if (map->type == _DRM_FRAME_BUFFER || if (map->type == _DRM_FRAME_BUFFER ||
(map->flags & _DRM_WRITE_COMBINING)) { (map->flags & _DRM_WRITE_COMBINING)) {
map->mtrr = mtrr_add(map->offset, map->size, map->mtrr =
MTRR_TYPE_WRCOMB, 1); arch_phys_wc_add(map->offset, map->size);
} }
} }
if (map->type == _DRM_REGISTERS) { if (map->type == _DRM_REGISTERS) {
map->handle = ioremap(map->offset, map->size); if (map->flags & _DRM_WRITE_COMBINING)
map->handle = ioremap_wc(map->offset,
map->size);
else
map->handle = ioremap(map->offset, map->size);
if (!map->handle) { if (!map->handle) {
kfree(map); kfree(map);
return -ENOMEM; return -ENOMEM;
...@@ -451,11 +455,8 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) ...@@ -451,11 +455,8 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
iounmap(map->handle); iounmap(map->handle);
/* FALLTHROUGH */ /* FALLTHROUGH */
case _DRM_FRAME_BUFFER: case _DRM_FRAME_BUFFER:
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { if (drm_core_has_MTRR(dev))
int retcode; arch_phys_wc_del(map->mtrr);
retcode = mtrr_del(map->mtrr, map->offset, map->size);
DRM_DEBUG("mtrr_del=%d\n", retcode);
}
break; break;
case _DRM_SHM: case _DRM_SHM:
vfree(map->handle); vfree(map->handle);
......
...@@ -43,18 +43,22 @@ ...@@ -43,18 +43,22 @@
static void drm_vm_open(struct vm_area_struct *vma); static void drm_vm_open(struct vm_area_struct *vma);
static void drm_vm_close(struct vm_area_struct *vma); static void drm_vm_close(struct vm_area_struct *vma);
static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) static pgprot_t drm_io_prot(struct drm_local_map *map,
struct vm_area_struct *vma)
{ {
pgprot_t tmp = vm_get_page_prot(vma->vm_flags); pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { if (map->type != _DRM_AGP) {
pgprot_val(tmp) |= _PAGE_PCD; if (map->type == _DRM_FRAME_BUFFER ||
pgprot_val(tmp) &= ~_PAGE_PWT; map->flags & _DRM_WRITE_COMBINING)
tmp = pgprot_writecombine(tmp);
else
tmp = pgprot_noncached(tmp);
} }
#elif defined(__powerpc__) #elif defined(__powerpc__)
pgprot_val(tmp) |= _PAGE_NO_CACHE; pgprot_val(tmp) |= _PAGE_NO_CACHE;
if (map_type == _DRM_REGISTERS) if (map->type == _DRM_REGISTERS)
pgprot_val(tmp) |= _PAGE_GUARDED; pgprot_val(tmp) |= _PAGE_GUARDED;
#elif defined(__ia64__) #elif defined(__ia64__)
if (efi_range_is_wc(vma->vm_start, vma->vm_end - if (efi_range_is_wc(vma->vm_start, vma->vm_end -
...@@ -250,13 +254,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) ...@@ -250,13 +254,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
switch (map->type) { switch (map->type) {
case _DRM_REGISTERS: case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER: case _DRM_FRAME_BUFFER:
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { if (drm_core_has_MTRR(dev))
int retcode; arch_phys_wc_del(map->mtrr);
retcode = mtrr_del(map->mtrr,
map->offset,
map->size);
DRM_DEBUG("mtrr_del = %d\n", retcode);
}
iounmap(map->handle); iounmap(map->handle);
break; break;
case _DRM_SHM: case _DRM_SHM:
...@@ -618,7 +617,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) ...@@ -618,7 +617,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
case _DRM_REGISTERS: case _DRM_REGISTERS:
offset = drm_core_get_reg_ofs(dev); offset = drm_core_get_reg_ofs(dev);
vma->vm_flags |= VM_IO; /* not in core dump */ vma->vm_flags |= VM_IO; /* not in core dump */
vma->vm_page_prot = drm_io_prot(map->type, vma); vma->vm_page_prot = drm_io_prot(map, vma);
if (io_remap_pfn_range(vma, vma->vm_start, if (io_remap_pfn_range(vma, vma->vm_start,
(map->offset + offset) >> PAGE_SHIFT, (map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_end - vma->vm_start,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment