PERFORCE change 176348 for review

Rafal Jaworowski raj at FreeBSD.org
Wed Mar 31 08:40:03 UTC 2010


http://p4web.freebsd.org/chv.cgi?CH=176348

Change 176348 by raj at raj_fdt on 2010/03/31 08:39:37

	Initial support for PCI / PCI-Express nodes.
	
	- Retrieve IMMR data from the DT at very early stage, reduce direct
	  usage of FDT_IMMR_VA.
	
	- Improve retrieving CESA SRAM range data.
	
	- Rework MV PCI driver to use DT-provided config data and parameters.
	
	- Collapse shared (platform) MV code.
	
	- Bring a number of other smaller fixes, corrections, renamings and
	  clean-up
	
	Tested with PCI-Express network card (em(4)) on DB-88F6281.

Affected files ...

.. //depot/projects/fdt/sys/arm/include/fdt.h#3 edit
.. //depot/projects/fdt/sys/arm/mv/common.c#8 edit
.. //depot/projects/fdt/sys/arm/mv/discovery/discovery.c#3 edit
.. //depot/projects/fdt/sys/arm/mv/discovery/files.db78xxx#2 edit
.. //depot/projects/fdt/sys/arm/mv/gpio.c#4 edit
.. //depot/projects/fdt/sys/arm/mv/kirkwood/db88f6xxx.c#4 delete
.. //depot/projects/fdt/sys/arm/mv/kirkwood/files.db88f6xxx#2 delete
.. //depot/projects/fdt/sys/arm/mv/kirkwood/kirkwood.c#9 edit
.. //depot/projects/fdt/sys/arm/mv/kirkwood/sheevaplug.c#3 edit
.. //depot/projects/fdt/sys/arm/mv/kirkwood/std.db88f6xxx#2 edit
.. //depot/projects/fdt/sys/arm/mv/mv_machdep.c#11 edit
.. //depot/projects/fdt/sys/arm/mv/mv_pci.c#2 edit
.. //depot/projects/fdt/sys/arm/mv/mvvar.h#6 edit
.. //depot/projects/fdt/sys/arm/mv/mvwin.h#4 edit
.. //depot/projects/fdt/sys/arm/mv/orion/db88f5xxx.c#3 edit
.. //depot/projects/fdt/sys/arm/mv/orion/orion.c#4 edit
.. //depot/projects/fdt/sys/conf/files#20 edit
.. //depot/projects/fdt/sys/dev/fdt/fdt_arm.c#5 edit
.. //depot/projects/fdt/sys/dev/fdt/fdt_common.c#12 edit
.. //depot/projects/fdt/sys/dev/fdt/fdt_common.h#10 edit
.. //depot/projects/fdt/sys/dev/fdt/fdt_pci.c#1 add
.. //depot/projects/fdt/sys/dev/fdt/fdtbus.c#6 edit
.. //depot/projects/fdt/sys/dev/fdt/simplebus.c#8 edit
.. //depot/projects/fdt/sys/dev/ofw/ofw_bus_subr.c#4 edit
.. //depot/projects/fdt/sys/dev/uart/uart_bus_fdt.c#7 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/lbc.c#6 edit

Differences ...

==== //depot/projects/fdt/sys/arm/include/fdt.h#3 (text+ko) ====

@@ -31,6 +31,12 @@
 
 #ifndef _MACHINE_FDT_H_
 
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/pmap.h>
 #include <machine/intr.h>
 
 #include <arm/mv/mvvar.h>
@@ -50,4 +56,7 @@
  */
 #define fdtbus_bs_tag	obio_tag
 
+int fdt_pci_devmap(phandle_t, struct pmap_devmap *devmap, vm_offset_t,
+    vm_offset_t);
+
 #endif /* _MACHINE_FDT_H_ */

==== //depot/projects/fdt/sys/arm/mv/common.c#8 (text+ko) ====

@@ -274,7 +274,7 @@
 	*rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff;
 }
 
-void
+static void
 soc_identify(void)
 {
 	uint32_t d, r;
@@ -336,6 +336,20 @@
 	/* TODO add info on currently set endianess */
 }
 
+static void
+platform_identify(void *dummy)
+{
+
+	soc_identify();
+
+	/*
+	 * XXX Board identification e.g. read out from FPGA or similar should
+	 * go here
+	 */
+}
+SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify,
+    NULL);
+
 #define MV_USB0_BASE	(FDT_IMMR_VA + usb0_base)
 #define MV_CESA_BASE	(FDT_IMMR_VA + cesa_base)
 #define MV_ETH0_BASE	(FDT_IMMR_VA + eth0_base)
@@ -1735,7 +1749,7 @@
 			if (soc_node->base == NULL)
 				continue;
 
-			err = fdt_get_regsize(child, soc_node->base, &size);
+			err = fdt_regsize(child, soc_node->base, &size);
 			if (err != 0)
 				return (err);
 		}
@@ -1779,12 +1793,19 @@
 	/*
 	 * Retrieve CESA SRAM data.
 	 */
-	if ((node = OF_finddevice("/sram")) == 0)
+	if ((node = OF_finddevice("sram")) != 0)
+		if (fdt_is_compatible(node, "mrvl,cesa-sram"))
+			goto moveon;
+
+	if ((node = OF_finddevice("/")) == 0)
+		return (ENXIO);
+
+	if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
 		/* SRAM block is not always present. */
 		return (0);
-
+moveon:
 	sram_base = sram_size = 0;
-	if (fdt_get_regsize(node, &sram_base, &sram_size) != 0)
+	if (fdt_regsize(node, &sram_base, &sram_size) != 0)
 		return (EINVAL);
 
 	cpu_win_tbl[++t].target = MV_WIN_CESA_TARGET;
@@ -1792,7 +1813,7 @@
 	cpu_win_tbl[t].base = sram_base;
 	cpu_win_tbl[t].size = sram_size;
 	cpu_win_tbl[t].remap = -1;
-	debugf("/sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
+	debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
 
 	return (0);
 }

==== //depot/projects/fdt/sys/arm/mv/discovery/discovery.c#3 (text+ko) ====

@@ -53,6 +53,7 @@
 #define	_MV_PCIE_IO_PHYS(n)	(MV_PCIE_IO_PHYS_BASE + ((n) * _MV_PCIE_IO_SIZE))
 #define	_MV_PCIE_MEM_PHYS(n)	(MV_PCIE_MEM_PHYS_BASE + ((n) * _MV_PCIE_MEM_SIZE))
 
+#if 0
 /*
  * Note the 'pcib' devices are not declared in the obio_devices[]: due to the
  * much more complex configuration schemes allowed, specifically of the
@@ -114,6 +115,7 @@
 
 	{ 0, 0, 0 }
 };
+#endif
 
 struct resource_spec mv_gpio_res[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },

==== //depot/projects/fdt/sys/arm/mv/discovery/files.db78xxx#2 (text+ko) ====

@@ -1,4 +1,3 @@
 # $FreeBSD: src/sys/arm/mv/discovery/files.db78xxx,v 1.1 2008/10/13 20:07:13 raj Exp $
 
 arm/mv/discovery/discovery.c	standard
-arm/mv/discovery/db78xxx.c	standard

==== //depot/projects/fdt/sys/arm/mv/gpio.c#4 (text+ko) ====

@@ -566,7 +566,7 @@
 	tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
 	tuples = len / tuple_size;
 
-	if (fdt_get_regsize(ctrl, &gpio_ctrl, &size))
+	if (fdt_regsize(ctrl, &gpio_ctrl, &size))
 		return (ENXIO);
 	/*
 	 * Since to set up GPIO we use the same functions as GPIO driver, and
@@ -578,7 +578,7 @@
 	mv_gpio_softc = &sc;
 
 	sc.bst = fdtbus_bs_tag;
-	gpio_ctrl += FDT_IMMR_VA;
+	gpio_ctrl += fdt_immr_va;
 
 	if (bus_space_map(sc.bst, gpio_ctrl, size, 0, &sc.bsh) != 0)
 		return (ENXIO);
@@ -588,7 +588,7 @@
 	sc.pin_num = fdt32_to_cpu(pincnt);
 
 	/*
-	 * Skip controller reference, since contoller's phandle is given
+	 * Skip controller reference, since controller's phandle is given
 	 * explicitly (in a function argument).
 	 */
 	inc = sizeof(ihandle_t) / sizeof(pcell_t);

==== //depot/projects/fdt/sys/arm/mv/kirkwood/kirkwood.c#9 (text+ko) ====

@@ -42,17 +42,6 @@
 #include <arm/mv/mvvar.h>
 #include <arm/mv/mvwin.h>
 
-const struct obio_pci mv_pci_info[] = {
-	{ MV_TYPE_PCIE,
-		MV_PCIE_BASE, MV_PCIE_SIZE,
-		MV_PCIE_IO_BASE, MV_PCIE_IO_SIZE,	4, 0xE0,
-		MV_PCIE_MEM_BASE, MV_PCIE_MEM_SIZE,	4, 0xE8,
-		NULL, MV_INT_PEX0
-	},
-
-	{ 0, 0, 0 }
-};
-
 struct resource_spec mv_gpio_res[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },

==== //depot/projects/fdt/sys/arm/mv/kirkwood/sheevaplug.c#3 (text+ko) ====

@@ -1,8 +1,10 @@
 /*-
- * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
- * Copyright (C) 2009 Semihalf
+ * Copyright (c) 2010 The FreeBSD Foundation
  * All rights reserved.
  *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -11,14 +13,11 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of MARVELL nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -29,80 +28,17 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/mv/kirkwood/sheevaplug.c,v 1.1 2009/08/25 10:09:25 raj Exp $");
+__FBSDID("$FreeBSD$");
 
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
 
-#include <vm/vm.h>
-#include <vm/pmap.h>
+#include <machine/fdt.h>
 
-#include <machine/bus.h>
-#include <machine/pte.h>
-#include <machine/pmap.h>
-#include <machine/vmparam.h>
-
-#include <arm/mv/mvreg.h>
-#include <arm/mv/mvvar.h>
-#include <arm/mv/mvwin.h>
-
-/*
- * Virtual address space layout:
- * -----------------------------
- * 0x0000_0000 - 0x7FFF_FFFF	: User Process (2 GB)
- * 0x8000_0000 - 0xBBFF_FFFF	: Unused (960 MB)
- * 0xBC00_0000 - 0xBDFF_FFFF	: Device Bus: CS1 (32 MB)
- * 0xBE00_0000 - 0xBECF_FFFF	: Unused (13 MB)
- * 0xBED0_0000 - 0xBEDF_FFFF	: Device Bus: CS2 (1 MB)
- * 0xBEE0_0000 - 0xBEEF_FFFF	: Device Bus: CS0 (1 MB)
- * 0xBEF0_0000 - 0xBEFF_FFFF	: Device Bus: BOOT (1 MB)
- * 0xBF00_0000 - 0xBFFF_FFFF	: Unused (16 MB)
- * 0xC000_0000 - virtual_avail	: Kernel Reserved (text, data, page tables,
- * 				: stack etc.)
- * virtual-avail - 0xEFFF_FFFF	: KVA (virtual_avail is typically < 0xc0a0_0000)
- * 0xF000_0000 - 0xF0FF_FFFF	: No-Cache allocation area (16 MB)
- * 0xF100_0000 - 0xF10F_FFFF	: SoC Integrated devices registers range (1 MB)
- * 0xF110_0000 - 0xF11F_FFFF	: CESA SRAM (1 MB)
- * 0xF120_0000 - 0xFFFE_FFFF	: Unused (237 MB + 960 kB)
- * 0xFFFF_0000 - 0xFFFF_0FFF	: 'High' vectors page (4 kB)
- * 0xFFFF_1000 - 0xFFFF_1FFF	: ARM_TP_ADDRESS/RAS page (4 kB)
- * 0xFFFF_2000 - 0xFFFF_FFFF	: Unused (56 kB)
- */
-
-/* Static device mappings. */
-const struct pmap_devmap pmap_devmap[] = {
-	/*
-	 * Map the on-board devices VA == PA so that we can access them
-	 * with the MMU on or off.
-	 */
-	{ /* SoC integrated peripherals registers range */
-		MV_BASE,
-		MV_PHYS_BASE,
-		MV_SIZE,
-		VM_PROT_READ | VM_PROT_WRITE,
-		PTE_NOCACHE,
-	},
-	{ /* CESA SRAM */
-		MV_CESA_SRAM_BASE,
-		MV_CESA_SRAM_PHYS_BASE,
-		MV_CESA_SRAM_SIZE,
-		VM_PROT_READ | VM_PROT_WRITE,
-		PTE_NOCACHE,
-	},
-	{ 0, 0, 0, 0, 0, }
-};
-
-static void
-platform_identify(void *dummy)
+int
+fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va,
+    vm_offset_t mem_va)
 {
 
-	soc_identify();
-
-	/*
-	 * XXX Board identification e.g. read out from FPGA or similar should
-	 * go here
-	 */
+	return (0);
 }
-SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);

==== //depot/projects/fdt/sys/arm/mv/kirkwood/std.db88f6xxx#2 (text+ko) ====

@@ -2,7 +2,6 @@
 
 include	"../mv/std.mv"
 include "../mv/kirkwood/std.kirkwood"
-files	"../mv/kirkwood/files.db88f6xxx"
-
+files	"../mv/kirkwood/files.kirkwood"
 
 options		PHYSMEM_SIZE=0x20000000

==== //depot/projects/fdt/sys/arm/mv/mv_machdep.c#11 (text+ko) ====

@@ -124,13 +124,10 @@
 extern u_int prefetch_abort_handler_address;
 extern u_int undefined_handler_address;
 
-extern const struct pmap_devmap *pmap_devmap_bootstrap_table;
 extern vm_offset_t pmap_bootstrap_lastaddr;
+extern int *end;
 
 struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
-
-extern int *end;
-
 struct pcpu __pcpu;
 struct pcpu *pcpup = &__pcpu;
 
@@ -166,6 +163,7 @@
 static void print_bootinfo(void);
 
 static void physmap_init(int);
+static int platform_devmap_init(void);
 static int platform_mpp_init(void);
 
 static char *
@@ -396,12 +394,13 @@
 		kmdp = preload_search_by_type("elf kernel");
 		if (kmdp != NULL) {
 			bootinfo = (struct bootinfo *)preload_search_info(kmdp,
-			    MODINFO_METADATA|MODINFOMD_BOOTINFO);
+			    MODINFO_METADATA | MODINFOMD_BOOTINFO);
 
 			boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
 			kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
 			dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
-			lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
+			lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND,
+			    vm_offset_t);
 		}
 
 		/* Initialize memory regions table */
@@ -415,7 +414,8 @@
 		}
 		availmem_regions_sz = i;
 	} else {
-		/* Fall back to hardcoded metadata. */
+		/* Fall back to hardcoded boothowto flags and metadata. */
+		boothowto = RB_VERBOSE | RB_SINGLE;
 		lastaddr = fake_preload_metadata();
 
 		/*
@@ -447,9 +447,11 @@
 	if (OF_init((void *)dtbp) != 0)
 		while (1);
 
+	if (fdt_immr_addr() != 0)
+		while (1);
+
 	/* Platform-specific initialisation */
-	pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE;
-	pmap_devmap_bootstrap_table = &pmap_devmap[0];
+	pmap_bootstrap_lastaddr = fdt_immr_va - ARM_NOCACHE_KVA_SIZE;
 
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 	PCPU_SET(curthread, &thread0);
@@ -564,7 +566,11 @@
 	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
 	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
 
+	/* Map pmap_devmap[] entries */
+	if (platform_devmap_init() != 0)
+		while (1);
 	pmap_devmap_bootstrap(l1pagetable, pmap_devmap_bootstrap_table);
+
 	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
 	    DOMAIN_CLIENT);
 	setttb(kernel_l1pt.pv_pa);
@@ -688,7 +694,6 @@
 {
 	pcell_t pinmap[MPP_PIN_MAX * MPP_PIN_CELLS];
 	int mpp[MPP_PIN_MAX];
-	char buf[64];
 	uint32_t ctrl_val, ctrl_offset;
 	pcell_t reg[4];
 	u_long start, size;
@@ -702,15 +707,9 @@
 	/*
 	 * Try to access the MPP node directly i.e. through /aliases/mpp.
 	 */
-	if ((node = OF_finddevice("/aliases")) != 0)
-		if (OF_getprop(node, "mpp", buf, sizeof(buf)) > 0) {
-			if ((node = OF_finddevice(buf)) == 0)
-				return (ENXIO);
-			if (!fdt_is_compatible(node, "mrvl,mpp"))
-				return (ENXIO);
+	if ((node = OF_finddevice("mpp")) != 0)
+		if (fdt_is_compatible(node, "mrvl,mpp"))
 			goto moveon;
-		}
-
 	/*
 	 * Find the node the long way.
 	 */
@@ -722,7 +721,6 @@
 
 	if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0)
 		return (ENXIO);
-
 moveon:
 	/*
 	 * Process 'reg' prop.
@@ -744,7 +742,7 @@
 	    &start, &size);
 	if (rv != 0)
 		return (rv);
-	start += FDT_IMMR_VA;
+	start += fdt_immr_va;
 
 	/*
 	 * Process 'pin-count' and 'pin-map' props.
@@ -810,6 +808,87 @@
 	return (0);
 }
 
+#define FDT_DEVMAP_MAX	(1 + 2 + 1 + 1)
+static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = {
+	{ 0, 0, 0, 0, 0, }
+};
+
+/*
+ * Construct pmap_devmap[] with DT-derived config data.
+ */
+static int
+platform_devmap_init(void)
+{
+	phandle_t root, child;
+	u_long base, size;
+	int i;
+
+	/*
+	 * IMMR range.
+	 */
+	i = 0;
+	fdt_devmap[i].pd_va = fdt_immr_va;
+	fdt_devmap[i].pd_pa = fdt_immr_pa;
+	fdt_devmap[i].pd_size = fdt_immr_size;
+	fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	fdt_devmap[i].pd_cache = PTE_NOCACHE;
+	i++;
+
+	/*
+	 * PCI range(s).
+	 */
+	if ((root = OF_finddevice("/")) == 0)
+		return (ENXIO);
+
+	for (child = OF_child(root); child != 0; child = OF_peer(child))
+		if (fdt_is_type(child, "pci")) {
+			/*
+			 * Check space: each PCI node will consume 2 devmap
+			 * entries.
+			 */
+			if (i + 1 >= FDT_DEVMAP_MAX) {
+				return (ENOMEM);
+				break;
+			}
+
+			/*
+			 * XXX this should account for PCI and multiple ranges
+			 * of a given kind.
+			 */
+			if (fdt_pci_devmap(child, &fdt_devmap[i],
+			    MV_PCIE_IO_BASE, MV_PCIE_MEM_BASE) != 0)
+				return (ENXIO);
+			i += 2;
+		}
+
+	/*
+	 * CESA SRAM range.
+	 */
+	if ((child = OF_finddevice("sram")) != 0)
+		if (fdt_is_compatible(child, "mrvl,cesa-sram"))
+			goto moveon;
+
+	if ((child = fdt_find_compatible(root, "mrvl,cesa-sram", 0)) == 0)
+		/* No CESA SRAM node. */
+		goto out;
+moveon:
+	if (i >= FDT_DEVMAP_MAX)
+		return (ENOMEM);
+
+	if (fdt_regsize(child, &base, &size) != 0)
+		return (EINVAL);
+
+	fdt_devmap[i].pd_va = MV_CESA_SRAM_BASE; /* XXX */
+	fdt_devmap[i].pd_pa = base;
+	fdt_devmap[i].pd_size = size;
+	fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	fdt_devmap[i].pd_cache = PTE_NOCACHE;
+
+out:
+	pmap_devmap_bootstrap_table = &fdt_devmap[0];
+	return (0);
+}
+
 struct arm32_dma_range *
 bus_dma_get_range(void)
 {

==== //depot/projects/fdt/sys/arm/mv/mv_pci.c#2 (text+ko) ====

@@ -1,9 +1,13 @@
 /*-
- * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
+ * Copyright (c) 2010 The FreeBSD Foundation
  * All rights reserved.
  *
  * Developed by Semihalf.
  *
+ * Portions of this software were developed by Semihalf
+ * under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -51,10 +55,14 @@
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcib_private.h>
 
+#include "ofw_bus_if.h"
 #include "pcib_if.h"
 
 #include <machine/resource.h>
@@ -62,6 +70,7 @@
 
 #include <arm/mv/mvreg.h>
 #include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
 
 #define PCI_CFG_ENA		(1 << 31)
 #define PCI_CFG_BUS(bus)	(((bus) & 0xff) << 16)
@@ -93,18 +102,22 @@
 
 #define PCI_VENDORID_MRVL	0x11AB
 
-struct pcib_mbus_softc {
+struct mv_pcib_softc {
 	device_t	sc_dev;
 
-	struct rman	sc_iomem_rman;
-	bus_addr_t	sc_iomem_base;
-	bus_addr_t	sc_iomem_size;
-	bus_addr_t	sc_iomem_alloc;		/* Next allocation. */
+	struct rman	sc_mem_rman;
+	bus_addr_t	sc_mem_base;
+	bus_addr_t	sc_mem_size;
+	bus_addr_t	sc_mem_alloc;		/* Next allocation. */
+	int		sc_mem_win_target;
+	int		sc_mem_win_attr;
 
-	struct rman	sc_ioport_rman;
-	bus_addr_t	sc_ioport_base;
-	bus_addr_t	sc_ioport_size;
-	bus_addr_t	sc_ioport_alloc;	/* Next allocation. */
+	struct rman	sc_io_rman;
+	bus_addr_t	sc_io_base;
+	bus_addr_t	sc_io_size;
+	bus_addr_t	sc_io_alloc;		/* Next allocation. */
+	int		sc_io_win_target;
+	int		sc_io_win_attr;
 
 	struct resource	*sc_res;
 	bus_space_handle_t sc_bsh;
@@ -113,452 +126,208 @@
 
 	int		sc_busnr;		/* Host bridge bus number */
 	int		sc_devnr;		/* Host bridge device number */
+	int		sc_type;
 
-	const struct obio_pci *sc_info;
+	struct fdt_pci_intr	sc_intr_info;
 };
 
-static void pcib_mbus_identify(driver_t *driver, device_t parent);
-static int pcib_mbus_probe(device_t);
-static int pcib_mbus_attach(device_t);
+/* Local forward prototypes */
+static int mv_pcib_decode_win(phandle_t, struct mv_pcib_softc *);
+static void mv_pcib_hw_cfginit(void);
+static uint32_t mv_pcib_hw_cfgread(struct mv_pcib_softc *, u_int, u_int,
+    u_int, u_int, int);
+static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int,
+    u_int, u_int, uint32_t, int);
+static int mv_pcib_init(struct mv_pcib_softc *, int, int);
+static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int);
+static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int);
+static int mv_pcib_intr_info(phandle_t, struct mv_pcib_softc *);
+static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t);
+
+
+/* Forward prototypes */
+static int mv_pcib_probe(device_t);
+static int mv_pcib_attach(device_t);
 
-static struct resource *pcib_mbus_alloc_resource(device_t, device_t, int, int *,
+static struct resource *mv_pcib_alloc_resource(device_t, device_t, int, int *,
     u_long, u_long, u_long, u_int);
-static int pcib_mbus_release_resource(device_t, device_t, int, int,
+static int mv_pcib_release_resource(device_t, device_t, int, int,
     struct resource *);
-static int pcib_mbus_read_ivar(device_t, device_t, int, uintptr_t *);
-static int pcib_mbus_write_ivar(device_t, device_t, int, uintptr_t);
+static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
+static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t);
 
-static int pcib_mbus_maxslots(device_t);
-static uint32_t pcib_mbus_read_config(device_t, u_int, u_int, u_int, u_int,
-    int);
-static void pcib_mbus_write_config(device_t, u_int, u_int, u_int, u_int,
+static int mv_pcib_maxslots(device_t);
+static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int);
+static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
     uint32_t, int);
-static int pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot);
-static int pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot,
-    int func, int barno);
-static void pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot,
-    int func);
-static int pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus,
-    int slot, int func, int hdrtype);
+static int mv_pcib_route_interrupt(device_t, device_t, int);
 
 /*
  * Bus interface definitions.
  */
-static device_method_t pcib_mbus_methods[] = {
+static device_method_t mv_pcib_methods[] = {
 	/* Device interface */
-	DEVMETHOD(device_identify,		pcib_mbus_identify),
-	DEVMETHOD(device_probe,			pcib_mbus_probe),
-	DEVMETHOD(device_attach,		pcib_mbus_attach),
+	DEVMETHOD(device_probe,			mv_pcib_probe),
+	DEVMETHOD(device_attach,		mv_pcib_attach),
 
 	/* Bus interface */
 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
-	DEVMETHOD(bus_read_ivar,		pcib_mbus_read_ivar),
-	DEVMETHOD(bus_write_ivar,		pcib_mbus_write_ivar),
-	DEVMETHOD(bus_alloc_resource,		pcib_mbus_alloc_resource),
-	DEVMETHOD(bus_release_resource,		pcib_mbus_release_resource),
+	DEVMETHOD(bus_read_ivar,		mv_pcib_read_ivar),
+	DEVMETHOD(bus_write_ivar,		mv_pcib_write_ivar),
+	DEVMETHOD(bus_alloc_resource,		mv_pcib_alloc_resource),
+	DEVMETHOD(bus_release_resource,		mv_pcib_release_resource),
 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
 
 	/* pcib interface */
-	DEVMETHOD(pcib_maxslots,		pcib_mbus_maxslots),
-	DEVMETHOD(pcib_read_config,		pcib_mbus_read_config),
-	DEVMETHOD(pcib_write_config,		pcib_mbus_write_config),
-	DEVMETHOD(pcib_route_interrupt,		pcib_route_interrupt),
+	DEVMETHOD(pcib_maxslots,		mv_pcib_maxslots),
+	DEVMETHOD(pcib_read_config,		mv_pcib_read_config),
+	DEVMETHOD(pcib_write_config,		mv_pcib_write_config),
+	DEVMETHOD(pcib_route_interrupt,		mv_pcib_route_interrupt),
+
+	/* OFW bus interface */
+	DEVMETHOD(ofw_bus_get_compat,   ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,    ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,     ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,     ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,     ofw_bus_gen_get_type),
 
 	{ 0, 0 }
 };
 
-static driver_t pcib_mbus_driver = {
+static driver_t mv_pcib_driver = {
 	"pcib",
-	pcib_mbus_methods,
-	sizeof(struct pcib_mbus_softc),
+	mv_pcib_methods,
+	sizeof(struct mv_pcib_softc),
 };
 
 devclass_t pcib_devclass;
 
-DRIVER_MODULE(pcib, mbus, pcib_mbus_driver, pcib_devclass, 0, 0);
+DRIVER_MODULE(pcib, fdtbus, mv_pcib_driver, pcib_devclass, 0, 0);
 
 static struct mtx pcicfg_mtx;
 
-static inline void
-pcib_write_irq_mask(struct pcib_mbus_softc *sc, uint32_t mask)
-{
-
-	if (!sc->sc_info->op_type != MV_TYPE_PCI)
-		return;
-
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh,
-	    PCIE_REG_IRQ_MASK, mask);
-}
-
-static void
-pcib_mbus_hw_cfginit(void)
-{
-	static int opened = 0;
-
-	if (opened)
-		return;
-
-	mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN);
-	opened = 1;
-}
-
-static uint32_t
-pcib_mbus_hw_cfgread(struct pcib_mbus_softc *sc, u_int bus, u_int slot,
-    u_int func, u_int reg, int bytes)
-{
-	uint32_t addr, data, ca, cd;
-
-	ca = (sc->sc_info->op_type != MV_TYPE_PCI) ?
-	    PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR;
-	cd = (sc->sc_info->op_type != MV_TYPE_PCI) ?
-	    PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA;
-	addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) |
-	    PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg);
-
-	mtx_lock_spin(&pcicfg_mtx);
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr);
-
-	data = ~0;
-	switch (bytes) {
-	case 1:
-		data = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
-		    cd + (reg & 3));
-		break;
-	case 2:
-		data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh,
-		    cd + (reg & 2)));
-		break;
-	case 4:
-		data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
-		    cd));
-		break;
-	}
-	mtx_unlock_spin(&pcicfg_mtx);
-	return (data);
-}
-
-static void
-pcib_mbus_hw_cfgwrite(struct pcib_mbus_softc *sc, u_int bus, u_int slot,
-    u_int func, u_int reg, uint32_t data, int bytes)
-{
-	uint32_t addr, ca, cd;
-
-	ca = (sc->sc_info->op_type != MV_TYPE_PCI) ?
-	    PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR;
-	cd = (sc->sc_info->op_type != MV_TYPE_PCI) ?
-	    PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA;
-	addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) |
-	    PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg);
-
-	mtx_lock_spin(&pcicfg_mtx);
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr);
-
-	switch (bytes) {
-	case 1:
-		bus_space_write_1(sc->sc_bst, sc->sc_bsh,
-		    cd + (reg & 3), data);
-		break;
-	case 2:
-		bus_space_write_2(sc->sc_bst, sc->sc_bsh,
-		    cd + (reg & 2), htole16(data));
-		break;
-	case 4:
-		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
-		    cd, htole32(data));
-		break;
-	}
-	mtx_unlock_spin(&pcicfg_mtx);
-}
-
 static int
