Author: tijl
Date: Thu Oct 30 14:26:36 2014
New Revision: 273862
URL: https://svnweb.freebsd.org/changeset/base/273862

Log:
  Port the TTM AGP backend to the FreeBSD agp driver and enable AGP support
  in the radeonkms driver.
  
  Note: In PCI mode virtual addresses on the graphics card that map to system
  RAM are translated to physical addresses by the graphics card itself.   In
  AGP mode address translation is done by the AGP chipset so fictitious
  addresses appear on the system bus.  For the CPU cache management to work
  correctly when the CPU accesses this memory it needs to use the same
  fictitious addresses (and let the chipset translate them) instead of using
  the physical addresses directly.
  
  Reviewed by:  kib
  MFC after:    1 month

Modified:
  head/sys/dev/drm2/drm_agpsupport.c
  head/sys/dev/drm2/radeon/radeon.h
  head/sys/dev/drm2/radeon/radeon_device.c
  head/sys/dev/drm2/radeon/radeon_ttm.c
  head/sys/dev/drm2/ttm/ttm_agp_backend.c
  head/sys/dev/drm2/ttm/ttm_bo_driver.h
  head/sys/dev/drm2/ttm/ttm_page_alloc.c

Modified: head/sys/dev/drm2/drm_agpsupport.c
==============================================================================
--- head/sys/dev/drm2/drm_agpsupport.c  Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/drm_agpsupport.c  Thu Oct 30 14:26:36 2014        
(r273862)
@@ -396,7 +396,7 @@ void *drm_agp_allocate_memory(size_t pag
        if (!agpdev)
                return NULL;
 
-       return agp_alloc_memory(agpdev, type, pages << AGP_PAGE_SHIFT);
+       return agp_alloc_memory(agpdev, type, pages << PAGE_SHIFT);
 }
 
 int drm_agp_free_memory(void *handle)

