mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [RFC V2 0/6] barebox PCI support
@ 2012-03-08 19:50 Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 1/6] PCI: initial commit (draft) Antony Pavlov
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

This patch series introduce PCI support to barebox.

Thanks to Jean-Christophe PLAGNIOL-VILLARD for reviewing and adding
some PCI common code.

The patches are draft. They need a very big future work, so I put on them "RFC"
title instead of "PATCH".

[RFC V2 1/6] PCI: initial commit (draft)
[RFC V2 2/6] MIPS: add file gt64120.h from linux 2.6.39
[RFC V2 3/6] MIPS: add PCI support for GT64120-based malta
[RFC V2 4/6] PCI: add draft lspci command
[RFC V2 5/6] net: add Realtek 8139 Ethernet controller support
[RFC V2 6/6] net: add DEC 21143 (tulip) Ethernet controller support

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [RFC V2 1/6] PCI: initial commit (draft)
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
@ 2012-03-08 19:50 ` Antony Pavlov
  2012-03-09 18:01   ` Sascha Hauer
  2012-03-08 19:50 ` [RFC V2 2/6] MIPS: add file gt64120.h from linux 2.6.39 Antony Pavlov
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

used shorten version of linux-2.6.39 pci_ids.h

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/Makefile                |    1 +
 drivers/pci/Kconfig             |   12 +
 drivers/pci/Makefile            |    8 +
 drivers/pci/bus.c               |  103 ++++++
 drivers/pci/pci.c               |  347 +++++++++++++++++++
 include/linux/mod_devicetable.h |   24 ++
 include/linux/pci.h             |  270 +++++++++++++++
 include/linux/pci_ids.h         |  136 ++++++++
 include/linux/pci_regs.h        |  698 +++++++++++++++++++++++++++++++++++++++
 9 files changed, 1599 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pci/Kconfig
 create mode 100644 drivers/pci/Makefile
 create mode 100644 drivers/pci/bus.c
 create mode 100644 drivers/pci/pci.c
 create mode 100644 include/linux/mod_devicetable.h
 create mode 100644 include/linux/pci.h
 create mode 100644 include/linux/pci_ids.h
 create mode 100644 include/linux/pci_regs.h

diff --git a/drivers/Makefile b/drivers/Makefile
index 3aefc12..f3e61d4 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_LED) += led/
 obj-y	+= eeprom/
 obj-$(CONFIG_PWM) += pwm/
 obj-y	+= input/
+obj-$(CONFIG_PCI) += pci/
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
new file mode 100644
index 0000000..88b8dfb
--- /dev/null
+++ b/drivers/pci/Kconfig
@@ -0,0 +1,12 @@
+#
+# PCI configuration
+#
+config PCI_DEBUG
+	bool "PCI Debugging"
+	depends on PCI
+	help
+	  Say Y here if you want the PCI core to produce a bunch of debug
+	  messages to the system log.  Select this if you are having a
+	  problem with PCI support and want to see more of what is going on.
+
+	  When in doubt, say N.
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
new file mode 100644
index 0000000..c7d43c3
--- /dev/null
+++ b/drivers/pci/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the PCI bus specific drivers.
+#
+obj-y		+= pci.o bus.o
+
+ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
+
+CPPFLAGS += $(ccflags-y)
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
new file mode 100644
index 0000000..ca1a8d5
--- /dev/null
+++ b/drivers/pci/bus.c
@@ -0,0 +1,103 @@
+#include <common.h>
+#include <driver.h>
+#include <linux/pci.h>
+
+/**
+ * pci_match_one_device - Tell if a PCI device structure has a matching
+ *                        PCI device id structure
+ * @id: single PCI device id structure to match
+ * @dev: the PCI device structure to match against
+ *
+ * Returns the matching pci_device_id structure or %NULL if there is no match.
+ */
+static inline const struct pci_device_id *
+pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
+{
+	if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
+	    (id->device == PCI_ANY_ID || id->device == dev->device) &&
+	    (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
+	    (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
+	    !((id->class ^ dev->class) & id->class_mask))
+		return id;
+	return NULL;
+}
+
+static int pci_match(struct device_d *dev, struct driver_d *drv)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pci_driver *pdrv = to_pci_driver(drv);
+	struct pci_device_id *id;
+
+	for (id = (struct pci_device_id*)pdrv->id_table; id->vendor; id++)
+		if (pci_match_one_device(id, pdev)) {
+			dev->priv = id;
+			return 0;
+		}
+
+	return -1;
+}
+
+static int pci_probe(struct device_d *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pci_driver *pdrv = to_pci_driver(dev->driver);
+
+	return pdrv->probe(pdev, dev->priv);
+}
+
+static void pci_remove(struct device_d *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pci_driver *pdrv = to_pci_driver(dev->driver);
+
+	pdrv->remove(pdev);
+}
+
+struct bus_type pci_bus = {
+	.name = "pci",
+	.match = pci_match,
+	.probe = pci_probe,
+	.remove = pci_remove,
+};
+
+int pci_register_driver(struct pci_driver *pdrv)
+{
+	struct driver_d *drv = &pdrv->driver;
+
+	if (!pdrv->id_table)
+		return -EIO;
+
+	strcpy(drv->name, pdrv->name);
+	drv->bus = &pci_bus;
+
+	return register_driver(drv);
+}
+
+int pci_register_device(struct pci_dev *pdev)
+{
+	char str[6];
+	struct device_d *dev = &pdev->dev;
+	int ret;
+
+	strcpy(dev->name, "pci");
+	dev->bus = &pci_bus;
+	dev->id = -1;
+
+	ret = register_device(dev);
+
+	if (ret)
+		return ret;
+
+	sprintf(str, "%02x", pdev->devfn);
+	dev_add_param_fixed(dev, "devfn", str);
+	sprintf(str, "%04x", (pdev->class >> 8) & 0xffff);
+	dev_add_param_fixed(dev, "class", str);
+	sprintf(str, "%04x", pdev->vendor);
+	dev_add_param_fixed(dev, "vendor", str);
+	sprintf(str, "%04x", pdev->device);
+	dev_add_param_fixed(dev, "device", str);
+	sprintf(str, "%04x", pdev->revision);
+	dev_add_param_fixed(dev, "revision", str);
+
+	return 0;
+}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
new file mode 100644
index 0000000..d1df399
--- /dev/null
+++ b/drivers/pci/pci.c
@@ -0,0 +1,347 @@
+#include <common.h>
+#include <init.h>
+#include <linux/pci.h>
+
+#include <command.h>
+#include <debug_ll.h>
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+unsigned int pci_scan_bus(struct pci_bus *bus);
+
+static struct pci_controller *hose_head, **hose_tail = &hose_head;
+
+struct pci_bus *pci_root;
+struct pci_dev *pci_devices = NULL;
+static struct pci_dev **pci_last_dev_p = &pci_devices;
+
+static struct pci_bus * pci_alloc_bus(void)
+{
+	struct pci_bus *b;
+
+	b = kzalloc(sizeof(*b), GFP_KERNEL);
+	if (b) {
+		INIT_LIST_HEAD(&b->node);
+		INIT_LIST_HEAD(&b->children);
+		INIT_LIST_HEAD(&b->devices);
+		INIT_LIST_HEAD(&b->slots);
+		INIT_LIST_HEAD(&b->resources);
+		//b->max_bus_speed = PCI_SPEED_UNKNOWN;
+		//b->cur_bus_speed = PCI_SPEED_UNKNOWN;
+	}
+	return b;
+}
+
+void register_pci_controller(struct pci_controller *hose)
+{
+	struct pci_bus *bus;
+
+	printf("PCI: register_pci_controller() \n");
+
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+
+	bus = pci_alloc_bus();
+	hose->bus = bus;
+	bus->ops = hose->pci_ops;
+	bus->resource[0] = hose->mem_resource;
+	bus->resource[1] = hose->io_resource;
+
+	pci_scan_bus(bus);
+
+	pci_root = bus;
+
+	return;
+}
+
+int
+pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, u8 where, u8 *val)
+{
+	u32 data;
+	int status;
+
+	status = bus->ops->read(bus, devfn, where & 0xfc, 4, &data);
+	*val = (u8) (data >> ((where & 3) << 3));
+	return status;
+}
+
+int
+pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, u8 where, u16 *val)
+{
+	u32 data;
+	int status;
+
+	status = bus->ops->read(bus, devfn, where & 0xfc, 4, &data);
+	*val = (u16) (data >> ((where & 3) << 3));
+	return status;
+}
+
+int
+pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn, u8 where, u32 *val)
+{
+	return bus->ops->read(bus, devfn, where, 4, val);
+}
+
+int
+pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, u8 where, u8 val)
+{
+	u32 data;
+	int status;
+
+	bus->ops->read(bus, devfn, where & 0xfc, 4, &data);
+	data = (data & ~(0xff << ((where & 3) << 3))) | (val << ((where & 3) << 3));
+	status = bus->ops->write(bus, devfn, where & 0xfc, 4, data);
+
+	return status;
+}
+
+int
+pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, u8 where, u16 val)
+{
+	u32 data;
+	int status;
+
+	bus->ops->read(bus, devfn, where & 0xfc, 4, &data);
+	data = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3));
+	status = bus->ops->write(bus, devfn, where & 0xfc, 4, data);
+
+	return status;
+}
+
+int
+pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, u8 where, u32 val)
+{
+	return bus->ops->write(bus, devfn, where, 4, val);
+}
+
+int
+pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val)
+{
+	return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
+}
+
+int
+pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val)
+{
+	return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
+}
+
+int
+pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val)
+{
+	return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
+}
+
+int
+pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val)
+{
+	return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
+}
+
+int
+pci_write_config_word(struct pci_dev *dev, u8 where, u16 val)
+{
+	return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
+}
+
+int
+pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val)
+{
+	return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
+}
+
+struct pci_dev *alloc_pci_dev(void)
+{
+	struct pci_dev *dev;
+
+	dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	INIT_LIST_HEAD(&dev->bus_list);
+
+	return dev;
+}
+
+unsigned int pci_scan_bus(struct pci_bus *bus)
+{
+	unsigned int devfn, l, max, class;
+	unsigned char cmd, irq, tmp, hdr_type, is_multi = 0;
+	struct pci_dev *dev, **bus_last;
+	struct pci_bus *child;
+	resource_size_t last_mem;
+	resource_size_t last_io;
+
+	//last_mem = bus->ops->res_start(bus,
+	last_mem = bus->resource[0]->start;
+	last_io = bus->resource[1]->start;
+	// FIXME
+	// add 0x1000: skip malta serial port
+	last_io += 0x1000;
+
+	DBG("pci_scan_bus for bus %d\n", bus->number);
+	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
+	bus_last = &bus->devices;
+	max = bus->secondary;
+
+	for (devfn = 0; devfn < 0xff; ++devfn) {
+		if (PCI_FUNC(devfn) && !is_multi) {
+			/* not a multi-function device */
+			continue;
+		}
+		if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
+			continue;
+		if (!PCI_FUNC(devfn))
+			is_multi = hdr_type & 0x80;
+
+		if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l) ||
+		    /* some broken boards return 0 if a slot is empty: */
+		    l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000)
+			continue;
+
+		dev = alloc_pci_dev();
+		if (!dev)
+			return 0;
+
+		dev->bus = bus;
+		dev->devfn = devfn;
+		dev->vendor = l & 0xffff;
+		dev->device = (l >> 16) & 0xffff;
+
+		/* non-destructively determine if device can be a master: */
+		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
+		pci_write_config_byte(dev, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);
+		pci_read_config_byte(dev, PCI_COMMAND, &tmp);
+		//dev->master = ((tmp & PCI_COMMAND_MASTER) != 0);
+		pci_write_config_byte(dev, PCI_COMMAND, cmd);
+
+		pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
+		dev->revision = class & 0xff;
+		class >>= 8;				    /* upper 3 bytes */
+		dev->class = class;
+		class >>= 8;
+		dev->hdr_type = hdr_type;
+
+		DBG("PCI: class = %08x, hdr_type = %08x\n", class, hdr_type);
+
+		switch (hdr_type & 0x7f) {		    /* header type */
+		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
+			if (class == PCI_CLASS_BRIDGE_PCI)
+				goto bad;
+			/*
+			 * If the card generates interrupts, read IRQ number
+			 * (some architectures change it during pcibios_fixup())
+			 */
+			pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
+			if (irq)
+				pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+			dev->irq = irq;
+			/*
+			 * read base address registers, again pcibios_fixup() can
+			 * tweak these
+			 */
+	//		pci_read_bases(dev, 6);
+			pci_read_config_dword(dev, PCI_ROM_ADDRESS, &l);
+			dev->rom_address = (l == 0xffffffff) ? 0 : l;
+			break;
+		#if 0
+		case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
+			if (class != PCI_CLASS_BRIDGE_PCI)
+				goto bad;
+			pci_read_bases(dev, 2);
+			pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l);
+			dev->rom_address = (l == 0xffffffff) ? 0 : l;
+			break;
+		case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
+			if (class != PCI_CLASS_BRIDGE_CARDBUS)
+				goto bad;
+			pci_read_bases(dev, 1);
+			break;
+#endif
+		default:				    /* unknown header */
+		bad:
+			printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
+			       bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
+			continue;
+		}
+
+		DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
+
+		list_add_tail(&dev->bus_list, &bus->devices);
+		pci_register_device(dev);
+
+		if (class == PCI_CLASS_BRIDGE_HOST) {
+			DBG("PCI: skip pci host bridge\n");
+			continue;
+		}
+
+		{
+			int bar;
+			u32 old_bar, mask;
+			int size;
+
+			for (bar = 0; bar < 6; bar++) {
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &old_bar);
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
+			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, old_bar);
+
+			if (mask == 0 || mask == 0xffffffff) {
+				//DBG("  PCI: pbar%d set bad mask\n", bar);
+				continue;
+			}
+
+			if (mask & 0x01) { /* IO */
+				size = -(mask & 0xfffffffe);
+				DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
+				DBG("       mapped to 0x%08x (0x%08x)\n", last_io, bus->ops->res_start(bus, last_io));
+				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
+				last_io += size;
+
+			} else { /* MEM */
+				size = -(mask & 0xfffffff0);
+				DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
+				DBG("       mapped to 0x%08x (0x%08x)\n", last_mem, bus->ops->res_start(bus, last_mem));
+				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
+				last_mem += size;
+			}
+			}
+		}
+	}
+
+	/*
+	 * After performing arch-dependent fixup of the bus, look behind
+	 * all PCI-to-PCI bridges on this bus.
+	 */
+	//pcibios_fixup_bus(bus);
+
+	/*
+	 * We've scanned the bus and so we know all about what's on
+	 * the other side of any bridges that may be on this bus plus
+	 * any devices.
+	 *
+	 * Return how far we've got finding sub-buses.
+	 */
+	DBG("PCI: pci_scan_bus returning with max=%02x\n", max);
+	return max;
+}
+
+static int pci_init(void)
+{
+	pcibios_init();
+
+	if (!pci_present()) {
+		printf("PCI: No PCI bus detected\n");
+		return 0;
+	}
+
+	/* give BIOS a chance to apply platform specific fixes: */
+	//pcibios_fixup();
+
+	return 0;
+}
+postcore_initcall(pci_init);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
new file mode 100644
index 0000000..911e461
--- /dev/null
+++ b/include/linux/mod_devicetable.h
@@ -0,0 +1,24 @@
+/*
+ * Device tables which are exported to userspace via
+ * scripts/mod/file2alias.c.  You must keep that file in sync with this
+ * header.
+ */
+
+#ifndef LINUX_MOD_DEVICETABLE_H
+#define LINUX_MOD_DEVICETABLE_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+typedef unsigned long kernel_ulong_t;
+#endif
+
+#define PCI_ANY_ID (~0)
+
+struct pci_device_id {
+	__u32 vendor, device;		/* Vendor and device ID or PCI_ANY_ID*/
+	__u32 subvendor, subdevice;	/* Subsystem ID's or PCI_ANY_ID */
+	__u32 class, class_mask;	/* (class,subclass,prog-if) triplet */
+	kernel_ulong_t driver_data;	/* Data private to the driver */
+};
+
+#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
new file mode 100644
index 0000000..e3d50d6
--- /dev/null
+++ b/include/linux/pci.h
@@ -0,0 +1,270 @@
+/*
+ *	pci.h
+ *
+ *	PCI defines and function prototypes
+ *	Copyright 1994, Drew Eckhardt
+ *	Copyright 1997--1999 Martin Mares <mj@ucw.cz>
+ *
+ *	For more information, please consult the following manuals (look at
+ *	http://www.pcisig.com/ for how to get them):
+ *
+ *	PCI BIOS Specification
+ *	PCI Local Bus Specification
+ *	PCI to PCI Bridge Specification
+ *	PCI System Design Guide
+ */
+
+#ifndef LINUX_PCI_H
+#define LINUX_PCI_H
+
+#include <linux/pci_regs.h>	/* The pci register defines */
+
+/*
+ * The PCI interface treats multi-function devices as independent
+ * devices.  The slot/function address of each device is encoded
+ * in a single byte as follows:
+ *
+ *	7:3 = slot
+ *	2:0 = function
+ */
+#define PCI_DEVFN(slot, func)	((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn)		(((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn)		((devfn) & 0x07)
+
+/* Ioctls for /proc/bus/pci/X/Y nodes. */
+#define PCIIOC_BASE		('P' << 24 | 'C' << 16 | 'I' << 8)
+#define PCIIOC_CONTROLLER	(PCIIOC_BASE | 0x00)	/* Get controller for PCI device. */
+#define PCIIOC_MMAP_IS_IO	(PCIIOC_BASE | 0x01)	/* Set mmap state to I/O space. */
+#define PCIIOC_MMAP_IS_MEM	(PCIIOC_BASE | 0x02)	/* Set mmap state to MEM space. */
+#define PCIIOC_WRITE_COMBINE	(PCIIOC_BASE | 0x03)	/* Enable/disable write-combining. */
+
+#ifdef __KERNEL__
+
+#include <linux/mod_devicetable.h>
+
+#include <linux/types.h>
+#include <init.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/compiler.h>
+#include <errno.h>
+//#include <linux/kobject.h>
+//#include <asm/atomic.h>
+//#include <linux/device.h>
+#include <asm/io.h>
+//#include <linux/irqreturn.h>
+
+/* Include the ID list */
+#include <linux/pci_ids.h>
+
+/* Include architecture-dependent settings and functions */
+
+//#include <asm/pci.h>
+
+/*
+ * Error values that may be returned by PCI functions.
+ */
+#define PCIBIOS_SUCCESSFUL		0x00
+#define PCIBIOS_FUNC_NOT_SUPPORTED	0x81
+#define PCIBIOS_BAD_VENDOR_ID		0x83
+#define PCIBIOS_DEVICE_NOT_FOUND	0x86
+#define PCIBIOS_BAD_REGISTER_NUMBER	0x87
+#define PCIBIOS_SET_FAILED		0x88
+#define PCIBIOS_BUFFER_TOO_SMALL	0x89
+
+#define DEVICE_COUNT_RESOURCE	12
+#define PCI_BRIDGE_RESOURCE_NUM 2
+/*
+ * There is one pci_dev structure for each slot-number/function-number
+ * combination:
+ */
+struct pci_dev {
+	struct list_head bus_list;	/* node in per-bus list */
+	struct pci_bus	*bus;		/* bus this device is on */
+	struct pci_bus	*subordinate;	/* bus this device bridges to */
+
+	void		*sysdata;	/* hook for sys-specific extension */
+	struct proc_dir_entry *procent;	/* device entry in /proc/bus/pci */
+	struct pci_slot	*slot;		/* Physical slot this device is in */
+
+	struct device_d dev;
+
+	unsigned int	devfn;		/* encoded device & function index */
+	unsigned short	vendor;
+	unsigned short	device;
+	unsigned short	subsystem_vendor;
+	unsigned short	subsystem_device;
+	unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */
+	u8		revision;	/* PCI revision, low byte of class word */
+	u8		hdr_type;	/* PCI header type (`multi' flag masked out) */
+	u8		pcie_cap;	/* PCI-E capability offset */
+	u8		pcie_type;	/* PCI-E device/port type */
+	u8		rom_base_reg;	/* which config register controls the ROM */
+	u8		pin;  		/* which interrupt pin this device uses */
+
+	/*
+	 * In theory, the irq level can be read from configuration
+	 * space and all would be fine.  However, old PCI chips don't
+	 * support these registers and return 0 instead.  For example,
+	 * the Vision864-P rev 0 chip can uses INTA, but returns 0 in
+	 * the interrupt line and pin registers.  pci_init()
+	 * initializes this field with the value at PCI_INTERRUPT_LINE
+	 * and it is the job of pcibios_fixup() to change it if
+	 * necessary.  The field must not be 0 unless the device
+	 * cannot generate interrupts at all.
+	 */
+	unsigned int	irq;		/* irq generated by this device */
+	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
+
+	/* Base registers for this device, can be adjusted by
+	 * pcibios_fixup() as necessary.
+	 */
+	unsigned long	base_address[6];
+	unsigned long	rom_address;
+};
+#define	to_pci_dev(dev) container_of(dev, struct pci_dev, dev)
+
+struct pci_bus {
+	struct list_head node;		/* node in list of buses */
+	struct pci_bus	*parent;	/* parent bus this bridge is on */
+	struct list_head children;	/* list of child buses */
+	struct list_head devices;	/* list of devices on this bus */
+	struct pci_dev	*self;		/* bridge device as seen by parent */
+	struct list_head slots;		/* list of slots on this bus */
+	struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
+	struct list_head resources;	/* address space routed to this bus */
+
+	struct pci_ops	*ops;		/* configuration access functions */
+	void		*sysdata;	/* hook for sys-specific extension */
+	struct proc_dir_entry *procdir;	/* directory entry in /proc/bus/pci */
+
+	unsigned char	number;		/* bus number */
+	unsigned char	primary;	/* number of primary bridge */
+	unsigned char	secondary;	/* number of secondary bridge */
+	unsigned char	subordinate;	/* max number of subordinate buses */
+	unsigned char	max_bus_speed;	/* enum pci_bus_speed */
+	unsigned char	cur_bus_speed;	/* enum pci_bus_speed */
+
+	char		name[48];
+};
+
+/* Low-level architecture-dependent routines */
+
+struct pci_ops {
+	int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
+	int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
+
+	/* return memory address for pci resource */
+	int (*res_start)(struct pci_bus *bus, resource_size_t res_addr);
+};
+
+extern struct pci_ops * pci_ops;
+
+static inline int pci_present()
+{
+	return 1;
+}
+
+#ifndef PCIBIOS_MAX_MEM_32
+#define PCIBIOS_MAX_MEM_32 (-1)
+#endif
+
+/*
+ * Each pci channel is a top-level PCI bus seem by CPU.  A machine  with
+ * multiple PCI channels may have multiple PCI host controllers or a
+ * single controller supporting multiple channels.
+ */
+struct pci_controller {
+	struct pci_controller *next;
+	struct pci_bus *bus;
+
+	struct pci_ops *pci_ops;
+	struct resource *mem_resource;
+	unsigned long mem_offset;
+	struct resource *io_resource;
+	unsigned long io_offset;
+	unsigned long io_map_base;
+
+	unsigned int index;
+	/* For compatibility with current (as of July 2003) pciutils
+	   and XFree86. Eventually will be removed. */
+	unsigned int need_domain_info;
+
+	int iommu;
+
+	/* Optional access methods for reading/writing the bus number
+	   of the PCI controller */
+	int (*get_busno)(void);
+	void (*set_busno)(int busno);
+};
+
+extern void register_pci_controller(struct pci_controller *hose);
+
+struct pci_driver {
+	struct list_head node;
+	const char *name;
+	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
+	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
+	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+	struct driver_d	driver;
+};
+
+#define	to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
+
+/**
+ * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table
+ * @_table: device table name
+ *
+ * This macro is used to create a struct pci_device_id array (a device table)
+ * in a generic manner.
+ */
+#define DEFINE_PCI_DEVICE_TABLE(_table) \
+	const struct pci_device_id _table[]
+
+/**
+ * PCI_DEVICE - macro used to describe a specific pci device
+ * @vend: the 16 bit PCI Vendor ID
+ * @dev: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific device.  The subvendor and subdevice fields will be set to
+ * PCI_ANY_ID.
+ */
+#define PCI_DEVICE(vend,dev) \
+	.vendor = (vend), .device = (dev), \
+	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+
+/**
+ * PCI_DEVICE_CLASS - macro used to describe a specific pci device class
+ * @dev_class: the class, subclass, prog-if triple for this device
+ * @dev_class_mask: the class mask for this device
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI class.  The vendor, device, subvendor, and subdevice
+ * fields will be set to PCI_ANY_ID.
+ */
+#define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \
+	.class = (dev_class), .class_mask = (dev_class_mask), \
+	.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+
+/**
+ * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * @vendor: the vendor name
+ * @device: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI device.  The subvendor, and subdevice fields will be set
+ * to PCI_ANY_ID. The macro allows the next field to follow as the device
+ * private data.
+ */
+
+#define PCI_VDEVICE(vendor, device)		\
+	PCI_VENDOR_ID_##vendor, (device),	\
+	PCI_ANY_ID, PCI_ANY_ID, 0, 0
+
+int pci_register_driver(struct pci_driver *pdrv);
+int pci_register_device(struct pci_dev *pdev);
+
+#endif /* __KERNEL__ */
+#endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
new file mode 100644
index 0000000..49e2954
--- /dev/null
+++ b/include/linux/pci_ids.h
@@ -0,0 +1,136 @@
+/*
+ *	PCI Class, Vendor and Device IDs
+ *
+ *	Please keep sorted.
+ *
+ *	Do not add new entries to this file unless the definitions
+ *	are shared between multiple drivers.
+ */
+
+/* Device classes and subclasses */
+
+#define PCI_CLASS_NOT_DEFINED		0x0000
+#define PCI_CLASS_NOT_DEFINED_VGA	0x0001
+
+#define PCI_BASE_CLASS_STORAGE		0x01
+#define PCI_CLASS_STORAGE_SCSI		0x0100
+#define PCI_CLASS_STORAGE_IDE		0x0101
+#define PCI_CLASS_STORAGE_FLOPPY	0x0102
+#define PCI_CLASS_STORAGE_IPI		0x0103
+#define PCI_CLASS_STORAGE_RAID		0x0104
+#define PCI_CLASS_STORAGE_SATA		0x0106
+#define PCI_CLASS_STORAGE_SATA_AHCI	0x010601
+#define PCI_CLASS_STORAGE_SAS		0x0107
+#define PCI_CLASS_STORAGE_OTHER		0x0180
+
+#define PCI_BASE_CLASS_NETWORK		0x02
+#define PCI_CLASS_NETWORK_ETHERNET	0x0200
+#define PCI_CLASS_NETWORK_TOKEN_RING	0x0201
+#define PCI_CLASS_NETWORK_FDDI		0x0202
+#define PCI_CLASS_NETWORK_ATM		0x0203
+#define PCI_CLASS_NETWORK_OTHER		0x0280
+
+#define PCI_BASE_CLASS_DISPLAY		0x03
+#define PCI_CLASS_DISPLAY_VGA		0x0300
+#define PCI_CLASS_DISPLAY_XGA		0x0301
+#define PCI_CLASS_DISPLAY_3D		0x0302
+#define PCI_CLASS_DISPLAY_OTHER		0x0380
+
+#define PCI_BASE_CLASS_MULTIMEDIA	0x04
+#define PCI_CLASS_MULTIMEDIA_VIDEO	0x0400
+#define PCI_CLASS_MULTIMEDIA_AUDIO	0x0401
+#define PCI_CLASS_MULTIMEDIA_PHONE	0x0402
+#define PCI_CLASS_MULTIMEDIA_OTHER	0x0480
+
+#define PCI_BASE_CLASS_MEMORY		0x05
+#define PCI_CLASS_MEMORY_RAM		0x0500
+#define PCI_CLASS_MEMORY_FLASH		0x0501
+#define PCI_CLASS_MEMORY_OTHER		0x0580
+
+#define PCI_BASE_CLASS_BRIDGE		0x06
+#define PCI_CLASS_BRIDGE_HOST		0x0600
+#define PCI_CLASS_BRIDGE_ISA		0x0601
+#define PCI_CLASS_BRIDGE_EISA		0x0602
+#define PCI_CLASS_BRIDGE_MC		0x0603
+#define PCI_CLASS_BRIDGE_PCI		0x0604
+#define PCI_CLASS_BRIDGE_PCMCIA		0x0605
+#define PCI_CLASS_BRIDGE_NUBUS		0x0606
+#define PCI_CLASS_BRIDGE_CARDBUS	0x0607
+#define PCI_CLASS_BRIDGE_RACEWAY	0x0608
+#define PCI_CLASS_BRIDGE_OTHER		0x0680
+
+#define PCI_BASE_CLASS_COMMUNICATION	0x07
+#define PCI_CLASS_COMMUNICATION_SERIAL	0x0700
+#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
+#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
+#define PCI_CLASS_COMMUNICATION_MODEM	0x0703
+#define PCI_CLASS_COMMUNICATION_OTHER	0x0780
+
+#define PCI_BASE_CLASS_SYSTEM		0x08
+#define PCI_CLASS_SYSTEM_PIC		0x0800
+#define PCI_CLASS_SYSTEM_PIC_IOAPIC	0x080010
+#define PCI_CLASS_SYSTEM_PIC_IOXAPIC	0x080020
+#define PCI_CLASS_SYSTEM_DMA		0x0801
+#define PCI_CLASS_SYSTEM_TIMER		0x0802
+#define PCI_CLASS_SYSTEM_RTC		0x0803
+#define PCI_CLASS_SYSTEM_PCI_HOTPLUG	0x0804
+#define PCI_CLASS_SYSTEM_SDHCI		0x0805
+#define PCI_CLASS_SYSTEM_OTHER		0x0880
+
+#define PCI_BASE_CLASS_INPUT		0x09
+#define PCI_CLASS_INPUT_KEYBOARD	0x0900
+#define PCI_CLASS_INPUT_PEN		0x0901
+#define PCI_CLASS_INPUT_MOUSE		0x0902
+#define PCI_CLASS_INPUT_SCANNER		0x0903
+#define PCI_CLASS_INPUT_GAMEPORT	0x0904
+#define PCI_CLASS_INPUT_OTHER		0x0980
+
+#define PCI_BASE_CLASS_DOCKING		0x0a
+#define PCI_CLASS_DOCKING_GENERIC	0x0a00
+#define PCI_CLASS_DOCKING_OTHER		0x0a80
+
+#define PCI_BASE_CLASS_PROCESSOR	0x0b
+#define PCI_CLASS_PROCESSOR_386		0x0b00
+#define PCI_CLASS_PROCESSOR_486		0x0b01
+#define PCI_CLASS_PROCESSOR_PENTIUM	0x0b02
+#define PCI_CLASS_PROCESSOR_ALPHA	0x0b10
+#define PCI_CLASS_PROCESSOR_POWERPC	0x0b20
+#define PCI_CLASS_PROCESSOR_MIPS	0x0b30
+#define PCI_CLASS_PROCESSOR_CO		0x0b40
+
+#define PCI_BASE_CLASS_SERIAL		0x0c
+#define PCI_CLASS_SERIAL_FIREWIRE	0x0c00
+#define PCI_CLASS_SERIAL_FIREWIRE_OHCI	0x0c0010
+#define PCI_CLASS_SERIAL_ACCESS		0x0c01
+#define PCI_CLASS_SERIAL_SSA		0x0c02
+#define PCI_CLASS_SERIAL_USB		0x0c03
+#define PCI_CLASS_SERIAL_USB_UHCI	0x0c0300
+#define PCI_CLASS_SERIAL_USB_OHCI	0x0c0310
+#define PCI_CLASS_SERIAL_USB_EHCI	0x0c0320
+#define PCI_CLASS_SERIAL_USB_XHCI	0x0c0330
+#define PCI_CLASS_SERIAL_FIBER		0x0c04
+#define PCI_CLASS_SERIAL_SMBUS		0x0c05
+
+#define PCI_BASE_CLASS_WIRELESS			0x0d
+#define PCI_CLASS_WIRELESS_RF_CONTROLLER	0x0d10
+#define PCI_CLASS_WIRELESS_WHCI			0x0d1010
+
+#define PCI_BASE_CLASS_INTELLIGENT	0x0e
+#define PCI_CLASS_INTELLIGENT_I2O	0x0e00
+
+#define PCI_BASE_CLASS_SATELLITE	0x0f
+#define PCI_CLASS_SATELLITE_TV		0x0f00
+#define PCI_CLASS_SATELLITE_AUDIO	0x0f01
+#define PCI_CLASS_SATELLITE_VOICE	0x0f03
+#define PCI_CLASS_SATELLITE_DATA	0x0f04
+
+#define PCI_BASE_CLASS_CRYPT		0x10
+#define PCI_CLASS_CRYPT_NETWORK		0x1000
+#define PCI_CLASS_CRYPT_ENTERTAINMENT	0x1001
+#define PCI_CLASS_CRYPT_OTHER		0x1080
+
+#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
+#define PCI_CLASS_SP_DPIO		0x1100
+#define PCI_CLASS_SP_OTHER		0x1180
+
+#define PCI_CLASS_OTHERS		0xff
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
new file mode 100644
index 0000000..be01380
--- /dev/null
+++ b/include/linux/pci_regs.h
@@ -0,0 +1,698 @@
+/*
+ *	pci_regs.h
+ *
+ *	PCI standard defines
+ *	Copyright 1994, Drew Eckhardt
+ *	Copyright 1997--1999 Martin Mares <mj@ucw.cz>
+ *
+ *	For more information, please consult the following manuals (look at
+ *	http://www.pcisig.com/ for how to get them):
+ *
+ *	PCI BIOS Specification
+ *	PCI Local Bus Specification
+ *	PCI to PCI Bridge Specification
+ *	PCI System Design Guide
+ *
+ * 	For hypertransport information, please consult the following manuals
+ * 	from http://www.hypertransport.org
+ *
+ *	The Hypertransport I/O Link Specification
+ */
+
+#ifndef LINUX_PCI_REGS_H
+#define LINUX_PCI_REGS_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID		0x00	/* 16 bits */
+#define PCI_DEVICE_ID		0x02	/* 16 bits */
+#define PCI_COMMAND		0x04	/* 16 bits */
+#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
+#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
+#define  PCI_COMMAND_MASTER	0x4	/* Enable bus mastering */
+#define  PCI_COMMAND_SPECIAL	0x8	/* Enable response to special cycles */
+#define  PCI_COMMAND_INVALIDATE	0x10	/* Use memory write and invalidate */
+#define  PCI_COMMAND_VGA_PALETTE 0x20	/* Enable palette snooping */
+#define  PCI_COMMAND_PARITY	0x40	/* Enable parity checking */
+#define  PCI_COMMAND_WAIT 	0x80	/* Enable address/data stepping */
+#define  PCI_COMMAND_SERR	0x100	/* Enable SERR */
+#define  PCI_COMMAND_FAST_BACK	0x200	/* Enable back-to-back writes */
+#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
+
+#define PCI_STATUS		0x06	/* 16 bits */
+#define  PCI_STATUS_INTERRUPT	0x08	/* Interrupt status */
+#define  PCI_STATUS_CAP_LIST	0x10	/* Support Capability List */
+#define  PCI_STATUS_66MHZ	0x20	/* Support 66 Mhz PCI 2.1 bus */
+#define  PCI_STATUS_UDF		0x40	/* Support User Definable Features [obsolete] */
+#define  PCI_STATUS_FAST_BACK	0x80	/* Accept fast-back to back */
+#define  PCI_STATUS_PARITY	0x100	/* Detected parity error */
+#define  PCI_STATUS_DEVSEL_MASK	0x600	/* DEVSEL timing */
+#define  PCI_STATUS_DEVSEL_FAST		0x000
+#define  PCI_STATUS_DEVSEL_MEDIUM	0x200
+#define  PCI_STATUS_DEVSEL_SLOW		0x400
+#define  PCI_STATUS_SIG_TARGET_ABORT	0x800 /* Set on target abort */
+#define  PCI_STATUS_REC_TARGET_ABORT	0x1000 /* Master ack of " */
+#define  PCI_STATUS_REC_MASTER_ABORT	0x2000 /* Set on master abort */
+#define  PCI_STATUS_SIG_SYSTEM_ERROR	0x4000 /* Set when we drive SERR */
+#define  PCI_STATUS_DETECTED_PARITY	0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION	0x08	/* High 24 bits are class, low 8 revision */
+#define PCI_REVISION_ID		0x08	/* Revision ID */
+#define PCI_CLASS_PROG		0x09	/* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE	0x0a	/* Device class */
+
+#define PCI_CACHE_LINE_SIZE	0x0c	/* 8 bits */
+#define PCI_LATENCY_TIMER	0x0d	/* 8 bits */
+#define PCI_HEADER_TYPE		0x0e	/* 8 bits */
+#define  PCI_HEADER_TYPE_NORMAL		0
+#define  PCI_HEADER_TYPE_BRIDGE		1
+#define  PCI_HEADER_TYPE_CARDBUS	2
+
+#define PCI_BIST		0x0f	/* 8 bits */
+#define  PCI_BIST_CODE_MASK	0x0f	/* Return result */
+#define  PCI_BIST_START		0x40	/* 1 to start BIST, 2 secs or less */
+#define  PCI_BIST_CAPABLE	0x80	/* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of
+ * 0xffffffff to the register, and reading it back.  Only
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0	0x10	/* 32 bits */
+#define PCI_BASE_ADDRESS_1	0x14	/* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2	0x18	/* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3	0x1c	/* 32 bits */
+#define PCI_BASE_ADDRESS_4	0x20	/* 32 bits */
+#define PCI_BASE_ADDRESS_5	0x24	/* 32 bits */
+#define  PCI_BASE_ADDRESS_SPACE		0x01	/* 0 = memory, 1 = I/O */
+#define  PCI_BASE_ADDRESS_SPACE_IO	0x01
+#define  PCI_BASE_ADDRESS_SPACE_MEMORY	0x00
+#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK	0x06
+#define  PCI_BASE_ADDRESS_MEM_TYPE_32	0x00	/* 32 bit address */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_1M	0x02	/* Below 1M [obsolete] */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
+#define  PCI_BASE_ADDRESS_MEM_PREFETCH	0x08	/* prefetchable? */
+#define  PCI_BASE_ADDRESS_MEM_MASK	(~0x0fUL)
+#define  PCI_BASE_ADDRESS_IO_MASK	(~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS		0x28
+#define PCI_SUBSYSTEM_VENDOR_ID	0x2c
+#define PCI_SUBSYSTEM_ID	0x2e
+#define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
+#define  PCI_ROM_ADDRESS_ENABLE	0x01
+#define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
+
+#define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
+
+/* 0x35-0x3b are reserved */
+#define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
+#define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
+#define PCI_MIN_GNT		0x3e	/* 8 bits */
+#define PCI_MAX_LAT		0x3f	/* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS		0x18	/* Primary bus number */
+#define PCI_SECONDARY_BUS	0x19	/* Secondary bus number */
+#define PCI_SUBORDINATE_BUS	0x1a	/* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER	0x1b	/* Latency timer for secondary interface */
+#define PCI_IO_BASE		0x1c	/* I/O range behind the bridge */
+#define PCI_IO_LIMIT		0x1d
+#define  PCI_IO_RANGE_TYPE_MASK	0x0fUL	/* I/O bridging type */
+#define  PCI_IO_RANGE_TYPE_16	0x00
+#define  PCI_IO_RANGE_TYPE_32	0x01
+#define  PCI_IO_RANGE_MASK	(~0x0fUL)
+#define PCI_SEC_STATUS		0x1e	/* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE		0x20	/* Memory range behind */
+#define PCI_MEMORY_LIMIT	0x22
+#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
+#define  PCI_MEMORY_RANGE_MASK	(~0x0fUL)
+#define PCI_PREF_MEMORY_BASE	0x24	/* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT	0x26
+#define  PCI_PREF_RANGE_TYPE_MASK 0x0fUL
+#define  PCI_PREF_RANGE_TYPE_32	0x00
+#define  PCI_PREF_RANGE_TYPE_64	0x01
+#define  PCI_PREF_RANGE_MASK	(~0x0fUL)
+#define PCI_PREF_BASE_UPPER32	0x28	/* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32	0x2c
+#define PCI_IO_BASE_UPPER16	0x30	/* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16	0x32
+/* 0x34 same as for htype 0 */
+/* 0x35-0x3b is reserved */
+#define PCI_ROM_ADDRESS1	0x38	/* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL	0x3e
+#define  PCI_BRIDGE_CTL_PARITY	0x01	/* Enable parity detection on secondary interface */
+#define  PCI_BRIDGE_CTL_SERR	0x02	/* The same for SERR forwarding */
+#define  PCI_BRIDGE_CTL_ISA	0x04	/* Enable ISA mode */
+#define  PCI_BRIDGE_CTL_VGA	0x08	/* Forward VGA addresses */
+#define  PCI_BRIDGE_CTL_MASTER_ABORT	0x20  /* Report master aborts */
+#define  PCI_BRIDGE_CTL_BUS_RESET	0x40	/* Secondary bus reset */
+#define  PCI_BRIDGE_CTL_FAST_BACK	0x80	/* Fast Back2Back enabled on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+#define PCI_CB_CAPABILITY_LIST	0x14
+/* 0x15 reserved */
+#define PCI_CB_SEC_STATUS	0x16	/* Secondary status */
+#define PCI_CB_PRIMARY_BUS	0x18	/* PCI bus number */
+#define PCI_CB_CARD_BUS		0x19	/* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS	0x1a	/* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER	0x1b	/* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0	0x1c
+#define PCI_CB_MEMORY_LIMIT_0	0x20
+#define PCI_CB_MEMORY_BASE_1	0x24
+#define PCI_CB_MEMORY_LIMIT_1	0x28
+#define PCI_CB_IO_BASE_0	0x2c
+#define PCI_CB_IO_BASE_0_HI	0x2e
+#define PCI_CB_IO_LIMIT_0	0x30
+#define PCI_CB_IO_LIMIT_0_HI	0x32
+#define PCI_CB_IO_BASE_1	0x34
+#define PCI_CB_IO_BASE_1_HI	0x36
+#define PCI_CB_IO_LIMIT_1	0x38
+#define PCI_CB_IO_LIMIT_1_HI	0x3a
+#define  PCI_CB_IO_RANGE_MASK	(~0x03UL)
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_CB_BRIDGE_CONTROL	0x3e
+#define  PCI_CB_BRIDGE_CTL_PARITY	0x01	/* Similar to standard bridge control register */
+#define  PCI_CB_BRIDGE_CTL_SERR		0x02
+#define  PCI_CB_BRIDGE_CTL_ISA		0x04
+#define  PCI_CB_BRIDGE_CTL_VGA		0x08
+#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT	0x20
+#define  PCI_CB_BRIDGE_CTL_CB_RESET	0x40	/* CardBus reset */
+#define  PCI_CB_BRIDGE_CTL_16BIT_INT	0x80	/* Enable interrupt for 16-bit cards */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100	/* Prefetch enable for both memory regions */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define  PCI_CB_BRIDGE_CTL_POST_WRITES	0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID	0x40
+#define PCI_CB_SUBSYSTEM_ID		0x42
+#define PCI_CB_LEGACY_MODE_BASE		0x44	/* 16-bit PC Card legacy mode base address (ExCa) */
+/* 0x48-0x7f reserved */
+
+/* Capability lists */
+
+#define PCI_CAP_LIST_ID		0	/* Capability ID */
+#define  PCI_CAP_ID_PM		0x01	/* Power Management */
+#define  PCI_CAP_ID_AGP		0x02	/* Accelerated Graphics Port */
+#define  PCI_CAP_ID_VPD		0x03	/* Vital Product Data */
+#define  PCI_CAP_ID_SLOTID	0x04	/* Slot Identification */
+#define  PCI_CAP_ID_MSI		0x05	/* Message Signalled Interrupts */
+#define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
+#define  PCI_CAP_ID_PCIX	0x07	/* PCI-X */
+#define  PCI_CAP_ID_HT		0x08	/* HyperTransport */
+#define  PCI_CAP_ID_VNDR	0x09	/* Vendor specific */
+#define  PCI_CAP_ID_DBG		0x0A	/* Debug port */
+#define  PCI_CAP_ID_CCRC	0x0B	/* CompactPCI Central Resource Control */
+#define  PCI_CAP_ID_SHPC 	0x0C	/* PCI Standard Hot-Plug Controller */
+#define  PCI_CAP_ID_SSVID	0x0D	/* Bridge subsystem vendor/device ID */
+#define  PCI_CAP_ID_AGP3	0x0E	/* AGP Target PCI-PCI bridge */
+#define  PCI_CAP_ID_EXP 	0x10	/* PCI Express */
+#define  PCI_CAP_ID_MSIX	0x11	/* MSI-X */
+#define  PCI_CAP_ID_AF		0x13	/* PCI Advanced Features */
+#define PCI_CAP_LIST_NEXT	1	/* Next capability in the list */
+#define PCI_CAP_FLAGS		2	/* Capability defined flags (16 bits) */
+#define PCI_CAP_SIZEOF		4
+
+/* Power Management Registers */
+
+#define PCI_PM_PMC		2	/* PM Capabilities Register */
+#define  PCI_PM_CAP_VER_MASK	0x0007	/* Version */
+#define  PCI_PM_CAP_PME_CLOCK	0x0008	/* PME clock required */
+#define  PCI_PM_CAP_RESERVED    0x0010  /* Reserved field */
+#define  PCI_PM_CAP_DSI		0x0020	/* Device specific initialization */
+#define  PCI_PM_CAP_AUX_POWER	0x01C0	/* Auxiliary power support mask */
+#define  PCI_PM_CAP_D1		0x0200	/* D1 power state support */
+#define  PCI_PM_CAP_D2		0x0400	/* D2 power state support */
+#define  PCI_PM_CAP_PME		0x0800	/* PME pin supported */
+#define  PCI_PM_CAP_PME_MASK	0xF800	/* PME Mask of all supported states */
+#define  PCI_PM_CAP_PME_D0	0x0800	/* PME# from D0 */
+#define  PCI_PM_CAP_PME_D1	0x1000	/* PME# from D1 */
+#define  PCI_PM_CAP_PME_D2	0x2000	/* PME# from D2 */
+#define  PCI_PM_CAP_PME_D3	0x4000	/* PME# from D3 (hot) */
+#define  PCI_PM_CAP_PME_D3cold	0x8000	/* PME# from D3 (cold) */
+#define  PCI_PM_CAP_PME_SHIFT	11	/* Start of the PME Mask in PMC */
+#define PCI_PM_CTRL		4	/* PM control and status register */
+#define  PCI_PM_CTRL_STATE_MASK	0x0003	/* Current power state (D0 to D3) */
+#define  PCI_PM_CTRL_NO_SOFT_RESET	0x0008	/* No reset for D3hot->D0 */
+#define  PCI_PM_CTRL_PME_ENABLE	0x0100	/* PME pin enable */
+#define  PCI_PM_CTRL_DATA_SEL_MASK	0x1e00	/* Data select (??) */
+#define  PCI_PM_CTRL_DATA_SCALE_MASK	0x6000	/* Data scale (??) */
+#define  PCI_PM_CTRL_PME_STATUS	0x8000	/* PME pin status */
+#define PCI_PM_PPB_EXTENSIONS	6	/* PPB support extensions (??) */
+#define  PCI_PM_PPB_B2_B3	0x40	/* Stop clock when in D3hot (??) */
+#define  PCI_PM_BPCC_ENABLE	0x80	/* Bus power/clock control enable (??) */
+#define PCI_PM_DATA_REGISTER	7	/* (??) */
+#define PCI_PM_SIZEOF		8
+
+/* AGP registers */
+
+#define PCI_AGP_VERSION		2	/* BCD version number */
+#define PCI_AGP_RFU		3	/* Rest of capability flags */
+#define PCI_AGP_STATUS		4	/* Status register */
+#define  PCI_AGP_STATUS_RQ_MASK	0xff000000	/* Maximum number of requests - 1 */
+#define  PCI_AGP_STATUS_SBA	0x0200	/* Sideband addressing supported */
+#define  PCI_AGP_STATUS_64BIT	0x0020	/* 64-bit addressing supported */
+#define  PCI_AGP_STATUS_FW	0x0010	/* FW transfers supported */
+#define  PCI_AGP_STATUS_RATE4	0x0004	/* 4x transfer rate supported */
+#define  PCI_AGP_STATUS_RATE2	0x0002	/* 2x transfer rate supported */
+#define  PCI_AGP_STATUS_RATE1	0x0001	/* 1x transfer rate supported */
+#define PCI_AGP_COMMAND		8	/* Control register */
+#define  PCI_AGP_COMMAND_RQ_MASK 0xff000000  /* Master: Maximum number of requests */
+#define  PCI_AGP_COMMAND_SBA	0x0200	/* Sideband addressing enabled */
+#define  PCI_AGP_COMMAND_AGP	0x0100	/* Allow processing of AGP transactions */
+#define  PCI_AGP_COMMAND_64BIT	0x0020 	/* Allow processing of 64-bit addresses */
+#define  PCI_AGP_COMMAND_FW	0x0010 	/* Force FW transfers */
+#define  PCI_AGP_COMMAND_RATE4	0x0004	/* Use 4x rate */
+#define  PCI_AGP_COMMAND_RATE2	0x0002	/* Use 2x rate */
+#define  PCI_AGP_COMMAND_RATE1	0x0001	/* Use 1x rate */
+#define PCI_AGP_SIZEOF		12
+
+/* Vital Product Data */
+
+#define PCI_VPD_ADDR		2	/* Address to access (15 bits!) */
+#define  PCI_VPD_ADDR_MASK	0x7fff	/* Address mask */
+#define  PCI_VPD_ADDR_F		0x8000	/* Write 0, 1 indicates completion */
+#define PCI_VPD_DATA		4	/* 32-bits of data returned here */
+
+/* Slot Identification */
+
+#define PCI_SID_ESR		2	/* Expansion Slot Register */
+#define  PCI_SID_ESR_NSLOTS	0x1f	/* Number of expansion slots available */
+#define  PCI_SID_ESR_FIC	0x20	/* First In Chassis Flag */
+#define PCI_SID_CHASSIS_NR	3	/* Chassis Number */
+
+/* Message Signalled Interrupts registers */
+
+#define PCI_MSI_FLAGS		2	/* Various flags */
+#define  PCI_MSI_FLAGS_64BIT	0x80	/* 64-bit addresses allowed */
+#define  PCI_MSI_FLAGS_QSIZE	0x70	/* Message queue size configured */
+#define  PCI_MSI_FLAGS_QMASK	0x0e	/* Maximum queue size available */
+#define  PCI_MSI_FLAGS_ENABLE	0x01	/* MSI feature enabled */
+#define  PCI_MSI_FLAGS_MASKBIT	0x100	/* 64-bit mask bits allowed */
+#define PCI_MSI_RFU		3	/* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO	4	/* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
+#define PCI_MSI_MASK_32		12	/* Mask bits register for 32-bit devices */
+#define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
+#define PCI_MSI_MASK_64		16	/* Mask bits register for 64-bit devices */
+
+/* MSI-X registers */
+#define PCI_MSIX_FLAGS		2
+#define  PCI_MSIX_FLAGS_QSIZE	0x7FF
+#define  PCI_MSIX_FLAGS_ENABLE	(1 << 15)
+#define  PCI_MSIX_FLAGS_MASKALL	(1 << 14)
+#define PCI_MSIX_TABLE		4
+#define PCI_MSIX_PBA		8
+#define  PCI_MSIX_FLAGS_BIRMASK	(7 << 0)
+
+/* MSI-X entry's format */
+#define PCI_MSIX_ENTRY_SIZE		16
+#define  PCI_MSIX_ENTRY_LOWER_ADDR	0
+#define  PCI_MSIX_ENTRY_UPPER_ADDR	4
+#define  PCI_MSIX_ENTRY_DATA		8
+#define  PCI_MSIX_ENTRY_VECTOR_CTRL	12
+#define   PCI_MSIX_ENTRY_CTRL_MASKBIT	1
+
+/* CompactPCI Hotswap Register */
+
+#define PCI_CHSWP_CSR		2	/* Control and Status Register */
+#define  PCI_CHSWP_DHA		0x01	/* Device Hiding Arm */
+#define  PCI_CHSWP_EIM		0x02	/* ENUM# Signal Mask */
+#define  PCI_CHSWP_PIE		0x04	/* Pending Insert or Extract */
+#define  PCI_CHSWP_LOO		0x08	/* LED On / Off */
+#define  PCI_CHSWP_PI		0x30	/* Programming Interface */
+#define  PCI_CHSWP_EXT		0x40	/* ENUM# status - extraction */
+#define  PCI_CHSWP_INS		0x80	/* ENUM# status - insertion */
+
+/* PCI Advanced Feature registers */
+
+#define PCI_AF_LENGTH		2
+#define PCI_AF_CAP		3
+#define  PCI_AF_CAP_TP		0x01
+#define  PCI_AF_CAP_FLR		0x02
+#define PCI_AF_CTRL		4
+#define  PCI_AF_CTRL_FLR	0x01
+#define PCI_AF_STATUS		5
+#define  PCI_AF_STATUS_TP	0x01
+
+/* PCI-X registers */
+
+#define PCI_X_CMD		2	/* Modes & Features */
+#define  PCI_X_CMD_DPERR_E	0x0001	/* Data Parity Error Recovery Enable */
+#define  PCI_X_CMD_ERO		0x0002	/* Enable Relaxed Ordering */
+#define  PCI_X_CMD_READ_512	0x0000	/* 512 byte maximum read byte count */
+#define  PCI_X_CMD_READ_1K	0x0004	/* 1Kbyte maximum read byte count */
+#define  PCI_X_CMD_READ_2K	0x0008	/* 2Kbyte maximum read byte count */
+#define  PCI_X_CMD_READ_4K	0x000c	/* 4Kbyte maximum read byte count */
+#define  PCI_X_CMD_MAX_READ	0x000c	/* Max Memory Read Byte Count */
+				/* Max # of outstanding split transactions */
+#define  PCI_X_CMD_SPLIT_1	0x0000	/* Max 1 */
+#define  PCI_X_CMD_SPLIT_2	0x0010	/* Max 2 */
+#define  PCI_X_CMD_SPLIT_3	0x0020	/* Max 3 */
+#define  PCI_X_CMD_SPLIT_4	0x0030	/* Max 4 */
+#define  PCI_X_CMD_SPLIT_8	0x0040	/* Max 8 */
+#define  PCI_X_CMD_SPLIT_12	0x0050	/* Max 12 */
+#define  PCI_X_CMD_SPLIT_16	0x0060	/* Max 16 */
+#define  PCI_X_CMD_SPLIT_32	0x0070	/* Max 32 */
+#define  PCI_X_CMD_MAX_SPLIT	0x0070	/* Max Outstanding Split Transactions */
+#define  PCI_X_CMD_VERSION(x) 	(((x) >> 12) & 3) /* Version */
+#define PCI_X_STATUS		4	/* PCI-X capabilities */
+#define  PCI_X_STATUS_DEVFN	0x000000ff	/* A copy of devfn */
+#define  PCI_X_STATUS_BUS	0x0000ff00	/* A copy of bus nr */
+#define  PCI_X_STATUS_64BIT	0x00010000	/* 64-bit device */
+#define  PCI_X_STATUS_133MHZ	0x00020000	/* 133 MHz capable */
+#define  PCI_X_STATUS_SPL_DISC	0x00040000	/* Split Completion Discarded */
+#define  PCI_X_STATUS_UNX_SPL	0x00080000	/* Unexpected Split Completion */
+#define  PCI_X_STATUS_COMPLEX	0x00100000	/* Device Complexity */
+#define  PCI_X_STATUS_MAX_READ	0x00600000	/* Designed Max Memory Read Count */
+#define  PCI_X_STATUS_MAX_SPLIT	0x03800000	/* Designed Max Outstanding Split Transactions */
+#define  PCI_X_STATUS_MAX_CUM	0x1c000000	/* Designed Max Cumulative Read Size */
+#define  PCI_X_STATUS_SPL_ERR	0x20000000	/* Rcvd Split Completion Error Msg */
+#define  PCI_X_STATUS_266MHZ	0x40000000	/* 266 MHz capable */
+#define  PCI_X_STATUS_533MHZ	0x80000000	/* 533 MHz capable */
+
+/* PCI Bridge Subsystem ID registers */
+
+#define PCI_SSVID_VENDOR_ID     4	/* PCI-Bridge subsystem vendor id register */
+#define PCI_SSVID_DEVICE_ID     6	/* PCI-Bridge subsystem device id register */
+
+/* PCI Express capability registers */
+
+#define PCI_EXP_FLAGS		2	/* Capabilities register */
+#define PCI_EXP_FLAGS_VERS	0x000f	/* Capability version */
+#define PCI_EXP_FLAGS_TYPE	0x00f0	/* Device/Port type */
+#define  PCI_EXP_TYPE_ENDPOINT	0x0	/* Express Endpoint */
+#define  PCI_EXP_TYPE_LEG_END	0x1	/* Legacy Endpoint */
+#define  PCI_EXP_TYPE_ROOT_PORT 0x4	/* Root Port */
+#define  PCI_EXP_TYPE_UPSTREAM	0x5	/* Upstream Port */
+#define  PCI_EXP_TYPE_DOWNSTREAM 0x6	/* Downstream Port */
+#define  PCI_EXP_TYPE_PCI_BRIDGE 0x7	/* PCI/PCI-X Bridge */
+#define  PCI_EXP_TYPE_RC_END	0x9	/* Root Complex Integrated Endpoint */
+#define  PCI_EXP_TYPE_RC_EC	0x10	/* Root Complex Event Collector */
+#define PCI_EXP_FLAGS_SLOT	0x0100	/* Slot implemented */
+#define PCI_EXP_FLAGS_IRQ	0x3e00	/* Interrupt message number */
+#define PCI_EXP_DEVCAP		4	/* Device capabilities */
+#define  PCI_EXP_DEVCAP_PAYLOAD	0x07	/* Max_Payload_Size */
+#define  PCI_EXP_DEVCAP_PHANTOM	0x18	/* Phantom functions */
+#define  PCI_EXP_DEVCAP_EXT_TAG	0x20	/* Extended tags */
+#define  PCI_EXP_DEVCAP_L0S	0x1c0	/* L0s Acceptable Latency */
+#define  PCI_EXP_DEVCAP_L1	0xe00	/* L1 Acceptable Latency */
+#define  PCI_EXP_DEVCAP_ATN_BUT	0x1000	/* Attention Button Present */
+#define  PCI_EXP_DEVCAP_ATN_IND	0x2000	/* Attention Indicator Present */
+#define  PCI_EXP_DEVCAP_PWR_IND	0x4000	/* Power Indicator Present */
+#define  PCI_EXP_DEVCAP_RBER	0x8000	/* Role-Based Error Reporting */
+#define  PCI_EXP_DEVCAP_PWR_VAL	0x3fc0000 /* Slot Power Limit Value */
+#define  PCI_EXP_DEVCAP_PWR_SCL	0xc000000 /* Slot Power Limit Scale */
+#define  PCI_EXP_DEVCAP_FLR     0x10000000 /* Function Level Reset */
+#define PCI_EXP_DEVCTL		8	/* Device Control */
+#define  PCI_EXP_DEVCTL_CERE	0x0001	/* Correctable Error Reporting En. */
+#define  PCI_EXP_DEVCTL_NFERE	0x0002	/* Non-Fatal Error Reporting Enable */
+#define  PCI_EXP_DEVCTL_FERE	0x0004	/* Fatal Error Reporting Enable */
+#define  PCI_EXP_DEVCTL_URRE	0x0008	/* Unsupported Request Reporting En. */
+#define  PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
+#define  PCI_EXP_DEVCTL_PAYLOAD	0x00e0	/* Max_Payload_Size */
+#define  PCI_EXP_DEVCTL_EXT_TAG	0x0100	/* Extended Tag Field Enable */
+#define  PCI_EXP_DEVCTL_PHANTOM	0x0200	/* Phantom Functions Enable */
+#define  PCI_EXP_DEVCTL_AUX_PME	0x0400	/* Auxiliary Power PM Enable */
+#define  PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800  /* Enable No Snoop */
+#define  PCI_EXP_DEVCTL_READRQ	0x7000	/* Max_Read_Request_Size */
+#define  PCI_EXP_DEVCTL_BCR_FLR 0x8000  /* Bridge Configuration Retry / FLR */
+#define PCI_EXP_DEVSTA		10	/* Device Status */
+#define  PCI_EXP_DEVSTA_CED	0x01	/* Correctable Error Detected */
+#define  PCI_EXP_DEVSTA_NFED	0x02	/* Non-Fatal Error Detected */
+#define  PCI_EXP_DEVSTA_FED	0x04	/* Fatal Error Detected */
+#define  PCI_EXP_DEVSTA_URD	0x08	/* Unsupported Request Detected */
+#define  PCI_EXP_DEVSTA_AUXPD	0x10	/* AUX Power Detected */
+#define  PCI_EXP_DEVSTA_TRPND	0x20	/* Transactions Pending */
+#define PCI_EXP_LNKCAP		12	/* Link Capabilities */
+#define  PCI_EXP_LNKCAP_SLS	0x0000000f /* Supported Link Speeds */
+#define  PCI_EXP_LNKCAP_MLW	0x000003f0 /* Maximum Link Width */
+#define  PCI_EXP_LNKCAP_ASPMS	0x00000c00 /* ASPM Support */
+#define  PCI_EXP_LNKCAP_L0SEL	0x00007000 /* L0s Exit Latency */
+#define  PCI_EXP_LNKCAP_L1EL	0x00038000 /* L1 Exit Latency */
+#define  PCI_EXP_LNKCAP_CLKPM	0x00040000 /* L1 Clock Power Management */
+#define  PCI_EXP_LNKCAP_SDERC	0x00080000 /* Surprise Down Error Reporting Capable */
+#define  PCI_EXP_LNKCAP_DLLLARC	0x00100000 /* Data Link Layer Link Active Reporting Capable */
+#define  PCI_EXP_LNKCAP_LBNC	0x00200000 /* Link Bandwidth Notification Capability */
+#define  PCI_EXP_LNKCAP_PN	0xff000000 /* Port Number */
+#define PCI_EXP_LNKCTL		16	/* Link Control */
+#define  PCI_EXP_LNKCTL_ASPMC	0x0003	/* ASPM Control */
+#define  PCI_EXP_LNKCTL_RCB	0x0008	/* Read Completion Boundary */
+#define  PCI_EXP_LNKCTL_LD	0x0010	/* Link Disable */
+#define  PCI_EXP_LNKCTL_RL	0x0020	/* Retrain Link */
+#define  PCI_EXP_LNKCTL_CCC	0x0040	/* Common Clock Configuration */
+#define  PCI_EXP_LNKCTL_ES	0x0080	/* Extended Synch */
+#define  PCI_EXP_LNKCTL_CLKREQ_EN 0x100	/* Enable clkreq */
+#define  PCI_EXP_LNKCTL_HAWD	0x0200	/* Hardware Autonomous Width Disable */
+#define  PCI_EXP_LNKCTL_LBMIE	0x0400	/* Link Bandwidth Management Interrupt Enable */
+#define  PCI_EXP_LNKCTL_LABIE	0x0800	/* Lnk Autonomous Bandwidth Interrupt Enable */
+#define PCI_EXP_LNKSTA		18	/* Link Status */
+#define  PCI_EXP_LNKSTA_CLS	0x000f	/* Current Link Speed */
+#define  PCI_EXP_LNKSTA_CLS_2_5GB 0x01	/* Current Link Speed 2.5GT/s */
+#define  PCI_EXP_LNKSTA_CLS_5_0GB 0x02	/* Current Link Speed 5.0GT/s */
+#define  PCI_EXP_LNKSTA_NLW	0x03f0	/* Nogotiated Link Width */
+#define  PCI_EXP_LNKSTA_NLW_SHIFT 4	/* start of NLW mask in link status */
+#define  PCI_EXP_LNKSTA_LT	0x0800	/* Link Training */
+#define  PCI_EXP_LNKSTA_SLC	0x1000	/* Slot Clock Configuration */
+#define  PCI_EXP_LNKSTA_DLLLA	0x2000	/* Data Link Layer Link Active */
+#define  PCI_EXP_LNKSTA_LBMS	0x4000	/* Link Bandwidth Management Status */
+#define  PCI_EXP_LNKSTA_LABS	0x8000	/* Link Autonomous Bandwidth Status */
+#define PCI_EXP_SLTCAP		20	/* Slot Capabilities */
+#define  PCI_EXP_SLTCAP_ABP	0x00000001 /* Attention Button Present */
+#define  PCI_EXP_SLTCAP_PCP	0x00000002 /* Power Controller Present */
+#define  PCI_EXP_SLTCAP_MRLSP	0x00000004 /* MRL Sensor Present */
+#define  PCI_EXP_SLTCAP_AIP	0x00000008 /* Attention Indicator Present */
+#define  PCI_EXP_SLTCAP_PIP	0x00000010 /* Power Indicator Present */
+#define  PCI_EXP_SLTCAP_HPS	0x00000020 /* Hot-Plug Surprise */
+#define  PCI_EXP_SLTCAP_HPC	0x00000040 /* Hot-Plug Capable */
+#define  PCI_EXP_SLTCAP_SPLV	0x00007f80 /* Slot Power Limit Value */
+#define  PCI_EXP_SLTCAP_SPLS	0x00018000 /* Slot Power Limit Scale */
+#define  PCI_EXP_SLTCAP_EIP	0x00020000 /* Electromechanical Interlock Present */
+#define  PCI_EXP_SLTCAP_NCCS	0x00040000 /* No Command Completed Support */
+#define  PCI_EXP_SLTCAP_PSN	0xfff80000 /* Physical Slot Number */
+#define PCI_EXP_SLTCTL		24	/* Slot Control */
+#define  PCI_EXP_SLTCTL_ABPE	0x0001	/* Attention Button Pressed Enable */
+#define  PCI_EXP_SLTCTL_PFDE	0x0002	/* Power Fault Detected Enable */
+#define  PCI_EXP_SLTCTL_MRLSCE	0x0004	/* MRL Sensor Changed Enable */
+#define  PCI_EXP_SLTCTL_PDCE	0x0008	/* Presence Detect Changed Enable */
+#define  PCI_EXP_SLTCTL_CCIE	0x0010	/* Command Completed Interrupt Enable */
+#define  PCI_EXP_SLTCTL_HPIE	0x0020	/* Hot-Plug Interrupt Enable */
+#define  PCI_EXP_SLTCTL_AIC	0x00c0	/* Attention Indicator Control */
+#define  PCI_EXP_SLTCTL_PIC	0x0300	/* Power Indicator Control */
+#define  PCI_EXP_SLTCTL_PCC	0x0400	/* Power Controller Control */
+#define  PCI_EXP_SLTCTL_EIC	0x0800	/* Electromechanical Interlock Control */
+#define  PCI_EXP_SLTCTL_DLLSCE	0x1000	/* Data Link Layer State Changed Enable */
+#define PCI_EXP_SLTSTA		26	/* Slot Status */
+#define  PCI_EXP_SLTSTA_ABP	0x0001	/* Attention Button Pressed */
+#define  PCI_EXP_SLTSTA_PFD	0x0002	/* Power Fault Detected */
+#define  PCI_EXP_SLTSTA_MRLSC	0x0004	/* MRL Sensor Changed */
+#define  PCI_EXP_SLTSTA_PDC	0x0008	/* Presence Detect Changed */
+#define  PCI_EXP_SLTSTA_CC	0x0010	/* Command Completed */
+#define  PCI_EXP_SLTSTA_MRLSS	0x0020	/* MRL Sensor State */
+#define  PCI_EXP_SLTSTA_PDS	0x0040	/* Presence Detect State */
+#define  PCI_EXP_SLTSTA_EIS	0x0080	/* Electromechanical Interlock Status */
+#define  PCI_EXP_SLTSTA_DLLSC	0x0100	/* Data Link Layer State Changed */
+#define PCI_EXP_RTCTL		28	/* Root Control */
+#define  PCI_EXP_RTCTL_SECEE	0x01	/* System Error on Correctable Error */
+#define  PCI_EXP_RTCTL_SENFEE	0x02	/* System Error on Non-Fatal Error */
+#define  PCI_EXP_RTCTL_SEFEE	0x04	/* System Error on Fatal Error */
+#define  PCI_EXP_RTCTL_PMEIE	0x08	/* PME Interrupt Enable */
+#define  PCI_EXP_RTCTL_CRSSVE	0x10	/* CRS Software Visibility Enable */
+#define PCI_EXP_RTCAP		30	/* Root Capabilities */
+#define PCI_EXP_RTSTA		32	/* Root Status */
+#define PCI_EXP_RTSTA_PME	0x10000 /* PME status */
+#define PCI_EXP_RTSTA_PENDING	0x20000 /* PME pending */
+#define PCI_EXP_DEVCAP2		36	/* Device Capabilities 2 */
+#define  PCI_EXP_DEVCAP2_ARI	0x20	/* Alternative Routing-ID */
+#define PCI_EXP_DEVCTL2		40	/* Device Control 2 */
+#define  PCI_EXP_DEVCTL2_ARI	0x20	/* Alternative Routing-ID */
+#define PCI_EXP_LNKCTL2		48	/* Link Control 2 */
+#define PCI_EXP_SLTCTL2		56	/* Slot Control 2 */
+
+/* Extended Capabilities (PCI-X 2.0 and Express) */
+#define PCI_EXT_CAP_ID(header)		(header & 0x0000ffff)
+#define PCI_EXT_CAP_VER(header)		((header >> 16) & 0xf)
+#define PCI_EXT_CAP_NEXT(header)	((header >> 20) & 0xffc)
+
+#define PCI_EXT_CAP_ID_ERR	1
+#define PCI_EXT_CAP_ID_VC	2
+#define PCI_EXT_CAP_ID_DSN	3
+#define PCI_EXT_CAP_ID_PWR	4
+#define PCI_EXT_CAP_ID_VNDR	11
+#define PCI_EXT_CAP_ID_ACS	13
+#define PCI_EXT_CAP_ID_ARI	14
+#define PCI_EXT_CAP_ID_ATS	15
+#define PCI_EXT_CAP_ID_SRIOV	16
+
+/* Advanced Error Reporting */
+#define PCI_ERR_UNCOR_STATUS	4	/* Uncorrectable Error Status */
+#define  PCI_ERR_UNC_TRAIN	0x00000001	/* Training */
+#define  PCI_ERR_UNC_DLP	0x00000010	/* Data Link Protocol */
+#define  PCI_ERR_UNC_POISON_TLP	0x00001000	/* Poisoned TLP */
+#define  PCI_ERR_UNC_FCP	0x00002000	/* Flow Control Protocol */
+#define  PCI_ERR_UNC_COMP_TIME	0x00004000	/* Completion Timeout */
+#define  PCI_ERR_UNC_COMP_ABORT	0x00008000	/* Completer Abort */
+#define  PCI_ERR_UNC_UNX_COMP	0x00010000	/* Unexpected Completion */
+#define  PCI_ERR_UNC_RX_OVER	0x00020000	/* Receiver Overflow */
+#define  PCI_ERR_UNC_MALF_TLP	0x00040000	/* Malformed TLP */
+#define  PCI_ERR_UNC_ECRC	0x00080000	/* ECRC Error Status */
+#define  PCI_ERR_UNC_UNSUP	0x00100000	/* Unsupported Request */
+#define PCI_ERR_UNCOR_MASK	8	/* Uncorrectable Error Mask */
+	/* Same bits as above */
+#define PCI_ERR_UNCOR_SEVER	12	/* Uncorrectable Error Severity */
+	/* Same bits as above */
+#define PCI_ERR_COR_STATUS	16	/* Correctable Error Status */
+#define  PCI_ERR_COR_RCVR	0x00000001	/* Receiver Error Status */
+#define  PCI_ERR_COR_BAD_TLP	0x00000040	/* Bad TLP Status */
+#define  PCI_ERR_COR_BAD_DLLP	0x00000080	/* Bad DLLP Status */
+#define  PCI_ERR_COR_REP_ROLL	0x00000100	/* REPLAY_NUM Rollover */
+#define  PCI_ERR_COR_REP_TIMER	0x00001000	/* Replay Timer Timeout */
+#define PCI_ERR_COR_MASK	20	/* Correctable Error Mask */
+	/* Same bits as above */
+#define PCI_ERR_CAP		24	/* Advanced Error Capabilities */
+#define  PCI_ERR_CAP_FEP(x)	((x) & 31)	/* First Error Pointer */
+#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
+#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
+#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
+#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
+#define PCI_ERR_HEADER_LOG	28	/* Header Log Register (16 bytes) */
+#define PCI_ERR_ROOT_COMMAND	44	/* Root Error Command */
+/* Correctable Err Reporting Enable */
+#define PCI_ERR_ROOT_CMD_COR_EN		0x00000001
+/* Non-fatal Err Reporting Enable */
+#define PCI_ERR_ROOT_CMD_NONFATAL_EN	0x00000002
+/* Fatal Err Reporting Enable */
+#define PCI_ERR_ROOT_CMD_FATAL_EN	0x00000004
+#define PCI_ERR_ROOT_STATUS	48
+#define PCI_ERR_ROOT_COR_RCV		0x00000001	/* ERR_COR Received */
+/* Multi ERR_COR Received */
+#define PCI_ERR_ROOT_MULTI_COR_RCV	0x00000002
+/* ERR_FATAL/NONFATAL Recevied */
+#define PCI_ERR_ROOT_UNCOR_RCV		0x00000004
+/* Multi ERR_FATAL/NONFATAL Recevied */
+#define PCI_ERR_ROOT_MULTI_UNCOR_RCV	0x00000008
+#define PCI_ERR_ROOT_FIRST_FATAL	0x00000010	/* First Fatal */
+#define PCI_ERR_ROOT_NONFATAL_RCV	0x00000020	/* Non-Fatal Received */
+#define PCI_ERR_ROOT_FATAL_RCV		0x00000040	/* Fatal Received */
+#define PCI_ERR_ROOT_ERR_SRC	52	/* Error Source Identification */
+
+/* Virtual Channel */
+#define PCI_VC_PORT_REG1	4
+#define PCI_VC_PORT_REG2	8
+#define PCI_VC_PORT_CTRL	12
+#define PCI_VC_PORT_STATUS	14
+#define PCI_VC_RES_CAP		16
+#define PCI_VC_RES_CTRL		20
+#define PCI_VC_RES_STATUS	26
+
+/* Power Budgeting */
+#define PCI_PWR_DSR		4	/* Data Select Register */
+#define PCI_PWR_DATA		8	/* Data Register */
+#define  PCI_PWR_DATA_BASE(x)	((x) & 0xff)	    /* Base Power */
+#define  PCI_PWR_DATA_SCALE(x)	(((x) >> 8) & 3)    /* Data Scale */
+#define  PCI_PWR_DATA_PM_SUB(x)	(((x) >> 10) & 7)   /* PM Sub State */
+#define  PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
+#define  PCI_PWR_DATA_TYPE(x)	(((x) >> 15) & 7)   /* Type */
+#define  PCI_PWR_DATA_RAIL(x)	(((x) >> 18) & 7)   /* Power Rail */
+#define PCI_PWR_CAP		12	/* Capability */
+#define  PCI_PWR_CAP_BUDGET(x)	((x) & 1)	/* Included in system budget */
+
+/*
+ * Hypertransport sub capability types
+ *
+ * Unfortunately there are both 3 bit and 5 bit capability types defined
+ * in the HT spec, catering for that is a little messy. You probably don't
+ * want to use these directly, just use pci_find_ht_capability() and it
+ * will do the right thing for you.
+ */
+#define HT_3BIT_CAP_MASK	0xE0
+#define HT_CAPTYPE_SLAVE	0x00	/* Slave/Primary link configuration */
+#define HT_CAPTYPE_HOST		0x20	/* Host/Secondary link configuration */
+
+#define HT_5BIT_CAP_MASK	0xF8
+#define HT_CAPTYPE_IRQ		0x80	/* IRQ Configuration */
+#define HT_CAPTYPE_REMAPPING_40	0xA0	/* 40 bit address remapping */
+#define HT_CAPTYPE_REMAPPING_64 0xA2	/* 64 bit address remapping */
+#define HT_CAPTYPE_UNITID_CLUMP	0x90	/* Unit ID clumping */
+#define HT_CAPTYPE_EXTCONF	0x98	/* Extended Configuration Space Access */
+#define HT_CAPTYPE_MSI_MAPPING	0xA8	/* MSI Mapping Capability */
+#define  HT_MSI_FLAGS		0x02		/* Offset to flags */
+#define  HT_MSI_FLAGS_ENABLE	0x1		/* Mapping enable */
+#define  HT_MSI_FLAGS_FIXED	0x2		/* Fixed mapping only */
+#define  HT_MSI_FIXED_ADDR	0x00000000FEE00000ULL	/* Fixed addr */
+#define  HT_MSI_ADDR_LO		0x04		/* Offset to low addr bits */
+#define  HT_MSI_ADDR_LO_MASK	0xFFF00000	/* Low address bit mask */
+#define  HT_MSI_ADDR_HI		0x08		/* Offset to high addr bits */
+#define HT_CAPTYPE_DIRECT_ROUTE	0xB0	/* Direct routing configuration */
+#define HT_CAPTYPE_VCSET	0xB8	/* Virtual Channel configuration */
+#define HT_CAPTYPE_ERROR_RETRY	0xC0	/* Retry on error configuration */
+#define HT_CAPTYPE_GEN3		0xD0	/* Generation 3 hypertransport configuration */
+#define HT_CAPTYPE_PM		0xE0	/* Hypertransport powermanagement configuration */
+
+/* Alternative Routing-ID Interpretation */
+#define PCI_ARI_CAP		0x04	/* ARI Capability Register */
+#define  PCI_ARI_CAP_MFVC	0x0001	/* MFVC Function Groups Capability */
+#define  PCI_ARI_CAP_ACS	0x0002	/* ACS Function Groups Capability */
+#define  PCI_ARI_CAP_NFN(x)	(((x) >> 8) & 0xff) /* Next Function Number */
+#define PCI_ARI_CTRL		0x06	/* ARI Control Register */
+#define  PCI_ARI_CTRL_MFVC	0x0001	/* MFVC Function Groups Enable */
+#define  PCI_ARI_CTRL_ACS	0x0002	/* ACS Function Groups Enable */
+#define  PCI_ARI_CTRL_FG(x)	(((x) >> 4) & 7) /* Function Group */
+
+/* Address Translation Service */
+#define PCI_ATS_CAP		0x04	/* ATS Capability Register */
+#define  PCI_ATS_CAP_QDEP(x)	((x) & 0x1f)	/* Invalidate Queue Depth */
+#define  PCI_ATS_MAX_QDEP	32	/* Max Invalidate Queue Depth */
+#define PCI_ATS_CTRL		0x06	/* ATS Control Register */
+#define  PCI_ATS_CTRL_ENABLE	0x8000	/* ATS Enable */
+#define  PCI_ATS_CTRL_STU(x)	((x) & 0x1f)	/* Smallest Translation Unit */
+#define  PCI_ATS_MIN_STU	12	/* shift of minimum STU block */
+
+/* Single Root I/O Virtualization */
+#define PCI_SRIOV_CAP		0x04	/* SR-IOV Capabilities */
+#define  PCI_SRIOV_CAP_VFM	0x01	/* VF Migration Capable */
+#define  PCI_SRIOV_CAP_INTR(x)	((x) >> 21) /* Interrupt Message Number */
+#define PCI_SRIOV_CTRL		0x08	/* SR-IOV Control */
+#define  PCI_SRIOV_CTRL_VFE	0x01	/* VF Enable */
+#define  PCI_SRIOV_CTRL_VFM	0x02	/* VF Migration Enable */
+#define  PCI_SRIOV_CTRL_INTR	0x04	/* VF Migration Interrupt Enable */
+#define  PCI_SRIOV_CTRL_MSE	0x08	/* VF Memory Space Enable */
+#define  PCI_SRIOV_CTRL_ARI	0x10	/* ARI Capable Hierarchy */
+#define PCI_SRIOV_STATUS	0x0a	/* SR-IOV Status */
+#define  PCI_SRIOV_STATUS_VFM	0x01	/* VF Migration Status */
+#define PCI_SRIOV_INITIAL_VF	0x0c	/* Initial VFs */
+#define PCI_SRIOV_TOTAL_VF	0x0e	/* Total VFs */
+#define PCI_SRIOV_NUM_VF	0x10	/* Number of VFs */
+#define PCI_SRIOV_FUNC_LINK	0x12	/* Function Dependency Link */
+#define PCI_SRIOV_VF_OFFSET	0x14	/* First VF Offset */
+#define PCI_SRIOV_VF_STRIDE	0x16	/* Following VF Stride */
+#define PCI_SRIOV_VF_DID	0x1a	/* VF Device ID */
+#define PCI_SRIOV_SUP_PGSIZE	0x1c	/* Supported Page Sizes */
+#define PCI_SRIOV_SYS_PGSIZE	0x20	/* System Page Size */
+#define PCI_SRIOV_BAR		0x24	/* VF BAR0 */
+#define  PCI_SRIOV_NUM_BARS	6	/* Number of VF BARs */
+#define PCI_SRIOV_VFM		0x3c	/* VF Migration State Array Offset*/
+#define  PCI_SRIOV_VFM_BIR(x)	((x) & 7)	/* State BIR */
+#define  PCI_SRIOV_VFM_OFFSET(x) ((x) & ~7)	/* State Offset */
+#define  PCI_SRIOV_VFM_UA	0x0	/* Inactive.Unavailable */
+#define  PCI_SRIOV_VFM_MI	0x1	/* Dormant.MigrateIn */
+#define  PCI_SRIOV_VFM_MO	0x2	/* Active.MigrateOut */
+#define  PCI_SRIOV_VFM_AV	0x3	/* Active.Available */
+
+/* Access Control Service */
+#define PCI_ACS_CAP		0x04	/* ACS Capability Register */
+#define  PCI_ACS_SV		0x01	/* Source Validation */
+#define  PCI_ACS_TB		0x02	/* Translation Blocking */
+#define  PCI_ACS_RR		0x04	/* P2P Request Redirect */
+#define  PCI_ACS_CR		0x08	/* P2P Completion Redirect */
+#define  PCI_ACS_UF		0x10	/* Upstream Forwarding */
+#define  PCI_ACS_EC		0x20	/* P2P Egress Control */
+#define  PCI_ACS_DT		0x40	/* Direct Translated P2P */
+#define PCI_ACS_CTRL		0x06	/* ACS Control Register */
+#define PCI_ACS_EGRESS_CTL_V	0x08	/* ACS Egress Control Vector */
+
+#endif /* LINUX_PCI_REGS_H */
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [RFC V2 2/6] MIPS: add file gt64120.h from linux 2.6.39
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 1/6] PCI: initial commit (draft) Antony Pavlov
@ 2012-03-08 19:50 ` Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 3/6] MIPS: add PCI support for GT64120-based malta Antony Pavlov
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 arch/mips/include/asm/gt64120.h |  575 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 575 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/gt64120.h

diff --git a/arch/mips/include/asm/gt64120.h b/arch/mips/include/asm/gt64120.h
new file mode 100644
index 0000000..91873b7
--- /dev/null
+++ b/arch/mips/include/asm/gt64120.h
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2000, 2004, 2005  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#ifndef _ASM_GT64120_H
+#define _ASM_GT64120_H
+
+#include <asm/byteorder.h>
+
+#define MSK(n)			((1 << (n)) - 1)
+
+/*
+ *  Register offset addresses
+ */
+/* CPU Configuration.  */
+#define GT_CPU_OFS		0x000
+
+#define GT_MULTI_OFS		0x120
+
+/* CPU Address Decode.  */
+#define GT_SCS10LD_OFS		0x008
+#define GT_SCS10HD_OFS		0x010
+#define GT_SCS32LD_OFS		0x018
+#define GT_SCS32HD_OFS		0x020
+#define GT_CS20LD_OFS		0x028
+#define GT_CS20HD_OFS		0x030
+#define GT_CS3BOOTLD_OFS	0x038
+#define GT_CS3BOOTHD_OFS	0x040
+#define GT_PCI0IOLD_OFS		0x048
+#define GT_PCI0IOHD_OFS		0x050
+#define GT_PCI0M0LD_OFS		0x058
+#define GT_PCI0M0HD_OFS		0x060
+#define GT_ISD_OFS		0x068
+
+#define GT_PCI0M1LD_OFS		0x080
+#define GT_PCI0M1HD_OFS		0x088
+#define GT_PCI1IOLD_OFS		0x090
+#define GT_PCI1IOHD_OFS		0x098
+#define GT_PCI1M0LD_OFS		0x0a0
+#define GT_PCI1M0HD_OFS		0x0a8
+#define GT_PCI1M1LD_OFS		0x0b0
+#define GT_PCI1M1HD_OFS		0x0b8
+#define GT_PCI1M1LD_OFS		0x0b0
+#define GT_PCI1M1HD_OFS		0x0b8
+
+#define GT_SCS10AR_OFS		0x0d0
+#define GT_SCS32AR_OFS		0x0d8
+#define GT_CS20R_OFS		0x0e0
+#define GT_CS3BOOTR_OFS		0x0e8
+
+#define GT_PCI0IOREMAP_OFS	0x0f0
+#define GT_PCI0M0REMAP_OFS	0x0f8
+#define GT_PCI0M1REMAP_OFS	0x100
+#define GT_PCI1IOREMAP_OFS	0x108
+#define GT_PCI1M0REMAP_OFS	0x110
+#define GT_PCI1M1REMAP_OFS	0x118
+
+/* CPU Error Report.  */
+#define GT_CPUERR_ADDRLO_OFS	0x070
+#define GT_CPUERR_ADDRHI_OFS	0x078
+
+#define GT_CPUERR_DATALO_OFS	0x128			/* GT-64120A only  */
+#define GT_CPUERR_DATAHI_OFS	0x130			/* GT-64120A only  */
+#define GT_CPUERR_PARITY_OFS	0x138			/* GT-64120A only  */
+
+/* CPU Sync Barrier.  */
+#define GT_PCI0SYNC_OFS		0x0c0
+#define GT_PCI1SYNC_OFS		0x0c8
+
+/* SDRAM and Device Address Decode.  */
+#define GT_SCS0LD_OFS		0x400
+#define GT_SCS0HD_OFS		0x404
+#define GT_SCS1LD_OFS		0x408
+#define GT_SCS1HD_OFS		0x40c
+#define GT_SCS2LD_OFS		0x410
+#define GT_SCS2HD_OFS		0x414
+#define GT_SCS3LD_OFS		0x418
+#define GT_SCS3HD_OFS		0x41c
+#define GT_CS0LD_OFS		0x420
+#define GT_CS0HD_OFS		0x424
+#define GT_CS1LD_OFS		0x428
+#define GT_CS1HD_OFS		0x42c
+#define GT_CS2LD_OFS		0x430
+#define GT_CS2HD_OFS		0x434
+#define GT_CS3LD_OFS		0x438
+#define GT_CS3HD_OFS		0x43c
+#define GT_BOOTLD_OFS		0x440
+#define GT_BOOTHD_OFS		0x444
+
+#define GT_ADERR_OFS		0x470
+
+/* SDRAM Configuration.  */
+#define GT_SDRAM_CFG_OFS	0x448
+
+#define GT_SDRAM_OPMODE_OFS	0x474
+#define GT_SDRAM_BM_OFS		0x478
+#define GT_SDRAM_ADDRDECODE_OFS	0x47c
+
+/* SDRAM Parameters.  */
+#define GT_SDRAM_B0_OFS		0x44c
+#define GT_SDRAM_B1_OFS		0x450
+#define GT_SDRAM_B2_OFS		0x454
+#define GT_SDRAM_B3_OFS		0x458
+
+/* Device Parameters.  */
+#define GT_DEV_B0_OFS		0x45c
+#define GT_DEV_B1_OFS		0x460
+#define GT_DEV_B2_OFS		0x464
+#define GT_DEV_B3_OFS		0x468
+#define GT_DEV_BOOT_OFS		0x46c
+
+/* ECC.  */
+#define GT_ECC_ERRDATALO	0x480			/* GT-64120A only  */
+#define GT_ECC_ERRDATAHI	0x484			/* GT-64120A only  */
+#define GT_ECC_MEM		0x488			/* GT-64120A only  */
+#define GT_ECC_CALC		0x48c			/* GT-64120A only  */
+#define GT_ECC_ERRADDR		0x490			/* GT-64120A only  */
+
+/* DMA Record.  */
+#define GT_DMA0_CNT_OFS		0x800
+#define GT_DMA1_CNT_OFS		0x804
+#define GT_DMA2_CNT_OFS		0x808
+#define GT_DMA3_CNT_OFS		0x80c
+#define GT_DMA0_SA_OFS		0x810
+#define GT_DMA1_SA_OFS		0x814
+#define GT_DMA2_SA_OFS		0x818
+#define GT_DMA3_SA_OFS		0x81c
+#define GT_DMA0_DA_OFS		0x820
+#define GT_DMA1_DA_OFS		0x824
+#define GT_DMA2_DA_OFS		0x828
+#define GT_DMA3_DA_OFS		0x82c
+#define GT_DMA0_NEXT_OFS	0x830
+#define GT_DMA1_NEXT_OFS	0x834
+#define GT_DMA2_NEXT_OFS	0x838
+#define GT_DMA3_NEXT_OFS	0x83c
+
+#define GT_DMA0_CUR_OFS		0x870
+#define GT_DMA1_CUR_OFS		0x874
+#define GT_DMA2_CUR_OFS		0x878
+#define GT_DMA3_CUR_OFS		0x87c
+
+/* DMA Channel Control.  */
+#define GT_DMA0_CTRL_OFS	0x840
+#define GT_DMA1_CTRL_OFS	0x844
+#define GT_DMA2_CTRL_OFS	0x848
+#define GT_DMA3_CTRL_OFS	0x84c
+
+/* DMA Arbiter.  */
+#define GT_DMA_ARB_OFS		0x860
+
+/* Timer/Counter.  */
+#define GT_TC0_OFS		0x850
+#define GT_TC1_OFS		0x854
+#define GT_TC2_OFS		0x858
+#define GT_TC3_OFS		0x85c
+
+#define GT_TC_CONTROL_OFS	0x864
+
+/* PCI Internal.  */
+#define GT_PCI0_CMD_OFS		0xc00
+#define GT_PCI0_TOR_OFS		0xc04
+#define GT_PCI0_BS_SCS10_OFS	0xc08
+#define GT_PCI0_BS_SCS32_OFS	0xc0c
+#define GT_PCI0_BS_CS20_OFS	0xc10
+#define GT_PCI0_BS_CS3BT_OFS	0xc14
+
+#define GT_PCI1_IACK_OFS	0xc30
+#define GT_PCI0_IACK_OFS	0xc34
+
+#define GT_PCI0_BARE_OFS	0xc3c
+#define GT_PCI0_PREFMBR_OFS	0xc40
+
+#define GT_PCI0_SCS10_BAR_OFS	0xc48
+#define GT_PCI0_SCS32_BAR_OFS	0xc4c
+#define GT_PCI0_CS20_BAR_OFS	0xc50
+#define GT_PCI0_CS3BT_BAR_OFS	0xc54
+#define GT_PCI0_SSCS10_BAR_OFS	0xc58
+#define GT_PCI0_SSCS32_BAR_OFS	0xc5c
+
+#define GT_PCI0_SCS3BT_BAR_OFS	0xc64
+
+#define GT_PCI1_CMD_OFS		0xc80
+#define GT_PCI1_TOR_OFS		0xc84
+#define GT_PCI1_BS_SCS10_OFS	0xc88
+#define GT_PCI1_BS_SCS32_OFS	0xc8c
+#define GT_PCI1_BS_CS20_OFS	0xc90
+#define GT_PCI1_BS_CS3BT_OFS	0xc94
+
+#define GT_PCI1_BARE_OFS	0xcbc
+#define GT_PCI1_PREFMBR_OFS	0xcc0
+
+#define GT_PCI1_SCS10_BAR_OFS	0xcc8
+#define GT_PCI1_SCS32_BAR_OFS	0xccc
+#define GT_PCI1_CS20_BAR_OFS	0xcd0
+#define GT_PCI1_CS3BT_BAR_OFS	0xcd4
+#define GT_PCI1_SSCS10_BAR_OFS	0xcd8
+#define GT_PCI1_SSCS32_BAR_OFS	0xcdc
+
+#define GT_PCI1_SCS3BT_BAR_OFS	0xce4
+
+#define GT_PCI1_CFGADDR_OFS	0xcf0
+#define GT_PCI1_CFGDATA_OFS	0xcf4
+#define GT_PCI0_CFGADDR_OFS	0xcf8
+#define GT_PCI0_CFGDATA_OFS	0xcfc
+
+/* Interrupts.  */
+#define GT_INTRCAUSE_OFS	0xc18
+#define GT_INTRMASK_OFS		0xc1c
+
+#define GT_PCI0_ICMASK_OFS	0xc24
+#define GT_PCI0_SERR0MASK_OFS	0xc28
+
+#define GT_CPU_INTSEL_OFS	0xc70
+#define GT_PCI0_INTSEL_OFS	0xc74
+
+#define GT_HINTRCAUSE_OFS	0xc98
+#define GT_HINTRMASK_OFS	0xc9c
+
+#define GT_PCI0_HICMASK_OFS	0xca4
+#define GT_PCI1_SERR1MASK_OFS	0xca8
+
+
+/*
+ * I2O Support Registers
+ */
+#define INBOUND_MESSAGE_REGISTER0_PCI_SIDE		0x010
+#define INBOUND_MESSAGE_REGISTER1_PCI_SIDE		0x014
+#define OUTBOUND_MESSAGE_REGISTER0_PCI_SIDE		0x018
+#define OUTBOUND_MESSAGE_REGISTER1_PCI_SIDE		0x01c
+#define INBOUND_DOORBELL_REGISTER_PCI_SIDE		0x020
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE	0x024
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE	0x028
+#define OUTBOUND_DOORBELL_REGISTER_PCI_SIDE		0x02c
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE	0x030
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE	0x034
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE	0x040
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE	0x044
+#define QUEUE_CONTROL_REGISTER_PCI_SIDE			0x050
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI_SIDE		0x054
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE	0x060
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE	0x064
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE	0x068
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE	0x06c
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE	0x070
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE	0x074
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE	0x078
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE	0x07c
+
+#define INBOUND_MESSAGE_REGISTER0_CPU_SIDE		0x1c10
+#define INBOUND_MESSAGE_REGISTER1_CPU_SIDE		0x1c14
+#define OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE		0x1c18
+#define OUTBOUND_MESSAGE_REGISTER1_CPU_SIDE		0x1c1c
+#define INBOUND_DOORBELL_REGISTER_CPU_SIDE		0x1c20
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE	0x1c24
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE	0x1c28
+#define OUTBOUND_DOORBELL_REGISTER_CPU_SIDE		0x1c2c
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE	0x1c30
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE	0x1c34
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE	0x1c40
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE	0x1c44
+#define QUEUE_CONTROL_REGISTER_CPU_SIDE			0x1c50
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE		0x1c54
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c60
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c64
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c68
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c6c
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c70
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c74
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE	0x1c78
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE	0x1c7c
+
+/*
+ *  Register encodings
+ */
+#define GT_CPU_ENDIAN_SHF	12
+#define GT_CPU_ENDIAN_MSK	(MSK(1) << GT_CPU_ENDIAN_SHF)
+#define GT_CPU_ENDIAN_BIT	GT_CPU_ENDIAN_MSK
+#define GT_CPU_WR_SHF		16
+#define GT_CPU_WR_MSK		(MSK(1) << GT_CPU_WR_SHF)
+#define GT_CPU_WR_BIT		GT_CPU_WR_MSK
+#define GT_CPU_WR_DXDXDXDX	0
+#define GT_CPU_WR_DDDD		1
+
+
+#define GT_PCI_DCRM_SHF		21
+#define GT_PCI_LD_SHF		0
+#define GT_PCI_LD_MSK		(MSK(15) << GT_PCI_LD_SHF)
+#define GT_PCI_HD_SHF		0
+#define GT_PCI_HD_MSK		(MSK(7) << GT_PCI_HD_SHF)
+#define GT_PCI_REMAP_SHF	0
+#define GT_PCI_REMAP_MSK	(MSK(11) << GT_PCI_REMAP_SHF)
+
+
+#define GT_CFGADDR_CFGEN_SHF	31
+#define GT_CFGADDR_CFGEN_MSK	(MSK(1) << GT_CFGADDR_CFGEN_SHF)
+#define GT_CFGADDR_CFGEN_BIT	GT_CFGADDR_CFGEN_MSK
+
+#define GT_CFGADDR_BUSNUM_SHF	16
+#define GT_CFGADDR_BUSNUM_MSK	(MSK(8) << GT_CFGADDR_BUSNUM_SHF)
+
+#define GT_CFGADDR_DEVNUM_SHF	11
+#define GT_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_CFGADDR_DEVNUM_SHF)
+
+#define GT_CFGADDR_FUNCNUM_SHF	8
+#define GT_CFGADDR_FUNCNUM_MSK	(MSK(3) << GT_CFGADDR_FUNCNUM_SHF)
+
+#define GT_CFGADDR_REGNUM_SHF	2
+#define GT_CFGADDR_REGNUM_MSK	(MSK(6) << GT_CFGADDR_REGNUM_SHF)
+
+
+#define GT_SDRAM_BM_ORDER_SHF	2
+#define GT_SDRAM_BM_ORDER_MSK	(MSK(1) << GT_SDRAM_BM_ORDER_SHF)
+#define GT_SDRAM_BM_ORDER_BIT	GT_SDRAM_BM_ORDER_MSK
+#define GT_SDRAM_BM_ORDER_SUB	1
+#define GT_SDRAM_BM_ORDER_LIN	0
+
+#define GT_SDRAM_BM_RSVD_ALL1	0xffb
+
+
+#define GT_SDRAM_ADDRDECODE_ADDR_SHF	0
+#define GT_SDRAM_ADDRDECODE_ADDR_MSK	(MSK(3) << GT_SDRAM_ADDRDECODE_ADDR_SHF)
+#define GT_SDRAM_ADDRDECODE_ADDR_0	0
+#define GT_SDRAM_ADDRDECODE_ADDR_1	1
+#define GT_SDRAM_ADDRDECODE_ADDR_2	2
+#define GT_SDRAM_ADDRDECODE_ADDR_3	3
+#define GT_SDRAM_ADDRDECODE_ADDR_4	4
+#define GT_SDRAM_ADDRDECODE_ADDR_5	5
+#define GT_SDRAM_ADDRDECODE_ADDR_6	6
+#define GT_SDRAM_ADDRDECODE_ADDR_7	7
+
+
+#define GT_SDRAM_B0_CASLAT_SHF		0
+#define GT_SDRAM_B0_CASLAT_MSK		(MSK(2) << GT_SDRAM_B0__SHF)
+#define GT_SDRAM_B0_CASLAT_2		1
+#define GT_SDRAM_B0_CASLAT_3		2
+
+#define GT_SDRAM_B0_FTDIS_SHF		2
+#define GT_SDRAM_B0_FTDIS_MSK		(MSK(1) << GT_SDRAM_B0_FTDIS_SHF)
+#define GT_SDRAM_B0_FTDIS_BIT		GT_SDRAM_B0_FTDIS_MSK
+
+#define GT_SDRAM_B0_SRASPRCHG_SHF	3
+#define GT_SDRAM_B0_SRASPRCHG_MSK	(MSK(1) << GT_SDRAM_B0_SRASPRCHG_SHF)
+#define GT_SDRAM_B0_SRASPRCHG_BIT	GT_SDRAM_B0_SRASPRCHG_MSK
+#define GT_SDRAM_B0_SRASPRCHG_2		0
+#define GT_SDRAM_B0_SRASPRCHG_3		1
+
+#define GT_SDRAM_B0_B0COMPAB_SHF	4
+#define GT_SDRAM_B0_B0COMPAB_MSK	(MSK(1) << GT_SDRAM_B0_B0COMPAB_SHF)
+#define GT_SDRAM_B0_B0COMPAB_BIT	GT_SDRAM_B0_B0COMPAB_MSK
+
+#define GT_SDRAM_B0_64BITINT_SHF	5
+#define GT_SDRAM_B0_64BITINT_MSK	(MSK(1) << GT_SDRAM_B0_64BITINT_SHF)
+#define GT_SDRAM_B0_64BITINT_BIT	GT_SDRAM_B0_64BITINT_MSK
+#define GT_SDRAM_B0_64BITINT_2		0
+#define GT_SDRAM_B0_64BITINT_4		1
+
+#define GT_SDRAM_B0_BW_SHF		6
+#define GT_SDRAM_B0_BW_MSK		(MSK(1) << GT_SDRAM_B0_BW_SHF)
+#define GT_SDRAM_B0_BW_BIT		GT_SDRAM_B0_BW_MSK
+#define GT_SDRAM_B0_BW_32		0
+#define GT_SDRAM_B0_BW_64		1
+
+#define GT_SDRAM_B0_BLODD_SHF		7
+#define GT_SDRAM_B0_BLODD_MSK		(MSK(1) << GT_SDRAM_B0_BLODD_SHF)
+#define GT_SDRAM_B0_BLODD_BIT		GT_SDRAM_B0_BLODD_MSK
+
+#define GT_SDRAM_B0_PAR_SHF		8
+#define GT_SDRAM_B0_PAR_MSK		(MSK(1) << GT_SDRAM_B0_PAR_SHF)
+#define GT_SDRAM_B0_PAR_BIT		GT_SDRAM_B0_PAR_MSK
+
+#define GT_SDRAM_B0_BYPASS_SHF		9
+#define GT_SDRAM_B0_BYPASS_MSK		(MSK(1) << GT_SDRAM_B0_BYPASS_SHF)
+#define GT_SDRAM_B0_BYPASS_BIT		GT_SDRAM_B0_BYPASS_MSK
+
+#define GT_SDRAM_B0_SRAS2SCAS_SHF	10
+#define GT_SDRAM_B0_SRAS2SCAS_MSK	(MSK(1) << GT_SDRAM_B0_SRAS2SCAS_SHF)
+#define GT_SDRAM_B0_SRAS2SCAS_BIT	GT_SDRAM_B0_SRAS2SCAS_MSK
+#define GT_SDRAM_B0_SRAS2SCAS_2		0
+#define GT_SDRAM_B0_SRAS2SCAS_3		1
+
+#define GT_SDRAM_B0_SIZE_SHF		11
+#define GT_SDRAM_B0_SIZE_MSK		(MSK(1) << GT_SDRAM_B0_SIZE_SHF)
+#define GT_SDRAM_B0_SIZE_BIT		GT_SDRAM_B0_SIZE_MSK
+#define GT_SDRAM_B0_SIZE_16M		0
+#define GT_SDRAM_B0_SIZE_64M		1
+
+#define GT_SDRAM_B0_EXTPAR_SHF		12
+#define GT_SDRAM_B0_EXTPAR_MSK		(MSK(1) << GT_SDRAM_B0_EXTPAR_SHF)
+#define GT_SDRAM_B0_EXTPAR_BIT		GT_SDRAM_B0_EXTPAR_MSK
+
+#define GT_SDRAM_B0_BLEN_SHF		13
+#define GT_SDRAM_B0_BLEN_MSK		(MSK(1) << GT_SDRAM_B0_BLEN_SHF)
+#define GT_SDRAM_B0_BLEN_BIT		GT_SDRAM_B0_BLEN_MSK
+#define GT_SDRAM_B0_BLEN_8		0
+#define GT_SDRAM_B0_BLEN_4		1
+
+
+#define GT_SDRAM_CFG_REFINT_SHF		0
+#define GT_SDRAM_CFG_REFINT_MSK		(MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
+
+#define GT_SDRAM_CFG_NINTERLEAVE_SHF	14
+#define GT_SDRAM_CFG_NINTERLEAVE_MSK	(MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
+#define GT_SDRAM_CFG_NINTERLEAVE_BIT	GT_SDRAM_CFG_NINTERLEAVE_MSK
+
+#define GT_SDRAM_CFG_RMW_SHF		15
+#define GT_SDRAM_CFG_RMW_MSK		(MSK(1) << GT_SDRAM_CFG_RMW_SHF)
+#define GT_SDRAM_CFG_RMW_BIT		GT_SDRAM_CFG_RMW_MSK
+
+#define GT_SDRAM_CFG_NONSTAGREF_SHF	16
+#define GT_SDRAM_CFG_NONSTAGREF_MSK	(MSK(1) << GT_SDRAM_CFG_NONSTAGREF_SHF)
+#define GT_SDRAM_CFG_NONSTAGREF_BIT	GT_SDRAM_CFG_NONSTAGREF_MSK
+
+#define GT_SDRAM_CFG_DUPCNTL_SHF	19
+#define GT_SDRAM_CFG_DUPCNTL_MSK	(MSK(1) << GT_SDRAM_CFG_DUPCNTL_SHF)
+#define GT_SDRAM_CFG_DUPCNTL_BIT	GT_SDRAM_CFG_DUPCNTL_MSK
+
+#define GT_SDRAM_CFG_DUPBA_SHF		20
+#define GT_SDRAM_CFG_DUPBA_MSK		(MSK(1) << GT_SDRAM_CFG_DUPBA_SHF)
+#define GT_SDRAM_CFG_DUPBA_BIT		GT_SDRAM_CFG_DUPBA_MSK
+
+#define GT_SDRAM_CFG_DUPEOT0_SHF	21
+#define GT_SDRAM_CFG_DUPEOT0_MSK	(MSK(1) << GT_SDRAM_CFG_DUPEOT0_SHF)
+#define GT_SDRAM_CFG_DUPEOT0_BIT	GT_SDRAM_CFG_DUPEOT0_MSK
+
+#define GT_SDRAM_CFG_DUPEOT1_SHF	22
+#define GT_SDRAM_CFG_DUPEOT1_MSK	(MSK(1) << GT_SDRAM_CFG_DUPEOT1_SHF)
+#define GT_SDRAM_CFG_DUPEOT1_BIT	GT_SDRAM_CFG_DUPEOT1_MSK
+
+#define GT_SDRAM_OPMODE_OP_SHF		0
+#define GT_SDRAM_OPMODE_OP_MSK		(MSK(3) << GT_SDRAM_OPMODE_OP_SHF)
+#define GT_SDRAM_OPMODE_OP_NORMAL	0
+#define GT_SDRAM_OPMODE_OP_NOP		1
+#define GT_SDRAM_OPMODE_OP_PRCHG	2
+#define GT_SDRAM_OPMODE_OP_MODE		3
+#define GT_SDRAM_OPMODE_OP_CBR		4
+
+#define GT_TC_CONTROL_ENTC0_SHF		0
+#define GT_TC_CONTROL_ENTC0_MSK		(MSK(1) << GT_TC_CONTROL_ENTC0_SHF)
+#define GT_TC_CONTROL_ENTC0_BIT		GT_TC_CONTROL_ENTC0_MSK
+#define GT_TC_CONTROL_SELTC0_SHF	1
+#define GT_TC_CONTROL_SELTC0_MSK	(MSK(1) << GT_TC_CONTROL_SELTC0_SHF)
+#define GT_TC_CONTROL_SELTC0_BIT	GT_TC_CONTROL_SELTC0_MSK
+
+
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_SHF	0
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_MSK	(MSK(1) << GT_PCI0_BARE_SWSCS3BOOTDIS_SHF)
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_BIT	GT_PCI0_BARE_SWSCS3BOOTDIS_MSK
+
+#define GT_PCI0_BARE_SWSCS32DIS_SHF	1
+#define GT_PCI0_BARE_SWSCS32DIS_MSK	(MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF)
+#define GT_PCI0_BARE_SWSCS32DIS_BIT	GT_PCI0_BARE_SWSCS32DIS_MSK
+
+#define GT_PCI0_BARE_SWSCS10DIS_SHF	2
+#define GT_PCI0_BARE_SWSCS10DIS_MSK	(MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF)
+#define GT_PCI0_BARE_SWSCS10DIS_BIT	GT_PCI0_BARE_SWSCS10DIS_MSK
+
+#define GT_PCI0_BARE_INTIODIS_SHF	3
+#define GT_PCI0_BARE_INTIODIS_MSK	(MSK(1) << GT_PCI0_BARE_INTIODIS_SHF)
+#define GT_PCI0_BARE_INTIODIS_BIT	GT_PCI0_BARE_INTIODIS_MSK
+
+#define GT_PCI0_BARE_INTMEMDIS_SHF	4
+#define GT_PCI0_BARE_INTMEMDIS_MSK	(MSK(1) << GT_PCI0_BARE_INTMEMDIS_SHF)
+#define GT_PCI0_BARE_INTMEMDIS_BIT	GT_PCI0_BARE_INTMEMDIS_MSK
+
+#define GT_PCI0_BARE_CS3BOOTDIS_SHF	5
+#define GT_PCI0_BARE_CS3BOOTDIS_MSK	(MSK(1) << GT_PCI0_BARE_CS3BOOTDIS_SHF)
+#define GT_PCI0_BARE_CS3BOOTDIS_BIT	GT_PCI0_BARE_CS3BOOTDIS_MSK
+
+#define GT_PCI0_BARE_CS20DIS_SHF	6
+#define GT_PCI0_BARE_CS20DIS_MSK	(MSK(1) << GT_PCI0_BARE_CS20DIS_SHF)
+#define GT_PCI0_BARE_CS20DIS_BIT	GT_PCI0_BARE_CS20DIS_MSK
+
+#define GT_PCI0_BARE_SCS32DIS_SHF	7
+#define GT_PCI0_BARE_SCS32DIS_MSK	(MSK(1) << GT_PCI0_BARE_SCS32DIS_SHF)
+#define GT_PCI0_BARE_SCS32DIS_BIT	GT_PCI0_BARE_SCS32DIS_MSK
+
+#define GT_PCI0_BARE_SCS10DIS_SHF	8
+#define GT_PCI0_BARE_SCS10DIS_MSK	(MSK(1) << GT_PCI0_BARE_SCS10DIS_SHF)
+#define GT_PCI0_BARE_SCS10DIS_BIT	GT_PCI0_BARE_SCS10DIS_MSK
+
+
+#define GT_INTRCAUSE_MASABORT0_SHF	18
+#define GT_INTRCAUSE_MASABORT0_MSK	(MSK(1) << GT_INTRCAUSE_MASABORT0_SHF)
+#define GT_INTRCAUSE_MASABORT0_BIT	GT_INTRCAUSE_MASABORT0_MSK
+
+#define GT_INTRCAUSE_TARABORT0_SHF	19
+#define GT_INTRCAUSE_TARABORT0_MSK	(MSK(1) << GT_INTRCAUSE_TARABORT0_SHF)
+#define GT_INTRCAUSE_TARABORT0_BIT	GT_INTRCAUSE_TARABORT0_MSK
+
+
+#define GT_PCI0_CFGADDR_REGNUM_SHF	2
+#define GT_PCI0_CFGADDR_REGNUM_MSK	(MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
+#define GT_PCI0_CFGADDR_FUNCTNUM_SHF	8
+#define GT_PCI0_CFGADDR_FUNCTNUM_MSK	(MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+#define GT_PCI0_CFGADDR_DEVNUM_SHF	11
+#define GT_PCI0_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
+#define GT_PCI0_CFGADDR_BUSNUM_SHF	16
+#define GT_PCI0_CFGADDR_BUSNUM_MSK	(MSK(8) << GT_PCI0_CFGADDR_BUSNUM_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_SHF	31
+#define GT_PCI0_CFGADDR_CONFIGEN_MSK	(MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_BIT	GT_PCI0_CFGADDR_CONFIGEN_MSK
+
+#define GT_PCI0_CMD_MBYTESWAP_SHF	0
+#define GT_PCI0_CMD_MBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+#define GT_PCI0_CMD_MBYTESWAP_BIT	GT_PCI0_CMD_MBYTESWAP_MSK
+#define GT_PCI0_CMD_MWORDSWAP_SHF	10
+#define GT_PCI0_CMD_MWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
+#define GT_PCI0_CMD_MWORDSWAP_BIT	GT_PCI0_CMD_MWORDSWAP_MSK
+#define GT_PCI0_CMD_SBYTESWAP_SHF	16
+#define GT_PCI0_CMD_SBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+#define GT_PCI0_CMD_SBYTESWAP_BIT	GT_PCI0_CMD_SBYTESWAP_MSK
+#define GT_PCI0_CMD_SWORDSWAP_SHF	11
+#define GT_PCI0_CMD_SWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
+#define GT_PCI0_CMD_SWORDSWAP_BIT	GT_PCI0_CMD_SWORDSWAP_MSK
+
+#define GT_INTR_T0EXP_SHF		8
+#define GT_INTR_T0EXP_MSK		(MSK(1) << GT_INTR_T0EXP_SHF)
+#define GT_INTR_T0EXP_BIT		GT_INTR_T0EXP_MSK
+#define GT_INTR_RETRYCTR0_SHF		20
+#define GT_INTR_RETRYCTR0_MSK		(MSK(1) << GT_INTR_RETRYCTR0_SHF)
+#define GT_INTR_RETRYCTR0_BIT		GT_INTR_RETRYCTR0_MSK
+
+/*
+ *  Misc
+ */
+#define GT_DEF_PCI0_IO_BASE	0x10000000UL
+#define GT_DEF_PCI0_IO_SIZE	0x02000000UL
+#define GT_DEF_PCI0_MEM0_BASE	0x12000000UL
+#define GT_DEF_PCI0_MEM0_SIZE	0x02000000UL
+#define GT_DEF_BASE		0x14000000UL
+
+#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)	/* Max 256MB bank  */
+#define GT_LATTIM_MIN		6			/* Minimum lat  */
+
+/*
+ * The gt64120_dep.h file must define the following macros
+ *
+ *   GT_READ(ofs, data_pointer)
+ *   GT_WRITE(ofs, data)           - read/write GT64120 registers in 32bit
+ *
+ *   TIMER 	- gt64120 timer irq, temporary solution until
+ *		  full gt64120 cascade interrupt support is in place
+ */
+
+/*
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the
+ * bytes when running bigendian.  We also provide non-swapping versions.
+ */
+#define __GT_READ(ofs)							\
+	(*(volatile u32 *)(GT64120_BASE+(ofs)))
+#define __GT_WRITE(ofs, data)						\
+	do { *(volatile u32 *)(GT64120_BASE+(ofs)) = (data); } while (0)
+#define GT_READ(ofs)		le32_to_cpu(__GT_READ(ofs))
+#define GT_WRITE(ofs, data)	__GT_WRITE(ofs, cpu_to_le32(data))
+
+extern void gt641xx_set_base_clock(unsigned int clock);
+extern int gt641xx_timer0_state(void);
+
+#endif /* _ASM_GT64120_H */
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [RFC V2 3/6] MIPS: add PCI support for GT64120-based malta
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 1/6] PCI: initial commit (draft) Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 2/6] MIPS: add file gt64120.h from linux 2.6.39 Antony Pavlov
@ 2012-03-08 19:50 ` Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 4/6] PCI: add draft lspci command Antony Pavlov
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 arch/mips/Kconfig             |   22 ++++
 arch/mips/mach-malta/Makefile |    1 +
 arch/mips/mach-malta/pci.c    |  241 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/mach-malta/pci.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 50d5c67..158cdce 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -36,6 +36,7 @@ config MACH_MIPS_MALTA
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select HAS_DEBUG_LL
+	select HW_HAS_PCI
 
 config MACH_MIPS_BCM47XX
 	bool "Broadcom BCM47xx-based boards"
