From f131f0e336748d91c1c5bc5b24d72307b467c08b Mon Sep 17 00:00:00 2001 From: LiLiang Chen Date: Tue, 10 Jun 2025 15:08:17 +0800 Subject: [PATCH] soc/mediatek/mt8189: Add clk_buf and srclken_rc drivers MT8189 uses MT6359 clk_buf, and will use new RC mode with srclken_rc. The clk_buf will provide several 26M clocks, and these clocks can be independently turned on. BUG=b:379008996,b:422503190,b:403478729 BRANCH=none TEST=show driver init log: RG_CENTRAL_CFG1: 0x104014e5 RG_CENTRAL_CFG2: 0x1010 RG_CENTRAL_CFG3: 0x400f Signed-off-by: LiLiang Chen Signed-off-by: Vince Liu Change-Id: Ia04526d55191c695caf3ef40002e1ec99f299966 Reviewed-on: https://review.coreboot.org/c/coreboot/+/88525 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/soc/mediatek/mt8189/Makefile.mk | 2 + src/soc/mediatek/mt8189/clkbuf_ctl.c | 218 ++++++++++++++ .../mediatek/mt8189/include/soc/addressmap.h | 1 + .../mediatek/mt8189/include/soc/clkbuf_ctl.h | 207 +++++++++++++ .../mediatek/mt8189/include/soc/srclken_rc.h | 156 ++++++++++ src/soc/mediatek/mt8189/srclken_rc.c | 281 ++++++++++++++++++ 6 files changed, 865 insertions(+) create mode 100644 src/soc/mediatek/mt8189/clkbuf_ctl.c create mode 100644 src/soc/mediatek/mt8189/include/soc/clkbuf_ctl.h create mode 100644 src/soc/mediatek/mt8189/include/soc/srclken_rc.h create mode 100644 src/soc/mediatek/mt8189/srclken_rc.c diff --git a/src/soc/mediatek/mt8189/Makefile.mk b/src/soc/mediatek/mt8189/Makefile.mk index b0adf83fa7..57666fc1d2 100644 --- a/src/soc/mediatek/mt8189/Makefile.mk +++ b/src/soc/mediatek/mt8189/Makefile.mk @@ -17,6 +17,7 @@ bootblock-y += ../common/mtcmos.c mtcmos.c bootblock-y += ../common/wdt.c ../common/wdt_req.c wdt.c romstage-y += ../common/cbmem.c +romstage-y += clkbuf_ctl.c romstage-y += ../common/cpu_id.c ../common/cpu_segment_id.c romstage-y += ../common/dram_init.c romstage-y += ../common/dramc_param.c @@ -32,6 +33,7 @@ romstage-y += ../common/pmif.c ../common/pmif_clk.c ../common/pmif_init.c pmif_c romstage-y += ../common/pmif_spi.c pmif_spi.c romstage-y += ../common/pmif_spmi.c ../common/pmif_spmi_v2.c pmif_spmi.c romstage-y += ../common/rtc.c ../common/rtc_osc_init.c ../common/rtc_mt6359p.c +romstage-y += ../common/srclken_rc.c srclken_rc.c ramstage-y += ../common/auxadc.c ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += ../common/bl31.c diff --git a/src/soc/mediatek/mt8189/clkbuf_ctl.c b/src/soc/mediatek/mt8189/clkbuf_ctl.c new file mode 100644 index 0000000000..c979e1a8fc --- /dev/null +++ b/src/soc/mediatek/mt8189/clkbuf_ctl.c @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include +#include + +#define PMIC_REG_MASK 0xFFFF +#define PMIC_REG_SHIFT 0 + +#define DCXO_DBG_AUXOUT_1 54 +#define DCXO_DBG_AUXOUT_2 55 +#define DCXO_DBG_AUXOUT_3 56 + +#define PMIC_CW00_INIT_VAL 0x4F1D +#define PMIC_CW09_INIT_VAL 0x31F0 +#define XO_SOC_VOTER_MASK 0x001 +#define XO_CONN_VOTER_MASK 0x7C0 +#define XO_NFC_VOTER_MASK 0x001 +#define XO_EXT_VOTER_MASK 0x001 +#define XO_CDAC_FPM_VAL 0xA8 +#define XO_CDAC_LPM_VAL 0xFF + +static void clk_buf_dump_clkbuf_log(void) +{ + u32 pmic_cw00, pmic_cw09, pmic_cw12, pmic_cw13, + pmic_cw15, pmic_cw19, top_spi_con1, + ldo_vrfck_op_en, ldo_vbbck_op_en, ldo_vrfck_en, + ldo_vbbck_en, vrfck_hv_en; + + pmic_cw00 = mt6359p_read_field(PMIC_XO_EXTBUF1_MODE_ADDR, + PMIC_REG_MASK, PMIC_REG_SHIFT); + pmic_cw09 = mt6359p_read_field(PMIC_XO_EXTBUF7_MODE_ADDR, + PMIC_REG_MASK, PMIC_REG_SHIFT); + pmic_cw12 = mt6359p_read_field(PMIC_XO_EXTBUF2_CLKSEL_MAN_ADDR, + PMIC_REG_MASK, PMIC_REG_SHIFT); + pmic_cw13 = mt6359p_read_field(PMIC_RG_XO_EXTBUF2_SRSEL_ADDR, + PMIC_REG_MASK, PMIC_REG_SHIFT); + pmic_cw15 = mt6359p_read_field(PMIC_RG_XO_RESERVED1_ADDR, + PMIC_REG_MASK, PMIC_REG_SHIFT); + pmic_cw19 = mt6359p_read_field(PMIC_RG_XO_EXTBUF2_RSEL_ADDR, + PMIC_REG_MASK, PMIC_REG_SHIFT); + top_spi_con1 = mt6359p_read_field(PMIC_RG_SRCLKEN_IN3_EN_ADDR, + PMIC_RG_SRCLKEN_IN3_EN_MASK, + PMIC_RG_SRCLKEN_IN3_EN_SHIFT); + ldo_vrfck_op_en = mt6359p_read_field(PMIC_RG_LDO_VRFCK_HW14_OP_EN_ADDR, + PMIC_RG_LDO_VRFCK_HW14_OP_EN_MASK, + PMIC_RG_LDO_VRFCK_HW14_OP_EN_SHIFT); + ldo_vbbck_op_en = mt6359p_read_field(PMIC_RG_LDO_VBBCK_HW14_OP_EN_ADDR, + PMIC_RG_LDO_VBBCK_HW14_OP_EN_MASK, + PMIC_RG_LDO_VBBCK_HW14_OP_EN_SHIFT); + ldo_vrfck_en = mt6359p_read_field(PMIC_RG_LDO_VRFCK_EN_ADDR, + PMIC_RG_LDO_VRFCK_EN_MASK, + PMIC_RG_LDO_VRFCK_EN_SHIFT); + ldo_vbbck_en = mt6359p_read_field(PMIC_RG_LDO_VBBCK_EN_ADDR, + PMIC_RG_LDO_VBBCK_EN_MASK, + PMIC_RG_LDO_VBBCK_EN_SHIFT); + printk(BIOS_INFO, "%s DCXO_CW00/09/12/13/15/19=0x%x %x %x %x %x %x\n", + __func__, pmic_cw00, pmic_cw09, pmic_cw12, pmic_cw13, pmic_cw15, pmic_cw19); + printk(BIOS_INFO, "%s spi_con1/ldo_rf_op/ldo_bb_op/ldo_rf_en/" + "ldo_bb_en=0x%x %x %x %x %x\n", __func__, top_spi_con1, + ldo_vrfck_op_en, ldo_vbbck_op_en, ldo_vrfck_en, ldo_vbbck_en); + vrfck_hv_en = mt6359p_read_field(PMIC_RG_VRFCK_HV_EN_ADDR, + PMIC_RG_VRFCK_HV_EN_MASK, + PMIC_RG_VRFCK_HV_EN_SHIFT); + printk(BIOS_INFO, "%s clk buf vrfck_hv_en=0x%x\n", __func__, vrfck_hv_en); +} + +u32 clk_buf_get_pmrc_en(void) +{ + return mt6359p_read_field(PMIC_PMRC_EN_ADDR, PMIC_PMRC_EN_MASK, PMIC_PMRC_EN_SHIFT); +} + +static void clk_buf_init_pmic_clkbuf(void) +{ + int pmic_cw04_l, pmic_cw04_h; + + /* Dump registers before setting */ + clk_buf_dump_clkbuf_log(); + + /* unlock pmic key */ + mt6359p_write_field(PMIC_TMA_KEY_ADDR, 0x9CA6, + PMIC_TMA_KEY_MASK, PMIC_TMA_KEY_SHIFT); + + /* 1.1 set VRFCK input supply */ + mt6359p_write_field(PMIC_RG_VRFCK_HV_EN_ADDR, 0x0, + PMIC_RG_VRFCK_HV_EN_MASK, PMIC_RG_VRFCK_HV_EN_SHIFT); + /* 1.2.1 set VRFCK En = 0 */ + mt6359p_write_field(PMIC_RG_LDO_VRFCK_EN_ADDR, 0x0, + PMIC_RG_LDO_VRFCK_EN_MASK, PMIC_RG_LDO_VRFCK_EN_SHIFT); + /* 1.2.1 set VRFCK1 as power src */ + mt6359p_write_field(PMIC_RG_LDO_VRFCK_ANA_SEL_ADDR, 0x1, + PMIC_RG_LDO_VRFCK_ANA_SEL_MASK, PMIC_RG_LDO_VRFCK_ANA_SEL_SHIFT); + /* 1.2.2 switch LDO-RFCK to LDO-RFCK1 */ + mt6359p_write_field(PMIC_RG_VRFCK_NDIS_EN_ADDR, 0x0, + PMIC_RG_VRFCK_NDIS_EN_MASK, PMIC_RG_VRFCK_NDIS_EN_SHIFT); + mt6359p_write_field(PMIC_RG_VRFCK_1_NDIS_EN_ADDR, 0x1, + PMIC_RG_VRFCK_1_NDIS_EN_MASK, PMIC_RG_VRFCK_1_NDIS_EN_SHIFT); + /* 1.2.3 Set VRFCK En = 1 */ + mt6359p_write_field(PMIC_RG_LDO_VRFCK_EN_ADDR, 0x1, + PMIC_RG_LDO_VRFCK_EN_MASK, PMIC_RG_LDO_VRFCK_EN_SHIFT); + + /* 1.3 turn on LDO HW control from EXTBUFs */ + mt6359p_write_field(PMIC_RG_LDO_VRFCK_OP_EN_SET_ADDR, 0x1, + PMIC_RG_LDO_VRFCK_HW14_OP_EN_MASK, + PMIC_RG_LDO_VRFCK_HW14_OP_EN_SHIFT); + mt6359p_write_field(PMIC_RG_LDO_VBBCK_OP_EN_SET_ADDR, 0x1, + PMIC_RG_LDO_VBBCK_HW14_OP_EN_MASK, + PMIC_RG_LDO_VBBCK_HW14_OP_EN_SHIFT); + + /* 1.4 turn on LDO SW control */ + mt6359p_write_field(PMIC_RG_LDO_VRFCK_EN_ADDR, 0x0, + PMIC_RG_LDO_VRFCK_EN_MASK, PMIC_RG_LDO_VRFCK_EN_SHIFT); + mt6359p_write_field(PMIC_RG_LDO_VBBCK_EN_ADDR, 0x0, + PMIC_RG_LDO_VBBCK_EN_MASK, PMIC_RG_LDO_VBBCK_EN_SHIFT); + + /* lock pmic key */ + mt6359p_write_field(PMIC_TMA_KEY_ADDR, 0, + PMIC_TMA_KEY_MASK, PMIC_TMA_KEY_SHIFT); + + /* Setup initial PMIC clock buffer setting */ + /* 1.5 Buffer de-sense setting */ + mt6359p_write_field(PMIC_RG_XO_EXTBUF2_SRSEL_ADDR, PMIC_CLK_BUF2_CONTROLS_FOR_DESENSE, + PMIC_RG_XO_EXTBUF2_SRSEL_MASK, PMIC_RG_XO_EXTBUF2_SRSEL_SHIFT); + mt6359p_write_field(PMIC_RG_XO_EXTBUF3_HD_ADDR, PMIC_CLK_BUF3_CONTROLS_FOR_DESENSE, + PMIC_RG_XO_EXTBUF3_HD_MASK, PMIC_RG_XO_EXTBUF3_HD_SHIFT); + mt6359p_write_field(PMIC_RG_XO_EXTBUF4_SRSEL_ADDR, PMIC_CLK_BUF4_CONTROLS_FOR_DESENSE, + PMIC_RG_XO_EXTBUF4_SRSEL_MASK, PMIC_RG_XO_EXTBUF4_SRSEL_SHIFT); + + /* 1.6 Buffer setting for trace impedance */ + mt6359p_write_field(PMIC_RG_XO_EXTBUF1_RSEL_ADDR, PMIC_CLK_BUF1_OUTPUT_IMPEDANCE, + PMIC_RG_XO_EXTBUF1_RSEL_MASK, PMIC_RG_XO_EXTBUF1_RSEL_SHIFT); + mt6359p_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); + mt6359p_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); + mt6359p_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); + mt6359p_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); + + /* 1.7 26M enable control */ + /* fully new co-clock mode */ + /* All XO mode should set to 2'b01 */ + mt6359p_write_field(PMIC_XO_EXTBUF1_MODE_ADDR, PMIC_CW00_INIT_VAL, + PMIC_REG_MASK, PMIC_REG_SHIFT); + mt6359p_write_field(PMIC_XO_EXTBUF7_MODE_ADDR, PMIC_CW09_INIT_VAL, + PMIC_REG_MASK, PMIC_REG_SHIFT); + /* update control mapping table */ + mt6359p_write_field(PMIC_XO_SOC_VOTE_ADDR, XO_SOC_VOTER_MASK, + PMIC_XO_SOC_VOTE_MASK, PMIC_XO_SOC_VOTE_SHIFT); + mt6359p_write_field(PMIC_XO_WCN_VOTE_ADDR, XO_CONN_VOTER_MASK, + PMIC_XO_WCN_VOTE_MASK, PMIC_XO_WCN_VOTE_SHIFT); + mt6359p_write_field(PMIC_XO_NFC_VOTE_ADDR, XO_NFC_VOTER_MASK, + PMIC_XO_NFC_VOTE_MASK, PMIC_XO_NFC_VOTE_SHIFT); + mt6359p_write_field(PMIC_XO_CEL_VOTE_ADDR, XO_CONN_VOTER_MASK, + PMIC_XO_CEL_VOTE_MASK, PMIC_XO_CEL_VOTE_SHIFT); + mt6359p_write_field(PMIC_XO_EXT_VOTE_ADDR, XO_EXT_VOTER_MASK, + PMIC_XO_EXT_VOTE_MASK, PMIC_XO_EXT_VOTE_SHIFT); + mdelay(1); + + /* switch to new control mode */ + /* + * XO_PMIC_TOP_DIG_SW is set to 0 + * XO_MODE_CONN_BT_MASK is set to 0 (BT only : 1) + * XO_BUF_CONN_BT_MASK is set to 0 (BT only : 1 ) + */ + mt6359p_write_field(PMIC_XO_PMIC_TOP_DIG_SW_ADDR, 0x0, + PMIC_XO_PMIC_TOP_DIG_SW_MASK, PMIC_XO_PMIC_TOP_DIG_SW_SHIFT); + mt6359p_write_field(PMIC_XO_MODE_CONN_BT_MASK_ADDR, 0x0, + PMIC_XO_MODE_CONN_BT_MASK_MASK, PMIC_XO_MODE_CONN_BT_MASK_SHIFT); + mt6359p_write_field(PMIC_XO_BUF_CONN_BT_MASK_ADDR, 0x0, + PMIC_XO_BUF_CONN_BT_MASK_MASK, PMIC_XO_BUF_CONN_BT_MASK_SHIFT); + + /* set capid */ + mt6359p_write_field(PMIC_XO_CDAC_FPM_ADDR, XO_CDAC_FPM_VAL, + PMIC_XO_CDAC_FPM_MASK, PMIC_XO_CDAC_FPM_SHIFT); + mt6359p_write_field(PMIC_XO_CDAC_LPM_ADDR, XO_CDAC_LPM_VAL, + PMIC_XO_CDAC_LPM_MASK, PMIC_XO_CDAC_LPM_SHIFT); + + pmic_cw04_l = mt6359p_read_field(PMIC_XO_CDAC_FPM_ADDR, + PMIC_XO_CDAC_FPM_MASK, PMIC_XO_CDAC_FPM_SHIFT); + pmic_cw04_h = mt6359p_read_field(PMIC_XO_CDAC_LPM_ADDR, + PMIC_XO_CDAC_LPM_MASK, PMIC_XO_CDAC_LPM_SHIFT); + printk(BIOS_INFO, + "%s clk buf pmic_cw04_l=0x%x, pmic_cw04_h=0x%x\n", + __func__, pmic_cw04_l, pmic_cw04_h); + + /* Check if the setting is ok */ + clk_buf_dump_clkbuf_log(); +} + +/* For CONN DBG */ +static void dcxo_dump_auxout(u16 sel) +{ + u32 rg_auxout; + + mt6359p_write_field(PMIC_XO_STATIC_AUXOUT_SEL_ADDR, sel, + PMIC_XO_STATIC_AUXOUT_SEL_MASK, + PMIC_XO_STATIC_AUXOUT_SEL_SHIFT); + rg_auxout = mt6359p_read_field(PMIC_XO_STATIC_AUXOUT_ADDR, + PMIC_XO_STATIC_AUXOUT_MASK, + PMIC_XO_STATIC_AUXOUT_SHIFT); + printk(BIOS_INFO, "%s: sel=%d, rg_auxout=0x%x\n", __func__, sel, rg_auxout); +} + +int clk_buf_init(void) +{ + /* dump lpsd dbg1-3 for debug */ + dcxo_dump_auxout(DCXO_DBG_AUXOUT_1); + dcxo_dump_auxout(DCXO_DBG_AUXOUT_2); + dcxo_dump_auxout(DCXO_DBG_AUXOUT_3); + + clk_buf_init_pmic_clkbuf(); + + return 0; +} diff --git a/src/soc/mediatek/mt8189/include/soc/addressmap.h b/src/soc/mediatek/mt8189/include/soc/addressmap.h index fed77162e8..8c633c5f17 100644 --- a/src/soc/mediatek/mt8189/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8189/include/soc/addressmap.h @@ -132,6 +132,7 @@ enum { SPM_BASE = IO_PHYS + 0x0C001000, RGU_BASE = IO_PHYS + 0x0C00A000, VLPCFG_REG_BASE = IO_PHYS + 0x0C00C000, + RC_BASE = IO_PHYS + 0x0C00D000, DVFSRC_TOP_BASE = IO_PHYS + 0x0C00F000, VLP_CK_BASE = IO_PHYS + 0x0C012000, PMICSPI_MST_BASE = IO_PHYS + 0x0C013000, diff --git a/src/soc/mediatek/mt8189/include/soc/clkbuf_ctl.h b/src/soc/mediatek/mt8189/include/soc/clkbuf_ctl.h new file mode 100644 index 0000000000..decc94c5e0 --- /dev/null +++ b/src/soc/mediatek/mt8189/include/soc/clkbuf_ctl.h @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_CLK_BUF_CTL_H__ +#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_CLK_BUF_CTL_H__ + +#define MT6359_PMRC_CON0 0x1A6 +#define MT6359_TOP_TMA_KEY 0x3A8 +#define MT6359_TOP_SPI_CON1 0x458 +#define MT6359_XO_BUF_CTL0 0x54C +#define MT6359_XO_BUF_CTL1 0x54E +#define MT6359_XO_BUF_CTL2 0x550 +#define MT6359_XO_BUF_CTL3 0x552 +#define MT6359_XO_BUF_CTL4 0x554 +#define MT6359_XO_CONN_BT0 0x556 +#define MT6359_DCXO_CW00 0x788 +#define MT6359_DCXO_CW00_SET 0x78A +#define MT6359_DCXO_CW00_CLR 0x78C +#define MT6359_DCXO_CW01 0x78E +#define MT6359_DCXO_CW02 0x790 +#define MT6359_DCXO_CW03 0x792 +#define MT6359_DCXO_CW04 0x794 +#define MT6359_DCXO_CW05 0x796 +#define MT6359_DCXO_CW06 0x798 +#define MT6359_DCXO_CW07 0x79A +#define MT6359_DCXO_CW08 0x79C +#define MT6359_DCXO_CW09 0x79E +#define MT6359_DCXO_CW09_SET 0x7A0 +#define MT6359_DCXO_CW09_CLR 0x7A2 +#define MT6359_DCXO_CW10 0x7A4 +#define MT6359_DCXO_CW11 0x7A6 +#define MT6359_DCXO_CW12 0x7A8 +#define MT6359_DCXO_CW13 0x7AA +#define MT6359_DCXO_CW14 0x7AC +#define MT6359_DCXO_CW15 0x7AE +#define MT6359_DCXO_CW16 0x7B0 +#define MT6359_DCXO_CW17 0x7B2 +#define MT6359_DCXO_CW18 0x7B4 +#define MT6359_DCXO_CW19 0x7B6 +#define MT6359_LDO_VRFCK_ELR 0x1B40 +#define MT6359_LDO_VRFCK_CON0 0x1D1C +#define MT6359_LDO_VRFCK_OP_EN 0x1D22 +#define MT6359_LDO_VRFCK_OP_EN_SET 0x1D24 +#define MT6359_LDO_VBBCK_CON0 0x1D2E +#define MT6359_LDO_VBBCK_OP_EN 0x1D34 +#define MT6359_LDO_VBBCK_OP_EN_SET 0x1D36 +#define MT6359_DCXO_ADLDO_BIAS_ELR_0 0x209C +#define MT6359_DCXO_ADLDO_BIAS_ELR_1 0x209E +#define PMIC_RG_SRCLKEN_IN3_EN_ADDR MT6359_TOP_SPI_CON1 +#define PMIC_RG_SRCLKEN_IN3_EN_MASK 0x1 +#define PMIC_RG_SRCLKEN_IN3_EN_SHIFT 0 +#define PMIC_RG_LDO_VBBCK_HW14_OP_EN_ADDR MT6359_LDO_VBBCK_OP_EN +#define PMIC_RG_LDO_VBBCK_HW14_OP_EN_MASK 0x1 +#define PMIC_RG_LDO_VBBCK_HW14_OP_EN_SHIFT 14 +#define PMIC_RG_LDO_VRFCK_HW14_OP_EN_ADDR MT6359_LDO_VRFCK_OP_EN +#define PMIC_RG_LDO_VRFCK_HW14_OP_EN_MASK 0x1 +#define PMIC_RG_LDO_VRFCK_HW14_OP_EN_SHIFT 14 +#define PMIC_RG_LDO_VRFCK_EN_ADDR MT6359_LDO_VRFCK_CON0 +#define PMIC_RG_LDO_VRFCK_EN_MASK 0x1 +#define PMIC_RG_LDO_VRFCK_EN_SHIFT 0 +#define PMIC_RG_LDO_VBBCK_EN_ADDR MT6359_LDO_VBBCK_CON0 +#define PMIC_RG_LDO_VBBCK_EN_MASK 0x1 +#define PMIC_RG_LDO_VBBCK_EN_SHIFT 0 +#define PMIC_RG_VRFCK_HV_EN_ADDR MT6359_DCXO_ADLDO_BIAS_ELR_0 +#define PMIC_RG_VRFCK_HV_EN_MASK 0x1 +#define PMIC_RG_VRFCK_HV_EN_SHIFT 9 +#define PMIC_PMRC_EN_ADDR MT6359_PMRC_CON0 +#define PMIC_PMRC_EN_MASK 0xFFFF +#define PMIC_PMRC_EN_SHIFT 0 +#define PMIC_TMA_KEY_ADDR MT6359_TOP_TMA_KEY +#define PMIC_TMA_KEY_MASK 0xFFFF +#define PMIC_TMA_KEY_SHIFT 0 +#define PMIC_RG_LDO_VRFCK_ANA_SEL_ADDR MT6359_LDO_VRFCK_ELR +#define PMIC_RG_LDO_VRFCK_ANA_SEL_MASK 0x1 +#define PMIC_RG_LDO_VRFCK_ANA_SEL_SHIFT 0 +#define PMIC_RG_VRFCK_NDIS_EN_ADDR MT6359_DCXO_ADLDO_BIAS_ELR_0 +#define PMIC_RG_VRFCK_NDIS_EN_MASK 0x1 +#define PMIC_RG_VRFCK_NDIS_EN_SHIFT 11 +#define PMIC_RG_LDO_VRFCK_OP_EN_SET_ADDR MT6359_LDO_VRFCK_OP_EN_SET +#define PMIC_RG_LDO_VBBCK_OP_EN_SET_ADDR MT6359_LDO_VBBCK_OP_EN_SET +#define PMIC_XO_EXTBUF1_MODE_ADDR MT6359_DCXO_CW00 +#define PMIC_XO_EXTBUF2_MODE_MASK 0x3 +#define PMIC_XO_EXTBUF2_MODE_SHIFT 3 +#define PMIC_XO_EXTBUF2_EN_M_MASK 0x1 +#define PMIC_XO_EXTBUF2_EN_M_SHIFT 5 +#define PMIC_XO_EXTBUF4_MODE_MASK 0x3 +#define PMIC_XO_EXTBUF4_MODE_SHIFT 9 +#define PMIC_XO_EXTBUF4_EN_M_MASK 0x1 +#define PMIC_XO_EXTBUF4_EN_M_SHIFT 11 +#define PMIC_DCXO_CW00_CLR_ADDR MT6359_DCXO_CW00_CLR +#define PMIC_XO_CLKSEL_EN_M_ADDR MT6359_DCXO_CW01 + +#define PMIC_XO_CDAC_FPM_ADDR MT6359_DCXO_CW04 +#define PMIC_XO_CDAC_FPM_MASK 0xFF +#define PMIC_XO_CDAC_FPM_SHIFT 0 +#define PMIC_XO_CDAC_LPM_ADDR MT6359_DCXO_CW04 +#define PMIC_XO_CDAC_LPM_MASK 0xFF +#define PMIC_XO_CDAC_LPM_SHIFT 8 + +#define PMIC_XO_PMIC_TOP_DIG_SW_ADDR MT6359_DCXO_CW08 +#define PMIC_XO_PMIC_TOP_DIG_SW_MASK 0x1 +#define PMIC_XO_PMIC_TOP_DIG_SW_SHIFT 2 +#define PMIC_XO_EXTBUF7_MODE_ADDR MT6359_DCXO_CW09 +#define PMIC_XO_EXTBUF2_CLKSEL_MAN_ADDR MT6359_DCXO_CW12 +#define PMIC_XO_EXTBUF2_CLKSEL_MAN_MASK 0x1 +#define PMIC_XO_EXTBUF2_CLKSEL_MAN_SHIFT 12 +#define PMIC_RG_XO_EXTBUF2_SRSEL_ADDR MT6359_DCXO_CW13 +#define PMIC_RG_XO_EXTBUF2_SRSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF2_SRSEL_SHIFT 0 +#define PMIC_RG_XO_EXTBUF4_SRSEL_ADDR MT6359_DCXO_CW13 +#define PMIC_RG_XO_EXTBUF4_SRSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF4_SRSEL_SHIFT 4 +#define PMIC_RG_XO_EXTBUF3_HD_ADDR MT6359_DCXO_CW13 +#define PMIC_RG_XO_EXTBUF3_HD_MASK 0x3 +#define PMIC_RG_XO_EXTBUF3_HD_SHIFT 10 +#define PMIC_RG_XO_RESERVED1_ADDR MT6359_DCXO_CW15 +#define PMIC_XO_STATIC_AUXOUT_SEL_ADDR MT6359_DCXO_CW16 +#define PMIC_XO_STATIC_AUXOUT_SEL_MASK 0x3F +#define PMIC_XO_STATIC_AUXOUT_SEL_SHIFT 0 +#define PMIC_XO_STATIC_AUXOUT_ADDR MT6359_DCXO_CW17 +#define PMIC_XO_STATIC_AUXOUT_MASK 0xFFFF +#define PMIC_XO_STATIC_AUXOUT_SHIFT 0 +#define PMIC_RG_XO_EXTBUF1_RSEL_ADDR MT6359_DCXO_CW19 +#define PMIC_RG_XO_EXTBUF1_RSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF1_RSEL_SHIFT 1 +#define PMIC_RG_XO_EXTBUF2_RSEL_ADDR MT6359_DCXO_CW19 +#define PMIC_RG_XO_EXTBUF2_RSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF2_RSEL_SHIFT 4 +#define PMIC_RG_XO_EXTBUF3_RSEL_ADDR MT6359_DCXO_CW19 +#define PMIC_RG_XO_EXTBUF3_RSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF3_RSEL_SHIFT 7 +#define PMIC_RG_XO_EXTBUF4_RSEL_ADDR MT6359_DCXO_CW19 +#define PMIC_RG_XO_EXTBUF4_RSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF4_RSEL_SHIFT 10 +#define PMIC_RG_XO_EXTBUF7_RSEL_ADDR MT6359_DCXO_CW19 +#define PMIC_RG_XO_EXTBUF7_RSEL_MASK 0x7 +#define PMIC_RG_XO_EXTBUF7_RSEL_SHIFT 13 +#define PMIC_RG_VRFCK_1_NDIS_EN_ADDR MT6359_DCXO_ADLDO_BIAS_ELR_1 +#define PMIC_RG_VRFCK_1_NDIS_EN_MASK 0x1 +#define PMIC_RG_VRFCK_1_NDIS_EN_SHIFT 0 +#define PMIC_XO_SOC_VOTE_ADDR MT6359_XO_BUF_CTL0 +#define PMIC_XO_SOC_VOTE_MASK 0x7FF +#define PMIC_XO_SOC_VOTE_SHIFT 0 +#define PMIC_XO_WCN_VOTE_ADDR MT6359_XO_BUF_CTL1 +#define PMIC_XO_WCN_VOTE_MASK 0x7FF +#define PMIC_XO_WCN_VOTE_SHIFT 0 +#define PMIC_XO_NFC_VOTE_ADDR MT6359_XO_BUF_CTL2 +#define PMIC_XO_NFC_VOTE_MASK 0x7FF +#define PMIC_XO_NFC_VOTE_SHIFT 0 +#define PMIC_XO_CEL_VOTE_ADDR MT6359_XO_BUF_CTL3 +#define PMIC_XO_CEL_VOTE_MASK 0x7FF +#define PMIC_XO_CEL_VOTE_SHIFT 0 +#define PMIC_XO_EXT_VOTE_ADDR MT6359_XO_BUF_CTL4 +#define PMIC_XO_EXT_VOTE_MASK 0x7FF +#define PMIC_XO_EXT_VOTE_SHIFT 0 +#define PMIC_XO_MODE_CONN_BT_MASK_ADDR MT6359_XO_CONN_BT0 +#define PMIC_XO_MODE_CONN_BT_MASK_MASK 0x1 +#define PMIC_XO_MODE_CONN_BT_MASK_SHIFT 0 +#define PMIC_XO_BUF_CONN_BT_MASK_ADDR MT6359_XO_CONN_BT0 +#define PMIC_XO_BUF_CONN_BT_MASK_MASK 0x1 +#define PMIC_XO_BUF_CONN_BT_MASK_SHIFT 1 + +enum { + CLOCK_BUFFER_DISABLE, + CLOCK_BUFFER_SW_CONTROL, + CLOCK_BUFFER_HW_CONTROL +}; + +enum { + CLK_BUF_OUTPUT_IMPEDANCE_0, + CLK_BUF_OUTPUT_IMPEDANCE_1, + CLK_BUF_OUTPUT_IMPEDANCE_2, + CLK_BUF_OUTPUT_IMPEDANCE_3, + CLK_BUF_OUTPUT_IMPEDANCE_4, + CLK_BUF_OUTPUT_IMPEDANCE_5, + CLK_BUF_OUTPUT_IMPEDANCE_6, + CLK_BUF_OUTPUT_IMPEDANCE_7, +}; + +enum { + CLK_BUF_CONTROLS_FOR_DESENSE_0, + CLK_BUF_CONTROLS_FOR_DESENSE_1, + CLK_BUF_CONTROLS_FOR_DESENSE_2, + CLK_BUF_CONTROLS_FOR_DESENSE_3, + CLK_BUF_CONTROLS_FOR_DESENSE_4, + CLK_BUF_CONTROLS_FOR_DESENSE_5, + CLK_BUF_CONTROLS_FOR_DESENSE_6, + CLK_BUF_CONTROLS_FOR_DESENSE_7, +}; + +#define CLK_BUF1_STATUS_PMIC CLOCK_BUFFER_HW_CONTROL +#define CLK_BUF2_STATUS_PMIC CLOCK_BUFFER_HW_CONTROL +#define CLK_BUF3_STATUS_PMIC CLOCK_BUFFER_HW_CONTROL +#define CLK_BUF4_STATUS_PMIC CLOCK_BUFFER_HW_CONTROL +#define CLK_BUF7_STATUS_PMIC CLOCK_BUFFER_HW_CONTROL +#define PMIC_CLK_BUF1_OUTPUT_IMPEDANCE CLK_BUF_OUTPUT_IMPEDANCE_6 +#define PMIC_CLK_BUF2_OUTPUT_IMPEDANCE CLK_BUF_OUTPUT_IMPEDANCE_4 +#define PMIC_CLK_BUF3_OUTPUT_IMPEDANCE CLK_BUF_OUTPUT_IMPEDANCE_4 +#define PMIC_CLK_BUF4_OUTPUT_IMPEDANCE CLK_BUF_OUTPUT_IMPEDANCE_4 +#define PMIC_CLK_BUF7_OUTPUT_IMPEDANCE CLK_BUF_OUTPUT_IMPEDANCE_4 +#define PMIC_CLK_BUF2_CONTROLS_FOR_DESENSE CLK_BUF_CONTROLS_FOR_DESENSE_4 +#define PMIC_CLK_BUF3_CONTROLS_FOR_DESENSE CLK_BUF_CONTROLS_FOR_DESENSE_0 +#define PMIC_CLK_BUF4_CONTROLS_FOR_DESENSE CLK_BUF_CONTROLS_FOR_DESENSE_4 + +int clk_buf_init(void); +u32 clk_buf_get_pmrc_en(void); + +#endif diff --git a/src/soc/mediatek/mt8189/include/soc/srclken_rc.h b/src/soc/mediatek/mt8189/include/soc/srclken_rc.h new file mode 100644 index 0000000000..4fe262aa7a --- /dev/null +++ b/src/soc/mediatek/mt8189/include/soc/srclken_rc.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SRCLKEN_RC_H__ +#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SRCLKEN_RC_H__ + +#include +#include +#include + +enum chn_id { + CHN_SUSPEND = 0, + CHN_MD0, + CHN_MD1, + CHN_MD2, + CHN_MDRF, + CHN_MMWAVE = 5, + CHN_GPS, + CHN_BT, + CHN_WF, + CHN_CONN_MCU, + CHN_COANT = 10, + CHN_NFC, + CHN_SUSPEND2, + CHN_UFS, + MAX_CHN_NUM, +}; + +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[MAX_CHN_NUM]; + u32 srclken_sw_con_cfg; + u32 rc_central_cfg4; + u32 reserved1; + u32 rc_debug_cfg; + u32 reserved2; + u32 reserved3; + u32 rc_central_cfg5; + u32 rc_central_cfg6; + u32 rcen_mt_m_cfg_0; + u32 rcen_mt_m_cfg_1; + u32 rcen_mt_p_cfg_0; + u32 rcen_mt_p_cfg_1; + u32 rcen_mt_cfg_0; + u32 reserved4[12]; + u32 subsys_intf_cfg; + u32 reserved5[19]; + u32 rc_spi_sta_0; + u32 rc_pi_po_sta; + u32 rc_mxx_req_sta[MAX_CHN_NUM]; +}; +check_member(mtk_rc_regs, rc_spi_sta_0, 0x10C); + +DEFINE_BIT(SW_RESET, 0) +DEFINE_BITFIELD(CG_32K_EN, 3, 1) +DEFINE_BIT(CG_FCLK_EN, 2) +DEFINE_BIT(CG_FCLK_FR_EN, 3) +DEFINE_BIT(MUX_FCLK_FR, 4) +DEFINE_BIT(RC_32K_DCM, 8) +DEFINE_BIT(SRCLKEN_RC_EN, 0) +DEFINE_BIT(RCEN_ISSUE_M, 1) +DEFINE_BIT(RC_SPI_ACTIVE, 2) +DEFINE_BIT(SRCLKEN_RC_EN_SEL, 3) +DEFINE_BITFIELD(VCORE_SETTLE_T, 7, 5) +DEFINE_BITFIELD(ULPOSC_SETTLE_T, 11, 8) +DEFINE_BITFIELD(NON_DCXO_SETTLE_T, 21, 12) +DEFINE_BITFIELD(DCXO_SETTLE_T, 31, 22) +DEFINE_BITFIELD(SRCVOLTEN_CTRL, 3, 0) +DEFINE_BITFIELD(VREQ_CTRL, 7, 4) +DEFINE_BIT(SRCVOLTEN_VREQ_SEL, 8) +DEFINE_BIT(SRCVOLTEN_VREQ_M, 9) +DEFINE_BIT(FORCE_SRCVOLTEN_OFF, 10) +DEFINE_BIT(FORCE_SRCVOLTEN_ON, 11) +DEFINE_BITFIELD(ULPOSC_CTRL_M, 15, 12) +DEFINE_BIT(FORCE_VCORE_RDY, 16) +DEFINE_BIT(FORCE_ULPOSC2ON, 17) +DEFINE_BIT(FORCE_ULPOSC_CLK_EN, 18) +DEFINE_BIT(FORCE_ULPOSC_ON, 19) +DEFINE_BIT(DIS_ULPOSC_RDY_CHK, 20) +DEFINE_BIT(PWRAP_SLP_CTRL_M, 21) +DEFINE_BIT(PWRAP_SLP_MUX_SEL, 25) +DEFINE_BIT(FORCE_PWRAP_ON, 26) +DEFINE_BIT(FORCE_PWRAP_AWK, 27) +DEFINE_BIT(NON_DCXO_REQ_FORCEON, 28) +DEFINE_BIT(NON_DCXO_REQ_FORCEOFF, 29) +DEFINE_BIT(DCXO_REQ_FORCEON, 30) +DEFINE_BIT(DCXO_REQ_FORCEOFF, 31) +DEFINE_BITFIELD(SW_RC_EN, 12, 0) +DEFINE_BITFIELD(SW_RCEN_EN, 25, 13) +DEFINE_BIT(SW_DCXO_M_EN, 28) +DEFINE_BITFIELD(SW_DCXO_M, 31, 29) +DEFINE_BITFIELD(DCXO_FPM_CTRL_M, 3, 0) +DEFINE_BIT(SRCVOLTEN_FPM_MSK_B, 4) +DEFINE_BITFIELD(SUB_SRCLKEN_FPM_MSK_B, 28, 16) +DEFINE_BIT(TO_LPM_SETTLE_EN, 0) +DEFINE_BIT(BLK_SCP_DXCO_MD_TARGET, 1) +DEFINE_BIT(BLK_COANT_DXCO_MD_TARGET, 2) +DEFINE_BIT(TO_BBLPM_SETTLE_EN, 3) +DEFINE_BIT(TO_BBLPM_SETTLE_ND_EN, 4) +DEFINE_BITFIELD(TO_LPM_SETTLE_T, 21, 12) +DEFINE_BIT(DCXO_SETTLE_BLK_EN, 1) +DEFINE_BIT(BYPASS_CMD_EN, 2) +DEFINE_BIT(SW_SRCLKEN_RC, 3) +DEFINE_BIT(SW_SRCLKEN_FPM, 4) +DEFINE_BIT(SW_SRCLKEN_BBLPM, 5) +DEFINE_BIT(XO_SOC_LINKAGE_EN, 6) +DEFINE_BIT(REQ_ACK_LOW_IMD_EN, 7) +DEFINE_BIT(SRCLKEN_TRACK_M_EN, 8) +DEFINE_BITFIELD(CNT_PRD_STEP, 11, 10) +DEFINE_BITFIELD(XO_STABLE_PRD, 21, 12) +DEFINE_BITFIELD(DCXO_STABLE_PRD, 31, 22) +DEFINE_BIT(TACE_EN, 0) +DEFINE_BITFIELD(TIE_SYS_RDY, 4, 1) +DEFINE_BITFIELD(KEEP_RC_SPI_ACTIVE, 12, 0) +DEFINE_BIT(PWRAP_VLD_FORCE, 16) +DEFINE_BIT(SLEEP_VLD_MODE, 17) +DEFINE_BIT(SCP_SLEEP_REQ_MODE, 18) +DEFINE_BIT(SLEEP_REQ_MODE, 20) +DEFINE_BIT(BYPASS_PMIF_M, 24) +DEFINE_BIT(BYPASS_PMIF_P, 25) +DEFINE_BIT(TRACE_MODE_EN, 24) +DEFINE_BIT(DBG_STOP_PROT_EN, 28) +DEFINE_BIT(SPMI_CMD_BYTE_CNT, 0) +DEFINE_BITFIELD(SPMI_M_SLV_ID, 8, 5) +DEFINE_BITFIELD(SPMI_P_SLV_ID, 12, 9) +DEFINE_BIT(SPMI_M_PMIF_ID, 17) +DEFINE_BIT(SPMI_P_PMIF_ID, 18) +DEFINE_BITFIELD(SPMI_M_CMD_TYPE, 21, 19) +DEFINE_BITFIELD(SPMI_P_CMD_TYPE, 22, 21) +DEFINE_BIT(SPMI_M_WRITE_EN, 23) +DEFINE_BIT(SPMI_P_WRITE_EN, 24) +DEFINE_BIT(BROADCAST_MODE_EN, 25) +DEFINE_BIT(MULTI_CMD_MODE_EN, 26) +DEFINE_BIT(DCXO_ENCODE, 27) +DEFINE_BIT(SPMI_M_FIRST, 28) +DEFINE_BIT(SPMI_BYTE_NUM, 29) +DEFINE_BITFIELD(REQ_TO_DCXO_MASK, 15, 0) +DEFINE_BITFIELD(REQ_TO_SPMI_P_MASK_B, 31, 16) +DEFINE_BITFIELD(PMIC_M_COUNTER_VAL, 3, 0) +DEFINE_BITFIELD(PMIC_P_COUNTER_VAL, 7, 4) +DEFINE_BITFIELD(SRCLKEN_FPM_MASK_B, 13, 0) +DEFINE_BITFIELD(SRCLKEN_BBLPM_MASK_B, 29, 16) +DEFINE_BIT(FPM_ACK, 1) +DEFINE_BIT(BBLPM_ACK, 3) +DEFINE_BITFIELD(BYPASS_DCXO_VOTE_H, 31, 16) +DEFINE_BITFIELD(BYPASS_DCXO_VOTE_L, 15, 0) + +static struct mtk_rc_regs *const rc_regs = (void *)RC_BASE; + +#endif diff --git a/src/soc/mediatek/mt8189/srclken_rc.c b/src/soc/mediatek/mt8189/srclken_rc.c new file mode 100644 index 0000000000..c77b6d6d59 --- /dev/null +++ b/src/soc/mediatek/mt8189/srclken_rc.c @@ -0,0 +1,281 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include +#include + +#define XO_MD2_STABLE_TIME 0x80 /* ~= 1260us */ + +/* merge with spm */ +#define SRCLKENO_0_CTRL_M MERGE_OR_MODE + +/* pmrc_en address */ +/* default use this reg direct write */ +#define PMRC_CON0 0x1A6 +#define PMRC_CON0_SET 0x1A8 +#define PMRC_CON0_CLR 0x1AA + +/* SUBSYS_INTF_CFG */ +#define SUB_BBLPM_SET (1 << CHN_COANT) +#define SUB_FPM_SET (1 << CHN_SUSPEND | 1 << CHN_MD0 | \ + 1 << CHN_MD1 | 1 << CHN_MD2 | \ + 1 << CHN_MDRF | 1 << CHN_MMWAVE | \ + 1 << CHN_GPS | 1 << CHN_BT | \ + 1 << CHN_WF | 1 << CHN_CONN_MCU | \ + 1 << CHN_NFC | 1 << CHN_SUSPEND2 | \ + 1 << CHN_UFS) + +/* CFG6, mask subsys XO/DCXO request */ +#define DCXO_MASK_SUBSYS 0 +#define REQ_TO_SPMI_P_SUBSYS 0 + +/* First try to switch fpm. After polling ack done, switch to HW mode */ +const struct rc_config rc_config[MAX_CHN_NUM] = { + [CHN_SUSPEND] = { .hw_mode = true }, + [CHN_MD0] = { .hw_mode = true }, + [CHN_MD1] = { .hw_mode = true }, + [CHN_MD2] = { .hw_mode = true }, + [CHN_MDRF] = { .hw_mode = true }, + [CHN_MMWAVE] = { .hw_mode = true }, + [CHN_GPS] = { .lpm = true, .hw_mode = true }, + [CHN_BT] = { .lpm = true, .hw_mode = true }, + [CHN_WF] = { .lpm = true, .hw_mode = true }, + [CHN_CONN_MCU] = { .lpm = true, .hw_mode = true }, + [CHN_COANT] = { .lpm = true, .hw_mode = true }, + [CHN_NFC] = { .lpm = true, .hw_mode = true }, + [CHN_SUSPEND2] = { .hw_mode = true }, + [CHN_UFS] = { .lpm = true, .hw_mode = true }, +}; + +const size_t rc_config_num = ARRAY_SIZE(rc_config); + +static const struct subsys_rc_con rc_ctrl[MAX_CHN_NUM] = { + SUB_CTRL_CON_EN(CHN_SUSPEND, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_MD0, XO_MD0_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_MD1, XO_MD1_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_MD2, XO_MD2_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_MDRF, XO_MDRF_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_MMWAVE, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_GPS, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_BT, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_WF, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_CONN_MCU, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_COANT, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_NFC, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_SUSPEND2, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), + SUB_CTRL_CON_EN(CHN_UFS, XO_DEFAULT_STABLE_TIME, REQ_ACK_IMD_EN), +}; + +static void rc_dump_reg_info(void) +{ + int chn_n; + + printk(BIOS_INFO, "RG_DEBUG_CFG[24]: %#lx\n", + (read32(&rc_regs->rc_debug_cfg) & BIT(24)) >> 24); + printk(BIOS_INFO, "SRCLKEN_RC_CFG: 0x%x\n", read32(&rc_regs->srclken_rc_cfg)); + printk(BIOS_INFO, "RG_SRCLKEN_SW_CON_CFG: 0x%x\n", + read32(&rc_regs->srclken_sw_con_cfg)); + printk(BIOS_INFO, "RG_PMIC_RCEN_ADDR: 0x%x\n", read32(&rc_regs->rc_pmic_rcen_addr)); + printk(BIOS_INFO, "RG_PMIC_RCEN_SET_CLR_ADDR: 0x%x\n", + read32(&rc_regs->rc_pmic_rcen_set_clr_addr)); + printk(BIOS_INFO, "RG_CMD_ARB_CFG: 0x%x\n", read32(&rc_regs->rc_cmd_arb_cfg)); + printk(BIOS_INFO, "RG_CENTRAL_CFG1: 0x%x\n", read32(&rc_regs->rc_central_cfg1)); + printk(BIOS_INFO, "RG_CENTRAL_CFG2: 0x%x\n", read32(&rc_regs->rc_central_cfg2)); + printk(BIOS_INFO, "RG_CENTRAL_CFG3: 0x%x\n", read32(&rc_regs->rc_central_cfg3)); + printk(BIOS_INFO, "RG_CENTRAL_CFG4: 0x%x\n", read32(&rc_regs->rc_central_cfg4)); + printk(BIOS_INFO, "RG_CENTRAL_CFG5: 0x%x\n", read32(&rc_regs->rc_central_cfg5)); + printk(BIOS_INFO, "RG_CENTRAL_CFG6: 0x%x\n", read32(&rc_regs->rc_central_cfg6)); + printk(BIOS_INFO, "RG_DCXO_FPM_CFG: 0x%x\n", read32(&rc_regs->rc_dcxo_fpm_cfg)); + printk(BIOS_INFO, "SUBSYS_INTF_CFG: 0x%x\n", read32(&rc_regs->subsys_intf_cfg)); + printk(BIOS_INFO, "RC_SPI_STA_0: 0x%x\n", read32(&rc_regs->rc_spi_sta_0)); + printk(BIOS_INFO, "RC_PI_PO_STA: 0x%x\n", read32(&rc_regs->rc_pi_po_sta)); + for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) + printk(BIOS_INFO, "M%d: 0x%x\n", chn_n, + read32(&rc_regs->rc_mxx_srclken_cfg[chn_n])); +} + +static void rc_ctrl_mode_switch_init(void) +{ + int ch; + const struct subsys_rc_con *rc_ctrl_ch; + for (ch = 0; ch < MAX_CHN_NUM; ch++) { + rc_ctrl_ch = &rc_ctrl[ch]; + SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[ch], + DCXO_SETTLE_BLK_EN, rc_ctrl_ch->dcxo_settle_blk_en, + BYPASS_CMD_EN, rc_ctrl_ch->bypass_cmd, + SW_SRCLKEN_RC, rc_ctrl_ch->sw_rc, + SW_SRCLKEN_FPM, rc_ctrl_ch->sw_fpm, + SW_SRCLKEN_BBLPM, rc_ctrl_ch->sw_bblpm, + XO_SOC_LINKAGE_EN, rc_ctrl_ch->xo_soc_link_en, + REQ_ACK_LOW_IMD_EN, rc_ctrl_ch->req_ack_imd_en, + SRCLKEN_TRACK_M_EN, rc_ctrl_ch->track_en, + CNT_PRD_STEP, rc_ctrl_ch->cnt_step, + XO_STABLE_PRD, rc_ctrl_ch->xo_prd, + DCXO_STABLE_PRD, rc_ctrl_ch->dcxo_prd); + } +} + +static int polling_rc_chn_ack(int chn, u32 chk_sta) +{ + u32 pmrc_en; + + if (!retry(ACK_DELAY_TIMES, + (read32(&rc_regs->rc_mxx_req_sta[chn]) & 0xA) == chk_sta, + udelay(ACK_DELAY_US))) { + pmrc_en = clk_buf_get_pmrc_en(); + printk(BIOS_ERR, "%s: polling M%u" + "status fail(R:0x%x)(C:0x%x)(PMRC:0x%x)\n", + __func__, chn, + read32(&rc_regs->rc_mxx_req_sta[chn]), + read32(&rc_regs->rc_mxx_srclken_cfg[chn]), + pmrc_en); + return -1; + } + + return 0; +} + +int srclken_rc_init(void) +{ + int chn_n, fpm; + u32 chk_sta; + + /* Todo: Init in pll init flow */ + /* enable srclken_rc debug trace */ + SET32_BITFIELDS(&rc_regs->rc_debug_cfg, TRACE_MODE_EN, 0x1); + + /* Set SW RESET 1 */ + SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, SW_RESET, 0x1); + + /* Wait 100us */ + udelay(100); + + /* Set SW CG 1 */ + SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, CG_32K_EN, 0x7); + + /* Wait 100us */ + udelay(100); + + /* Set Clock Mux*/ + SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, MUX_FCLK_FR, 0x1); + + /* Set req_filter m00~m13 as default SW_FPM */ + rc_ctrl_mode_switch_init(); + + /* enable sw trace & pmrc_o0 sel */ + SET32_BITFIELDS(&rc_regs->srclken_sw_con_cfg, TACE_EN, 0x1); + SET32_BITFIELDS(&rc_regs->srclken_sw_con_cfg, TIE_SYS_RDY, 0x1); + + /* Set PMIC addr for SPI CMD */ + write32(&rc_regs->rc_pmic_rcen_addr, PMRC_CON0); + write32(&rc_regs->rc_cmd_arb_cfg, 0); + + /* CFG1 setting for spi cmd config */ + WRITE32_BITFIELDS(&rc_regs->rc_central_cfg1, + DCXO_SETTLE_T, DCXO_SETTLE_TIME_VAL, + NON_DCXO_SETTLE_T, NON_DCXO_SETTLE_TIME_VAL, + ULPOSC_SETTLE_T, ULPOSC_SETTLE_TIME_VAL, + VCORE_SETTLE_T, VCORE_SETTLE_TIME_VAL, + SRCLKEN_RC_EN_SEL, SRCLKEN_RC_EN_SEL_VAL, + RC_SPI_ACTIVE, KEEP_RC_SPI_ACTIVE_VAL, + RCEN_ISSUE_M, IS_SPI2PMIC_SET_CLR_VAL, + SRCLKEN_RC_EN, RC_CENTRAL_DISABLE_VAL); + + /* CFG2 setting for signal mode of each control mux */ + WRITE32_BITFIELDS(&rc_regs->rc_central_cfg2, + PWRAP_SLP_MUX_SEL, SPI_CLK_SRC, + PWRAP_SLP_CTRL_M, PWRAP_CTRL_M, + ULPOSC_CTRL_M, ULPOSC_CTRL_M_VAL, + SRCVOLTEN_VREQ_M, IS_SPI_DONE_RELEASE, + SRCVOLTEN_VREQ_SEL, SPI_TRIG_MODE, + VREQ_CTRL, VREQ_CTRL_M, + SRCVOLTEN_CTRL, SRCLKENO_0_CTRL_M); + WRITE32_BITFIELDS(&rc_regs->rc_central_cfg3, + TO_LPM_SETTLE_T, 0x4, + TO_BBLPM_SETTLE_EN, 0x1, + BLK_COANT_DXCO_MD_TARGET, 0x1, + BLK_SCP_DXCO_MD_TARGET, 0x1, + TO_LPM_SETTLE_EN, 0x1); + + /* broadcast/multi-cmd setting */ + WRITE32_BITFIELDS(&rc_regs->rc_central_cfg5, + SPMI_CMD_BYTE_CNT, RC_SPMI_BYTE_LEN, + SPMI_M_SLV_ID, PMIC_GROUP_ID, + SPMI_P_SLV_ID, PMIC_GROUP_ID, + SPMI_P_PMIF_ID, 0x1, + SPMI_M_CMD_TYPE, 0x3, + SPMI_P_CMD_TYPE, 0x3, + SPMI_M_WRITE_EN, 0x1, + SPMI_P_WRITE_EN, 0x1, + BROADCAST_MODE_EN, 0x1, + DCXO_ENCODE, 0x1, + SPMI_M_FIRST, 0x1); + + /* CFG6 = 0x0 */ + WRITE32_BITFIELDS(&rc_regs->rc_central_cfg6, + REQ_TO_DCXO_MASK, DCXO_MASK_SUBSYS, + REQ_TO_SPMI_P_MASK_B, REQ_TO_SPMI_P_SUBSYS); + + /* Set srclkeno_0/conn_bt as factor to allow dcxo change to FPM */ + WRITE32_BITFIELDS(&rc_regs->rc_dcxo_fpm_cfg, + SUB_SRCLKEN_FPM_MSK_B, FULL_SET_HW_MODE, + SRCVOLTEN_FPM_MSK_B, MD0_SRCLKENO_0_MASK_B, + DCXO_FPM_CTRL_M, DCXO_FPM_CTRL_MODE); + + /* Set bblpm/fpm channel */ + WRITE32_BITFIELDS(&rc_regs->subsys_intf_cfg, + SRCLKEN_BBLPM_MASK_B, SUB_BBLPM_SET, + SRCLKEN_FPM_MASK_B, SUB_FPM_SET); + + /* Trigger srclken_rc enable */ + SET32_BITFIELDS(&rc_regs->rc_central_cfg1, SRCLKEN_RC_EN, 0x1); + + /* MT8189 uses PMIF_M only */ + WRITE32_BITFIELDS(&rc_regs->rc_central_cfg4, + SLEEP_VLD_MODE, 0x1, + PWRAP_VLD_FORCE, 0x1, + KEEP_RC_SPI_ACTIVE, 0x800, + BYPASS_PMIF_P, 0x1); + + /* Wait 100us */ + udelay(100); + + /* Set SW RESET 0 */ + SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, SW_RESET, 0x0); + + /* Wait 100us */ + udelay(100); + + /* Set SW CG 0 */ + SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, CG_32K_EN, 0x0); + + /* 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++) { + fpm = rc_ctrl[chn_n].sw_fpm; + if (rc_config[chn_n].lpm) + fpm = SW_FPM_LOW; + + chk_sta = (fpm & SW_SRCLKEN_FPM_MSK) << 1 | + (rc_ctrl[chn_n].sw_bblpm & SW_SRCLKEN_BBLPM_MSK) << 3; + if (polling_rc_chn_ack(chn_n, chk_sta)) + die("%s() failed to polling rc_chn %d\n", __func__, chn_n); + } + + /* Set req_filter m00~m13 */ + rc_init_subsys_hw_mode(); + + /* release force pmic req signal*/ + SET32_BITFIELDS(&rc_regs->rc_central_cfg4, PWRAP_VLD_FORCE, 0x0); + + rc_dump_reg_info(); + + return 0; +}