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 <land...@landonf.org>
  Reviewed by:  Michael Zhilin <miz...@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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to