| From 0befbca168c6420ed27682d74ca4768fd15b0128 Mon Sep 17 00:00:00 2001 |
| From: Andy Lutomirski <luto@amacapital.net> |
| Date: Mon, 13 May 2013 23:58:43 +0000 |
| Subject: drm, agpgart: Use pgprot_writecombine for AGP maps and make the MTRR |
| optional |
| |
| I'm not sure I understand the intent of the previous behavior. mmap |
| on /dev/agpgart and DRM_AGP maps had no cache flags set, so they |
| would be fully cacheable. But the DRM code (most of the time) would |
| add a write-combining MTRR that would change the effective memory |
| type to WC. |
| |
| The new behavior just requests WC explicitly for all AGP maps. |
| |
| If there is any code out there that expects cacheable access to the |
| AGP aperture (because the drm driver doesn't request an MTRR or |
| because it's using /dev/agpgart directly), then it will now end up |
| with a UC or WC mapping, depending on the architecture and PAT |
| availability. But cacheable access to the aperture seems like it's |
| asking for trouble, because, AIUI, the aperture is an alias of RAM. |
| |
| Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Signed-off-by: Andy Lutomirski <luto@amacapital.net> |
| Signed-off-by: Dave Airlie <airlied@redhat.com> |
| (cherry picked from commit f435046d38af631920b299455db9e95dfc06d055) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/char/agp/frontend.c | 8 +++++--- |
| drivers/gpu/drm/drm_pci.c | 8 ++++---- |
| drivers/gpu/drm/drm_stub.c | 10 ++-------- |
| drivers/gpu/drm/drm_vm.c | 11 ++++------- |
| 4 files changed, 15 insertions(+), 22 deletions(-) |
| |
| diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c |
| index 2e044338753c..1b192395a90c 100644 |
| --- a/drivers/char/agp/frontend.c |
| +++ b/drivers/char/agp/frontend.c |
| @@ -603,7 +603,8 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) |
| vma->vm_ops = kerninfo.vm_ops; |
| } else if (io_remap_pfn_range(vma, vma->vm_start, |
| (kerninfo.aper_base + offset) >> PAGE_SHIFT, |
| - size, vma->vm_page_prot)) { |
| + size, |
| + pgprot_writecombine(vma->vm_page_prot))) { |
| goto out_again; |
| } |
| mutex_unlock(&(agp_fe.agp_mutex)); |
| @@ -618,8 +619,9 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) |
| if (kerninfo.vm_ops) { |
| vma->vm_ops = kerninfo.vm_ops; |
| } else if (io_remap_pfn_range(vma, vma->vm_start, |
| - kerninfo.aper_base >> PAGE_SHIFT, |
| - size, vma->vm_page_prot)) { |
| + kerninfo.aper_base >> PAGE_SHIFT, |
| + size, |
| + pgprot_writecombine(vma->vm_page_prot))) { |
| goto out_again; |
| } |
| mutex_unlock(&(agp_fe.agp_mutex)); |
| diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c |
| index 14194b6ef644..80c0b2b29801 100644 |
| --- a/drivers/gpu/drm/drm_pci.c |
| +++ b/drivers/gpu/drm/drm_pci.c |
| @@ -278,10 +278,10 @@ static int drm_pci_agp_init(struct drm_device *dev) |
| } |
| if (drm_core_has_MTRR(dev)) { |
| if (dev->agp) |
| - dev->agp->agp_mtrr = |
| - mtrr_add(dev->agp->agp_info.aper_base, |
| - dev->agp->agp_info.aper_size * |
| - 1024 * 1024, MTRR_TYPE_WRCOMB, 1); |
| + dev->agp->agp_mtrr = arch_phys_wc_add( |
| + dev->agp->agp_info.aper_base, |
| + dev->agp->agp_info.aper_size * |
| + 1024 * 1024); |
| } |
| } |
| return 0; |
| diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c |
| index 16f3ec579b3b..577786ce9fbc 100644 |
| --- a/drivers/gpu/drm/drm_stub.c |
| +++ b/drivers/gpu/drm/drm_stub.c |
| @@ -451,14 +451,8 @@ void drm_put_dev(struct drm_device *dev) |
| |
| drm_lastclose(dev); |
| |
| - if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && |
| - dev->agp && dev->agp->agp_mtrr >= 0) { |
| - int retval; |
| - retval = mtrr_del(dev->agp->agp_mtrr, |
| - dev->agp->agp_info.aper_base, |
| - dev->agp->agp_info.aper_size * 1024 * 1024); |
| - DRM_DEBUG("mtrr_del=%d\n", retval); |
| - } |
| + if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp) |
| + arch_phys_wc_del(dev->agp->agp_mtrr); |
| |
| if (dev->driver->unload) |
| dev->driver->unload(dev); |
| diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c |
| index 43e7825d3717..1575694ccaca 100644 |
| --- a/drivers/gpu/drm/drm_vm.c |
| +++ b/drivers/gpu/drm/drm_vm.c |
| @@ -49,13 +49,10 @@ static pgprot_t drm_io_prot(struct drm_local_map *map, |
| pgprot_t tmp = vm_get_page_prot(vma->vm_flags); |
| |
| #if defined(__i386__) || defined(__x86_64__) |
| - 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); |
| - } |
| + if (map->type == _DRM_REGISTERS && !(map->flags & _DRM_WRITE_COMBINING)) |
| + tmp = pgprot_noncached(tmp); |
| + else |
| + tmp = pgprot_writecombine(tmp); |
| #elif defined(__powerpc__) |
| pgprot_val(tmp) |= _PAGE_NO_CACHE; |
| if (map->type == _DRM_REGISTERS) |
| -- |
| 1.8.5.rc3 |
| |