Author: landonf Date: Sat Aug 27 00:06:20 2016 New Revision: 304871 URL: https://svnweb.freebsd.org/changeset/base/304871
Log: [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 Added: head/sys/mips/broadcom/bcm_pmu.c (contents, props changed) Deleted: head/sys/mips/broadcom/bcm_socinfo.c head/sys/mips/broadcom/bcm_socinfo.h Modified: head/sys/dev/bhnd/cores/chipc/chipcreg.h head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctlvar.h head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c head/sys/dev/bhnd/cores/pmu/bhnd_pmu_private.h head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c head/sys/dev/bhnd/cores/pmu/bhnd_pmuvar.h head/sys/mips/broadcom/bcm_machdep.c head/sys/mips/broadcom/bcm_machdep.h head/sys/mips/broadcom/files.broadcom head/sys/mips/broadcom/uart_bus_chipc.c head/sys/mips/broadcom/uart_cpu_chipc.c Modified: head/sys/dev/bhnd/cores/chipc/chipcreg.h ============================================================================== --- head/sys/dev/bhnd/cores/chipc/chipcreg.h Sat Aug 27 00:03:02 2016 (r304870) +++ head/sys/dev/bhnd/cores/chipc/chipcreg.h Sat Aug 27 00:06:20 2016 (r304871) @@ -31,6 +31,10 @@ required during bus enumeration */ +/** Evaluates to true if the given ChipCommon core revision supports + * the CHIPC_CORECTRL register */ +#define CHIPC_HWREV_HAS_CORECTRL(hwrev) ((hwrev) >= 1) + /** Evaluates to true if the given ChipCommon core revision provides * the core count via the chip identification register. */ #define CHIPC_NCORES_MIN_HWREV(hwrev) ((hwrev) == 4 || (hwrev) >= 6) @@ -278,14 +282,14 @@ enum { #define CHIPC_CST_SPROM_OTP_SEL_R23_SHIFT 6 /* PLL type */ -#define CHIPC_PLL_NONE 0x00 -#define CHIPC_PLL_TYPE1 0x10 /* 48MHz base, 3 dividers */ -#define CHIPC_PLL_TYPE2 0x20 /* 48MHz, 4 dividers */ -#define CHIPC_PLL_TYPE3 0x30 /* 25MHz, 2 dividers */ -#define CHIPC_PLL_TYPE4 0x08 /* 48MHz, 4 dividers */ -#define CHIPC_PLL_TYPE5 0x18 /* 25MHz, 4 dividers */ -#define CHIPC_PLL_TYPE6 0x28 /* 100/200 or 120/240 only */ -#define CHIPC_PLL_TYPE7 0x38 /* 25MHz, 4 dividers */ +#define CHIPC_PLL_NONE 0x0 +#define CHIPC_PLL_TYPE1 0x2 /* 48MHz base, 3 dividers */ +#define CHIPC_PLL_TYPE2 0x4 /* 48MHz, 4 dividers */ +#define CHIPC_PLL_TYPE3 0x6 /* 25MHz, 2 dividers */ +#define CHIPC_PLL_TYPE4 0x8 /* 48MHz, 4 dividers */ +#define CHIPC_PLL_TYPE5 0x3 /* 25MHz, 4 dividers */ +#define CHIPC_PLL_TYPE6 0x5 /* 100/200 or 120/240 only */ +#define CHIPC_PLL_TYPE7 0x7 /* 25MHz, 4 dividers */ /* dynamic clock control defines */ #define CHIPC_LPOMINFREQ 25000 /* low power oscillator min */ Modified: head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c ============================================================================== --- head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c Sat Aug 27 00:03:02 2016 (r304870) +++ head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c Sat Aug 27 00:06:20 2016 (r304871) @@ -46,8 +46,6 @@ __FBSDID("$FreeBSD$"); #include "bhnd_pwrctl_private.h" static uint32_t bhnd_pwrctl_factor6(uint32_t x); -static uint32_t bhnd_pwrctl_clock_rate(uint32_t pll_type, uint32_t n, - uint32_t m); /** * Return the factor value corresponding to a given N3M clock control magic @@ -75,14 +73,122 @@ bhnd_pwrctl_factor6(uint32_t x) } /** + * Return the backplane clock's chipc 'M' register offset for a given PLL type, + * or 0 if a fixed clock speed should be used. + * + * @param cid Chip identification. + * @param pll_type PLL type (CHIPC_PLL_TYPE*) + * @param[out] fixed_hz If 0 is returned, will be set to the fixed clock + * speed for this device. + */ +bus_size_t +bhnd_pwrctl_si_clkreg_m(const struct bhnd_chipid *cid, + uint8_t pll_type, uint32_t *fixed_hz) +{ + switch (pll_type) { + case CHIPC_PLL_TYPE6: + return (CHIPC_CLKC_M3); + case CHIPC_PLL_TYPE3: + return (CHIPC_CLKC_M2); + default: + return (CHIPC_CLKC_SB); + } +} + +/** + * Calculate the backplane clock speed (in Hz) for a given a set of clock + * control values. + * + * @param cid Chip identification. + * @param pll_type PLL type (CHIPC_PLL_TYPE*) + * @param n clock control N register value. + * @param m clock control M register value. + */ +uint32_t +bhnd_pwrctl_si_clock_rate(const struct bhnd_chipid *cid, + uint32_t pll_type, uint32_t n, uint32_t m) +{ + uint32_t rate; + + KASSERT(bhnd_pwrctl_si_clkreg_m(cid, pll_type, NULL) != 0, + ("can't compute clock rate on fixed clock")); + + rate = bhnd_pwrctl_clock_rate(pll_type, n, m); + if (pll_type == CHIPC_PLL_TYPE3) + rate /= 2; + + return (rate); +} + +/** + * Return the CPU clock's chipc 'M' register offset for a given PLL type, + * or 0 if a fixed clock speed should be used. + * + * @param cid Chip identification. + * @param pll_type PLL type (CHIPC_PLL_TYPE*) + * @param[out] fixed_hz If 0 is returned, will be set to the fixed clock + * speed for this device. + */ +bus_size_t +bhnd_pwrctl_cpu_clkreg_m(const struct bhnd_chipid *cid, + uint8_t pll_type, uint32_t *fixed_hz) +{ + switch (pll_type) { + case CHIPC_PLL_TYPE2: + case CHIPC_PLL_TYPE4: + case CHIPC_PLL_TYPE6: + case CHIPC_PLL_TYPE7: + return (CHIPC_CLKC_M3); + + case CHIPC_PLL_TYPE5: + /* fixed 200MHz */ + if (fixed_hz != NULL) + *fixed_hz = 200 * 1000 * 1000; + return (0); + + case CHIPC_PLL_TYPE3: + if (cid->chip_id == BHND_CHIPID_BCM5365) { + /* fixed 200MHz */ + if (fixed_hz != NULL) + *fixed_hz = 200 * 1000 * 1000; + return (0); + } + + return (CHIPC_CLKC_M2); + + default: + return (CHIPC_CLKC_SB); + } +} + +/** + * Calculate the CPU clock speed (in Hz) for a given a set of clock control + * values. + * + * @param cid Chip identification. + * @param pll_type PLL type (CHIPC_PLL_TYPE*) + * @param n clock control N register value. + * @param m clock control M register value. + */ +uint32_t +bhnd_pwrctl_cpu_clock_rate(const struct bhnd_chipid *cid, + uint32_t pll_type, uint32_t n, uint32_t m) +{ + KASSERT(bhnd_pwrctl_cpu_clkreg_m(cid, pll_type, NULL) != 0, + ("can't compute clock rate on fixed clock")); + + return (bhnd_pwrctl_clock_rate(pll_type, n, m)); +} + +/** * Calculate the clock speed (in Hz) for a given a set of clockcontrol * values. * * @param pll_type PLL type (CHIPC_PLL_TYPE*) * @param n clock control N register value. - * @param m clock control N register value. + * @param m clock control M register value. */ -static uint32_t +uint32_t bhnd_pwrctl_clock_rate(uint32_t pll_type, uint32_t n, uint32_t m) { uint32_t clk_base; @@ -195,38 +301,27 @@ bhnd_pwrctl_clock_rate(uint32_t pll_type uint32_t bhnd_pwrctl_getclk_speed(struct bhnd_pwrctl_softc *sc) { - struct chipc_caps *ccaps; - bus_size_t creg; - uint32_t n, m; - uint32_t rate; + const struct bhnd_chipid *cid; + struct chipc_caps *ccaps; + bus_size_t creg; + uint32_t n, m; + uint32_t rate; PWRCTL_LOCK_ASSERT(sc, MA_OWNED); + cid = bhnd_get_chipid(sc->chipc_dev); ccaps = BHND_CHIPC_GET_CAPS(sc->chipc_dev); n = bhnd_bus_read_4(sc->res, CHIPC_CLKC_N); - switch (ccaps->pll_type) { - case CHIPC_PLL_TYPE6: - creg = CHIPC_CLKC_M3; /* non-extif regster */ - break; - case CHIPC_PLL_TYPE3: - creg = CHIPC_CLKC_M2; - break; - default: - creg = CHIPC_CLKC_SB; - break; - } - - m = bhnd_bus_read_4(sc->res, creg); + /* Get M register offset */ + creg = bhnd_pwrctl_si_clkreg_m(cid, ccaps->pll_type, &rate); + if (creg == 0) /* fixed rate */ + return (rate); /* calculate rate */ - rate = bhnd_pwrctl_clock_rate(ccaps->pll_type, n, m); - - if (ccaps->pll_type == CHIPC_PLL_TYPE3) - rate /= 2; - - return (rate); + m = bhnd_bus_read_4(sc->res, creg); + return (bhnd_pwrctl_si_clock_rate(cid, ccaps->pll_type, n, m)); } /* return the slow clock source */ Modified: head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctlvar.h ============================================================================== --- head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctlvar.h Sat Aug 27 00:03:02 2016 (r304870) +++ head/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctlvar.h Sat Aug 27 00:06:20 2016 (r304871) @@ -36,6 +36,21 @@ #include <sys/bus.h> #include <sys/queue.h> +#include <dev/bhnd/bhnd.h> + +uint32_t bhnd_pwrctl_clock_rate(uint32_t pll_type, uint32_t n, + uint32_t m); + +bus_size_t bhnd_pwrctl_si_clkreg_m(const struct bhnd_chipid *cid, + uint8_t pll_type, uint32_t *fixed_hz); +uint32_t bhnd_pwrctl_si_clock_rate(const struct bhnd_chipid *cid, + uint32_t pll_type, uint32_t n, uint32_t m); + +bus_size_t bhnd_pwrctl_cpu_clkreg_m(const struct bhnd_chipid *cid, + uint8_t pll_type, uint32_t *fixed_hz); +uint32_t bhnd_pwrctl_cpu_clock_rate(const struct bhnd_chipid *cid, + uint32_t pll_type, uint32_t n, uint32_t m); + /** * bhnd pwrctl device quirks. */ Modified: head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c ============================================================================== --- head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c Sat Aug 27 00:03:02 2016 (r304870) +++ head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c Sat Aug 27 00:06:20 2016 (r304871) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <machine/resource.h> #include <dev/bhnd/bhnd.h> +#include <dev/bhnd/cores/chipc/chipc.h> #include "bhnd_nvram_map.h" @@ -69,6 +70,16 @@ static int bhnd_pmu_sysctl_bus_freq(SYSC static int bhnd_pmu_sysctl_cpu_freq(SYSCTL_HANDLER_ARGS); static int bhnd_pmu_sysctl_mem_freq(SYSCTL_HANDLER_ARGS); +static uint32_t bhnd_pmu_read_4(bus_size_t reg, void *ctx); +static void bhnd_pmu_write_4(bus_size_t reg, uint32_t val, void *ctx); +static uint32_t bhnd_pmu_read_chipst(void *ctx); + +static const struct bhnd_pmu_io bhnd_pmu_res_io = { + .rd4 = bhnd_pmu_read_4, + .wr4 = bhnd_pmu_write_4, + .rd_chipst = bhnd_pmu_read_chipst +}; + #define BPMU_CLKCTL_READ_4(_pinfo) \ bhnd_bus_read_4((_pinfo)->pm_res, (_pinfo)->pm_regs) @@ -144,6 +155,14 @@ bhnd_pmu_attach(device_t dev, struct bhn return (ENXIO); } + /* Initialize query state */ + error = bhnd_pmu_query_init(&sc->query, dev, sc->cid, &bhnd_pmu_res_io, + sc); + if (error) + return (error); + sc->io = sc->query.io; + sc->io_ctx = sc->query.io_ctx; + BPMU_LOCK_INIT(sc); /* Set quirk flags */ @@ -183,6 +202,7 @@ bhnd_pmu_attach(device_t dev, struct bhn failed: BPMU_LOCK_DESTROY(sc); + bhnd_pmu_query_fini(&sc->query); return (error); } @@ -197,6 +217,7 @@ bhnd_pmu_detach(device_t dev) sc = device_get_softc(dev); BPMU_LOCK_DESTROY(sc); + bhnd_pmu_query_fini(&sc->query); return (0); } @@ -239,7 +260,7 @@ bhnd_pmu_sysctl_bus_freq(SYSCTL_HANDLER_ sc = arg1; BPMU_LOCK(sc); - freq = bhnd_pmu_si_clock(sc); + freq = bhnd_pmu_si_clock(&sc->query); BPMU_UNLOCK(sc); return (sysctl_handle_32(oidp, NULL, freq, req)); @@ -254,7 +275,7 @@ bhnd_pmu_sysctl_cpu_freq(SYSCTL_HANDLER_ sc = arg1; BPMU_LOCK(sc); - freq = bhnd_pmu_cpu_clock(sc); + freq = bhnd_pmu_cpu_clock(&sc->query); BPMU_UNLOCK(sc); return (sysctl_handle_32(oidp, NULL, freq, req)); @@ -269,7 +290,7 @@ bhnd_pmu_sysctl_mem_freq(SYSCTL_HANDLER_ sc = arg1; BPMU_LOCK(sc); - freq = bhnd_pmu_mem_clock(sc); + freq = bhnd_pmu_mem_clock(&sc->query); BPMU_UNLOCK(sc); return (sysctl_handle_32(oidp, NULL, freq, req)); @@ -445,6 +466,27 @@ bhnd_pmu_core_release(device_t dev, stru return (0); } +static uint32_t +bhnd_pmu_read_4(bus_size_t reg, void *ctx) +{ + struct bhnd_pmu_softc *sc = ctx; + return (bhnd_bus_read_4(sc->res, reg)); +} + +static void +bhnd_pmu_write_4(bus_size_t reg, uint32_t val, void *ctx) +{ + struct bhnd_pmu_softc *sc = ctx; + return (bhnd_bus_write_4(sc->res, reg, val)); +} + +static uint32_t +bhnd_pmu_read_chipst(void *ctx) +{ + struct bhnd_pmu_softc *sc = ctx; + return (BHND_CHIPC_READ_CHIPST(sc->chipc_dev)); +} + static device_method_t bhnd_pmu_methods[] = { /* Device interface */ DEVMETHOD(device_probe, bhnd_pmu_probe), Modified: head/sys/dev/bhnd/cores/pmu/bhnd_pmu_private.h ============================================================================== --- head/sys/dev/bhnd/cores/pmu/bhnd_pmu_private.h Sat Aug 27 00:03:02 2016 (r304870) +++ head/sys/dev/bhnd/cores/pmu/bhnd_pmu_private.h Sat Aug 27 00:06:20 2016 (r304871) @@ -30,15 +30,9 @@ #include "bhnd_pmuvar.h" /* Register I/O */ -#define BHND_PMU_READ_1(_sc, _reg) bhnd_bus_read_1((_sc)->res, (_reg)) -#define BHND_PMU_READ_2(_sc, _reg) bhnd_bus_read_2((_sc)->res, (_reg)) -#define BHND_PMU_READ_4(_sc, _reg) bhnd_bus_read_4((_sc)->res, (_reg)) -#define BHND_PMU_WRITE_1(_sc, _reg, _val) \ - bhnd_bus_write_1((_sc)->res, (_reg), (_val)) -#define BHND_PMU_WRITE_2(_sc, _reg, _val) \ - bhnd_bus_write_2((_sc)->res, (_reg), (_val)) +#define BHND_PMU_READ_4(_sc, _reg) (_sc)->io->rd4((_reg), (_sc)->io_ctx) #define BHND_PMU_WRITE_4(_sc, _reg, _val) \ - bhnd_bus_write_4((_sc)->res, (_reg), (_val)) + (_sc)->io->wr4((_reg), (_val), (_sc)->io_ctx) #define BHND_PMU_AND_4(_sc, _reg, _val) \ BHND_PMU_WRITE_4((_sc), (_reg), \ @@ -49,10 +43,11 @@ /* Indirect register support */ #define BHND_PMU_IND_READ(_sc, _src, _reg) \ - bhnd_pmu_ind_read((_sc), BHND_PMU_ ## _src ## _ADDR, \ - BHND_PMU_ ## _src ## _DATA, (_reg)) + bhnd_pmu_ind_read((_sc)->io, (_sc)->io_ctx, \ + BHND_PMU_ ## _src ## _ADDR, BHND_PMU_ ## _src ## _DATA, (_reg)) #define BHND_PMU_IND_WRITE(_sc, _src, _reg, _val, _mask) \ - bhnd_pmu_ind_write(sc, BHND_PMU_ ## _src ## _ADDR, \ + bhnd_pmu_ind_write((_sc)->io, (_sc)->io_ctx, \ + BHND_PMU_ ## _src ## _ADDR, \ BHND_PMU_ ## _src ## _DATA, (_reg), (_val), (_mask)) /* Chip Control indirect registers */ @@ -96,10 +91,12 @@ enum { SET_LDO_VOLTAGE_LNLDO2_SEL = 10, }; -uint32_t bhnd_pmu_ind_read(struct bhnd_pmu_softc *sc, bus_size_t addr, - bus_size_t data, uint32_t reg); -void bhnd_pmu_ind_write(struct bhnd_pmu_softc *sc, bus_size_t addr, - bus_size_t data, uint32_t reg, uint32_t val, uint32_t mask); + +uint32_t bhnd_pmu_ind_read(const struct bhnd_pmu_io *io, void *io_ctx, + bus_size_t addr, bus_size_t data, uint32_t reg); +void bhnd_pmu_ind_write(const struct bhnd_pmu_io *io, void *io_ctx, + bus_size_t addr, bus_size_t data, uint32_t reg, + uint32_t val, uint32_t mask); bool bhnd_pmu_wait_clkst(struct bhnd_pmu_softc *sc, device_t dev, struct bhnd_resource *r, bus_size_t clkst_reg, @@ -112,12 +109,6 @@ void bhnd_pmu_swreg_init(struct bhnd_pm uint32_t bhnd_pmu_force_ilp(struct bhnd_pmu_softc *sc, bool force); -uint32_t bhnd_pmu_si_clock(struct bhnd_pmu_softc *sc); -uint32_t bhnd_pmu_cpu_clock(struct bhnd_pmu_softc *sc); -uint32_t bhnd_pmu_mem_clock(struct bhnd_pmu_softc *sc); -uint32_t bhnd_pmu_alp_clock(struct bhnd_pmu_softc *sc); -uint32_t bhnd_pmu_ilp_clock(struct bhnd_pmu_softc *sc); - void bhnd_pmu_set_switcher_voltage(struct bhnd_pmu_softc *sc, uint8_t bb_voltage, uint8_t rf_voltage); void bhnd_pmu_set_ldo_voltage(struct bhnd_pmu_softc *sc, Modified: head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c ============================================================================== --- head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c Sat Aug 27 00:03:02 2016 (r304870) +++ head/sys/dev/bhnd/cores/pmu/bhnd_pmu_subr.c Sat Aug 27 00:06:20 2016 (r304871) @@ -38,33 +38,36 @@ __FBSDID("$FreeBSD$"); #include "bhnd_pmu_private.h" -#ifdef BCMDBG -#define PMU_MSG(args) printf args -#define PMU_ERROR(args) do { \ - panic args; \ +#define PMU_LOG(_sc, _fmt, ...) do { \ + if (_sc->dev != NULL) \ + device_printf(_sc->dev, _fmt, ##__VA_ARGS__); \ + else \ + printf(_fmt, ##__VA_ARGS__); \ } while (0) + +#ifdef BCMDBG +#define PMU_DEBUG(_sc, _fmt, ...) PMU_LOG(_sc, _fmt, ##__VA_ARGS__) #else -#define PMU_MSG(args) -#define PMU_ERROR(args) printf args +#define PMU_DEBUG(_sc, _fmt, ...) #endif typedef struct pmu0_xtaltab0 pmu0_xtaltab0_t; typedef struct pmu1_xtaltab0 pmu1_xtaltab0_t; /* PLL controls/clocks */ -static const pmu1_xtaltab0_t *bhnd_pmu1_xtaltab0(struct bhnd_pmu_softc *sc); -static const pmu1_xtaltab0_t *bhnd_pmu1_xtaldef0(struct bhnd_pmu_softc *sc); +static const pmu1_xtaltab0_t *bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc); +static const pmu1_xtaltab0_t *bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc); static void bhnd_pmu0_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal); -static uint32_t bhnd_pmu0_cpuclk0(struct bhnd_pmu_softc *sc); -static uint32_t bhnd_pmu0_alpclk0(struct bhnd_pmu_softc *sc); +static uint32_t bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc); +static uint32_t bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc); static void bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal); -static uint32_t bhnd_pmu1_pllfvco0(struct bhnd_pmu_softc *sc); -static uint32_t bhnd_pmu1_cpuclk0(struct bhnd_pmu_softc *sc); -static uint32_t bhnd_pmu1_alpclk0(struct bhnd_pmu_softc *sc); +static uint32_t bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc); +static uint32_t bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc); +static uint32_t bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc); -static uint32_t bhnd_pmu5_clock(struct bhnd_pmu_softc *sc, u_int pll0, u_int m); +static uint32_t bhnd_pmu5_clock(struct bhnd_pmu_query *sc, u_int pll0, u_int m); /* PMU resources */ static bool bhnd_pmu_res_depfltr_bb(struct bhnd_pmu_softc *sc); @@ -93,7 +96,45 @@ static void bhnd_pmu_set_4330_plldivs(st (1 << (BHND_PMU_ ## _bit)) #define PMU_CST4330_SDIOD_CHIPMODE(_sc) \ - CHIPC_CST4330_CHIPMODE_SDIOD(BHND_CHIPC_READ_CHIPST((_sc)->chipc_dev)) + CHIPC_CST4330_CHIPMODE_SDIOD((_sc)->io->rd_chipst((_sc)->io_ctx)) + +/** + * Initialize @p query state. + * + * @param[out] query On success, will be populated with a valid query instance + * state. + * @param dev The device owning @p query, or NULL. + * @param id The bhnd chip identification. + * @param io I/O callback functions. + * @param ctx I/O callback context. + * + * @retval 0 success + * @retval non-zero if the query state could not be initialized. + */ +int +bhnd_pmu_query_init(struct bhnd_pmu_query *query, device_t dev, + struct bhnd_chipid id, const struct bhnd_pmu_io *io, void *ctx) +{ + query->dev = dev; + query->io = io; + query->io_ctx = ctx; + query->cid = id; + query->caps = BHND_PMU_READ_4(query, BHND_PMU_CAP); + + return (0); +} + +/** + * Release any resources held by @p query. + * + * @param query A query instance previously initialized via + * bhnd_pmu_query_init(). + */ +void +bhnd_pmu_query_fini(struct bhnd_pmu_query *query) +{ + /* nothing to do */ +} /** * Perform an indirect register read. @@ -103,11 +144,11 @@ static void bhnd_pmu_set_4330_plldivs(st * @param reg Indirect register to be read. */ uint32_t -bhnd_pmu_ind_read(struct bhnd_pmu_softc *sc, bus_size_t addr, bus_size_t data, - uint32_t reg) +bhnd_pmu_ind_read(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr, + bus_size_t data, uint32_t reg) { - BHND_PMU_WRITE_4(sc, addr, reg); - return (BHND_PMU_READ_4(sc, data)); + io->wr4(addr, reg, io_ctx); + return (io->rd4(data, io_ctx)); } /** @@ -120,21 +161,21 @@ bhnd_pmu_ind_read(struct bhnd_pmu_softc * @param mask Only the bits defined by @p mask will be updated from @p val. */ void -bhnd_pmu_ind_write(struct bhnd_pmu_softc *sc, bus_size_t addr, +bhnd_pmu_ind_write(const struct bhnd_pmu_io *io, void *io_ctx, bus_size_t addr, bus_size_t data, uint32_t reg, uint32_t val, uint32_t mask) { uint32_t rval; - BHND_PMU_WRITE_4(sc, addr, reg); + io->wr4(addr, reg, io_ctx); if (mask != UINT32_MAX) { - rval = BHND_PMU_READ_4(sc, data); + rval = io->rd4(data, io_ctx); rval &= ~mask | (val & mask); } else { rval = val; } - BHND_PMU_WRITE_4(sc, data, rval); + io->wr4(data, rval, io_ctx); } /** @@ -375,7 +416,7 @@ bhnd_pmu_fast_pwrup_delay(struct bhnd_pm if (error) return (error); - ilp = bhnd_pmu_ilp_clock(sc); + ilp = bhnd_pmu_ilp_clock(&sc->query); delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -387,7 +428,7 @@ bhnd_pmu_fast_pwrup_delay(struct bhnd_pm if (error) return (error); - ilp = bhnd_pmu_ilp_clock(sc); + ilp = bhnd_pmu_ilp_clock(&sc->query); delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -403,7 +444,7 @@ bhnd_pmu_fast_pwrup_delay(struct bhnd_pm if (error) return (error); - ilp = bhnd_pmu_ilp_clock(sc); + ilp = bhnd_pmu_ilp_clock(&sc->query); delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -415,7 +456,7 @@ bhnd_pmu_fast_pwrup_delay(struct bhnd_pm if (error) return (error); - ilp = bhnd_pmu_ilp_clock(sc); + ilp = bhnd_pmu_ilp_clock(&sc->query); delay = (uptime + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -882,22 +923,22 @@ bhnd_pmu_res_masks(struct bhnd_pmu_softc /* Apply nvram override to min mask */ error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMIN, &nval); if (error && error != ENOENT) { - device_printf(sc->dev, "NVRAM error reading %s: %d\n", + PMU_LOG(sc, "NVRAM error reading %s: %d\n", BHND_NVAR_RMIN, error); return (error); } else if (!error) { - PMU_MSG(("Applying rmin=%#x to min_mask\n", nval)); + PMU_DEBUG(sc, "Applying rmin=%#x to min_mask\n", nval); min_mask = nval; } /* Apply nvram override to max mask */ error = bhnd_nvram_getvar_uint32(sc->chipc_dev, BHND_NVAR_RMAX, &nval); if (error && error != ENOENT) { - device_printf(sc->dev, "NVRAM error reading %s: %d\n", + PMU_LOG(sc, "NVRAM error reading %s: %d\n", BHND_NVAR_RMAX, error); return (error); } else if (!error) { - PMU_MSG(("Applying rmax=%#x to max_mask\n", nval)); + PMU_DEBUG(sc, "Applying rmax=%#x to max_mask\n", nval); min_mask = nval; } @@ -1013,8 +1054,8 @@ bhnd_pmu_res_init(struct bhnd_pmu_softc updt = &pmu_res_updown_table[pmu_res_updown_table_sz - i - 1]; - PMU_MSG(("Changing rsrc %d res_updn_timer to %#x\n", - updt->resnum, updt->updown)); + PMU_DEBUG(sc, "Changing rsrc %d res_updn_timer to %#x\n", + updt->resnum, updt->updown); BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, updt->resnum); BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, updt->updown); @@ -1031,13 +1072,13 @@ bhnd_pmu_res_init(struct bhnd_pmu_softc if (error == ENOENT) { continue; } else if (error) { - device_printf(sc->dev, "NVRAM error reading %s: %d\n", + PMU_LOG(sc, "NVRAM error reading %s: %d\n", name, error); return (error); } - PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, - val, i)); + PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_updn_timer\n", + name, val, i); BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); BHND_PMU_WRITE_4(sc, BHND_PMU_RES_UPDN_TIMER, val); @@ -1066,21 +1107,21 @@ bhnd_pmu_res_init(struct bhnd_pmu_softc BHND_PMU_RES_DEP_MASK); switch (rdep->action) { case RES_DEPEND_SET: - PMU_MSG(("Changing rsrc %hhu res_dep_mask to " - "%#x\n", i, table->depend_mask)); + PMU_DEBUG(sc, "Changing rsrc %hhu res_dep_mask to " + "%#x\n", i, table->depend_mask); depend_mask = rdep->depend_mask; break; case RES_DEPEND_ADD: - PMU_MSG(("Adding %#x to rsrc %hhu " - "res_dep_mask\n", table->depend_mask, i)); + PMU_DEBUG(sc, "Adding %#x to rsrc %hhu " + "res_dep_mask\n", table->depend_mask, i); depend_mask |= rdep->depend_mask; break; case RES_DEPEND_REMOVE: - PMU_MSG(("Removing %#x from rsrc %hhu " - "res_dep_mask\n", table->depend_mask, i)); + PMU_DEBUG(sc, "Removing %#x from rsrc %hhu " + "res_dep_mask\n", table->depend_mask, i); depend_mask &= ~(rdep->depend_mask); break; @@ -1106,13 +1147,13 @@ bhnd_pmu_res_init(struct bhnd_pmu_softc if (error == ENOENT) { continue; } else if (error) { - device_printf(sc->dev, "NVRAM error reading %s: %d\n", - name, error); + PMU_LOG(sc, "NVRAM error reading %s: %d\n", name, + error); return (error); } - PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, - i)); + PMU_DEBUG(sc, "Applying %s=%s to rsrc %d res_dep_mask\n", name, + val, i); BHND_PMU_WRITE_4(sc, BHND_PMU_RES_TABLE_SEL, i); BHND_PMU_WRITE_4(sc, BHND_PMU_RES_DEP_MASK, val); @@ -1126,14 +1167,14 @@ bhnd_pmu_res_init(struct bhnd_pmu_softc /* Program max resource mask */ if (max_mask != 0) { - PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask)); + PMU_DEBUG(sc, "Changing max_res_mask to 0x%x\n", max_mask); BHND_PMU_WRITE_4(sc, BHND_PMU_MAX_RES_MASK, max_mask); } /* Program min resource mask */ if (min_mask != 0) { - PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask)); + PMU_DEBUG(sc, "Changing min_res_mask to 0x%x\n", min_mask); BHND_PMU_WRITE_4(sc, BHND_PMU_MIN_RES_MASK, min_mask); } @@ -1367,7 +1408,7 @@ static const pmu1_xtaltab0_t pmu1_xtalta /* select xtal table for each chip */ static const pmu1_xtaltab0_t * -bhnd_pmu1_xtaltab0(struct bhnd_pmu_softc *sc) +bhnd_pmu1_xtaltab0(struct bhnd_pmu_query *sc) { switch (sc->cid.chip_id) { case BHND_CHIPID_BCM4315: @@ -1386,15 +1427,15 @@ bhnd_pmu1_xtaltab0(struct bhnd_pmu_softc else return (pmu1_xtaltab0_1440); default: - PMU_MSG(("bhnd_pmu1_xtaltab0: Unknown chipid %#hx\n", - sc->cid.chip_id)); + PMU_DEBUG(sc, "bhnd_pmu1_xtaltab0: Unknown chipid %#hx\n", + sc->cid.chip_id); return (NULL); } } /* select default xtal frequency for each chip */ static const pmu1_xtaltab0_t * -bhnd_pmu1_xtaldef0(struct bhnd_pmu_softc *sc) +bhnd_pmu1_xtaldef0(struct bhnd_pmu_query *sc) { switch (sc->cid.chip_id) { case BHND_CHIPID_BCM4315: @@ -1419,15 +1460,15 @@ bhnd_pmu1_xtaldef0(struct bhnd_pmu_softc else return (&pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]); default: - PMU_MSG(("bhnd_pmu1_xtaldef0: Unknown chipid %#hx\n", - sc->cid.chip_id)); + PMU_DEBUG(sc, "bhnd_pmu1_xtaldef0: Unknown chipid %#hx\n", + sc->cid.chip_id); return (NULL); } } /* select default pll fvco for each chip */ static uint32_t -bhnd_pmu1_pllfvco0(struct bhnd_pmu_softc *sc) +bhnd_pmu1_pllfvco0(struct bhnd_pmu_query *sc) { switch (sc->cid.chip_id) { case BHND_CHIPID_BCM4329: @@ -1442,15 +1483,15 @@ bhnd_pmu1_pllfvco0(struct bhnd_pmu_softc else return (FVCO_1440); default: - PMU_MSG(("bhnd_pmu1_pllfvco0: Unknown chipid %#hx\n", - sc->cid.chip_id)); + PMU_DEBUG(sc, "bhnd_pmu1_pllfvco0: Unknown chipid %#hx\n", + sc->cid.chip_id); return (0); } } /* query alp/xtal clock frequency */ static uint32_t -bhnd_pmu1_alpclk0(struct bhnd_pmu_softc *sc) +bhnd_pmu1_alpclk0(struct bhnd_pmu_query *sc) { const pmu1_xtaltab0_t *xt; uint32_t xf; @@ -1469,8 +1510,7 @@ bhnd_pmu1_alpclk0(struct bhnd_pmu_softc xt = bhnd_pmu1_xtaldef0(sc); if (xt == NULL || xt->fref == 0) { - device_printf(sc->dev, - "no matching ALP/XTAL frequency found\n"); + PMU_LOG(sc, "no matching ALP/XTAL frequency found\n"); return (0); } @@ -1489,8 +1529,8 @@ bhnd_pmu0_pllinit0(struct bhnd_pmu_softc /* Use h/w default PLL config */ if (xtal == 0) { - PMU_MSG(("Unspecified xtal frequency, skipping PLL " - "configuration\n")); + PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL " + "configuration\n"); return; } @@ -1503,7 +1543,8 @@ bhnd_pmu0_pllinit0(struct bhnd_pmu_softc if (xt->freq == 0) xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; - PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); + PMU_DEBUG(sc, "XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, + xt->xf); /* Check current PLL state */ pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); @@ -1517,19 +1558,20 @@ bhnd_pmu0_pllinit0(struct bhnd_pmu_softc } #endif /* BCMUSBDEV */ - PMU_MSG(("PLL already programmed for %d.%d MHz\n", - xt->freq / 1000, xt->freq % 1000)); + PMU_DEBUG(sc, "PLL already programmed for %d.%d MHz\n", + xt->freq / 1000, xt->freq % 1000); return; } if (xf != 0) { - PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", + PMU_DEBUG(sc, + "Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", xt->freq / 1000, xt->freq % 1000, pmu0_xtaltab0[tmp-1].freq / 1000, - pmu0_xtaltab0[tmp-1].freq % 1000)); + pmu0_xtaltab0[tmp-1].freq % 1000); } else { - PMU_MSG(("Programming PLL for %d.%d MHz\n", - xt->freq / 1000, xt->freq % 1000)); + PMU_DEBUG(sc, "Programming PLL for %d.%d MHz\n", + xt->freq / 1000, xt->freq % 1000); } /* Make sure the PLL is off */ @@ -1549,7 +1591,7 @@ bhnd_pmu0_pllinit0(struct bhnd_pmu_softc /* Wait for HT clock to shutdown. */ PMU_WAIT_CLKST(sc, 0, BHND_CCS_HTAVAIL); - PMU_MSG(("Done masking\n")); + PMU_DEBUG(sc, "Done masking\n"); /* Write PDIV in pllcontrol[0] */ if (xt->freq >= BHND_PMU0_PLL0_PC0_PDIV_FREQ) { @@ -1582,7 +1624,7 @@ bhnd_pmu0_pllinit0(struct bhnd_pmu_softc pll_mask = BHND_PMU0_PLL0_PC2_WILD_INT_MASK; BHND_PMU_PLL_WRITE(sc, BHND_PMU0_PLL0_PLLCTL2, pll_data, pll_mask); - PMU_MSG(("Done pll\n")); + PMU_DEBUG(sc, "Done pll\n"); /* Write XtalFreq. Set the divisor also. */ pmu_ctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL); @@ -1597,7 +1639,7 @@ bhnd_pmu0_pllinit0(struct bhnd_pmu_softc /* query alp/xtal clock frequency */ static uint32_t -bhnd_pmu0_alpclk0(struct bhnd_pmu_softc *sc) +bhnd_pmu0_alpclk0(struct bhnd_pmu_query *sc) { const pmu0_xtaltab0_t *xt; uint32_t xf; @@ -1618,7 +1660,7 @@ bhnd_pmu0_alpclk0(struct bhnd_pmu_softc /* query CPU clock frequency */ static uint32_t -bhnd_pmu0_cpuclk0(struct bhnd_pmu_softc *sc) +bhnd_pmu0_cpuclk0(struct bhnd_pmu_query *sc) { uint32_t tmp, divarm; uint32_t FVCO; @@ -1654,8 +1696,8 @@ bhnd_pmu0_cpuclk0(struct bhnd_pmu_softc fvco /= 1000; fvco *= 1000; - PMU_MSG(("bhnd_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n", - wbint, wbfrac, fvco)); + PMU_DEBUG(sc, "bhnd_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n", + wbint, wbfrac, fvco); FVCO = fvco; #endif /* BCMDBG */ @@ -1677,19 +1719,21 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc uint32_t FVCO; uint8_t ndiv_mode; - FVCO = bhnd_pmu1_pllfvco0(sc) / 1000; + FVCO = bhnd_pmu1_pllfvco0(&sc->query) / 1000; buf_strength = 0; ndiv_mode = 1; /* Use h/w default PLL config */ if (xtal == 0) { - PMU_MSG(("Unspecified xtal frequency, skipping PLL " - "configuration\n")); + PMU_DEBUG(sc, "Unspecified xtal frequency, skipping PLL " + "configuration\n"); return; } /* Find the frequency in the table */ - for (xt = bhnd_pmu1_xtaltab0(sc); xt != NULL && xt->fref != 0; xt++) { + for (xt = bhnd_pmu1_xtaltab0(&sc->query); xt != NULL && xt->fref != 0; + xt++) + { if (xt->fref == xtal) break; } @@ -1698,8 +1742,8 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc * we don't know how to program it. */ if (xt == NULL || xt->fref == 0) { - device_printf(sc->dev, "Unsupported XTAL frequency %d.%dMHz, " - "skipping PLL configuration\n", xtal / 1000, xtal % 1000); + PMU_LOG(sc, "Unsupported XTAL frequency %d.%dMHz, skipping PLL " + "configuration\n", xtal / 1000, xtal % 1000); return; } @@ -1710,14 +1754,14 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc sc->cid.chip_id != BHND_CHIPID_BCM4319 && sc->cid.chip_id != BHND_CHIPID_BCM4330) { - PMU_MSG(("PLL already programmed for %d.%dMHz\n", - xt->fref / 1000, xt->fref % 1000)); + PMU_DEBUG(sc, "PLL already programmed for %d.%dMHz\n", + xt->fref / 1000, xt->fref % 1000); return; } - PMU_MSG(("XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf)); - PMU_MSG(("Programming PLL for %d.%dMHz\n", xt->fref / 1000, - xt->fref % 1000)); + PMU_DEBUG(sc, "XTAL %d.%dMHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf); + PMU_DEBUG(sc, "Programming PLL for %d.%dMHz\n", xt->fref / 1000, + xt->fref % 1000); switch (sc->cid.chip_id) { case BHND_CHIPID_BCM4325: @@ -1840,7 +1884,7 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc panic("unsupported chipid %#hx\n", sc->cid.chip_id); } - PMU_MSG(("Done masking\n")); + PMU_DEBUG(sc, "Done masking\n"); /* Write p1div and p2div to pllcontrol[0] */ plldata = @@ -1916,8 +1960,8 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc /* Write clock driving strength to pllcontrol[5] */ if (buf_strength) { - PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", - buf_strength)); + PMU_DEBUG(sc, "Adjusting PLL buffer drive strength: %x\n", + buf_strength); plldata = BHND_PMU_SET_BITS(buf_strength, BHND_PMU1_PLL0_PC5_CLK_DRV); @@ -1946,7 +1990,7 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc pllmask); } - PMU_MSG(("Done pll\n")); + PMU_DEBUG(sc, "Done pll\n"); /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs * to be updated. @@ -1995,7 +2039,7 @@ bhnd_pmu1_pllinit0(struct bhnd_pmu_softc /* query the CPU clock frequency */ static uint32_t -bhnd_pmu1_cpuclk0(struct bhnd_pmu_softc *sc) +bhnd_pmu1_cpuclk0(struct bhnd_pmu_query *sc) { uint32_t tmp, m1div; #ifdef BCMDBG @@ -2032,8 +2076,8 @@ bhnd_pmu1_cpuclk0(struct bhnd_pmu_softc fvco /= 1000; fvco *= 1000; - PMU_MSG(("bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u " - "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco)); + PMU_DEBUG(sc, "bhnd_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u " + "p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco); FVCO = fvco; #endif /* BCMDBG */ @@ -2134,15 +2178,19 @@ bhnd_pmu_pll_init(struct bhnd_pmu_softc bhnd_pmu1_pllinit0(sc, xtalfreq); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"