linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Jerome Glisse <j.glisse@gmail.com>
To: Christoph Hellwig <hch@lst.de>
Cc: linuxppc64-dev@ozlabs.org, linuxppc-dev@ozlabs.org
Subject: Re: U3 G5 AGP support patch (v4)
Date: Sun, 9 Jan 2005 18:46:05 +0100	[thread overview]
Message-ID: <4240b91605010909463e44bba8@mail.gmail.com> (raw)
In-Reply-To: <20050109160614.GA22839@lst.de>

[-- Attachment #1: Type: text/plain, Size: 335 bytes --]

> Please delcare separate driver instance instead of overriding.

I hope new patch follow codestyle ? :)
 
> And asm-ppc64 is still missing an agp.h, no?

Maybe, some one with better knowledge may tell us more on that :)
Anyway BenH tell me that there is still pending issue with agp & a
potential cache aliasing.

best,
Jerome Glisse

[-- Attachment #2: uninorth-patch5 --]
[-- Type: application/octet-stream, Size: 11216 bytes --]

diff -Nru linux/drivers/char/agp/Kconfig linux-new/drivers/char/agp/Kconfig
--- linux/drivers/char/agp/Kconfig	2004-12-26 14:39:28.000000000 +0100
+++ linux-new/drivers/char/agp/Kconfig	2005-01-09 14:53:07.000000000 +0100
@@ -155,11 +155,11 @@
 	default AGP
 
 config AGP_UNINORTH
-	tristate "Apple UniNorth AGP support"
+	tristate "Apple UniNorth & U3 AGP support"
 	depends on AGP && PPC_PMAC
 	help
 	  This option gives you AGP support for Apple machines with a
-	  UniNorth bridge.
+	  UniNorth or U3 (Apple G5) bridge.
 
 config AGP_EFFICEON
 	tristate "Transmeta Efficeon support"
diff -Nru linux/drivers/char/agp/uninorth-agp.c linux-new/drivers/char/agp/uninorth-agp.c
--- linux/drivers/char/agp/uninorth-agp.c	2004-12-26 14:39:28.000000000 +0100
+++ linux-new/drivers/char/agp/uninorth-agp.c	2005-01-09 18:31:51.000000000 +0100
@@ -8,8 +8,37 @@
 #include <linux/agp_backend.h>
 #include <asm/uninorth.h>
 #include <asm/pci-bridge.h>
+#include <asm/sections.h>
+#include <asm/prom.h>
 #include "agp.h"
 
+/*
+ * NOTES for uninorth3 (G5 AGP) supports :
+ *
+ * This are redundant with arch/ppc(64)/platforms/pmac_features.c,
+ * we need to know uninorth_rev any other way ?
+ *
+ * There maybe also possibility to have bigger cache line size for
+ * agp (see pmac_pci.c and look for cache line). Need to be investigated
+ * by someone.
+ *
+ * Darwin seems to add UNI_N_CFG_GART_PERFRD for all agp3 controller but
+ * this seems to work without this, so in order to minimize code differences
+ * between AGP2 & AGP3 uninorth, i do not set this.
+ *
+ * PAGE size are hardcoded but this may change, see asm/page.h.
+ *
+ * Jerome Glisse <j.glisse@gmail.com>
+ */
+static struct device_node *uninorth_node __pmacdata;
+static u32 __iomem *uninorth_base __pmacdata;
+static u32 uninorth_rev __pmacdata;
+
+/*
+ * Uninorth reg. access. Note that Uni-N regs are big endian
+ */
+#define UN_REG(r)	(uninorth_base + ((r) >> 2))
+
 static int uninorth_fetch_size(void)
 {
 	int i;
@@ -17,7 +46,7 @@
 	struct aper_size_info_32 *values;
 
 	pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
-	temp &= ~(0xfffff000);
+	temp &= ~PAGE_MASK;
 	values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
 
 	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
@@ -73,7 +102,7 @@
 	/* aperture size and gatt addr */
 	pci_write_config_dword(agp_bridge->dev,
 		UNI_N_CFG_GART_BASE,
-		(agp_bridge->gatt_bus_addr & 0xfffff000)
+		(agp_bridge->gatt_bus_addr & PAGE_MASK)
 			| current_size->size_value);
 
 	/* HACK ALERT
@@ -111,14 +140,55 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		agp_bridge->gatt_table[j] = cpu_to_le32((mem->memory[i] & 0xfffff000) | 0x00000001UL);
+		agp_bridge->gatt_table[j] = cpu_to_le32((mem->memory[i] &
+							 PAGE_MASK) |
+							0x00000001UL);
+		flush_dcache_range((unsigned long)__va(mem->memory[i]),
+				   (unsigned long)__va(mem->memory[i])+0x1000);
+	}
+	(void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
+	mb();
+	flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start], 
+		(unsigned long)&agp_bridge->gatt_table[pg_start +
+							mem->page_count]);
+
+	uninorth_tlbflush(mem);
+	return 0;
+}
+
+static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
+{
+	int i, j, num_entries;
+	void *temp;
+
+	temp = agp_bridge->current_size;
+	num_entries = A_SIZE_32(temp)->num_entries;
+
+	if (type != 0 || mem->type != 0)
+		/* We know nothing of memory types */
+		return -EINVAL;
+	if ((pg_start + mem->page_count) > num_entries)
+		return -EINVAL;
+
+	j = pg_start;
+
+	while (j < (pg_start + mem->page_count)) {
+		if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[j]))
+			return -EBUSY;
+		j++;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		agp_bridge->gatt_table[j] = ((mem->memory[i] >> PAGE_SHIFT) |
+						0x80000000UL);
 		flush_dcache_range((unsigned long)__va(mem->memory[i]),
 				   (unsigned long)__va(mem->memory[i])+0x1000);
 	}
 	(void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
 	mb();
 	flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start], 
