diff options
-rw-r--r-- | chip/mt_scp/mt8192/build.mk | 1 | ||||
-rw-r--r-- | chip/mt_scp/mt8192/clock.c (renamed from chip/mt_scp/rv32i_common/clock.c) | 12 | ||||
-rw-r--r-- | chip/mt_scp/mt8192/clock_regs.h | 85 | ||||
-rw-r--r-- | chip/mt_scp/mt8195/build.mk | 1 | ||||
-rw-r--r-- | chip/mt_scp/mt8195/clock.c | 432 | ||||
-rw-r--r-- | chip/mt_scp/mt8195/clock_regs.h | 92 | ||||
-rw-r--r-- | chip/mt_scp/rv32i_common/build.mk | 1 | ||||
-rw-r--r-- | chip/mt_scp/rv32i_common/clock_chip.h | 23 | ||||
-rw-r--r-- | chip/mt_scp/rv32i_common/registers.h | 73 |
9 files changed, 622 insertions, 98 deletions
diff --git a/chip/mt_scp/mt8192/build.mk b/chip/mt_scp/mt8192/build.mk index 02ffdaeefe..5ca0f1033c 100644 --- a/chip/mt_scp/mt8192/build.mk +++ b/chip/mt_scp/mt8192/build.mk @@ -5,3 +5,4 @@ # Required chip modules chip-y+=$(CHIP_VARIANT)/uart.o +chip-y+=$(CHIP_VARIANT)/clock.o diff --git a/chip/mt_scp/rv32i_common/clock.c b/chip/mt_scp/mt8192/clock.c index a460d818c7..43f570fc62 100644 --- a/chip/mt_scp/rv32i_common/clock.c +++ b/chip/mt_scp/mt8192/clock.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -8,7 +8,6 @@ #include <assert.h> #include <string.h> -#include "clock_chip.h" #include "clock.h" #include "common.h" #include "console.h" @@ -21,6 +20,13 @@ #define CPRINTF(format, args...) cprintf(CC_CLOCK, format, ##args) #define CPRINTS(format, args...) cprints(CC_CLOCK, format, ##args) +enum scp_clock_source { + SCP_CLK_26M = CLK_SW_SEL_26M, + SCP_CLK_32K = CLK_SW_SEL_32K, + SCP_CLK_ULPOSC2 = CLK_SW_SEL_ULPOSC2, + SCP_CLK_ULPOSC1 = CLK_SW_SEL_ULPOSC1, +}; + static struct opp_ulposc_cfg { uint32_t osc; uint32_t div; @@ -277,7 +283,7 @@ static void clock_calibrate_ulposc(struct opp_ulposc_cfg *opp) #endif } -void clock_select_clock(enum scp_clock_source src) +static void clock_select_clock(enum scp_clock_source src) { /* * DIV2 divider takes precedence over clock selection to prevent diff --git a/chip/mt_scp/mt8192/clock_regs.h b/chip/mt_scp/mt8192/clock_regs.h new file mode 100644 index 0000000000..5928ca0473 --- /dev/null +++ b/chip/mt_scp/mt8192/clock_regs.h @@ -0,0 +1,85 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* SCP clock module registers */ + +#ifndef __CROS_EC_CLOCK_REGS_H +#define __CROS_EC_CLOCK_REGS_H + +/* clock source select */ +#define SCP_CLK_SW_SEL REG32(SCP_CLK_CTRL_BASE + 0x0000) +#define CLK_SW_SEL_26M 0 +#define CLK_SW_SEL_32K 1 +#define CLK_SW_SEL_ULPOSC2 2 +#define CLK_SW_SEL_ULPOSC1 3 +#define SCP_CLK_ENABLE REG32(SCP_CLK_CTRL_BASE + 0x0004) +#define CLK_HIGH_EN BIT(1) /* ULPOSC */ +#define CLK_HIGH_CG BIT(2) +/* clock general control */ +#define SCP_CLK_CTRL_GENERAL_CTRL REG32(SCP_CLK_CTRL_BASE + 0x009C) +#define VREQ_PMIC_WRAP_SEL (0x2) + +/* TOPCK clk */ +#define TOPCK_BASE AP_REG_BASE +#define AP_CLK_MISC_CFG_0 REG32(TOPCK_BASE + 0x0140) +#define MISC_METER_DIVISOR_MASK 0xff000000 +#define MISC_METER_DIV_1 0 +/* OSC meter */ +#define AP_CLK_DBG_CFG REG32(TOPCK_BASE + 0x017C) +#define DBG_MODE_MASK 3 +#define DBG_MODE_SET_CLOCK 0 +#define DBG_BIST_SOURCE_MASK (0x3f << 16) +#define DBG_BIST_SOURCE_ULPOSC1 (0x25 << 16) +#define DBG_BIST_SOURCE_ULPOSC2 (0x24 << 16) +#define AP_SCP_CFG_0 REG32(TOPCK_BASE + 0x0220) +#define CFG_FREQ_METER_RUN BIT(4) +#define CFG_FREQ_METER_ENABLE BIT(12) +#define AP_SCP_CFG_1 REG32(TOPCK_BASE + 0x0224) +#define CFG_FREQ_COUNTER(CFG1) ((CFG1) & 0xFFFF) +/* + * ULPOSC + * osc: 0 for ULPOSC1, 1 for ULPOSC2. + */ +#define AP_ULPOSC_CON0_BASE (AP_REG_BASE + 0xC2B0) +#define AP_ULPOSC_CON1_BASE (AP_REG_BASE + 0xC2B4) +#define AP_ULPOSC_CON2_BASE (AP_REG_BASE + 0xC2B8) +#define AP_ULPOSC_CON0(osc) \ + REG32(AP_ULPOSC_CON0_BASE + (osc) * 0x10) +#define AP_ULPOSC_CON1(osc) \ + REG32(AP_ULPOSC_CON1_BASE + (osc) * 0x10) +#define AP_ULPOSC_CON2(osc) \ + REG32(AP_ULPOSC_CON2_BASE + (osc) * 0x10) +/* + * AP_ULPOSC_CON0 + * bit0-6: calibration + * bit7-13: iband + * bit14-17: fband + * bit18-23: div + * bit24: cp_en + * bit25-31: reserved + */ +#define OSC_CALI_MASK 0x7f +#define OSC_IBAND_SHIFT 7 +#define OSC_FBAND_SHIFT 14 +#define OSC_DIV_SHIFT 18 +#define OSC_CP_EN BIT(24) +/* AP_ULPOSC_CON1 + * bit0-7: 32K calibration + * bit 8-15: rsv1 + * bit 16-23: rsv2 + * bit 24-25: mod + * bit26: div2_en + * bit27-31: reserved + */ +#define OSC_RSV1_SHIFT 8 +#define OSC_RSV2_SHIFT 16 +#define OSC_MOD_SHIFT 24 +#define OSC_DIV2_EN BIT(26) +/* AP_ULPOSC_CON2 + * bit0-7: bias + * bit8-31: reserved + */ + +#endif /* __CROS_EC_CLOCK_REGS_H */ diff --git a/chip/mt_scp/mt8195/build.mk b/chip/mt_scp/mt8195/build.mk index 02ffdaeefe..5ca0f1033c 100644 --- a/chip/mt_scp/mt8195/build.mk +++ b/chip/mt_scp/mt8195/build.mk @@ -5,3 +5,4 @@ # Required chip modules chip-y+=$(CHIP_VARIANT)/uart.o +chip-y+=$(CHIP_VARIANT)/clock.o diff --git a/chip/mt_scp/mt8195/clock.c b/chip/mt_scp/mt8195/clock.c new file mode 100644 index 0000000000..bf85af2254 --- /dev/null +++ b/chip/mt_scp/mt8195/clock.c @@ -0,0 +1,432 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Clocks, PLL and power settings */ + +#include <assert.h> +#include <string.h> + +#include "clock.h" +#include "common.h" +#include "console.h" +#include "csr.h" +#include "ec_commands.h" +#include "power.h" +#include "registers.h" +#include "timer.h" + +#define CPRINTF(format, args...) cprintf(CC_CLOCK, format, ##args) +#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ##args) + +enum scp_clock_source { + SCP_CLK_SYSTEM, + SCP_CLK_32K, + SCP_CLK_ULPOSC1, + SCP_CLK_ULPOSC2_LOW_SPEED, + SCP_CLK_ULPOSC2_HIGH_SPEED, +}; + +enum { + OPP_ULPOSC2_LOW_SPEED, + OPP_ULPOSC2_HIGH_SPEED, +}; + +static struct opp_ulposc_cfg { + uint32_t osc; + uint32_t div; + uint32_t fband; + uint32_t mod; + uint32_t cali; + uint32_t target_mhz; + uint32_t clk_div; +} opp[] = { + [OPP_ULPOSC2_LOW_SPEED] = { + .osc = 1, .target_mhz = 326, .clk_div = CLK_DIV_SEL2, .div = 19, + .fband = 10, .mod = 0, .cali = 64, /* 326MHz / 2 = 163MHz */ + }, + [OPP_ULPOSC2_HIGH_SPEED] = { + .osc = 1, .target_mhz = 360, .clk_div = CLK_DIV_SEL1, .div = 21, + .fband = 10, .mod = 0, .cali = 64, /* 360MHz / 1 = 360MHz */ + }, +}; + +static inline void clock_busy_udelay(int usec) +{ + /* + * Delaying by busy-looping, for place that can't use udelay because of + * the clock not configured yet. The value 28 is chosen approximately + * from experiment. + * + * `volatile' in order to avoid compiler to optimize the function out + * (otherwise, the function will be eliminated). + */ + volatile int i = usec * 28; + + while (--i) + ; +} + +static void clock_ulposc_config_default(struct opp_ulposc_cfg *opp) +{ + uint32_t val = 0; + + /* set mod, div2_en = 0, cp_en = 0 */ + val |= opp->mod << OSC_MOD_SHIFT; + /* set div */ + val |= opp->div << OSC_DIV_SHIFT; + /* set F-band, I-band = 82 */ + val |= (opp->fband << OSC_FBAND_SHIFT) | (82 << OSC_IBAND_SHIFT); + /* set calibration */ + val |= opp->cali; + /* set control register 0 */ + AP_ULPOSC_CON0(opp->osc) = val; + + clock_busy_udelay(50); + + /* bias = 65 */ + val = 65 << OSC_BIAS_SHIFT; + /* rsv2 = 0, rsv1 = 41, cali_32k = 0 */ + val |= 41 << OSC_RSV1_SHIFT; + /* set control register 1 */ + AP_ULPOSC_CON1(opp->osc) = val; + + /* set settle time */ + SCP_CLK_HIGH_VAL = + (SCP_CLK_HIGH_VAL & ~CLK_HIGH_VAL_MASK) | CLK_HIGH_VAL_VAL(2); +} + +static void clock_ulposc_config_cali(struct opp_ulposc_cfg *opp, + uint32_t cali_val) +{ + uint32_t val; + + val = AP_ULPOSC_CON0(opp->osc); + val &= ~OSC_CALI_MASK; + val |= cali_val; + AP_ULPOSC_CON0(opp->osc) = val; + opp->cali = cali_val; + + clock_busy_udelay(50); +} + +static uint32_t clock_ulposc_measure_freq(uint32_t osc) +{ + uint32_t result = 0; + int cnt; + + /* Set ckgen_load_cnt: CLK26CALI_1[25:16] */ + AP_CLK26CALI_1 = CFG_CKGEN_LOAD_CNT; + + /* before select meter clock input, bit[1:0] = b00 */ + AP_CLK_DBG_CFG = (AP_CLK_DBG_CFG & ~DBG_MODE_MASK) | + DBG_MODE_SET_CLOCK; + + /* select monclk_ext2fqmtr_sel: AP_CLK_DBG_CFG[14:8] */ + AP_CLK_DBG_CFG = (AP_CLK_DBG_CFG & ~DBG_BIST_SOURCE_MASK) | + (osc == 0 ? DBG_BIST_SOURCE_ULPOSC1 : + DBG_BIST_SOURCE_ULPOSC2); + + /* set meter divisor to 1, bit[31:24] = b00000000 */ + AP_CLK_MISC_CFG_0 = (AP_CLK_MISC_CFG_0 & ~MISC_METER_DIVISOR_MASK) | + MISC_METER_DIV_1; + + /* enable frequency meter, without start */ + AP_CLK26CALI_0 |= CFG_FREQ_METER_ENABLE; + + /* trigger frequency meter start */ + AP_CLK26CALI_0 |= CFG_FREQ_METER_RUN; + + clock_busy_udelay(45); + + for (cnt = 10000; cnt > 0; --cnt) { + clock_busy_udelay(10); + if (!(AP_CLK26CALI_0 & CFG_FREQ_METER_RUN)) { + result = CFG_FREQ_COUNTER(AP_CLK26CALI_1); + break; + } + } + + /* disable freq meter */ + AP_CLK26CALI_0 &= ~CFG_FREQ_METER_ENABLE; + + return result; +} + +#define CAL_MIS_RATE 40 +static int clock_ulposc_is_calibrated(struct opp_ulposc_cfg *opp) +{ + uint32_t curr, target; + + curr = clock_ulposc_measure_freq(opp->osc); + target = opp->target_mhz * 512 / 26; + +#ifdef DEBUG + CPRINTF("osc:%u, target=%uMHz, curr=%uMHz, cali:%u\n", + opp->osc, opp->target_mhz, (curr * 26) / 512, opp->cali); +#endif + + /* check if calibrated value is in the range of target value +- 4% */ + if (curr > (target * (1000 - CAL_MIS_RATE) / 1000) && + curr < (target * (1000 + CAL_MIS_RATE) / 1000)) + return 1; + else + return 0; +} + +static uint32_t clock_ulposc_process_cali(struct opp_ulposc_cfg *opp) +{ + uint32_t current_val = 0; + uint32_t target_val = opp->target_mhz * 512 / 26; + uint32_t middle, min = 0, max = OSC_CALI_MASK; + uint32_t diff_by_min, diff_by_max, cal_result; + + do { + middle = (min + max) / 2; + if (middle == min) + break; + + clock_ulposc_config_cali(opp, middle); + current_val = clock_ulposc_measure_freq(opp->osc); + + if (current_val > target_val) + max = middle; + else + min = middle; + } while (min <= max); + + clock_ulposc_config_cali(opp, min); + current_val = clock_ulposc_measure_freq(opp->osc); + if (current_val > target_val) + diff_by_min = current_val - target_val; + else + diff_by_min = target_val - current_val; + + clock_ulposc_config_cali(opp, max); + current_val = clock_ulposc_measure_freq(opp->osc); + if (current_val > target_val) + diff_by_max = current_val - target_val; + else + diff_by_max = target_val - current_val; + + if (diff_by_min < diff_by_max) + cal_result = min; + else + cal_result = max; + + clock_ulposc_config_cali(opp, cal_result); + if (!clock_ulposc_is_calibrated(opp)) + assert(0); + + return cal_result; +} + +static void clock_high_enable(int osc) +{ + /* enable high speed clock */ + SCP_CLK_ENABLE |= CLK_HIGH_EN; + + switch (osc) { + case 0: + /* after 150us, enable ULPOSC */ + clock_busy_udelay(150); + SCP_CLK_ENABLE |= CLK_HIGH_CG | CLK_HIGH_EN; + + /* topck ulposc1 clk gating off */ + AP_CLK_CFG_29_CLR = PDN_F_ULPOSC_CK; + /* select topck ulposc1 as scp clk parent */ + AP_CLK_CFG_29_CLR = ULPOSC1_CLK_SEL; + + AP_CLK_CFG_UPDATE3 = F_ULPOSC_CK_UPDATE; + clock_busy_udelay(50); + break; + case 1: + /* turn off ULPOSC2 high-core-disable switch */ + SCP_CLK_ON_CTRL &= ~HIGH_CORE_DIS_SUB; + /* after 150us, scp requests ULPOSC2 high core clock */ + clock_busy_udelay(150); + SCP_CLK_HIGH_CORE_CG |= HIGH_CORE_CG; + SCP_CLK_ENABLE &= ~CLK_HIGH_CG; + clock_busy_udelay(50); + + /* topck ulposc2 clk gating off */ + AP_CLK_CFG_29_CLR = PDN_F_ULPOSC_CORE_CK; + /* select topck ulposc2 as scp clk parent */ + AP_CLK_CFG_29_CLR = ULPOSC2_CLK_SEL; + + AP_CLK_CFG_UPDATE3 = F_ULPOSC_CORE_CK_UPDATE; + clock_busy_udelay(50); + break; + default: + break; + } +} + +static void clock_high_disable(int osc) +{ + switch (osc) { + case 0: + /* topck ulposc1 clk gating on */ + AP_CLK_CFG_29_SET = PDN_F_ULPOSC_CK; + AP_CLK_CFG_UPDATE3 = F_ULPOSC_CK_UPDATE; + clock_busy_udelay(50); + + /* scp doesn't request ulposc1 clk */ + SCP_CLK_ENABLE &= ~CLK_HIGH_CG; + clock_busy_udelay(50); + SCP_CLK_ENABLE &= ~CLK_HIGH_EN; + clock_busy_udelay(50); + break; + case 1: + /* topck ulposc2 clk gating on */ + AP_CLK_CFG_29_SET = PDN_F_ULPOSC_CORE_CK; + AP_CLK_CFG_UPDATE3 = F_ULPOSC_CORE_CK_UPDATE; + clock_busy_udelay(50); + + /* scp doesn't request ulposc2 clk */ + SCP_CLK_HIGH_CORE_CG &= ~HIGH_CORE_CG; + clock_busy_udelay(50); + SCP_CLK_ON_CTRL |= HIGH_CORE_DIS_SUB; + clock_busy_udelay(50); + break; + default: + break; + } +} + +static void clock_calibrate_ulposc(struct opp_ulposc_cfg *opp) +{ + /* + * ULPOSC1(osc=0) is already + * - calibrated + * - enabled in coreboot + * - used by pmic wrapper + */ + if (opp->osc != 0) { + clock_high_disable(opp->osc); + clock_ulposc_config_default(opp); + clock_high_enable(opp->osc); + } + + /* Calibrate only if it is not accurate enough. */ + if (!clock_ulposc_is_calibrated(opp)) + opp->cali = clock_ulposc_process_cali(opp); +} + +static void clock_select_clock(enum scp_clock_source src) +{ + uint32_t sel; + uint32_t div; + + switch (src) { + case SCP_CLK_SYSTEM: + div = CLK_DIV_SEL1; + sel = CLK_SW_SEL_SYSTEM; + break; + case SCP_CLK_32K: + div = CLK_DIV_SEL1; + sel = CLK_SW_SEL_32K; + break; + case SCP_CLK_ULPOSC1: + div = CLK_DIV_SEL1; + sel = CLK_SW_SEL_ULPOSC1; + break; + case SCP_CLK_ULPOSC2_LOW_SPEED: + /* parking at scp system clk until ulposc clk is ready */ + clock_select_clock(SCP_CLK_SYSTEM); + + clock_ulposc_config_cali(&opp[OPP_ULPOSC2_LOW_SPEED], + opp[OPP_ULPOSC2_LOW_SPEED].cali); + div = opp[OPP_ULPOSC2_LOW_SPEED].clk_div; + + sel = CLK_SW_SEL_ULPOSC2; + break; + case SCP_CLK_ULPOSC2_HIGH_SPEED: + /* parking at scp system clk until ulposc clk is ready */ + clock_select_clock(SCP_CLK_SYSTEM); + + clock_ulposc_config_cali(&opp[OPP_ULPOSC2_HIGH_SPEED], + opp[OPP_ULPOSC2_HIGH_SPEED].cali); + div = opp[OPP_ULPOSC2_HIGH_SPEED].clk_div; + + sel = CLK_SW_SEL_ULPOSC2; + break; + default: + div = CLK_DIV_SEL1; + sel = CLK_SW_SEL_SYSTEM; + break; + } + + SCP_CLK_DIV_SEL = div; + SCP_CLK_SW_SEL = sel; +} + +__override void +power_chipset_handle_host_sleep_event(enum host_sleep_event state, + struct host_sleep_event_context *ctx) +{ + if (state == HOST_SLEEP_EVENT_S3_SUSPEND) { + CPRINTS("AP suspend"); + clock_select_clock(SCP_CLK_ULPOSC2_LOW_SPEED); + } else if (state == HOST_SLEEP_EVENT_S3_RESUME) { + CPRINTS("AP resume"); + clock_select_clock(SCP_CLK_ULPOSC2_HIGH_SPEED); + } +} + +void clock_init(void) +{ + uint32_t i; + + /* select scp system clock (default 26MHz) */ + clock_select_clock(SCP_CLK_SYSTEM); + + /* set VREQ to HW mode */ + SCP_CPU_VREQ_CTRL = VREQ_SEL | VREQ_DVFS_SEL; + SCP_CLK_CTRL_GENERAL_CTRL &= ~VREQ_PMIC_WRAP_SEL; + SCP_SEC_CTRL &= ~VREQ_SECURE_DIS; + + /* set DDREN to auto mode */ + SCP_SYS_CTRL |= AUTO_DDREN; + + /* set settle time */ + SCP_CLK_SYS_VAL = + (SCP_CLK_SYS_VAL & ~CLK_SYS_VAL_MASK) | CLK_SYS_VAL_VAL(1); + SCP_CLK_HIGH_VAL = + (SCP_CLK_HIGH_VAL & ~CLK_HIGH_VAL_MASK) | CLK_HIGH_VAL_VAL(1); + SCP_SLEEP_CTRL = + (SCP_SLEEP_CTRL & ~VREQ_COUNT_MASK) | VREQ_COUNT_VAL(1); + + /* turn off ULPOSC2 */ + SCP_CLK_ON_CTRL |= HIGH_CORE_DIS_SUB; + + /* calibrate ULPOSC2 */ + for (i = 0; i < ARRAY_SIZE(opp); ++i) + clock_calibrate_ulposc(&opp[i]); + + /* select ULPOSC2 high speed SCP clock */ + clock_select_clock(SCP_CLK_ULPOSC2_HIGH_SPEED); + + /* select BCLK to use ULPOSC / 8 */ + SCP_BCLK_CK_SEL = BCLK_CK_SEL_ULPOSC_DIV8; + + /* enable default clock gate */ + SCP_SET_CLK_CG |= CG_DMA_CH3 | CG_DMA_CH2 | CG_DMA_CH1 | CG_DMA_CH0 | + CG_I2C_MCLK | CG_MAD_MCLK | CG_AP2P_MCLK; +} + +#ifdef DEBUG +int command_ulposc(int argc, char *argv[]) +{ + uint32_t osc; + + for (osc = 0; osc <= OPP_ULPOSC2_HIGH_SPEED; ++osc) + ccprintf("ULPOSC%u frequency: %u kHz\n", osc + 1, + clock_ulposc_measure_freq(osc) * 26 * 1000 / 512); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(ulposc, command_ulposc, "[ulposc]", + "Measure ULPOSC frequency"); +#endif diff --git a/chip/mt_scp/mt8195/clock_regs.h b/chip/mt_scp/mt8195/clock_regs.h new file mode 100644 index 0000000000..6e7ec6bdbb --- /dev/null +++ b/chip/mt_scp/mt8195/clock_regs.h @@ -0,0 +1,92 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* SCP clock module registers */ + +#ifndef __CROS_EC_CLOCK_REGS_H +#define __CROS_EC_CLOCK_REGS_H + +/* clock source select */ +#define SCP_CLK_SW_SEL REG32(SCP_CLK_CTRL_BASE + 0x0000) +#define CLK_SW_SEL_SYSTEM 0 +#define CLK_SW_SEL_32K 1 +#define CLK_SW_SEL_ULPOSC2 2 +#define CLK_SW_SEL_ULPOSC1 3 +#define SCP_CLK_ENABLE REG32(SCP_CLK_CTRL_BASE + 0x0004) +#define CLK_HIGH_EN BIT(1) /* ULPOSC */ +#define CLK_HIGH_CG BIT(2) +/* clock general control */ +#define SCP_CLK_CTRL_GENERAL_CTRL REG32(SCP_CLK_CTRL_BASE + 0x009C) +#define VREQ_PMIC_WRAP_SEL (0x3) + +/* TOPCK clk */ +#define TOPCK_BASE AP_REG_BASE +#define AP_CLK_CFG_UPDATE3 REG32(TOPCK_BASE + 0x0010) +#define F_ULPOSC_CK_UPDATE BIT(21) +#define F_ULPOSC_CORE_CK_UPDATE BIT(22) +#define AP_CLK_CFG_29_SET REG32(TOPCK_BASE + 0x0180) +#define AP_CLK_CFG_29_CLR REG32(TOPCK_BASE + 0x0184) +#define ULPOSC1_CLK_SEL (0x3 << 8) +#define PDN_F_ULPOSC_CK BIT(15) +#define ULPOSC2_CLK_SEL (0x3 << 16) +#define PDN_F_ULPOSC_CORE_CK BIT(23) +/* OSC meter */ +#define AP_CLK_DBG_CFG REG32(TOPCK_BASE + 0x020C) +#define DBG_MODE_MASK 3 +#define DBG_MODE_SET_CLOCK 0 +#define DBG_BIST_SOURCE_MASK (0x7f << 8) +#define DBG_BIST_SOURCE_ULPOSC1 (0x30 << 8) +#define DBG_BIST_SOURCE_ULPOSC2 (0x32 << 8) +#define AP_CLK26CALI_0 REG32(TOPCK_BASE + 0x0218) +#define CFG_FREQ_METER_RUN BIT(4) +#define CFG_FREQ_METER_ENABLE BIT(7) +#define AP_CLK26CALI_1 REG32(TOPCK_BASE + 0x021C) +#define CFG_CKGEN_LOAD_CNT 0x01ff0000 +#define CFG_FREQ_COUNTER(CFG1) ((CFG1) & 0xFFFF) +#define AP_CLK_MISC_CFG_0 REG32(TOPCK_BASE + 0x022C) +#define MISC_METER_DIVISOR_MASK 0xff000000 +#define MISC_METER_DIV_1 0 +/* + * ULPOSC + * osc: 0 for ULPOSC1, 1 for ULPOSC2. + */ +#define AP_ULPOSC_CON0_BASE (AP_REG_BASE + 0xC2B0) +#define AP_ULPOSC_CON1_BASE (AP_REG_BASE + 0xC2B4) +#define AP_ULPOSC_CON0(osc) \ + REG32(AP_ULPOSC_CON0_BASE + (osc) * 0x10) +#define AP_ULPOSC_CON1(osc) \ + REG32(AP_ULPOSC_CON1_BASE + (osc) * 0x10) +/* + * AP_ULPOSC_CON0 + * bit0-6: calibration + * bit7-13: iband + * bit14-17: fband + * bit18-23: div + * bit24: cp_en + * bit25-26: mod + * bit27: div2_en + * bit28-31: reserved + */ +#define OSC_CALI_SHIFT 0 +#define OSC_CALI_MASK 0x7f +#define OSC_IBAND_SHIFT 7 +#define OSC_FBAND_SHIFT 14 +#define OSC_DIV_SHIFT 18 +#define OSC_CP_EN BIT(24) +#define OSC_MOD_SHIFT 25 +#define OSC_DIV2_EN BIT(27) +/* + * AP_ULPOSC_CON1 + * bit0-7: rsv1 + * bit8-15: rsv2 + * bit16-23: 32K calibration + * bit24-31: bias + */ +#define OSC_RSV1_SHIFT 0 +#define OSC_RSV2_SHIFT 8 +#define OSC_32KCALI_SHIFT 16 +#define OSC_BIAS_SHIFT 24 + +#endif /* __CROS_EC_CLOCK_REGS_H */ diff --git a/chip/mt_scp/rv32i_common/build.mk b/chip/mt_scp/rv32i_common/build.mk index 3c09548a8c..ac7e13db77 100644 --- a/chip/mt_scp/rv32i_common/build.mk +++ b/chip/mt_scp/rv32i_common/build.mk @@ -10,7 +10,6 @@ CORE:=riscv-rv32i # Required chip modules chip-y+=rv32i_common/cache.o -chip-y+=rv32i_common/clock.o chip-y+=rv32i_common/gpio.o chip-y+=rv32i_common/intc.o chip-y+=rv32i_common/memmap.o diff --git a/chip/mt_scp/rv32i_common/clock_chip.h b/chip/mt_scp/rv32i_common/clock_chip.h deleted file mode 100644 index ee1c22be92..0000000000 --- a/chip/mt_scp/rv32i_common/clock_chip.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Clocks, PLL and power settings */ - -#ifndef __CROS_EC_CLOCK_CHIP_H -#define __CROS_EC_CLOCK_CHIP_H - -#include "registers.h" - -enum scp_clock_source { - SCP_CLK_26M = CLK_SW_SEL_26M, - SCP_CLK_32K = CLK_SW_SEL_32K, - SCP_CLK_ULPOSC2 = CLK_SW_SEL_ULPOSC2, - SCP_CLK_ULPOSC1 = CLK_SW_SEL_ULPOSC1, -}; - -/* Switches to use 'src' clock */ -void clock_select_clock(enum scp_clock_source src); - -#endif /* __CROS_EC_CLOCK_CHIP_H */ diff --git a/chip/mt_scp/rv32i_common/registers.h b/chip/mt_scp/rv32i_common/registers.h index f4d03aa228..b19afe5e0d 100644 --- a/chip/mt_scp/rv32i_common/registers.h +++ b/chip/mt_scp/rv32i_common/registers.h @@ -17,15 +17,6 @@ /* clock control */ #define SCP_CLK_CTRL_BASE (SCP_REG_BASE + 0x21000) -/* clock source select */ -#define SCP_CLK_SW_SEL REG32(SCP_CLK_CTRL_BASE + 0x0000) -#define CLK_SW_SEL_26M 0 -#define CLK_SW_SEL_32K 1 -#define CLK_SW_SEL_ULPOSC2 2 -#define CLK_SW_SEL_ULPOSC1 3 -#define SCP_CLK_ENABLE REG32(SCP_CLK_CTRL_BASE + 0x0004) -#define CLK_HIGH_EN BIT(1) /* ULPOSC */ -#define CLK_HIGH_CG BIT(2) /* system clock counter value */ #define SCP_CLK_SYS_VAL REG32(SCP_CLK_CTRL_BASE + 0x0014) #define CLK_SYS_VAL_MASK (0x3ff << 0) @@ -117,9 +108,6 @@ #define HIGH_CORE_AO BIT(4) #define HIGH_CORE_DIS_SUB BIT(5) #define HIGH_CORE_CG_AO BIT(6) -/* clock general control */ -#define SCP_CLK_CTRL_GENERAL_CTRL REG32(SCP_CLK_CTRL_BASE + 0x009C) -#define VREQ_PMIC_WRAP_SEL (0x2) /* system control */ #define SCP_SYS_CTRL REG32(SCP_REG_BASE + 0x24000) @@ -212,22 +200,6 @@ /* external address: AP */ #define AP_REG_BASE 0x60000000 /* 0x10000000 remap to 0x6 */ -/* OSC meter */ -#define TOPCK_BASE AP_REG_BASE -#define AP_CLK_MISC_CFG_0 REG32(TOPCK_BASE + 0x0140) -#define MISC_METER_DIVISOR_MASK 0xff000000 -#define MISC_METER_DIV_1 0 -#define AP_CLK_DBG_CFG REG32(TOPCK_BASE + 0x017C) -#define DBG_MODE_MASK 3 -#define DBG_MODE_SET_CLOCK 0 -#define DBG_BIST_SOURCE_MASK (0x3f << 16) -#define DBG_BIST_SOURCE_ULPOSC1 (0x25 << 16) -#define DBG_BIST_SOURCE_ULPOSC2 (0x24 << 16) -#define AP_SCP_CFG_0 REG32(TOPCK_BASE + 0x0220) -#define CFG_FREQ_METER_RUN BIT(4) -#define CFG_FREQ_METER_ENABLE BIT(12) -#define AP_SCP_CFG_1 REG32(TOPCK_BASE + 0x0224) -#define CFG_FREQ_COUNTER(CFG1) ((CFG1) & 0xFFFF) /* AP GPIO */ #define AP_GPIO_BASE (AP_REG_BASE + 0x5000) #define AP_GPIO_MODE11_SET REG32(AP_GPIO_BASE + 0x03B4) @@ -236,49 +208,8 @@ #define AP_GPIO_MODE12_CLR REG32(AP_GPIO_BASE + 0x03C8) #define AP_GPIO_MODE20_SET REG32(AP_GPIO_BASE + 0x0444) #define AP_GPIO_MODE20_CLR REG32(AP_GPIO_BASE + 0x0448) -/* - * ULPOSC - * osc: 0 for ULPOSC1, 1 for ULPOSC2. - */ -#define AP_ULPOSC_CON0_BASE (AP_REG_BASE + 0xC2B0) -#define AP_ULPOSC_CON1_BASE (AP_REG_BASE + 0xC2B4) -#define AP_ULPOSC_CON2_BASE (AP_REG_BASE + 0xC2B8) -#define AP_ULPOSC_CON0(osc) \ - REG32(AP_ULPOSC_CON0_BASE + (osc) * 0x10) -#define AP_ULPOSC_CON1(osc) \ - REG32(AP_ULPOSC_CON1_BASE + (osc) * 0x10) -#define AP_ULPOSC_CON2(osc) \ - REG32(AP_ULPOSC_CON2_BASE + (osc) * 0x10) -/* - * AP_ULPOSC_CON0 - * bit0-6: calibration - * bit7-13: iband - * bit14-17: fband - * bit18-23: div - * bit24: cp_en - * bit25-31: reserved - */ -#define OSC_CALI_MASK 0x7f -#define OSC_IBAND_SHIFT 7 -#define OSC_FBAND_SHIFT 14 -#define OSC_DIV_SHIFT 18 -#define OSC_CP_EN BIT(24) -/* AP_ULPOSC_CON1 - * bit0-7: 32K calibration - * bit 8-15: rsv1 - * bit 16-23: rsv2 - * bit 24-25: mod - * bit26: div2_en - * bit27-31: reserved - */ -#define OSC_RSV1_SHIFT 8 -#define OSC_RSV2_SHIFT 16 -#define OSC_MOD_SHIFT 24 -#define OSC_DIV2_EN BIT(26) -/* AP_ULPOSC_CON2 - * bit0-7: bias - * bit8-31: reserved - */ + +#include "clock_regs.h" /* IRQ numbers */ #define SCP_IRQ_GIPC_IN0 0 |