aboutsummaryrefslogtreecommitdiff
path: root/sys/mips/broadcom
diff options
context:
space:
mode:
authorLandon J. Fuller <landonf@FreeBSD.org>2016-08-26 20:16:02 +0000
committerLandon J. Fuller <landonf@FreeBSD.org>2016-08-26 20:16:02 +0000
commitcb4abe62ba33151c0f84f48d9fe9b919e2f982f3 (patch)
tree40c59f1f8a03ffd86e288bea3bbcb3e3233fdb5b /sys/mips/broadcom
parentffe1b10d956ef5aefaf0e362ae6b056e07ad04a5 (diff)
downloadsrc-cb4abe62ba33151c0f84f48d9fe9b919e2f982f3.tar.gz
src-cb4abe62ba33151c0f84f48d9fe9b919e2f982f3.zip
[mips/broadcom] Generic platform_reset() support.
This adds support for performing platform_reset() on all supported devices, using early boot enumeration of chipc capabilities and available cores. - Added Broadcom-specific MIPS CP0 register definitions used by BCM4785-specific reset handling. - Added a bcm_platform structure for tracking chipc/pmu/cfe platform data. - Extended the BCMA EROM API to support early boot lookup of core info (including port/region mappings). - Extended platform_reset() to support PMU, PMU+AOB, and non-PMU devices. Reviewed by: mizhka Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D7539
Notes
Notes: svn path=/head/; revision=304859
Diffstat (limited to 'sys/mips/broadcom')
-rw-r--r--sys/mips/broadcom/bcm_bcma.c100
-rw-r--r--sys/mips/broadcom/bcm_machdep.c248
-rw-r--r--sys/mips/broadcom/bcm_machdep.h93
-rw-r--r--sys/mips/broadcom/bcm_mips_exts.h190
-rw-r--r--sys/mips/broadcom/bcm_siba.c64
-rw-r--r--sys/mips/broadcom/bcm_socinfo.c6
-rw-r--r--sys/mips/broadcom/bcm_socinfo.h13
-rw-r--r--sys/mips/broadcom/files.broadcom2
-rw-r--r--sys/mips/broadcom/uart_cpu_chipc.c10
9 files changed, 658 insertions, 68 deletions
diff --git a/sys/mips/broadcom/bcm_bcma.c b/sys/mips/broadcom/bcm_bcma.c
new file mode 100644
index 000000000000..08ff97a40e79
--- /dev/null
+++ b/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, &region))) {
+ BCMFC_ERR("sport parse failed: %d\n", error);
+ return (error);
+ }
+
+ if (addr != NULL)
+ *addr = region.base_addr;
+
+ return (0);
+ }
+
+ /* Not found */
+ return (ENOENT);
+}
diff --git a/sys/mips/broadcom/bcm_machdep.c b/sys/mips/broadcom/bcm_machdep.c
index 58b268cad694..f03c72b6cebf 100644
--- a/sys/mips/broadcom/bcm_machdep.c
+++ b/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 @@ __FBSDID("$FreeBSD$");
#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 @@ __FBSDID("$FreeBSD$");
#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 @@ mips_init(void)
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 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
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 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
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 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
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(handle, &ch, 1)) == 0)
continue;
}
diff --git a/sys/mips/broadcom/bcm_machdep.h b/sys/mips/broadcom/bcm_machdep.h
new file mode 100644
index 000000000000..1a33c61788be
--- /dev/null
+++ b/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_ */
diff --git a/sys/mips/broadcom/bcm_mips_exts.h b/sys/mips/broadcom/bcm_mips_exts.h
new file mode 100644
index 000000000000..582fb8b3068f
--- /dev/null
+++ b/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_ */
diff --git a/sys/mips/broadcom/bcm_siba.c b/sys/mips/broadcom/bcm_siba.c
new file mode 100644
index 000000000000..ff8fa09a564c
--- /dev/null
+++ b/sys/mips/broadcom/bcm_siba.c
@@ -0,0 +1,64 @@
+/*-
+ * 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 <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;
+
+ return (0);
+}
diff --git a/sys/mips/broadcom/bcm_socinfo.c b/sys/mips/broadcom/bcm_socinfo.c
index 9ea41a1e47b9..fba5d0e9e056 100644
--- a/sys/mips/broadcom/bcm_socinfo.c
+++ b/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 @@ bcm_get_socinfo(void)
* --------------------------------------------------------------
*/
- 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;
}
diff --git a/sys/mips/broadcom/bcm_socinfo.h b/sys/mips/broadcom/bcm_socinfo.h
index cdac486438c0..d4f34a8207eb 100644
--- a/sys/mips/broadcom/bcm_socinfo.h
+++ b/sys/mips/broadcom/bcm_socinfo.h
@@ -44,17 +44,4 @@ struct bcm_socinfo {
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_ */
diff --git a/sys/mips/broadcom/files.broadcom b/sys/mips/broadcom/files.broadcom
index 10564d982c13..aa784b4dda6d 100644
--- a/sys/mips/broadcom/files.broadcom
+++ b/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
diff --git a/sys/mips/broadcom/uart_cpu_chipc.c b/sys/mips/broadcom/uart_cpu_chipc.c
index 008906598b95..91548a424a0a 100644
--- a/sys/mips/broadcom/uart_cpu_chipc.c
+++ b/sys/mips/broadcom/uart_cpu_chipc.c
@@ -45,14 +45,15 @@ __FBSDID("$FreeBSD$");
#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 @@ uart_cpu_init(struct uart_devinfo *di, u_int uart, int baudrate)
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 @@ uart_getenv_cfe(int devtype, struct uart_devinfo *di)
return (ENXIO);
/* Fetch device handle */
- fd = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+ fd = bcm_get_platform()->cfe_console;
if (fd < 0)
return (ENXIO);