-		(unsigned long)&agp_bridge->gatt_table[pg_start + mem->page_count]);
+		(unsigned long)&agp_bridge->gatt_table[pg_start +
+							mem->page_count]);
 
 	uninorth_tlbflush(mem);
 	return 0;
@@ -134,7 +204,23 @@
 			      &command);
 
 	command = agp_collect_device_status(mode, command);
-	command |= 0x100;
+	command |= UNI_N_CFG_GART_ENABLE;
+	
+	if (uninorth_rev == 0x21) {
+		/*
+		 * Darwin disable AGP 4x on this revision, thus we
+		 * may assume it's broken. This is an AGP2 controller.
+		 */
+		command &= ~AGPSTAT2_4X;
+	}
+
+	if ((uninorth_rev >= 0x30) && (uninorth_rev <= 0x33)) {
+		/*
+		 * We need to to set REQ_DEPTH to 7 for U3 versions 1.0, 2.1,
+		 * 2.2 and 2.3, Darwin do so.
+		 */
+		command |= (7 << AGPSTAT_RQ_DEPTH_SHIFT);
+	}
 
 	uninorth_tlbflush(NULL);
 
@@ -146,11 +232,17 @@
 		pci_read_config_dword(agp_bridge->dev,
 				       agp_bridge->capndx + PCI_AGP_COMMAND,
 				       &scratch);
-	} while ((scratch & 0x100) == 0 && ++timeout < 1000);
-	if ((scratch & 0x100) == 0)
+	} while ((scratch & UNI_N_CFG_GART_ENABLE) == 0 && ++timeout < 1000);
+	if ((scratch & UNI_N_CFG_GART_ENABLE) == 0)
 		printk(KERN_ERR PFX "failed to write UniNorth AGP command reg\n");
 
-	agp_device_command(command, 0);
+	if (agp_bridge->dev->device == PCI_DEVICE_ID_APPLE_U3_AGP) {
+		/* This is an AGP V3 */
+		agp_device_command(command, 1);
+	} else {
+		/* AGP V2 */
+		agp_device_command(command, 0);
+	}
 
 	uninorth_tlbflush(NULL);
 }
