Module Name: src Committed By: riastradh Date: Fri Mar 6 22:03:06 UTC 2015
Modified Files: src/sys/dev/pci: agp_i810.c agp_i810var.h src/sys/external/bsd/drm2/i915drm: intel_gtt.c src/sys/external/bsd/drm2/include/drm: intel-gtt.h Log Message: Pass cache-related flags through to the GTT on pre-SNB devices. I had assumed for ages this would increase the amount of caching and thereby increase the chance of stale caches leading to rendering glitches. But apparently I was wrong, and failing to pass these through was causing all sorts of problems! To generate a diff of this commit: cvs rdiff -u -r1.116 -r1.117 src/sys/dev/pci/agp_i810.c cvs rdiff -u -r1.5 -r1.6 src/sys/dev/pci/agp_i810var.h cvs rdiff -u -r1.4 -r1.5 src/sys/external/bsd/drm2/i915drm/intel_gtt.c cvs rdiff -u -r1.4 -r1.5 src/sys/external/bsd/drm2/include/drm/intel-gtt.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/agp_i810.c diff -u src/sys/dev/pci/agp_i810.c:1.116 src/sys/dev/pci/agp_i810.c:1.117 --- src/sys/dev/pci/agp_i810.c:1.116 Thu Feb 26 00:58:17 2015 +++ src/sys/dev/pci/agp_i810.c Fri Mar 6 22:03:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: agp_i810.c,v 1.116 2015/02/26 00:58:17 riastradh Exp $ */ +/* $NetBSD: agp_i810.c,v 1.117 2015/03/06 22:03:06 riastradh Exp $ */ /*- * Copyright (c) 2000 Doug Rabson @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.116 2015/02/26 00:58:17 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.117 2015/03/06 22:03:06 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -120,15 +120,23 @@ static struct agp_methods agp_i810_metho }; int -agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, bus_addr_t v) +agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, + bus_addr_t addr, int flags) { u_int32_t pte; - /* Bits 11:4 (physical start address extension) should be zero. */ - if ((v & 0xff0) != 0) + /* + * Bits 11:4 (physical start address extension) should be zero. + * Flag bits 3:0 should be zero too. + * + * XXX This should be a kassert -- no reason for this routine + * to allow failure. + */ + if ((addr & 0xfff) != 0) return EINVAL; + KASSERT(flags == (flags & 0x7)); - pte = (u_int32_t)v; + pte = (u_int32_t)addr; /* * We need to massage the pte if bus_addr_t is wider than 32 bits. * The compiler isn't smart enough, hence the casts to uintmax_t. @@ -138,17 +146,17 @@ agp_i810_write_gtt_entry(struct agp_i810 if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33 || isc->chiptype == CHIP_G4X) { - if (((uintmax_t)v >> 36) != 0) + if (((uintmax_t)addr >> 36) != 0) return EINVAL; - pte |= (v >> 28) & 0xf0; + pte |= (addr >> 28) & 0xf0; } else { - if (((uintmax_t)v >> 32) != 0) + if (((uintmax_t)addr >> 32) != 0) return EINVAL; } } bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, - 4*(off >> AGP_PAGE_SHIFT), pte); + 4*(off >> AGP_PAGE_SHIFT), pte | flags); return 0; } @@ -1128,7 +1136,8 @@ agp_i810_bind_page(struct agp_softc *sc, } } - return agp_i810_write_gtt_entry(isc, offset, physical | 1); + return agp_i810_write_gtt_entry(isc, offset, physical, + AGP_I810_GTT_VALID); } static int @@ -1146,7 +1155,7 @@ agp_i810_unbind_page(struct agp_softc *s } } - return agp_i810_write_gtt_entry(isc, offset, 0); + return agp_i810_write_gtt_entry(isc, offset, 0, 0); } /* @@ -1322,9 +1331,6 @@ agp_i810_bind_memory(struct agp_softc *s return 0; } -#define I810_GTT_PTE_VALID 0x01 -#define I810_GTT_PTE_DCACHE 0x02 - static int agp_i810_bind_memory_dcache(struct agp_softc *sc, struct agp_memory *mem, off_t offset) @@ -1338,7 +1344,7 @@ agp_i810_bind_memory_dcache(struct agp_s KASSERT((mem->am_size & (AGP_PAGE_SIZE - 1)) == 0); for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { error = agp_i810_write_gtt_entry(isc, offset + i, - i | I810_GTT_PTE_VALID | I810_GTT_PTE_DCACHE); + i, AGP_I810_GTT_VALID | AGP_I810_GTT_I810_DCACHE); if (error) goto fail0; } Index: src/sys/dev/pci/agp_i810var.h diff -u src/sys/dev/pci/agp_i810var.h:1.5 src/sys/dev/pci/agp_i810var.h:1.6 --- src/sys/dev/pci/agp_i810var.h:1.5 Tue Jun 10 14:00:56 2014 +++ src/sys/dev/pci/agp_i810var.h Fri Mar 6 22:03:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: agp_i810var.h,v 1.5 2014/06/10 14:00:56 riastradh Exp $ */ +/* $NetBSD: agp_i810var.h,v 1.6 2015/03/06 22:03:06 riastradh Exp $ */ /*- * Copyright (c) 2000 Doug Rabson @@ -67,6 +67,11 @@ struct agp_i810_softc { extern struct agp_softc *agp_i810_sc; -int agp_i810_write_gtt_entry(struct agp_i810_softc *, off_t, bus_addr_t); +#define AGP_I810_GTT_VALID 0x01 +#define AGP_I810_GTT_I810_DCACHE 0x02 /* i810-only */ +#define AGP_I810_GTT_CACHED 0x06 /* >=i830 */ + +int agp_i810_write_gtt_entry(struct agp_i810_softc *, off_t, bus_addr_t, + int); void agp_i810_post_gtt_entry(struct agp_i810_softc *, off_t); void agp_i810_chipset_flush(struct agp_i810_softc *); Index: src/sys/external/bsd/drm2/i915drm/intel_gtt.c diff -u src/sys/external/bsd/drm2/i915drm/intel_gtt.c:1.4 src/sys/external/bsd/drm2/i915drm/intel_gtt.c:1.5 --- src/sys/external/bsd/drm2/i915drm/intel_gtt.c:1.4 Wed Jul 16 20:56:25 2014 +++ src/sys/external/bsd/drm2/i915drm/intel_gtt.c Fri Mar 6 22:03:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: intel_gtt.c,v 1.4 2014/07/16 20:56:25 riastradh Exp $ */ +/* $NetBSD: intel_gtt.c,v 1.5 2015/03/06 22:03:06 riastradh Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ /* Intel GTT stubs */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intel_gtt.c,v 1.4 2014/07/16 20:56:25 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intel_gtt.c,v 1.5 2015/03/06 22:03:06 riastradh Exp $"); #include <sys/types.h> #include <sys/bus.h> @@ -143,19 +143,31 @@ intel_gtt_insert_entries(bus_dmamap_t dm struct agp_i810_softc *const isc = agp_i810_sc->as_chipc; off_t va = (va_page << PAGE_SHIFT); unsigned seg; + int gtt_flags = 0; int error; KASSERT(0 <= va); KASSERT((va >> PAGE_SHIFT) == va_page); KASSERT(0 < dmamap->dm_nsegs); + gtt_flags |= AGP_I810_GTT_VALID; + switch (flags) { + case AGP_USER_MEMORY: + break; + case AGP_USER_CACHED_MEMORY: + gtt_flags |= AGP_I810_GTT_CACHED; + break; + default: + panic("invalid intel gtt flags: %x", flags); + } + for (seg = 0; seg < dmamap->dm_nsegs; seg++) { const bus_addr_t addr = dmamap->dm_segs[seg].ds_addr; KASSERT(dmamap->dm_segs[seg].ds_len == PAGE_SIZE); /* XXX Respect flags. */ - error = agp_i810_write_gtt_entry(isc, va, (addr | 1)); + error = agp_i810_write_gtt_entry(isc, va, addr, gtt_flags); if (error) device_printf(agp_i810_sc->as_dev, "write gtt entry" @@ -171,6 +183,7 @@ intel_gtt_clear_range(unsigned va_page, { struct agp_i810_softc *const isc = agp_i810_sc->as_chipc; const bus_addr_t addr = intel_gtt.scratch_map->dm_segs[0].ds_addr; + const int gtt_flags = AGP_I810_GTT_VALID; off_t va = (va_page << PAGE_SHIFT); KASSERT(0 <= va); @@ -178,7 +191,7 @@ intel_gtt_clear_range(unsigned va_page, KASSERT(0 < npages); while (npages--) { - agp_i810_write_gtt_entry(isc, va, (addr | 1)); + agp_i810_write_gtt_entry(isc, va, addr, gtt_flags); va += PAGE_SIZE; } agp_i810_post_gtt_entry(isc, va - PAGE_SIZE); Index: src/sys/external/bsd/drm2/include/drm/intel-gtt.h diff -u src/sys/external/bsd/drm2/include/drm/intel-gtt.h:1.4 src/sys/external/bsd/drm2/include/drm/intel-gtt.h:1.5 --- src/sys/external/bsd/drm2/include/drm/intel-gtt.h:1.4 Wed Jul 16 20:56:25 2014 +++ src/sys/external/bsd/drm2/include/drm/intel-gtt.h Fri Mar 6 22:03:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: intel-gtt.h,v 1.4 2014/07/16 20:56:25 riastradh Exp $ */ +/* $NetBSD: intel-gtt.h,v 1.5 2015/03/06 22:03:06 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -50,14 +50,8 @@ void intel_gtt_chipset_flush(void); void intel_gtt_insert_entries(bus_dmamap_t, unsigned, unsigned); void intel_gtt_clear_range(unsigned, unsigned); -#define AGP_DCACHE_MEMORY 1 -#define AGP_PHYS_MEMORY 2 - -/* XXX Dummy stubs -- should make these mean something and respect them. */ -#define AGP_USER_MEMORY 0 -#define AGP_USER_CACHED_MEMORY 0 - -#define AGP_USER_CACHED_MEMORY_GFDT __BIT(3) +#define AGP_USER_MEMORY 1 +#define AGP_USER_CACHED_MEMORY 2 extern int intel_iommu_gfx_mapped;