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>