All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/2] imx: ventana: add PCIe dt fixups
@ 2016-06-17 13:10 Tim Harvey
  2016-06-17 13:10 ` [U-Boot] [PATCH 1/2] imx: ventana: add dt fixup for GW16082 irq mapping Tim Harvey
  2016-06-17 13:10 ` [U-Boot] [PATCH 2/2] imx: ventana: add dt fixup for eth1 mac-address Tim Harvey
  0 siblings, 2 replies; 5+ messages in thread
From: Tim Harvey @ 2016-06-17 13:10 UTC (permalink / raw)
  To: u-boot

There are a couple of device-tree fixups that need to be applied to the
PCIe node in the devicetree which is a set of nested nodes based on bus
topology. This series adds the ability to track the PCI devices enumerated
and build a nested topology which is supported on newer kernels.

Tim Harvey (2):
  imx: ventana: add dt fixup for GW16082 irq mapping
  imx: ventana: add dt fixup for eth1 mac-address

 board/gateworks/gw_ventana/gw_ventana.c | 263 ++++++++++++++++++++++++++++++++
 1 file changed, 263 insertions(+)

-- 
1.9.1

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

* [U-Boot] [PATCH 1/2] imx: ventana: add dt fixup for GW16082 irq mapping
  2016-06-17 13:10 [U-Boot] [PATCH 0/2] imx: ventana: add PCIe dt fixups Tim Harvey
@ 2016-06-17 13:10 ` Tim Harvey
  2016-07-28 10:31   ` Stefano Babic
  2016-06-17 13:10 ` [U-Boot] [PATCH 2/2] imx: ventana: add dt fixup for eth1 mac-address Tim Harvey
  1 sibling, 1 reply; 5+ messages in thread
From: Tim Harvey @ 2016-06-17 13:10 UTC (permalink / raw)
  To: u-boot

The GW16082 mini-PCI expansion mezzanine uses a TI XIO2001 PCIe-to-PCI
bridge with legacy INTA/B/C/D interrupts. These interrupts are assigned
in the reverse order according to the PCI spec.

If the TI bridge is found on the Ventana PCI bus, add device-tree nodes
according to bus enumeration explicitly defining the interrupt mapping
to override the default PCI mapping in the Linux kernel. This allows
the GW16082 to work with upstream kernels that support device-tree
irq parsing.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/gw_ventana.c | 228 ++++++++++++++++++++++++++++++++
 1 file changed, 228 insertions(+)

diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index c02ded7..3607542 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -491,14 +491,54 @@ int imx6_pcie_toggle_reset(void)
  * GPIO's as PERST# signals for its downstream ports - configure the GPIO's
  * properly and assert reset for 100ms.
  */
+#define MAX_PCI_DEVS	32
+struct pci_dev {
+	pci_dev_t devfn;
+	unsigned short vendor;
+	unsigned short device;
+	unsigned short class;
+	unsigned short busno; /* subbordinate busno */
+	struct pci_dev *ppar;
+};
+struct pci_dev pci_devs[MAX_PCI_DEVS];
+int pci_devno;
+int pci_bridgeno;
+
 void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
 			 unsigned short vendor, unsigned short device,
 			 unsigned short class)
 {
+	int i;
 	u32 dw;
+	struct pci_dev *pdev = &pci_devs[pci_devno++];
 
 	debug("%s: %02d:%02d.%02d: %04x:%04x\n", __func__,
 	      PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), vendor, device);
+
+	/* store array of devs for later use in device-tree fixup */
+	pdev->devfn = dev;
+	pdev->vendor = vendor;
+	pdev->device = device;
+	pdev->class = class;
+	pdev->ppar = NULL;
+	if (class == PCI_CLASS_BRIDGE_PCI)
+		pdev->busno = ++pci_bridgeno;
+	else
+		pdev->busno = 0;
+
+	/* fixup RC - it should be 00:00.0 not 00:01.0 */
+	if (PCI_BUS(dev) == 0)
+		pdev->devfn = 0;
+
+	/* find dev's parent */
+	for (i = 0; i < pci_devno; i++) {
+		if (pci_devs[i].busno == PCI_BUS(pdev->devfn)) {
+			pdev->ppar = &pci_devs[i];
+			break;
+		}
+	}
+
+	/* assert downstream PERST# */
 	if (vendor == PCI_VENDOR_ID_PLX &&
 	    (device & 0xfff0) == 0x8600 &&
 	    PCI_DEV(dev) == 0 && PCI_FUNC(dev) == 0) {
@@ -937,6 +977,189 @@ static int disable_dt_ldo(void *blob)
 	return 0;
 }
 
+#if defined(CONFIG_CMD_PCI)
+#define PCI_ID(x) ( \
+	(PCI_BUS(x->devfn)<<16)| \
+	(PCI_DEV(x->devfn)<<11)| \
+	(PCI_FUNC(x->devfn)<<8) \
+	)
+#define PCIE_PATH	"/soc/pcie@0x01000000"
+int fdt_add_pci_node(void *blob, int par, struct pci_dev *dev)
+{
+	uint32_t reg[5];
+	char node[32];
+	int np;
+
+	sprintf(node, "pcie@%d,%d,%d", PCI_BUS(dev->devfn),
+		PCI_DEV(dev->devfn), PCI_FUNC(dev->devfn));
+
+	np = fdt_subnode_offset(blob, par, node);
+	if (np >= 0)
+		return np;
+	np = fdt_add_subnode(blob, par, node);
+	if (np < 0) {
+		printf("   %s failed: no space\n", __func__);
+		return np;
+	}
+
+	memset(reg, 0, sizeof(reg));
+	reg[0] = cpu_to_fdt32(PCI_ID(dev));
+	fdt_setprop(blob, np, "reg", reg, sizeof(reg));
+
+	return np;
+}
+
+/* build a path of nested PCI devs for all bridges passed through */
+int fdt_add_pci_path(void *blob, struct pci_dev *dev)
+{
+	struct pci_dev *bridges[MAX_PCI_DEVS];
+	int k, np;
+
+	/* build list of parents */
+	np = fdt_path_offset(blob, PCIE_PATH);
+	if (np < 0)
+		return np;
+
+	k = 0;
+	while (dev) {
+		bridges[k++] = dev;
+		dev = dev->ppar;
+	};
+
+	/* now add them the to DT in reverse order */
+	while (k--) {
+		np = fdt_add_pci_node(blob, np, bridges[k]);
+		if (np < 0)
+			break;
+	}
+
+	return np;
+}
+
+/*
+ * The GW16082 has a hardware errata errata such that it's
+ * INTA/B/C/D are mis-mapped to its four slots (slot12-15). Because
+ * of this normal PCI interrupt swizzling will not work so we will
+ * provide an irq-map via device-tree.
+ */
+int fdt_fixup_gw16082(void *blob, int np, struct pci_dev *dev)
+{
+	int len;
+	int host;
+	uint32_t imap_new[8*4*4];
+	const uint32_t *imap;
+	uint32_t irq[4];
+	uint32_t reg[4];
+	int i;
+
+	/* build irq-map based on host controllers map */
+	host = fdt_path_offset(blob, PCIE_PATH);
+	if (host < 0) {
+		printf("   %s failed: missing host\n", __func__);
+		return host;
+	}
+
+	/* use interrupt data from root complex's node */
+	imap = fdt_getprop(blob, host, "interrupt-map", &len);
+	if (!imap || len != 128) {
+		printf("   %s failed: invalid interrupt-map\n",
+		       __func__);
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	/* obtain irq's of host controller in pin order */
+	for (i = 0; i < 4; i++)
+		irq[(fdt32_to_cpu(imap[(i*8)+3])-1)%4] = imap[(i*8)+6];
+
+	/*
+	 * determine number of swizzles necessary:
+	 *   For each bridge we pass through we need to swizzle
+	 *   the number of the slot we are on.
+	 */
+	struct pci_dev *d;
+	int b;
+	b = 0;
+	d = dev->ppar;
+	while(d && d->ppar) {
+		b += PCI_DEV(d->devfn);
+		d = d->ppar;
+	}
+
+	/* create new irq mappings for slots12-15
+	 * <skt> <idsel> <slot> <skt-inta> <skt-intb>
+	 * J3    AD28    12     INTD      INTA
+	 * J4    AD29    13     INTC      INTD
+	 * J5    AD30    14     INTB      INTC
+	 * J2    AD31    15     INTA      INTB
+	 */
+	for (i = 0; i < 4; i++) {
+		/* addr matches bus:dev:func */
+		u32 addr = dev->busno << 16 | (12+i) << 11;
+
+		/* default cells from root complex */
+		memcpy(&imap_new[i*32], imap, 128);
+		/* first cell is PCI device address (BDF) */
+		imap_new[(i*32)+(0*8)+0] = cpu_to_fdt32(addr);
+		imap_new[(i*32)+(1*8)+0] = cpu_to_fdt32(addr);
+		imap_new[(i*32)+(2*8)+0] = cpu_to_fdt32(addr);
+		imap_new[(i*32)+(3*8)+0] = cpu_to_fdt32(addr);
+		/* third cell is pin */
+		imap_new[(i*32)+(0*8)+3] = cpu_to_fdt32(1);
+		imap_new[(i*32)+(1*8)+3] = cpu_to_fdt32(2);
+		imap_new[(i*32)+(2*8)+3] = cpu_to_fdt32(3);
+		imap_new[(i*32)+(3*8)+3] = cpu_to_fdt32(4);
+		/* sixth cell is relative interrupt */
+		imap_new[(i*32)+(0*8)+6] = irq[(15-(12+i)+b+0)%4];
+		imap_new[(i*32)+(1*8)+6] = irq[(15-(12+i)+b+1)%4];
+		imap_new[(i*32)+(2*8)+6] = irq[(15-(12+i)+b+2)%4];
+		imap_new[(i*32)+(3*8)+6] = irq[(15-(12+i)+b+3)%4];
+	}
+	fdt_setprop(blob, np, "interrupt-map", imap_new,
+		    sizeof(imap_new));
+	reg[0] = cpu_to_fdt32(0xfff00);
+	reg[1] = 0;
+	reg[2] = 0;
+	reg[3] = cpu_to_fdt32(0x7);
+	fdt_setprop(blob, np, "interrupt-map-mask", reg, sizeof(reg));
+	fdt_setprop_cell(blob, np, "#interrupt-cells", 1);
+	fdt_setprop_string(blob, np, "device_type", "pci");
+	fdt_setprop_cell(blob, np, "#address-cells", 3);
+	fdt_setprop_cell(blob, np, "#size-cells", 2);
+	printf("   Added custom interrupt-map for GW16082\n");
+
+	return 0;
+}
+
+/*
+ * PCI DT nodes must be nested therefore if we need to apply a DT fixup
+ * we will walk the PCI bus and add bridge nodes up to the device receiving
+ * the fixup.
+ */
+void ft_board_pci_fixup(void *blob, bd_t *bd)
+{
+	int i, np;
+	struct pci_dev *dev;
+
+	for (i = 0; i < pci_devno; i++) {
+		dev = &pci_devs[i];
+
+		/*
+		 * The GW16082 consists of a TI XIO2001 PCIe-to-PCI bridge and
+		 * an EEPROM@i2c1-0x50.
+		 */
+		if ((dev->vendor == PCI_VENDOR_ID_TI) &&
+		    (dev->device == 0x8240) &&
+		    (i2c_set_bus_num(1) == 0) &&
+		    (i2c_probe(0x50) == 0))
+		{
+			np = fdt_add_pci_path(blob, dev);
+			if (np > 0)
+				fdt_fixup_gw16082(blob, np, dev);
+		}
+	}
+}
+#endif /* if defined(CONFIG_CMD_PCI) */
+
 /*
  * called prior to booting kernel or by 'fdt boardsetup' command
  *
@@ -1126,6 +1349,11 @@ int ft_board_setup(void *blob, bd_t *bd)
 	/* Adjust pmic rails depending on LDO enabled vs bypass */
 	adjust_pmic(ldo_enabled);
 
+#if defined(CONFIG_CMD_PCI)
+	if (!getenv("nopcifixup"))
+		ft_board_pci_fixup(blob, bd);
+#endif
+
 	/*
 	 * Peripheral Config:
 	 *  remove nodes by alias path if EEPROM config tells us the
-- 
1.9.1

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

* [U-Boot] [PATCH 2/2] imx: ventana: add dt fixup for eth1 mac-address
  2016-06-17 13:10 [U-Boot] [PATCH 0/2] imx: ventana: add PCIe dt fixups Tim Harvey
  2016-06-17 13:10 ` [U-Boot] [PATCH 1/2] imx: ventana: add dt fixup for GW16082 irq mapping Tim Harvey
@ 2016-06-17 13:10 ` Tim Harvey
  2016-07-28 10:32   ` Stefano Babic
  1 sibling, 1 reply; 5+ messages in thread
From: Tim Harvey @ 2016-06-17 13:10 UTC (permalink / raw)
  To: u-boot

Ventana boards with a PCI Marvell Sky2 GigE MAC require the MAC address to
be placed in a DT node in order for the mainline linux driver to obtain it.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/gw_ventana.c | 35 +++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index 3607542..1464ceb 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -1130,6 +1130,32 @@ int fdt_fixup_gw16082(void *blob, int np, struct pci_dev *dev)
 	return 0;
 }
 
+/* The sky2 GigE MAC obtains it's MAC addr from device-tree by default */
+int fdt_fixup_sky2(void *blob, int np, struct pci_dev *dev)
+{
+	char *tmp, *end;
+	char mac[16];
+	unsigned char mac_addr[6];
+	int j;
+
+	sprintf(mac, "eth1addr");
+	tmp = getenv(mac);
+	if (tmp) {
+		for (j = 0; j < 6; j++) {
+			mac_addr[j] = tmp ?
+				      simple_strtoul(tmp, &end,16) : 0;
+			if (tmp)
+				tmp = (*end) ? end+1 : end;
+		}
+		fdt_setprop(blob, np, "local-mac-address", mac_addr,
+			    sizeof(mac_addr));
+		printf("   Added mac addr for eth1\n");
+		return 0;
+	}
+
+	return -1;
+}
+
 /*
  * PCI DT nodes must be nested therefore if we need to apply a DT fixup
  * we will walk the PCI bus and add bridge nodes up to the device receiving
@@ -1156,6 +1182,15 @@ void ft_board_pci_fixup(void *blob, bd_t *bd)
 			if (np > 0)
 				fdt_fixup_gw16082(blob, np, dev);
 		}
+
+		/* ethernet1 mac address */
+		else if ((dev->vendor == PCI_VENDOR_ID_MARVELL) &&
+		         (dev->device == 0x4380))
+		{
+			np = fdt_add_pci_path(blob, dev);
+			if (np > 0)
+				fdt_fixup_sky2(blob, np, dev);
+		}
 	}
 }
 #endif /* if defined(CONFIG_CMD_PCI) */
-- 
1.9.1

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

* [U-Boot] [PATCH 1/2] imx: ventana: add dt fixup for GW16082 irq mapping
  2016-06-17 13:10 ` [U-Boot] [PATCH 1/2] imx: ventana: add dt fixup for GW16082 irq mapping Tim Harvey
@ 2016-07-28 10:31   ` Stefano Babic
  0 siblings, 0 replies; 5+ messages in thread
From: Stefano Babic @ 2016-07-28 10:31 UTC (permalink / raw)
  To: u-boot

On 17/06/2016 15:10, Tim Harvey wrote:
> The GW16082 mini-PCI expansion mezzanine uses a TI XIO2001 PCIe-to-PCI
> bridge with legacy INTA/B/C/D interrupts. These interrupts are assigned
> in the reverse order according to the PCI spec.
> 
> If the TI bridge is found on the Ventana PCI bus, add device-tree nodes
> according to bus enumeration explicitly defining the interrupt mapping
> to override the default PCI mapping in the Linux kernel. This allows
> the GW16082 to work with upstream kernels that support device-tree
> irq parsing.
> 
> Signed-off-by: Tim Harvey <tharvey@gateworks.com>
> ---


Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic



-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

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

* [U-Boot] [PATCH 2/2] imx: ventana: add dt fixup for eth1 mac-address
  2016-06-17 13:10 ` [U-Boot] [PATCH 2/2] imx: ventana: add dt fixup for eth1 mac-address Tim Harvey
@ 2016-07-28 10:32   ` Stefano Babic
  0 siblings, 0 replies; 5+ messages in thread
From: Stefano Babic @ 2016-07-28 10:32 UTC (permalink / raw)
  To: u-boot

On 17/06/2016 15:10, Tim Harvey wrote:
> Ventana boards with a PCI Marvell Sky2 GigE MAC require the MAC address to
> be placed in a DT node in order for the mainline linux driver to obtain it.
> 
> Signed-off-by: Tim Harvey <tharvey@gateworks.com>
> ---

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic


-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

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

end of thread, other threads:[~2016-07-28 10:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-17 13:10 [U-Boot] [PATCH 0/2] imx: ventana: add PCIe dt fixups Tim Harvey
2016-06-17 13:10 ` [U-Boot] [PATCH 1/2] imx: ventana: add dt fixup for GW16082 irq mapping Tim Harvey
2016-07-28 10:31   ` Stefano Babic
2016-06-17 13:10 ` [U-Boot] [PATCH 2/2] imx: ventana: add dt fixup for eth1 mac-address Tim Harvey
2016-07-28 10:32   ` Stefano Babic

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.