-pcib_mbus_maxslots(device_t dev)
+mv_pcib_probe(device_t self)
 {
-	struct pcib_mbus_softc *sc = device_get_softc(dev);
+	phandle_t parnode;
 
-	return ((sc->sc_info->op_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX);
-}
+	/*
+	 * The PCI subnode does not have the 'compatible' property, so we need
+	 * to check in the parent PCI node. However the parent is not
+	 * represented by a separate ofw_bus child, and therefore
+	 * ofw_bus_is_compatible() cannot be used, but direct fdt equivalent.
+	 */
+	parnode = OF_parent(ofw_bus_get_node(self));
+	if (parnode == 0)
+		return (ENXIO);
+	if (!(fdt_is_compatible(parnode, "mrvl,pcie") ||
+	    fdt_is_compatible(parnode, "mrvl,pci")))
+		return (ENXIO);
 
-static uint32_t
-pcib_mbus_read_config(device_t dev, u_int bus, u_int slot, u_int func,
-    u_int reg, int bytes)
-{
-	struct pcib_mbus_softc *sc = device_get_softc(dev);
+	device_set_desc(self, "Marvell Integrated PCI/PCI-E Controller");
 
-	/* Skip self */
-	if (bus == sc->sc_busnr && slot == sc->sc_devnr)
-		return (~0U);
-
-	return (pcib_mbus_hw_cfgread(sc, bus, slot, func, reg, bytes));
-}
-
-static void
-pcib_mbus_write_config(device_t dev, u_int bus, u_int slot, u_int func,
-    u_int reg, uint32_t val, int bytes)
-{
-	struct pcib_mbus_softc *sc = device_get_softc(dev);
-
-	/* Skip self */
-	if (bus == sc->sc_busnr && slot == sc->sc_devnr)
-		return;
-
-	pcib_mbus_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes);
-}
-
-static void
-pcib_mbus_add_child(driver_t *driver, device_t parent, struct pcib_mbus_softc *sc)
-{
-	device_t child;
-	int error;
-
-	/* Configure CPU decoding windows */
-	error = decode_win_cpu_set(sc->sc_info->op_io_win_target,
-	    sc->sc_info->op_io_win_attr, sc->sc_info->op_io_base,
-	    sc->sc_info->op_io_size, -1);
-	if (error < 0) {
-		device_printf(parent, "Could not set up CPU decode "
-		    "window for PCI IO\n");
-		return;
-	}
-	error = decode_win_cpu_set(sc->sc_info->op_mem_win_target,
-	    sc->sc_info->op_mem_win_attr, sc->sc_info->op_mem_base,
-	    sc->sc_info->op_mem_size, -1);
-	if (error < 0) {
-		device_printf(parent, "Could not set up CPU decode "
-		    "windows for PCI MEM\n");
-		return;
-	}
-
-	/* Create driver instance */
-	child = BUS_ADD_CHILD(parent, 0, driver->name, -1);
-	bus_set_resource(child, SYS_RES_MEMORY, 0,
-	    sc->sc_info->op_base, sc->sc_info->op_size);
-	device_set_softc(child, sc);
-}
-
-static void
-pcib_mbus_identify(driver_t *driver, device_t parent)
-{
-	const struct obio_pci *info = mv_pci_info;
-	struct pcib_mbus_softc *sc;
-	uint32_t control;
-
-	while (info->op_base) {
-		sc = malloc(driver->size, M_DEVBUF, M_NOWAIT | M_ZERO);
-		if (sc == NULL) {
-			device_printf(parent, "Could not allocate pcib "
-			    "memory\n");
-			break;
-		}
-		sc->sc_info = info++;
-
-		/*
-		 * PCI bridge objects are instantiated immediately. PCI-Express
-		 * bridges require more complicated handling depending on
-		 * platform configuration.
-		 */
-		if (sc->sc_info->op_type == MV_TYPE_PCI) {
-			pcib_mbus_add_child(driver, parent, sc);
-			continue;
-		}
-
-		/*
-		 * Read link configuration
-		 */
-		sc->sc_rid = 0;
-		sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY,
-		    &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base +
-		    sc->sc_info->op_size - 1, sc->sc_info->op_size,
-		    RF_ACTIVE);
-		if (sc->sc_res == NULL) {
-			device_printf(parent, "Could not map pcib memory\n");
-			break;
-		}
-
-		sc->sc_bst = rman_get_bustag(sc->sc_res);
-		sc->sc_bsh = rman_get_bushandle(sc->sc_res);
-
-		control = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
-		    PCIE_REG_CONTROL);
-
-		BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid,
-		    sc->sc_res);
-
-		/*
-		 * If this PCI-E port (controller) is configured (by the
-		 * underlying firmware) with lane width other than 1x, there
-		 * are auxiliary resources defined for aggregating more width
-		 * on our lane. Skip all such entries as they are not
-		 * standalone ports and must not have a device object
-		 * instantiated.
-		 */
-		if ((control & PCIE_CTRL_LINK1X) == 0)
-			while (info->op_base &&
-			    info->op_type == MV_TYPE_PCIE_AGGR_LANE)
-				info++;
-
-		pcib_mbus_add_child(driver, parent, sc);
-	}
+	return (BUS_PROBE_DEFAULT);
 }
 
 static int

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list