@@ -219,6 +220,27 @@ config CMD_MIPS_CPUINFO
 
 endmenu
 
+menu "Bus options (PCI)"
+
+config HW_HAS_PCI
+	bool
+
+config PCI
+	bool "Support for PCI controller"
+	depends on HW_HAS_PCI
+	select PCI_DOMAINS
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. If you have PCI, say Y, otherwise N.
+
+config PCI_DOMAINS
+	bool
+
+source "drivers/pci/Kconfig"
+
+endmenu
+
 source common/Kconfig
 source commands/Kconfig
 source net/Kconfig
diff --git a/arch/mips/mach-malta/Makefile b/arch/mips/mach-malta/Makefile
index f3cc668..0c5a701 100644
--- a/arch/mips/mach-malta/Makefile
+++ b/arch/mips/mach-malta/Makefile
@@ -1 +1,2 @@
 obj-y += reset.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/mach-malta/pci.c b/arch/mips/mach-malta/pci.c
new file mode 100644
index 0000000..5e679a7
--- /dev/null
+++ b/arch/mips/mach-malta/pci.c
@@ -0,0 +1,241 @@
+#include <common.h>
+#include <types.h>
+#include <driver.h>
+#include <init.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+#include <linux/pci.h>
+#include <asm/gt64120.h>
+
+#define GT64120_BASE    0xb4000000
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+static struct resource gt64120_mem_resource = {
+	.name	= "GT-64120 PCI MEM",
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource gt64120_io_resource = {
+	.name	= "GT-64120 PCI I/O",
+	.flags	= IORESOURCE_IO,
+};
+
+static int gt64xxx_pci0_pcibios_config_access(unsigned char access_type,
+		struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
+{
+	unsigned char busnum = bus->number;
+	u32 intr;
+
+	if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
+		return -1;	/* Because of a bug in the galileo (for slot 31). */
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+	                             GT_INTRCAUSE_TARABORT0_BIT));
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+			/*
+			 * The Galileo system controller is acting
+			 * differently than other devices.
+			 */
+			GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+		} else
+			__GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+	} else {
+		if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+			/*
+			 * The Galileo system controller is acting
+			 * differently than other devices.
+			 */
+			*data = GT_READ(GT_PCI0_CFGDATA_OFS);
+		} else
+			*data = __GT_READ(GT_PCI0_CFGDATA_OFS);
+	}
+
+	/* Check for master or target abort */
+	intr = GT_READ(GT_INTRCAUSE_OFS);
+
+	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
+		/* Error occurred */
+
+		/* Clear bits */
+		GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+		                             GT_INTRCAUSE_TARABORT0_BIT));
+
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int gt64xxx_pci0_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+		int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+	                                       where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int gt64xxx_pci0_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+		int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if (size == 4)
+		data = val;
+	else {
+		if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus,
+		                                       devfn, where, &data))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+	                                       where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* FIXME: it's HACK */
+/* function returns memory address for begin of pci resource */
+static int gt64xxx_res_start(struct pci_bus *bus, resource_size_t res_addr)
+{
+	return res_addr | 0xa0000000;
+}
+
+struct pci_ops gt64xxx_pci0_ops = {
+	.read	= gt64xxx_pci0_pcibios_read,
+	.write	= gt64xxx_pci0_pcibios_write,
+
+	.res_start = gt64xxx_res_start,
+};
+
+static struct pci_controller gt64120_controller = {
+	.pci_ops	= &gt64xxx_pci0_ops,
+	.io_resource	= &gt64120_io_resource,
+	.mem_resource	= &gt64120_mem_resource,
+};
+
+int pcibios_init()
+{
+	resource_size_t start, end, map, start1, end1, map1, mask, res_end;
+
+	/*
+	 * Due to a bug in the Galileo system controller, we need
+	 * to setup the PCI BAR for the Galileo internal registers.
+	 * This should be done in the bios/bootprom and will be
+	 * fixed in a later revision of YAMON (the MIPS boards
+	 * boot prom).
+	 */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+		 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+		 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	/* Perform the write */
+	//GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+	//GT_WRITE(GT_PCI0_CFGDATA_OFS, GT64120_BASE);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x14000000);
+
+#define PCI0_IO_SPACE_BASE	0x10000000
+#define PCI0_IO_SPACE_SIZE	0x01000000
+#define PCI0_MEM_SPACE_BASE	0x11000000
+#define PCI0_MEM_SPACE_SIZE	0x01000000
+
+#if 1
+	GT_WRITE(GT_PCI0IOLD_OFS, (PCI0_IO_SPACE_BASE >> 21) & 0x7ff);
+	GT_WRITE(GT_PCI0IOHD_OFS, ((PCI0_IO_SPACE_BASE + PCI0_IO_SPACE_SIZE - 1) >> 21) & 0x7f);
+	GT_WRITE(GT_PCI0M0LD_OFS, (PCI0_MEM_SPACE_BASE >> 21) & 0x7ff);
+	GT_WRITE(GT_PCI0M0HD_OFS, ((PCI0_MEM_SPACE_BASE + PCI0_MEM_SPACE_SIZE - 1) >> 21) & 0x7f);
+#endif
+
+	/* Here is linux code. It assumes, that firmware made the work... */
+
+	/* Set up resource ranges from the controller's registers.  */
+	start = GT_READ(GT_PCI0M0LD_OFS);
+	end = GT_READ(GT_PCI0M0HD_OFS);
+	map = GT_READ(GT_PCI0M0REMAP_OFS);
+	end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+	start1 = GT_READ(GT_PCI0M1LD_OFS);
+	end1 = GT_READ(GT_PCI0M1HD_OFS);
+	map1 = GT_READ(GT_PCI0M1REMAP_OFS);
+	end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
+#if 0
+	/* Cannot support multiple windows, use the wider.  */
+	if (end1 - start1 > end - start) {
+		start = start1;
+		end = end1;
+		map = map1;
+	}
+#endif
+	mask = ~(start ^ end);
+        /* We don't support remapping with a discontiguous mask.  */
+	BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+	       mask != ~((mask & -mask) - 1));
+	gt64120_mem_resource.start = start;
+	res_end = end;
+	gt64120_controller.mem_offset = (start & mask) - (map & mask);
+	/* Addresses are 36-bit, so do shifts in the destinations.  */
+	gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
+	res_end <<= GT_PCI_DCRM_SHF;
+	res_end |= (1 << GT_PCI_DCRM_SHF) - 1;
+	gt64120_mem_resource.size = res_end - gt64120_mem_resource.start + 1;
+	gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
+
+	start = GT_READ(GT_PCI0IOLD_OFS);
+	end = GT_READ(GT_PCI0IOHD_OFS);
+	map = GT_READ(GT_PCI0IOREMAP_OFS);
+	end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+	mask = ~(start ^ end);
+        /* We don't support remapping with a discontiguous mask.  */
+	BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+	       mask != ~((mask & -mask) - 1));
+	gt64120_io_resource.start = map & mask;
+	res_end = (map & mask) | ~mask;
+	gt64120_controller.io_offset = 0;
+	/* Addresses are 36-bit, so do shifts in the destinations.  */
+	gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
+	res_end <<= GT_PCI_DCRM_SHF;
+	res_end |= (1 << GT_PCI_DCRM_SHF) - 1;
+	gt64120_io_resource.size = res_end - gt64120_io_resource.start + 1;
+
+	register_pci_controller(&gt64120_controller);
+
+	return 0;
+}
+EXPORT_SYMBOL(pcibios_init);
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [RFC V2 4/6] PCI: add draft lspci command
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
                   ` (2 preceding siblings ...)
  2012-03-08 19:50 ` [RFC V2 3/6] MIPS: add PCI support for GT64120-based malta Antony Pavlov
@ 2012-03-08 19:50 ` Antony Pavlov
  2012-03-08 19:50 ` [RFC V2 5/6] net: add Realtek 8139 Ethernet controller support Antony Pavlov
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 commands/Kconfig  |    8 ++++++++
 commands/Makefile |    1 +
 commands/lspci.c  |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 0 deletions(-)
 create mode 100644 commands/lspci.c

diff --git a/commands/Kconfig b/commands/Kconfig
index e332a85..2367014 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -516,6 +516,14 @@ config CMD_USB
 	help
 	  The usb command allows to rescan for USB devices.
 
+config CMD_LSPCI
+	bool
+	depends on PCI
+	prompt "lspci command"
+	default y
+	help
+	  The lspci command allows to list all PCI devices.
+
 endmenu
 
 endif
diff --git a/commands/Makefile b/commands/Makefile
index 31442b5..273acce 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_CMD_OFTREE)	+= oftree.o
 obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
 obj-$(CONFIG_CMD_IOMEM)		+= iomem.o
 obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
+obj-$(CONFIG_CMD_LSPCI)		+= lspci.o
diff --git a/commands/lspci.c b/commands/lspci.c
new file mode 100644
index 0000000..1460f39
--- /dev/null
+++ b/commands/lspci.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/pci.h>
+
+#include <command.h>
+
+extern struct pci_bus *pci_root;
+
+static int do_lspci(struct command *cmdtp, int argc, char *argv[])
+{
+	struct pci_dev *dev;
+
+	if (!pci_present()) {
+		printf("no pci!\n");
+		return 1;
+	}
+
+	list_for_each_entry(dev, &pci_root->devices, bus_list) {
+		printf("%02x: %04x: %04x:%04x (rev %02x)\n",
+			      dev->devfn,
+			      (dev->class >> 8) & 0xffff,
+			      dev->vendor,
+			      dev->device,
+			      dev->revision);
+	}
+
+	return 0;
+}
+
+BAREBOX_CMD_START(lspci)
+	.cmd            = do_lspci,
+	.usage          = "Show PCI info",
+BAREBOX_CMD_END
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [RFC V2 5/6] net: add Realtek 8139 Ethernet controller support
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
                   ` (3 preceding siblings ...)
  2012-03-08 19:50 ` [RFC V2 4/6] PCI: add draft lspci command Antony Pavlov
@ 2012-03-08 19:50 ` Antony Pavlov
  2012-03-09 18:17   ` Sascha Hauer
  2012-03-08 19:50 ` [RFC V2 6/6] net: add DEC 21143 (tulip) " Antony Pavlov
  2012-03-09 17:56 ` [RFC V2 0/6] barebox PCI support Sascha Hauer
  6 siblings, 1 reply; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

This driver is based on Linux 2.6.39 8139too driver.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/net/Kconfig     |    8 +
 drivers/pci/Makefile    |    1 +
 drivers/pci/rtl8139.c   |  654 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci_ids.h |    5 +
 4 files changed, 668 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pci/rtl8139.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b236d17..ff18b5e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -100,6 +100,14 @@ config TSE_USE_DEDICATED_DESC_MEM
 	  reserved with a malloc but directly mapped to the memory
 	  address (defined in config.h)
 
+config 8139
+	depends on PCI
+	bool "RealTek RTL-8139 PCI Fast Ethernet Adapter support"
+	select MIIDEV
+	help
+	  This is a driver for the Fast Ethernet PCI network cards based on
+	  the RTL 8139 chips.
+
 source "drivers/net/usb/Kconfig"
 
 endmenu
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c7d43c3..6523385 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the PCI bus specific drivers.
 #
 obj-y		+= pci.o bus.o
+obj-$(CONFIG_8139)	+= rtl8139.o
 
 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
 
diff --git a/drivers/pci/rtl8139.c b/drivers/pci/rtl8139.c
new file mode 100644
index 0000000..57575bb
--- /dev/null
+++ b/drivers/pci/rtl8139.c
@@ -0,0 +1,654 @@
+#include <common.h>
+
+#include <command.h>
+#include <net.h>
+#include <miidev.h>
+#include <malloc.h>
+#include <init.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+
+#include <linux/pci.h>
+
+#undef RTL8139_DEBUG
+#define RTL8139_DEBUG
+
+/*
+ * Receive ring size
+ * Warning: 64K ring has hardware issues and may lock up.
+ */
+#define RX_BUF_IDX	0	/* 8K ring */
+#define RX_BUF_LEN	(8192 << RX_BUF_IDX)
+#define RX_BUF_PAD	16
+#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
+
+#if RX_BUF_LEN == 65536
+#define RX_BUF_TOT_LEN	RX_BUF_LEN
+#else
+#define RX_BUF_TOT_LEN	(RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
+#endif
+
+/* Number of Tx descriptor registers. */
+#define NUM_TX_DESC	4
+
+/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/
+#define MAX_ETH_FRAME_SIZE	1536
+
+/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
+#define TX_BUF_SIZE	MAX_ETH_FRAME_SIZE
+#define TX_BUF_TOT_LEN	(TX_BUF_SIZE * NUM_TX_DESC)
+
+/* PCI Tuning Parameters
+   Threshold is bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
+
+/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
+#define RX_FIFO_THRESH	7	/* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	7	/* Maximum PCI burst, '6' is 1024 */
+#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+#define TX_RETRY	8	/* 0-15.  retries = 16 + (TX_RETRY * 16) */
+
+struct rtl8139_priv {
+	void __iomem		*base;
+	struct pci_dev		*pci_dev;
+	unsigned char		*rx_ring;
+	unsigned int		cur_rx; /* RX buf index of next pkt */
+	dma_addr_t		rx_ring_dma;
+
+	u32			rx_config;
+	unsigned int		tx_flag;
+	unsigned long		cur_tx;
+	unsigned long		dirty_tx;
+	unsigned char		*tx_buf[NUM_TX_DESC];   /* Tx bounce buffers */
+	unsigned char		*tx_bufs;       /* Tx bounce buffer region. */
+	dma_addr_t		tx_bufs_dma;
+
+	struct mii_device	miidev;
+};
+
+#define ETH_ZLEN        60              /* Min. octets in frame sans FCS */
+
+/* Registers */
+#define MAC0		0x00
+#define MAR0		0x08
+#define TxStatus0	0x10
+
+enum TxStatusBits {
+	TxHostOwns	= 0x2000,
+	TxUnderrun	= 0x4000,
+	TxStatOK	= 0x8000,
+	TxOutOfWindow	= 0x20000000,
+	TxAborted	= 0x40000000,
+	TxCarrierLost	= 0x80000000,
+};
+
+#define TxAddr0		0x20
+#define RxBuf		0x30
+#define ChipCmd		0x37
+#define  CmdReset	0x10
+#define  CmdRxEnb	0x08
+#define  CmdTxEnb	0x04
+#define  RxBufEmpty	0x01
+#define RxBufPtr	0x38
+#define RxBufAddr	0x3A
+#define IntrMask	0x3C
+#define IntrStatus	0x3E
+#define  PCIErr		0x8000
+#define  PCSTimeout	0x4000
+#define  RxFIFOOver	0x0040
+#define  RxUnderrun	0x0020
+#define  RxOverflow	0x0010
+#define  TxErr		0x0008
+#define  TxOK		0x0004
+#define  RxErr		0x0002
+#define  RxOK		0x0001
+#define    RxAckBits	(RxFIFOOver | RxOverflow | RxOK)
+
+#define TxConfig	0x40
+/* Bits in TxConfig. */
+enum tx_config_bits {
+	/* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
+	TxIFGShift	= 24,
+	TxIFG84		= (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */
+	TxIFG88		= (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */
+	TxIFG92		= (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */
+	TxIFG96		= (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */
+
+	TxLoopBack	= (1 << 18) | (1 << 17), /* enable loopback test mode */
+	TxCRC		= (1 << 16),	/* DISABLE Tx pkt CRC append */
+	TxClearAbt	= (1 << 0),	/* Clear abort (WO) */
+	TxDMAShift	= 8, /* DMA burst value (0-7) is shifted X many bits */
+	TxRetryShift	= 4, /* TXRR value (0-15) is shifted X many bits */
+
+	TxVersionMask	= 0x7C800000, /* mask out version bits 30-26, 23 */
+};
+
+#define RxConfig	0x44
+	/* rx fifo threshold */
+#define  RxCfgFIFOShift	13
+#define	 RxCfgFIFONone	(7 << RxCfgFIFOShift)
+	/* Max DMA burst */
+#define	 RxCfgDMAShift	8
+#define	 RxCfgDMAUnlimited (7 << RxCfgDMAShift)
+	/* rx ring buffer length */
+#define	 RxCfgRcv8K	0
+#define	 RxCfgRcv16K	(1 << 11)
+#define	 RxCfgRcv32K	(1 << 12)
+#define	 RxCfgRcv64K	((1 << 11) | (1 << 12))
+	/* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
+#define	 RxNoWrap	(1 << 7)
+#define	 AcceptErr		0x20
+#define	 AcceptRunt		0x10
+#define	 AcceptBroadcast	0x08
+#define	 AcceptMulticast	0x04
+#define	 AcceptMyPhys		0x02
+#define	 AcceptAllPhys		0x01
+
+#define RxMissed	0x4C
+#define Cfg9346		0x50
+#define  Cfg9346_Lock	0x00
+#define  Cfg9346_Unlock	0xC0
+#define BasicModeCtrl	0x62
+#define BasicModeStatus	0x64
+#define NWayAdvert	0x66
+#define NWayLPAR	0x68
+#define NWayExpansion	0x6a
+
+static const char mii_2_8139_map[8] = {
+	BasicModeCtrl,
+	BasicModeStatus,
+	0,
+	0,
+	NWayAdvert,
+	NWayLPAR,
+	NWayExpansion,
+	0
+};
+
+/* write MMIO register */
+#define RTL_W8(priv, reg, val)	writeb(val, ((char *)(priv->base) + reg))
+#define RTL_W16(priv, reg, val)	writew(val, ((char *)(priv->base) + reg))
+#define RTL_W32(priv, reg, val)	writel(val, ((char *)(priv->base) + reg))
+
+/* read MMIO register */
+#define RTL_R8(priv, reg)	readb(((char *)(priv->base) + reg))
+#define RTL_R16(priv, reg)	readw(((char *)(priv->base) + reg))
+#define RTL_R32(priv, reg)	readl(((char *)(priv->base) + reg))
+
+/* write MMIO register, with flush */
+/* Flush avoids rtl8139 bug w/ posted MMIO writes */
+static inline void RTL_W8_F(struct rtl8139_priv *priv, int reg, int val)
+{
+	RTL_W8(priv, reg, val);
+	RTL_R8(priv, reg);
+}
+
+static inline void RTL_W16_F(struct rtl8139_priv *priv, int reg, int val)
+{
+	RTL_W16(priv, reg, val);
+	RTL_R16(priv, reg);
+}
+
+static inline void RTL_W32_F(struct rtl8139_priv *priv, int reg, int val)
+{
+	RTL_W32(priv, reg, val);
+	RTL_R32(priv, reg);
+}
+
+static const unsigned int rtl8139_rx_config =
+	RxCfgRcv8K | RxNoWrap |
+	(RX_FIFO_THRESH << RxCfgFIFOShift) |
+	(RX_DMA_BURST << RxCfgDMAShift);
+
+static const unsigned int rtl8139_tx_config =
+	TxIFG96 | (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
+
+static void rtl8139_chip_reset(struct rtl8139_priv *priv)
+{
+	int i;
+
+#ifdef RTL8139_DEBUG
+	printf("rtl8139_chip_reset()\n");
+#endif
+
+	/* Soft reset the chip. */
+	RTL_W8(priv, ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--) {
+		//barrier();
+		if ((RTL_R8(priv, ChipCmd) & CmdReset) == 0)
+			break;
+		udelay(10);
+	}
+}
+
+static void __set_rx_mode(struct rtl8139_priv *priv)
+{
+	u32 mc_filter[2];	/* Multicast hash filter */
+	int rx_mode;
+	u32 tmp;
+
+	rx_mode =
+	    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+	    AcceptAllPhys;
+	mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+	/* We can safely update without stopping the chip. */
+	tmp = rtl8139_rx_config | rx_mode;
+	if (priv->rx_config != tmp) {
+		RTL_W32_F(priv, RxConfig, tmp);
+		priv->rx_config = tmp;
+	}
+
+	RTL_W32_F(priv, MAR0 + 0, mc_filter[0]);
+	RTL_W32_F(priv, MAR0 + 4, mc_filter[1]);
+}
+
+/* Start the hardware at open or resume. */
+static void rtl8139_hw_start(struct rtl8139_priv *priv)
+{
+	u32 i;
+	u8 tmp;
+
+	rtl8139_chip_reset(priv);
+
+	/* unlock Config[01234] and BMCR register writes */
+	RTL_W8_F(priv, Cfg9346, Cfg9346_Unlock);
+
+#if 0
+	/* Restore our idea of the MAC address. */
+	RTL_W32_F(priv, MAC0 + 0, *(__le32 *) (dev->dev_addr + 0));
+	RTL_W32_F(priv, MAC0 + 4, *(__le16 *) (dev->dev_addr + 4));
+#endif
+
+	priv->cur_rx = 0;
+
+	/* init Rx ring buffer DMA address */
+	RTL_W32_F(priv, RxBuf, priv->rx_ring_dma);
+
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	RTL_W8(priv, ChipCmd, CmdRxEnb | CmdTxEnb);
+
+	priv->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
+	RTL_W32(priv, RxConfig, priv->rx_config);
+	RTL_W32(priv, TxConfig, rtl8139_tx_config);
+
+	/* Lock Config[01234] and BMCR register writes */
+	RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+
+	/* init Tx buffer DMA addresses */
+	for (i = 0; i < NUM_TX_DESC; i++)
+		RTL_W32_F(priv, TxAddr0 + (i * 4), priv->tx_bufs_dma + (priv->tx_buf[i] - priv->tx_bufs));
+
+	RTL_W32(priv, RxMissed, 0);
+
+	__set_rx_mode(priv);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16(priv, IntrMask, 0);
+
+	/* make sure RxTx has started */
+	tmp = RTL_R8(priv, ChipCmd);
+	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
+		RTL_W8(priv, ChipCmd, CmdRxEnb | CmdTxEnb);
+}
+
+static inline void rtl8139_tx_clear(struct rtl8139_priv *priv)
+{
+	priv->cur_tx = 0;
+	priv->dirty_tx = 0;
+
+	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
+}
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void rtl8139_init_ring(struct rtl8139_priv *priv)
+{
+	int i;
+
+	priv->cur_rx = 0;
+	priv->cur_tx = 0;
+	priv->dirty_tx = 0;
+
+	for (i = 0; i < NUM_TX_DESC; i++)
+		priv->tx_buf[i] = &priv->tx_bufs[i * TX_BUF_SIZE];
+}
+
+static int rtl8139_phy_read(struct mii_device *mdev, int phy_addr, int reg)
+{
+	struct eth_device *edev = mdev->edev;
+	struct rtl8139_priv *priv = edev->priv;
+	int val;
+
+	val = 0;
+
+	if (phy_addr == 0) { /* Really a 8139. Use internal registers. */
+		val = reg < 8 && mii_2_8139_map[reg] ?
+				RTL_R16(priv, mii_2_8139_map[reg]) : 0;
+	}
+
+#ifdef RTL8139_DEBUG
+	printf("%s: addr: 0x%02x reg: 0x%02x val: 0x%04x\n", __func__,
+			phy_addr, reg, val);
+#endif
+
+	return val;
+}
+
+static int rtl8139_phy_write(struct mii_device *mdev, int phy_addr,
+	int reg, int val)
+{
+	struct eth_device *edev = mdev->edev;
+	struct rtl8139_priv *priv = edev->priv;
+
+#ifdef RTL8139_DEBUG
+	printf("%s: addr: 0x%02x reg: 0x%02x val: 0x%04x\n", __func__,
+	      phy_addr, reg, val);
+#endif
+
+	if (phy_addr == 0) { /* Really a 8139. Use internal registers. */
+		if (reg == 0) {
+			RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+			RTL_W16(priv, BasicModeCtrl, val);
+			RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+		} else if (reg < 8 && mii_2_8139_map[reg]) {
+			RTL_W16(priv, mii_2_8139_map[reg], val);
+		}
+	}
+
+	return 0;
+}
+
+static int rtl8139_get_ethaddr(struct eth_device *edev, unsigned char *m)
+{
+	struct rtl8139_priv *priv = edev->priv;
+	int i;
+
+	for (i = 0; i < 6; ++i) {
+		m[i] = RTL_R8(priv, (MAC0 + i));
+	}
+
+	return 0;
+}
+
+static int rtl8139_set_ethaddr(struct eth_device *edev,
+					unsigned char *mac_addr)
+{
+	struct rtl8139_priv *priv = edev->priv;
+	int i;
+
+	RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+
+	for (i = 0; i < 6; i++) {
+		RTL_W8(priv, (MAC0 + i), mac_addr[i]);
+		RTL_R8(priv, mac_addr[i]);
+	}
+
+	RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+
+	return 0;
+}
+
+static int rtl8139_init_dev(struct eth_device *edev)
+{
+	struct rtl8139_priv *priv = edev->priv;
+
+#ifdef RTL8139_DEBUG
+	printf("rtl8139_init_dev()\n");
+#endif
+
+	rtl8139_chip_reset(priv);
+
+	//miidev_restart_aneg(&priv->miidev);
+
+	return 0;
+}
+
+static int rtl8139_eth_open(struct eth_device *edev)
+{
+	struct rtl8139_priv *priv = edev->priv;
+
+	/* HACK: FIXME */
+	priv->tx_bufs = (unsigned char *)0xa1000000;
+	priv->tx_bufs_dma = (dma_addr_t)0x01000000;
+
+	priv->rx_ring = (unsigned char *)0xa2000000;
+	priv->rx_ring_dma = (dma_addr_t)0x02000000;
+
+	priv->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
+
+	rtl8139_init_ring(priv);
+	rtl8139_hw_start(priv);
+
+	miidev_wait_aneg(&priv->miidev);
+	miidev_print_status(&priv->miidev);
+
+	return 0;
+}
+
+static void rtl8139_eth_halt(struct eth_device *edev)
+{
+	struct rtl8139_priv *priv = edev->priv;
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	RTL_W8(priv, ChipCmd, 0);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16(priv, IntrMask, 0);
+
+	/* Green! Put the chip in low-power mode. */
+	RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+}
+
+static void rtl8139_tx_interrupt(struct rtl8139_priv *priv)
+{
+	unsigned long dirty_tx, tx_left;
+
+	dirty_tx = priv->dirty_tx;
+	tx_left = priv->cur_tx - dirty_tx;
+	while (tx_left > 0) {
+		int entry = dirty_tx % NUM_TX_DESC;
+		int txstatus;
+
+		txstatus = RTL_R32(priv, TxStatus0 + (entry * sizeof(u32)));
+
+		if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
+			break;	/* It still hasn't been Txed */
+
+		/* Note: TxCarrierLost is always asserted at 100mbps. */
+		if (txstatus & (TxOutOfWindow | TxAborted)) {
+			/* There was an major error, log it. */
+			printf("Transmit error, Tx status %08x\n", txstatus);
+			if (txstatus & TxAborted) {
+				RTL_W32(priv, TxConfig, TxClearAbt);
+				RTL_W16(priv, IntrStatus, TxErr);
+			}
+		} else {
+			if (txstatus & TxUnderrun) {
+				/* Add 64 to the Tx FIFO threshold. */
+				if (priv->tx_flag < 0x00300000)
+					priv->tx_flag += 0x00020000;
+			}
+		}
+
+		dirty_tx++;
+		tx_left--;
+	}
+
+	if (priv->dirty_tx != dirty_tx) {
+		priv->dirty_tx = dirty_tx;
+	}
+}
+
+static int rtl8139_eth_send(struct eth_device *edev, void *packet,
+				int packet_length)
+{
+	struct rtl8139_priv *priv = edev->priv;
+
+	unsigned int entry;
+
+#ifdef RTL8139_DEBUG
+	printf("rtl8139_eth_send()\n");
+	memory_display(packet, 0, 70, 1);
+#endif
+
+	rtl8139_tx_interrupt(priv);
+
+	/* Calculate the next Tx descriptor entry. */
+	entry = priv->cur_tx % NUM_TX_DESC;
+
+	/* Note: the chip doesn't have auto-pad! */
+	if (likely(packet_length < TX_BUF_SIZE)) {
+		if (packet_length < ETH_ZLEN)
+			memset(priv->tx_buf[entry], 0, ETH_ZLEN);
+		memcpy(priv->tx_buf[entry], packet, packet_length);
+	} else {
+		printf("packet too long\n");
+		return 0;
+	}
+
+	/*
+	 * Writing to TxStatus triggers a DMA transfer of the data
+	 * copied to tp->tx_buf[entry] above.
+	 */
+	if (packet_length < ETH_ZLEN) {
+		packet_length = ETH_ZLEN;
+	}
+	RTL_W32_F(priv, (TxStatus0 + (entry * sizeof(u32))),
+			(priv->tx_flag | packet_length));
+
+	priv->cur_tx++;
+
+	return 0;
+}
+
+static const u16 rtl8139_intr_mask =
+		PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
+		TxErr | TxOK | RxErr | RxOK;
+
+static int rtl8139_eth_rx(struct eth_device *edev)
+{
+	struct rtl8139_priv *priv = edev->priv;
+	unsigned char *rx_ring = priv->rx_ring;
+	unsigned int cur_rx = priv->cur_rx;
+	unsigned int rx_size = 0;
+
+	u32 ring_offset = cur_rx % RX_BUF_LEN;
+	u32 rx_status;
+	unsigned int pkt_size;
+
+#ifdef RTL8139_DEBUG
+	printf("rtl8139_eth_rx()\n");
+
+	printf("In %s(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
+		   __func__, (u16)cur_rx,
+		   RTL_R16(priv, RxBufAddr), RTL_R16(priv, RxBufPtr),
+		   RTL_R8(priv, ChipCmd));
+#endif
+
+	rtl8139_tx_interrupt(priv);
+
+	if (RTL_R8(priv, ChipCmd) & RxBufEmpty) {
+		/* no data */
+		return 0;
+	}
+
+	rx_status = le32_to_cpu(*(__le32 *) (rx_ring + ring_offset));
+	rx_size = rx_status >> 16;
+	pkt_size = rx_size - 4;
+
+#ifdef RTL8139_DEBUG
+	memory_display(&rx_ring[ring_offset], 0, 70, 1);
+#endif
+
+	net_receive(&rx_ring[ring_offset + 4], pkt_size);
+
+	cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+	cur_rx = cur_rx & (RX_BUF_LEN - 1); /* FIXME */
+	RTL_W16(priv, RxBufPtr, (u16) (cur_rx - 16));
+
+	priv->cur_rx = cur_rx;
+
+	return pkt_size /* size */;
+}
+
+static int rtl8139_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct eth_device *edev;
+	struct rtl8139_priv *priv;
+
+	u32 bar;
+	struct pci_bus *bus = pdev->bus;
+	struct device_d *dev = &pdev->dev;
+
+#ifdef RTL8139_DEBUG
+	printf("rtl8139_probe()\n");
+#endif
+
+	/* enable pci device */
+	pci_read_config_dword(pdev, PCI_COMMAND, &bar);
+	pci_write_config_dword(pdev, PCI_COMMAND, bar | 0x03);
+
+	edev = xzalloc(sizeof(struct eth_device) +
+			sizeof(struct rtl8139_priv));
+	dev->type_data = edev;
+	priv = (struct rtl8139_priv *)(edev + 1);
+
+	edev->priv = priv;
+
+	priv->pci_dev = pdev;
+
+	priv->miidev.read = rtl8139_phy_read;
+	priv->miidev.write = rtl8139_phy_write;
+	priv->miidev.address = 0;
+	priv->miidev.flags = 0;
+	priv->miidev.edev = edev;
+
+	/* FIXME: pci_resource_start() */
+	pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, &bar);
+	priv->base = (void *)bus->ops->res_start(bus, bar);
+
+	printf("found rtl8139 (rev %02x) at %02x: %04x (base=%p)\n",
+			pdev->revision,
+			pdev->devfn,
+			(pdev->class >> 8) & 0xffff,
+			priv->base);
+
+	edev->init = rtl8139_init_dev;
+	edev->open = rtl8139_eth_open;
+	edev->send = rtl8139_eth_send;
+	edev->recv = rtl8139_eth_rx;
+	edev->get_ethaddr = rtl8139_get_ethaddr;
+	edev->set_ethaddr = rtl8139_set_ethaddr;
+	edev->halt = rtl8139_eth_halt;
+
+	mii_register(&priv->miidev);
+	eth_register(edev);
+
+	return 0;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(rtl8139_pci_tbl) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	PCI_DEVICE_ID_REALTEK_8139), },
+	{ },
+};
+
+static struct pci_driver rtl8139_eth_driver = {
+	.name = "rtl8139_eth",
+	.id_table = rtl8139_pci_tbl,
+	.probe = rtl8139_probe,
+};
+
+static int rtl8139_init(void)
+{
+	pci_register_driver(&rtl8139_eth_driver);
+
+	add_generic_device("rtl8139_eth", -1, NULL, 0xb0000000, 16,
+		IORESOURCE_MEM, NULL);
+
+	return 0;
+}
+device_initcall(rtl8139_init);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 49e2954..17ac7fd 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -134,3 +134,8 @@
 #define PCI_CLASS_SP_OTHER		0x1180
 
 #define PCI_CLASS_OTHERS		0xff
+
+/* Vendors and devices.  Sort key: vendor first, device next. */
+
+#define PCI_VENDOR_ID_REALTEK		0x10ec
+#define PCI_DEVICE_ID_REALTEK_8139	0x8139
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [RFC V2 6/6] net: add DEC 21143 (tulip) Ethernet controller support
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
                   ` (4 preceding siblings ...)
  2012-03-08 19:50 ` [RFC V2 5/6] net: add Realtek 8139 Ethernet controller support Antony Pavlov
@ 2012-03-08 19:50 ` Antony Pavlov
  2012-03-09 17:56 ` [RFC V2 0/6] barebox PCI support Sascha Hauer
  6 siblings, 0 replies; 10+ messages in thread
From: Antony Pavlov @ 2012-03-08 19:50 UTC (permalink / raw)
  To: barebox

This driver is based on the tulip driver from Linux, and on
the dc driver from *BSD.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 drivers/net/Kconfig     |    8 +
 drivers/pci/21143.c     |  769 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/Makefile    |    1 +
 include/linux/pci_ids.h |    3 +
 4 files changed, 781 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pci/21143.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ff18b5e..7b87501 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -108,6 +108,14 @@ config 8139
 	  This is a driver for the Fast Ethernet PCI network cards based on
 	  the RTL 8139 chips.
 
+config 21143
+	depends on PCI
+	bool "DECchip Tulip (dc21143) PCI Fast Ethernet Adapter support"
+	select MIIDEV
+	help
+	  This is a driver for the Fast Ethernet PCI network cards based on
+	  the DEC 21143 chips.
+
 source "drivers/net/usb/Kconfig"
 
 endmenu
diff --git a/drivers/pci/21143.c b/drivers/pci/21143.c
new file mode 100644
index 0000000..bd2268a
--- /dev/null
+++ b/drivers/pci/21143.c
@@ -0,0 +1,769 @@
+/*
+ * DEC/Intel 21143 (tulip) ethernet driver
+ *
+ * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+
+#include <command.h>
+#include <net.h>
+#include <miidev.h>
+#include <malloc.h>
+#include <init.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+
+#include <linux/pci.h>
+
+#undef DEC21143_DEBUG
+#define DEC21143_DEBUG
+
+#define NUM_RX_DESC 1
+#define NUM_TX_DESC 1
+#define RX_BUFF_SZ  1600
+
+struct tx_desc {
+	u32 status;
+	u32 length;
+	u32 buffer1;
+	u32 buffer2;
+};
+
+struct rx_desc {
+	u32 status;
+	u32 length;
+	u32 buffer1;
+	u32 buffer2;
+};
+
+/* Descriptor bits. */
+#define TULIP_RDES0_OWN   (1 << 31) /* Own Bit: indicates that the descriptor is owned by the 21143 */
+#define RD_RER		0x02000000	/* Receive End Of Ring */
+#define RD_LS		0x00000100	/* Last Descriptor */
+#define RD_ES		0x00008000	/* Error Summary */
+
+#define TULIP_TDES0_OWN   (1 << 31) /* Own Bit: indicates that the descriptor is owned by the 21143 */
+#define TULIP_TDES1_LS    (1 << 30) /* Last Segment */
+#define TULIP_TDES1_FS    (1 << 29) /* First Segment */
+#define TULIP_TDES1_SET   (1 << 27) /* Setup Packet */
+#define TD_TER		0x02000000	/* Transmit End Of Ring */
+#define TD_ES		0x00008000	/* Error Summary */
+
+struct dec21143_priv {
+	void __iomem		*base;
+	struct pci_dev		*pci_dev;
+
+	struct mii_device	miidev;
+
+	struct rx_desc		*rx_ring;
+	struct tx_desc		*tx_ring;
+
+	int			tx_new;
+	int			rx_new;
+};
+
+/* FIXME: write 0 to CSR7 */
+
+#define TULIP_CSR0	0x00 /* Setting Register */
+ #define TULIP_CSR0_SWR		0x01 /* Software Reset */
+ #define TULIP_CSR0_TAP_MASK	(0x03 << 17)
+
+#define TULIP_CSR1	0x08 /* Transmit Poll Demand Register */
+
+#define TULIP_CSR2	0x10 /* Receive Poll Demand Register */
+#define POLL_DEMAND	1
+
+#define TULIP_CSR3	0x18 /* Start of Receive List */
+
+#define TULIP_CSR4	0x20 /* Start of Transmit List */
+
+#define TULIP_CSR5	0x28 /* Status Register */
+ #define TULIP_CSR5_RI	(1 << 6) /* Receive Interrupt */
+ #define TULIP_CSR5_TI	1 /* Transmit Interrupt */
+ #define TULIP_CSR5_TS_MASK	(0x07 << 20)
+ #define TULIP_CSR5_RS_MASK	(0x07 << 17)
+
+#define TULIP_CSR6	0x30 /* Operation Mode Register */
+ #define TULIP_CSR6_TXON	0x2000
+ #define TULIP_CSR6_RXON	0x0002
+
+#define TULIP_CSR7	0x38 /* Interrupt Enable Register */
+
+#define TULIP_CSR8	0x40 /* Unused */
+
+#define TULIP_CSR9	0x48 /* Boot ROM, Serial ROM, and MII Management Register */
+#define TULIP_MDIO_DATA0 0x00000
+#define TULIP_MDIO_DATA1 0x20000
+#define MDIO_ENB		0x00000		/* Ignore the 0x02000 databook setting. */
+#define MDIO_ENB_IN		0x40000
+#define MDIO_DATA_READ	0x80000
+
+ #define TULIP_CSR9_MDI         (1 << 19) /* MDIO Data In */
+ #define TULIP_CSR9_MDOM        (1 << 18) /* MDIO Operation Mode */
+ #define TULIP_CSR9_MDO         (1 << 17) /* MDIO Data Out */
+ #define TULIP_CSR9_MDC         (1 << 16) /* MDIO Clock */
+ #define TULIP_CSR9_RD          (1 << 14)
+ #define TULIP_CSR9_WR          (1 << 13)
+ #define TULIP_CSR9_SR          (1 << 11) /* Serial ROM Select */
+ #define TULIP_CSR9_SRDO        (1 << 3) /* Serial ROM Data Out */
+ #define TULIP_CSR9_SRDI        (1 << 2) /* Serial ROM Data In */
+ #define TULIP_CSR9_SRCK        (1 << 1) /* Serial ROM Clock */
+ #define TULIP_CSR9_SRCS        (1) /* Serial ROM Chip Select */
+
+#define TULIP_CSR10	0x50 /* Unused */
+#define TULIP_CSR11	0x58 /* Unused */
+#define TULIP_CSR12	0x60 /* Unused */
+#define TULIP_CSR13	0x68 /* Unused */
+#define TULIP_CSR14	0x70 /* Unused: SIA Transmit and Receive Register */
+#define TULIP_CSR15	0x78 /* Unused */
+
+/* Register bits. */
+/* CSR5 */
+#define STS_TS		0x00700000	/* Transmit Process State */
+#define STS_RS		0x000e0000	/* Receive Process State */
+
+/* CSR6 */
+#define OMR_PS		0x00040000	/* Port Select */
+#define OMR_SDP		0x02000000	/* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM		0x00000080	/* Pass All Multicast */
+
+#define DC_W32(priv, reg, val)	writel(val, ((char *)(priv->base) + reg))
+#define DC_R32(priv, reg)	readl(((char *)(priv->base) + reg))
+
+/* Read and write the MII registers using software-generated serial
+   MDIO protocol.  It is just different enough from the EEPROM protocol
+   to not share code.  The maxium data clock rate is 2.5 MHz. */
+
+#define mdio_delay() (void)DC_R32(priv, TULIP_CSR9)
+
+static int dec21143_phy_read(struct mii_device *mdev, int phy_addr, int reg)
+{
+	struct eth_device *edev = mdev->edev;
+	struct dec21143_priv *priv = edev->priv;
+	int val;
+
+	int i;
+	int read_cmd = (0xf6 << 10) | (priv->miidev.address << 5) | reg;
+
+	val = 0;
+
+	/* Establish sync by sending at least 32 logic ones. */
+	for (i = 32; i >= 0; i--) {
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | TULIP_MDIO_DATA1);
+		mdio_delay();
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | TULIP_MDIO_DATA1 | TULIP_CSR9_MDC);
+		mdio_delay();
+	}
+
+	/* Shift the read command bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? TULIP_MDIO_DATA1 : TULIP_MDIO_DATA0;
+
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | dataval);
+		mdio_delay();
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | dataval | TULIP_CSR9_MDC);
+		mdio_delay();
+	}
+
+	/* Read the two transition, 16 data, and wire-idle bits. */
+	for (i = 19; i > 0; i--) {
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB_IN);
+		mdio_delay();
+		val = (val << 1) | ((DC_R32(priv, TULIP_CSR9) & MDIO_DATA_READ) ? 1 : 0);
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB_IN | TULIP_CSR9_MDC);
+		mdio_delay();
+	}
+
+	val = (val >> 1) & 0xffff;
+
+//#ifdef DEC21143_DEBUG
+#if 0
+	printf("%s: addr: 0x%02x reg: 0x%02x val: 0x%04x\n", __func__,
+			phy_addr, reg, val);
+#endif
+
+	return val;
+}
+
+static int dec21143_phy_write(struct mii_device *mdev, int phy_addr,
+	int reg, int val)
+{
+	struct eth_device *edev = mdev->edev;
+	struct dec21143_priv *priv = edev->priv;
+
+	int i;
+	int cmd = (0x5002 << 16) | (priv->miidev.address << 23) | (reg << 18) | val;
+
+#ifdef DEC21143_DEBUG
+	printf("%s: addr: 0x%02x reg: 0x%02x val: 0x%04x\n", __func__,
+	      phy_addr, reg, val);
+#endif
+
+	/* Establish sync by sending 32 logic ones. */
+	for (i = 32; i >= 0; i--) {
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | TULIP_MDIO_DATA1);
+		mdio_delay();
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | TULIP_MDIO_DATA1 | TULIP_CSR9_MDC);
+		mdio_delay();
+	}
+
+	/* Shift the command bits out. */
+	for (i = 31; i >= 0; i--) {
+		int dataval = (cmd & (1 << i)) ? TULIP_MDIO_DATA1 : TULIP_MDIO_DATA0;
+
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | dataval);
+		mdio_delay();
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB | dataval | TULIP_CSR9_MDC);
+		mdio_delay();
+	}
+
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB_IN);
+		mdio_delay();
+		DC_W32(priv, TULIP_CSR9, MDIO_ENB_IN | TULIP_CSR9_MDC);
+		mdio_delay();
+	}
+
+	return 0;
+}
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN	6
+#define	TOUT_LOOP	100
+
+/* FIXME */
+#define phys_to_bus(x) (0x0fffffff & (x))
+
+static void dump_rings(struct dec21143_priv *priv)
+{
+	int i;
+
+	printf("dump_rings(): tx_new = %d, rx_new = %d\n", priv->tx_new, priv->rx_new);
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		printf("rx_ring[%d].status  = %08x\n", i, le32_to_cpu(priv->rx_ring[i].status));
+		printf("rx_ring[%d].length  = %08x\n", i, le32_to_cpu(priv->rx_ring[i].length));
+		printf("rx_ring[%d].buffer1 = %08x\n", i, le32_to_cpu(priv->rx_ring[i].buffer1));
+		printf("rx_ring[%d].buffer2 = %08x\n", i, le32_to_cpu(priv->rx_ring[i].buffer2));
+	}
+	printf("\n");
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		printf("tx_ring[%d].status  = %08x\n", i, le32_to_cpu(priv->tx_ring[i].status));
+		printf("tx_ring[%d].length  = %08x\n", i, le32_to_cpu(priv->tx_ring[i].length));
+		printf("tx_ring[%d].buffer1 = %08x\n", i, le32_to_cpu(priv->tx_ring[i].buffer1));
+		printf("tx_ring[%d].buffer2 = %08x\n", i, le32_to_cpu(priv->tx_ring[i].buffer2));
+	}
+	printf("\n");
+	printf("TULIP_CSR0 = 0x%08x\n", DC_R32(priv, TULIP_CSR0));
+	printf("TULIP_CSR1 = 0x%08x\n", DC_R32(priv, TULIP_CSR1));
+	printf("TULIP_CSR2 = 0x%08x\n", DC_R32(priv, TULIP_CSR2));
+	printf("TULIP_CSR3 = 0x%08x\n", DC_R32(priv, TULIP_CSR3));
+	printf("TULIP_CSR4 = 0x%08x\n", DC_R32(priv, TULIP_CSR4));
+{
+	int t;
+	t = DC_R32(priv, TULIP_CSR5);
+	printf("TULIP_CSR5 = 0x%08x ", t);
+	if (t & 1) {
+		printf("<tx int>");
+	}
+	if (t & 2) {
+		printf("<tx stop>");
+	}
+	if (t & 4) {
+		printf("<tx bufun>");
+	}
+	printf("\n");
+}
+	printf("TULIP_CSR6 = 0x%08x\n", DC_R32(priv, TULIP_CSR6));
+
+}
+
+static void dec21143_send_setup_frame(struct eth_device *edev)
+{
+	struct dec21143_priv *priv = edev->priv;
+	int i;
+	char setup_frame[SETUP_FRAME_LEN];
+	char *pa = &setup_frame[15 * 6];
+	char *eaddrs[6];
+
+	/* add the broadcast address. */
+	memset(setup_frame, 0xff, SETUP_FRAME_LEN);
+
+	edev->get_ethaddr(edev, eaddrs);
+
+	/* Fill the final entry of the table with our physical address. */
+	*pa++ = eaddrs[0]; *pa++ = eaddrs[0];
+	*pa++ = eaddrs[1]; *pa++ = eaddrs[1];
+	*pa++ = eaddrs[2]; *pa++ = eaddrs[2];
+
+	dump_rings(priv);
+
+	for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(TULIP_TDES0_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx buffer not ready 0\n", edev->dev.name);
+			goto Done;
+		}
+	}
+
+	priv->tx_ring[priv->tx_new].buffer1 = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
+	priv->tx_ring[priv->tx_new].length = cpu_to_le32(TD_TER | TULIP_TDES1_SET | SETUP_FRAME_LEN);
+	priv->tx_ring[priv->tx_new].status = cpu_to_le32(TULIP_TDES0_OWN);
+
+	DC_W32(priv, TULIP_CSR1, POLL_DEMAND);
+
+	dump_rings(priv);
+	for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(TULIP_TDES0_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx buffer not ready 1\n", edev->dev.name);
+			goto Done;
+		}
+	}
+
+	if (le32_to_cpu(priv->tx_ring[priv->tx_new].status) != 0x7FFFFFFF) {
+		printf("TX error status2 = 0x%08X\n", le32_to_cpu(priv->tx_ring[priv->tx_new].status));
+	}
+
+	priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC;
+
+	printf("============================== done\n");
+Done:
+	return;
+}
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x02	/* EEPROM shift clock. */
+#define EE_CS		0x01	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x04	/* Data from the Tulip to EEPROM. */
+#define EE_WRITE_0	0x01
+#define EE_WRITE_1	0x05
+#define EE_DATA_READ	0x08	/* Data from the EEPROM chip. */
+#define EE_ENB		(0x4800 | EE_CS)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_READ_CMD		(6)
+
+#define eeprom_delay()	(void)DC_R32(priv, TULIP_CSR9)
+
+static int dec21143_read_eeprom(struct dec21143_priv *priv, int addr, u_int16_t *dest)
+{
+	int i;
+	unsigned retval = 0;
+	int addr_len = 6;
+	int read_cmd = addr | (EE_READ_CMD << addr_len);
+
+	DC_W32(priv, TULIP_CSR9, EE_ENB & ~EE_CS);
+	DC_W32(priv, TULIP_CSR9, EE_ENB);
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		DC_W32(priv, TULIP_CSR9, EE_ENB | dataval);
+		eeprom_delay();
+		DC_W32(priv, TULIP_CSR9, EE_ENB | dataval | EE_SHIFT_CLK);
+		eeprom_delay();
+		retval = (retval << 1) | ((DC_R32(priv, TULIP_CSR9) & EE_DATA_READ) ? 1 : 0);
+	}
+	DC_W32(priv, TULIP_CSR9, EE_ENB);
+	eeprom_delay();
+
+	for (i = 16; i > 0; i--) {
+		DC_W32(priv, TULIP_CSR9, EE_ENB | EE_SHIFT_CLK);
+		eeprom_delay();
+		retval = (retval << 1) | ((DC_R32(priv, TULIP_CSR9) & EE_DATA_READ) ? 1 : 0);
+		DC_W32(priv, TULIP_CSR9, EE_ENB);
+		eeprom_delay();
+	}
+
+	/* Terminate the EEPROM access. */
+	DC_W32(priv, TULIP_CSR9, EE_ENB & ~EE_CS);
+
+	*dest = retval;
+
+	//return (tp->flags & HAS_SWAPPED_SEEPROM) ? swab16(retval) : retval;
+	return retval;
+}
+
+static int dec21143_get_ethaddr(struct eth_device *edev, unsigned char *m)
+{
+	struct dec21143_priv *priv = edev->priv;
+	int i;
+
+	for (i = 0; i < 6; i += sizeof(u16)) {
+		u_int16_t val;
+		dec21143_read_eeprom(priv, 10 + i/2, &val);
+		m[i] = val & 0xff;
+		m[i + 1] = val >> 8;
+	}
+
+	return 0;
+}
+
+static int dec21143_set_ethaddr(struct eth_device *edev,
+					unsigned char *mac_addr)
+{
+	struct dec21143_priv *priv = edev->priv;
+
+	return 0;
+}
+
+static int dec21143_init_dev(struct eth_device *edev)
+{
+	struct dec21143_priv *priv = edev->priv;
+	int i;
+
+#ifdef DEC21143_DEBUG
+	printf("%s\n", __func__);
+#endif
+
+	/* RESET_DE4X5(dev); */
+
+	i = DC_R32(priv, TULIP_CSR0);
+	udelay(1000);
+	DC_W32(priv, TULIP_CSR0, i | TULIP_CSR0_SWR);
+	udelay(1000);
+	DC_W32(priv, TULIP_CSR0, i);
+	udelay(1000);
+
+	for (i = 0; i < 5; i++) {
+		(void)DC_R32(priv, TULIP_CSR0);
+		udelay(10000);
+	}
+	udelay(1000);
+
+	if ((DC_R32(priv, TULIP_CSR5) & (STS_TS | STS_RS)) != 0) {
+		printf("Error: Cannot reset ethernet controller.\n");
+		return -1;
+	}
+
+	DC_W32(priv, TULIP_CSR6, OMR_SDP | OMR_PS | OMR_PM | 0x40);
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		priv->rx_ring[i].status = cpu_to_le32(TULIP_RDES0_OWN);
+		priv->rx_ring[i].length = cpu_to_le32(RX_BUFF_SZ);
+		/* FIXME: VERY dirty */
+		priv->rx_ring[i].buffer1 = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+#if 1
+		/* More that one descriptor */
+		priv->rx_ring[i].buffer2 = cpu_to_le32(phys_to_bus((u32) &priv->rx_ring[(i+1) % NUM_RX_DESC]));
+#else
+		priv->rx_ring[i].buffer2 = 0;
+#endif
+	}
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		priv->tx_ring[i].status = 0;
+		priv->tx_ring[i].length = 0;
+		priv->tx_ring[i].buffer1 = 0;
+
+#if 0
+		priv->tx_ring[i].buffer2 = cpu_to_le32(phys_to_bus((u32) &priv->tx_ring[(i+1) % NUM_TX_DESC]));
+#endif
+		priv->tx_ring[i].buffer2 = 0;
+	}
+
+	/* Write the end of list marker to the descriptor lists. */
+	priv->rx_ring[NUM_RX_DESC - 1].length |= cpu_to_le32(RD_RER);
+	priv->tx_ring[NUM_TX_DESC - 1].length |= cpu_to_le32(TD_TER);
+
+//	priv->tx_ring[NUM_TX_DESC - 1].buffer2 = cpu_to_le32(phys_to_bus((u32) &priv->tx_ring[0]));
+
+	/* Tell the adapter where the TX/RX rings are located. */
+	/* FIXME: rx_ring to bus */
+	DC_W32(priv, TULIP_CSR3, phys_to_bus((u32) (priv->rx_ring)));
+	DC_W32(priv, TULIP_CSR4, phys_to_bus((u32) (priv->tx_ring)));
+
+	priv->rx_new = 0;
+	priv->tx_new = 0;
+
+	/* Start the chip's Tx to process setup frame. */
+	DC_W32(priv, TULIP_CSR6, DC_R32(priv, TULIP_CSR6)
+				| TULIP_CSR6_TXON | TULIP_CSR6_RXON);
+
+	dec21143_send_setup_frame(edev);
+
+	//miidev_restart_aneg(&priv->miidev);
+
+	return 0;
+}
+
+static int dec21143_eth_open(struct eth_device *edev)
+{
+	struct dec21143_priv *priv = edev->priv;
+
+	miidev_wait_aneg(&priv->miidev);
+	miidev_print_status(&priv->miidev);
+
+	return 0;
+}
+
+static void dec21143_eth_halt(struct eth_device *edev)
+{
+	struct dec21143_priv *priv = edev->priv;
+
+#ifdef DEC21143_DEBUG
+	printf("%s\n", __func__);
+#endif
+
+	/* Stop the Tx and Rx processes. */
+	DC_W32(priv, TULIP_CSR6, DC_R32(priv, TULIP_CSR6) &
+			~ (TULIP_CSR6_TXON | TULIP_CSR6_RXON));
+}
+
+static int dec21143_eth_send(struct eth_device *edev, void *packet,
+				int packet_length)
+{
+	struct dec21143_priv *priv = edev->priv;
+
+	int status = -1;
+	int i;
+
+#ifdef DEC21143_DEBUG
+//	printf("%s\n", __func__);
+//	memory_display(packet, 0, 70, 1);
+#endif
+
+	if (packet_length <= 0) {
+		printf("%s: bad packet size: %d\n", edev->dev.name, packet_length);
+		goto Done;
+	}
+
+	for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(TULIP_TDES0_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx error buffer not ready\n", edev->dev.name);
+			goto Done;
+		}
+	}
+
+	priv->tx_ring[priv->tx_new].buffer1 = cpu_to_le32(phys_to_bus((u32) packet));
+	priv->tx_ring[priv->tx_new].length = cpu_to_le32(TD_TER | TULIP_TDES1_LS | TULIP_TDES1_FS | packet_length);
+	priv->tx_ring[priv->tx_new].status = cpu_to_le32(TULIP_TDES0_OWN);
+
+	DC_W32(priv, TULIP_CSR1, POLL_DEMAND);
+
+	for(i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(TULIP_TDES0_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+//			printf("%s: tx buffer not ready 2\n", edev->dev.name);
+			goto Done;
+		}
+	}
+
+	if (le32_to_cpu(priv->tx_ring[priv->tx_new].status) & TD_ES) {
+#if 0 /* test-only */
+		printf("TX error status = 0x%08X\n",
+			le32_to_cpu(priv->tx_ring[priv->tx_new].status));
+#endif
+		priv->tx_ring[priv->tx_new].status = 0x0;
+		goto Done;
+	}
+
+	status = packet_length;
+
+Done:
+	priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC;
+
+	return status;
+}
+
+static int dec21143_eth_rx(struct eth_device *edev)
+{
+	struct dec21143_priv *priv = edev->priv;
+
+	s32 status;
+	int length = 0;
+
+#ifdef DEC21143_DEBUG
+	//printf("%s rx_new=%d\n", __func__, priv->rx_new);
+	//dump_rings(priv);
+#endif
+
+	DC_W32(priv, TULIP_CSR2, POLL_DEMAND);
+
+	for ( ; ; ) {
+		status = (s32)le32_to_cpu(priv->rx_ring[priv->rx_new].status);
+
+		if (status & TULIP_RDES0_OWN) {
+			break;
+		}
+
+		if (status & RD_LS) {
+			/* Valid frame status. */
+			if (status & RD_ES) {
+				/* There was an error. */
+				printf("RX error status = 0x%08X\n", status);
+			} else {
+				/* A valid frame received. */
+				length = (le32_to_cpu(priv->rx_ring[priv->rx_new].status) >> 16);
+
+				/* Pass the packet up to the protocol layers. */
+				/* FIXME: VERY dirty */
+				//net_receive(0xa0000000 | cpu_to_le32(priv->rx_ring[priv->rx_new].buffer1), length);
+				/* Skip 4 byte CRC */
+				net_receive(NetRxPackets[priv->rx_new], length - 4);
+			}
+
+			/* Change buffer ownership for this frame, back to the adapter. */
+			priv->rx_ring[priv->rx_new].status = cpu_to_le32(TULIP_RDES0_OWN);
+			DC_W32(priv, TULIP_CSR2, POLL_DEMAND);
+		}
+
+		/* Update entry information. */
+		priv->rx_new = (priv->rx_new + 1) % NUM_RX_DESC;
+
+		break;
+	}
+
+	DC_W32(priv, TULIP_CSR2, POLL_DEMAND);
+
+	return length;
+}
+
+static int dec21143_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct eth_device *edev;
+	struct dec21143_priv *priv;
+
+	u32 bar;
+	struct pci_bus *bus = pdev->bus;
+	struct device_d *dev = &pdev->dev;
+
+#ifdef DEC21143_DEBUG
+	printf("%s\n", __func__);
+#endif
+
+	/* enable pci device */
+	pci_read_config_dword(pdev, PCI_COMMAND, &bar);
+	pci_write_config_dword(pdev, PCI_COMMAND, bar | 0x03);
+
+	edev = xzalloc(sizeof(struct eth_device) +
+			sizeof(struct dec21143_priv));
+	dev->type_data = edev;
+	priv = (struct dec21143_priv *)(edev + 1);
+
+	edev->priv = priv;
+
+	/* FIXME: unused ? */
+	priv->pci_dev = pdev;
+
+	/* FIXME: pci_resource_start() */
+	pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, &bar);
+	priv->base = (void *)bus->ops->res_start(bus, bar);
+
+	printf("found dec21142/3 (rev %02x) at %02x: %04x (base=%p)\n",
+			pdev->revision,
+			pdev->devfn,
+			(pdev->class >> 8) & 0xffff,
+			priv->base);
+
+	edev->init = dec21143_init_dev;
+	edev->open = dec21143_eth_open;
+	edev->send = dec21143_eth_send;
+	edev->recv = dec21143_eth_rx;
+	edev->get_ethaddr = dec21143_get_ethaddr;
+	edev->set_ethaddr = dec21143_set_ethaddr;
+	edev->halt = dec21143_eth_halt;
+
+	priv->miidev.read = dec21143_phy_read;
+	priv->miidev.write = dec21143_phy_write;
+	priv->miidev.address = 0;
+	priv->miidev.flags = 0;
+	priv->miidev.edev = edev;
+
+	/* FIXME: there is no warranty what this memory can be seen from pci */
+	priv->rx_ring = xzalloc(sizeof(struct rx_desc) * NUM_RX_DESC);
+	priv->tx_ring = xzalloc(sizeof(struct tx_desc) * NUM_TX_DESC);
+
+	mii_register(&priv->miidev);
+	eth_register(edev);
+
+	return 0;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(dec21143_pci_tbl) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21142), },
+	{ },
+};
+
+static struct pci_driver dec21143_pci_eth_driver = {
+	.name = "dec21143_pci_eth",
+	.id_table = dec21143_pci_tbl,
+	.probe = dec21143_pci_probe,
+};
+
+static int dec21143_pci_init(void)
+{
+	pci_register_driver(&dec21143_pci_eth_driver);
+
+	return 0;
+}
+device_initcall(dec21143_pci_init);
+
+static int dec21143_eth_probe(struct device_d *dev)
+{
+	struct eth_device *edev;
+	struct dec21143_priv *priv;
+
+	edev = xzalloc(sizeof(struct eth_device) +
+			sizeof(struct dec21143_priv));
+	dev->type_data = edev;
+	priv = (struct dec21143_priv *)(edev + 1);
+
+	priv->base = dev_request_mem_region(dev, 0);
+
+	edev->priv = priv;
+
+	edev->init = dec21143_init_dev;
+	edev->open = dec21143_eth_open;
+	edev->send = dec21143_eth_send;
+	edev->recv = dec21143_eth_rx;
+	edev->get_ethaddr = dec21143_get_ethaddr;
+	edev->set_ethaddr = dec21143_set_ethaddr;
+	edev->halt = dec21143_eth_halt;
+
+	priv->miidev.read = dec21143_phy_read;
+	priv->miidev.write = dec21143_phy_write;
+	priv->miidev.address = 0;
+	priv->miidev.flags = 0;
+	priv->miidev.edev = edev;
+
+	priv->rx_ring = xzalloc(sizeof(struct rx_desc) * NUM_RX_DESC);
+	priv->tx_ring = xzalloc(sizeof(struct tx_desc) * NUM_TX_DESC);
+
+	mii_register(&priv->miidev);
+	eth_register(edev);
+
+	return 0;
+}
+
+static struct driver_d dec21143_eth_driver = {
+	.name = "dec21143_eth",
+	.probe = dec21143_eth_probe,
+};
+
+static int dec21143_eth_init(void)
+{
+	register_driver(&dec21143_eth_driver);
+
+	return 0;
+}
+device_initcall(dec21143_eth_init);
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 6523385..a10f471 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -3,6 +3,7 @@
 #
 obj-y		+= pci.o bus.o
 obj-$(CONFIG_8139)	+= rtl8139.o
+obj-$(CONFIG_21143)	+= 21143.o
 
 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
 
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 17ac7fd..a525653 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -137,5 +137,8 @@
 
 /* Vendors and devices.  Sort key: vendor first, device next. */
 
+#define PCI_VENDOR_ID_DEC		0x1011
+#define PCI_DEVICE_ID_DEC_21142		0x0019
+
 #define PCI_VENDOR_ID_REALTEK		0x10ec
 #define PCI_DEVICE_ID_REALTEK_8139	0x8139
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [RFC V2 0/6] barebox PCI support
  2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
                   ` (5 preceding siblings ...)
  2012-03-08 19:50 ` [RFC V2 6/6] net: add DEC 21143 (tulip) " Antony Pavlov
@ 2012-03-09 17:56 ` Sascha Hauer
  6 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-03-09 17:56 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

Hi Antony,

On Thu, Mar 08, 2012 at 11:50:26PM +0400, Antony Pavlov wrote:
> This patch series introduce PCI support to barebox.
> 
> Thanks to Jean-Christophe PLAGNIOL-VILLARD for reviewing and adding
> some PCI common code.
> 
> The patches are draft. They need a very big future work, so I put on them "RFC"
> title instead of "PATCH".

Overall this looks quite nice now. I think we are getting in the region
of 'merging in the near future'. There are some fixme markers aka C++
comments which should simply be removed like non present irq includes.
With others I don't understand if they have something to do with your
hardware or with porting PCI in general to barebox. I don't know much
about PCI, so only some comments inline where better barebox integration
is needed.

Thanks for working on this.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [RFC V2 1/6] PCI: initial commit (draft)
  2012-03-08 19:50 ` [RFC V2 1/6] PCI: initial commit (draft) Antony Pavlov
@ 2012-03-09 18:01   ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-03-09 18:01 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

On Thu, Mar 08, 2012 at 11:50:27PM +0400, Antony Pavlov wrote:
> used shorten version of linux-2.6.39 pci_ids.h
> 
> +
> +static int pci_init(void)
> +{
> +	pcibios_init();
> +
> +	if (!pci_present()) {
> +		printf("PCI: No PCI bus detected\n");
> +		return 0;
> +	}
> +
> +	/* give BIOS a chance to apply platform specific fixes: */
> +	//pcibios_fixup();
> +
> +	return 0;
> +}
> +postcore_initcall(pci_init);

Here the logic is the wrong way round. The initcall should be in your
architecture code which then calls register_pci_controller().

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [RFC V2 5/6] net: add Realtek 8139 Ethernet controller support
  2012-03-08 19:50 ` [RFC V2 5/6] net: add Realtek 8139 Ethernet controller support Antony Pavlov
@ 2012-03-09 18:17   ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-03-09 18:17 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

On Thu, Mar 08, 2012 at 11:50:31PM +0400, Antony Pavlov wrote:
> This driver is based on Linux 2.6.39 8139too driver.
> 
> +
> +static void rtl8139_chip_reset(struct rtl8139_priv *priv)
> +{
> +	int i;
> +
> +#ifdef RTL8139_DEBUG
> +	printf("rtl8139_chip_reset()\n");
> +#endif

Please use dev_dbg()

> +
> +	/* Soft reset the chip. */
> +	RTL_W8(priv, ChipCmd, CmdReset);
> +
> +	/* Check that the chip has finished the reset. */
> +	for (i = 1000; i > 0; i--) {
> +		//barrier();
> +		if ((RTL_R8(priv, ChipCmd) & CmdReset) == 0)
> +			break;
> +		udelay(10);
> +	}

while (!is_timeout(start, 10 * MSECOND)

> +static struct pci_driver rtl8139_eth_driver = {
> +	.name = "rtl8139_eth",
> +	.id_table = rtl8139_pci_tbl,
> +	.probe = rtl8139_probe,
> +};
> +
> +static int rtl8139_init(void)
> +{
> +	pci_register_driver(&rtl8139_eth_driver);
> +
> +	add_generic_device("rtl8139_eth", -1, NULL, 0xb0000000, 16,
> +		IORESOURCE_MEM, NULL);

This makes me wonder. I assumed the PCI core would register the device.
Or is this just a leftover from an earlier version?

SAscha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2012-03-09 18:17 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-08 19:50 [RFC V2 0/6] barebox PCI support Antony Pavlov
2012-03-08 19:50 ` [RFC V2 1/6] PCI: initial commit (draft) Antony Pavlov
2012-03-09 18:01   ` Sascha Hauer
2012-03-08 19:50 ` [RFC V2 2/6] MIPS: add file gt64120.h from linux 2.6.39 Antony Pavlov
2012-03-08 19:50 ` [RFC V2 3/6] MIPS: add PCI support for GT64120-based malta Antony Pavlov
2012-03-08 19:50 ` [RFC V2 4/6] PCI: add draft lspci command Antony Pavlov
2012-03-08 19:50 ` [RFC V2 5/6] net: add Realtek 8139 Ethernet controller support Antony Pavlov
2012-03-09 18:17   ` Sascha Hauer
2012-03-08 19:50 ` [RFC V2 6/6] net: add DEC 21143 (tulip) " Antony Pavlov
2012-03-09 17:56 ` [RFC V2 0/6] barebox PCI support Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox