mirror of
https://github.com/torvalds/linux.git
synced 2024-11-08 05:01:48 +00:00
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: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
247d36d751
commit
ff47eaf24d
@ -210,11 +210,15 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
|
||||
if (drm_core_has_MTRR(dev)) {
|
||||
if (map->type == _DRM_FRAME_BUFFER ||
|
||||
(map->flags & _DRM_WRITE_COMBINING)) {
|
||||
map->mtrr = mtrr_add(map->offset, map->size,
|
||||
MTRR_TYPE_WRCOMB, 1);
|
||||
map->mtrr =
|
||||
arch_phys_wc_add(map->offset, map->size);
|
||||
}
|
||||
}
|
||||
if (map->type == _DRM_REGISTERS) {
|
||||
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) {
|
||||
kfree(map);
|
||||
@ -451,11 +455,8 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
|
||||
iounmap(map->handle);
|
||||
/* FALLTHROUGH */
|
||||
case _DRM_FRAME_BUFFER:
|
||||
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
|
||||
int retcode;
|
||||
retcode = mtrr_del(map->mtrr, map->offset, map->size);
|
||||
DRM_DEBUG("mtrr_del=%d\n", retcode);
|
||||
}
|
||||
if (drm_core_has_MTRR(dev))
|
||||
arch_phys_wc_del(map->mtrr);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
vfree(map->handle);
|
||||
|
@ -43,18 +43,22 @@
|
||||
static void drm_vm_open(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);
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) {
|
||||
pgprot_val(tmp) |= _PAGE_PCD;
|
||||
pgprot_val(tmp) &= ~_PAGE_PWT;
|
||||
if (map->type != _DRM_AGP) {
|
||||
if (map->type == _DRM_FRAME_BUFFER ||
|
||||
map->flags & _DRM_WRITE_COMBINING)
|
||||
tmp = pgprot_writecombine(tmp);
|
||||
else
|
||||
tmp = pgprot_noncached(tmp);
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
pgprot_val(tmp) |= _PAGE_NO_CACHE;
|
||||
if (map_type == _DRM_REGISTERS)
|
||||
if (map->type == _DRM_REGISTERS)
|
||||
pgprot_val(tmp) |= _PAGE_GUARDED;
|
||||
#elif defined(__ia64__)
|
||||
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)
|
||||
switch (map->type) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
|
||||
int retcode;
|
||||
retcode = mtrr_del(map->mtrr,
|
||||
map->offset,
|
||||
map->size);
|
||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
||||
}
|
||||
if (drm_core_has_MTRR(dev))
|
||||
arch_phys_wc_del(map->mtrr);
|
||||
iounmap(map->handle);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
@ -618,7 +617,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
|
||||
case _DRM_REGISTERS:
|
||||
offset = drm_core_get_reg_ofs(dev);
|
||||
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,
|
||||
(map->offset + offset) >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
|
Loading…
Reference in New Issue
Block a user