intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] agp/intel: Fix cache control for Sandybridge
@ 2010-05-27  2:55 Zhenyu Wang
  2010-05-28 18:09 ` Eric Anholt
  0 siblings, 1 reply; 2+ messages in thread
From: Zhenyu Wang @ 2010-05-27  2:55 UTC (permalink / raw)
  To: eric; +Cc: intel-gfx

Sandybridge GTT has new cache control bits in PTE, which controls
graphics page cache in LLC or LLC/MLC. This one trys to setup a
new gtt driver for Gen6, and using new type mask function for that.
And this sets cache control to always LLC only by default on Gen6.

As this gtt memory cache control bits are internal to intel hw,
so I don't add new flags in agp_backend.h but add them only in
intel_gtt.c. So drm/i915 stuff needs to know these new flags too.

Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
---
 drivers/char/agp/intel-agp.c    |    4 +-
 drivers/char/agp/intel-agp.h    |    6 +++
 drivers/char/agp/intel-gtt.c    |   96 +++++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/i915_drv.h |   10 ++++
 4 files changed, 106 insertions(+), 10 deletions(-)

diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index d836a71..5bbc7be 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -816,9 +816,9 @@ static const struct intel_driver_description {
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
 	    "HD Graphics", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG,
-	    "Sandybridge", NULL, &intel_i965_driver },
+	    "Sandybridge", NULL, &intel_gen6_driver },
 	{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
-	    "Sandybridge", NULL, &intel_i965_driver },
+	    "Sandybridge", NULL, &intel_gen6_driver },
 	{ 0, 0, NULL, NULL, NULL }
 };
 
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h
index 2547465..c05e3e5 100644
--- a/drivers/char/agp/intel-agp.h
+++ b/drivers/char/agp/intel-agp.h
@@ -60,6 +60,12 @@
 #define I810_PTE_LOCAL		0x00000002
 #define I810_PTE_VALID		0x00000001
 #define I830_PTE_SYSTEM_CACHED  0x00000006
+/* GT PTE cache control fields */
+#define GEN6_PTE_UNCACHED	0x00000002
+#define GEN6_PTE_LLC		0x00000004
+#define GEN6_PTE_LLC_MLC	0x00000006
+#define GEN6_PTE_GFDT		0x00000008
+
 #define I810_SMRAM_MISCC	0x70
 #define I810_GFX_MEM_WIN_SIZE	0x00010000
 #define I810_GFX_MEM_WIN_32M	0x00010000
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index e8ea682..1a255a1 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -45,6 +45,33 @@ static struct gatt_mask intel_i810_masks[] =
 	 .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
+
+/* Don't try to pollute agp_backend.h...
+ * 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)
+/* bit flag for GFDT type */
+#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3)
+
+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 {
 	struct pci_dev *pcidev;	/* device one */
 	u8 __iomem *registers;
@@ -171,13 +198,6 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
 					off_t pg_start, int mask_type)
 {
 	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 = I830_PTE_SYSTEM_CACHED;
-	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
@@ -310,6 +330,22 @@ static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge,
 		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,
 				int type)
 {
@@ -1147,7 +1183,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);
 
-	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)
 		goto out_err;
 
@@ -1274,6 +1310,17 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
 	return addr | bridge->driver->masks[type].mask;
 }
 
+/* GEN6 support 40-bit physical address, bits 39:32 shift to
+ * bits 11:4. And GEN6 has new memory types.
+ */
+static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge,
+					    dma_addr_t addr, int type)
+{
+	addr |= (addr >> 28) & 0xff;
+
+	return addr | bridge->driver->masks[type].mask;
+}
+
 static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
 {
 	u16 snb_gmch_ctl;
@@ -1514,3 +1561,36 @@ static const struct agp_bridge_driver intel_g33_driver = {
 	.agp_unmap_memory	= intel_agp_unmap_memory,
 #endif
 };
+
+static const struct agp_bridge_driver intel_gen6_driver = {
+	.owner                  = THIS_MODULE,
+	.aperture_sizes         = intel_i830_sizes,
+	.size_type              = FIXED_APER_SIZE,
+	.num_aperture_sizes     = 4,
+	.needs_scratch_page     = true,
+	.configure              = intel_i915_configure,
+	.fetch_size             = intel_i9xx_fetch_size,
+	.cleanup                = intel_i915_cleanup,
+	.mask_memory            = intel_gen6_mask_memory,
+	.masks                  = intel_gen6_masks,
+	.agp_enable             = intel_i810_agp_enable,
+	.cache_flush            = global_cache_flush,
+	.create_gatt_table      = intel_i965_create_gatt_table,
+	.free_gatt_table        = intel_i830_free_gatt_table,
+	.insert_memory          = intel_i915_insert_entries,
+	.remove_memory          = intel_i915_remove_entries,
+	.alloc_by_type          = intel_i830_alloc_by_type,
+	.free_by_type           = intel_i810_free_by_type,
+	.agp_alloc_page         = agp_generic_alloc_page,
+	.agp_alloc_pages        = agp_generic_alloc_pages,
+	.agp_destroy_page       = agp_generic_destroy_page,
+	.agp_destroy_pages      = agp_generic_destroy_pages,
+	.agp_type_to_mask_type  = intel_gen6_type_to_mask_type,
+	.chipset_flush          = intel_i915_chipset_flush,
+#ifdef USE_PCI_DMA_API
+	.agp_map_page           = intel_agp_map_page,
+	.agp_unmap_page         = intel_agp_unmap_page,
+	.agp_map_memory         = intel_agp_map_memory,
+	.agp_unmap_memory       = intel_agp_unmap_memory,
+#endif
+};
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7f797ef..9710b4b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1170,4 +1170,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
+/* Intel specific agp_memory type for Gen6,
+ * must be same as in intel_gtt.c */
+
+/* GEN6: memory only cached in LLC. As default we always make
+ * memory cached in LLC. */
+#define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2)
+#define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4)
+/* GFDT bit flag */
+#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3)
+
 #endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [RFC PATCH] agp/intel: Fix cache control for Sandybridge
  2010-05-27  2:55 [RFC PATCH] agp/intel: Fix cache control for Sandybridge Zhenyu Wang
@ 2010-05-28 18:09 ` Eric Anholt
  0 siblings, 0 replies; 2+ messages in thread
From: Eric Anholt @ 2010-05-28 18:09 UTC (permalink / raw)
  To: Zhenyu Wang; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 891 bytes --]

On Thu, 27 May 2010 10:55:10 +0800, Zhenyu Wang <zhenyuw@linux.intel.com> wrote:
> Sandybridge GTT has new cache control bits in PTE, which controls
> graphics page cache in LLC or LLC/MLC. This one trys to setup a
> new gtt driver for Gen6, and using new type mask function for that.
> And this sets cache control to always LLC only by default on Gen6.
> 
> As this gtt memory cache control bits are internal to intel hw,
> so I don't add new flags in agp_backend.h but add them only in
> intel_gtt.c. So drm/i915 stuff needs to know these new flags too.
> 
> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>

Please put shared definitions in a header file instead of having two .c
files define them.  intel-agp.h maybe?  You might need to move the IS_*,
but they should probably be bitfields in device info like they are in
i915 now, and then the macros could go away.

[-- Attachment #1.2: Type: application/pgp-signature, Size: 197 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-05-28 18:09 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-27  2:55 [RFC PATCH] agp/intel: Fix cache control for Sandybridge Zhenyu Wang
2010-05-28 18:09 ` Eric Anholt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).