Skip to contentSkip to conversation

PCI and Tegra series revamp

PATCH Applied Lucas Stach 2 participants 21 messages Oct 4, 2014 – Oct 8, 2014

Subsystems (11)
lore
Share & tools
lore
#0 lore raw

v2 cover PCI and Tegra series revamp

Ok, I got around to work a bit more on this. I now actually finished the rtl8169 network driver, so this series yields working PCI attached ethernet on Tegra30 Beaver.

For Jetson K1 some work is left to setup the PHYs, but that shouldn't be far out.

While working on this I stumbled upon a few more issues, so I decided to just roll the fixes into this series and resend.

Lucas Stach (19):
MIPS: malta: fix pci IO resource assignment
pci: split out device init
pci: add resource enum
pci: properly populate prefetchable BARs
pci: setup bridges and traverse buses behind them
pci: defer device registration until after bridge setup
pci: prettyprint device names
pci: track parent<->child relationship
commands: lspci: go down into subordinate busses
clk: tegra: add PLLE setup functions
clk: tegra30: add PCIe clocks
i2c: tegra: move to fs initcall
ARM: tegra: beaver: enable PEX voltage rail
tegra: pmc: add powerdomain handling
of: import pci range parser from linux
pci: add Tegra host controller driver
ARM: tegra: advertise PCI support
net: add rtl8169 driver
ARM: tegra: enable network related options in defconfig

 arch/arm/Kconfig                                   |    1 +
 arch/arm/boards/nvidia-beaver/board.c              |   13 +-
 arch/arm/configs/tegra_v7_defconfig                |    8 +
 arch/arm/mach-tegra/include/mach/tegra-powergate.h |   93 ++
 arch/arm/mach-tegra/include/mach/tegra20-car.h     |    2 +
 arch/arm/mach-tegra/include/mach/tegra30-car.h     |    2 +
 arch/arm/mach-tegra/tegra20-pmc.c                  |  139 ++-
 arch/mips/mach-malta/pci.c                         |    4 +-
 commands/lspci.c                                   |   25 +-
 drivers/clk/tegra/clk-pll.c                        |  116 ++
 drivers/clk/tegra/clk-tegra30.c                    |   31 +
 drivers/clk/tegra/clk.h                            |    6 +
 drivers/i2c/busses/i2c-tegra.c                     |    2 +-
 drivers/net/Kconfig                                |    8 +
 drivers/net/Makefile                               |    1 +
 drivers/net/rtl8169.c                              |  566 ++++++++++
 drivers/of/Kconfig                                 |    1 +
 drivers/of/address.c                               |   68 ++
 drivers/pci/Kconfig                                |    7 +
 drivers/pci/Makefile                               |    1 +
 drivers/pci/bus.c                                  |    3 +-
 drivers/pci/pci-tegra.c                            | 1193 ++++++++++++++++++++
 drivers/pci/pci.c                                  |  276 +++--
 include/linux/pci.h                                |    9 +
 include/linux/pci_regs.h                           |   28 +
 include/of_address.h                               |   57 +
 26 files changed, 2573 insertions(+), 87 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/tegra-powergate.h
 create mode 100644 drivers/net/rtl8169.c
 create mode 100644 drivers/pci/pci-tegra.c
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#1 lore raw

PATCH v2 1/19 MIPS: malta: fix pci IO resource assignment

Does the same thing as the Linux kernel now.

---
I tested this with qemu-malta and at least barebox is now again able to enumerate all 4 PCI devices.

---
 arch/mips/mach-malta/pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/mach-malta/pci.c +2 -2
index 9035175..47c0e22 100644
@@ -151,7 +151,7 @@ static struct pci_controller gt64120_controller = {
 
 static int pcibios_init(void)
 {
-	resource_size_t start, end, map, start1, end1, map1, mask, res_end;
+	resource_size_t start, end, map, start1, end1, map1, mask;
 
 	/*
 	 * Due to a bug in the Galileo system controller, we need
@@ -207,7 +207,7 @@ static int pcibios_init(void)
 	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_io_resource.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;
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#2 lore raw

PATCH v2 2/19 pci: split out device init

In reply to Lucas Stach

To make it reusable and the code more readable.

---
 drivers/pci/pci.c | 137 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 74 insertions(+), 63 deletions(-)
drivers/pci/pci.c +74 -63
index a1b7680..ef998dc 100644
@@ -12,6 +12,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head;
 LIST_HEAD(pci_root_buses);
 EXPORT_SYMBOL(pci_root_buses);
 static u8 bus_index;
+static resource_size_t last_mem;
+static resource_size_t last_io;
 
 static struct pci_bus *pci_alloc_bus(void)
 {
@@ -45,6 +47,10 @@ void register_pci_controller(struct pci_controller *hose)
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
+
+	last_mem = bus->resource[0]->start;
+	last_io = bus->resource[1]->start;
+
 	pci_scan_bus(bus);
 
 	list_add_tail(&bus->node, &pci_root_buses);
@@ -111,27 +117,80 @@ static struct pci_dev *alloc_pci_dev(void)
 	return dev;
 }
 
+static void setup_device(struct pci_dev *dev, int max_bar)
+{
+	int bar, size;
+	u32 mask;
+	u8 cmd;
+
+	pci_read_config_byte(dev, PCI_COMMAND, &cmd);
+	pci_write_config_byte(dev, PCI_COMMAND,
+			      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
+	for (bar = 0; bar < max_bar; bar++) {
+		resource_size_t last_addr;
+
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
+		pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
+
+		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);
+			if (last_mem + size > dev->bus->resource[0]->end) {
+				DBG("BAR does not fit within bus IO res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
+			dev->resource[bar].flags = IORESOURCE_IO;
+			last_addr = last_io;
+			last_io += size;
+		} else { /* MEM */
+			size = -(mask & 0xfffffff0);
+			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
+			if (last_mem + size > dev->bus->resource[0]->end) {
+				DBG("BAR does not fit within bus mem res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
+			dev->resource[bar].flags = IORESOURCE_MEM;
+			last_addr = last_mem;
+			last_mem += size;
+
+			if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			    PCI_BASE_ADDRESS_MEM_TYPE_64) {
+				dev->resource[bar].flags |= IORESOURCE_MEM_64;
+				pci_write_config_dword(dev,
+				       PCI_BASE_ADDRESS_1 + bar * 4, 0);
+			}
+		}
+
+		dev->resource[bar].start = last_addr;
+		dev->resource[bar].end = last_addr + size - 1;
+		if (dev->resource[bar].flags & IORESOURCE_MEM_64)
+			bar++;
+	}
+
+	pci_write_config_byte(dev, PCI_COMMAND, cmd);
+	list_add_tail(&dev->bus_list, &dev->bus->devices);
+	pci_register_device(dev);
+}
+
 unsigned int pci_scan_bus(struct pci_bus *bus)
 {
+	struct pci_dev *dev;
 	unsigned int devfn, l, max, class;
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
-	struct pci_dev *dev;
-	resource_size_t last_mem;
-	resource_size_t last_io;
-
-	/* FIXME: use res_start() */
-	last_mem = bus->resource[0]->start;
-	last_io = bus->resource[1]->start;
 
 	DBG("pci_scan_bus for bus %d\n", bus->number);
 	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
 	max = bus->secondary;
 
 	for (devfn = 0; devfn < 0xff; ++devfn) {
-		int bar;
-		u32 old_bar, mask;
-		int size;
-
 		if (PCI_FUNC(devfn) && !is_multi) {
 			/* not a multi-function device */
 			continue;
@@ -169,6 +228,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		dev->hdr_type = hdr_type;
 
 		DBG("PCI: class = %08x, hdr_type = %08x\n", class, hdr_type);
+		DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
+		    dev->vendor, dev->device);
 
 		switch (hdr_type & 0x7f) {		    /* header type */
 		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
@@ -181,6 +242,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			 */
 			pci_read_config_dword(dev, PCI_ROM_ADDRESS, &l);
 			dev->rom_address = (l == 0xffffffff) ? 0 : l;
+
+			setup_device(dev, 6);
 			break;
 		default:				    /* unknown header */
 		bad:
@@ -189,62 +252,10 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			continue;
 		}
 
-		DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
-
 		if (class == PCI_CLASS_BRIDGE_HOST) {
 			DBG("PCI: skip pci host bridge\n");
 			continue;
 		}
-
-		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
-		pci_write_config_byte(dev, PCI_COMMAND,
-				      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-
-		for (bar = 0; bar < 6; bar++) {
-			resource_size_t last_addr;
-
-			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);
-				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
-				dev->resource[bar].flags = IORESOURCE_IO;
-				last_addr = last_io;
-				last_io += size;
-			} else { /* MEM */
-				size = -(mask & 0xfffffff0);
-				DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
-				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
-				dev->resource[bar].flags = IORESOURCE_MEM;
-				last_addr = last_mem;
-				last_mem += size;
-
-				if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-				    PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					dev->resource[bar].flags |= IORESOURCE_MEM_64;
-					pci_write_config_dword(dev,
-					       PCI_BASE_ADDRESS_1 + bar * 4, 0);
-				}
-			}
-
-			dev->resource[bar].start = last_addr;
-			dev->resource[bar].end = last_addr + size - 1;
-			if (dev->resource[bar].flags & IORESOURCE_MEM_64)
-				bar++;
-		}
-
-		pci_write_config_byte(dev, PCI_COMMAND, cmd);
-		list_add_tail(&dev->bus_list, &bus->devices);
-		pci_register_device(dev);
 	}
 
 	/*
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#3 lore raw

PATCH v2 3/19 pci: add resource enum

In reply to Lucas Stach

Makes things way clearer than juggling numbers.

---
 drivers/pci/pci.c   | 14 ++++++++------
 include/linux/pci.h |  6 ++++++
 2 files changed, 14 insertions(+), 6 deletions(-)
drivers/pci/pci.c +8 -6
index ef998dc..e9f0cb5 100644
@@ -41,15 +41,15 @@ void register_pci_controller(struct pci_controller *hose)
 	hose->bus = bus;
 	bus->host = hose;
 	bus->ops = hose->pci_ops;
-	bus->resource[0] = hose->mem_resource;
-	bus->resource[1] = hose->io_resource;
+	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
+	bus->resource[PCI_BUS_RESOURCE_IO] = hose->io_resource;
 	bus->number = bus_index++;
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
 
-	last_mem = bus->resource[0]->start;
-	last_io = bus->resource[1]->start;
+	last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
+	last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
 
 	pci_scan_bus(bus);
 
@@ -141,7 +141,8 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 		if (mask & 0x01) { /* IO */
 			size = -(mask & 0xfffffffe);
 			DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
-			if (last_mem + size > dev->bus->resource[0]->end) {
+			if (last_io + size >
+			    dev->bus->resource[PCI_BUS_RESOURCE_IO]->end) {
 				DBG("BAR does not fit within bus IO res\n");
 				return;
 			}
@@ -152,7 +153,8 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 		} else { /* MEM */
 			size = -(mask & 0xfffffff0);
 			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
-			if (last_mem + size > dev->bus->resource[0]->end) {
+			if (last_mem + size >
+			    dev->bus->resource[PCI_BUS_RESOURCE_MEM]->end) {
 				DBG("BAR does not fit within bus mem res\n");
 				return;
 			}
include/linux/pci.h +6 -0
index 0ec1320..f5ef588 100644
@@ -114,6 +114,12 @@ struct pci_dev {
 };
 #define	to_pci_dev(dev) container_of(dev, struct pci_dev, dev)
 
+enum {
+	PCI_BUS_RESOURCE_IO = 0,
+	PCI_BUS_RESOURCE_MEM = 1,
+	PCI_BUS_RESOURCE_MEM_PREF = 2,
+	PCI_BUS_RESOURCE_BUSN = 3,
+};
 struct pci_bus {
 	struct pci_controller *host;	/* associated host controller */
 	struct list_head node;		/* node in list of buses */
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#4 lore raw

PATCH v2 4/19 pci: properly populate prefetchable BARs

In reply to Lucas Stach

Some host controllers provide a prefetchable
memory area and devices will prefer this for
some of their BARs.

---
 drivers/pci/pci.c   | 59 ++++++++++++++++++++++++++++++++++++++++-------------
 include/linux/pci.h |  1 +
 2 files changed, 46 insertions(+), 14 deletions(-)
drivers/pci/pci.c +45 -14
index e9f0cb5..115d8a3 100644
@@ -13,6 +13,7 @@ LIST_HEAD(pci_root_buses);
 EXPORT_SYMBOL(pci_root_buses);
 static u8 bus_index;
 static resource_size_t last_mem;
+static resource_size_t last_mem_pref;
 static resource_size_t last_io;
 
 static struct pci_bus *pci_alloc_bus(void)
@@ -42,14 +43,27 @@ void register_pci_controller(struct pci_controller *hose)
 	bus->host = hose;
 	bus->ops = hose->pci_ops;
 	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
+	bus->resource[PCI_BUS_RESOURCE_MEM_PREF] = hose->mem_pref_resource;
 	bus->resource[PCI_BUS_RESOURCE_IO] = hose->io_resource;
 	bus->number = bus_index++;
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
 
-	last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
-	last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
+	if (bus->resource[PCI_BUS_RESOURCE_MEM])
+		last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
+	else
+		last_mem = 0;
+
+	if (bus->resource[PCI_BUS_RESOURCE_MEM])
+		last_mem_pref = bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->start;
+	else
+		last_mem_pref = 0;
+
+	if (bus->resource[PCI_BUS_RESOURCE_IO])
+		last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
+	else
+		last_io = 0;
 
 	pci_scan_bus(bus);
 
@@ -150,31 +164,46 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 			dev->resource[bar].flags = IORESOURCE_IO;
 			last_addr = last_io;
 			last_io += size;
-		} else { /* MEM */
+		} else if ((mask & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
+		           last_mem_pref) /* prefetchable MEM */ {
 			size = -(mask & 0xfffffff0);
-			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
+			DBG("  PCI: pbar%d: mask=%08x P memory %d bytes\n",
+			    bar, mask, size);
+			if (last_mem_pref + size >
+			    dev->bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->end) {
+				DBG("BAR does not fit within bus p-mem res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem_pref);
+			dev->resource[bar].flags = IORESOURCE_MEM |
+			                           IORESOURCE_PREFETCH;
+			last_addr = last_mem_pref;
+			last_mem_pref += size;
+		} else { /* non-prefetch MEM */
+			size = -(mask & 0xfffffff0);
+			DBG("  PCI: pbar%d: mask=%08x NP memory %d bytes\n",
+			    bar, mask, size);
 			if (last_mem + size >
 			    dev->bus->resource[PCI_BUS_RESOURCE_MEM]->end) {
-				DBG("BAR does not fit within bus mem res\n");
+				DBG("BAR does not fit within bus np-mem res\n");
 				return;
 			}
 			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
 			dev->resource[bar].flags = IORESOURCE_MEM;
 			last_addr = last_mem;
 			last_mem += size;
-
-			if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-			    PCI_BASE_ADDRESS_MEM_TYPE_64) {
-				dev->resource[bar].flags |= IORESOURCE_MEM_64;
-				pci_write_config_dword(dev,
-				       PCI_BASE_ADDRESS_1 + bar * 4, 0);
-			}
 		}
 
 		dev->resource[bar].start = last_addr;
 		dev->resource[bar].end = last_addr + size - 1;
-		if (dev->resource[bar].flags & IORESOURCE_MEM_64)
+
+		if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+		    PCI_BASE_ADDRESS_MEM_TYPE_64) {
+			dev->resource[bar].flags |= IORESOURCE_MEM_64;
+			pci_write_config_dword(dev,
+			       PCI_BASE_ADDRESS_1 + bar * 4, 0);
 			bar++;
+		}
 	}
 
 	pci_write_config_byte(dev, PCI_COMMAND, cmd);
@@ -189,7 +218,9 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
 
 	DBG("pci_scan_bus for bus %d\n", bus->number);
-	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
+	DBG(" last_io = 0x%08x, last_mem = 0x%08x, last_mem_pref = 0x%08x\n",
+	    last_io, last_mem, last_mem_pref);
+
 	max = bus->secondary;
 
 	for (devfn = 0; devfn < 0xff; ++devfn) {
include/linux/pci.h +1 -0
index f5ef588..932acf0 100644
@@ -162,6 +162,7 @@ struct pci_controller {
 
 	struct pci_ops *pci_ops;
 	struct resource *mem_resource;
+	struct resource *mem_pref_resource;
 	unsigned long mem_offset;
 	struct resource *io_resource;
 	unsigned long io_offset;
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#5 lore raw

PATCH v2 5/19 pci: setup bridges and traverse buses behind them

In reply to Lucas Stach
---
 drivers/pci/pci.c        | 92 ++++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/pci_regs.h | 28 +++++++++++++++
 2 files changed, 117 insertions(+), 3 deletions(-)
drivers/pci/pci.c +89 -3
index 115d8a3..59f942d 100644
@@ -211,9 +211,73 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 	pci_register_device(dev);
 }
 
+static void prescan_setup_bridge(struct pci_dev *dev)
+{
+	u16 cmdstat;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmdstat);
+
+	/* Configure bus number registers */
+	pci_write_config_byte(dev, PCI_PRIMARY_BUS, dev->bus->number);
+	pci_write_config_byte(dev, PCI_SECONDARY_BUS, dev->subordinate->number);
+	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, 0xff);
+
+	if (last_mem) {
+		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+		pci_write_config_word(dev, PCI_MEMORY_BASE,
+				      (last_mem & 0xfff00000) >> 16);
+		cmdstat |= PCI_COMMAND_MEMORY;
+	}
+
+	if (last_mem_pref) {
+		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+		pci_write_config_word(dev, PCI_PREF_MEMORY_BASE,
+				      (last_mem_pref & 0xfff00000) >> 16);
+		cmdstat |= PCI_COMMAND_MEMORY;
+	} else {
+
+		/* We don't support prefetchable memory for now, so disable */
+		pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x1000);
+		pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0x0);
+	}
+
+	if (last_io) {
+		pci_write_config_byte(dev, PCI_IO_BASE,
+				      (last_io & 0x0000f000) >> 8);
+		pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+				      (last_io & 0xffff0000) >> 16);
+		cmdstat |= PCI_COMMAND_IO;
+	}
+
+	/* Enable memory and I/O accesses, enable bus master */
+	pci_write_config_word(dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
+}
+
+static void postscan_setup_bridge(struct pci_dev *dev)
+{
+	/* limit subordinate to last used bus number */
+	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, bus_index - 1);
+
+	if (last_mem)
+		pci_write_config_word(dev, PCI_MEMORY_LIMIT,
+				      ((last_mem - 1) & 0xfff00000) >> 16);
+
+	if (last_mem_pref)
+		pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT,
+				      ((last_mem_pref - 1) & 0xfff00000) >> 16);
+
+	if (last_io) {
+		pci_write_config_byte(dev, PCI_IO_LIMIT,
+				((last_io - 1) & 0x0000f000) >> 8);
+		pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+				((last_io - 1) & 0xffff0000) >> 16);
+	}
+}
+
 unsigned int pci_scan_bus(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
+	struct pci_bus *child_bus;
 	unsigned int devfn, l, max, class;
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
 
@@ -264,8 +328,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
 		    dev->vendor, dev->device);
 
-		switch (hdr_type & 0x7f) {		    /* header type */
-		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
+		switch (hdr_type & 0x7f) {
+		case PCI_HEADER_TYPE_NORMAL:
 			if (class == PCI_CLASS_BRIDGE_PCI)
 				goto bad;
 
@@ -278,7 +342,28 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 
 			setup_device(dev, 6);
 			break;
-		default:				    /* unknown header */
+		case PCI_HEADER_TYPE_BRIDGE:
+			setup_device(dev, 2);
+
+			child_bus = pci_alloc_bus();
+			/* inherit parent properties */
+			child_bus->host = bus->host;
+			child_bus->ops = bus->host->pci_ops;
+			child_bus->resource[PCI_BUS_RESOURCE_MEM] =
+				bus->resource[PCI_BUS_RESOURCE_MEM];
+			child_bus->resource[PCI_BUS_RESOURCE_MEM_PREF] =
+				bus->resource[PCI_BUS_RESOURCE_MEM_PREF];
+			child_bus->resource[PCI_BUS_RESOURCE_IO] =
+				bus->resource[PCI_BUS_RESOURCE_IO];
+			child_bus->number = bus_index++;
+			list_add_tail(&child_bus->node, &bus->children);
+			dev->subordinate = child_bus;
+
+			prescan_setup_bridge(dev);
+			pci_scan_bus(child_bus);
+			postscan_setup_bridge(dev);
+			break;
+		default:
 		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);
@@ -298,6 +383,7 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 	 *
 	 * Return how far we've got finding sub-buses.
 	 */
+	max = bus_index;
 	DBG("PCI: pci_scan_bus returning with max=%02x\n", max);
 
 	return max;
include/linux/pci_regs.h +28 -0
index 14a3ed3..8669fc7 100644
@@ -107,4 +107,32 @@
 #define  PCI_ROM_ADDRESS_ENABLE	0x01
 #define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
 
+/* 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) /* Standard 4K I/O windows */
+#define  PCI_IO_1K_RANGE_MASK	(~0x03UL) /* Intel 1K I/O windows */
+#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
+
 #endif /* LINUX_PCI_REGS_H */
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#6 lore raw

PATCH v2 6/19 pci: defer device registration until after bridge setup

In reply to Lucas Stach

Otherwise the drivers for a device may probe before the devices parent bridge is fully configured, which leads to errors when accessing the BARs.

---
 drivers/pci/pci.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/pci/pci.c +5 -1
index 59f942d..943d0e8 100644
@@ -208,7 +208,6 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 
 	pci_write_config_byte(dev, PCI_COMMAND, cmd);
 	list_add_tail(&dev->bus_list, &dev->bus->devices);
-	pci_register_device(dev);
 }
 
 static void prescan_setup_bridge(struct pci_dev *dev)
@@ -362,6 +361,11 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			prescan_setup_bridge(dev);
 			pci_scan_bus(child_bus);
 			postscan_setup_bridge(dev);
+			/* first activate bridge then all devices on it's bus */
+			pci_register_device(dev);
+			list_for_each_entry(dev, &child_bus->devices, bus_list)
+				if (!dev->subordinate)
+					pci_register_device(dev);
 			break;
 		default:
 		bad:
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#7 lore raw

PATCH v2 7/19 pci: prettyprint device names

In reply to Lucas Stach
---
 drivers/pci/bus.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pci/bus.c +2 -1
index 8215ee5..866ab08 100644
@@ -86,7 +86,8 @@ int pci_register_device(struct pci_dev *pdev)
 	struct device_d *dev = &pdev->dev;
 	int ret;
 
-	strcpy(dev->name, "pci");
+	snprintf(dev->name, MAX_DRIVER_NAME, "pci-%04x:%04x.",
+	         pdev->vendor, pdev->device);
 	dev->bus = &pci_bus;
 	dev->id = DEVICE_ID_DYNAMIC;
 
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#8 lore raw

PATCH v2 8/19 pci: track parent<->child relationship

In reply to Lucas Stach

So that PCI devices hang down from bridges and root bridges down from the PCI host controller when calling devinfo.

---
 drivers/pci/pci.c   | 4 ++++
 include/linux/pci.h | 2 ++
 2 files changed, 6 insertions(+)
drivers/pci/pci.c +4 -0
index 943d0e8..ba9d097 100644
@@ -40,6 +40,7 @@ void register_pci_controller(struct pci_controller *hose)
 
 	bus = pci_alloc_bus();
 	hose->bus = bus;
+	bus->parent = hose->parent;
 	bus->host = hose;
 	bus->ops = hose->pci_ops;
 	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
@@ -309,6 +310,7 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		dev->devfn = devfn;
 		dev->vendor = l & 0xffff;
 		dev->device = (l >> 16) & 0xffff;
+		dev->dev.parent = bus->parent;
 
 		/* non-destructively determine if device can be a master: */
 		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
@@ -354,6 +356,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 				bus->resource[PCI_BUS_RESOURCE_MEM_PREF];
 			child_bus->resource[PCI_BUS_RESOURCE_IO] =
 				bus->resource[PCI_BUS_RESOURCE_IO];
+
+			child_bus->parent = &dev->dev;
 			child_bus->number = bus_index++;
 			list_add_tail(&child_bus->node, &bus->children);
 			dev->subordinate = child_bus;
include/linux/pci.h +2 -0
index 932acf0..3d0e73b 100644
@@ -122,6 +122,7 @@ enum {
 };
 struct pci_bus {
 	struct pci_controller *host;	/* associated host controller */
+	struct device_d *parent;
 	struct list_head node;		/* node in list of buses */
 	struct list_head children;	/* list of child buses */
 	struct list_head devices;	/* list of devices on this bus */
@@ -158,6 +159,7 @@ extern struct pci_ops *pci_ops;
  */
 struct pci_controller {
 	struct pci_controller *next;
+	struct device_d *parent;
 	struct pci_bus *bus;
 
 	struct pci_ops *pci_ops;
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#9 lore raw

PATCH v2 9/19 commands: lspci: go down into subordinate busses

In reply to Lucas Stach

This way we also list devices that are behind
bridges.

---
 commands/lspci.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
commands/lspci.c +16 -9
index fdf0269..27edd5d 100644
@@ -20,10 +20,24 @@
 #include <complete.h>
 #include <linux/pci.h>
 
+static void traverse_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		printf("%02x:%02x.%1x %04x: %04x:%04x (rev %02x)\n",
+		       dev->bus->number, PCI_SLOT(dev->devfn),
+		       PCI_FUNC(dev->devfn), (dev->class >> 8) & 0xffff,
+		       dev->vendor, dev->device, dev->revision);
+
+		if (dev->subordinate)
+			traverse_bus(dev->subordinate);
+	}
+}
+
 static int do_lspci(int argc, char *argv[])
 {
 	struct pci_bus *root_bus;
-	struct pci_dev *dev;
 
 	if (list_empty(&pci_root_buses)) {
 		printf("No PCI bus detected\n");
@@ -31,14 +45,7 @@ static int do_lspci(int argc, char *argv[])
 	}
 
 	list_for_each_entry(root_bus, &pci_root_buses, node) {
-		list_for_each_entry(dev, &root_bus->devices, bus_list) {
-			printf("%02x: %04x: %04x:%04x (rev %02x)\n",
-				      dev->devfn,
-				      (dev->class >> 8) & 0xffff,
-				      dev->vendor,
-				      dev->device,
-				      dev->revision);
-		}
+		traverse_bus(root_bus);
 	}
 
 	return 0;
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#10 lore raw

PATCH v2 10/19 clk: tegra: add PLLE setup functions

In reply to Lucas Stach

From: Lucas Stach <[email protected]>

---
 arch/arm/mach-tegra/include/mach/tegra30-car.h |   2 +
 drivers/clk/tegra/clk-pll.c                    | 116 +++++++++++++++++++++++++
 drivers/clk/tegra/clk.h                        |   6 ++
 3 files changed, 124 insertions(+)
arch/arm/mach-tegra/include/mach/tegra30-car.h +2 -0
index c8f6c9f..7fb2238 100644
@@ -33,3 +33,5 @@
 #define CRC_RST_DEV_V_CLR		0x434
 
 #define CRC_CLK_OUT_ENB_V_SET		0x440
+
+#define CRC_PLLE_AUX			0x48c
drivers/clk/tegra/clk-pll.c +116 -0

137 lines not on this page · raw message

drivers/clk/tegra/clk.h +6 -0
index d5d0730..85777a8 100644
@@ -101,6 +101,12 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
 		struct tegra_clk_pll_params *pll_params, u8 pll_flags,
 		struct tegra_clk_pll_freq_table *freq_table);
 
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+		void __iomem *clk_base,
+		unsigned long flags, unsigned long fixed_rate,
+		struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+		struct tegra_clk_pll_freq_table *freq_table);
+
 /* struct tegra_clk_pll_out - PLL output divider */
 struct tegra_clk_pll_out {
 	struct clk	hw;
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#11 lore raw

PATCH v2 11/19 clk: tegra30: add PCIe clocks

In reply to Lucas Stach

From: Lucas Stach <[email protected]>

---
 arch/arm/mach-tegra/include/mach/tegra20-car.h |  2 ++
 drivers/clk/tegra/clk-tegra30.c                | 31 ++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)
arch/arm/mach-tegra/include/mach/tegra20-car.h +2 -0
index 161e3d8..5a35f21 100644
@@ -49,6 +49,8 @@
 #define CRC_CLK_OUT_ENB_H		0x014
 #define CRC_CLK_OUT_ENB_H_DVC		(1 << 15)
 
+#define CRC_CLK_OUT_ENB_U		0x018
+
 #define CRC_CCLK_BURST_POLICY		0x020
 #define CRC_CCLK_BURST_POLICY_SYS_STATE_SHIFT	28
 #define CRC_CCLK_BURST_POLICY_SYS_STATE_FIQ	8
drivers/clk/tegra/clk-tegra30.c +31 -0
index ed6d736..9997ab9 100644
@@ -130,6 +130,13 @@ static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
 	{ 0, 0, 0, 0, 0, 0 },
 };
 
+static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
+	/* PLLE special case: use cpcon field to store cml divider value */
+	{ 12000000,  100000000, 150, 1,  18, 11},
+	{ 216000000, 100000000, 200, 18, 24, 13},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
 /* PLL parameters */
 static struct tegra_clk_pll_params pll_c_params = {
 	.input_min = 2000000,
@@ -201,6 +208,19 @@ static struct tegra_clk_pll_params pll_u_params = {
 	.lock_delay = 1000,
 };
 
+static struct tegra_clk_pll_params pll_e_params = {
+	.input_min = 12000000,
+	.input_max = 216000000,
+	.cf_min = 12000000,
+	.cf_max = 12000000,
+	.vco_min = 1200000000,
+	.vco_max = 2400000000U,
+	.base_reg = CRC_PLLE_BASE,
+	.misc_reg = CRC_PLLE_MISC,
+	.lock_enable_bit_idx = CRC_PLLE_MISC_LOCK_ENABLE,
+	.lock_delay = 300,
+};
+
 static void tegra30_pll_init(void)
 {
 	/* PLLC */
@@ -251,6 +271,11 @@ static void tegra30_pll_init(void)
 	clks[TEGRA30_CLK_PLL_U] = tegra_clk_register_pll("pll_u", "pll_ref",
 			car_base, 0, 0, &pll_u_params, TEGRA_PLLU |
 			TEGRA_PLL_HAS_CPCON, pll_u_freq_table);
+
+	/* PLLE */
+	clks[TEGRA30_CLK_PLL_E] = tegra_clk_register_plle("pll_e", "pll_ref",
+			car_base, 0, 100000000, &pll_e_params,
+			TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, pll_e_freq_table);
 }
 
 static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"};
@@ -278,6 +303,12 @@ static void tegra30_periph_init(void)
 			mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base,
 			CRC_CLK_SOURCE_UARTE, TEGRA30_CLK_UARTE,
 			TEGRA_PERIPH_ON_APB);
+	clks[TEGRA30_CLK_PCIE] = clk_gate("pcie", "clk_m",
+			car_base + CRC_CLK_OUT_ENB_U, 6, 0, 0);
+	clks[TEGRA30_CLK_AFI] = clk_gate("afi", "clk_m",
+			car_base + CRC_CLK_OUT_ENB_U, 8, 0, 0);
+	clks[TEGRA30_CLK_CML0] = clk_gate("cml0", "pll_e",
+			car_base + CRC_PLLE_AUX, 0, 0, 0);
 
 	/* peripheral clocks with a divider */
 	clks[TEGRA30_CLK_MSELECT] = tegra_clk_register_periph("mselect",
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#12 lore raw

PATCH v2 12/19 i2c: tegra: move to fs initcall

In reply to Lucas Stach

From: Lucas Stach <[email protected]>

i2c is needed to enable voltage rails that are later needed by other drivers.

---
 arch/arm/boards/nvidia-beaver/board.c | 2 +-
 drivers/i2c/busses/i2c-tegra.c        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm/boards/nvidia-beaver/board.c +1 -1
index e87594d..e67d2aa 100644
@@ -35,4 +35,4 @@ static int nvidia_beaver_devices_init(void)
 
 	return 0;
 }
-device_initcall(nvidia_beaver_devices_init);
+fs_initcall(nvidia_beaver_devices_init);
drivers/i2c/busses/i2c-tegra.c +1 -1
index c52da18..f793cbe 100644
@@ -696,4 +696,4 @@ static struct driver_d tegra_i2c_driver = {
 	.probe   = tegra_i2c_probe,
 	.of_compatible = DRV_OF_COMPAT(tegra_i2c_compatible),
 };
-device_platform_driver(tegra_i2c_driver);
+register_driver_macro(fs, platform, tegra_i2c_driver);
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#13 lore raw

PATCH v2 13/19 ARM: tegra: beaver: enable PEX voltage rail

In reply to Lucas Stach

From: Lucas Stach <[email protected]>

Supply for the PCIe PLL.

---
 arch/arm/boards/nvidia-beaver/board.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
arch/arm/boards/nvidia-beaver/board.c +10 -1
index e67d2aa..20707d8 100644
@@ -15,8 +15,10 @@
  */
 
 #include <common.h>
-#include <init.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <gpio.h>
 #include <i2c/i2c.h>
+#include <init.h>
 
 static int nvidia_beaver_devices_init(void)
 {
@@ -33,6 +35,13 @@ static int nvidia_beaver_devices_init(void)
 	data = 0x65;
 	i2c_write_reg(&client, 0x32, &data, 1);
 
+	/* TPS659110: LDO1_REG = 1.05v, ACTIVE to PEX */
+	data = 0x15;
+	i2c_write_reg(&client, 0x30, &data, 1);
+
+	/* enable SYS_3V3_PEXS */
+	gpio_direction_output(TEGRA_GPIO(L, 7), 1);
+
 	return 0;
 }
 fs_initcall(nvidia_beaver_devices_init);
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#14 lore raw

PATCH v2 14/19 tegra: pmc: add powerdomain handling

In reply to Lucas Stach

From: Lucas Stach <[email protected]>

In order to use some devices we first have to power up their power domain. Add support to do this in a generic way.

---
 arch/arm/mach-tegra/include/mach/tegra-powergate.h |  93 ++++++++++++++
 arch/arm/mach-tegra/tegra20-pmc.c                  | 139 ++++++++++++++++++++-
 2 files changed, 229 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/tegra-powergate.h
arch/arm/mach-tegra/include/mach/tegra-powergate.h new file +93 -0
new file mode 100644
index 0000000..e32250a
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ *	Colin Cross <[email protected]>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _MACH_TEGRA_POWERGATE_H_
+#define _MACH_TEGRA_POWERGATE_H_
+
+struct clk;
+struct reset_control;
+
+#define TEGRA_POWERGATE_CPU	0
+#define TEGRA_POWERGATE_3D	1
+#define TEGRA_POWERGATE_VENC	2
+#define TEGRA_POWERGATE_PCIE	3
+#define TEGRA_POWERGATE_VDEC	4
+#define TEGRA_POWERGATE_L2	5
+#define TEGRA_POWERGATE_MPE	6
+#define TEGRA_POWERGATE_HEG	7
+#define TEGRA_POWERGATE_SATA	8
+#define TEGRA_POWERGATE_CPU1	9
+#define TEGRA_POWERGATE_CPU2	10
+#define TEGRA_POWERGATE_CPU3	11
+#define TEGRA_POWERGATE_CELP	12
+#define TEGRA_POWERGATE_3D1	13
+#define TEGRA_POWERGATE_CPU0	14
+#define TEGRA_POWERGATE_C0NC	15
+#define TEGRA_POWERGATE_C1NC	16
+#define TEGRA_POWERGATE_SOR	17
+#define TEGRA_POWERGATE_DIS	18
+#define TEGRA_POWERGATE_DISB	19
+#define TEGRA_POWERGATE_XUSBA	20
+#define TEGRA_POWERGATE_XUSBB	21
+#define TEGRA_POWERGATE_XUSBC	22
+#define TEGRA_POWERGATE_VIC	23
+#define TEGRA_POWERGATE_IRAM	24
+
+#define TEGRA_POWERGATE_3D0	TEGRA_POWERGATE_3D
+
+#define TEGRA_IO_RAIL_CSIA	0
+#define TEGRA_IO_RAIL_CSIB	1
+#define TEGRA_IO_RAIL_DSI	2
+#define TEGRA_IO_RAIL_MIPI_BIAS	3
+#define TEGRA_IO_RAIL_PEX_BIAS	4
+#define TEGRA_IO_RAIL_PEX_CLK1	5
+#define TEGRA_IO_RAIL_PEX_CLK2	6
+#define TEGRA_IO_RAIL_USB0	9
+#define TEGRA_IO_RAIL_USB1	10
+#define TEGRA_IO_RAIL_USB2	11
+#define TEGRA_IO_RAIL_USB_BIAS	12
+#define TEGRA_IO_RAIL_NAND	13
+#define TEGRA_IO_RAIL_UART	14
+#define TEGRA_IO_RAIL_BB	15
+#define TEGRA_IO_RAIL_AUDIO	17
+#define TEGRA_IO_RAIL_HSIC	19
+#define TEGRA_IO_RAIL_COMP	22
+#define TEGRA_IO_RAIL_HDMI	28
+#define TEGRA_IO_RAIL_PEX_CNTRL	32
+#define TEGRA_IO_RAIL_SDMMC1	33
+#define TEGRA_IO_RAIL_SDMMC3	34
+#define TEGRA_IO_RAIL_SDMMC4	35
+#define TEGRA_IO_RAIL_CAM	36
+#define TEGRA_IO_RAIL_RES	37
+#define TEGRA_IO_RAIL_HV	38
+#define TEGRA_IO_RAIL_DSIB	39
+#define TEGRA_IO_RAIL_DSIC	40
+#define TEGRA_IO_RAIL_DSID	41
+#define TEGRA_IO_RAIL_CSIE	44
+#define TEGRA_IO_RAIL_LVDS	57
+#define TEGRA_IO_RAIL_SYS_DDC	58
+
+int tegra_powergate_is_powered(int id);
+int tegra_powergate_power_on(int id);
+int tegra_powergate_power_off(int id);
+int tegra_powergate_remove_clamping(int id);
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+				      struct reset_control *rst);
+
+#endif /* _MACH_TEGRA_POWERGATE_H_ */
arch/arm/mach-tegra/tegra20-pmc.c +136 -3

168 lines not on this page · raw message

Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#15 lore raw

PATCH v2 15/19 of: import pci range parser from linux

In reply to Lucas Stach
---
 drivers/of/Kconfig   |  1 +
 drivers/of/address.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/of_address.h | 57 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+)
drivers/of/Kconfig +1 -0
index 97a1d93..97378ab 100644
@@ -30,6 +30,7 @@ config OF_GPIO
 config OF_PCI
 	bool
 	depends on PCI
+	select OF_ADDRESS_PCI
 	help
 	  OpenFirmware PCI bus accessors
 
drivers/of/address.c +68 -0

74 lines not on this page · raw message

include/of_address.h +57 -0

67 lines not on this page · raw message

Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#16 lore raw

PATCH v2 16/19 pci: add Tegra host controller driver

In reply to Lucas Stach

Only tested on Tegra30 for now.

---
 drivers/pci/Kconfig     |    7 +
 drivers/pci/Makefile    |    1 +
 drivers/pci/pci-tegra.c | 1193 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1201 insertions(+)
 create mode 100644 drivers/pci/pci-tegra.c
drivers/pci/Kconfig +7 -0
index d17a151..0e9308e 100644
@@ -30,6 +30,13 @@ config PCI_MVEBU
 	select OF_PCI
 	select PCI
 
+config PCI_TEGRA
+	bool "NVDIA Tegra PCIe driver"
+	depends on ARCH_TEGRA
+	select OF_ADDRESS_PCI
+	select OF_PCI
+	select PCI
+
 endmenu
 
 endif
drivers/pci/Makefile +1 -0
index 4423531..b93b28a 100644
@@ -8,3 +8,4 @@ ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
 CPPFLAGS += $(ccflags-y)
 
 obj-$(CONFIG_PCI_MVEBU)	+= pci-mvebu.o pci-mvebu-phy.o
+obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
drivers/pci/pci-tegra.c new file +1193 -0

1,193 lines not on this page · raw message

Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#17 lore raw

PATCH v2 17/19 ARM: tegra: advertise PCI support

In reply to Lucas Stach

From: Lucas Stach <[email protected]>

---
 arch/arm/Kconfig                    | 1 +
 arch/arm/configs/tegra_v7_defconfig | 1 +
 2 files changed, 2 insertions(+)
arch/arm/Kconfig +1 -0
index 3c9b81a..2a00e5e 100644
@@ -198,6 +198,7 @@ config ARCH_TEGRA
 	bool "NVIDIA Tegra"
 	select CPU_V7
 	select HAS_DEBUG_LL
+	select HW_HAS_PCI
 	select COMMON_CLK
 	select COMMON_CLK_OF_PROVIDER
 	select CLKDEV_LOOKUP
arch/arm/configs/tegra_v7_defconfig +1 -0
index 22f5765..8f01b54 100644
@@ -37,6 +37,7 @@ CONFIG_DRIVER_SERIAL_NS16550=y
 CONFIG_MCI=y
 CONFIG_MCI_MMC_BOOT_PARTITIONS=y
 CONFIG_MCI_TEGRA=y
+CONFIG_PCI_TEGRA=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_FAT=y
 CONFIG_FS_FAT_LFN=y
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#18 lore raw

PATCH v2 18/19 net: add rtl8169 driver

In reply to Lucas Stach

This adds the driver for RealTek 8169 and compatible pci attached network chips.

---
 drivers/net/Kconfig   |   8 +
 drivers/net/Makefile  |   1 +
 drivers/net/rtl8169.c | 566 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 575 insertions(+)
 create mode 100644 drivers/net/rtl8169.c
drivers/net/Kconfig +8 -0
index c99fcc8..24b9844 100644
@@ -156,6 +156,14 @@ config DRIVER_NET_RTL8139
 	  This is a driver for the Fast Ethernet PCI network cards based on
 	  the RTL 8139 chips.
 
+config DRIVER_NET_RTL8169
+	bool "RealTek RTL-8169 PCI Ethernet driver"
+	depends on PCI
+	select PHYLIB
+	help
+	  This is a driver for the Fast Ethernet PCI network cards based on
+	  the RTL 8169 chips.
+
 config DRIVER_NET_SMC911X
 	bool "smc911x ethernet driver"
 	select PHYLIB
drivers/net/Makefile +1 -0
index 1b85778..3e66b31 100644
@@ -22,6 +22,7 @@ obj-$(CONFIG_DRIVER_NET_MPC5200)	+= fec_mpc5200.o
 obj-$(CONFIG_DRIVER_NET_NETX)		+= netx_eth.o
 obj-$(CONFIG_DRIVER_NET_ORION)		+= orion-gbe.o
 obj-$(CONFIG_DRIVER_NET_RTL8139)	+= rtl8139.o
+obj-$(CONFIG_DRIVER_NET_RTL8169)	+= rtl8169.o
 obj-$(CONFIG_DRIVER_NET_SMC911X)	+= smc911x.o
 obj-$(CONFIG_DRIVER_NET_SMC91111)	+= smc91111.o
 obj-$(CONFIG_DRIVER_NET_TAP)		+= tap.o
drivers/net/rtl8169.c new file +566 -0

566 lines not on this page · raw message

Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#19 lore raw

PATCH v2 19/19 ARM: tegra: enable network related options in defconfig

In reply to Lucas Stach

Now that we have working network support on the Beaver board it makes sense to enable some network options.

---
 arch/arm/configs/tegra_v7_defconfig | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/configs/tegra_v7_defconfig +7 -0
index 8f01b54..ead69ed 100644
@@ -27,17 +27,24 @@ CONFIG_CMD_RESET=y
 CONFIG_CMD_EXPORT=y
 CONFIG_CMD_LOADENV=y
 CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_DETECT=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
 CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_NET_RTL8169=y
 CONFIG_MCI=y
 CONFIG_MCI_MMC_BOOT_PARTITIONS=y
 CONFIG_MCI_TEGRA=y
 CONFIG_PCI_TEGRA=y
 CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
 CONFIG_FS_FAT=y
 CONFIG_FS_FAT_LFN=y
Signature · 7 lines
1.9.3


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
Applied
#20 lore raw
In reply to Lucas Stach
Quoted 24 lines · Lucas Stach

Ok, I got around to work a bit more on this. I now actually finished the rtl8169 network driver, so this series yields working PCI attached ethernet on Tegra30 Beaver.

For Jetson K1 some work is left to setup the PHYs, but that shouldn't be far out.

While working on this I stumbled upon a few more issues, so I decided to just roll the fixes into this series and resend.

Lucas Stach (19):
MIPS: malta: fix pci IO resource assignment
pci: split out device init
pci: add resource enum
pci: properly populate prefetchable BARs
pci: setup bridges and traverse buses behind them
pci: defer device registration until after bridge setup
pci: prettyprint device names
pci: track parent<->child relationship
commands: lspci: go down into subordinate busses
clk: tegra: add PLLE setup functions
clk: tegra30: add PCIe clocks

Quoted 8 lines

i2c: tegra: move to fs initcall
ARM: tegra: beaver: enable PEX voltage rail
tegra: pmc: add powerdomain handling
of: import pci range parser from linux
pci: add Tegra host controller driver
ARM: tegra: advertise PCI support
net: add rtl8169 driver
ARM: tegra: enable network related options in defconfig

Applied, thanks

Sascha

Signature · 9 lines
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
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox