Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Jan 2002 01:03:51 -0800 (PST)
From:      Kyle Martin <mkm@idsi.net>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/34057: tested patch for agpgart for AMD chipsets
Message-ID:  <200201190903.g0J93pc41164@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         34057
>Category:       i386
>Synopsis:       tested patch for agpgart for AMD chipsets
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 19 01:10:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Kyle Martin
>Release:        4.5-RC
>Organization:
>Environment:
FreeBSD marvin.idsi.net 4.5-RC FreeBSD 4.5-RC #3: Sat Jan 19 01:49:35 CST 2002     mkm@marvin.idsi.net:/usr/src/sys/compile/MARVIN  i386

>Description:
this is and update of pr i386/32301.  This adds in the support for the 760MP chipset which contained the 762 AGP chip.  I have tested this and it works wonderfully.
>How-To-Repeat:
try to get dri working for a radeon on a tyan thunder k7 mobo.      
>Fix:
*** /usr/src/sys/pci/agp_amd.c  Thu Dec 20 04:27:41 2001
--- agp_amd.c   Sat Jan 19 01:35:20 2002
***************
*** 58,66 ****
  
  struct agp_amd_gatt {
        u_int32_t       ag_entries;
        u_int32_t      *ag_vdir;        /* virtual address of page dir */
        vm_offset_t     ag_pdir;        /* physical address of page dir */
-       u_int32_t      *ag_virtual;     /* virtual address of gatt */
  };
  
  struct agp_amd_softc {
--- 58,67 ----
  
  struct agp_amd_gatt {
        u_int32_t       ag_entries;
+       u_int32_t      *ag_virtual;     /* virtual address of gatt */
+       vm_offset_t     ag_physical;    /* physical address of the gatt */
        u_int32_t      *ag_vdir;        /* virtual address of page dir */
        vm_offset_t     ag_pdir;        /* physical address of page dir */
  };
  
  struct agp_amd_softc {
***************
*** 78,84 ****
        u_int32_t apsize = AGP_GET_APERTURE(dev);
        u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
        struct agp_amd_gatt *gatt;
!       int i, npages;
  
        if (bootverbose)
                device_printf(dev,
--- 79,85 ----
        u_int32_t apsize = AGP_GET_APERTURE(dev);
        u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
        struct agp_amd_gatt *gatt;
!       int i, npages, pdir_offset;
  
        if (bootverbose)
                device_printf(dev,
***************
*** 92,113 ****
        /*
         * The AMD751 uses a page directory to map a non-contiguous
         * gatt so we don't need to use contigmalloc.
         */
-       gatt->ag_entries = entries;
-       gatt->ag_virtual = malloc(entries * sizeof(u_int32_t),
-                                 M_AGP, M_NOWAIT);
-       if (!gatt->ag_virtual) {
-               if (bootverbose)
-                       device_printf(dev, "allocation failed\n");
-               free(gatt, M_AGP);
-               return 0;
-       }
-       bzero(gatt->ag_virtual, entries * sizeof(u_int32_t));
  
        /*
         * Allocate the page directory.
         */
        gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT);
        if (!gatt->ag_vdir) {
                if (bootverbose)
                        device_printf(dev,
 ***************
*** 92,113 ****
        /*
         * The AMD751 uses a page directory to map a non-contiguous
         * gatt so we don't need to use contigmalloc.
         */
-       gatt->ag_entries = entries;
-       gatt->ag_virtual = malloc(entries * sizeof(u_int32_t),
-                                 M_AGP, M_NOWAIT);
-       if (!gatt->ag_virtual) {
-               if (bootverbose)
-                       device_printf(dev, "allocation failed\n");
-               free(gatt, M_AGP);
-               return 0;
-       }
-       bzero(gatt->ag_virtual, entries * sizeof(u_int32_t));
  
        /*
         * Allocate the page directory.
         */
        gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT);
        if (!gatt->ag_vdir) {
                if (bootverbose)
                        device_printf(dev,
--- 93,108 ----
        /*
         * The AMD751 uses a page directory to map a non-contiguous
         * gatt so we don't need to use contigmalloc.
+        * Malloc indiviual gatt pages and map them into the page
+        * directory.   
         */
  
        /*
         * Allocate the page directory.
         */
        gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT);
+       bzero(gatt->ag_vdir, AGP_PAGE_SIZE);
+ 
        if (!gatt->ag_vdir) {
                if (bootverbose)
                        device_printf(dev,
***************
*** 116,137 ****
                free(gatt, M_AGP);
                return 0;
        }
-       bzero(gatt->ag_vdir, AGP_PAGE_SIZE);
        gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir);
!       gatt->ag_pdir = vtophys(gatt->ag_virtual);
  
        /*
         * Map the pages of the GATT into the page directory.
         */
        npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1)
                  >> AGP_PAGE_SHIFT);
        for (i = 0; i < npages; i++) {
                vm_offset_t va;
                vm_offset_t pa;
  
                va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE;
                pa = vtophys(va);
!               gatt->ag_vdir[i] = pa | 1;
        }
  
        /*
 --- 111,164 ----
                free(gatt, M_AGP);
                return 0;
        }
        gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir);
!               if (bootverbose)
!                   device_printf(dev,
!                        "gatt -> ag_pdir %8x\n",
!                       (vm_offset_t) gatt->ag_pdir );
! 
!       /*
!        * Allocate the gatt pages
!        */
!       gatt->ag_entries = entries;
!       if (bootverbose)
!                 device_printf(dev,
!                               "allocating GATT for %d AGP page entries\n",
!                               gatt->ag_entries = entries);
! 
!       gatt->ag_virtual = malloc(entries * sizeof(u_int32_t),
!                                 M_AGP, M_NOWAIT);
! 
!       if (!gatt->ag_virtual) {
!               if (bootverbose)
!                       device_printf(dev, "allocation failed\n");
!               free(gatt, M_AGP);
!               return 0;
!       }
!       bzero(gatt->ag_virtual, entries * sizeof(u_int32_t));
!       gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual);
  
        /*
         * Map the pages of the GATT into the page directory.
+        *
+        * The gatt page addresses are mapped into the directory
+        * offset by an amount dependent on the base address of the 
+        * aperture.  This is an offset into the page directory
+        * not an offset added to the addresses of the gatt pages.
         */
+       
+       pdir_offset = pci_read_config(dev, AGP_AMD751_APBASE, 4) >> 22;
+ 
        npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1)
                  >> AGP_PAGE_SHIFT);
