Hello Roger Lu, Ran Bi,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/46878
to review the following change.
Change subject: soc/mediatek/mt8192: add clkbuf and srclken_rc MT6359P driver ......................................................................
soc/mediatek/mt8192: add clkbuf and srclken_rc MT6359P driver
Add clkbuf and srclken_rc init for low power.
TEST=boot asurada
Signed-off-by: Ran Bi ran.bi@mediatek.com Change-Id: I947bf14df7a307bf359c590c2a20265882b3f1be --- M src/soc/mediatek/mt8192/Makefile.inc M src/soc/mediatek/mt8192/bootblock.c A src/soc/mediatek/mt8192/clkbuf.c M src/soc/mediatek/mt8192/include/soc/addressmap.h A src/soc/mediatek/mt8192/include/soc/clkbuf.h M src/soc/mediatek/mt8192/include/soc/pmif.h M src/soc/mediatek/mt8192/include/soc/rtc.h A src/soc/mediatek/mt8192/include/soc/srclken_rc.h M src/soc/mediatek/mt8192/pmif.c M src/soc/mediatek/mt8192/rtc.c A src/soc/mediatek/mt8192/srclken_rc.c 11 files changed, 1,381 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/78/46878/1
diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc index d695824..6890910 100755 --- a/src/soc/mediatek/mt8192/Makefile.inc +++ b/src/soc/mediatek/mt8192/Makefile.inc @@ -12,6 +12,7 @@ bootblock-y += ../common/uart.c bootblock-y += ../common/wdt.c bootblock-y += pmif.c pmif_clk.c pmif_spi.c pmif_spmi.c +bootblock-y += clkbuf.c srclken_rc.c bootblock-y += ../common/rtc.c rtc.c bootblock-y += mt6315.c bootblock-y += mt6359p.c diff --git a/src/soc/mediatek/mt8192/bootblock.c b/src/soc/mediatek/mt8192/bootblock.c old mode 100755 new mode 100644 index dac9a37..5d1380a --- a/src/soc/mediatek/mt8192/bootblock.c +++ b/src/soc/mediatek/mt8192/bootblock.c @@ -1,14 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <bootblock_common.h> +#include <soc/clkbuf.h> +#include <soc/eint_event.h> #include <soc/mmu_operations.h> #include <soc/mt6315.h> #include <soc/mt6359p.h> #include <soc/pll.h> #include <soc/pmif.h> -#include <soc/wdt.h> #include <soc/rtc.h> -#include <soc/eint_event.h> +#include <soc/srclken_rc.h> +#include <soc/wdt.h>
void bootblock_soc_init(void) { @@ -19,5 +21,7 @@ mt6359p_init(); mt6315_init(); unmask_eint_event_mask(); + srclken_rc_init(); + clk_buf_init(); rtc_boot(); } diff --git a/src/soc/mediatek/mt8192/clkbuf.c b/src/soc/mediatek/mt8192/clkbuf.c new file mode 100644 index 0000000..937a227 --- /dev/null +++ b/src/soc/mediatek/mt8192/clkbuf.c @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/mmio.h> +#include <soc/clkbuf.h> +#include <soc/pmif.h> +#include <soc/srclken_rc.h> + + +#define BUFTAG "[CLKBUF]" +#define buf_info(fmt, arg ...) printk(BIOS_INFO, BUFTAG "%s,%d: " fmt, \ + __func__, __LINE__, ## arg) + +//#define clkbuf_readl_ap(addr) read32(addr) +//#define clkbuf_writel_ap(addr, val) write32(addr, val) + + +#define PMIC_REG_MASK 0xFFFF +#define PMIC_REG_SHIFT 0 + +/* #define CLKBUF_CONN_SUPPORT_CTRL_FROM_I1 */ + +#if 0 +#if MTK_SRCLKEN_RC_FULL_SET +#define PMIC_CW00_INIT_VAL 0x4A4D /* 0100 1010 0100 1101 */ +#define PMIC_CW09_INIT_VAL 0x51F0 /* 0101 0001 1111 0000 */ +#else +#define PMIC_CW00_INIT_VAL 0x4E1D /* 0100 1110 0001 1101 */ +#define PMIC_CW09_INIT_VAL 0x31F0 /* 0011 0001 1111 0000 */ +#endif +#endif + +#define PMIC_CW00_INIT_VAL 0x4005 /* 0100 0000 0000 0101 */ +#define PMIC_CW09_INIT_VAL 0x01F0 /* 0000 0001 1111 0000 */ + +static struct pmif *pmif_arb = NULL; + +static int buf_read(u32 addr, u32 *rdata) +{ + if (pmif_arb == NULL) + pmif_arb = get_pmif_controller(PMIF_SPI, 0); + return pmif_arb->read_cmd(pmif_arb, 0, addr, rdata); +} + +static int buf_write(u32 addr, u32 wdata) +{ + if (pmif_arb == NULL) + pmif_arb = get_pmif_controller(PMIF_SPI, 0); + return pmif_arb->write_cmd(pmif_arb, 0, addr, wdata); +} + +static u32 buf_read_field(u32 reg, u32 mask, u32 shift) +{ + u32 rdata; + + buf_read(reg, &rdata); + rdata &= (mask << shift); + rdata = (rdata >> shift); + + return rdata; +} + +static void buf_write_field(u32 reg, u32 val, u32 mask, u32 shift) +{ + u32 old, new; + + buf_read(reg, &old); + new = old & ~(mask << shift); + new |= (val << shift); + buf_write(reg, new); +} + +static void clk_buf_dump_clkbuf_log(void) +{ + u32 pmic_cw00 = 0, pmic_cw09 = 0, pmic_cw12 = 0, pmic_cw13 = 0, + pmic_cw15 = 0, pmic_cw19 = 0, top_spi_con1 = 0, + ldo_vrfck_op_en = 0, ldo_vbbck_op_en = 0, ldo_vrfck_en = 0, + ldo_vbbck_en = 0; + /*u32 vrfck_vosel = 0, vrfck_votrim = 0;*/ + u32 vrfck_hv_en = 0; + + pmic_cw00 = buf_read_field(PMIC_RG_DCXO_CW00, 0xffff, 0); + pmic_cw09 = buf_read_field(PMIC_RG_DCXO_CW09, 0xffff, 0); + pmic_cw12 = buf_read_field(PMIC_RG_DCXO_CW12, 0xffff, 0); + pmic_cw13 = buf_read_field(PMIC_RG_DCXO_CW13, 0xffff, 0); + pmic_cw15 = buf_read_field(PMIC_RG_DCXO_CW15, 0xffff, 0); + pmic_cw19 = buf_read_field(PMIC_RG_DCXO_CW19, 0xffff, 0); + top_spi_con1 = buf_read_field(PMIC_RG_TOP_SPI_CON1, 0x1, 0); + ldo_vrfck_op_en = buf_read_field(PMIC_RG_LDO_VRFCK_OP_EN, 0x1, 14); + ldo_vbbck_op_en = buf_read_field(PMIC_RG_LDO_VBBCK_OP_EN, 0x1, 14); + ldo_vrfck_en = buf_read_field(PMIC_RG_LDO_VRFCK_CON0, 0x1, 0); + ldo_vbbck_en = buf_read_field(PMIC_RG_LDO_VBBCK_CON0, 0x1, 0); + buf_info("DCXO_CW00/09/12/13/15/19=0x%x %x %x %x %x %x\n", + pmic_cw00, pmic_cw09, pmic_cw12, + pmic_cw13, pmic_cw15, pmic_cw19); + buf_info("spi_con1/ldo_rf_op/ldo_bb_op/ldo_rf_en/ldo_bb_en=0x%x %x %x %x %x\n", + top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en, + ldo_vrfck_en, ldo_vbbck_en); + + vrfck_hv_en = buf_read_field(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, 0x1, 9); + buf_info("clk buf vrfck_hv_en=0x%x\n", vrfck_hv_en); +} + +static void clk_buf_init_pmic_clkbuf(void) +{ + /* Dump registers before setting */ + clk_buf_dump_clkbuf_log(); + +#if 1 + /* 1.0 XO_WCN/XO_RF switch from VS1 to LDO VRFCK_1 */ + /* unlock pmic key */ + buf_write_field(PMIC_TOP_TMA_KEY, 0x9CA6, 0xFFFF, 0); + + /* 1.1 set VRFCK input supply(11.ac mode) */ + buf_write_field(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, 0x0, + PMIC_RG_VRFCK_HV_EN_MASK, PMIC_RG_VRFCK_HV_EN_SHIFT); + + /* 1.2.0 Set VRFCK En = 0 */ + buf_write_field(PMIC_RG_LDO_VRFCK_CON0, 0x0, + PMIC_RG_LDO_VRFCK_EN_MASK, PMIC_RG_LDO_VRFCK_EN_SHIFT); + /* 1.2.1 set VRFCK1 as power src */ + buf_write_field(PMIC_RG_LDO_VRFCK_ELR, 0x1, + PMIC_RG_LDO_VRFCK_ANA_SEL_MASK, PMIC_RG_LDO_VRFCK_ANA_SEL_SHIFT); + + /* 1.2.2 switch LDO-RFCK to LDO-RFCK1 */ + buf_write_field(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, 0x0, + PMIC_RG_VRFCK_NDIS_EN_MASK, PMIC_RG_VRFCK_NDIS_EN_SHIFT); + buf_write_field(PMIC_RG_DCXO_ADLDO_BIAS_ELR_1, 0x1, + PMIC_RG_VRFCK_1_NDIS_EN_MASK, PMIC_RG_VRFCK_1_NDIS_EN_SHIFT); + + /* 1.2.0 Set VRFCK En = 1 */ + buf_write_field(PMIC_RG_LDO_VRFCK_CON0, 0x1, + PMIC_RG_LDO_VRFCK_EN_MASK, PMIC_RG_LDO_VRFCK_EN_SHIFT); + + /* 1.2.3 lock pmic key */ + buf_write_field(PMIC_TOP_TMA_KEY, 0, 0xFFFF, 0); + + /* enable XO LDO */ + buf_write_field(PMIC_RG_LDO_VRFCK_OP_EN_SET, 0x1, + PMIC_RG_LDO_VRFCK_HW14_OP_EN_MASK, PMIC_RG_LDO_VRFCK_HW14_OP_EN_SHIFT); + buf_write_field(PMIC_RG_LDO_VBBCK_OP_EN_SET, 0x1, + PMIC_RG_LDO_VBBCK_HW14_OP_EN_MASK, PMIC_RG_LDO_VBBCK_HW14_OP_EN_SHIFT); + buf_write_field(PMIC_RG_LDO_VRFCK_CON0, 0x0, + PMIC_RG_LDO_VRFCK_EN_MASK, PMIC_RG_LDO_VRFCK_EN_SHIFT); + buf_write_field(PMIC_RG_LDO_VBBCK_CON0, 0x0, + PMIC_RG_LDO_VBBCK_EN_MASK, PMIC_RG_LDO_VBBCK_EN_SHIFT); + +#endif + +#if 0 + /* Setup initial PMIC clock buffer setting */ + /* 1.1 Buffer de-sense setting */ + /* FIXME: read dts and set to SRSEL and HD */ + buf_write_field(PMIC_RG_DCXO_CW13, PMIC_CLK_BUF2_CONTROLS_FOR_DESENSE, + 0x7, 0); + buf_write_field(PMIC_RG_DCXO_CW13, PMIC_CLK_BUF3_CONTROLS_FOR_DESENSE, + 0x3, 10); + buf_write_field(PMIC_RG_DCXO_CW13, PMIC_CLK_BUF4_CONTROLS_FOR_DESENSE, + 0x7, 4); +#endif + +#if 0 + /* 1.2 Buffer setting for trace impedance */ + /* FIXME: read dts and set to RSEL */ + buf_write_field(PMIC_RG_DCXO_CW19, PMIC_CLK_BUF1_OUTPUT_IMPEDANCE, + 0x7, 1); + buf_write_field(PMIC_RG_XO_EXTBUF2_RSEL_ADDR, PMIC_CLK_BUF2_OUTPUT_IMPEDANCE, + PMIC_RG_XO_EXTBUF2_RSEL_MASK, PMIC_RG_XO_EXTBUF2_RSEL_SHIFT); + buf_write_field(PMIC_RG_XO_EXTBUF3_RSEL_ADDR, PMIC_CLK_BUF3_OUTPUT_IMPEDANCE, + PMIC_RG_XO_EXTBUF3_RSEL_MASK, PMIC_RG_XO_EXTBUF3_RSEL_SHIFT); + buf_write_field(PMIC_RG_XO_EXTBUF4_RSEL_ADDR, PMIC_CLK_BUF4_OUTPUT_IMPEDANCE, + PMIC_RG_XO_EXTBUF4_RSEL_MASK, PMIC_RG_XO_EXTBUF4_RSEL_SHIFT); + buf_write_field(PMIC_RG_XO_EXTBUF7_RSEL_ADDR, PMIC_CLK_BUF7_OUTPUT_IMPEDANCE, + PMIC_RG_XO_EXTBUF7_RSEL_MASK, PMIC_RG_XO_EXTBUF7_RSEL_SHIFT); +#endif + + /* 1.4 26M enable control */ +#ifndef MTK_SRCLKEN_RC_SUPPORT + + /*Legacy co-clock mode */ +#ifdef CLKBUF_CONN_SUPPORT_CTRL_FROM_I1 + buf_write_field(PMIC_RG_DCXO_CW12, 0x1, 0x1, 12); +#else + buf_write_field(PMIC_RG_TOP_SPI_CON1, 0, 0x1, 0); +#endif + + buf_write_field(PMIC_RG_DCXO_CW00, PMIC_CW00_INIT_VAL, 0xFFFF, 0); + buf_write_field(PMIC_RG_DCXO_CW09, PMIC_CW09_INIT_VAL, 0xFFFF, 0); + +#else /* MTK_SRCLKEN_RC_SUPPORT */ + +#if MTK_SRCLKEN_RC_FULL_SET + + /* fully new co-clock mode */ + + /* All XO mode should set to 2'b01 */ + buf_write_field(PMIC_RG_DCXO_CW00, PMIC_CW00_INIT_VAL, 0xFFFF, 0); + buf_info("part2.1 done\n"); + buf_write_field(PMIC_RG_DCXO_CW09, PMIC_CW09_INIT_VAL, 0xFFFF, 0); + buf_info("part2.2 done\n"); + + /* 1.update control mapping table */ + /* + * XO_SOC_VOTE=11'h005 + */ + buf_write_field(PMIC_RG_XO_BUF_CTL0, 0x005, 0x7FF, 0); + + /* 2.switch to new control mode */ + /* + * XO_PMIC_TOP_DIG_SW=0 + * XO_MODE_CONN_BT_MASK=0 (BTonly : 1) + * XO_BUF_CONN_BT_MASK=0 (BTonly : 1 ) + */ + buf_write_field(PMIC_RG_DCXO_CW08, 0x0, + 0x1, 2); + buf_info("part2.3 done\n"); + buf_write_field(PMIC_RG_XO_CONN_BT0, 0x0, + 0x1, 0); + buf_info("part2.4 done\n"); + buf_write_field(PMIC_RG_XO_CONN_BT0, 0x0, + 0x1, 1); + buf_info("part2.5 done\n"); + +#endif +#endif /* MTK_SRCLKEN_RC_SUPPORT */ + + /* Check if the setting is ok */ + clk_buf_dump_clkbuf_log(); +} + +static void clk_buf_init_pmic_wrap(void) +{ +#if 0 + /* Setup PMIC_WRAP setting for XO2 & XO3 */ + if (CLK_BUF2_STATUS_PMIC != CLOCK_BUFFER_DISABLE) { +#ifdef CLKBUF_CONN_SUPPORT_CTRL_FROM_I1 + clkbuf_writel_ap(PMIFSPI_DCXO_CMD_ADDR0, PMIC_DCXO_CW00_CLR_ADDR | (PMIC_DCXO_CW00_SET_ADDR << DCXO_CMD_ADDR0_1_SHFT)); + clkbuf_writel_ap(PMIFSPI_DCXO_CMD_WDATA0, (PMIC_XO_EXTBUF2_EN_M_MASK << PMIC_XO_EXTBUF2_EN_M_SHIFT) + | (PMIC_XO_EXTBUF2_EN_M_MASK << PMIC_XO_EXTBUF2_EN_M_SHIFT) << DCXO_CMD_WDATA0_1_SHFT ); +#else + clkbuf_writel_ap(PMIFSPI_DCXO_CMD_ADDR0, PMIC_RG_SRCLKEN_IN3_EN_ADDR | (PMIC_RG_SRCLKEN_IN3_EN_ADDR << DCXO_CMD_ADDR0_1_SHFT)); + clkbuf_writel_ap(PMIFSPI_DCXO_CMD_WDATA0, (0 << PMIC_RG_SRCLKEN_IN3_EN_SHIFT) + | (1 << PMIC_RG_SRCLKEN_IN3_EN_SHIFT) << DCXO_CMD_WDATA0_1_SHFT ); +#endif + } + + if (CLK_BUF3_STATUS_PMIC != CLOCK_BUFFER_DISABLE) { + clkbuf_writel_ap(PMIFSPI_DCXO_CMD_ADDR1, PMIC_DCXO_CW00_CLR_ADDR | (PMIC_DCXO_CW00_SET_ADDR << DCXO_CMD_ADDR0_1_SHFT)); + clkbuf_writel_ap(PMIFSPI_DCXO_CMD_WDATA1, (PMIC_XO_EXTBUF3_EN_M_MASK << PMIC_XO_EXTBUF3_EN_M_SHIFT) + | (PMIC_XO_EXTBUF3_EN_M_MASK << PMIC_XO_EXTBUF3_EN_M_SHIFT) << DCXO_CMD_WDATA0_1_SHFT ); + } + + buf_info("DCXO_CMD_ADR0/WDATA0=0x%x/%x\n", + clkbuf_readl_ap(PMIFSPI_DCXO_CMD_ADDR0), + clkbuf_readl_ap(PMIFSPI_DCXO_CMD_WDATA0)); + buf_info("DCXO_CMD_ADR1/WDATA1=0x%x/%x\n", + clkbuf_readl_ap(PMIFSPI_DCXO_CMD_ADDR1), + clkbuf_readl_ap(PMIFSPI_DCXO_CMD_WDATA1)); +#endif +} + +int clk_buf_init(void) +{ + clk_buf_init_pmic_clkbuf(); + clk_buf_init_pmic_wrap(); + + return 0; +} + diff --git a/src/soc/mediatek/mt8192/include/soc/addressmap.h b/src/soc/mediatek/mt8192/include/soc/addressmap.h index 85eac5b..3266a3a 100644 --- a/src/soc/mediatek/mt8192/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8192/include/soc/addressmap.h @@ -20,6 +20,8 @@ INFRACFG_AO_MEM_BASE = IO_PHYS + 0x00002000, GPIO_BASE = IO_PHYS + 0x00005000, SPM_BASE = IO_PHYS + 0x00006000, + RC_BASE = IO_PHYS + 0x00006500, + RC_STATUS_BASE = IO_PHYS + 0x00006E00, RGU_BASE = IO_PHYS + 0x00007000, GPT_BASE = IO_PHYS + 0x00008000, EINT_BASE = IO_PHYS + 0x0000B000, diff --git a/src/soc/mediatek/mt8192/include/soc/clkbuf.h b/src/soc/mediatek/mt8192/include/soc/clkbuf.h new file mode 100644 index 0000000..2facd3e --- /dev/null +++ b/src/soc/mediatek/mt8192/include/soc/clkbuf.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SOC_MEDIATEK_MT8192_CLKBUF_H +#define SOC_MEDIATEK_MT8192_CLKBUF_H + +enum { + PMIC_RG_DCXO_CW00 = 0x0788, + PMIC_RG_DCXO_CW02 = 0x0790, + PMIC_RG_DCXO_CW08 = 0x079C, + PMIC_RG_DCXO_CW09 = 0x079E, + PMIC_RG_DCXO_CW09_CLR = 0x07A2, + PMIC_RG_DCXO_CW10 = 0x07A4, + PMIC_RG_DCXO_CW12 = 0x07A8, + PMIC_RG_DCXO_CW13 = 0x07AA, + PMIC_RG_DCXO_CW15 = 0x07AE, + PMIC_RG_DCXO_CW19 = 0x07B6, +}; + + +enum { + PMIC_TOP_TMA_KEY = 0x3A8, + PMIC_RG_TOP_SPI_CON1 = 0x458, +}; + +enum { + PMIC_RG_LDO_VRFCK_ELR = 0x1b40, + PMIC_RG_LDO_VRFCK_CON0 = 0x1D1C, + PMIC_RG_LDO_VRFCK_OP_EN = 0x1D22, + PMIC_RG_LDO_VRFCK_OP_EN_SET = 0x1D24, + PMIC_RG_LDO_VBBCK_CON0 = 0x1D2E, + PMIC_RG_LDO_VBBCK_OP_EN = 0x1D34, + PMIC_RG_LDO_VBBCK_OP_EN_SET = 0x1D36, +}; + +enum { + PMIC_RG_DCXO_ADLDO_BIAS_ELR_0 = 0x209C, + PMIC_RG_DCXO_ADLDO_BIAS_ELR_1 = 0x209E, +}; + +enum { + PMIC_RG_XO_BUF_CTL0 = 0x54C, + PMIC_RG_XO_CONN_BT0 = 0x556, +}; + +#define PMIC_RG_VRFCK_HV_EN_MASK 0x1 +#define PMIC_RG_VRFCK_HV_EN_SHIFT 9 +#define PMIC_RG_LDO_VRFCK_EN_MASK 0x1 +#define PMIC_RG_LDO_VRFCK_EN_SHIFT 0 +#define PMIC_RG_LDO_VRFCK_ANA_SEL_MASK 0x1 +#define PMIC_RG_LDO_VRFCK_ANA_SEL_SHIFT 0 +#define PMIC_RG_LDO_VBBCK_EN_MASK 0x1 +#define PMIC_RG_LDO_VBBCK_EN_SHIFT 0 +#define PMIC_RG_VRFCK_NDIS_EN_MASK 0x1 +#define PMIC_RG_VRFCK_NDIS_EN_SHIFT 11 +#define PMIC_RG_VRFCK_1_NDIS_EN_MASK 0x1 +#define PMIC_RG_VRFCK_1_NDIS_EN_SHIFT 0 +#define PMIC_RG_LDO_VRFCK_HW14_OP_EN_MASK 0x1 +#define PMIC_RG_LDO_VRFCK_HW14_OP_EN_SHIFT 14 +#define PMIC_RG_LDO_VBBCK_HW14_OP_EN_MASK 0x1 +#define PMIC_RG_LDO_VBBCK_HW14_OP_EN_SHIFT 14 + +int clk_buf_init(void); + +#endif + diff --git a/src/soc/mediatek/mt8192/include/soc/pmif.h b/src/soc/mediatek/mt8192/include/soc/pmif.h index 6106a3d..71f3724 100644 --- a/src/soc/mediatek/mt8192/include/soc/pmif.h +++ b/src/soc/mediatek/mt8192/include/soc/pmif.h @@ -154,7 +154,48 @@ E_SPI_INIT_SIDLY, /* SPI edge calibration fail */ };
+enum pmic_interface { + PMIF_VLD_RDY = 0, + PMIF_SLP_REQ, + PMIF_MAX, +}; + +#define PMIFSPI_INF_EN_SRCLKEN_RC_HW_MSK 0x1 +#define PMIFSPI_INF_EN_SRCLKEN_RC_HW_SHFT 4 +#define PMIFSPI_OTHER_INF_DXCO0_EN_MSK 0x1 +#define PMIFSPI_OTHER_INF_DXCO0_EN_SHFT 0 +#define PMIFSPI_OTHER_INF_DXCO1_EN_MSK 0x1 +#define PMIFSPI_OTHER_INF_DXCO1_EN_SHFT 1 +#define PMIFSPI_ARB_EN_SRCLKEN_RC_HW_MSK 0x1 +#define PMIFSPI_ARB_EN_SRCLKEN_RC_HW_SHFT 4 +#define PMIFSPI_ARB_EN_DCXO_CONN_MSK 0x1 +#define PMIFSPI_ARB_EN_DCXO_CONN_SHFT 15 +#define PMIFSPI_ARB_EN_DCXO_NFC_MSK 0x1 +#define PMIFSPI_ARB_EN_DCXO_NFC_SHFT 16 +#define PMIFSPI_SPM_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPI_SPM_SLEEP_REQ_SEL_SHFT 0 +#define PMIFSPI_SCP_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPI_SCP_SLEEP_REQ_SEL_SHFT 9 +#define PMIFSPI_MD_CTL_PMIF_RDY_MSK 0x1 +#define PMIFSPI_MD_CTL_PMIF_RDY_SHFT 11 +#define PMIFSPI_MD_CTL_SRCLK_EN_MSK 0x1 +#define PMIFSPI_MD_CTL_SRCLK_EN_SHFT 12 +#define PMIFSPI_MD_CTL_SRVOL_EN_MSK 0x1 +#define PMIFSPI_MD_CTL_SRVOL_EN_SHFT 13 + +#define PMIFSPMI_SPM_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPMI_SPM_SLEEP_REQ_SEL_SHFT 0 +#define PMIFSPMI_SCP_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPMI_SCP_SLEEP_REQ_SEL_SHFT 9 +#define PMIFSPMI_MD_CTL_PMIF_RDY_MSK 0x1 +#define PMIFSPMI_MD_CTL_PMIF_RDY_SHFT 11 +#define PMIFSPMI_MD_CTL_SRCLK_EN_MSK 0x1 +#define PMIFSPMI_MD_CTL_SRCLK_EN_SHFT 12 +#define PMIFSPMI_MD_CTL_SRVOL_EN_MSK 0x1 +#define PMIFSPMI_MD_CTL_SRVOL_EN_SHFT 13 + /* start external API */ extern struct pmif *get_pmif_controller(int inf, int mstid); +extern void pmwrap_interface_init(void); extern int mtk_pmif_init(void); #endif /*__MT8192_SOC_PMIF_H__*/ diff --git a/src/soc/mediatek/mt8192/include/soc/rtc.h b/src/soc/mediatek/mt8192/include/soc/rtc.h index bad7c68..4ec7475 100755 --- a/src/soc/mediatek/mt8192/include/soc/rtc.h +++ b/src/soc/mediatek/mt8192/include/soc/rtc.h @@ -159,6 +159,7 @@ PMIC_RG_BANK_FQMTR_RST_SHIFT = 6 };
+#if 0 /* PMIC DCXO Register Definition */ enum { PMIC_RG_DCXO_CW00 = 0x0788, @@ -171,6 +172,7 @@ PMIC_RG_DCXO_CW09_CLR = 0x07A2, PMIC_RG_DCXO_CW12 = 0x07A8 }; +#endif
/* PMIC Frequency Meter Definition */ enum { diff --git a/src/soc/mediatek/mt8192/include/soc/srclken_rc.h b/src/soc/mediatek/mt8192/include/soc/srclken_rc.h new file mode 100644 index 0000000..0ed4da9 --- /dev/null +++ b/src/soc/mediatek/mt8192/include/soc/srclken_rc.h @@ -0,0 +1,425 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SOC_MEDIATEK_MT8192_SRCLKEN_RC_H +#define SOC_MEDIATEK_MT8192_SRCLKEN_RC_H + +//#include <soc/addressmap.h> + +struct mtk_rc_regs { + u32 srclken_rc_cfg; + u32 rc_central_cfg1; + u32 rc_central_cfg2; + u32 rc_cmd_arb_cfg; + u32 rc_pmic_rcen_addr; + u32 rc_pmic_rcen_set_clr_addr; + u32 rc_dcxo_fpm_cfg; + u32 rc_central_cfg3; + u32 rc_mxx_srclken_cfg[13]; + u32 srclken_sw_con_cfg; + u32 rc_central_cfg4; + u32 reserved1; + u32 rc_protocol_chk_cfg; + u32 rc_debug_cfg; + u32 reserved2[19]; + u32 rc_misc_0; + u32 rc_spm_ctrl; + u32 rc_subsys_intf_cfg; +}; + +check_member(mtk_rc_regs, rc_central_cfg1, 0x4); +check_member(mtk_rc_regs, rc_mxx_srclken_cfg[0], 0x20); +check_member(mtk_rc_regs, rc_mxx_srclken_cfg[12], 0x50); +check_member(mtk_rc_regs, rc_central_cfg4, 0x58); +check_member(mtk_rc_regs, rc_protocol_chk_cfg, 0x60); +check_member(mtk_rc_regs, rc_misc_0, 0xb4); +check_member(mtk_rc_regs, rc_subsys_intf_cfg, 0xbc); + +struct mtk_rc_status_regs { + u32 rc_fsm_sta_0; + u32 rc_cmd_sta_0; + u32 rc_cmd_sta_1; + u32 rc_spi_sta_0; + u32 rc_pi_po_sta_0; + u32 rc_mxx_req_sta_0[14]; + u32 reserved2[2]; + u32 rc_debug_trace; +}; + +check_member(mtk_rc_status_regs, rc_cmd_sta_1, 0x8); +check_member(mtk_rc_status_regs, rc_mxx_req_sta_0[0], 0x14); +check_member(mtk_rc_status_regs, rc_mxx_req_sta_0[13], 0x48); +check_member(mtk_rc_status_regs, rc_debug_trace, 0x54); + +/* + * Definitions + */ + +#define MTK_SRCLKEN_RC_BRINGUP (0) +#define MTK_SRCLKEN_RC_SUPPORT +#ifdef MTK_SRCLKEN_RC_SUPPORT +#define MTK_SRCLKEN_RC_FULL_SET (1) +#endif +#define SRCLKEN_DBG (1) + + +//#define AP_BASE (0x1000C000) +//#define SPM_BASE (0x10006000) +//#define RC_BASE (0x10006500) +//#define RC_STATE_BASE (0x10006E00) +//#define PMIF_SPI_BASE (0x10026000) +//#define PMIF_SPMI_BASE (0x10027000) + +#if 0 +/* PMIF Register*/ +#define PMIFSPI_INF_EN (PMIF_SPI_BASE + 0x0024) +#define PMIFSPI_INF_EN_SRCLKEN_RC_HW_MSK 0x1 +#define PMIFSPI_INF_EN_SRCLKEN_RC_HW_SHFT 4 + +#define PMIFSPI_OTHER_INF_EN (PMIF_SPI_BASE + 0x0028) +#define PMIFSPI_OTHER_INF_DXCO0_EN_MSK 0x1 +#define PMIFSPI_OTHER_INF_DXCO0_EN_SHFT 0 +#define PMIFSPI_OTHER_INF_DXCO1_EN_MSK 0x1 +#define PMIFSPI_OTHER_INF_DXCO1_EN_SHFT 1 + +#define PMIFSPI_DCXO_CMD_ADDR0 (PMIF_SPI_BASE + 0x005C) +#define DCXO_CMD_ADDR0_0_MSK 0xffff +#define DCXO_CMD_ADDR0_0_SHFT 0 +#define DCXO_CMD_ADDR0_1_MSK 0xffff +#define DCXO_CMD_ADDR0_1_SHFT 16 + +#define PMIFSPI_DCXO_CMD_WDATA0 (PMIF_SPI_BASE + 0x0060) +#define DCXO_CMD_WDATA0_0_MSK 0xffff +#define DCXO_CMD_WDATA0_0_SHFT 0 +#define DCXO_CMD_WDATA0_1_MSK 0xffff +#define DCXO_CMD_WDATA0_1_SHFT 16 + +#define PMIFSPI_DCXO_CMD_ADDR1 (PMIF_SPI_BASE + 0x0064) +#define DCXO_CMD_ADDR1_0_MSK 0xffff +#define DCXO_CMD_ADDR1_0_SHFT 0 +#define DCXO_CMD_ADDR1_1_MSK 0xffff +#define DCXO_CMD_ADDR1_1_SHFT 16 + +#define PMIFSPI_DCXO_CMD_WDATA1 (PMIF_SPI_BASE + 0x0068) +#define DCXO_CMD_WDATA1_0_MSK 0xffff +#define DCXO_CMD_WDATA1_0_SHFT 0 +#define DCXO_CMD_WDATA1_1_MSK 0xffff +#define DCXO_CMD_WDATA1_1_SHFT 16 + +#define PMIFSPI_ARB_EN (PMIF_SPI_BASE + 0x0150) +#define PMIFSPI_ARB_EN_SRCLKEN_RC_HW_MSK 0x1 +#define PMIFSPI_ARB_EN_SRCLKEN_RC_HW_SHFT 4 +#define PMIFSPI_ARB_EN_DCXO_CONN_MSK 0x1 +#define PMIFSPI_ARB_EN_DCXO_CONN_SHFT 15 +#define PMIFSPI_ARB_EN_DCXO_NFC_MSK 0x1 +#define PMIFSPI_ARB_EN_DCXO_NFC_SHFT 16 + +#define PMIFSPI_SLEEP_PROTECTION_CRL (PMIF_SPI_BASE + 0x03E8) +#define PMIFSPI_SPM_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPI_SPM_SLEEP_REQ_SEL_SHFT 0 +#define PMIFSPI_SCP_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPI_SCP_SLEEP_REQ_SEL_SHFT 9 + +#define PMIFSPI_MODE_CRL (PMIF_SPI_BASE + 0x0400) +#define PMIFSPI_MD_CTL_PMIF_RDY_MSK 0x1 +#define PMIFSPI_MD_CTL_PMIF_RDY_SHFT 11 +#define PMIFSPI_MD_CTL_SRCLK_EN_MSK 0x1 +#define PMIFSPI_MD_CTL_SRCLK_EN_SHFT 12 +#define PMIFSPI_MD_CTL_SRVOL_EN_MSK 0x1 +#define PMIFSPI_MD_CTL_SRVOL_EN_SHFT 13 + +#define PMIFSPMI_SLEEP_PROTECTION_CRL (PMIF_SPMI_BASE + 0x03E8) +#define PMIFSPMI_SPM_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPMI_SPM_SLEEP_REQ_SEL_SHFT 0 +#define PMIFSPMI_SCP_SLEEP_REQ_SEL_MSK 0x3 +#define PMIFSPMI_SCP_SLEEP_REQ_SEL_SHFT 9 + +#define PMIFSPMI_MODE_CRL (PMIF_SPMI_BASE + 0x0400) +#define PMIFSPMI_MD_CTL_PMIF_RDY_MSK 0x1 +#define PMIFSPMI_MD_CTL_PMIF_RDY_SHFT 11 +#define PMIFSPMI_MD_CTL_SRCLK_EN_MSK 0x1 +#define PMIFSPMI_MD_CTL_SRCLK_EN_SHFT 12 +#define PMIFSPMI_MD_CTL_SRVOL_EN_MSK 0x1 +#define PMIFSPMI_MD_CTL_SRVOL_EN_SHFT 13 +#endif + +/* SPM Register */ +#define ULPOSC_CON (SPM_BASE + 0x0440) +#define ULPOSC_EN_SHFT 0 +#define ULPOSC_RST_SHFT 1 +#define ULPOSC_CG_EN_SHFT 2 +#define ULPOSC_CLK_SEL_SHFT 3 + +#define SRCLKEN_RC_CFG (RC_BASE + 0x0000) +#define SW_RESET_MSK 0x1 +#define SW_RESET_SHFT 0 +#define CG_32K_EN_MSK 0x1 +#define CG_32K_EN_SHFT 1 +#define CG_FCLK_EN_MSK 0x1 +#define CG_FCLK_EN_SHFT 2 +#define CG_FCLK_FR_EN_MSK 0x1 +#define CG_FCLK_FR_EN_SHFT 3 +#define MUX_FCLK_FR_MSK 0x1 +#define MUX_FCLK_FR_SHFT 4 +#define RC_32K_DCM_MSK 0x1 +#define RC_32K_DCM_SHFT 8 + + +#define RC_CENTRAL_CFG1 (RC_BASE + 0x0004) +#define SRCLKEN_RC_EN_MSK 0x1 +#define SRCLKEN_RC_EN_SHFT 0 +#define RCEN_ISSUE_M_MSK 0x1 +#define RCEN_ISSUE_M_SHFT 1 +#define RC_SPI_ACTIVE_MSK 0x1 +#define RC_SPI_ACTIVE_SHFT 2 +#define SRCLKEN_RC_EN_SEL_MSK 0x1 +#define SRCLKEN_RC_EN_SEL_SHFT 3 +#define VCORE_SETTLE_T_MSK 0x7 +#define VCORE_SETTLE_T_SHFT 5 +#define ULPOSC_SETTLE_T_MSK 0xf +#define ULPOSC_SETTLE_T_SHFT 8 +#define NON_DCXO_SETTLE_T_MSK 0x3ff +#define NON_DCXO_SETTLE_T_SHFT 12 +#define DCXO_SETTLE_T_MSK 0x3ff +#define DCXO_SETTLE_T_SHFT 22 + +#define RC_CENTRAL_CFG2 (RC_BASE + 0x0008) +#define SRCVOLTEN_CTRL_MSK 0xf +#define SRCVOLTEN_CTRL_SHFT 0 +#define VREQ_CTRL_MSK 0xf +#define VREQ_CTRL_SHFT 4 +#define SRCVOLTEN_VREQ_SEL_MSK 0x1 +#define SRCVOLTEN_VREQ_SEL_SHFT 8 +#define SRCVOLTEN_VREQ_M_MSK 0x1 +#define SRCVOLTEN_VREQ_M_SHFT 9 +#define FORCE_SRCVOLTEN_OFF_MSK 0x1 +#define FORCE_SRCVOLTEN_OFF_SHFT 10 +#define FORCE_SRCVOLTEN_ON_MSK 0x1 +#define FORCE_SRCVOLTEN_ON_SHFT 11 +#define ULPOSC_CTRL_M_MSK 0xf +#define ULPOSC_CTRL_M_SHFT 12 +#define FORCE_VCORE_RDY_MSK 0x1 +#define FORCE_VCORE_RDY_SHFT 16 +#define FORCE_ULPOSC2ON_MSK 0x1 +#define FORCE_ULPOSC2ON_SHFT 17 +#define FORCE_ULPOSC_CLK_EN_MSK 0x1 +#define FORCE_ULPOSC_CLK_EN_SHFT 18 +#define FORCE_ULPOSC_ON_MSK 0x1 +#define FORCE_ULPOSC_ON_SHFT 19 +#define DIS_ULPOSC_RDY_CHK_MSK 0x1 +#define DIS_ULPOSC_RDY_CHK_SHFT 20 +#define PWRAP_SLP_CTRL_M_MSK 0xf +#define PWRAP_SLP_CTRL_M_SHFT 21 +#define PWRAP_SLP_MUX_SEL_MSK 0x1 +#define PWRAP_SLP_MUX_SEL_SHFT 25 +#define FORCE_PWRAP_ON_MSK 0x1 +#define FORCE_PWRAP_ON_SHFT 26 +#define FORCE_PWRAP_AWK_MSK 0x1 +#define FORCE_PWRAP_AWK_SHFT 27 +#define NON_DCXO_REQ_FORCEON_MSK 0x1 +#define NON_DCXO_REQ_FORCEON_SHFT 28 +#define NON_DCXO_REQ_FORCEOFF_MSK 0x1 +#define NON_DCXO_REQ_FORCEOFF_SHFT 29 +#define DCXO_REQ_FORCEON_MSK 0x1 +#define DCXO_REQ_FORCEON_SHFT 30 +#define DCXO_REQ_FORCEOFF_MSK 0x1 +#define DCXO_REQ_FORCEOFF_SHFT 31 + +#define RC_CMD_ARB_CFG (RC_BASE + 0x000C) +#define SW_RC_EN_MSK 0x1fff +#define SW_RC_EN_SHFT 0 +#define SW_RCEN_EN_MSK 0x1fff +#define SW_RCEN_EN_SHFT 13 +#define SW_DCXO_M_EN_MSK 0x1 +#define SW_DCXO_M_EN_SHFT 28 +#define SW_DCXO_M_MSK 0x7 +#define SW_DCXO_M_SHFT 29 + +#define RC_PMIC_RCEN_ADDR (RC_BASE + 0x0010) +#define RC_PMIC_RCEN_SET_CLR_ADDR (RC_BASE + 0x0014) +#define RC_DCXO_FPM_CFG (RC_BASE + 0x0018) +#define DCXO_FPM_CTRL_M_MSK 0xf +#define DCXO_FPM_CTRL_M_SHFT 0 +#define SRCVOLTEN_FPM_MSK_B_MSK 0x1 +#define SRCVOLTEN_FPM_MSK_B_SHFT 4 +#define SUB_SRCLKEN_FPM_MSK_B_MSK 0x1fff +#define SUB_SRCLKEN_FPM_MSK_B_SHFT 16 + +#define RC_CENTRAL_CFG3 (RC_BASE + 0x001C) +#define TO_LPM_SETTLE_EN_MSK 0x1 +#define TO_LPM_SETTLE_EN_SHFT 0 +#define BLK_SCP_DXCO_MD_TARGET_MSK 0x1 +#define BLK_SCP_DXCO_MD_TARGET_SHFT 1 +#define BLK_COANT_DXCO_MD_TARGET_MSK 0x1 +#define BLK_COANT_DXCO_MD_TARGET_SHFT 2 +#define TO_BBLPM_SETTLE_EN_MSK 0x1 +#define TO_BBLPM_SETTLE_EN_SHFT 0x3 +#define TO_BBLPM_SETTLE_ND_EN_MSK 0x1 +#define TO_BBLPM_SETTLE_ND_EN_SHFT 0x4 +#define TO_LPM_SETTLE_T_MSK 0x2ff +#define TO_LPM_SETTLE_T_SHFT 12 + +#define RC_MXX_SRCLKEN_CFG (RC_BASE + 0x0020) +#define DCXO_SETTLE_BLK_EN_MSK 0x1 +#define DCXO_SETTLE_BLK_EN_SHFT 1 +#define BYPASS_CMD_EN_MSK 0x1 +#define BYPASS_CMD_EN_SHFT 2 +#define SW_SRCLKEN_RC_MSK 0x1 +#define SW_SRCLKEN_RC_SHFT 3 +#define SW_SRCLKEN_FPM_MSK 0x1 +#define SW_SRCLKEN_FPM_SHFT 4 +#define SW_SRCLKEN_BBLPM_MSK 0x1 +#define SW_SRCLKEN_BBLPM_SHFT 5 +#define XO_SOC_LINK_EN_MSK 0x1 +#define XO_SOC_LINK_EN_SHFT 6 +#define REQ_ACK_LOW_IMD_EN_MSK 0x1 +#define REQ_ACK_LOW_IMD_EN_SHFT 7 +#define SRCLKEN_TRACK_M_EN_MSK 0x1 +#define SRCLKEN_TRACK_M_EN_SHFT 8 +#define CNT_PRD_STEP_MSK 0x3 +#define CNT_PRD_STEP_SHFT 10 +#define XO_STABLE_PRD_MSK 0x3ff +#define XO_STABLE_PRD_SHFT 12 +#define DCXO_STABLE_PRD_MSK 0x3ff +#define DCXO_STABLE_PRD_SHFT 22 + +#define RC_DEBUG_TRACE (RC_BASE + 0x0054) +#define TACE_EN_MSK 0x1 +#define TACE_EN_SHFT 0 + +#define RC_CENTRAL_CFG4 (RC_BASE + 0x0058) +#define KEEP_RC_SPI_ACTIVE_MSK 0x1ff +#define KEEP_RC_SPI_ACTIVE_SHFT 0 +#define PWRAP_VLD_FORCE_MAK 0x1 +#define PWRAP_VLD_FORCE_SHFT 16 +#define SLEEP_VLD_MODE_MAK 0x1 +#define SLEEP_VLD_MODE_SHFT 17 +#define SCP_SLEEP_REQ_MODE_MAK 0x1 +#define SCP_SLEEP_REQ_MODE_SHFT 18 +#define SLEEP_REQ_MODE_MSK 0x1 +#define SLEEP_REQ_MODE_SHFT 20 + +#define RC_DEBUG_CFG (RC_BASE + 0x0064) +#define TRACE_MODE_EN_MSK 0x1 +#define TRACE_MODE_EN_SHFT 24 +#define DBG_STOP_PROT_EN_MSK 0x1 +#define DBG_STOP_PROT_EN_SHFT 28 + +#define SUBSYS_INTF_CFG (RC_BASE + 0x00BC) +#define SRCLKEN_FPM_MASK_B_MSK 0x1fff +#define SRCLKEN_FPM_MASK_B_SHFT 0 +#define SRCLKEN_BBLPM_MASK_B_MSK 0x1fff +#define SRCLKEN_BBLPM_MASK_B_SHFT 16 + +#define RC_PI_PO_STA (RC_STATUS_BASE + 0x0010) +#define RC_MXX_REQ_STA_0 (RC_STATUS_BASE + 0x0014) +#define FPM_ACK_MSK 0x1 +#define FPM_ACK_SHFT 1 +#define BBLPM_ACK_MSK 0x1 +#define BBLPM_ACK_SHFT 3 + +#define RC_SPI_STA_0 (RC_STATUS_BASE + 0x000C) + +/*#define TEST_UFS (UFS_HCI_BASE + 0x0144)*/ + +enum { + PMIC_PMRC_CON0 = 0x1A6, +}; + +typedef struct { + u32 osc_div; + u32 cali_val; +} ulposc_con_t; + +enum { + ULPOSC_DIV_1 = 0, + ULPOSC_DIV_4 = 1 +}; + +enum chn_id { + CHN_SUSPEND = 0, + CHN_RF = 1, + CHN_DEEPIDLE = 2, + CHN_MD= 3, + CHN_GPS = 4, + CHN_BT = 5, + CHN_WIFI = 6, + CHN_MCU = 7, + CHN_COANT = 8, + CHN_NFC = 9, + CHN_UFS = 10, + CHN_SCP = 11, + CHN_RESERVE = 12, + MAX_CHN_NUM, +}; + +enum { + SRCLKENAO_MODE, + VREQ_MODE, +}; + +enum { + MERGE_OR_MODE = 0x0, + BYPASS_MODE = 0x1, + MERGE_AND_MODE = 0x1 << 1, + BYPASS_RC_MODE = 0x2 << 1, + BYPASS_OTHER_MODE = 0x3 << 1, + ASYNC_MODE = 0x1 << 3, +}; + +enum { + RC_32K = 0, + RC_ULPOSC1, +}; + +enum rc_ctrl_m { + HW_MODE = 0, + SW_MODE = 1, + INIT_MODE = 0xff, +}; + +enum rc_ctrl_r { + NO_REQ = 0, + FPM_REQ = 1 << SW_SRCLKEN_FPM_SHFT, + BBLPM_REQ = 1 << SW_SRCLKEN_BBLPM_SHFT, +}; + +enum { + SRLCKEN_RC_BRINGUP = 0, + SRCLKEN_RC_DISABLE, + SRCLKEN_RC_ENABLE, + SRCLKEN_RC_SKIP, +}; + +struct subsys_rc_con { + enum chn_id id; + unsigned int dcxo_prd; + unsigned int xo_prd; + unsigned int cnt_step; + unsigned int track_en; + unsigned int req_ack_imd_en; + unsigned int xo_soc_link_en; + unsigned int sw_bblpm; + unsigned int sw_fpm; + unsigned int sw_rc; + unsigned int bypass_cmd; + unsigned int dcxo_settle_blk_en; +}; + +#define RC_SUBSYS_SET(_dcxo_prd, _xo_prd, _cnt_step, _track_en, \ + _req_ack_imd_en, _xo_soc_link_en, _sw_bblpm, \ + _sw_fpm, _sw_rc, _bypass_settle) { \ + .dcxo_prd = _dcxo_prd, \ + .xo_prd = _xo_prd, \ + .cnt_step = _cnt_step, \ + .track_en = _track_en, \ + .req_ack_imd_en = _req_ack_imd_en, \ + .xo_soc_link_en = _xo_soc_link_en, \ + .sw_bblpm = _sw_bblpm, \ + .sw_fpm = _sw_fpm, \ + .sw_rc = _sw_rc, \ + .bypass_settle = _bypass_settle, \ + } + +//extern void rc_ctrl_mode_switch_hw(enum chn_id id); +//extern void rc_ctrl_mode_switch_sw(enum chn_id id); +extern int srclken_rc_init(void); +#endif diff --git a/src/soc/mediatek/mt8192/pmif.c b/src/soc/mediatek/mt8192/pmif.c index 295deaf..c7d325b 100644 --- a/src/soc/mediatek/mt8192/pmif.c +++ b/src/soc/mediatek/mt8192/pmif.c @@ -156,6 +156,134 @@ return NULL; }
+static void pmif_select(enum pmic_interface mode) +{ + unsigned int spi_sleep_ctrl, spmi_sleep_ctrl; + unsigned int spi_mode_ctrl, spmi_mode_ctrl; + unsigned int inf_en, other_inf_en, arb_en; + + spi_sleep_ctrl = read32(&pmif_spi_arb[0].mtk_pmif->sleep_protection_ctrl); + spmi_sleep_ctrl = read32(&pmif_spmi_arb[0].mtk_pmif->sleep_protection_ctrl); + spi_mode_ctrl = read32(&pmif_spi_arb[0].mtk_pmif->spi_mode_ctrl); + spmi_mode_ctrl = read32(&pmif_spmi_arb[0].mtk_pmif->spi_mode_ctrl); + inf_en = read32(&pmif_spi_arb[0].mtk_pmif->inf_en); + other_inf_en = read32(&pmif_spi_arb[0].mtk_pmif->other_inf_en); + arb_en = read32(&pmif_spi_arb[0].mtk_pmif->arb_en); + + if(PMIF_VLD_RDY == mode){ + /* spm and scp sleep request disable spi and spmi */ + spi_sleep_ctrl = (spi_sleep_ctrl & ~(PMIFSPI_SPM_SLEEP_REQ_SEL_MSK << PMIFSPI_SPM_SLEEP_REQ_SEL_SHFT)) + | (0x1 << PMIFSPI_SPM_SLEEP_REQ_SEL_SHFT); + spi_sleep_ctrl = (spi_sleep_ctrl & ~(PMIFSPI_SCP_SLEEP_REQ_SEL_MSK << PMIFSPI_SCP_SLEEP_REQ_SEL_SHFT)) + | (0x1 << PMIFSPI_SCP_SLEEP_REQ_SEL_SHFT); + + spmi_sleep_ctrl = (spmi_sleep_ctrl & ~(PMIFSPMI_SPM_SLEEP_REQ_SEL_MSK << PMIFSPMI_SPM_SLEEP_REQ_SEL_SHFT)) + | (0x1 << PMIFSPMI_SPM_SLEEP_REQ_SEL_SHFT); + spmi_sleep_ctrl = (spmi_sleep_ctrl & ~(PMIFSPMI_SCP_SLEEP_REQ_SEL_MSK << PMIFSPMI_SCP_SLEEP_REQ_SEL_SHFT)) + | (0x1 << PMIFSPMI_SCP_SLEEP_REQ_SEL_SHFT); + /* pmic vld/rdy control spi mode enable*/ + spi_mode_ctrl = (spi_mode_ctrl & ~(PMIFSPI_MD_CTL_PMIF_RDY_MSK << PMIFSPI_MD_CTL_PMIF_RDY_SHFT)) + | (0x1 << PMIFSPI_MD_CTL_PMIF_RDY_SHFT); + /* srclken control spi mode disable*/ + spi_mode_ctrl = (spi_mode_ctrl & ~(PMIFSPI_MD_CTL_SRCLK_EN_MSK << PMIFSPI_MD_CTL_SRCLK_EN_SHFT)) + | (0x0 << PMIFSPI_MD_CTL_SRCLK_EN_SHFT); + /* vreq control spi mode disable*/ + spi_mode_ctrl = (spi_mode_ctrl & ~(PMIFSPI_MD_CTL_SRVOL_EN_MSK << PMIFSPI_MD_CTL_SRVOL_EN_SHFT)) + | (0x0 << PMIFSPI_MD_CTL_SRVOL_EN_SHFT); + spmi_mode_ctrl = (spmi_mode_ctrl & ~(PMIFSPMI_MD_CTL_PMIF_RDY_MSK << PMIFSPMI_MD_CTL_PMIF_RDY_SHFT)) + | (0x1 << PMIFSPMI_MD_CTL_PMIF_RDY_SHFT); + spmi_mode_ctrl = (spmi_mode_ctrl & ~(PMIFSPMI_MD_CTL_SRCLK_EN_MSK << PMIFSPMI_MD_CTL_SRCLK_EN_SHFT)) + | (0x0 << PMIFSPMI_MD_CTL_SRCLK_EN_SHFT); + spmi_mode_ctrl = (spmi_mode_ctrl & ~(PMIFSPMI_MD_CTL_SRVOL_EN_MSK << PMIFSPMI_MD_CTL_SRVOL_EN_SHFT)) + | (0x0 << PMIFSPMI_MD_CTL_SRVOL_EN_SHFT); + + /* srclken rc interface enable*/ + inf_en = (inf_en & ~(PMIFSPI_INF_EN_SRCLKEN_RC_HW_MSK << PMIFSPI_INF_EN_SRCLKEN_RC_HW_SHFT)) + | (0x1 << PMIFSPI_INF_EN_SRCLKEN_RC_HW_SHFT); + + /* dcxo interface disable */ + other_inf_en = (other_inf_en & ~(PMIFSPI_OTHER_INF_DXCO0_EN_MSK << PMIFSPI_OTHER_INF_DXCO0_EN_SHFT)) + | (0x0 << PMIFSPI_OTHER_INF_DXCO0_EN_SHFT); + other_inf_en = (other_inf_en & ~(PMIFSPI_OTHER_INF_DXCO1_EN_MSK << PMIFSPI_OTHER_INF_DXCO1_EN_SHFT)) + | (0x0 << PMIFSPI_OTHER_INF_DXCO1_EN_SHFT); + /*srclken enable, dcxo0,1 disable*/ + arb_en = (arb_en & ~(PMIFSPI_ARB_EN_SRCLKEN_RC_HW_MSK << PMIFSPI_ARB_EN_SRCLKEN_RC_HW_SHFT)) + | (0x1 << PMIFSPI_ARB_EN_SRCLKEN_RC_HW_SHFT); + arb_en = (arb_en & ~(PMIFSPI_ARB_EN_DCXO_CONN_MSK << PMIFSPI_ARB_EN_DCXO_CONN_SHFT)) + | (0x0 << PMIFSPI_ARB_EN_DCXO_CONN_SHFT); + arb_en = (arb_en & ~(PMIFSPI_ARB_EN_DCXO_NFC_MSK << PMIFSPI_ARB_EN_DCXO_NFC_SHFT)) + | (0x0 << PMIFSPI_ARB_EN_DCXO_NFC_SHFT); + + } else if (PMIF_SLP_REQ == mode) { + + /* spm and scp sleep request enable spi and spmi */ + spi_sleep_ctrl = (spi_sleep_ctrl & ~(PMIFSPI_SPM_SLEEP_REQ_SEL_MSK << PMIFSPI_SPM_SLEEP_REQ_SEL_SHFT)) + | (0x0 << PMIFSPI_SPM_SLEEP_REQ_SEL_SHFT); + spi_sleep_ctrl = (spi_sleep_ctrl & ~(PMIFSPI_SCP_SLEEP_REQ_SEL_MSK << PMIFSPI_SCP_SLEEP_REQ_SEL_SHFT)) + | (0x0 << PMIFSPI_SCP_SLEEP_REQ_SEL_SHFT); + + spmi_sleep_ctrl = (spmi_sleep_ctrl & ~(PMIFSPMI_SPM_SLEEP_REQ_SEL_MSK << PMIFSPMI_SPM_SLEEP_REQ_SEL_SHFT)) + | (0x0 << PMIFSPMI_SPM_SLEEP_REQ_SEL_SHFT); + spmi_sleep_ctrl = (spmi_sleep_ctrl & ~(PMIFSPMI_SCP_SLEEP_REQ_SEL_MSK << PMIFSPMI_SCP_SLEEP_REQ_SEL_SHFT)) + | (0x0 << PMIFSPMI_SCP_SLEEP_REQ_SEL_SHFT); + + /* pmic vld/rdy control spi mode disable*/ + spi_mode_ctrl = (spi_mode_ctrl & ~(PMIFSPI_MD_CTL_PMIF_RDY_MSK << PMIFSPI_MD_CTL_PMIF_RDY_SHFT)) + | (0x0 << PMIFSPI_MD_CTL_PMIF_RDY_SHFT); + /* srclken control spi mode enable*/ + spi_mode_ctrl = (spi_mode_ctrl & ~(PMIFSPI_MD_CTL_SRCLK_EN_MSK << PMIFSPI_MD_CTL_SRCLK_EN_SHFT)) + | (0x1 << PMIFSPI_MD_CTL_SRCLK_EN_SHFT); + /* vreq control spi mode enable*/ + spi_mode_ctrl = (spi_mode_ctrl & ~(PMIFSPI_MD_CTL_SRVOL_EN_MSK << PMIFSPI_MD_CTL_SRVOL_EN_SHFT)) + | (0x1 << PMIFSPI_MD_CTL_SRVOL_EN_SHFT); + + spmi_mode_ctrl = (spmi_mode_ctrl & ~(PMIFSPMI_MD_CTL_PMIF_RDY_MSK << PMIFSPMI_MD_CTL_PMIF_RDY_SHFT)) + | (0x0 << PMIFSPMI_MD_CTL_PMIF_RDY_SHFT); + spmi_mode_ctrl = (spmi_mode_ctrl & ~(PMIFSPMI_MD_CTL_SRCLK_EN_MSK << PMIFSPMI_MD_CTL_SRCLK_EN_SHFT)) + | (0x1 << PMIFSPMI_MD_CTL_SRCLK_EN_SHFT); + spmi_mode_ctrl = (spmi_mode_ctrl & ~(PMIFSPMI_MD_CTL_SRVOL_EN_MSK << PMIFSPMI_MD_CTL_SRVOL_EN_SHFT)) + | (0x1 << PMIFSPMI_MD_CTL_SRVOL_EN_SHFT); + + /* srclken rc interface disable*/ + inf_en = (inf_en & ~(PMIFSPI_INF_EN_SRCLKEN_RC_HW_MSK << PMIFSPI_INF_EN_SRCLKEN_RC_HW_SHFT)) + | (0x0 << PMIFSPI_INF_EN_SRCLKEN_RC_HW_SHFT); + /* dcxo interface enable */ + other_inf_en = (other_inf_en & ~(PMIFSPI_OTHER_INF_DXCO0_EN_MSK << PMIFSPI_OTHER_INF_DXCO0_EN_SHFT)) + | (0x1 << PMIFSPI_OTHER_INF_DXCO0_EN_SHFT); + other_inf_en = (other_inf_en & ~(PMIFSPI_OTHER_INF_DXCO1_EN_MSK << PMIFSPI_OTHER_INF_DXCO1_EN_SHFT)) + | (0x1 << PMIFSPI_OTHER_INF_DXCO1_EN_SHFT); + + /*srclken dissable, dcxo0,1 enable*/ + arb_en = (arb_en & ~(PMIFSPI_ARB_EN_SRCLKEN_RC_HW_MSK << PMIFSPI_ARB_EN_SRCLKEN_RC_HW_SHFT)) + | (0x0 << PMIFSPI_ARB_EN_SRCLKEN_RC_HW_SHFT); + arb_en = (arb_en & ~(PMIFSPI_ARB_EN_DCXO_CONN_MSK << PMIFSPI_ARB_EN_DCXO_CONN_SHFT)) + | (0x1 << PMIFSPI_ARB_EN_DCXO_CONN_SHFT); + arb_en = (arb_en & ~(PMIFSPI_ARB_EN_DCXO_NFC_MSK << PMIFSPI_ARB_EN_DCXO_NFC_SHFT)) + | (0x1 << PMIFSPI_ARB_EN_DCXO_NFC_SHFT); + + } else + return; + + write32(&pmif_spi_arb[0].mtk_pmif->sleep_protection_ctrl, spi_sleep_ctrl); + write32(&pmif_spmi_arb[0].mtk_pmif->sleep_protection_ctrl, spmi_sleep_ctrl); + write32(&pmif_spi_arb[0].mtk_pmif->spi_mode_ctrl, spi_mode_ctrl); + write32(&pmif_spmi_arb[0].mtk_pmif->spi_mode_ctrl, spmi_mode_ctrl); + write32(&pmif_spi_arb[0].mtk_pmif->inf_en, inf_en); + write32(&pmif_spi_arb[0].mtk_pmif->other_inf_en, other_inf_en); + write32(&pmif_spi_arb[0].mtk_pmif->arb_en, arb_en); +} + +void pmwrap_interface_init(void){ + /* MTK_SRCLKEN_RC_SUPPORT */ +#if 1 + printk(BIOS_ERR, "[%s] PMIF_VLD_RDY\n", __func__); + pmif_select(PMIF_VLD_RDY); +#else + printk(BIOS_ERR, "[%s] PMIF_SLP_REQ\n", __func__); + pmic_select(PMIF_SLP_REQ); +#endif +} + int mtk_pmif_init(void) { int ret = 1; diff --git a/src/soc/mediatek/mt8192/rtc.c b/src/soc/mediatek/mt8192/rtc.c index f02c633..ca817fa 100755 --- a/src/soc/mediatek/mt8192/rtc.c +++ b/src/soc/mediatek/mt8192/rtc.c @@ -14,6 +14,7 @@ */ #include <delay.h> #include <halt.h> +#include <soc/clkbuf.h> #include <soc/mt6359p.h> #include <soc/pmif.h> #include <soc/rtc_common.h> @@ -428,6 +429,7 @@ halt(); }
+#if 0 static void dcxo_init(void) { u16 tmp; @@ -459,13 +461,17 @@ rtc_write_field(PMIC_RG_DCXO_CW12, 0x2, 0x3, 0); }
+#endif + /* the rtc boot flow entry */ void rtc_boot(void) { u16 tmp;
+#if 0 /* dcxo clock init settings */ dcxo_init(); +#endif /* dcxo 32k init settings */ rtc_write_field(PMIC_RG_DCXO_CW02, 0xF, 0xF, 0); rtc_read(PMIC_RG_SCK_TOP_CON0, &tmp); diff --git a/src/soc/mediatek/mt8192/srclken_rc.c b/src/soc/mediatek/mt8192/srclken_rc.c new file mode 100644 index 0000000..31a0098 --- /dev/null +++ b/src/soc/mediatek/mt8192/srclken_rc.c @@ -0,0 +1,437 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <delay.h> +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/pmif.h> +#include <soc/srclken_rc.h> + +#define RCTAG "[SRCLKEN_RC]" +#define rc_info(fmt, arg ...) printk(BIOS_INFO, RCTAG "%s,%d: " fmt, \ + __func__, __LINE__, ## arg) + +/* RC settle time setting */ +/*#define NO_DCXO_XO_CHN ((1 << CHN_COANT) | (1 << CHN_SCP) | (1 << CHN_RESERVE))*/ +//#define BT_ONLY_HW_MODE ((1 << CHN_BT)) /* only BT use HW side-band signal */ +#define FULL_SET_HW_MODE 0 /* dcxo mode use pmrc_en */ +#define VCORE_SETTLE_TIME 1 /* ~= 30us */ +#define ULPOSC_SETTLE_TIME 4 /* ~= ? 150us */ +#define XO_SETTLE_TIME 0x1 /* 2^(step_sz+5) * 0x33 *30.77ns~=400us */ +#define DCXO_SETTLE_TIME 0x1 /* 2^(step_sz+5) * 0x87 *30.77ns~= 1063us */ +#define CENTROL_CNT_STEP 0x3 /* Fix in 3, central align with Mxx Channel */ +#define DCXO_STABLE_TIME 0x70 +#define XO_STABLE_TIME 0x70 +#define KEEP_RC_SPI_ACTIVE 1 +#define SRCLKEN_RC_EN_SEL 0 + +#define INIT_SUBSYS_FPM_TO_LPM ( 1 << CHN_RF | 1 << CHN_DEEPIDLE \ + | 1 << CHN_MD | 1 << CHN_GPS | 1 <<CHN_BT \ + | 1 << CHN_WIFI | 1 << CHN_MCU \ + | 1 << CHN_COANT | 1 << CHN_NFC | 1 << CHN_UFS \ + | 1 << CHN_SCP | 1 << CHN_RESERVE) + +#define INIT_SUBSYS_FPM_TO_BBLPM ( 1 << CHN_DEEPIDLE) + +#define INIT_SUBSYS_TO_HW ( 1 << CHN_SUSPEND | 1 << CHN_RF | 1 << CHN_DEEPIDLE \ + | 1 << CHN_GPS | 1 <<CHN_BT \ + | 1 << CHN_WIFI | 1 << CHN_MCU \ + | 1 << CHN_COANT | 1 << CHN_NFC ) + +/* RC central setting */ +#define RC_CENTRAL_ENABLE 1 +#define RC_CENTRAL_DISABLE 0 +#if MTK_SRCLKEN_RC_FULL_SET +#define SPI_TRIG_MODE SRCLKENAO_MODE /* use srlckenao to set vcore */ +#define IS_SPI_DONE_RELEASE 0 /* release vcore when spi request done */ +#define IS_SPI2PMIC_SET_CLR 0 /* register direct write */ +#define SRCLKENO_0_CTRL_M MERGE_OR_MODE /* merge with spm */ +#define VREQ_CTRL_M BYPASS_MODE /* merge with vreq */ +#define ULPOSC_CTRL_M BYPASS_MODE /* merge with ulposc */ +#define PWRAP_CTRL_M MERGE_OR_MODE /* merge with pwrap_scp */ +#endif +#define SPI_CLK_SRC RC_32K /* pmic spec under 200us */ + +/* other setting */ +#define PMRC_CON0 0x1A6 /* default use this reg direct write */ +#define PMRC_CON0_SET 0x1A8 +#define PMRC_CON0_CLR 0x1AA + +#define DCXO_FPM_CTRL_MODE MERGE_OR_MODE | ASYNC_MODE /* merge with spm */ + +#define PWRAP_TMOUT_VAL 0xA /* 31us * 0xa ~= 310us */ + +#if MTK_SRCLKEN_RC_FULL_SET +#define FPM_MSK_B FULL_SET_HW_MODE +#define MD0_SRCLKENO_0_MASK_B 0 /* md0 control by pmrc */ + +#define SUB_BBLPM_SET ( 1 << CHN_COANT | 1 << CHN_DEEPIDLE ) +#define SUB_FPM_SET (1 << CHN_SUSPEND | 1 << CHN_RF \ + | 1 << CHN_MD | 1 << CHN_GPS | 1 <<CHN_BT \ + | 1 << CHN_WIFI | 1 << CHN_MCU \ + | 1 << CHN_NFC | 1 << CHN_UFS | 1 << CHN_SCP \ + | 1 << CHN_RESERVE) + +#define SW_BBLPM_HIGH 1 +#define SW_BBLPM_LOW 0 +#define SW_FPM_HIGH 1 +#define SW_FPM_LOW 0 +#define DXCO_SETTLE_BLK_EN 1 +#define DXCO_SETTLE_BLK_DIS 0 + +#define SUB_CTRL_CON(_id, _dcxo_prd, _xo_prd , _sw_bblpm, _sw_fpm, \ + _sw_rc, _bypass_cmd, _dcxo_settle_blk_en) { \ + .id = _id, \ + .dcxo_prd = _dcxo_prd, \ + .xo_prd = _xo_prd, \ + .cnt_step = CENTROL_CNT_STEP, \ + .track_en = 0x0, \ + .req_ack_imd_en = 0x1, \ + .xo_soc_link_en = 0x0, \ + .sw_bblpm = _sw_bblpm, \ + .sw_fpm = _sw_fpm, \ + .sw_rc = _sw_rc, \ + .bypass_cmd = _bypass_cmd, \ + .dcxo_settle_blk_en = _dcxo_settle_blk_en, \ + } + +static struct mtk_rc_regs *rc_regs = (struct mtk_rc_regs *)RC_BASE; +static struct mtk_rc_status_regs *rc_sta_regs = + (struct mtk_rc_status_regs *)RC_STATUS_BASE; + +static struct subsys_rc_con rc_ctrl[MAX_CHN_NUM] = { + SUB_CTRL_CON(CHN_SUSPEND, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_RF, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_DEEPIDLE, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_MD, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_GPS, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_BT, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_WIFI, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_MCU, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_COANT, 0x0, 0x0, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x1 /*bypass*/,DXCO_SETTLE_BLK_DIS), + SUB_CTRL_CON(CHN_NFC, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_UFS, DCXO_STABLE_TIME, XO_STABLE_TIME, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x0 /*bypass*/,DXCO_SETTLE_BLK_EN), + SUB_CTRL_CON(CHN_SCP, 0x0, 0x0, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x1 /*bypass*/,DXCO_SETTLE_BLK_DIS), + SUB_CTRL_CON(CHN_RESERVE, 0x0, 0x0, SW_BBLPM_LOW, SW_FPM_HIGH, SW_MODE, 0x1 /*bypass*/,DXCO_SETTLE_BLK_DIS), +}; +#endif + +static struct pmif *pmif_arb = NULL; +static s32 pmic_read(u32 addr, u32 *rdata) +{ + if (pmif_arb == NULL) + pmif_arb = get_pmif_controller(PMIF_SPI, 0); + + return pmif_arb->read_cmd(pmif_arb, 0, addr, rdata); +} + +static void rc_dump_reg_info(void){ +#if SRCLKEN_DBG + unsigned int chn_n; + + rc_info("SRCLKEN_RC_CFG:0x%x\n", read32(&rc_regs->srclken_rc_cfg)); + rc_info("RC_CENTRAL_CFG1:0x%x\n", read32(&rc_regs->rc_central_cfg1)); + rc_info("RC_CENTRAL_CFG2:0x%x\n", read32(&rc_regs->rc_central_cfg2)); + rc_info("RC_CENTRAL_CFG3:0x%x\n", read32(&rc_regs->rc_central_cfg3)); + rc_info("RC_CENTRAL_CFG4:0x%x\n", read32(&rc_regs->rc_central_cfg4)); + rc_info("RC_DCXO_FPM_CFG:0x%x\n", read32(&rc_regs->rc_dcxo_fpm_cfg)); + rc_info("SUBSYS_INTF_CFG:0x%x\n", read32(&rc_regs->rc_subsys_intf_cfg)); + rc_info("RC_SPI_STA_0:0x%x\n", read32(&rc_sta_regs->rc_spi_sta_0)); + rc_info("RC_PI_PO_STA:0x%x\n", read32(&rc_sta_regs->rc_pi_po_sta_0)); + + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++){ + rc_info("M0%d: 0x%x\n", chn_n, + read32(&rc_regs->rc_mxx_srclken_cfg[chn_n])); + } +#endif +} + +/* RC initial flow and relative setting */ +static void __rc_ctrl_mode_switch(enum chn_id id, enum rc_ctrl_m mode) +{ +#ifdef MTK_SRCLKEN_RC_SUPPORT + + unsigned int value = 0; + + if(mode == INIT_MODE){ + value = ((rc_ctrl[id].dcxo_settle_blk_en & DCXO_SETTLE_BLK_EN_MSK) << DCXO_SETTLE_BLK_EN_SHFT) | + ((rc_ctrl[id].bypass_cmd & BYPASS_CMD_EN_MSK) << BYPASS_CMD_EN_SHFT) | + ((rc_ctrl[id].sw_rc & SW_SRCLKEN_RC_MSK) << SW_SRCLKEN_RC_SHFT) | + ((rc_ctrl[id].sw_fpm & SW_SRCLKEN_FPM_MSK) << SW_SRCLKEN_FPM_SHFT) | + ((rc_ctrl[id].sw_bblpm & SW_SRCLKEN_BBLPM_MSK) << SW_SRCLKEN_BBLPM_SHFT) | + ((rc_ctrl[id].xo_soc_link_en & XO_SOC_LINK_EN_MSK) << XO_SOC_LINK_EN_SHFT) | + ((rc_ctrl[id].req_ack_imd_en & REQ_ACK_LOW_IMD_EN_MSK) << REQ_ACK_LOW_IMD_EN_SHFT) | + ((rc_ctrl[id].track_en & SRCLKEN_TRACK_M_EN_MSK) << SRCLKEN_TRACK_M_EN_SHFT) | + ((rc_ctrl[id].cnt_step & CNT_PRD_STEP_MSK) << CNT_PRD_STEP_SHFT) | + ((rc_ctrl[id].xo_prd & XO_STABLE_PRD_MSK) << XO_STABLE_PRD_SHFT) | + ((rc_ctrl[id].dcxo_prd & DCXO_STABLE_PRD_MSK) << DCXO_STABLE_PRD_SHFT) ; + }else if (mode == SW_MODE){ + value = read32(&rc_regs->rc_mxx_srclken_cfg[id]) | ( 0x1 << SW_SRCLKEN_RC_SHFT); + }else if (mode == HW_MODE){ + value = read32(&rc_regs->rc_mxx_srclken_cfg[id]) & ~(SW_SRCLKEN_RC_MSK << SW_SRCLKEN_RC_SHFT); + }else + return; + + write32(&rc_regs->rc_mxx_srclken_cfg[id], value); + + rc_info("M0%d: 0x%x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id])); +#endif +} + + +/* RC subsys FPM control*/ +static void __rc_ctrl_fpm_switch(enum chn_id id, unsigned int mode) +{ +#ifdef MTK_SRCLKEN_RC_SUPPORT + + unsigned int value = 0; + + if (mode == SW_FPM_HIGH){ + value = read32(&rc_regs->rc_mxx_srclken_cfg[id]) | ( 0x1 << SW_SRCLKEN_FPM_SHFT); + }else if (mode == SW_FPM_LOW){ + value = read32(&rc_regs->rc_mxx_srclken_cfg[id]) & ~(SW_SRCLKEN_FPM_MSK << SW_SRCLKEN_FPM_SHFT); + }else + return; + + rc_ctrl[id].sw_fpm = mode; + write32(&rc_regs->rc_mxx_srclken_cfg[id], value); + + rc_info("M0%d FPM SWITCH: 0x%x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id])); +#endif +} + +static void __rc_ctrl_bblpm_switch(enum chn_id id, unsigned int mode) +{ +#ifdef MTK_SRCLKEN_RC_SUPPORT + + unsigned int value = 0; + + if (mode == SW_BBLPM_HIGH){ + value = read32(&rc_regs->rc_mxx_srclken_cfg[id]) | ( 0x1 << SW_SRCLKEN_BBLPM_SHFT); + }else if (mode == SW_BBLPM_LOW){ + value = read32(&rc_regs->rc_mxx_srclken_cfg[id]) & ~(SW_SRCLKEN_BBLPM_MSK << SW_SRCLKEN_BBLPM_SHFT); + }else + return; + + rc_ctrl[id].sw_bblpm = mode; + write32(&rc_regs->rc_mxx_srclken_cfg[id], value); + + rc_info("M0%d BBLPM SWITCH: 0x%x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id])); +#endif +} + +static void rc_init_subsys_hw_mode(void){ +#ifdef MTK_SRCLKEN_RC_SUPPORT + unsigned int chn_n; + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++){ + if( INIT_SUBSYS_TO_HW & (1 << chn_n)) + __rc_ctrl_mode_switch(chn_n, HW_MODE); + } +#endif +} + +static void rc_init_subsys_lpm(void){ +#ifdef MTK_SRCLKEN_RC_SUPPORT + unsigned int chn_n; + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++){ + if( INIT_SUBSYS_FPM_TO_LPM & (1 << chn_n)) + __rc_ctrl_fpm_switch(chn_n, SW_FPM_LOW); + } + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++){ + if( INIT_SUBSYS_FPM_TO_BBLPM & (1 << chn_n)) + __rc_ctrl_bblpm_switch(chn_n, SW_BBLPM_HIGH); + } +#endif +} + +#if 0 +static void rc_ctrl_mode_switch_hw(enum chn_id id) +{ + __rc_ctrl_mode_switch(id, HW_MODE); +} + +static void rc_ctrl_mode_switch_sw(enum chn_id id) +{ + __rc_ctrl_mode_switch(id, SW_MODE); +} +#endif + +static void rc_ctrl_mode_switch_init(enum chn_id id) +{ + __rc_ctrl_mode_switch(id, INIT_MODE); +} + +static int srclken_rc_chk_init_cfg(void) +{ +#if MTK_SRCLKEN_RC_BRINGUP + rc_info("Bring-UP : skip srclken_rc init\n"); + + return SRLCKEN_RC_BRINGUP; +#else + pmwrap_interface_init(); + + /*enable debug trace*/ +#if SRCLKEN_DBG + write32(&rc_sta_regs->rc_debug_trace, 1); + write32(&rc_regs->rc_debug_cfg, + read32(&rc_regs->rc_debug_cfg) + | (TRACE_MODE_EN_MSK << TRACE_MODE_EN_SHFT)); +#endif +#ifdef MTK_SRCLKEN_RC_SUPPORT + return SRCLKEN_RC_ENABLE; +#else + return SRCLKEN_RC_DISABLE; +#endif +#endif +} + +int srclken_rc_init(void) +{ + /* new co-clock architecture srclkenrc implement here */ + unsigned int chn_n; + int ret = 0; + + /* check platform config to proceed init flow */ + if (srclken_rc_chk_init_cfg() != SRCLKEN_RC_ENABLE) + return ret; + + /* Set SW RESET 1 */ + write32(&rc_regs->srclken_rc_cfg, 1 << SW_RESET_SHFT); + + /* Wait 100us */ + udelay(100); + + /* Set SW CG 1 */ + write32(&rc_regs->srclken_rc_cfg, + (1 << SW_RESET_SHFT) | (1 << CG_32K_EN_SHFT) + | (1 << CG_FCLK_EN_SHFT) | (1 << CG_FCLK_FR_EN_SHFT)); + + /* Wait 100us */ + udelay(100); + + /* Set Clock Mux*/ + write32(&rc_regs->srclken_rc_cfg, + (1 << SW_RESET_SHFT) |(1 << CG_32K_EN_SHFT) + | (1 << CG_FCLK_EN_SHFT) | (1 << CG_FCLK_FR_EN_SHFT) + | (1 << MUX_FCLK_FR_SHFT)); + + /* Set req_filter m00~m12 as default SW_FPM */ + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) + rc_ctrl_mode_switch_init(chn_n); + + /* Set PMIC addr for SPI CMD */ + write32(&rc_regs->rc_pmic_rcen_addr, PMRC_CON0); + + write32(&rc_regs->rc_pmic_rcen_set_clr_addr, + (PMRC_CON0_CLR << 16 | PMRC_CON0_SET)); + + write32(&rc_regs->rc_cmd_arb_cfg, 0); + + /* CFG1 setting for spi cmd config */ + write32(&rc_regs->rc_central_cfg1, + DCXO_SETTLE_TIME << DCXO_SETTLE_T_SHFT | + XO_SETTLE_TIME << NON_DCXO_SETTLE_T_SHFT | + ULPOSC_SETTLE_TIME << ULPOSC_SETTLE_T_SHFT | + VCORE_SETTLE_TIME << VCORE_SETTLE_T_SHFT | + SRCLKEN_RC_EN_SEL << SRCLKEN_RC_EN_SEL_SHFT | + KEEP_RC_SPI_ACTIVE << RC_SPI_ACTIVE_SHFT | + IS_SPI2PMIC_SET_CLR << RCEN_ISSUE_M_SHFT | + RC_CENTRAL_DISABLE << SRCLKEN_RC_EN_SHFT); + + /* CFG2 setting for signal mode of each control mux */ + write32(&rc_regs->rc_central_cfg2, + SPI_CLK_SRC << PWRAP_SLP_MUX_SEL_SHFT | + PWRAP_CTRL_M << PWRAP_SLP_CTRL_M_SHFT | + ULPOSC_CTRL_M << ULPOSC_CTRL_M_SHFT | + IS_SPI_DONE_RELEASE << SRCVOLTEN_VREQ_M_SHFT | + SPI_TRIG_MODE << SRCVOLTEN_VREQ_SEL_SHFT | + VREQ_CTRL_M << VREQ_CTRL_SHFT | + SRCLKENO_0_CTRL_M << SRCVOLTEN_CTRL_SHFT); + + write32(&rc_regs->rc_central_cfg3, + 0x4 << TO_LPM_SETTLE_T_SHFT | + 1 << TO_BBLPM_SETTLE_EN_SHFT | + 1 << BLK_COANT_DXCO_MD_TARGET_SHFT | + 1 << BLK_SCP_DXCO_MD_TARGET_SHFT | + 1 << TO_LPM_SETTLE_EN_SHFT); + + /* Set srclkeno_0/conn_bt as factor to allow dcxo change to FPM */ + write32(&rc_regs->rc_dcxo_fpm_cfg, + FPM_MSK_B << SUB_SRCLKEN_FPM_MSK_B_SHFT | + MD0_SRCLKENO_0_MASK_B << SRCVOLTEN_FPM_MSK_B_SHFT | + DCXO_FPM_CTRL_MODE << DCXO_FPM_CTRL_M_SHFT); + + /* Set bblpm/fpm channel */ + write32(&rc_regs->rc_subsys_intf_cfg, + SUB_BBLPM_SET << SRCLKEN_BBLPM_MASK_B_SHFT| + SUB_FPM_SET << SRCLKEN_FPM_MASK_B_SHFT); + + /* Trigger srclken_rc enable */ + write32(&rc_regs->rc_central_cfg1, read32(&rc_regs->rc_central_cfg1) + | (RC_CENTRAL_ENABLE << SRCLKEN_RC_EN_SHFT)); + + write32(&rc_regs->rc_central_cfg4, + 0x1 << SLEEP_VLD_MODE_SHFT | + 0x1 << PWRAP_VLD_FORCE_SHFT | + 0x800 << KEEP_RC_SPI_ACTIVE_SHFT); + + + /* Wait 100us */ + udelay(100); + + /* Set SW RESET 0 */ + write32(&rc_regs->srclken_rc_cfg, + (1 << CG_32K_EN_SHFT) | (1 << CG_FCLK_EN_SHFT) + | (1 << CG_FCLK_FR_EN_SHFT) | (1 << MUX_FCLK_FR_SHFT)); + + /* Wait 100us */ + udelay(100); + + /* Set SW CG 0 */ + write32(&rc_regs->srclken_rc_cfg, 1 << MUX_FCLK_FR_SHFT); + + /* Wait 500us */ + udelay(500); + + /* Set req_filter m00~m12 FPM to LPM*/ + rc_init_subsys_lpm(); + + /* Polling ACK of Initial Subsys Input */ + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) { + unsigned int chk_sta, shift_chn_n = 0; + int i = 0; + u32 temp; + + if(chn_n > 0) + shift_chn_n = 1; + + chk_sta = (rc_ctrl[chn_n].sw_fpm & SW_SRCLKEN_FPM_MSK) << 1 + | (rc_ctrl[chn_n].sw_bblpm & SW_SRCLKEN_BBLPM_MSK) << 3; + ; /* Fix RC_MXX_REQ_STA_0 register shift */ + while((read32(&rc_sta_regs->rc_mxx_req_sta_0[chn_n + shift_chn_n]) & 0xa) != chk_sta) { + udelay(10); + i++; + if(i > 200) { + pmic_read(PMIC_PMRC_CON0, &temp); + rc_info("%s: polling M%d status fail.(R:0x%x)(C:0x%x)(PMRC:0x%x)\n", + __func__, chn_n, + read32(&rc_sta_regs->rc_mxx_req_sta_0[chn_n + shift_chn_n]), + read32(&rc_regs->rc_mxx_srclken_cfg[chn_n]), temp); + ret = -1; + break; + } + } + } + + /* Set req_filter m00~m12 */ + rc_init_subsys_hw_mode(); + + /* release force pmic req signal*/ + write32(&rc_regs->rc_central_cfg4, + 0x1 << SLEEP_VLD_MODE_SHFT | + 0x800 << KEEP_RC_SPI_ACTIVE_SHFT); + + rc_dump_reg_info(); + + return ret; +}