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!
This commit is contained in:
parent
8bf6e1b17b
commit
1a0c0250a7
|
@ -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_methods = {
|
|||
};
|
||||
|
||||
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_softc *isc, off_t off, bus_addr_t v)
|
|||
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, off_t offset, bus_addr_t physical)
|
|||
}
|
||||
}
|
||||
|
||||
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 *sc, off_t offset)
|
|||
}
|
||||
}
|
||||
|
||||
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 *sc, struct agp_memory *mem,
|
|||
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_softc *sc, struct agp_memory *mem,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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 dmamap, unsigned va_page, unsigned flags)
|
|||
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, unsigned npages)
|
|||
{
|
||||
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, unsigned npages)
|
|||
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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue