Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Jan 2009 10:20:51 +0000 (UTC)
From:      Rafal Jaworowski <raj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186932 - in head/sys/arm/mv: . orion
Message-ID:  <200901091020.n09AKpRa049618@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: raj
Date: Fri Jan  9 10:20:51 2009
New Revision: 186932
URL: http://svn.freebsd.org/changeset/base/186932

Log:
  Improve Marvell SOCs PCI/PCIE driver.
  
  - Provide dedicated rmans for MEM and IO resources.
  
  - Convert PCI IRQ routing info into a table (from callback approach), provide
    config data for alternative DB- boards.
  
  - Fix a wrong boundary check error in pcib_mbus_init_bar()
  
  Obtained from:	Semihalf

Modified:
  head/sys/arm/mv/mv_pci.c
  head/sys/arm/mv/mvvar.h
  head/sys/arm/mv/orion/db88f5xxx.c
  head/sys/arm/mv/orion/orion.c

Modified: head/sys/arm/mv/mv_pci.c
==============================================================================
--- head/sys/arm/mv/mv_pci.c	Fri Jan  9 10:16:19 2009	(r186931)
+++ head/sys/arm/mv/mv_pci.c	Fri Jan  9 10:20:51 2009	(r186932)
@@ -95,10 +95,12 @@ __FBSDID("$FreeBSD$");
 struct pcib_mbus_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_ioport_rman;
 	bus_addr_t	sc_ioport_base;
 	bus_addr_t	sc_ioport_size;
 	bus_addr_t	sc_ioport_alloc;	/* Next allocation. */
@@ -521,12 +523,39 @@ pcib_mbus_attach(device_t self)
 	sc->sc_ioport_size = sc->sc_info->op_io_size;
 	sc->sc_ioport_alloc = sc->sc_info->op_io_base;
 
+	sc->sc_iomem_rman.rm_type = RMAN_ARRAY;
+	err = rman_init(&sc->sc_iomem_rman);
+	if (err)
+		return (err);
+
+	sc->sc_ioport_rman.rm_type = RMAN_ARRAY;
+	err = rman_init(&sc->sc_ioport_rman);
+	if (err) {
+		rman_fini(&sc->sc_iomem_rman);
+		return (err);
+	}
+
+	err = rman_manage_region(&sc->sc_iomem_rman, sc->sc_iomem_base,
+	    sc->sc_iomem_base + sc->sc_iomem_size - 1);
+	if (err)
+		goto error;
+
+	err = rman_manage_region(&sc->sc_ioport_rman, sc->sc_ioport_base,
+	    sc->sc_ioport_base + sc->sc_ioport_size - 1);
+	if (err)
+		goto error;
+
 	err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev));
 	if (err)
-		return(err);
+		goto error;
 
 	device_add_child(self, "pci", -1);
 	return (bus_generic_attach(self));
+
+error:
+	rman_fini(&sc->sc_iomem_rman);
+	rman_fini(&sc->sc_ioport_rman);
+	return (err);
 }
 
 static int
@@ -570,7 +599,7 @@ pcib_mbus_init_bar(struct pcib_mbus_soft
 		return (width);
 
 	addr = (*allocp + mask) & ~mask;
-	if ((*allocp = addr + size) >= limit)
+	if ((*allocp = addr + size) > limit)
 		return (-1);
 
 	if (bootverbose)
@@ -634,8 +663,10 @@ static int
 pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot,
     int func, int hdrtype)
 {
+	const struct obio_pci_irq_map *map = sc->sc_info->op_pci_irq_map;
 	int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6;
-	int bar = 0, irq, pin, i;
+	int bar = 0, irq = -1;
+	int pin, i;
 
 	/* Program the base address registers */
 	while (bar < maxbar) {
@@ -652,8 +683,14 @@ pcib_mbus_init_resources(struct pcib_mbu
 	pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func,
 	    PCIR_INTPIN, 1);
 
-	if (sc->sc_info->op_get_irq != NULL)
-		irq = sc->sc_info->op_get_irq(bus, slot, func, pin);
+	if (map != NULL)
+		while (map->opim_irq >= 0) {
+			if ((map->opim_slot == slot || map->opim_slot < 0) &&
+			    (map->opim_pin == pin || map->opim_pin < 0))
+				irq = map->opim_irq;
+
+			map++;
+		}
 	else
 		irq = sc->sc_info->op_irq;
 
@@ -728,9 +765,37 @@ static struct resource *
 pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
 {
+	struct pcib_mbus_softc *sc = device_get_softc(dev);
+	struct rman *rm = NULL;
+	struct resource *res;
 
-	return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
-	    type, rid, start, end, count, flags));
+	switch (type) {
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_ioport_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_iomem_rman;
+		break;
+	default:
+		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+		    type, rid, start, end, count, flags));
+	};
+
+	res = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (res == NULL)
+		return (NULL);
+
+	rman_set_rid(res, *rid);
+	rman_set_bustag(res, obio_tag);
+	rman_set_bushandle(res, start);
+
+	if (flags & RF_ACTIVE)
+		if (bus_activate_resource(child, type, *rid, res)) {
+			rman_release_resource(res);
+			return (NULL);
+		}
+
+	return (res);
 }
 
 static int
@@ -738,8 +803,11 @@ pcib_mbus_release_resource(device_t dev,
     struct resource *res)
 {
 
-	return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
-	    type, rid, res));
+	if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY)
+		return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+		    type, rid, res));
+
+	return (rman_release_resource(res));
 }
 
 static int

Modified: head/sys/arm/mv/mvvar.h
==============================================================================
--- head/sys/arm/mv/mvvar.h	Fri Jan  9 10:16:19 2009	(r186931)
+++ head/sys/arm/mv/mvvar.h	Fri Jan  9 10:20:51 2009	(r186932)
@@ -63,7 +63,11 @@ struct obio_device {
 	struct resource_list od_resources;
 };
 
-typedef int (*obio_get_irq_t)(u_int bus, u_int slot, u_int func, u_int pin);
+struct obio_pci_irq_map {
+	int		opim_slot;
+	int		opim_pin;
+	int		opim_irq;
+};
 
 struct obio_pci {
 	int		op_type;
@@ -82,8 +86,8 @@ struct obio_pci {
 	int		op_mem_win_target;
 	int		op_mem_win_attr;
 
-	obio_get_irq_t	op_get_irq;	/* IRQ Mapping callback */
-	int		op_irq;		/* used if callback is NULL */
+	const struct obio_pci_irq_map	*op_pci_irq_map;
+	int		op_irq;		/* used if IRQ map table is NULL */
 };
 
 struct gpio_config {

Modified: head/sys/arm/mv/orion/db88f5xxx.c
==============================================================================
--- head/sys/arm/mv/orion/db88f5xxx.c	Fri Jan  9 10:16:19 2009	(r186931)
+++ head/sys/arm/mv/orion/db88f5xxx.c	Fri Jan  9 10:20:51 2009	(r186932)
@@ -123,35 +123,32 @@ static const struct pmap_devmap pmap_dev
 	{ 0, 0, 0, 0, 0, }
 };
 
-int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin)
-{
-	int irq;
-
-	switch (slot) {
-	case 7:
-		irq = GPIO2IRQ(12);	/* GPIO 0 for DB-88F5182  */
-		break;			/* GPIO 12 for DB-88F5281 */
-	case 8:
-	case 9:
-		irq = GPIO2IRQ(13);	/* GPIO 1 for DB-88F5182  */
-		break;			/* GPIO 13 for DB-88F5281 */
-	default:
-		irq = -1;
-		break;
-	};
+/*
+ * The pci_irq_map table consists of 3 columns:
+ * - PCI slot number (less than zero means ANY).
+ * - PCI IRQ pin (less than zero means ANY).
+ * - PCI IRQ (less than zero marks end of table).
+ *
+ * IRQ number from the first matching entry is used to configure PCI device
+ */
 
-	/*
-	 * XXX This isn't the right place to setup GPIO, but it makes sure
-	 * that PCI works on 5XXX targets where U-Boot doesn't set up the GPIO
-	 * correctly to handle PCI IRQs (e.g., on 5182). This code will go
-	 * away once we set up GPIO in a generic way in a proper place (TBD).
-	 */
-	if (irq >= 0)
-		mv_gpio_configure(IRQ2GPIO(irq), MV_GPIO_POLAR_LOW |
-		    MV_GPIO_LEVEL, ~0u);
+/* PCI IRQ Map for DB-88F5281 */
+const struct obio_pci_irq_map pci_irq_map[] = {
+	{ 7, -1, GPIO2IRQ(12) },
+	{ 8, -1, GPIO2IRQ(13) },
+	{ 9, -1, GPIO2IRQ(13) },
+	{ -1, -1, -1 }
+};
 
-	return (irq);
-}
+#if 0
+/* PCI IRQ Map for DB-88F5182 */
+const struct obio_pci_irq_map pci_irq_map[] = {
+	{ 7, -1, GPIO2IRQ(0) },
+	{ 8, -1, GPIO2IRQ(1) },
+	{ 9, -1, GPIO2IRQ(1) },
+	{ -1, -1, -1 }
+};
+#endif
 
 /*
  * mv_gpio_config row structure:

Modified: head/sys/arm/mv/orion/orion.c
==============================================================================
--- head/sys/arm/mv/orion/orion.c	Fri Jan  9 10:16:19 2009	(r186931)
+++ head/sys/arm/mv/orion/orion.c	Fri Jan  9 10:20:51 2009	(r186932)
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <arm/mv/mvreg.h>
 #include <arm/mv/mvvar.h>
 
-extern int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin);
+extern const struct obio_pci_irq_map pci_irq_map[];
 
 struct obio_device obio_devices[] = {
 	{ "ic", MV_IC_BASE, MV_IC_SIZE,
@@ -106,7 +106,7 @@ const struct obio_pci mv_pci_info[] = {
 		MV_PCI_BASE, MV_PCI_SIZE,
 		MV_PCI_IO_BASE, MV_PCI_IO_SIZE,		3, 0x51,
 		MV_PCI_MEM_BASE, MV_PCI_MEM_SIZE,	3, 0x59,
-		platform_pci_get_irq, -1
+		pci_irq_map, -1
 	},
 
 	{ 0, 0, 0 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901091020.n09AKpRa049618>