agp/intel: Fix cache control for Sandybridge
Sandybridge GTT has new cache control bits in PTE, which controls graphics page cache in LLC or LLC/MLC, so we need to extend the mask function to respect the new bits. And set cache control to always LLC only by default on Gen6. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Cc: stable@kernel.org Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
committed by
Chris Wilson
parent
93f5f7f124
commit
f8f235e5bb
@@ -12,6 +12,7 @@
|
|||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
#include "agp.h"
|
#include "agp.h"
|
||||||
#include "intel-agp.h"
|
#include "intel-agp.h"
|
||||||
|
#include <linux/intel-gtt.h>
|
||||||
|
|
||||||
#include "intel-gtt.c"
|
#include "intel-gtt.c"
|
||||||
|
|
||||||
|
@@ -49,6 +49,26 @@ static struct gatt_mask intel_i810_masks[] =
|
|||||||
.type = INTEL_AGP_CACHED_MEMORY}
|
.type = INTEL_AGP_CACHED_MEMORY}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define INTEL_AGP_UNCACHED_MEMORY 0
|
||||||
|
#define INTEL_AGP_CACHED_MEMORY_LLC 1
|
||||||
|
#define INTEL_AGP_CACHED_MEMORY_LLC_GFDT 2
|
||||||
|
#define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3
|
||||||
|
#define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4
|
||||||
|
|
||||||
|
static struct gatt_mask intel_gen6_masks[] =
|
||||||
|
{
|
||||||
|
{.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED,
|
||||||
|
.type = INTEL_AGP_UNCACHED_MEMORY },
|
||||||
|
{.mask = I810_PTE_VALID | GEN6_PTE_LLC,
|
||||||
|
.type = INTEL_AGP_CACHED_MEMORY_LLC },
|
||||||
|
{.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT,
|
||||||
|
.type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT },
|
||||||
|
{.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC,
|
||||||
|
.type = INTEL_AGP_CACHED_MEMORY_LLC_MLC },
|
||||||
|
{.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT,
|
||||||
|
.type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT },
|
||||||
|
};
|
||||||
|
|
||||||
static struct _intel_private {
|
static struct _intel_private {
|
||||||
struct pci_dev *pcidev; /* device one */
|
struct pci_dev *pcidev; /* device one */
|
||||||
u8 __iomem *registers;
|
u8 __iomem *registers;
|
||||||
@@ -178,13 +198,6 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
|
|||||||
off_t pg_start, int mask_type)
|
off_t pg_start, int mask_type)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
u32 cache_bits = 0;
|
|
||||||
|
|
||||||
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
|
|
||||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
|
|
||||||
{
|
|
||||||
cache_bits = GEN6_PTE_LLC_MLC;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
|
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
|
||||||
writel(agp_bridge->driver->mask_memory(agp_bridge,
|
writel(agp_bridge->driver->mask_memory(agp_bridge,
|
||||||
@@ -317,6 +330,23 @@ static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge,
|
||||||
|
int type)
|
||||||
|
{
|
||||||
|
unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT;
|
||||||
|
unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT;
|
||||||
|
|
||||||
|
if (type_mask == AGP_USER_UNCACHED_MEMORY)
|
||||||
|
return INTEL_AGP_UNCACHED_MEMORY;
|
||||||
|
else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
|
||||||
|
return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT :
|
||||||
|
INTEL_AGP_CACHED_MEMORY_LLC_MLC;
|
||||||
|
else /* set 'normal'/'cached' to LLC by default */
|
||||||
|
return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT :
|
||||||
|
INTEL_AGP_CACHED_MEMORY_LLC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
|
static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
|
||||||
int type)
|
int type)
|
||||||
{
|
{
|
||||||
@@ -1163,7 +1193,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
|
|||||||
|
|
||||||
mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
|
mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
|
||||||
|
|
||||||
if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
|
if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
|
||||||
mask_type != INTEL_AGP_CACHED_MEMORY)
|
mask_type != INTEL_AGP_CACHED_MEMORY)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
@@ -1563,7 +1593,7 @@ static const struct agp_bridge_driver intel_gen6_driver = {
|
|||||||
.fetch_size = intel_i9xx_fetch_size,
|
.fetch_size = intel_i9xx_fetch_size,
|
||||||
.cleanup = intel_i915_cleanup,
|
.cleanup = intel_i915_cleanup,
|
||||||
.mask_memory = intel_gen6_mask_memory,
|
.mask_memory = intel_gen6_mask_memory,
|
||||||
.masks = intel_i810_masks,
|
.masks = intel_gen6_masks,
|
||||||
.agp_enable = intel_i810_agp_enable,
|
.agp_enable = intel_i810_agp_enable,
|
||||||
.cache_flush = global_cache_flush,
|
.cache_flush = global_cache_flush,
|
||||||
.create_gatt_table = intel_i965_create_gatt_table,
|
.create_gatt_table = intel_i965_create_gatt_table,
|
||||||
@@ -1576,7 +1606,7 @@ static const struct agp_bridge_driver intel_gen6_driver = {
|
|||||||
.agp_alloc_pages = agp_generic_alloc_pages,
|
.agp_alloc_pages = agp_generic_alloc_pages,
|
||||||
.agp_destroy_page = agp_generic_destroy_page,
|
.agp_destroy_page = agp_generic_destroy_page,
|
||||||
.agp_destroy_pages = agp_generic_destroy_pages,
|
.agp_destroy_pages = agp_generic_destroy_pages,
|
||||||
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
|
.agp_type_to_mask_type = intel_gen6_type_to_mask_type,
|
||||||
.chipset_flush = intel_i915_chipset_flush,
|
.chipset_flush = intel_i915_chipset_flush,
|
||||||
#ifdef USE_PCI_DMA_API
|
#ifdef USE_PCI_DMA_API
|
||||||
.agp_map_page = intel_agp_map_page,
|
.agp_map_page = intel_agp_map_page,
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
#include <linux/intel-gtt.h>
|
||||||
|
|
||||||
static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
|
static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
|
||||||
static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
|
static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
|
||||||
|
20
include/linux/intel-gtt.h
Normal file
20
include/linux/intel-gtt.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Common Intel AGPGART and GTT definitions.
|
||||||
|
*/
|
||||||
|
#ifndef _INTEL_GTT_H
|
||||||
|
#define _INTEL_GTT_H
|
||||||
|
|
||||||
|
#include <linux/agp_backend.h>
|
||||||
|
|
||||||
|
/* This is for Intel only GTT controls.
|
||||||
|
*
|
||||||
|
* Sandybridge: AGP_USER_CACHED_MEMORY default to LLC only
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2)
|
||||||
|
#define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4)
|
||||||
|
|
||||||
|
/* flag for GFDT type */
|
||||||
|
#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3)
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user