Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132401029
D7539.id19371.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
41 KB
Referenced Files
None
Subscribers
None
D7539.id19371.diff
View Options
Index: sys/dev/bhnd/bcma/bcma_erom.c
===================================================================
--- sys/dev/bhnd/bcma/bcma_erom.c
+++ sys/dev/bhnd/bcma/bcma_erom.c
@@ -65,10 +65,18 @@
static int erom_skip_sport_region(struct bcma_erom *erom);
static int erom_seek_next(struct bcma_erom *erom, uint8_t etype);
-
-#define EROM_LOG(erom, fmt, ...) \
- device_printf(erom->dev, "erom[0x%llx]: " fmt, \
- (unsigned long long) (erom->offset), ##__VA_ARGS__);
+static int erom_region_to_port_type(struct bcma_erom *erom,
+ uint8_t region_type, bhnd_port_type *port_type);
+
+#define EROM_LOG(erom, fmt, ...) do { \
+ if (erom->dev != NULL) { \
+ device_printf(erom->dev, "erom[0x%llx]: " fmt, \
+ (unsigned long long) (erom->offset), ##__VA_ARGS__);\
+ } else { \
+ printf("erom[0x%llx]: " fmt, \
+ (unsigned long long) (erom->offset), ##__VA_ARGS__);\
+ } \
+} while(0)
/**
* Open an EROM table for reading.
@@ -82,11 +90,37 @@
* @retval non-zero if the erom table could not be opened.
*/
int
-bcma_erom_open(struct bcma_erom *erom, struct resource *r, bus_size_t offset)
+bcma_erom_open(struct bcma_erom *erom, struct resource *r,
+ bus_size_t offset)
+{
+ return (bhnd_erom_bus_space_open(erom, rman_get_device(r),
+ rman_get_bustag(r), rman_get_bushandle(r), offset));
+
+ return (0);
+}
+
+/**
+ * Open an EROM table for reading using the provided bus space tag and
+ * handle.
+ *
+ * @param[out] erom On success, will be populated with a valid EROM
+ * read state.
+ * @param dev The owning device, or NULL if none.
+ * @param bst EROM table bus space tag.
+ * @param bsh EROM table bus space handle.
+ * @param offset Offset of the EROM core from @p resource.
+ *
+ * @retval 0 success
+ * @retval non-zero if the erom table could not be opened.
+ */
+int
+bhnd_erom_bus_space_open(struct bcma_erom *erom, device_t dev,
+ bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t offset)
{
/* Initialize the EROM reader */
- erom->dev = rman_get_device(r);
- erom->r = r;
+ erom->dev = dev;
+ erom->bst = bst;
+ erom->bsh = bsh;
erom->start = offset + BCMA_EROM_TABLE_START;
erom->offset = 0;
@@ -145,7 +179,8 @@
return (EINVAL);
}
- *entry = bus_read_4(erom->r, erom->start + erom->offset);
+ *entry = bus_space_read_4(erom->bst, erom->bsh,
+ erom->start + erom->offset);
return (0);
}
@@ -300,6 +335,20 @@
}
/**
+ * Seek to the next core entry.
+ *
+ * @param erom EROM read state.
+ * @retval 0 success
+ * @retval ENOENT The end of the EROM table was reached.
+ * @retval non-zero Reading or parsing failed.
+ */
+int
+bcma_erom_seek_next_core(struct bcma_erom *erom)
+{
+ return (erom_seek_next(erom, BCMA_EROM_ENTRY_TYPE_CORE));
+}
+
+/**
* Seek to the requested core entry.
*
* @param erom EROM read state.
@@ -387,6 +436,153 @@
}
/**
+ * Seek to a region record associated with @p core_index.
+ *
+ * @param erom EROM read state.
+ * @param core_index The index of the core record to be searched.
+ * @param port_type The port type to search for.
+ * @param port_num The port number to search for.
+ * @param region_num The region number to search for.
+ * @retval 0 success
+ * @retval ENOENT The requested region was not found.
+ * @retval non-zero Reading or parsing failed.
+ */
+int
+bcma_erom_seek_core_sport_region(struct bcma_erom *erom, u_int core_index,
+ bhnd_port_type port_type, u_int port_num, u_int region_num)
+{
+ struct bcma_erom_core core;
+ uint32_t entry;
+ uint8_t region_port, region_type;
+ bool found;
+ int error;
+
+ if ((error = bcma_erom_seek_core_index(erom, core_index)))
+ return (error);
+
+ if ((error = bcma_erom_parse_core(erom, &core)))
+ return (error);
+
+ /* Skip master ports */
+ for (u_long i = 0; i < core.num_mport; i++) {
+ if ((error = erom_skip_mport(erom)))
+ return (error);
+ }
+
+ /* Seek to the region block for the given port type */
+ found = false;
+ while (1) {
+ bhnd_port_type p_type;
+ uint8_t r_type;
+
+ if ((error = bcma_erom_peek32(erom, &entry)))
+ return (error);
+
+ if (!BCMA_EROM_ENTRY_IS(entry, REGION))
+ return (ENOENT);
+
+ /* Expected region type? */
+ r_type = BCMA_EROM_GET_ATTR(entry, REGION_TYPE);
+ if ((error = erom_region_to_port_type(erom, r_type, &p_type)))
+ return (error);
+
+ if (p_type == port_type) {
+ found = true;
+ break;
+ }
+
+ /* Skip to next entry */
+ if ((error = erom_skip_sport_region(erom)))
+ return (error);
+ }
+
+ if (!found)
+ return (ENOENT);
+
+ /* Found the appropriate port type block; now find the region records
+ * for the given port number */
+ found = false;
+ for (u_int i = 0; i <= port_num; i++) {
+ bhnd_port_type p_type;
+
+ if ((error = bcma_erom_peek32(erom, &entry)))
+ return (error);
+
+ if (!BCMA_EROM_ENTRY_IS(entry, REGION))
+ return (ENOENT);
+
+ /* Fetch the type/port of the first region entry */
+ region_type = BCMA_EROM_GET_ATTR(entry, REGION_TYPE);
+ region_port = BCMA_EROM_GET_ATTR(entry, REGION_PORT);
+
+ /* Have we found the region entries for the desired port? */
+ if (i == port_num) {
+ error = erom_region_to_port_type(erom, region_type,
+ &p_type);
+ if (error)
+ return (error);
+
+ if (p_type == port_type)
+ found = true;
+
+ break;
+ }
+
+ /* Otherwise, seek to next block of region records */
+ while (1) {
+ uint8_t next_type, next_port;
+
+ if ((error = erom_skip_sport_region(erom)))
+ return (error);
+
+ if ((error = bcma_erom_peek32(erom, &entry)))
+ return (error);
+
+ if (!BCMA_EROM_ENTRY_IS(entry, REGION))
+ return (ENOENT);
+
+ next_type = BCMA_EROM_GET_ATTR(entry, REGION_TYPE);
+ next_port = BCMA_EROM_GET_ATTR(entry, REGION_PORT);
+
+ if (next_type != region_type ||
+ next_port != region_port)
+ break;
+ }
+ }
+
+ if (!found)
+ return (ENOENT);
+
+ /* Finally, search for the requested region number */
+ for (u_int i = 0; i <= region_num; i++) {
+ uint8_t next_port, next_type;
+
+ if ((error = bcma_erom_peek32(erom, &entry)))
+ return (error);
+
+ if (!BCMA_EROM_ENTRY_IS(entry, REGION))
+ return (ENOENT);
+
+ /* Check for the end of the region block */
+ next_type = BCMA_EROM_GET_ATTR(entry, REGION_TYPE);
+ next_port = BCMA_EROM_GET_ATTR(entry, REGION_PORT);
+
+ if (next_type != region_type ||
+ next_port != region_port)
+ break;
+
+ if (i == region_num)
+ return (0);
+
+ if ((error = erom_skip_sport_region(erom)))
+ return (error);
+ }
+
+ /* Not found */
+ return (ENOENT);
+}
+
+/**
* Read the next master port descriptor from the EROM table.
*
* @param erom EROM read state.
@@ -492,6 +688,25 @@
}
/**
+ * Convert a bcma_erom_core record to its bhnd_core_info representation.
+ *
+ * @param core EROM core record to convert.
+ * @param core_idx The core index of @p core.
+ * @param core_unit The core unit of @p core.
+ * @param[out] info The populated bhnd_core_info representation.
+ */
+void
+bcma_erom_to_core_info(const struct bcma_erom_core *core, u_int core_idx,
+ int core_unit, struct bhnd_core_info *info)
+{
+ info->vendor = core->vendor;
+ info->device = core->device;
+ info->hwrev = core->rev;
+ info->core_idx = core_idx;
+ info->unit = core_unit;
+}
+
+/**
* Parse all cores descriptors from @p erom and return the array
* in @p cores and the count in @p num_cores. The current EROM read position
* is left unmodified.
@@ -545,7 +760,8 @@
/* Parse all core descriptors */
bcma_erom_reset(erom);
for (u_int i = 0; i < count; i++) {
- struct bcma_erom_core core;
+ struct bcma_erom_core core;
+ int unit;
/* Parse the core */
error = erom_seek_next(erom, BCMA_EROM_ENTRY_TYPE_CORE);
@@ -555,20 +771,17 @@
error = bcma_erom_parse_core(erom, &core);
if (error)
goto cleanup;
-
- /* Convert to a bhnd info record */
- buffer[i].vendor = core.vendor;
- buffer[i].device = core.device;
- buffer[i].hwrev = core.rev;
- buffer[i].core_idx = i;
- buffer[i].unit = 0;
/* Determine the unit number */
+ unit = 0;
for (u_int j = 0; j < i; j++) {
if (buffer[i].vendor == buffer[j].vendor &&
buffer[i].device == buffer[j].device)
- buffer[i].unit++;
+ unit++;
}
+
+ /* Convert to a bhnd info record */
+ bcma_erom_to_core_info(&core, i, unit, &buffer[i]);
}
cleanup:
@@ -585,6 +798,33 @@
return (error);
}
+/**
+ * Map an EROM region type to its corresponding port type.
+ *
+ * @param region_type Region type value.
+ * @param[out] port_type On success, the corresponding port type.
+ */
+static int
+erom_region_to_port_type(struct bcma_erom *erom, uint8_t region_type,
+ bhnd_port_type *port_type)
+{
+ switch (region_type) {
+ case BCMA_EROM_REGION_TYPE_DEVICE:
+ *port_type = BHND_PORT_DEVICE;
+ return (0);
+ case BCMA_EROM_REGION_TYPE_BRIDGE:
+ *port_type = BHND_PORT_BRIDGE;
+ return (0);
+ case BCMA_EROM_REGION_TYPE_MWRAP:
+ case BCMA_EROM_REGION_TYPE_SWRAP:
+ *port_type = BHND_PORT_AGENT;
+ return (0);
+ default:
+ EROM_LOG(erom, "unsupported region type %hhx\n",
+ region_type);
+ return (EINVAL);
+ }
+}
/**
* Register all MMIO region descriptors for the given slave port.
@@ -608,24 +848,10 @@
bhnd_port_type port_type;
error = 0;
-
+
/* Determine the port type for this region type. */
- switch (region_type) {
- case BCMA_EROM_REGION_TYPE_DEVICE:
- port_type = BHND_PORT_DEVICE;
- break;
- case BCMA_EROM_REGION_TYPE_BRIDGE:
- port_type = BHND_PORT_BRIDGE;
- break;
- case BCMA_EROM_REGION_TYPE_MWRAP:
- case BCMA_EROM_REGION_TYPE_SWRAP:
- port_type = BHND_PORT_AGENT;
- break;
- default:
- EROM_LOG(erom, "unsupported region type %hhx\n",
- region_type);
- return (EINVAL);
- }
+ if ((error = erom_region_to_port_type(erom, region_type, &port_type)))
+ return (error);
/* Fetch the list to be populated */
sports = bcma_corecfg_get_port_list(corecfg, port_type);
Index: sys/dev/bhnd/bcma/bcma_eromvar.h
===================================================================
--- sys/dev/bhnd/bcma/bcma_eromvar.h
+++ sys/dev/bhnd/bcma/bcma_eromvar.h
@@ -40,10 +40,11 @@
* EROM read context.
*/
struct bcma_erom {
- device_t dev; /**< EROM parent device */
- struct resource *r; /**< EROM table resource. */
- bus_size_t start; /**< EROM table offset */
- bus_size_t offset; /**< current read offset */
+ device_t dev; /**< EROM parent device */
+ bus_space_tag_t bst; /**< EROM table bus space */
+ bus_space_handle_t bsh; /**< EROM table bus handle */
+ bus_size_t start; /**< EROM table offset */
+ bus_size_t offset; /**< current read offset */
};
/** EROM core descriptor. */
@@ -78,22 +79,34 @@
int bcma_erom_open(struct bcma_erom *erom, struct resource *r,
bus_size_t offset);
+int bhnd_erom_bus_space_open(struct bcma_erom *erom, device_t owner,
+ bus_space_tag_t bst, bus_space_handle_t bsh,
+ bus_size_t offset);
+
int bcma_erom_peek32(struct bcma_erom *erom, uint32_t *entry);
bus_size_t bcma_erom_tell(struct bcma_erom *erom);
void bcma_erom_seek(struct bcma_erom *erom, bus_size_t offset);
void bcma_erom_reset(struct bcma_erom *erom);
+int bcma_erom_seek_next_core(struct bcma_erom *erom);
int bcma_erom_seek_core_index(struct bcma_erom *erom,
u_int core_index);
int bcma_erom_parse_core(struct bcma_erom *erom,
struct bcma_erom_core *core);
+int bcma_erom_seek_core_sport_region(struct bcma_erom *erom,
+ u_int core_index, bhnd_port_type port_type, u_int port_num,
+ u_int region_num);
+
int bcma_erom_parse_mport(struct bcma_erom *erom,
struct bcma_erom_mport *mport);
int bcma_erom_parse_sport_region(struct bcma_erom *erom,
struct bcma_erom_sport_region *region);
+void bcma_erom_to_core_info(const struct bcma_erom_core *core,
+ u_int core_idx, int core_unit, struct bhnd_core_info *info);
+
int bcma_erom_get_core_info(struct bcma_erom *erom,
struct bhnd_core_info **cores,
u_int *num_cores);
Index: sys/dev/bhnd/bhnd_ids.h
===================================================================
--- sys/dev/bhnd/bhnd_ids.h
+++ sys/dev/bhnd/bhnd_ids.h
@@ -535,6 +535,12 @@
#define BHND_CHIPTYPE_UBUS 2 /**< ubus interconnect found in bcm63xx devices */
#define BHND_CHIPTYPE_BCMA_ALT 3 /**< bcma(4) interconnect */
+/** Evaluates to true if @p _type uses a BCMA EROM table */
+#define BHND_CHIPTYPE_HAS_EROM(_type) \
+ ((_type) == BHND_CHIPTYPE_BCMA || \
+ (_type) == BHND_CHIPTYPE_BCMA_ALT || \
+ (_type) == BHND_CHIPTYPE_UBUS)
+
/* Boardflags */
#define BHND_BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */
#define BHND_BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */
Index: sys/dev/bhnd/bhnd_subr.c
===================================================================
--- sys/dev/bhnd/bhnd_subr.c
+++ sys/dev/bhnd/bhnd_subr.c
@@ -834,12 +834,16 @@
bus_size_t chipc_offset, struct bhnd_chipid *result)
{
struct resource *res;
+ bhnd_addr_t enum_addr;
uint32_t reg;
+ uint8_t chip_type;
int error, rid, rtype;
- /* Allocate the ChipCommon window resource and fetch the chipid data */
rid = rs->rid;
rtype = rs->type;
+ error = 0;
+
+ /* Allocate the ChipCommon window resource and fetch the chipid data */
res = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE);
if (res == NULL) {
device_printf(dev,
@@ -849,30 +853,23 @@
/* Fetch the basic chip info */
reg = bus_read_4(res, chipc_offset + CHIPC_ID);
- *result = bhnd_parse_chipid(reg, 0x0);
-
- /* Fetch the enum base address */
- error = 0;
- switch (result->chip_type) {
- case BHND_CHIPTYPE_SIBA:
- result->enum_addr = BHND_DEFAULT_CHIPC_ADDR;
- break;
- case BHND_CHIPTYPE_BCMA:
- case BHND_CHIPTYPE_BCMA_ALT:
- result->enum_addr = bus_read_4(res, chipc_offset +
- CHIPC_EROMPTR);
- break;
- case BHND_CHIPTYPE_UBUS:
- device_printf(dev, "unsupported ubus/bcm63xx chip type");
- error = ENODEV;
- goto cleanup;
- default:
- device_printf(dev, "unknown chip type %hhu\n",
- result->chip_type);
+ chip_type = CHIPC_GET_BITS(reg, CHIPC_ID_BUS);
+
+ /* Fetch the EROMPTR */
+ if (BHND_CHIPTYPE_HAS_EROM(chip_type)) {
+ enum_addr = bus_read_4(res, chipc_offset + CHIPC_EROMPTR);
+ } else if (chip_type == BHND_CHIPTYPE_SIBA) {
+ /* siba(4) uses the ChipCommon base address as the enumeration
+ * address */
+ enum_addr = rman_get_start(res) + chipc_offset;
+ } else {
+ device_printf(dev, "unknown chip type %hhu\n", chip_type);
error = ENODEV;
goto cleanup;
}
+ *result = bhnd_parse_chipid(reg, enum_addr);
+
cleanup:
/* Clean up */
bus_release_resource(dev, rtype, rid, res);
Index: sys/dev/bhnd/cores/chipc/chipcreg.h
===================================================================
--- sys/dev/bhnd/cores/chipc/chipcreg.h
+++ sys/dev/bhnd/cores/chipc/chipcreg.h
@@ -35,6 +35,16 @@
* the core count via the chip identification register. */
#define CHIPC_NCORES_MIN_HWREV(hwrev) ((hwrev) == 4 || (hwrev) >= 6)
+/** Evaluates to true if the given ChipCommon core revision supports
+ * the CHIPC_CAPABILITIES_EXT register */
+#define CHIPC_HWREV_HAS_CAP_EXT(hwrev) ((hwrev) >= 35)
+
+/** Evaluates to true if the chipcommon core (determined from the provided
+ * @p _chipid (CHIPC_ID) register value) provides a pointer to the enumeration
+ * table via CHIPC_EROMPTR */
+#define CHIPC_HAS_EROMPTR(_chipid) \
+ (CHIPC_GET_BITS((_chipid), CHIPC_ID_BUS) != BHND_CHIPTYPE_SIBA)
+
#define CHIPC_GET_FLAG(_value, _flag) (((_value) & _flag) != 0)
#define CHIPC_GET_BITS(_value, _field) \
((_value & _field ## _MASK) >> _field ## _SHIFT)
Index: sys/mips/broadcom/bcm_bcma.c
===================================================================
--- /dev/null
+++ sys/mips/broadcom/bcm_bcma.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * 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 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)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <machine/bus.h>
+
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/bcma/bcma_eromvar.h>
+
+#include "bcm_machdep.h"
+
+#define BCMFC_ERR(fmt, ...) printf("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+
+int
+bcm_find_core_bcma(struct bhnd_chipid *chipid, bhnd_devclass_t devclass,
+ int unit, struct bhnd_core_info *info, uintptr_t *addr)
+{
+ struct bcma_erom erom;
+ struct bcma_erom_core core;
+ struct bcma_erom_sport_region region;
+ bhnd_devclass_t core_class;
+ int error;
+
+ error = bhnd_erom_bus_space_open(&erom, NULL, mips_bus_space_generic,
+ (bus_space_handle_t) BCM_SOC_ADDR(chipid->enum_addr, 0), 0);
+ if (error) {
+ BCMFC_ERR("erom open failed: %d\n", error);
+ return (error);
+ }
+
+ for (u_long core_index = 0; core_index < ULONG_MAX; core_index++) {
+ /* Fetch next core record */
+ if ((error = bcma_erom_seek_next_core(&erom)))
+ return (error);
+
+ if ((error = bcma_erom_parse_core(&erom, &core))) {
+ BCMFC_ERR("core parse failed: %d\n", error);
+ return (error);
+ }
+
+ /* Check for match */
+ core_class = bhnd_find_core_class(core.vendor,
+ core.device);
+ if (core_class != devclass)
+ continue;
+
+ /* Provide the basic core info */
+ if (info != NULL)
+ bcma_erom_to_core_info(&core, core_index, 0, info);
+
+ /* Provide the core's device0.0 port address */
+ error = bcma_erom_seek_core_sport_region(&erom, core_index,
+ BHND_PORT_DEVICE, 0, 0);
+ if (error) {
+ BCMFC_ERR("sport not found: %d\n", error);
+ return (error);
+ }
+
+ if ((error = bcma_erom_parse_sport_region(&erom, ®ion))) {
+ BCMFC_ERR("sport parse failed: %d\n", error);
+ return (error);
+ }
+
+ if (addr != NULL)
+ *addr = region.base_addr;
+
+ return (0);
+ }
+
+ /* Not found */
+ return (ENOENT);
+}
Index: sys/mips/broadcom/bcm_machdep.h
===================================================================
--- /dev/null
+++ sys/mips/broadcom/bcm_machdep.h
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MIPS_BROADCOM_BCM_MACHDEP_H_
+#define _MIPS_BROADCOM_BCM_MACHDEP_H_
+
+#include <machine/cpufunc.h>
+#include <machine/cpuregs.h>
+
+#include <dev/bhnd/bhnd.h>
+
+struct bcm_platform {
+ struct bhnd_chipid id; /**< chip id */
+ struct bhnd_core_info cc_id; /**< chipc core info */
+ uintptr_t cc_addr; /**< chipc core phys address */
+ uint32_t cc_caps; /**< chipc capabilities */
+ uint32_t cc_caps_ext; /**< chipc extended capabilies */
+
+ /* On non-AOB devices, the PMU register block is mapped to chipc;
+ * the pmu_id and pmu_addr values will be copied from cc_id
+ * and cc_addr. */
+ struct bhnd_core_info pmu_id; /**< PMU core info */
+ uintptr_t pmu_addr; /**< PMU core phys address. */
+
+#ifdef CFE
+ int cfe_console; /**< Console handle, or -1 */
+#endif
+};
+
+
+typedef int (bcm_bus_find_core)(struct bhnd_chipid *chipid,
+ bhnd_devclass_t devclass, int unit, struct bhnd_core_info *info,
+ uintptr_t *addr);
+
+struct bcm_platform *bcm_get_platform(void);
+
+bcm_bus_find_core bcm_find_core_default;
+bcm_bus_find_core bcm_find_core_bcma;
+bcm_bus_find_core bcm_find_core_siba;
+
+#define BCM_SOC_ADDR(_addr, _offset) \
+ MIPS_PHYS_TO_KSEG1((_addr) + (_offset))
+
+#define BCM_SOC_READ_4(_addr, _offset) \
+ readl(BCM_SOC_ADDR((_addr), (_offset)))
+#define BCM_SOC_WRITE_4(_addr, _reg, _val) \
+ writel(BCM_SOC_ADDR((_addr), (_offset)), (_val))
+
+#define BCM_CORE_ADDR(_name, _reg) \
+ BCM_SOC_ADDR(bcm_get_platform()->_name, (_reg))
+
+#define BCM_CORE_READ_4(_name, _reg) \
+ readl(BCM_CORE_ADDR(_name, (_reg)))
+#define BCM_CORE_WRITE_4(_name, _reg, _val) \
+ writel(BCM_CORE_ADDR(_name, (_reg)), (_val))
+
+#define BCM_CHIPC_READ_4(_reg) BCM_CORE_READ_4(cc_addr, (_reg))
+#define BCM_CHIPC_WRITE_4(_reg, _val) \
+ BCM_CORE_WRITE_4(cc_addr, (_reg), (_val))
+
+#define BCM_PMU_READ_4(_reg) BCM_CORE_READ_4(pmu_addr, (_reg))
+#define BCM_PMU_WRITE_4(_reg, _val) \
+ BCM_CORE_WRITE_4(pmu_addr, (_reg), (_val))
+
+#endif /* _MIPS_BROADCOM_BCM_MACHDEP_H_ */
Index: sys/mips/broadcom/bcm_machdep.c
===================================================================
--- sys/mips/broadcom/bcm_machdep.c
+++ sys/mips/broadcom/bcm_machdep.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2007 Bruce M. Simpson.
* Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com>
+ * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
*
* All rights reserved.
*
@@ -71,6 +72,18 @@
#include <machine/trap.h>
#include <machine/vmparam.h>
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/bhndreg.h>
+
+#include <dev/bhnd/bcma/bcma_eromvar.h>
+
+#include <dev/bhnd/siba/sibareg.h>
+#include <dev/bhnd/siba/sibavar.h>
+
+#include <dev/bhnd/cores/chipc/chipcreg.h>
+
+#include "bcm_machdep.h"
+#include "bcm_mips_exts.h"
#include "bcm_socinfo.h"
#ifdef CFE
@@ -83,8 +96,150 @@
#define BCM_TRACE(_fmt, ...)
#endif
-extern int *edata;
-extern int *end;
+static int bcm_find_core(struct bhnd_chipid *chipid,
+ bhnd_devclass_t devclass, int unit,
+ struct bhnd_core_info *info, uintptr_t *addr);
+static int bcm_init_platform_data(struct bcm_platform *pdata);
+
+/* Allow bus-specific implementations to override bcm_find_core_(bcma|siba)
+ * symbols, if included in the kernel build */
+__weak_reference(bcm_find_core_default, bcm_find_core_bcma);
+__weak_reference(bcm_find_core_default, bcm_find_core_siba);
+
+extern int *edata;
+extern int *end;
+
+static struct bcm_platform bcm_platform_data;
+static bool bcm_platform_data_avail = false;
+
+struct bcm_platform *
+bcm_get_platform(void)
+{
+ if (!bcm_platform_data_avail)
+ panic("platform data not available");
+
+ return (&bcm_platform_data);
+}
+
+/* Default (no-op) bcm_find_core() implementation. */
+int
+bcm_find_core_default(struct bhnd_chipid *chipid, bhnd_devclass_t devclass,
+ int unit, struct bhnd_core_info *info, uintptr_t *addr)
+{
+ return (ENODEV);
+}
+
+/**
+ * Search @p chipid's enumeration table for a core with @p devclass and
+ * @p unit.
+ *
+ * @param chipid Chip identification data, including the address
+ * of the enumeration table to be searched.
+ * @param devclass Search for a core matching this device class.
+ * @param unit The core's required unit number.
+ * @param[out] info On success, will be populated with the core
+ * info.
+ */
+static int
+bcm_find_core(struct bhnd_chipid *chipid, bhnd_devclass_t devclass, int unit,
+ struct bhnd_core_info *info, uintptr_t *addr)
+{
+ switch (chipid->chip_type) {
+ case BHND_CHIPTYPE_SIBA:
+ return (bcm_find_core_siba(chipid, devclass, unit, info, addr));
+ break;
+ default:
+ if (!BHND_CHIPTYPE_HAS_EROM(chipid->chip_type)) {
+ printf("%s: unsupported chip type: %d\n", __FUNCTION__,
+ chipid->chip_type);
+ return (ENXIO);
+ }
+ return (bcm_find_core_bcma(chipid, devclass, unit, info, addr));
+ }
+}
+
+/**
+ * Populate platform configuration data.
+ */
+static int
+bcm_init_platform_data(struct bcm_platform *pdata)
+{
+ uint32_t reg;
+ bhnd_addr_t enum_addr;
+ long maddr;
+ uint8_t chip_type;
+ bool aob, pmu;
+ int error;
+
+ /* Fetch CFE console handle (if any). Must be initialized before
+ * any calls to printf/early_putc. */
+#ifdef CFE
+ if ((pdata->cfe_console = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE)) < 0)
+ pdata->cfe_console = -1;
+#endif
+
+ /* Fetch bhnd/chipc address */
+ if (resource_long_value("bhnd", 0, "maddr", &maddr) == 0)
+ pdata->cc_addr = (u_long)maddr;
+ else
+ pdata->cc_addr = BHND_DEFAULT_CHIPC_ADDR;
+
+ /* Read chip identifier from ChipCommon */
+ reg = BCM_SOC_READ_4(pdata->cc_addr, CHIPC_ID);
+ chip_type = CHIPC_GET_BITS(reg, CHIPC_ID_BUS);
+
+ if (BHND_CHIPTYPE_HAS_EROM(chip_type))
+ enum_addr = BCM_SOC_READ_4(pdata->cc_addr, CHIPC_EROMPTR);
+ else
+ enum_addr = pdata->cc_addr;
+
+ pdata->id = bhnd_parse_chipid(reg, enum_addr);
+
+ /* Fetch chipc core info and capabilities */
+ pdata->cc_caps = BCM_SOC_READ_4(pdata->cc_addr, CHIPC_CAPABILITIES);
+
+ error = bcm_find_core(&pdata->id, BHND_DEVCLASS_CC, 0, &pdata->cc_id,
+ NULL);
+ if (error) {
+ printf("%s: error locating chipc core: %d", __FUNCTION__,
+ error);
+ return (error);
+ }
+
+ if (CHIPC_HWREV_HAS_CAP_EXT(pdata->cc_id.hwrev)) {
+ pdata->cc_caps_ext = BCM_SOC_READ_4(pdata->cc_addr,
+ CHIPC_CAPABILITIES_EXT);
+ } else {
+ pdata->cc_caps_ext = 0x0;
+ }
+
+ /* Fetch PMU info */
+ pmu = CHIPC_GET_FLAG(pdata->cc_caps, CHIPC_CAP_PMU);
+ aob = CHIPC_GET_FLAG(pdata->cc_caps_ext, CHIPC_CAP2_AOB);
+
+ if (pmu && aob) {
+ /* PMU block mapped to a PMU core on the Always-on-Bus (aob) */
+ error = bcm_find_core(&pdata->id, BHND_DEVCLASS_PMU, 0,
+ &pdata->pmu_id, &pdata->pmu_addr);
+
+ if (error) {
+ printf("%s: error locating pmu core: %d", __FUNCTION__,
+ error);
+ return (error);
+ }
+ } else if (pmu) {
+ /* PMU block mapped to chipc */
+ pdata->pmu_addr = pdata->cc_addr;
+ pdata->pmu_id = pdata->cc_id;
+ } else {
+ /* No PMU */
+ pdata->pmu_addr = 0x0;
+ memset(&pdata->pmu_id, 0, sizeof(pdata->pmu_id));
+ }
+
+ bcm_platform_data_avail = true;
+ return (0);
+}
void
platform_cpu_init()
@@ -162,23 +317,42 @@
void
platform_reset(void)
{
+ bool bcm4785war;
+
printf("bcm::platform_reset()\n");
intr_disable();
-#if defined(CFE)
- cfe_exit(0, 0);
-#else
- /* PMU watchdog reset */
- BCM_WRITE_REG32(BCM_REG_CHIPC_PMUWD_OFFS, 2); /* PMU watchdog */
+#ifdef CFE
+ /* Fall back on CFE if reset requested during platform
+ * data initialization */
+ if (!bcm_platform_data_avail) {
+ cfe_exit(0, 0);
+ while (1);
+ }
#endif
-#if 0
- /* Non-PMU reset
- * XXX: Need chipc capability flags */
- *((volatile uint8_t *)MIPS_PHYS_TO_KSEG1(SENTRY5_EXTIFADR)) = 0x80;
-#endif
-
- for (;;);
+ /* Handle BCM4785-specific behavior */
+ bcm4785war = false;
+ if (bcm_get_platform()->id.chip_id == BHND_CHIPID_BCM4785) {
+ bcm4785war = true;
+
+ /* Switch to async mode */
+ bcm_mips_wr_pllcfg3(MIPS_BCMCFG_PLLCFG3_SM);
+ }
+
+ /* Set watchdog (PMU or ChipCommon) */
+ if (bcm_get_platform()->pmu_addr != 0x0) {
+ BCM_CHIPC_WRITE_4(CHIPC_PMU_WATCHDOG, 1);
+ } else
+ BCM_CHIPC_WRITE_4(CHIPC_WATCHDOG, 1);
+
+ /* BCM4785 */
+ if (bcm4785war) {
+ mips_sync();
+ __asm __volatile("wait");
+ }
+
+ while (1);
}
void
@@ -188,6 +362,7 @@
vm_offset_t kernend;
uint64_t platform_counter_freq;
struct bcm_socinfo *socinfo;
+ int error;
/* clear the BSS and SBSS segments */
kernend = (vm_offset_t)&end;
@@ -213,36 +388,9 @@
cfe_init(a0, a2);
#endif
-#if 0
- /*
- * Probe the Broadcom on-chip PLL clock registers
- * and discover the CPU pipeline clock and bus clock
- * multipliers from this.
- * XXX: Wrong place. You have to ask the ChipCommon
- * or External Interface cores on the SiBa.
- */
- uint32_t busmult, cpumult, refclock, clkcfg1;
-#define S5_CLKCFG1_REFCLOCK_MASK 0x0000001F
-#define S5_CLKCFG1_BUSMULT_MASK 0x000003E0
-#define S5_CLKCFG1_BUSMULT_SHIFT 5
-#define S5_CLKCFG1_CPUMULT_MASK 0xFFFFFC00
-#define S5_CLKCFG1_CPUMULT_SHIFT 10
-
- counter_freq = 100000000; /* XXX */
-
- clkcfg1 = s5_rd_clkcfg1();
- printf("clkcfg1 = 0x%08x\n", clkcfg1);
-
- refclock = clkcfg1 & 0x1F;
- busmult = ((clkcfg1 & 0x000003E0) >> 5) + 1;
- cpumult = ((clkcfg1 & 0xFFFFFC00) >> 10) + 1;
-
- printf("refclock = %u\n", refclock);
- printf("busmult = %u\n", busmult);
- printf("cpumult = %u\n", cpumult);
-
- counter_freq = cpumult * refclock;
-#endif
+ /* Init BCM platform data */
+ if ((error = bcm_init_platform_data(&bcm_platform_data)))
+ panic("bcm_init_platform_data() failed: %d", error);
socinfo = bcm_get_socinfo();
platform_counter_freq = socinfo->cpurate * 1000 * 1000; /* BCM4718 is 480MHz */
@@ -267,20 +415,20 @@
static void
bcm_cfe_eputc(int c)
{
- static int fd = -1;
unsigned char ch;
+ int handle;
ch = (unsigned char) c;
- if (fd == -1) {
- if ((fd = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE)) < 0)
- return;
- }
+ /* bcm_get_platform() cannot be used here, as we may be called
+ * from bcm_init_platform_data(). */
+ if ((handle = bcm_platform_data.cfe_console) < 0)
+ return;
if (ch == '\n')
early_putc('\r');
- while ((cfe_write(fd, &ch, 1)) == 0)
+ while ((cfe_write(bcm_platform_data.cfe_console, &ch, 1)) == 0)
continue;
}
Index: sys/mips/broadcom/bcm_mips_exts.h
===================================================================
--- /dev/null
+++ sys/mips/broadcom/bcm_mips_exts.h
@@ -0,0 +1,190 @@
+/*-
+ * Copyright 2000,2001,2002,2003 Broadcom Corporation.
+ * All rights reserved.
+ *
+ * This file is derived from the sbmips32.h header distributed
+ * by Broadcom with the CFE 1.4.2 sources.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS32 CPU definitions File: sbmips32.h
+ *
+ * This module contains constants and macros specific to the
+ * Broadcom MIPS32 core. In addition to generic MIPS32, it
+ * includes definitions for the MIP32-01 and MIPS3302 OCP cores
+ * for the Silicon Backplane.
+ *
+ *********************************************************************/
+
+#ifndef _MIPS_BROADCOM_BCM_MIPS_EXTS_H_
+#define _MIPS_BROADCOM_BCM_MIPS_EXTS_H_
+
+#include <machine/cpufunc.h>
+
+/*
+ * The following Broadcom Custom CP0 Registers appear in the Broadcom
+ * BMIPS330x MIPS32 core.
+ */
+
+#define MIPS_COP_0_BCMCFG 22
+
+/*
+ * Custom CP0 Accessors
+ */
+
+#define BCM_MIPS_RW32_COP0_SEL(n,r,s) \
+static __inline uint32_t \
+bcm_mips_rd_ ## n(void) \
+{ \
+ int v0; \
+ __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \
+ : [v0] "=&r"(v0)); \
+ mips_barrier(); \
+ return (v0); \
+} \
+static __inline void \
+bcm_mips_wr_ ## n(uint32_t a0) \
+{ \
+ __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \
+ __XSTRING(COP0_SYNC)";" \
+ "nop;" \
+ "nop;" \
+ : \
+ : [a0] "r"(a0)); \
+ mips_barrier(); \
+} struct __hack
+
+BCM_MIPS_RW32_COP0_SEL(pllcfg1, MIPS_COP_0_CONFIG, 1);
+BCM_MIPS_RW32_COP0_SEL(pllcfg2, MIPS_COP_0_CONFIG, 2);
+BCM_MIPS_RW32_COP0_SEL(clksync, MIPS_COP_0_CONFIG, 3);
+BCM_MIPS_RW32_COP0_SEL(pllcfg3, MIPS_COP_0_CONFIG, 4);
+BCM_MIPS_RW32_COP0_SEL(rstcfg, MIPS_COP_0_CONFIG, 5);
+
+/*
+ * Broadcom PLLConfig1 Register (22, select 1)
+ */
+
+/* SoftMIPSPLLCfg */
+#define MIPS_BCMCFG_PLLCFG1_MC_SHIFT 10
+#define MIPS_BCMCFG_PLLCFG1_MC_MASK 0xFFFFFC00
+
+/* SoftISBPLLCfg */
+#define MIPS_BCMCFG_PLLCFG1_BC_SHIFT 5
+#define MIPS_BCMCFG_PLLCFG1_BC_MASK 0x000003E0
+
+/* SoftRefPLLCfg */
+#define MIPS_BCMCFG_PLLCFG1_PC_SHIFT 0
+#define MIPS_BCMCFG_PLLCFG1_PC_MASK 0x0000001F
+
+/*
+ * Broadcom PLLConfig2 Register (22, select 2)
+ */
+
+/* Soft1to1ClkRatio */
+#define MIPS_BCMCFG_PLLCFG2_CR (1<<23)
+
+/* SoftUSBxPLLCfg */
+#define MIPS_BCMCFG_PLLCFG2_UC_SHIFT 15
+#define MIPS_BCMCFG_PLLCFG2_UC_MASK 0x007F8000
+
+/* SoftIDExPLLCfg */
+#define MIPS_BCMCFG_PLLCFG2_IC_SHIFT 7
+#define MIPS_BCMCFG_PLLCFG2_IC_MASK 0x00007F80
+
+#define MIPS_BCMCFG_PLLCFG2_BE (1<<6) /* ISBxSoftCfgEnable */
+#define MIPS_BCMCFG_PLLCFG2_UE (1<<5) /* USBxSoftCfgEnable */
+#define MIPS_BCMCFG_PLLCFG2_IE (1<<4) /* IDExSoftCfgEnable */
+#define MIPS_BCMCFG_PLLCFG2_CA (1<<3) /* CfgActive */
+#define MIPS_BCMCFG_PLLCFG2_CF (1<<2) /* RefSoftCfgEnable */
+#define MIPS_BCMCFG_PLLCFG2_CI (1<<1) /* ISBSoftCfgEnable */
+#define MIPS_BCMCFG_PLLCFG2_CC (1<<0) /* MIPSSoftCfgEnable */
+
+/*
+ * Broadcom ClkSync Register (22, select 3)
+ */
+/* SoftClkCfgHigh */
+#define MIPS_BCMCFG_CLKSYNC_CH_SHIFT 16
+#define MIPS_BCMCFG_CLKSYNC_CH_MASK 0xFFFF0000
+
+/* SoftClkCfgLow */
+#define MIPS_BCMCFG_CLKSYNC_CL_SHIFT 0
+#define MIPS_BCMCFG_CLKSYNC_CL_MASK 0x0000FFFF
+
+/*
+ * Broadcom ISBxPLLConfig3 Register (22, select 4)
+ */
+
+/* AsyncClkRatio */
+#define MIPS_BCMCFG_PLLCFG3_AR_SHIFT 23
+#define MIPS_BCMCFG_PLLCFG3_AR_MASK 0x01800000
+
+#define MIPS_BCMCFG_PLLCFG3_SM (1<<22) /* SyncMode */
+
+/* SoftISBxPLLCfg */
+#define MIPS_BCMCFG_PLLCFG3_IC_SHIFT 0
+#define MIPS_BCMCFG_PLLCFG3_IC_MASK 0x003FFFFF
+
+/*
+ * Broadcom BRCMRstConfig Register (22, select 5)
+ */
+
+#define MIPS_BCMCFG_RSTCFG_SR (1<<18) /* SSMR */
+#define MIPS_BCMCFG_RSTCFG_DT (1<<16) /* BHTD */
+
+/* RStSt */
+#define MIPS_BCMCFG_RSTCFG_RS_SHIFT 8
+#define MIPS_BCMCFG_RSTCFG_RS_MASK 0x00001F00
+#define MIPS_BCMCFG_RST_OTHER 0x00
+#define MIPS_BCMCFG_RST_SH 0x01
+#define MIPS_BCMCFG_RST_SS 0x02
+#define MIPS_BCMCFG_RST_EJTAG 0x04
+#define MIPS_BCMCFG_RST_WDOG 0x08
+#define MIPS_BCMCFG_RST_CRC 0x10
+
+#define MIPS_BCMCFG_RSTCFG_CR (1<<7) /* RStCr */
+
+/* WBMD */
+#define MIPS_BCMCFG_RSTCFG_WD_SHIFT 3
+#define MIPS_BCMCFG_RSTCFG_WD_MASK 0x00000078
+
+#define MIPS_BCMCFG_RSTCFG_SS (1<<2) /* SSR */
+#define MIPS_BCMCFG_RSTCFG_SH (1<<1) /* SHR */
+#define MIPS_BCMCFG_RSTCFG_BR (1<<0) /* BdR */
+
+#endif /* _MIPS_BROADCOM_BCM_MIPS_EXTS_H_ */
Index: sys/mips/broadcom/bcm_siba.c
===================================================================
--- sys/mips/broadcom/bcm_siba.c
+++ sys/mips/broadcom/bcm_siba.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com>
+ * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
*
* All rights reserved.
*
@@ -25,36 +25,40 @@
* SUCH DAMAGE.
*/
-/*
- * $FreeBSD$
- */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/bhndreg.h>
+
+#include <dev/bhnd/siba/sibareg.h>
+#include <dev/bhnd/siba/sibavar.h>
+
+#include "bcm_machdep.h"
+
+int
+bcm_find_core_siba(struct bhnd_chipid *chipid, bhnd_devclass_t devclass,
+ int unit, struct bhnd_core_info *info, uintptr_t *addr)
+{
+ struct siba_core_id scid;
+ uintptr_t cc_addr;
+ uint32_t idhigh, idlow;
+
+ /* No other cores are required during early boot on siba(4) devices */
+ if (devclass != BHND_DEVCLASS_CC || unit != 0)
+ return (ENOENT);
+
+ cc_addr = chipid->enum_addr;
+ idhigh = BCM_SOC_READ_4(cc_addr, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
+ idlow = BCM_SOC_READ_4(cc_addr, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
+
+ scid = siba_parse_core_id(idhigh, idlow, 0, 0);
+
+ if (info != NULL)
+ *info = scid.core_info;
+
+ if (addr != NULL)
+ *addr = cc_addr;
-#ifndef _MIPS_BROADCOM_BCM_SOCINFO_H_
-#define _MIPS_BROADCOM_BCM_SOCINFO_H_
-
-#include <machine/cpuregs.h>
-
-struct bcm_socinfo {
- uint32_t id;
- uint32_t cpurate; /* in MHz */
- uint32_t uartrate; /* in Hz */
- int double_count;
-};
-
-struct bcm_socinfo* bcm_get_socinfo_by_socid(uint32_t key);
-struct bcm_socinfo* bcm_get_socinfo(void);
-
-#define BCM_SOCADDR 0x18000000
-#define BCM_REG_CHIPC_ID 0x0
-#define BCM_REG_CHIPC_UART 0x300
-#define BCM_REG_CHIPC_PMUWD_OFFS 0x634
-#define BCM_SOCREG(reg) \
- MIPS_PHYS_TO_KSEG1((BCM_SOCADDR + (reg)))
-#define BCM_READ_REG32(reg) \
- *((volatile uint32_t *)BCM_SOCREG(reg))
-#define BCM_WRITE_REG32(reg, value) \
- do { \
- writel((void*)BCM_SOCREG((reg)),value); \
- } while (0);
-
-#endif /* _MIPS_BROADCOM_BCM_SOCINFO_H_ */
+ return (0);
+}
Index: sys/mips/broadcom/bcm_socinfo.h
===================================================================
--- sys/mips/broadcom/bcm_socinfo.h
+++ sys/mips/broadcom/bcm_socinfo.h
@@ -44,17 +44,4 @@
struct bcm_socinfo* bcm_get_socinfo_by_socid(uint32_t key);
struct bcm_socinfo* bcm_get_socinfo(void);
-#define BCM_SOCADDR 0x18000000
-#define BCM_REG_CHIPC_ID 0x0
-#define BCM_REG_CHIPC_UART 0x300
-#define BCM_REG_CHIPC_PMUWD_OFFS 0x634
-#define BCM_SOCREG(reg) \
- MIPS_PHYS_TO_KSEG1((BCM_SOCADDR + (reg)))
-#define BCM_READ_REG32(reg) \
- *((volatile uint32_t *)BCM_SOCREG(reg))
-#define BCM_WRITE_REG32(reg, value) \
- do { \
- writel((void*)BCM_SOCREG((reg)),value); \
- } while (0);
-
#endif /* _MIPS_BROADCOM_BCM_SOCINFO_H_ */
Index: sys/mips/broadcom/bcm_socinfo.c
===================================================================
--- sys/mips/broadcom/bcm_socinfo.c
+++ sys/mips/broadcom/bcm_socinfo.c
@@ -29,6 +29,10 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+
+#include <dev/bhnd/cores/chipc/chipcreg.h>
+
+#include "bcm_machdep.h"
#include "bcm_socinfo.h"
/* found on https://wireless.wiki.kernel.org/en/users/drivers/b43/soc */
@@ -85,7 +89,7 @@
* --------------------------------------------------------------
*/
- socid = BCM_READ_REG32(BCM_REG_CHIPC_ID) & 0x00FFFFFF;
+ socid = BCM_CHIPC_READ_4(CHIPC_ID) & 0x00FFFFFF;
socinfo = bcm_get_socinfo_by_socid(socid);
return (socinfo != NULL) ? socinfo : &BCM_DEFAULT_SOCINFO;
}
Index: sys/mips/broadcom/files.broadcom
===================================================================
--- sys/mips/broadcom/files.broadcom
+++ sys/mips/broadcom/files.broadcom
@@ -4,7 +4,9 @@
# for USB 1.1 OHCI, Ethernet and IPSEC cores
# which are believed to be devices we have drivers for
# which just need to be tweaked for attachment to an BHND system bus.
+mips/broadcom/bcm_bcma.c optional bcma_nexus bcma
mips/broadcom/bcm_machdep.c standard
+mips/broadcom/bcm_siba.c optional siba_nexus siba
mips/mips/tick.c standard
mips/mips/mips_pic.c standard
kern/subr_intr.c standard
Index: sys/mips/broadcom/uart_cpu_chipc.c
===================================================================
--- sys/mips/broadcom/uart_cpu_chipc.c
+++ sys/mips/broadcom/uart_cpu_chipc.c
@@ -45,14 +45,15 @@
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
-#include "bcm_socinfo.h"
-
#ifdef CFE
#include <dev/cfe/cfe_api.h>
#include <dev/cfe/cfe_ioctl.h>
#include <dev/cfe/cfe_error.h>
#endif
+#include "bcm_machdep.h"
+#include "bcm_socinfo.h"
+
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
@@ -78,7 +79,8 @@
di->ops = uart_getops(chipc_uart_class);
di->bas.chan = 0;
di->bas.bst = uart_bus_space_mem;
- di->bas.bsh = (bus_space_handle_t) BCM_SOCREG(CHIPC_UART(uart));
+ di->bas.bsh = (bus_space_handle_t) BCM_CORE_ADDR(cc_addr,
+ CHIPC_UART(uart));
di->bas.regshft = 0;
di->bas.rclk = socinfo->uartrate; /* in Hz */
di->baudrate = baudrate;
@@ -112,7 +114,7 @@
return (ENXIO);
/* Fetch device handle */
- fd = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+ fd = bcm_get_platform()->cfe_console;
if (fd < 0)
return (ENXIO);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 17, 2:57 PM (58 m, 44 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23835425
Default Alt Text
D7539.id19371.diff (41 KB)
Attached To
Mode
D7539: [mips/broadcom] Implement early boot hardware probing and generic platform_reset() support.
Attached
Detach File
Event Timeline
Log In to Comment