Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 May 2016 00:43:08 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300702 - head/sys/dev/bhnd/cores/chipc
Message-ID:  <201605260043.u4Q0h8S5069171@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu May 26 00:43:08 2016
New Revision: 300702
URL: https://svnweb.freebsd.org/changeset/base/300702

Log:
  [bhnd] Integrate bhnd_chipc's BUS_ADD_CHILD() with a child resource mapping table.
  
  This adds support for automatically configuring bhnd_chipc bus children
  with associated resources, using an internal 'hints' table based directly
  on Michael Zhilin's chipc resource mapping work.
  
  The bhnd_sprom_chipc driver has been converted to use DEVICE_IDENTIFY()
  with the new resource table.
  
  This should be nearly drop-in compatible with the child device drivers
  in D6250.
  
  Submitted by:	Landon Fuller <landonf@landonf.org>
  Reviewed by:	Michael Zhilin <mizhka@gmail.com>
  Differential Revision:	https://reviews.freebsd.org/D6525

Modified:
  head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
  head/sys/dev/bhnd/cores/chipc/chipc.c
  head/sys/dev/bhnd/cores/chipc/chipcreg.h

Modified: head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c	Thu May 26 00:03:23 2016	(r300701)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c	Thu May 26 00:43:08 2016	(r300702)
@@ -46,9 +46,23 @@ __FBSDID("$FreeBSD$");
 #include <dev/bhnd/nvram/bhnd_nvram.h>
 #include <dev/bhnd/nvram/bhnd_spromvar.h>
 
-#include "bhnd_chipc_if.h"
 #include "bhnd_nvram_if.h"
 
+#include "chipc.h"
+
+static void
+chipc_sprom_identify(driver_t *driver, device_t parent)
+{
+	if (bhnd_chipc_nvram_src(parent) != BHND_NVRAM_SRC_SPROM)
+		return;
+
+	if (device_find_child(parent, "bhnd_nvram", 0) != NULL)
+		return;
+
+	if (BUS_ADD_CHILD(parent, 0, "bhnd_nvram", 0) == NULL)
+		device_printf(parent, "add bhnd_nvram failed\n");
+}
+
 static int
 chipc_sprom_probe(device_t dev)
 {
@@ -87,6 +101,7 @@ chipc_sprom_attach(device_t dev)
 
 static device_method_t chipc_sprom_methods[] = {
 	/* Device interface */
+	DEVMETHOD(device_identify,		chipc_sprom_identify),
 	DEVMETHOD(device_probe,			chipc_sprom_probe),
 	DEVMETHOD(device_attach,		chipc_sprom_attach),
 	DEVMETHOD_END

Modified: head/sys/dev/bhnd/cores/chipc/chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c	Thu May 26 00:03:23 2016	(r300701)
+++ head/sys/dev/bhnd/cores/chipc/chipc.c	Thu May 26 00:43:08 2016	(r300702)
@@ -98,6 +98,32 @@ static struct bhnd_device_quirk chipc_qu
 	BHND_DEVICE_QUIRK_END
 };
 
+
+static const struct chipc_hint {
+	const char	*name;
+	int		 unit;
+	int		 type;
+	int		 rid;
+	rman_res_t	 base;		/* relative to parent resource */
+	rman_res_t	 size;
+	u_int		 port;		/* ignored if SYS_RES_IRQ */
+	u_int		 region;
+} chipc_hints[] = {
+	// FIXME: cfg/spi port1.1 mapping on siba(4) SoCs
+	/* device	unit	type		rid	base			size			port,region */
+	{ "bhnd_nvram",	0, SYS_RES_MEMORY,	0,	CHIPC_SPROM_OTP,	CHIPC_SPROM_OTP_SIZE,	0,0 },
+	{ "uart",	0, SYS_RES_MEMORY,	0,	CHIPC_UART0_BASE,	CHIPC_UART_SIZE,	0,0 },
+	{ "uart",	0, SYS_RES_IRQ,		0,	0,			RM_MAX_END },
+	{ "uart",	1, SYS_RES_MEMORY,	0,	CHIPC_UART1_BASE,	CHIPC_UART_SIZE,	0,0 },
+	{ "uart",	1, SYS_RES_IRQ,		0,	0,			RM_MAX_END },
+	{ "spi",	0, SYS_RES_MEMORY,	0,	0,			RM_MAX_END,		1,1 },
+	{ "spi",	0, SYS_RES_MEMORY,	1,	CHIPC_SFLASH_BASE,	CHIPC_SFLASH_SIZE,	0,0 },
+	{ "cfi",	0, SYS_RES_MEMORY,	0,	0,			RM_MAX_END,		1,1},
+	{ "cfi",	0, SYS_RES_MEMORY, 	1,	CHIPC_SFLASH_BASE,	CHIPC_SFLASH_SIZE,	0,0 },
+	{ NULL }
+};
+
+
 static int			 chipc_try_activate_resource(
 				    struct chipc_softc *sc, device_t child,
 				    int type, int rid, struct resource *r,
@@ -106,7 +132,6 @@ static int			 chipc_try_activate_resourc
 static int			 chipc_read_caps(struct chipc_softc *sc,
 				     struct chipc_caps *caps);
 
-static int			 chipc_nvram_attach(struct chipc_softc *sc);
 static bhnd_nvram_src_t		 chipc_nvram_identify(struct chipc_softc *sc);
 static bool			 chipc_should_enable_sprom(
 				     struct chipc_softc *sc);
@@ -210,12 +235,11 @@ chipc_attach(device_t dev)
 	if (bootverbose)
 		chipc_print_caps(sc->dev, &sc->caps);
 
-	/* Identify NVRAM source and add child device. */
+	/* Identify NVRAM source */
 	sc->nvram_src = chipc_nvram_identify(sc);
-	if ((error = chipc_nvram_attach(sc)))
-		goto failed;
 
-	/* Standard bus probe */
+	/* Probe and attach children */
+	bus_generic_probe(dev);
 	if ((error = bus_generic_attach(dev)))
 		goto failed;
 
@@ -335,51 +359,6 @@ chipc_read_caps(struct chipc_softc *sc, 
 }
 
 /**
- * If supported, add an appropriate NVRAM child device.
- */
-static int
-chipc_nvram_attach(struct chipc_softc *sc)
-{
-	device_t	 nvram_dev;
-	rman_res_t	 start;
-	int		 error;
-
-	switch (sc->nvram_src) {
-	case BHND_NVRAM_SRC_OTP:
-		// TODO OTP support
-		device_printf(sc->dev, "OTP nvram source unsupported\n");
-		return (0);
-
-	case BHND_NVRAM_SRC_SPROM:
-		/* Add OTP/SPROM device */
-		nvram_dev = BUS_ADD_CHILD(sc->dev, 0, "bhnd_nvram", -1);
-		if (nvram_dev == NULL) {
-			device_printf(sc->dev, "failed to add NVRAM device\n");
-			return (ENXIO);
-		}
-
-		start = rman_get_start(sc->core->res) + CHIPC_SPROM_OTP;
-		error = bus_set_resource(nvram_dev, SYS_RES_MEMORY, 0, start,
-		    CHIPC_SPROM_OTP_SIZE);
-		return (error);
-
-	case BHND_NVRAM_SRC_FLASH:
-		// TODO flash support
-		device_printf(sc->dev, "flash nvram source unsupported\n");
-		return (0);
-
-	case BHND_NVRAM_SRC_UNKNOWN:
-		/* Handled externally */
-		return (0);
-
-	default:
-		device_printf(sc->dev, "invalid nvram source: %u\n",
-		     sc->nvram_src);
-		return (ENXIO);
-	}
-}
-
-/**
  * Determine the NVRAM data source for this device.
  *
  * @param sc chipc driver state.
@@ -500,7 +479,9 @@ static device_t
 chipc_add_child(device_t dev, u_int order, const char *name, int unit)
 {
 	struct chipc_devinfo	*dinfo;
+	const struct chipc_hint	*hint;
 	device_t		 child;
+	int			 error;
 
 	child = device_add_child_ordered(dev, order, name, unit);
 	if (child == NULL)
@@ -513,10 +494,81 @@ chipc_add_child(device_t dev, u_int orde
 	}
 
 	resource_list_init(&dinfo->resources);
-
 	device_set_ivars(child, dinfo);
 
+	/* Hint matching requires a device name */
+	if (name == NULL)
+		return (child);
+
+	/* Use hint table to set child resources */
+	for (hint = chipc_hints; hint->name != NULL; hint++) {
+		bhnd_addr_t	region_addr;
+		bhnd_size_t	region_size;
+
+		if (strcmp(hint->name, name) != 0)
+			continue;
+
+		switch (hint->type) {
+		case SYS_RES_IRQ:
+			/* Add child resource */
+			error = bus_set_resource(child, hint->type, hint->rid,
+			    hint->base, hint->size);
+			if (error) {
+				device_printf(dev,
+				    "bus_set_resource() failed for %s: %d\n",
+				    device_get_nameunit(child), error);
+				goto failed;
+			}
+			break;
+
+		case SYS_RES_MEMORY:
+			/* Fetch region address and size */
+			error = bhnd_get_region_addr(dev, BHND_PORT_DEVICE,
+			    hint->port, hint->region, &region_addr,
+			    &region_size);
+			if (error) {
+				device_printf(dev,
+				    "lookup of %s%u.%u failed: %d\n",
+				    bhnd_port_type_name(BHND_PORT_DEVICE),
+				    hint->port, hint->region, error);
+				goto failed;
+			}
+
+			/* Verify requested range is mappable */
+			if (hint->base > region_size ||
+			    hint->size > region_size ||
+			    region_size - hint->base < hint->size )
+			{
+				device_printf(dev,
+				    "%s%u.%u region cannot map requested range "
+				        "%#jx+%#jx\n",
+				    bhnd_port_type_name(BHND_PORT_DEVICE),
+				    hint->port, hint->region, hint->base,
+				    hint->size);
+			}
+
+			/* Add child resource */
+			error = bus_set_resource(child, hint->type,
+			    hint->rid, region_addr + hint->base, hint->size);
+			if (error) {
+				device_printf(dev,
+				    "bus_set_resource() failed for %s: %d\n",
+				    device_get_nameunit(child), error);
+				goto failed;
+			}
+			break;
+		default:
+			device_printf(child, "unknown hint resource type: %d\n",
+			    hint->type);
+			break;
+		}
+	}
+
 	return (child);
+
+failed:
+	device_delete_child(dev, child);
+	return (NULL);
 }
 
 static void

Modified: head/sys/dev/bhnd/cores/chipc/chipcreg.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipcreg.h	Thu May 26 00:03:23 2016	(r300701)
+++ head/sys/dev/bhnd/cores/chipc/chipcreg.h	Thu May 26 00:43:08 2016	(r300702)
@@ -61,6 +61,8 @@
 #define	CHIPC_JTAGDR			0x38
 #define	CHIPC_JTAGCTRL			0x3c
 
+#define	CHIPC_SFLASH_BASE		0x40
+#define	CHIPC_SFLASH_SIZE		12
 #define	CHIPC_SFLASHCTRL		0x40
 #define	CHIPC_SFLASHADDR		0x44
 #define	CHIPC_SFLASHDATA		0x48
@@ -171,11 +173,15 @@
 #define	CHIPC_CLK_CTL_ST		0x1E0
 #define	CHIPC_SPROM_HWWAR		0x19
 
-#define	CHIPC_UART0			0x300
-#define	CHIPC_UART1			0x400
+#define	CHIPC_UART_BASE			0x300
+#define	CHIPC_UART_SIZE			0x100
+#define	CHIPC_UART0_BASE		CHIPC_UART_BASE
+#define	CHIPC_UART1_BASE		(CHIPC_UART_BASE + CHIPC_UART_SIZE)
 
 /* PMU registers (rev >= 20) */
 #define	CHIPC_PMU_BASE			0x600
+#define	CHIPC_PMU_SIZE			0x70
+
 #define	CHIPC_PMU_CTRL			0x600
 #define	CHIPC_PMU_CAP			0x604
 #define	CHIPC_PMU_ST			0x608



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