diff options
author | Landon J. Fuller <landonf@FreeBSD.org> | 2016-08-27 00:06:20 +0000 |
---|---|---|
committer | Landon J. Fuller <landonf@FreeBSD.org> | 2016-08-27 00:06:20 +0000 |
commit | eb175e8bfb9b2f7616d27148d917cd41cd6b1767 (patch) | |
tree | f6cebf0eb4317f2ea46eb2f8acce05140ea8695c /sys/mips/broadcom | |
parent | f90f4b65322a1d76ae934c5aa9e2bfbc2d9f5477 (diff) | |
download | src-eb175e8bfb9b2f7616d27148d917cd41cd6b1767.tar.gz src-eb175e8bfb9b2f7616d27148d917cd41cd6b1767.zip |
[mips/broadcom]: Replace static frequency table with generic PMU clock
handling.
- Extended PWRCTL/PMU APIs to support querying clock frequency during very
early boot, prior to bus attach.
- Implement generic PMU-based calculation of UART rclk values.
- Replaced use of static frequency tables (bcm_socinfo) with
runtime-determined values.
Approved by: adrian (mentor)
Differential Revision: https://reviews.freebsd.org/D7552
Notes
Notes:
svn path=/head/; revision=304871
Diffstat (limited to 'sys/mips/broadcom')
-rw-r--r-- | sys/mips/broadcom/bcm_machdep.c | 35 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_machdep.h | 54 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_pmu.c | 298 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_socinfo.c | 95 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_socinfo.h | 47 | ||||
-rw-r--r-- | sys/mips/broadcom/files.broadcom | 2 | ||||
-rw-r--r-- | sys/mips/broadcom/uart_bus_chipc.c | 10 | ||||
-rw-r--r-- | sys/mips/broadcom/uart_cpu_chipc.c | 10 |
8 files changed, 363 insertions, 188 deletions
diff --git a/sys/mips/broadcom/bcm_machdep.c b/sys/mips/broadcom/bcm_machdep.c index 2d288a15ecd8..9a241b898e04 100644 --- a/sys/mips/broadcom/bcm_machdep.c +++ b/sys/mips/broadcom/bcm_machdep.c @@ -85,7 +85,6 @@ __FBSDID("$FreeBSD$"); #include "bcm_machdep.h" #include "bcm_mips_exts.h" -#include "bcm_socinfo.h" #ifdef CFE #include <dev/cfe/cfe_api.h> @@ -238,6 +237,16 @@ bcm_init_platform_data(struct bcm_platform *pdata) memset(&pdata->pmu_id, 0, sizeof(pdata->pmu_id)); } + if (pmu) { + error = bhnd_pmu_query_init(&pdata->pmu, NULL, pdata->id, + &bcm_pmu_soc_io, pdata); + if (error) { + printf("%s: bhnd_pmu_query_init() failed: %d\n", + __FUNCTION__, error); + return (error); + } + } + bcm_platform_data_avail = true; return (0); } @@ -318,7 +327,8 @@ mips_init(void) void platform_reset(void) { - bool bcm4785war; + struct bcm_platform *bp; + bool bcm4785war; printf("bcm::platform_reset()\n"); intr_disable(); @@ -332,9 +342,11 @@ platform_reset(void) } #endif - /* Handle BCM4785-specific behavior */ + bp = bcm_get_platform(); bcm4785war = false; - if (bcm_get_platform()->id.chip_id == BHND_CHIPID_BCM4785) { + + /* Handle BCM4785-specific behavior */ + if (bp->id.chip_id == BHND_CHIPID_BCM4785) { bcm4785war = true; /* Switch to async mode */ @@ -342,10 +354,10 @@ platform_reset(void) } /* Set watchdog (PMU or ChipCommon) */ - if (bcm_get_platform()->pmu_addr != 0x0) { - BCM_CHIPC_WRITE_4(BHND_PMU_WATCHDOG, 1); + if (bp->pmu_addr != 0x0) { + BCM_PMU_WRITE_4(bp, BHND_PMU_WATCHDOG, 1); } else - BCM_CHIPC_WRITE_4(CHIPC_WATCHDOG, 1); + BCM_CHIPC_WRITE_4(bp, CHIPC_WATCHDOG, 1); /* BCM4785 */ if (bcm4785war) { @@ -362,7 +374,6 @@ 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 */ @@ -393,16 +404,16 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, 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 */ + platform_counter_freq = bcm_get_cpufreq(bcm_get_platform()); - mips_timer_early_init(platform_counter_freq); + /* CP0 ticks every two cycles */ + mips_timer_early_init(platform_counter_freq / 2); cninit(); mips_init(); - mips_timer_init_params(platform_counter_freq, socinfo->double_count); + mips_timer_init_params(platform_counter_freq, 1); } /* diff --git a/sys/mips/broadcom/bcm_machdep.h b/sys/mips/broadcom/bcm_machdep.h index 1a33c61788be..d8d551f3ac1a 100644 --- a/sys/mips/broadcom/bcm_machdep.h +++ b/sys/mips/broadcom/bcm_machdep.h @@ -36,6 +36,13 @@ #include <machine/cpuregs.h> #include <dev/bhnd/bhnd.h> +#include <dev/bhnd/cores/pmu/bhnd_pmuvar.h> + +extern const struct bhnd_pmu_io bcm_pmu_soc_io; + +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 { struct bhnd_chipid id; /**< chip id */ @@ -48,46 +55,53 @@ struct bcm_platform { * 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. */ + uintptr_t pmu_addr; /**< PMU core phys address, or + 0x0 if no PMU */ + + struct bhnd_pmu_query pmu; /**< PMU query instance */ #ifdef CFE int cfe_console; /**< Console handle, or -1 */ #endif }; +struct bcm_platform *bcm_get_platform(void); -typedef int (bcm_bus_find_core)(struct bhnd_chipid *chipid, - bhnd_devclass_t devclass, int unit, struct bhnd_core_info *info, - uintptr_t *addr); +uint64_t bcm_get_cpufreq(struct bcm_platform *bp); +uint64_t bcm_get_sifreq(struct bcm_platform *bp); +uint64_t bcm_get_alpfreq(struct bcm_platform *bp); +uint64_t bcm_get_ilpfreq(struct bcm_platform *bp); -struct bcm_platform *bcm_get_platform(void); +u_int bcm_get_uart_rclk(struct bcm_platform *bp); 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) \ +#define BCM_SOC_ADDR(_addr, _offset) \ MIPS_PHYS_TO_KSEG1((_addr) + (_offset)) -#define BCM_SOC_READ_4(_addr, _offset) \ +#define BCM_SOC_READ_4(_addr, _offset) \ readl(BCM_SOC_ADDR((_addr), (_offset))) -#define BCM_SOC_WRITE_4(_addr, _reg, _val) \ +#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_ADDR(_bp, _name, _reg) \ + BCM_SOC_ADDR(_bp->_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_CORE_READ_4(_bp, _name, _reg) \ + readl(BCM_CORE_ADDR(_bp, _name, (_reg))) +#define BCM_CORE_WRITE_4(_bp, _name, _reg, _val) \ + writel(BCM_CORE_ADDR(_bp, _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_CHIPC_READ_4(_bp, _reg) \ + BCM_CORE_READ_4(_bp, cc_addr, (_reg)) +#define BCM_CHIPC_WRITE_4(_bp, _reg, _val) \ + BCM_CORE_WRITE_4(_bp, 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)) +#define BCM_PMU_READ_4(_bp, _reg) \ + BCM_CORE_READ_4(_bp, pmu_addr, (_reg)) +#define BCM_PMU_WRITE_4(_bp, _reg, _val) \ + BCM_CORE_WRITE_4(_bp, pmu_addr, (_reg), (_val)) #endif /* _MIPS_BROADCOM_BCM_MACHDEP_H_ */ diff --git a/sys/mips/broadcom/bcm_pmu.c b/sys/mips/broadcom/bcm_pmu.c new file mode 100644 index 000000000000..9ded7cc3840f --- /dev/null +++ b/sys/mips/broadcom/bcm_pmu.c @@ -0,0 +1,298 @@ +/*- + * 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/cores/chipc/chipcreg.h> + +#include <dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctlvar.h> + +#include <dev/bhnd/cores/pmu/bhnd_pmureg.h> +#include <dev/bhnd/cores/pmu/bhnd_pmuvar.h> + +#include "bcm_machdep.h" + +static struct bhnd_pmu_query *bcm_get_pmu(struct bcm_platform *bp); +static bool bcm_has_pmu(struct bcm_platform *bp); + +static uint32_t bcm_pmu_read4(bus_size_t reg, void *ctx); +static void bcm_pmu_write4(bus_size_t reg, uint32_t val, + void *ctx); +static uint32_t bcm_pmu_read_chipst(void *ctx); + +const struct bhnd_pmu_io bcm_pmu_soc_io = { + .rd4 = bcm_pmu_read4, + .wr4 = bcm_pmu_write4, + .rd_chipst = bcm_pmu_read_chipst +}; + +/** + * Supported UART clock sources. + */ +typedef enum { + BCM_UART_RCLK_PLL_T1 = 0, /**< UART uses PLL m2 (mii/uart/mipsref) with no divisor */ + BCM_UART_RCLK_ALP = 1, /**< UART uses ALP rclk with no divisor */ + BCM_UART_RCLK_EXT = 2, /**< UART uses 1.8423 MHz external clock */ + BCM_UART_RCLK_SI = 3, /**< UART uses backplane clock with divisor of two */ + BCM_UART_RCLK_FIXED = 4, /**< UART uses fixed 88Mhz backplane clock with a divisor of 48 */ +} bcm_uart_clksrc; + +/** + * UART clock configuration. + */ +struct bcm_uart_clkcfg { + bcm_uart_clksrc src; /**< clock source */ + uint32_t div; /**< clock divisor */ + uint32_t freq; /**< clock frequency (Hz) */ +}; + +#define BCM_UART_RCLK_PLL_T1_DIV 1 +#define BCM_UART_RCLK_ALP_DIV 1 +#define BCM_UART_RCLK_EXT_HZ 1842300 /* 1.8423MHz */ +#define BCM_UART_RCLK_EXT_DIV 1 +#define BCM_UART_RCLK_FIXED_HZ 88000000 /* 88MHz */ +#define BCM_UART_RCLK_FIXED_DIV 48 + +/* Fetch PLL type from ChipCommon capability flags */ +#define BCM_PMU_PLL_TYPE(_bp) \ + CHIPC_GET_BITS(_bp->cc_caps, CHIPC_CAP_PLL) + +/** + * Return the PMU instance, or NULL if no PMU. + */ +static struct bhnd_pmu_query * +bcm_get_pmu(struct bcm_platform *bp) +{ + if (!bcm_has_pmu(bp)) + return (NULL); + return (&bp->pmu); +} + +/** + * Return true if a PMU is available, false otherwise. + */ +static bool +bcm_has_pmu(struct bcm_platform *bp) +{ + return (bp->pmu_addr != 0); +} + +/** + * Determine the UART clock source for @p bp and return the + * corresponding clock configuration, if any. + */ +static struct bcm_uart_clkcfg +bcm_get_uart_clkcfg(struct bcm_platform *bp) +{ + struct bcm_uart_clkcfg cfg; + struct bhnd_core_info *cc_id; + + cc_id = &bp->cc_id; + + /* These tests are ordered by precedence. */ + + /* PLL M2 clock source? */ + if (!bcm_has_pmu(bp) && BCM_PMU_PLL_TYPE(bp) == CHIPC_PLL_TYPE1) { + uint32_t n, m; + + n = BCM_CHIPC_READ_4(bp, CHIPC_CLKC_N); + m = BCM_CHIPC_READ_4(bp, CHIPC_CLKC_M2); + + cfg = (struct bcm_uart_clkcfg) { + BCM_UART_RCLK_PLL_T1, + BCM_UART_RCLK_PLL_T1_DIV, + bhnd_pwrctl_clock_rate(BCM_PMU_PLL_TYPE(bp), n, m) + }; + + return (cfg); + } + + /* ALP clock source? */ + if (cc_id->hwrev != 15 && cc_id->hwrev >= 11) { + cfg = (struct bcm_uart_clkcfg) { + BCM_UART_RCLK_ALP, + BCM_UART_RCLK_ALP_DIV, + bcm_get_alpfreq(bp) + }; + return (cfg); + } + + /* External clock? */ + if (CHIPC_HWREV_HAS_CORECTRL(cc_id->hwrev)) { + uint32_t corectrl, uclksel; + bool uintclk0; + + /* Fetch UART clock support flag */ + uclksel = CHIPC_GET_BITS(bp->cc_caps, CHIPC_CAP_UCLKSEL); + + /* Is UART using internal clock? */ + corectrl = BCM_CHIPC_READ_4(bp, CHIPC_CORECTRL); + uintclk0 = CHIPC_GET_FLAG(corectrl, CHIPC_UARTCLKO); + + if (uintclk0 && uclksel == CHIPC_CAP_UCLKSEL_UINTCLK) { + cfg = (struct bcm_uart_clkcfg) { + BCM_UART_RCLK_EXT, + BCM_UART_RCLK_EXT_DIV, + BCM_UART_RCLK_EXT_HZ + }; + return (cfg); + } + } + + /* UART uses backplane clock? */ + if (cc_id->hwrev == 15 || (cc_id->hwrev >= 3 && cc_id->hwrev <= 10)) { + cfg = (struct bcm_uart_clkcfg) { + BCM_UART_RCLK_SI, + BCM_CHIPC_READ_4(bp, CHIPC_CLKDIV) & CHIPC_CLKD_UART, + bcm_get_sifreq(bp) + }; + + return (cfg); + } + + /* UART uses fixed clock? */ + if (cc_id->hwrev <= 2) { + cfg = (struct bcm_uart_clkcfg) { + BCM_UART_RCLK_FIXED, + BCM_UART_RCLK_FIXED_DIV, + BCM_UART_RCLK_FIXED_HZ + }; + + return (cfg); + } + + /* All cases must be accounted for above */ + panic("unreachable - no clock config"); +} + +/** + * Return the UART reference clock frequency (in Hz). + */ +u_int +bcm_get_uart_rclk(struct bcm_platform *bp) +{ + struct bcm_uart_clkcfg cfg; + + cfg = bcm_get_uart_clkcfg(bp); + return (cfg.freq / cfg.div); +} + +/** ALP clock frequency (in Hz) */ +uint64_t +bcm_get_alpfreq(struct bcm_platform *bp) { + if (!bcm_has_pmu(bp)) + panic("%s requires PMU\n", __FUNCTION__); + + return (bhnd_pmu_alp_clock(bcm_get_pmu(bp))); +} + +/** ILP clock frequency (in Hz) */ +uint64_t +bcm_get_ilpfreq(struct bcm_platform *bp) { + if (!bcm_has_pmu(bp)) + panic("%s requires PMU\n", __FUNCTION__); + + return (bhnd_pmu_ilp_clock(bcm_get_pmu(bp))); +} + +/** CPU clock frequency (in Hz) */ +uint64_t +bcm_get_cpufreq(struct bcm_platform *bp) +{ + uint32_t fixed_hz; + uint32_t n, m; + bus_size_t mreg; + uint8_t pll_type; + + /* PMU support */ + if (bcm_has_pmu(bp)) + return (bhnd_pmu_cpu_clock(bcm_get_pmu(bp))); + + /* + * PWRCTL support + */ + pll_type = CHIPC_GET_BITS(bp->cc_caps, CHIPC_CAP_PLL); + mreg = bhnd_pwrctl_cpu_clkreg_m(&bp->id, pll_type, &fixed_hz); + if (mreg == 0) + return (fixed_hz); + + n = BCM_CHIPC_READ_4(bp, CHIPC_CLKC_N); + m = BCM_CHIPC_READ_4(bp, mreg); + + return (bhnd_pwrctl_cpu_clock_rate(&bp->id, pll_type, n, m)); + +} + +/** Backplane clock frequency (in Hz) */ +uint64_t +bcm_get_sifreq(struct bcm_platform *bp) +{ + uint32_t fixed_hz; + uint32_t n, m; + bus_size_t mreg; + uint8_t pll_type; + + /* PMU support */ + if (bcm_has_pmu(bp)) + return (bhnd_pmu_si_clock(bcm_get_pmu(bp))); + + /* + * PWRCTL support + */ + pll_type = CHIPC_GET_BITS(bp->cc_caps, CHIPC_CAP_PLL); + mreg = bhnd_pwrctl_si_clkreg_m(&bp->id, pll_type, &fixed_hz); + if (mreg == 0) + return (fixed_hz); + + n = BCM_CHIPC_READ_4(bp, CHIPC_CLKC_N); + m = BCM_CHIPC_READ_4(bp, mreg); + + return (bhnd_pwrctl_si_clock_rate(&bp->id, pll_type, n, m)); +} + + +static uint32_t +bcm_pmu_read4(bus_size_t reg, void *ctx) { + struct bcm_platform *bp = ctx; + return (readl(BCM_SOC_ADDR(bp->pmu_addr, reg))); +} + +static void +bcm_pmu_write4(bus_size_t reg, uint32_t val, void *ctx) { + struct bcm_platform *bp = ctx; + writel(BCM_SOC_ADDR(bp->pmu_addr, reg), val); +} + +static uint32_t +bcm_pmu_read_chipst(void *ctx) +{ + struct bcm_platform *bp = ctx; + return (readl(BCM_SOC_ADDR(bp->cc_addr, CHIPC_CHIPST))); +} diff --git a/sys/mips/broadcom/bcm_socinfo.c b/sys/mips/broadcom/bcm_socinfo.c deleted file mode 100644 index fba5d0e9e056..000000000000 --- a/sys/mips/broadcom/bcm_socinfo.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com> - * - * 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/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 */ -struct bcm_socinfo bcm_socinfos[] = { - {0x00005300, 600, 25000000, 1}, /* BCM4706 to check */ - {0x0022B83A, 300, 20000000, 1}, /* BCM4716B0 ASUS RT-N12 */ - {0x00914716, 354, 20000000, 1}, /* BCM4717A1 to check */ - {0x00A14716, 480, 20000000, 1}, /* BCM4718A1 ASUS RT-N16 */ - {0x00435356, 300, 25000000, 1}, /* BCM5356A1 (RT-N10, WNR1000v3) */ - {0x00825357, 500, 20000000, 1}, /* BCM5358UB0 ASUS RT-N53A1 */ - {0x00845357, 300, 20000000, 1}, /* BCM5357B0 to check */ - {0x00945357, 500, 20000000, 1}, /* BCM5358 */ - {0x00A45357, 500, 20000000, 1}, /* BCM47186B0 Tenda N60 */ - {0x0085D144, 300, 20000000, 1}, /* BCM5356C0 */ - {0x00B5D144, 300, 20000000, 1}, /* BCM5357C0 */ - {0x00015365, 200, 0, 1}, /* BCM5365 */ - {0,0,0} -}; - -/* Most popular BCM SoC info */ -struct bcm_socinfo BCM_DEFAULT_SOCINFO = {0x0, 300, 20000000, 0}; - -struct bcm_socinfo* -bcm_get_socinfo_by_socid(uint32_t key) -{ - struct bcm_socinfo* start; - - if(!key) - return (NULL); - - for(start = bcm_socinfos; start->id > 0; start++) - if(start->id == key) - return (start); - - return (NULL); -} - -struct bcm_socinfo* -bcm_get_socinfo(void) -{ - uint32_t socid; - struct bcm_socinfo *socinfo; - - /* - * We need Chip ID + Revision + Package - * -------------------------------------------------------------- - * | Mask | Usage | - * -------------------------------------------------------------- - * | 0x0000FFFF | Chip ID | - * | 0x000F0000 | Chip Revision | - * | 0x00F00000 | Package Options | - * | 0x0F000000 | Number of Cores (ChipCommon Rev. >= 4)| - * | 0xF0000000 | Chip Type | - * -------------------------------------------------------------- - */ - - 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 deleted file mode 100644 index d4f34a8207eb..000000000000 --- a/sys/mips/broadcom/bcm_socinfo.h +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com> - * - * 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. - */ - -/* - * $FreeBSD$ - */ - -#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); - -#endif /* _MIPS_BROADCOM_BCM_SOCINFO_H_ */ diff --git a/sys/mips/broadcom/files.broadcom b/sys/mips/broadcom/files.broadcom index aa784b4dda6d..61b120073e48 100644 --- a/sys/mips/broadcom/files.broadcom +++ b/sys/mips/broadcom/files.broadcom @@ -6,6 +6,7 @@ # 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_pmu.c standard mips/broadcom/bcm_siba.c optional siba_nexus siba mips/mips/tick.c standard mips/mips/mips_pic.c standard @@ -16,7 +17,6 @@ kern/msi_if.m optional intrng mips/broadcom/uart_cpu_chipc.c optional uart mips/broadcom/uart_bus_chipc.c optional uart -mips/broadcom/bcm_socinfo.c standard mips/broadcom/bcm_mipscore.c standard # TODO: Replace with BCM47xx/57xx/etc-aware geom_map diff --git a/sys/mips/broadcom/uart_bus_chipc.c b/sys/mips/broadcom/uart_bus_chipc.c index 84d2c7aa1647..69c2fa779c69 100644 --- a/sys/mips/broadcom/uart_bus_chipc.c +++ b/sys/mips/broadcom/uart_bus_chipc.c @@ -48,22 +48,20 @@ __FBSDID("$FreeBSD$"); #include "uart_if.h" #include "bhnd_chipc_if.h" -#include "bcm_socinfo.h" +#include "bcm_machdep.h" static int uart_chipc_probe(device_t dev) { struct uart_softc *sc; - struct bcm_socinfo *socinfo; + u_int rclk; sc = device_get_softc(dev); sc->sc_class = &uart_ns8250_class; - /* TODO: UART rate should be calculated from CPU clock speed - * as fetched from bhnd bus */ - socinfo = bcm_get_socinfo(); - return (uart_bus_probe(dev, 0, socinfo->uartrate, 0, 0)); + rclk = bcm_get_uart_rclk(bcm_get_platform()); + return (uart_bus_probe(dev, 0, rclk, 0, 0)); } static device_method_t uart_chipc_methods[] = { diff --git a/sys/mips/broadcom/uart_cpu_chipc.c b/sys/mips/broadcom/uart_cpu_chipc.c index 91548a424a0a..2120cf0ba4f5 100644 --- a/sys/mips/broadcom/uart_cpu_chipc.c +++ b/sys/mips/broadcom/uart_cpu_chipc.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #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; @@ -70,19 +69,16 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) static int uart_cpu_init(struct uart_devinfo *di, u_int uart, int baudrate) { - struct bcm_socinfo *socinfo; - if (uart >= CHIPC_UART_MAX) return (EINVAL); - socinfo = bcm_get_socinfo(); 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_CORE_ADDR(cc_addr, - CHIPC_UART(uart)); + di->bas.bsh = (bus_space_handle_t) BCM_CORE_ADDR(bcm_get_platform(), + cc_addr, CHIPC_UART(uart)); di->bas.regshft = 0; - di->bas.rclk = socinfo->uartrate; /* in Hz */ + di->bas.rclk = bcm_get_uart_rclk(bcm_get_platform()); di->baudrate = baudrate; di->databits = 8; di->stopbits = 1; |