@@ -258,6 +350,22 @@
 	{4, 1024, 0, 1}
 };
 
+/*
+ * Not sure that u3 supports that high aperture sizes but it
+ * would strange if it did not :)
+ */
+static struct aper_size_info_32 u3_sizes[8] =
+{
+	{512, 131072, 7, 128},
+	{256, 65536, 6, 64},
+	{128, 32768, 5, 32},
+	{64, 16384, 4, 16},
+	{32, 8192, 3, 8},
+	{16, 4096, 2, 4},
+	{8, 2048, 1, 2},
+	{4, 1024, 0, 1}
+};
+
 struct agp_bridge_driver uninorth_agp_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= (void *)uninorth_sizes,
@@ -282,6 +390,30 @@
 	.cant_use_aperture	= 1,
 };
 
+struct agp_bridge_driver u3_agp_driver = {
+	.owner			= THIS_MODULE,
+	.aperture_sizes		= (void *)u3_sizes,
+	.size_type		= U32_APER_SIZE,
+	.num_aperture_sizes	= 8,
+	.configure		= uninorth_configure,
+	.fetch_size		= uninorth_fetch_size,
+	.cleanup		= uninorth_cleanup,
+	.tlb_flush		= uninorth_tlbflush,
+	.mask_memory		= agp_generic_mask_memory,
+	.masks			= NULL,
+	.cache_flush		= null_cache_flush,
+	.agp_enable		= uninorth_agp_enable,
+	.create_gatt_table	= uninorth_create_gatt_table,
+	.free_gatt_table	= uninorth_free_gatt_table,
+	.insert_memory		= u3_insert_memory,
+	.remove_memory		= agp_generic_remove_memory,
+	.alloc_by_type		= agp_generic_alloc_by_type,
+	.free_by_type		= agp_generic_free_by_type,
+	.agp_alloc_page		= agp_generic_alloc_page,
+	.agp_destroy_page	= agp_generic_destroy_page,
+	.cant_use_aperture	= 1,
+};
+
 static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
 	{
 		.device_id	= PCI_DEVICE_ID_APPLE_UNI_N_AGP,
@@ -299,6 +431,10 @@
 		.device_id	= PCI_DEVICE_ID_APPLE_UNI_N_AGP2,
 		.chipset_name	= "UniNorth 2",
 	},
+	{
+		.device_id	= PCI_DEVICE_ID_APPLE_U3_AGP,
+		.chipset_name	= "U3",
+	},
 };
 
 static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
@@ -327,11 +463,35 @@
 	return -ENODEV;
 
  found:
+	/* Set revision to 0 if we could not read it. */
+	uninorth_rev = 0;
+	/* Locate core99 Uni-N */
+	uninorth_node = of_find_node_by_name(NULL, "uni-n");
+	/* Locate G5 u3 */
+	if (uninorth_node == NULL) {
+		uninorth_node = of_find_node_by_name(NULL, "u3");
+	}
+	if (uninorth_node && uninorth_node->n_addrs > 0) {
+		unsigned long address = uninorth_node->addrs[0].address;
+		uninorth_base = ioremap(address, 0x40000);
+		uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
+		/*
+		 * Some revs have some high bits sets in the version register,
+		 * mask it thus they won't mess up with the version number
+		 */
+		uninorth_rev &= 0x3f;
+	}
+
 	bridge = agp_alloc_bridge();
 	if (!bridge)
 		return -ENOMEM;
 
-	bridge->driver = &uninorth_agp_driver;
+	if (pdev->device == PCI_DEVICE_ID_APPLE_U3_AGP) {
+		bridge->driver = &u3_agp_driver;
+	} else {
+		bridge->driver = &uninorth_agp_driver;
+	}
+
 	bridge->dev = pdev;
 	bridge->capndx = cap_ptr;
 