Modified: head/sys/dev/drm2/radeon/radeon.h
==============================================================================
--- head/sys/dev/drm2/radeon/radeon.h   Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/radeon/radeon.h   Thu Oct 30 14:26:36 2014        
(r273862)
@@ -1618,6 +1618,7 @@ struct radeon_device {
        bool                            need_dma32;
        bool                            accel_working;
        bool                            fictitious_range_registered;
+       bool                            fictitious_agp_range_registered;
        struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
        const struct firmware *me_fw;   /* all family ME firmware */
        const struct firmware *pfp_fw;  /* r6/700 PFP firmware */

Modified: head/sys/dev/drm2/radeon/radeon_device.c
==============================================================================
--- head/sys/dev/drm2/radeon/radeon_device.c    Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/radeon/radeon_device.c    Thu Oct 30 14:26:36 2014        
(r273862)
@@ -1014,6 +1014,7 @@ int radeon_device_init(struct radeon_dev
        rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        rdev->accel_working = false;
        rdev->fictitious_range_registered = false;
+       rdev->fictitious_agp_range_registered = false;
        /* set up ring ids */
        for (i = 0; i < RADEON_NUM_RINGS; i++) {
                rdev->ring[i].idx = i;
@@ -1168,6 +1169,24 @@ int radeon_device_init(struct radeon_dev
                return (-r);
        }
        rdev->fictitious_range_registered = true;
+#if __OS_HAS_AGP
+       if (rdev->flags & RADEON_IS_AGP) {
+               DRM_INFO("%s: Taking over the fictitious range 0x%jx-0x%jx\n",
+                   __func__, (uintmax_t)rdev->mc.agp_base,
+                   (uintmax_t)rdev->mc.agp_base + rdev->mc.gtt_size);
+               r = vm_phys_fictitious_reg_range(
+                   rdev->mc.agp_base,
+                   rdev->mc.agp_base + rdev->mc.gtt_size,
+                   VM_MEMATTR_WRITE_COMBINING);
+               if (r != 0) {
+                       DRM_ERROR("Failed to register fictitious range "
+                           "0x%jx-0x%jx (%d).\n", (uintmax_t)rdev->mc.agp_base,
+                           (uintmax_t)rdev->mc.agp_base + rdev->mc.gtt_size, 
r);
+                       return (-r);
+               }
+               rdev->fictitious_agp_range_registered = true;
+       }
+#endif
 
        if ((radeon_testing & 1)) {
                radeon_test_moves(rdev);
@@ -1205,6 +1224,13 @@ void radeon_device_fini(struct radeon_de
                    rdev->mc.aper_base,
                    rdev->mc.aper_base + rdev->mc.visible_vram_size);
        }
+#if __OS_HAS_AGP
+       if (rdev->fictitious_agp_range_registered) {
+               vm_phys_fictitious_unreg_range(
+                   rdev->mc.agp_base,
+                   rdev->mc.agp_base + rdev->mc.gtt_size);
+       }
+#endif
 
        radeon_fini(rdev);
 #ifdef DUMBBELL_WIP

Modified: head/sys/dev/drm2/radeon/radeon_ttm.c
==============================================================================
--- head/sys/dev/drm2/radeon/radeon_ttm.c       Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/radeon/radeon_ttm.c       Thu Oct 30 14:26:36 2014        
(r273862)
@@ -560,12 +560,10 @@ static struct ttm_tt *radeon_ttm_tt_crea
 
        rdev = radeon_get_rdev(bdev);
 #if __OS_HAS_AGP
-#ifdef DUMBBELL_WIP
        if (rdev->flags & RADEON_IS_AGP) {
                return ttm_agp_tt_create(bdev, rdev->ddev->agp->agpdev,
                                         size, page_flags, dummy_read_page);
        }
-#endif /* DUMBBELL_WIP */
 #endif
 
        gtt = malloc(sizeof(struct radeon_ttm_tt),
@@ -610,11 +608,9 @@ static int radeon_ttm_tt_populate(struct
 
        rdev = radeon_get_rdev(ttm->bdev);
 #if __OS_HAS_AGP
-#ifdef DUMBBELL_WIP
        if (rdev->flags & RADEON_IS_AGP) {
                return ttm_agp_tt_populate(ttm);
        }
-#endif /* DUMBBELL_WIP */
 #endif
 
 #ifdef CONFIG_SWIOTLB
@@ -660,12 +656,10 @@ static void radeon_ttm_tt_unpopulate(str
 
        rdev = radeon_get_rdev(ttm->bdev);
 #if __OS_HAS_AGP
-#ifdef DUMBBELL_WIP
        if (rdev->flags & RADEON_IS_AGP) {
                ttm_agp_tt_unpopulate(ttm);
                return;
        }
-#endif /* DUMBBELL_WIP */
 #endif
 
 #ifdef CONFIG_SWIOTLB

Modified: head/sys/dev/drm2/ttm/ttm_agp_backend.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_agp_backend.c     Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/ttm/ttm_agp_backend.c     Thu Oct 30 14:26:36 2014        
(r273862)
@@ -41,7 +41,8 @@ __FBSDID("$FreeBSD$");
 
 struct ttm_agp_backend {
        struct ttm_tt ttm;
-       struct agp_memory *mem;
+       vm_offset_t offset;
+       vm_page_t *pages;
        device_t bridge;
 };
 
@@ -51,31 +52,23 @@ static int ttm_agp_bind(struct ttm_tt *t
 {
        struct ttm_agp_backend *agp_be = container_of(ttm, struct 
ttm_agp_backend, ttm);
        struct drm_mm_node *node = bo_mem->mm_node;
-       struct agp_memory *mem;
-       int ret, cached = (bo_mem->placement & TTM_PL_FLAG_CACHED);
+       int ret;
        unsigned i;
 
-       mem = agp_alloc_memory(agp_be->bridge, AGP_USER_MEMORY, ttm->num_pages);
-       if (unlikely(mem == NULL))
-               return -ENOMEM;
-
-       mem->page_count = 0;
        for (i = 0; i < ttm->num_pages; i++) {
                vm_page_t page = ttm->pages[i];
 
                if (!page)
                        page = ttm->dummy_read_page;
 
-               mem->pages[mem->page_count++] = page;
+               agp_be->pages[i] = page;
        }
-       agp_be->mem = mem;
-
-       mem->is_flushed = 1;
-       mem->type = (cached) ? AGP_USER_CACHED_MEMORY : AGP_USER_MEMORY;
 
-       ret = agp_bind_memory(mem, node->start);
+       agp_be->offset = node->start * PAGE_SIZE;
+       ret = -agp_bind_pages(agp_be->bridge, agp_be->pages,
+                             ttm->num_pages << PAGE_SHIFT, agp_be->offset);
        if (ret)
-               pr_err("AGP Bind memory failed\n");
+               printf("[TTM] AGP Bind memory failed\n");
 
        return ret;
 }
@@ -84,22 +77,16 @@ static int ttm_agp_unbind(struct ttm_tt 
 {
        struct ttm_agp_backend *agp_be = container_of(ttm, struct 
ttm_agp_backend, ttm);
 
-       if (agp_be->mem) {
-               if (agp_be->mem->is_bound)
-                       return agp_unbind_memory(agp_be->mem);
-               agp_free_memory(agp_be->mem);
-               agp_be->mem = NULL;
-       }
-       return 0;
+       return -agp_unbind_pages(agp_be->bridge, ttm->num_pages << PAGE_SHIFT,
+                                agp_be->offset);
 }
 
 static void ttm_agp_destroy(struct ttm_tt *ttm)
 {
        struct ttm_agp_backend *agp_be = container_of(ttm, struct 
ttm_agp_backend, ttm);
 
-       if (agp_be->mem)
-               ttm_agp_unbind(ttm);
        ttm_tt_fini(ttm);
+       free(agp_be->pages, M_TTM_AGP);
        free(agp_be, M_TTM_AGP);
 }
 
@@ -118,14 +105,18 @@ struct ttm_tt *ttm_agp_tt_create(struct 
 
        agp_be = malloc(sizeof(*agp_be), M_TTM_AGP, M_WAITOK | M_ZERO);
 
-       agp_be->mem = NULL;
        agp_be->bridge = bridge;
        agp_be->ttm.func = &ttm_agp_func;
 
        if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) 
{
+               free(agp_be, M_TTM_AGP);
                return NULL;
        }
 
+       agp_be->offset = 0;
+       agp_be->pages = malloc(agp_be->ttm.num_pages * sizeof(*agp_be->pages),
+                              M_TTM_AGP, M_WAITOK);
+
        return &agp_be->ttm;
 }
 

Modified: head/sys/dev/drm2/ttm/ttm_bo_driver.h
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_bo_driver.h       Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/ttm/ttm_bo_driver.h       Thu Oct 30 14:26:36 2014        
(r273862)
@@ -990,9 +990,8 @@ extern vm_memattr_t ttm_io_prot(uint32_t
 
 extern const struct ttm_mem_type_manager_func ttm_bo_manager_func;
 
-#if (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
+#if __OS_HAS_AGP
 #define TTM_HAS_AGP
-#include <linux/agp_backend.h>
 
 /**
  * ttm_agp_tt_create
@@ -1009,7 +1008,7 @@ extern const struct ttm_mem_type_manager
  * bind and unbind memory backing a ttm_tt.
  */
 extern struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
-                                       struct agp_bridge_data *bridge,
+                                       device_t bridge,
                                        unsigned long size, uint32_t page_flags,
                                        struct vm_page *dummy_read_page);
 int ttm_agp_tt_populate(struct ttm_tt *ttm);

Modified: head/sys/dev/drm2/ttm/ttm_page_alloc.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_page_alloc.c      Thu Oct 30 14:05:48 2014        
(r273861)
+++ head/sys/dev/drm2/ttm/ttm_page_alloc.c      Thu Oct 30 14:26:36 2014        
(r273862)
@@ -45,10 +45,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/drm2/ttm/ttm_bo_driver.h>
 #include <dev/drm2/ttm/ttm_page_alloc.h>
 
-#ifdef TTM_HAS_AGP
-#include <asm/agp.h>
-#endif
-
 #define NUM_PAGES_TO_ALLOC             (PAGE_SIZE/sizeof(vm_page_t))
 #define SMALL_ALLOCATION               16
 #define FREE_ALL_PAGES                 (~0U)
@@ -220,46 +216,34 @@ static struct ttm_pool_manager *_manager
 
 static int set_pages_array_wb(vm_page_t *pages, int addrinarray)
 {
-       vm_page_t m;
+#ifdef TTM_HAS_AGP
        int i;
 
-       for (i = 0; i < addrinarray; i++) {
-               m = pages[i];
-#ifdef TTM_HAS_AGP
-               unmap_page_from_agp(m);
+       for (i = 0; i < addrinarray; i++)
+               pmap_page_set_memattr(pages[i], VM_MEMATTR_WRITE_BACK);
 #endif
-               pmap_page_set_memattr(m, VM_MEMATTR_WRITE_BACK);
-       }
        return 0;
 }
 
 static int set_pages_array_wc(vm_page_t *pages, int addrinarray)
 {
-       vm_page_t m;
+#ifdef TTM_HAS_AGP
        int i;
 
-       for (i = 0; i < addrinarray; i++) {
-               m = pages[i];
-#ifdef TTM_HAS_AGP
-               map_page_into_agp(pages[i]);
+       for (i = 0; i < addrinarray; i++)
+               pmap_page_set_memattr(pages[i], VM_MEMATTR_WRITE_COMBINING);
 #endif
-               pmap_page_set_memattr(m, VM_MEMATTR_WRITE_COMBINING);
-       }
        return 0;
 }
 
 static int set_pages_array_uc(vm_page_t *pages, int addrinarray)
 {
-       vm_page_t m;
+#ifdef TTM_HAS_AGP
        int i;
 
-       for (i = 0; i < addrinarray; i++) {
-               m = pages[i];
-#ifdef TTM_HAS_AGP
-               map_page_into_agp(pages[i]);
+       for (i = 0; i < addrinarray; i++)
+               pmap_page_set_memattr(pages[i], VM_MEMATTR_UNCACHEABLE);
 #endif
-               pmap_page_set_memattr(m, VM_MEMATTR_UNCACHEABLE);
-       }
        return 0;
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to