[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
This commit is contained in:
parent
40cb6df5f3
commit
785df0cb3f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=300702
@ -46,9 +46,23 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/bhnd/nvram/bhnd_nvram.h>
|
#include <dev/bhnd/nvram/bhnd_nvram.h>
|
||||||
#include <dev/bhnd/nvram/bhnd_spromvar.h>
|
#include <dev/bhnd/nvram/bhnd_spromvar.h>
|
||||||
|
|
||||||
#include "bhnd_chipc_if.h"
|
|
||||||
#include "bhnd_nvram_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
|
static int
|
||||||
chipc_sprom_probe(device_t dev)
|
chipc_sprom_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -87,6 +101,7 @@ chipc_sprom_attach(device_t dev)
|
|||||||
|
|
||||||
static device_method_t chipc_sprom_methods[] = {
|
static device_method_t chipc_sprom_methods[] = {
|
||||||
/* Device interface */
|
/* Device interface */
|
||||||
|
DEVMETHOD(device_identify, chipc_sprom_identify),
|
||||||
DEVMETHOD(device_probe, chipc_sprom_probe),
|
DEVMETHOD(device_probe, chipc_sprom_probe),
|
||||||
DEVMETHOD(device_attach, chipc_sprom_attach),
|
DEVMETHOD(device_attach, chipc_sprom_attach),
|
||||||
DEVMETHOD_END
|
DEVMETHOD_END
|
||||||
|
@ -98,6 +98,32 @@ static struct bhnd_device_quirk chipc_quirks[] = {
|
|||||||
BHND_DEVICE_QUIRK_END
|
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(
|
static int chipc_try_activate_resource(
|
||||||
struct chipc_softc *sc, device_t child,
|
struct chipc_softc *sc, device_t child,
|
||||||
int type, int rid, struct resource *r,
|
int type, int rid, struct resource *r,
|
||||||
@ -106,7 +132,6 @@ static int chipc_try_activate_resource(
|
|||||||
static int chipc_read_caps(struct chipc_softc *sc,
|
static int chipc_read_caps(struct chipc_softc *sc,
|
||||||
struct chipc_caps *caps);
|
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 bhnd_nvram_src_t chipc_nvram_identify(struct chipc_softc *sc);
|
||||||
static bool chipc_should_enable_sprom(
|
static bool chipc_should_enable_sprom(
|
||||||
struct chipc_softc *sc);
|
struct chipc_softc *sc);
|
||||||
@ -210,12 +235,11 @@ chipc_attach(device_t dev)
|
|||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
chipc_print_caps(sc->dev, &sc->caps);
|
chipc_print_caps(sc->dev, &sc->caps);
|
||||||
|
|
||||||
/* Identify NVRAM source and add child device. */
|
/* Identify NVRAM source */
|
||||||
sc->nvram_src = chipc_nvram_identify(sc);
|
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)))
|
if ((error = bus_generic_attach(dev)))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
@ -334,51 +358,6 @@ chipc_read_caps(struct chipc_softc *sc, struct chipc_caps *caps)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Determine the NVRAM data source for this device.
|
||||||
*
|
*
|
||||||
@ -500,7 +479,9 @@ static device_t
|
|||||||
chipc_add_child(device_t dev, u_int order, const char *name, int unit)
|
chipc_add_child(device_t dev, u_int order, const char *name, int unit)
|
||||||
{
|
{
|
||||||
struct chipc_devinfo *dinfo;
|
struct chipc_devinfo *dinfo;
|
||||||
|
const struct chipc_hint *hint;
|
||||||
device_t child;
|
device_t child;
|
||||||
|
int error;
|
||||||
|
|
||||||
child = device_add_child_ordered(dev, order, name, unit);
|
child = device_add_child_ordered(dev, order, name, unit);
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
@ -513,10 +494,81 @@ chipc_add_child(device_t dev, u_int order, const char *name, int unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
resource_list_init(&dinfo->resources);
|
resource_list_init(&dinfo->resources);
|
||||||
|
|
||||||
device_set_ivars(child, dinfo);
|
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, ®ion_addr,
|
||||||
|
®ion_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);
|
return (child);
|
||||||
|
|
||||||
|
failed:
|
||||||
|
device_delete_child(dev, child);
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -61,6 +61,8 @@
|
|||||||
#define CHIPC_JTAGDR 0x38
|
#define CHIPC_JTAGDR 0x38
|
||||||
#define CHIPC_JTAGCTRL 0x3c
|
#define CHIPC_JTAGCTRL 0x3c
|
||||||
|
|
||||||
|
#define CHIPC_SFLASH_BASE 0x40
|
||||||
|
#define CHIPC_SFLASH_SIZE 12
|
||||||
#define CHIPC_SFLASHCTRL 0x40
|
#define CHIPC_SFLASHCTRL 0x40
|
||||||
#define CHIPC_SFLASHADDR 0x44
|
#define CHIPC_SFLASHADDR 0x44
|
||||||
#define CHIPC_SFLASHDATA 0x48
|
#define CHIPC_SFLASHDATA 0x48
|
||||||
@ -171,11 +173,15 @@
|
|||||||
#define CHIPC_CLK_CTL_ST 0x1E0
|
#define CHIPC_CLK_CTL_ST 0x1E0
|
||||||
#define CHIPC_SPROM_HWWAR 0x19
|
#define CHIPC_SPROM_HWWAR 0x19
|
||||||
|
|
||||||
#define CHIPC_UART0 0x300
|
#define CHIPC_UART_BASE 0x300
|
||||||
#define CHIPC_UART1 0x400
|
#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) */
|
/* PMU registers (rev >= 20) */
|
||||||
#define CHIPC_PMU_BASE 0x600
|
#define CHIPC_PMU_BASE 0x600
|
||||||
|
#define CHIPC_PMU_SIZE 0x70
|
||||||
|
|
||||||
#define CHIPC_PMU_CTRL 0x600
|
#define CHIPC_PMU_CTRL 0x600
|
||||||
#define CHIPC_PMU_CAP 0x604
|
#define CHIPC_PMU_CAP 0x604
|
||||||
#define CHIPC_PMU_ST 0x608
|
#define CHIPC_PMU_ST 0x608
|
||||||
|
Loading…
Reference in New Issue
Block a user