diff -Nru linux/drivers/ide/ppc/pmac.c linux-new/drivers/ide/ppc/pmac.c
--- linux/drivers/ide/ppc/pmac.c	2004-12-26 14:39:43.000000000 +0100
+++ linux-new/drivers/ide/ppc/pmac.c	2005-01-09 15:11:58.000000000 +0100
@@ -1527,7 +1527,7 @@
 };
 
 static struct pci_device_id pmac_ide_pci_match[] = {
-	{ PCI_VENDOR_ID_APPLE, PCI_DEVIEC_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 };
diff -Nru linux/include/asm/uninorth.h linux-new/include/asm/uninorth.h
--- linux/include/asm/uninorth.h	2004-12-26 14:40:03.000000000 +0100
+++ linux-new/include/asm/uninorth.h	2005-01-09 14:45:27.000000000 +0100
@@ -34,6 +34,11 @@
 #define UNI_N_CFG_GART_ENABLE		0x00000100
 #define UNI_N_CFG_GART_2xRESET		0x00010000
 #define UNI_N_CFG_GART_DISSBADET	0x00020000
+/* The following seems to only be used only on U3 <j.glisse@gmail.com> */
+#define U3_N_CFG_GART_SYNCMODE		0x00040000
+#define U3_N_CFG_GART_PERFRD		0x00080000
+#define U3_N_CFG_GART_B2BGNT		0x00200000
+#define U3_N_CFG_GART_FASTDDR		0x00400000
 
 /* My understanding of UniNorth AGP as of UniNorth rev 1.0x,
  * revision 1.5 (x4 AGP) may need further changes.
diff -Nru linux/include/asm-ppc/uninorth.h linux-new/include/asm-ppc/uninorth.h
--- linux/include/asm-ppc/uninorth.h	2004-12-26 14:40:03.000000000 +0100
+++ linux-new/include/asm-ppc/uninorth.h	2005-01-09 14:45:27.000000000 +0100
@@ -34,6 +34,11 @@
 #define UNI_N_CFG_GART_ENABLE		0x00000100
 #define UNI_N_CFG_GART_2xRESET		0x00010000
 #define UNI_N_CFG_GART_DISSBADET	0x00020000
+/* The following seems to only be used only on U3 <j.glisse@gmail.com> */
+#define U3_N_CFG_GART_SYNCMODE		0x00040000
+#define U3_N_CFG_GART_PERFRD		0x00080000
+#define U3_N_CFG_GART_B2BGNT		0x00200000
+#define U3_N_CFG_GART_FASTDDR		0x00400000
 
 /* My understanding of UniNorth AGP as of UniNorth rev 1.0x,
  * revision 1.5 (x4 AGP) may need further changes.
diff -Nru linux/include/linux/pci_ids.h linux-new/include/linux/pci_ids.h
--- linux/include/linux/pci_ids.h	2004-12-26 14:40:05.000000000 +0100
+++ linux-new/include/linux/pci_ids.h	2005-01-09 14:46:17.000000000 +0100
@@ -840,8 +840,9 @@
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15	0x002d
 #define PCI_DEVICE_ID_APPLE_UNI_N_FW2	0x0030
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2	0x0032
-#define PCI_DEVIEC_ID_APPLE_UNI_N_ATA	0x0033
+#define PCI_DEVICE_ID_APPLE_UNI_N_ATA	0x0033
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2	0x0034
+#define PCI_DEVICE_ID_APPLE_U3_AGP	0x0059
 #define PCI_DEVICE_ID_APPLE_IPID_ATA100	0x003b
 #define PCI_DEVICE_ID_APPLE_KEYLARGO_I	0x003e
 #define PCI_DEVICE_ID_APPLE_K2_ATA100	0x0043

  reply	other threads:[~2005-01-09 17:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-09 15:26 U3 G5 AGP support patch (v4) Jerome Glisse
2005-01-09 16:06 ` Christoph Hellwig
2005-01-09 17:46   ` Jerome Glisse [this message]
2005-01-09 20:41     ` Jerome Glisse
2005-01-10 18:16       ` Jerome Glisse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4240b91605010909463e44bba8@mail.gmail.com \
    --to=j.glisse@gmail.com \
    --cc=hch@lst.de \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=linuxppc64-dev@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).