+ 
        for (i = 0; i < npages; i++) {
                vm_offset_t va;
                vm_offset_t pa;
  
                va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE;
                pa = vtophys(va);
!               gatt->ag_vdir[i + pdir_offset ] = pa | 1;
        }
  
        /*
***************
*** 165,170 ****
--- 192,200 ----
                return ("AMD 751 host to AGP bridge");
        case 0x700e1022:
                return ("AMD 761 host to AGP bridge");
+ 
+       case 0x700c1022:
+               return ("AMD 762 host to AGP bridge");
        };
  
        return NULL;
***************
*** 303,311 ****
  
        vas = ffs(aperture / 32*1024*1024) - 1;
        
        pci_write_config(dev, AGP_AMD751_APCTRL,
!                        ((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06)
!                         | vas << 1), 1);
  
        return 0;
  }
--- 333,346 ----
  
        vas = ffs(aperture / 32*1024*1024) - 1;
        
+       /*
+        * while the size register is bits 1-3 of APCTRL, bit 0 needs
+        * be set for the size value to be "valid"
+        */
+       
        pci_write_config(dev, AGP_AMD751_APCTRL,
!               (((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06) 
!                 | ((vas << 1) | 1))), 1); 
  
        return 0;
  }
***************
*** 318,324 ****
        if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
                return EINVAL;
  
!       sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1;
        return 0;
  }
  
--- 353,364 ----
        if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
                return EINVAL;
  
!       sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1 ; 
! 
!       /* ivalidate the cache */
!       AGP_FLUSH_TLB(dev);
!       
!       
        return 0;
  }
  
*** /usr/src/sys/pci/agpreg.h   Mon Nov 19 01:16:40 2001
--- agpreg.h    Sat Jan 19 01:35:20 2002
***************
*** 89,94 ****
--- 89,95 ----
  /*
   * Config offsets for the AMD 751 chipset.
   */
+ #define AGP_AMD751_APBASE     0x10
  #define AGP_AMD751_REGISTERS  0x14
  #define AGP_AMD751_APCTRL     0xac
  #define AGP_AMD751_MODECTRL   0xb0    
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200201190903.g0J93pc41164>