diff options
author | Landon J. Fuller <landonf@FreeBSD.org> | 2016-08-26 20:16:02 +0000 |
---|---|---|
committer | Landon J. Fuller <landonf@FreeBSD.org> | 2016-08-26 20:16:02 +0000 |
commit | cb4abe62ba33151c0f84f48d9fe9b919e2f982f3 (patch) | |
tree | 40c59f1f8a03ffd86e288bea3bbcb3e3233fdb5b /sys/mips/broadcom | |
parent | ffe1b10d956ef5aefaf0e362ae6b056e07ad04a5 (diff) | |
download | src-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.c | 100 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_machdep.c | 248 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_machdep.h | 93 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_mips_exts.h | 190 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_siba.c | 64 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_socinfo.c | 6 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_socinfo.h | 13 | ||||
-rw-r--r-- | sys/mips/broadcom/files.broadcom | 2 | ||||
-rw-r--r-- | sys/mips/broadcom/uart_cpu_chipc.c | 10 |
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, ®ion))) { + 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); |