From 2368a310be4bf60ea9c83fc89e89be9d6a040775 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Tue, 2 Feb 2021 21:00:36 +0800 Subject: soc/mediatek: Move the common part of PMIC drivers to common/ The PMIC drivers can be shared by MT8192 and MT8195. Signed-off-by: Yidi Lin Change-Id: Ie17e01d25405b1e5119d9c70c5f7afb915daf80b Reviewed-on: https://review.coreboot.org/c/coreboot/+/52666 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/common/include/soc/mt6315.h | 42 +++ src/soc/mediatek/common/include/soc/mt6359p.h | 72 +++++ src/soc/mediatek/common/include/soc/pmif_common.h | 87 ++++++ src/soc/mediatek/common/include/soc/pmif_spi.h | 119 ++++++++ src/soc/mediatek/common/include/soc/pmif_spmi.h | 87 ++++++ src/soc/mediatek/common/include/soc/pmif_sw.h | 27 ++ src/soc/mediatek/common/include/soc/spmi.h | 52 ++++ src/soc/mediatek/common/mt6315.c | 102 +++++++ src/soc/mediatek/common/mt6359p.c | 271 ++++++++++++++++++ src/soc/mediatek/common/pmif.c | 304 ++++++++++++++++++++ src/soc/mediatek/common/pmif_spi.c | 327 ++++++++++++++++++++++ src/soc/mediatek/common/pmif_spmi.c | 203 ++++++++++++++ src/soc/mediatek/mt8192/Makefile.inc | 10 +- src/soc/mediatek/mt8192/include/soc/iocfg.h | 29 ++ src/soc/mediatek/mt8192/include/soc/mt6315.h | 40 --- src/soc/mediatek/mt8192/include/soc/mt6359p.h | 69 ----- src/soc/mediatek/mt8192/include/soc/pmif.h | 79 +----- src/soc/mediatek/mt8192/include/soc/pmif_spi.h | 125 --------- src/soc/mediatek/mt8192/include/soc/pmif_spmi.h | 91 ------ src/soc/mediatek/mt8192/include/soc/pmif_sw.h | 45 --- src/soc/mediatek/mt8192/include/soc/spmi.h | 50 ---- src/soc/mediatek/mt8192/mt6315.c | 102 +------ src/soc/mediatek/mt8192/mt6359p.c | 272 +----------------- src/soc/mediatek/mt8192/pmif.c | 304 -------------------- src/soc/mediatek/mt8192/pmif_clk.c | 14 +- src/soc/mediatek/mt8192/pmif_spi.c | 322 +-------------------- src/soc/mediatek/mt8192/pmif_spmi.c | 200 +------------ 27 files changed, 1746 insertions(+), 1699 deletions(-) create mode 100644 src/soc/mediatek/common/include/soc/mt6315.h create mode 100644 src/soc/mediatek/common/include/soc/mt6359p.h create mode 100644 src/soc/mediatek/common/include/soc/pmif_common.h create mode 100644 src/soc/mediatek/common/include/soc/pmif_spi.h create mode 100644 src/soc/mediatek/common/include/soc/pmif_spmi.h create mode 100644 src/soc/mediatek/common/include/soc/pmif_sw.h create mode 100644 src/soc/mediatek/common/include/soc/spmi.h create mode 100644 src/soc/mediatek/common/mt6315.c create mode 100644 src/soc/mediatek/common/mt6359p.c create mode 100644 src/soc/mediatek/common/pmif.c create mode 100644 src/soc/mediatek/common/pmif_spi.c create mode 100644 src/soc/mediatek/common/pmif_spmi.c create mode 100644 src/soc/mediatek/mt8192/include/soc/iocfg.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/mt6315.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/mt6359p.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/pmif_spi.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/pmif_spmi.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/pmif_sw.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/spmi.h delete mode 100644 src/soc/mediatek/mt8192/pmif.c (limited to 'src/soc') diff --git a/src/soc/mediatek/common/include/soc/mt6315.h b/src/soc/mediatek/common/include/soc/mt6315.h new file mode 100644 index 0000000000..6925c3d24f --- /dev/null +++ b/src/soc/mediatek/common/include/soc/mt6315.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT6315_H__ +#define __SOC_MEDIATEK_MT6315_H__ + +#include +#include + +struct mt6315_setting { + unsigned short addr; + unsigned short val; + unsigned short mask; + unsigned char shift; +}; + +enum { + MT6315_CPU = SPMI_SLAVE_6, + MT6315_GPU = SPMI_SLAVE_7, + MT6315_MAX, +}; + +enum { + MT6315_BUCK_1 = 0, + MT6315_BUCK_2, + MT6315_BUCK_3, + MT6315_BUCK_4, + MT6315_BUCK_max, +}; + +enum { + MT6315_BUCK_TOP_ELR0 = 0x1449, + MT6315_BUCK_TOP_ELR3 = 0x144d, + MT6315_BUCK_VBUCK1_DBG0 = 0x1499, + MT6315_BUCK_VBUCK1_DBG3 = 0x1599, +}; + +void mt6315_init(void); +void mt6315_buck_set_voltage(u32 slvid, u32 buck_id, u32 buck_uv); +u32 mt6315_buck_get_voltage(u32 slvid, u32 buck_id); +void mt6315_init_setting(void); +void mt6315_write_field(u32 slvid, u32 reg, u32 val, u32 mask, u32 shift); +#endif /* __SOC_MEDIATEK_MT6315_H__ */ diff --git a/src/soc/mediatek/common/include/soc/mt6359p.h b/src/soc/mediatek/common/include/soc/mt6359p.h new file mode 100644 index 0000000000..996d2e86d9 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/mt6359p.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT6359P_H__ +#define __SOC_MEDIATEK_MT6359P_H__ + +#include + +enum { + PMIC_HWCID = 0x0008, + PMIC_SWCID = 0x000a, + PMIC_TOP_CKPDN_CON0 = 0x010c, + PMIC_TOP_CKHWEN_CON0 = 0x012a, + PMIC_TOP_RST_MISC_SET = 0x014c, + PMIC_TOP_RST_MISC_CLR = 0x014e, + PMIC_OTP_CON0 = 0x038a, + PMIC_OTP_CON8 = 0x039a, + PMIC_OTP_CON11 = 0x03a0, + PMIC_OTP_CON12 = 0x03a2, + PMIC_OTP_CON13 = 0x03a4, + PMIC_PWRHOLD = 0x0a08, + PMIC_VGPU11_DBG0 = 0x15a6, + PMIC_VGPU11_ELR0 = 0x15b4, + PMIC_VS2_VOTER = 0x18aa, + PMIC_VS2_VOTER_CFG = 0x18b0, + PMIC_VS2_ELR0 = 0x18b4, + PMIC_BUCK_VPA_DLC_CON0 = 0x1918, + PMIC_BUCK_VPA_DLC_CON1 = 0x191a, + PMIC_VSRAM_PROC1_ELR = 0x1b44, + PMIC_VSRAM_PROC2_ELR = 0x1b46, + PMIC_VSRAM_PROC1_VOSEL1 = 0x1e90, + PMIC_VSRAM_PROC2_VOSEL1 = 0x1eb0, + PMIC_VM18_ANA_CON0 = 0x2020, +}; + +struct pmic_setting { + unsigned short addr; + unsigned short val; + unsigned short mask; + unsigned char shift; +}; + +struct pmic_efuse { + unsigned short efuse_bit; + unsigned short addr; + unsigned short mask; + unsigned char shift; +}; + +enum { + MT6359P_GPU11 = 0, + MT6359P_SRAM_PROC1, + MT6359P_SRAM_PROC2, + MT6359P_MAX, +}; + +#define VM18_VOL_REG_SHIFT 8 +#define VM18_VOL_OFFSET 600 + +#define EFUSE_WAIT_US 5000 +#define EFUSE_BUSY 1 + +#define EFUSE_RG_VPA_OC_FT 78 + +void mt6359p_init(void); +void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv); +u32 mt6359p_buck_get_voltage(u32 buck_id); +void mt6359p_set_vm18_voltage(u32 vm18_uv); +u32 mt6359p_get_vm18_voltage(void); +void mt6359p_write_field(u32 reg, u32 val, u32 mask, u32 shift); +void pmic_init_setting(void); +void pmic_lp_setting(void); +#endif /* __SOC_MEDIATEK_MT6359P_H__ */ diff --git a/src/soc/mediatek/common/include/soc/pmif_common.h b/src/soc/mediatek/common/include/soc/pmif_common.h new file mode 100644 index 0000000000..a8db658c06 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/pmif_common.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __MEDIATEK_SOC_PMIF_COMMON__ +#define __MEDIATEK_SOC_PMIF_COMMON__ + +#include + +enum { + PMIF_CMD_REG_0, + PMIF_CMD_REG, + PMIF_CMD_EXT_REG, + PMIF_CMD_EXT_REG_LONG, +}; + +struct chan_regs { + u32 ch_send; + u32 wdata; + u32 reserved12[3]; + u32 rdata; + u32 reserved13[3]; + u32 ch_rdy; + u32 ch_sta; +}; + +struct pmif { + struct mtk_pmif_regs *mtk_pmif; + struct chan_regs *ch; + u32 swinf_no; + u32 mstid; + u32 pmifid; + void (*read)(struct pmif *arb, u32 slvid, u32 reg, u32 *data); + void (*write)(struct pmif *arb, u32 slvid, u32 reg, u32 data); + u32 (*read_field)(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift); + void (*write_field)(struct pmif *arb, u32 slvid, u32 reg, u32 val, u32 mask, u32 shift); + int (*is_pmif_init_done)(struct pmif *arb); +}; + +enum { + PMIF_SPI, + PMIF_SPMI, +}; + +enum { + E_IO = 1, /* I/O error */ + E_BUSY, /* Device or resource busy */ + E_NODEV, /* No such device */ + E_INVAL, /* Invalid argument */ + E_OPNOTSUPP, /* Operation not supported on transport endpoint */ + E_TIMEOUT, /* Wait for idle time out */ + E_READ_TEST_FAIL, /* SPI read fail */ + E_SPI_INIT_RESET_SPI, /* Reset SPI fail */ + E_SPI_INIT_SIDLY, /* SPI edge calibration fail */ +}; + +enum pmic_interface { + PMIF_VLD_RDY = 0, + PMIF_SLP_REQ, +}; + +DEFINE_BIT(PMIFSPI_INF_EN_SRCLKEN_RC_HW, 4) + +DEFINE_BIT(PMIFSPI_OTHER_INF_DXCO0_EN, 0) +DEFINE_BIT(PMIFSPI_OTHER_INF_DXCO1_EN, 1) + +DEFINE_BIT(PMIFSPI_ARB_EN_SRCLKEN_RC_HW, 4) +DEFINE_BIT(PMIFSPI_ARB_EN_DCXO_CONN, 15) +DEFINE_BIT(PMIFSPI_ARB_EN_DCXO_NFC, 16) + +DEFINE_BITFIELD(PMIFSPI_SPM_SLEEP_REQ_SEL, 1, 0) +DEFINE_BITFIELD(PMIFSPI_SCP_SLEEP_REQ_SEL, 10, 9) + +DEFINE_BIT(PMIFSPI_MD_CTL_PMIF_RDY, 9) +DEFINE_BIT(PMIFSPI_MD_CTL_SRCLK_EN, 10) +DEFINE_BIT(PMIFSPI_MD_CTL_SRVOL_EN, 11) + +DEFINE_BITFIELD(PMIFSPMI_SPM_SLEEP_REQ_SEL, 1, 0) +DEFINE_BITFIELD(PMIFSPMI_SCP_SLEEP_REQ_SEL, 10, 9) + +DEFINE_BIT(PMIFSPMI_MD_CTL_PMIF_RDY, 9) +DEFINE_BIT(PMIFSPMI_MD_CTL_SRCLK_EN, 10) +DEFINE_BIT(PMIFSPMI_MD_CTL_SRVOL_EN, 11) + +/* External API */ +struct pmif *get_pmif_controller(int inf, int mstid); +void pmwrap_interface_init(void); +int mtk_pmif_init(void); +#endif /*__MEDIATEK_SOC_PMIF_COMMON__*/ diff --git a/src/soc/mediatek/common/include/soc/pmif_spi.h b/src/soc/mediatek/common/include/soc/pmif_spi.h new file mode 100644 index 0000000000..ead1e81705 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/pmif_spi.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_PMIF_SPI_H__ +#define __SOC_MEDIATEK_PMIF_SPI_H__ + +#include +#include +#include + +struct mtk_pmicspi_mst_regs { + u32 reserved1[4]; + u32 other_busy_sta_0; + u32 wrap_en; + u32 reserved2[2]; + u32 man_en; + u32 man_acc; + u32 reserved3[3]; + u32 mux_sel; + u32 reserved4[3]; + u32 dio_en; + u32 rddmy; + u32 cslext_write; + u32 cslext_read; + u32 cshext_write; + u32 cshext_read; + u32 ext_ck_write; + u32 ext_ck_read; + u32 si_sampling_ctrl; +}; + +check_member(mtk_pmicspi_mst_regs, other_busy_sta_0, 0x10); +check_member(mtk_pmicspi_mst_regs, man_en, 0x20); +check_member(mtk_pmicspi_mst_regs, mux_sel, 0x34); +check_member(mtk_pmicspi_mst_regs, dio_en, 0x44); + +static struct mtk_pmicspi_mst_regs * const mtk_pmicspi_mst = (void *)PMICSPI_MST_BASE; + +/* PMIC registers */ +enum { + PMIC_BASE = 0x0000, + PMIC_SMT_CON1 = PMIC_BASE + 0x0032, + PMIC_DRV_CON1 = PMIC_BASE + 0x003a, + PMIC_FILTER_CON0 = PMIC_BASE + 0x0042, + PMIC_GPIO_PULLEN0_CLR = PMIC_BASE + 0x0098, + PMIC_RG_SPI_CON0 = PMIC_BASE + 0x0408, + PMIC_DEW_DIO_EN = PMIC_BASE + 0x040c, + PMIC_DEW_READ_TEST = PMIC_BASE + 0x040e, + PMIC_DEW_WRITE_TEST = PMIC_BASE + 0x0410, + PMIC_DEW_CRC_EN = PMIC_BASE + 0x0414, + PMIC_DEW_CRC_VAL = PMIC_BASE + 0x0416, + PMIC_DEW_RDDMY_NO = PMIC_BASE + 0x0424, + PMIC_RG_SPI_CON2 = PMIC_BASE + 0x0426, + PMIC_SPISLV_KEY = PMIC_BASE + 0x044a, + PMIC_INT_STA = PMIC_BASE + 0x0452, + PMIC_AUXADC_ADC7 = PMIC_BASE + 0x1096, + PMIC_AUXADC_ADC10 = PMIC_BASE + 0x109c, + PMIC_AUXADC_RQST0 = PMIC_BASE + 0x1108, +}; + +#define PMIF_SPI_HW_INF 0x307F +#define PMIF_SPI_MD BIT(8) +#define PMIF_SPI_AP_SECURE BIT(9) +#define PMIF_SPI_AP BIT(10) +#define PMIF_SPI_STAUPD BIT(14) +#define PMIF_SPI_TSX_HW BIT(19) +#define PMIF_SPI_DCXO_HW BIT(20) + +#define DEFAULT_SLVID 0 + +#define PMIF_CMD_STA BIT(2) +#define SPIMST_STA BIT(9) + +enum { + SPI_CLK = 0x1, + SPI_CSN = 0x1 << 1, + SPI_MOSI = 0x1 << 2, + SPI_MISO = 0x1 << 3, + SPI_FILTER = (SPI_CLK | SPI_CSN | SPI_MOSI | SPI_MISO) << 4, + SPI_SMT = SPI_CLK | SPI_CSN | SPI_MOSI | SPI_MISO, + SPI_PULL_DISABLE = (SPI_CLK | SPI_CSN | SPI_MOSI | SPI_MISO) << 4, +}; + +enum { + SLV_IO_4_MA = 0x8, +}; + +enum { + SPI_CLK_SHIFT = 0, + SPI_CSN_SHIFT = 4, + SPI_MOSI_SHIFT = 8, + SPI_MISO_SHIFT = 12, + SPI_DRIVING = SLV_IO_4_MA << SPI_CLK_SHIFT | SLV_IO_4_MA << SPI_CSN_SHIFT | + SLV_IO_4_MA << SPI_MOSI_SHIFT | SLV_IO_4_MA << SPI_MISO_SHIFT, +}; + +enum { + OP_WR = 0x1, + OP_CSH = 0x0, + OP_CSL = 0x1, + OP_OUTS = 0x8, +}; + +enum { + DEFAULT_VALUE_READ_TEST = 0x5aa5, + WRITE_TEST_VALUE = 0xa55a, +}; + +enum { + DUMMY_READ_CYCLES = 0x8, +}; + +enum { + E_CLK_EDGE = 1, + E_CLK_LAST_SETTING, +}; + +int pmif_spi_init(struct pmif *arb); +void pmif_spi_iocfg(void); +#endif /* __SOC_MEDIATEK_PMIF_SPI_H__ */ diff --git a/src/soc/mediatek/common/include/soc/pmif_spmi.h b/src/soc/mediatek/common/include/soc/pmif_spmi.h new file mode 100644 index 0000000000..142217d068 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/pmif_spmi.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_PMIF_SPMI_H__ +#define __SOC_MEDIATEK_PMIF_SPMI_H__ + +#include +#include + +#define DEFAULT_VALUE_READ_TEST (0x5a) +#define DEFAULT_VALUE_WRITE_TEST (0xa5) + +/* indicate which number SW channel start, by project */ +#define PMIF_SPMI_SW_CHAN BIT(6) +#define PMIF_SPMI_INF 0x2F7 + +struct mtk_rgu_regs { + u32 reserved[36]; + u32 wdt_swsysrst2; +}; +check_member(mtk_rgu_regs, wdt_swsysrst2, 0x90); + +struct mtk_spmi_mst_reg { + u32 op_st_ctrl; + u32 grp_id_en; + u32 op_st_sta; + u32 mst_sampl; + u32 mst_req_en; + u32 reserved1[11]; + u32 rec_ctrl; + u32 rec0; + u32 rec1; + u32 rec2; + u32 rec3; + u32 rec4; + u32 reserved2[41]; + u32 mst_dbg; +}; + +check_member(mtk_spmi_mst_reg, rec_ctrl, 0x40); +check_member(mtk_spmi_mst_reg, mst_dbg, 0xfc); + +#define mtk_rug ((struct mtk_rgu_regs *)RGU_BASE) +#define mtk_spmi_mst ((struct mtk_spmi_mst_reg *)SPMI_MST_BASE) + +struct cali { + unsigned int dly; + unsigned int pol; +}; + +enum { + SPMI_CK_NO_DLY = 0, + SPMI_CK_DLY_1T, +}; + +enum { + SPMI_CK_POL_NEG = 0, + SPMI_CK_POL_POS, +}; + +enum spmi_regs { + SPMI_OP_ST_CTRL, + SPMI_GRP_ID_EN, + SPMI_OP_ST_STA, + SPMI_MST_SAMPL, + SPMI_MST_REQ_EN, + SPMI_REC_CTRL, + SPMI_REC0, + SPMI_REC1, + SPMI_REC2, + SPMI_REC3, + SPMI_REC4, + SPMI_MST_DBG +}; + +/* MT6315 registers */ +enum { + MT6315_BASE = 0x0, + MT6315_READ_TEST = MT6315_BASE + 0x9, + MT6315_READ_TEST_1 = MT6315_BASE + 0xb, +}; + +#define MT6315_DEFAULT_VALUE_READ 0x15 + +int pmif_spmi_init(struct pmif *arb); +int spmi_config_master(void); +void pmif_spmi_iocfg(void); +#endif /* __SOC_MEDIATEK_PMIF_SPMI_H__ */ diff --git a/src/soc/mediatek/common/include/soc/pmif_sw.h b/src/soc/mediatek/common/include/soc/pmif_sw.h new file mode 100644 index 0000000000..3b3e4dfb70 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/pmif_sw.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_PMIF_SW_H__ +#define __SOC_MEDIATEK_PMIF_SW_H__ + +/* macro for SWINF_FSM */ +#define SWINF_FSM_IDLE 0x00 +#define SWINF_FSM_REQ 0x02 +#define SWINF_FSM_WFDLE 0x04 +#define SWINF_FSM_WFVLDCLR 0x06 +#define SWINF_INIT_DONE 0x01 + +#define GET_SWINF_0_FSM(x) (((x) >> 1) & 0x7) + +enum { + PMIF_READ_US = 1000, + PMIF_WAIT_IDLE_US = 1000, +}; + +/* calibation tolerance rate, unit: 0.1% */ +enum { + CAL_TOL_RATE = 40, + CAL_MAX_VAL = 0x7F, +}; + +int pmif_clk_init(void); +#endif /* __SOC_MEDIATEK_PMIF_SW_H__ */ diff --git a/src/soc/mediatek/common/include/soc/spmi.h b/src/soc/mediatek/common/include/soc/spmi.h new file mode 100644 index 0000000000..6d6d4a7df8 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/spmi.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_SPMI_H__ +#define __SOC_MEDIATEK_SPMI_H__ + +#include + +enum spmi_master { + SPMI_MASTER_0, + SPMI_MASTER_1, + SPMI_MASTER_2, + SPMI_MASTER_3, +}; + +enum spmi_slave { + SPMI_SLAVE_0, + SPMI_SLAVE_1, + SPMI_SLAVE_2, + SPMI_SLAVE_3, + SPMI_SLAVE_4, + SPMI_SLAVE_5, + SPMI_SLAVE_6, + SPMI_SLAVE_7, + SPMI_SLAVE_8, + SPMI_SLAVE_9, + SPMI_SLAVE_10, + SPMI_SLAVE_11, + SPMI_SLAVE_12, + SPMI_SLAVE_13, + SPMI_SLAVE_14, + SPMI_SLAVE_15, + SPMI_SLAVE_MAX, +}; + +enum slv_type { + BUCK_CPU, + BUCK_GPU, + SLV_TYPE_MAX, +}; + +enum slv_type_id { + BUCK_CPU_ID, + BUCK_GPU_ID, + SLV_TYPE_ID_MAX, +}; + +struct spmi_device { + u32 slvid; + enum slv_type type; + enum slv_type_id type_id; +}; +#endif /* __SOC_MEDIATEK_SPMI_H__ */ diff --git a/src/soc/mediatek/common/mt6315.c b/src/soc/mediatek/common/mt6315.c new file mode 100644 index 0000000000..928d5499be --- /dev/null +++ b/src/soc/mediatek/common/mt6315.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static struct pmif *pmif_arb = NULL; + +static void mt6315_read(u32 slvid, u32 reg, u32 *data) +{ + pmif_arb->read(pmif_arb, slvid, reg, data); +} + +static void mt6315_write(u32 slvid, u32 reg, u32 data) +{ + pmif_arb->write(pmif_arb, slvid, reg, data); +} + +void mt6315_write_field(u32 slvid, u32 reg, u32 val, u32 mask, u32 shift) +{ + pmif_arb->write_field(pmif_arb, slvid, reg, val, mask, shift); +} + +static void mt6315_wdt_enable(u32 slvid) +{ + mt6315_write(slvid, 0x3A9, 0x63); + mt6315_write(slvid, 0x3A8, 0x15); + mt6315_write(slvid, 0x127, 0x2); + mt6315_write(slvid, 0x127, 0x1); + mt6315_write(slvid, 0x127, 0x8); + udelay(50); + mt6315_write(slvid, 0x128, 0x8); + mt6315_write(slvid, 0x3A8, 0); + mt6315_write(slvid, 0x3A9, 0); +} + +void mt6315_buck_set_voltage(u32 slvid, u32 buck_id, u32 buck_uv) +{ + unsigned int vol_reg, vol_val; + + if (!pmif_arb) + die("ERROR: pmif_arb not initialized"); + + switch (buck_id) { + case MT6315_BUCK_1: + vol_reg = MT6315_BUCK_TOP_ELR0; + break; + case MT6315_BUCK_3: + vol_reg = MT6315_BUCK_TOP_ELR3; + break; + default: + die("ERROR: Unknown buck_id %u", buck_id); + return; + }; + + vol_val = buck_uv / 6250; + mt6315_write(slvid, vol_reg, vol_val); +} + +u32 mt6315_buck_get_voltage(u32 slvid, u32 buck_id) +{ + u32 vol_reg, vol; + + if (!pmif_arb) + die("ERROR: pmif_arb not initialized"); + + switch (buck_id) { + case MT6315_BUCK_1: + vol_reg = MT6315_BUCK_VBUCK1_DBG0; + break; + case MT6315_BUCK_3: + vol_reg = MT6315_BUCK_VBUCK1_DBG3; + break; + default: + die("ERROR: Unknown buck_id %u", buck_id); + return 0; + }; + + mt6315_read(slvid, vol_reg, &vol); + return vol * 6250; +} + +static void init_pmif_arb(void) +{ + if (!pmif_arb) { + pmif_arb = get_pmif_controller(PMIF_SPMI, 0); + if (!pmif_arb) + die("ERROR: No spmi device"); + } + + if (pmif_arb->is_pmif_init_done(pmif_arb)) + die("ERROR - Failed to initialize pmif spmi"); +} + +void mt6315_init(void) +{ + init_pmif_arb(); + mt6315_wdt_enable(MT6315_CPU); + mt6315_wdt_enable(MT6315_GPU); + mt6315_init_setting(); +} diff --git a/src/soc/mediatek/common/mt6359p.c b/src/soc/mediatek/common/mt6359p.c new file mode 100644 index 0000000000..8ebcfc6458 --- /dev/null +++ b/src/soc/mediatek/common/mt6359p.c @@ -0,0 +1,271 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +static const struct pmic_setting key_protect_setting[] = { + {0x3A8, 0x9CA6, 0xFFFF, 0}, + {0x44A, 0xBADE, 0xFFFF, 0}, + {0xA3A, 0x4729, 0xFFFF, 0}, + {0xC58, 0x1605, 0xFFFF, 0}, + {0xC5A, 0x1706, 0xFFFF, 0}, + {0xC5C, 0x1807, 0xFFFF, 0}, + {0xFB4, 0x6359, 0xFFFF, 0}, + {0x1432, 0x5543, 0xFFFF, 0}, +}; + +static const struct pmic_efuse efuse_setting[] = { + {79, 0xa0e, 0x1, 0xf}, + {886, 0x198c, 0xf, 0x8}, + {890, 0x198e, 0xf, 0x0}, + {902, 0x1998, 0xf, 0x8}, + {906, 0x1998, 0xf, 0xc}, + {918, 0x19a2, 0xf, 0x8}, + {922, 0x19a2, 0xf, 0xc}, + {1014, 0x19ae, 0xf, 0x7}, + {1018, 0x19ae, 0xf, 0xb}, + {1158, 0x1a0a, 0xf, 0x7}, + {1162, 0x1a0a, 0xf, 0xb}, + {1206, 0x1a16, 0xf, 0x7}, + {1210, 0x1a16, 0xf, 0xb}, + {1254, 0x1a22, 0xf, 0x7}, + {1258, 0x1a22, 0xf, 0xb}, + {1304, 0x1a2c, 0x7, 0x4}, + {1307, 0x1a32, 0x7, 0x8}, + {1336, 0x1a34, 0x7, 0x4}, + {1339, 0x1a3a, 0x7, 0x8}, + {1683, 0x79c, 0xf, 0x4}, + {1688, 0xc8a, 0x1, 0x3}, + {1689, 0xc88, 0x1, 0x3}, + {1690, 0xc88, 0x7, 0x0}, +}; + +static struct pmif *pmif_arb = NULL; +static void mt6359p_write(u32 reg, u32 data) +{ + pmif_arb->write(pmif_arb, 0, reg, data); +} + +static u32 mt6359p_read_field(u32 reg, u32 mask, u32 shift) +{ + return pmif_arb->read_field(pmif_arb, 0, reg, mask, shift); +} + +void mt6359p_write_field(u32 reg, u32 val, u32 mask, u32 shift) +{ + pmif_arb->write_field(pmif_arb, 0, reg, val, mask, shift); +} + +static void pmic_set_power_hold(void) +{ + mt6359p_write_field(PMIC_PWRHOLD, 0x1, 0x1, 0); +} + +static void pmic_wdt_set(void) +{ + /* [5]=1, RG_WDTRSTB_DEB */ + mt6359p_write_field(PMIC_TOP_RST_MISC_SET, 0x20, 0xFFFF, 0); + /* [1]=0, RG_WDTRSTB_MODE */ + mt6359p_write_field(PMIC_TOP_RST_MISC_CLR, 0x02, 0xFFFF, 0); + /* [0]=1, RG_WDTRSTB_EN */ + mt6359p_write_field(PMIC_TOP_RST_MISC_SET, 0x01, 0xFFFF, 0); +} + +static void pmic_protect_key_setting(bool lock) +{ + for (int i = 0; i < ARRAY_SIZE(key_protect_setting); i++) + mt6359p_write(key_protect_setting[i].addr, + lock ? 0 : key_protect_setting[i].val); +} + +static int check_idle(u32 timeout, u32 addr, u32 mask) +{ + if (!wait_us(timeout, !mt6359p_read_field(addr, mask, 0))) + return -1; + + return 0; +} + +static u32 pmic_read_efuse(u32 efuse_bit, u32 mask) +{ + u32 efuse_data; + int index, shift; + + index = efuse_bit / 16; + shift = efuse_bit % 16; + mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 0, 0x1, 2); + mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 0, 0x1, 4); + mt6359p_write_field(PMIC_OTP_CON11, 1, 0x1, 0); + mt6359p_write_field(PMIC_OTP_CON0, index * 2, 0xFF, 0); + if (mt6359p_read_field(PMIC_OTP_CON8, 1, 0)) + mt6359p_write_field(PMIC_OTP_CON8, 0, 1, 0); + else + mt6359p_write_field(PMIC_OTP_CON8, 1, 1, 0); + + udelay(300); + if (check_idle(EFUSE_WAIT_US, PMIC_OTP_CON13, EFUSE_BUSY)) + die("[%s] timeout after %d usecs\n", __func__, EFUSE_WAIT_US); + + udelay(100); + + efuse_data = mt6359p_read_field(PMIC_OTP_CON12, 0xFFFF, 0); + efuse_data = (efuse_data >> shift) & mask; + + mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 1, 0x1, 2); + mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 1, 0x1, 4); + + return efuse_data; +} + +static void pmic_efuse_setting(void) +{ + u32 efuse_data; + struct stopwatch sw; + + stopwatch_init(&sw); + + for (int i = 0; i < ARRAY_SIZE(efuse_setting); i++) { + efuse_data = pmic_read_efuse(efuse_setting[i].efuse_bit, efuse_setting[i].mask); + mt6359p_write_field(efuse_setting[i].addr, efuse_data, + efuse_setting[i].mask, efuse_setting[i].shift); + } + + efuse_data = pmic_read_efuse(EFUSE_RG_VPA_OC_FT, 0x1); + if (efuse_data) { + /* restore VPA_DLC initial setting */ + mt6359p_write(PMIC_BUCK_VPA_DLC_CON0, 0x2810); + mt6359p_write(PMIC_BUCK_VPA_DLC_CON1, 0x800); + } + + printk(BIOS_DEBUG, "%s: Set efuses in %ld msecs\n", + __func__, stopwatch_duration_msecs(&sw)); +} + +static void pmic_wk_vs2_voter_setting(void) +{ + /* + * 1. Set VS2_VOTER_VOSEL = 1.35V + * 2. Clear VS2_VOTER + * 3. Set VS2_VOSEL = 1.4V + */ + mt6359p_write_field(PMIC_VS2_VOTER_CFG, 0x2C, 0x7F, 0); + mt6359p_write_field(PMIC_VS2_VOTER, 0, 0xFFF, 0); + mt6359p_write_field(PMIC_VS2_ELR0, 0x30, 0x7F, 0); +} + +void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv) +{ + u32 vol_offset, vol_reg, vol; + + if (!pmif_arb) + die("ERROR: pmif_arb not initialized"); + + switch (buck_id) { + case MT6359P_GPU11: + vol_offset = 400000; + vol_reg = PMIC_VGPU11_ELR0; + break; + case MT6359P_SRAM_PROC1: + vol_offset = 500000; + vol_reg = PMIC_VSRAM_PROC1_ELR; + break; + case MT6359P_SRAM_PROC2: + vol_offset = 500000; + vol_reg = PMIC_VSRAM_PROC2_ELR; + break; + default: + die("ERROR: Unknown buck_id %u", buck_id); + return; + }; + + vol = (buck_uv - vol_offset) / 6250; + mt6359p_write_field(vol_reg, vol, 0x7F, 0); +} + +u32 mt6359p_buck_get_voltage(u32 buck_id) +{ + u32 vol_shift, vol_offset, vol_reg, vol; + + if (!pmif_arb) + die("ERROR: pmif_arb not initialized"); + + switch (buck_id) { + case MT6359P_GPU11: + vol_shift = 0; + vol_offset = 400000; + vol_reg = PMIC_VGPU11_DBG0; + break; + case MT6359P_SRAM_PROC1: + vol_shift = 8; + vol_offset = 500000; + vol_reg = PMIC_VSRAM_PROC1_VOSEL1; + break; + case MT6359P_SRAM_PROC2: + vol_shift = 8; + vol_offset = 500000; + vol_reg = PMIC_VSRAM_PROC2_VOSEL1; + break; + default: + die("ERROR: Unknown buck_id %u", buck_id); + return 0; + }; + + vol = mt6359p_read_field(vol_reg, 0x7F, vol_shift); + return vol_offset + vol * 6250; +} + +void mt6359p_set_vm18_voltage(u32 vm18_uv) +{ + u32 reg_vol, reg_cali; + + if (!pmif_arb) + die("ERROR: pmif_arb not initialized"); + + assert(vm18_uv >= 1700000); + assert(vm18_uv < 2000000); + + reg_vol = (vm18_uv / 1000 - VM18_VOL_OFFSET) / 100; + reg_cali = ((vm18_uv / 1000) % 100) / 10; + mt6359p_write(PMIC_VM18_ANA_CON0, (reg_vol << VM18_VOL_REG_SHIFT) | reg_cali); +} + +u32 mt6359p_get_vm18_voltage(void) +{ + u32 reg_vol, reg_cali; + + if (!pmif_arb) + die("ERROR: pmif_arb not initialized"); + + reg_vol = 100 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, VM18_VOL_REG_SHIFT); + reg_cali = 10 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, 0); + return 1000 * (VM18_VOL_OFFSET + reg_vol + reg_cali); +} + +static void init_pmif_arb(void) +{ + if (!pmif_arb) { + pmif_arb = get_pmif_controller(PMIF_SPI, 0); + if (!pmif_arb) + die("ERROR: No spi device"); + } + + if (pmif_arb->is_pmif_init_done(pmif_arb)) + die("ERROR - Failed to initialize pmif spi"); +} + +void mt6359p_init(void) +{ + init_pmif_arb(); + pmic_set_power_hold(); + pmic_wdt_set(); + pmic_protect_key_setting(false); + pmic_init_setting(); + pmic_lp_setting(); + pmic_efuse_setting(); + pmic_protect_key_setting(true); + pmic_wk_vs2_voter_setting(); +} diff --git a/src/soc/mediatek/common/pmif.c b/src/soc/mediatek/common/pmif.c new file mode 100644 index 0000000000..a7ab4e5fa5 --- /dev/null +++ b/src/soc/mediatek/common/pmif.c @@ -0,0 +1,304 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int pmif_check_swinf(struct pmif *arb, long timeout_us, u32 expected_status) +{ + u32 reg_rdata; + struct stopwatch sw; + + stopwatch_init_usecs_expire(&sw, timeout_us); + do { + reg_rdata = read32(&arb->ch->ch_sta); + if (stopwatch_expired(&sw)) + return E_TIMEOUT; + } while (GET_SWINF_0_FSM(reg_rdata) != expected_status); + + return 0; +} + +static void pmif_send_cmd(struct pmif *arb, int write, u32 opc, u32 slvid, + u32 addr, u32 *rdata, u32 wdata, u32 len) +{ + int ret; + u32 data, bc = len - 1; + + /* Wait for Software Interface FSM state to be IDLE. */ + ret = pmif_check_swinf(arb, PMIF_WAIT_IDLE_US, SWINF_FSM_IDLE); + if (ret) { + printk(BIOS_ERR, "[%s] idle timeout\n", __func__); + return; + } + + /* Set the write data */ + if (write) + write32(&arb->ch->wdata, wdata); + + /* Send the command. */ + write32(&arb->ch->ch_send, + (opc << 30) | (write << 29) | (slvid << 24) | (bc << 16) | addr); + + if (!write) { + /* + * Wait for Software Interface FSM state to be WFVLDCLR, + * read the data and clear the valid flag. + */ + ret = pmif_check_swinf(arb, PMIF_READ_US, SWINF_FSM_WFVLDCLR); + if (ret) { + printk(BIOS_ERR, "[%s] read timeout\n", __func__); + return; + } + + data = read32(&arb->ch->rdata); + *rdata = data; + write32(&arb->ch->ch_rdy, 0x1); + } +} + +static void pmif_spmi_read(struct pmif *arb, u32 slvid, u32 reg, u32 *data) +{ + *data = 0; + pmif_send_cmd(arb, 0, PMIF_CMD_EXT_REG_LONG, slvid, reg, data, 0, 1); +} + +static void pmif_spmi_write(struct pmif *arb, u32 slvid, u32 reg, u32 data) +{ + pmif_send_cmd(arb, 1, PMIF_CMD_EXT_REG_LONG, slvid, reg, NULL, data, 1); +} + +static u32 pmif_spmi_read_field(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift) +{ + u32 data; + + pmif_spmi_read(arb, slvid, reg, &data); + data &= (mask << shift); + data >>= shift; + + return data; +} + +static void pmif_spmi_write_field(struct pmif *arb, u32 slvid, u32 reg, + u32 val, u32 mask, u32 shift) +{ + u32 old, new; + + pmif_spmi_read(arb, slvid, reg, &old); + new = old & ~(mask << shift); + new |= (val << shift); + pmif_spmi_write(arb, slvid, reg, new); +} + +static void pmif_spi_read(struct pmif *arb, u32 slvid, u32 reg, u32 *data) +{ + *data = 0; + pmif_send_cmd(arb, 0, PMIF_CMD_REG_0, slvid, reg, data, 0, 1); +} + +static void pmif_spi_write(struct pmif *arb, u32 slvid, u32 reg, u32 data) +{ + pmif_send_cmd(arb, 1, PMIF_CMD_REG_0, slvid, reg, NULL, data, 1); +} + +static u32 pmif_spi_read_field(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift) +{ + u32 data; + + pmif_spi_read(arb, slvid, reg, &data); + data &= (mask << shift); + data >>= shift; + + return data; +} + +static void pmif_spi_write_field(struct pmif *arb, u32 slvid, u32 reg, + u32 val, u32 mask, u32 shift) +{ + u32 old, new; + + pmif_spi_read(arb, slvid, reg, &old); + new = old & ~(mask << shift); + new |= (val << shift); + pmif_spi_write(arb, slvid, reg, new); +} + +static int is_pmif_init_done(struct pmif *arb) +{ + if (read32(&arb->mtk_pmif->init_done) & 0x1) + return 0; + + return -E_NODEV; +} + +static const struct pmif pmif_spmi_arb[] = { + { + .mtk_pmif = (struct mtk_pmif_regs *)PMIF_SPMI_BASE, + .ch = (struct chan_regs *)PMIF_SPMI_AP_CHAN, + .mstid = SPMI_MASTER_0, + .pmifid = PMIF_SPMI, + .write = pmif_spmi_write, + .read = pmif_spmi_read, + .write_field = pmif_spmi_write_field, + .read_field = pmif_spmi_read_field, + .is_pmif_init_done = is_pmif_init_done, + }, +}; + +static const struct pmif pmif_spi_arb[] = { + { + .mtk_pmif = (struct mtk_pmif_regs *)PMIF_SPI_BASE, + .ch = (struct chan_regs *)PMIF_SPI_AP_CHAN, + .pmifid = PMIF_SPI, + .write = pmif_spi_write, + .read = pmif_spi_read, + .write_field = pmif_spi_write_field, + .read_field = pmif_spi_read_field, + .is_pmif_init_done = is_pmif_init_done, + }, +}; + +struct pmif *get_pmif_controller(int inf, int mstid) +{ + if (inf == PMIF_SPMI && mstid < ARRAY_SIZE(pmif_spmi_arb)) + return (struct pmif *)&pmif_spmi_arb[mstid]; + else if (inf == PMIF_SPI) + return (struct pmif *)&pmif_spi_arb[0]; + + die("[%s] Failed to get pmif controller: inf = %d, mstid = %d\n", __func__, inf, mstid); + return NULL; +} + +static void pmif_select(enum pmic_interface mode) +{ + unsigned int spi_spm_sleep_req, spi_scp_sleep_req, + spmi_spm_sleep_req, spmi_scp_sleep_req, + spi_md_ctl_pmif_rdy, spi_md_ctl_srclk_en, spi_md_ctl_srvol_en, + spmi_md_ctl_pmif_rdy, spmi_md_ctl_srclk_en, spmi_md_ctl_srvol_en, + spi_inf_srclken_rc_en, spi_other_inf_dcxo0_en, spi_other_inf_dcxo1_en, + spi_arb_srclken_rc_en, spi_arb_dcxo_conn_en, spi_arb_dcxo_nfc_en; + + switch (mode) { + case PMIF_VLD_RDY: + /* spm and scp sleep request disable spi and spmi */ + spi_spm_sleep_req = 1; + spi_scp_sleep_req = 1; + spmi_spm_sleep_req = 1; + spmi_scp_sleep_req = 1; + + /* + * pmic vld/rdy control spi mode enable + * srclken control spi mode disable + * vreq control spi mode disable + */ + spi_md_ctl_pmif_rdy = 1; + spi_md_ctl_srclk_en = 0; + spi_md_ctl_srvol_en = 0; + spmi_md_ctl_pmif_rdy = 1; + spmi_md_ctl_srclk_en = 0; + spmi_md_ctl_srvol_en = 0; + + /* srclken rc interface enable */ + spi_inf_srclken_rc_en = 1; + + /* dcxo interface disable */ + spi_other_inf_dcxo0_en = 0; + spi_other_inf_dcxo1_en = 0; + + /* srclken enable, dcxo0,1 disable */ + spi_arb_srclken_rc_en = 1; + spi_arb_dcxo_conn_en = 0; + spi_arb_dcxo_nfc_en = 0; + break; + + case PMIF_SLP_REQ: + /* spm and scp sleep request enable spi and spmi */ + spi_spm_sleep_req = 0; + spi_scp_sleep_req = 0; + spmi_spm_sleep_req = 0; + spmi_scp_sleep_req = 0; + + /* + * pmic vld/rdy control spi mode disable + * srclken control spi mode enable + * vreq control spi mode enable + */ + spi_md_ctl_pmif_rdy = 0; + spi_md_ctl_srclk_en = 1; + spi_md_ctl_srvol_en = 1; + spmi_md_ctl_pmif_rdy = 0; + spmi_md_ctl_srclk_en = 1; + spmi_md_ctl_srvol_en = 1; + + /* srclken rc interface disable */ + spi_inf_srclken_rc_en = 0; + + /* dcxo interface enable */ + spi_other_inf_dcxo0_en = 1; + spi_other_inf_dcxo1_en = 1; + + /* srclken disable, dcxo0,1 enable */ + spi_arb_srclken_rc_en = 0; + spi_arb_dcxo_conn_en = 1; + spi_arb_dcxo_nfc_en = 1; + break; + + default: + die("Can't support pmif mode %d\n", mode); + } + + SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->sleep_protection_ctrl, + PMIFSPI_SPM_SLEEP_REQ_SEL, spi_spm_sleep_req, + PMIFSPI_SCP_SLEEP_REQ_SEL, spi_scp_sleep_req); + SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->sleep_protection_ctrl, + PMIFSPMI_SPM_SLEEP_REQ_SEL, spmi_spm_sleep_req, + PMIFSPMI_SCP_SLEEP_REQ_SEL, spmi_scp_sleep_req); + SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->spi_mode_ctrl, + PMIFSPI_MD_CTL_PMIF_RDY, spi_md_ctl_pmif_rdy, + PMIFSPI_MD_CTL_SRCLK_EN, spi_md_ctl_srclk_en, + PMIFSPI_MD_CTL_SRVOL_EN, spi_md_ctl_srvol_en); + SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->spi_mode_ctrl, + PMIFSPMI_MD_CTL_PMIF_RDY, spmi_md_ctl_pmif_rdy, + PMIFSPMI_MD_CTL_SRCLK_EN, spmi_md_ctl_srclk_en, + PMIFSPMI_MD_CTL_SRVOL_EN, spmi_md_ctl_srvol_en); + SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->inf_en, + PMIFSPI_INF_EN_SRCLKEN_RC_HW, spi_inf_srclken_rc_en); + SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->other_inf_en, + PMIFSPI_OTHER_INF_DXCO0_EN, spi_other_inf_dcxo0_en, + PMIFSPI_OTHER_INF_DXCO1_EN, spi_other_inf_dcxo1_en); + SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->arb_en, + PMIFSPI_ARB_EN_SRCLKEN_RC_HW, spi_arb_srclken_rc_en, + PMIFSPI_ARB_EN_DCXO_CONN, spi_arb_dcxo_conn_en, + PMIFSPI_ARB_EN_DCXO_NFC, spi_arb_dcxo_nfc_en); +} + +void pmwrap_interface_init(void) +{ + if (CONFIG(SRCLKEN_RC_SUPPORT)) { + printk(BIOS_INFO, "%s: Select PMIF_VLD_RDY\n", __func__); + pmif_select(PMIF_VLD_RDY); + } else { + printk(BIOS_INFO, "%s: Select PMIF_SLP_REQ\n", __func__); + pmif_select(PMIF_SLP_REQ); + } +} + +int mtk_pmif_init(void) +{ + int ret; + + ret = pmif_clk_init(); + if (!ret) + ret = pmif_spmi_init(get_pmif_controller(PMIF_SPMI, SPMI_MASTER_0)); + if (!ret) + ret = pmif_spi_init(get_pmif_controller(PMIF_SPI, 0)); + + return ret; +} diff --git a/src/soc/mediatek/common/pmif_spi.c b/src/soc/mediatek/common/pmif_spi.c new file mode 100644 index 0000000000..1d0af071d4 --- /dev/null +++ b/src/soc/mediatek/common/pmif_spi.c @@ -0,0 +1,327 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* PMIF, SPI_MODE_CTRL */ +DEFINE_BIT(SPI_MODE_CTRL_VLD_SRCLK_EN_CTRL, 5) +DEFINE_BIT(SPI_MODE_CTRL_PMIF_RDY, 9) +DEFINE_BIT(SPI_MODE_CTRL_SRCLK_EN, 10) +DEFINE_BIT(SPI_MODE_CTRL_SRVOL_EN, 11) + +/* PMIF, SLEEP_PROTECTION_CTRL */ +DEFINE_BITFIELD(SPM_SLEEP_REQ_SEL, 1, 0) +DEFINE_BITFIELD(SCP_SLEEP_REQ_SEL, 10, 9) + +/* PMIF, OTHER_INF_EN */ +DEFINE_BITFIELD(INTGPSADCINF_EN, 5, 4) + +/* PMIF, STAUPD_CTRL */ +DEFINE_BITFIELD(STAUPD_CTRL_PRD, 3, 0) +DEFINE_BIT(STAUPD_CTRL_PMIC0_SIG_STA, 4) +DEFINE_BIT(STAUPD_CTRL_PMIC0_EINT_STA, 6) + +/* SPIMST, Manual_Mode_Access */ +DEFINE_BITFIELD(MAN_ACC_SPI_OP, 12, 8) +DEFINE_BIT(MAN_ACC_SPI_RW, 13) + +static void pmif_spi_config(struct pmif *arb) +{ + /* Set srclk_en always valid regardless of ulposc_sel_for_scp */ + SET32_BITFIELDS(&arb->mtk_pmif->spi_mode_ctrl, SPI_MODE_CTRL_VLD_SRCLK_EN_CTRL, 0); + + /* Set SPI mode controlled by srclk_en and srvol_en instead of pmif_rdy */ + SET32_BITFIELDS(&arb->mtk_pmif->spi_mode_ctrl, + SPI_MODE_CTRL_SRCLK_EN, 1, + SPI_MODE_CTRL_SRVOL_EN, 1, + SPI_MODE_CTRL_PMIF_RDY, 0); + + SET32_BITFIELDS(&arb->mtk_pmif->sleep_protection_ctrl, SPM_SLEEP_REQ_SEL, 0, + SCP_SLEEP_REQ_SEL, 0); + + /* Enable SWINF for AP */ + write32(&arb->mtk_pmif->inf_en, PMIF_SPI_AP); + + /* Enable arbitration for SWINF for AP */ + write32(&arb->mtk_pmif->arb_en, PMIF_SPI_AP); + + /* Enable PMIF_SPI Command Issue */ + write32(&arb->mtk_pmif->cmdissue_en, 1); +} + +static int check_idle(void *addr, u32 expected) +{ + u32 reg_rdata; + struct stopwatch sw; + + stopwatch_init_usecs_expire(&sw, PMIF_WAIT_IDLE_US); + do { + reg_rdata = read32(addr); + if (stopwatch_expired(&sw)) + return E_TIMEOUT; + } while ((reg_rdata & expected) != 0); + + return 0; +} + +static int reset_spislv(void) +{ + u32 pmicspi_mst_dio_en_backup; + + write32(&mtk_pmicspi_mst->wrap_en, 0); + write32(&mtk_pmicspi_mst->mux_sel, 1); + write32(&mtk_pmicspi_mst->man_en, 1); + pmicspi_mst_dio_en_backup = read32(&mtk_pmicspi_mst->dio_en); + write32(&mtk_pmicspi_mst->dio_en, 0); + + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_CSL); + /* Reset counter */ + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_OUTS); + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_CSH); + /* + * In order to pull CSN signal to PMIC, + * PMIC will count it then reset spi slave + */ + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_OUTS); + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_OUTS); + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_OUTS); + SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, + MAN_ACC_SPI_OP, OP_OUTS); + + /* Wait for PMIC SPI Master to be idle */ + if (check_idle(&mtk_pmicspi_mst->other_busy_sta_0, SPIMST_STA)) { + printk(BIOS_ERR, "[%s] spi master busy, timeout\n", __func__); + return E_TIMEOUT; + } + + write32(&mtk_pmicspi_mst->man_en, 0); + write32(&mtk_pmicspi_mst->mux_sel, 0); + write32(&mtk_pmicspi_mst->wrap_en, 1); + write32(&mtk_pmicspi_mst->dio_en, pmicspi_mst_dio_en_backup); + + return 0; +} + +static void init_reg_clock(struct pmif *arb) +{ + pmif_spi_iocfg(); + + /* Configure SPI protocol */ + write32(&mtk_pmicspi_mst->ext_ck_write, 1); + write32(&mtk_pmicspi_mst->ext_ck_read, 0); + write32(&mtk_pmicspi_mst->cshext_write, 0); + write32(&mtk_pmicspi_mst->cshext_read, 0); + write32(&mtk_pmicspi_mst->cslext_write, 0); + write32(&mtk_pmicspi_mst->cslext_read, 0x100); + + /* Set Read Dummy Cycle Number (Slave Clock is 18MHz) */ + arb->write(arb, DEFAULT_SLVID, PMIC_DEW_RDDMY_NO, DUMMY_READ_CYCLES); + write32(&mtk_pmicspi_mst->rddmy, DUMMY_READ_CYCLES); + + /* Enable DIO mode */ + arb->write(arb, DEFAULT_SLVID, PMIC_DEW_DIO_EN, 0x1); + + /* Wait for completion of sending the commands */ + if (check_idle(&arb->mtk_pmif->inf_busy_sta, PMIF_SPI_AP)) { + printk(BIOS_ERR, "[%s] pmif channel busy, timeout\n", __func__); + return; + } + + if (check_idle(&arb->mtk_pmif->other_busy_sta_0, PMIF_CMD_STA)) { + printk(BIOS_ERR, "[%s] pmif cmd busy, timeout\n", __func__); + return; + } + + if (check_idle(&mtk_pmicspi_mst->other_busy_sta_0, SPIMST_STA)) { + printk(BIOS_ERR, "[%s] spi master busy, timeout\n", __func__); + return; + } + + write32(&mtk_pmicspi_mst->dio_en, 1); +} + +static void init_spislv(struct pmif *arb) +{ + /* Turn on SPI IO filter function */ + arb->write(arb, DEFAULT_SLVID, PMIC_FILTER_CON0, SPI_FILTER); + /* Turn on SPI IO SMT function to improve noise immunity */ + arb->write(arb, DEFAULT_SLVID, PMIC_SMT_CON1, SPI_SMT); + /* Turn off SPI IO pull function for power saving */ + arb->write(arb, DEFAULT_SLVID, PMIC_GPIO_PULLEN0_CLR, SPI_PULL_DISABLE); + /* Enable SPI access in SODI-3.0 and Suspend modes */ + arb->write(arb, DEFAULT_SLVID, PMIC_RG_SPI_CON0, 0x2); + /* Set SPI IO driving strength to 4 mA */ + arb->write(arb, DEFAULT_SLVID, PMIC_DRV_CON1, SPI_DRIVING); +} + +static int init_sistrobe(struct pmif *arb) +{ + u32 rdata = 0; + int si_sample_ctrl; + /* Random data for testing */ + const u32 test_data[30] = { + 0x6996, 0x9669, 0x6996, 0x9669, 0x6996, 0x9669, 0x6996, + 0x9669, 0x6996, 0x9669, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, + 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x1B27, + 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, + 0x1B27, 0x1B27 + }; + + for (si_sample_ctrl = 0; si_sample_ctrl < 16; si_sample_ctrl++) { + write32(&mtk_pmicspi_mst->si_sampling_ctrl, si_sample_ctrl << 5); + + arb->read(arb, DEFAULT_SLVID, PMIC_DEW_READ_TEST, &rdata); + if (rdata == DEFAULT_VALUE_READ_TEST) + break; + } + + if (si_sample_ctrl == 16) + return E_CLK_EDGE; + + if (si_sample_ctrl == 15) + return E_CLK_LAST_SETTING; + + /* + * Add the delay time of SPI data from PMIC to align the start boundary + * to current sampling clock edge. + */ + for (int si_dly = 0; si_dly < 10; si_dly++) { + arb->write(arb, DEFAULT_SLVID, PMIC_RG_SPI_CON2, si_dly); + + int start_boundary_found = 0; + for (int i = 0; i < ARRAY_SIZE(test_data); i++) { + arb->write(arb, DEFAULT_SLVID, PMIC_DEW_WRITE_TEST, test_data[i]); + arb->read(arb, DEFAULT_SLVID, PMIC_DEW_WRITE_TEST, &rdata); + if ((rdata & 0x7fff) != (test_data[i] & 0x7fff)) { + start_boundary_found = 1; + break; + } + } + if (start_boundary_found == 1) + break; + } + + /* + * Change the sampling clock edge to the next one which is the middle + * of SPI data window. + */ + write32(&mtk_pmicspi_mst->si_sampling_ctrl, ++si_sample_ctrl << 5); + + /* Read Test */ + arb->read(arb, DEFAULT_SLVID, PMIC_DEW_READ_TEST, &rdata); + if (rdata != DEFAULT_VALUE_READ_TEST) { + printk(BIOS_ERR, "[%s] Failed for read test, data = %#x.\n", + __func__, rdata); + return E_READ_TEST_FAIL; + } + + return 0; +} + +static void init_staupd(struct pmif *arb) +{ + /* Unlock SPI Slave registers */ + arb->write(arb, DEFAULT_SLVID, PMIC_SPISLV_KEY, 0xbade); + + /* Enable CRC of PMIC 0 */ + arb->write(arb, DEFAULT_SLVID, PMIC_DEW_CRC_EN, 0x1); + + /* Wait for completion of sending the commands */ + if (check_idle(&arb->mtk_pmif->inf_busy_sta, PMIF_SPI_AP)) { + printk(BIOS_ERR, "[%s] pmif channel busy, timeout\n", __func__); + return; + } + + if (check_idle(&arb->mtk_pmif->other_busy_sta_0, PMIF_CMD_STA)) { + printk(BIOS_ERR, "[%s] pmif cmd busy, timeout\n", __func__); + return; + } + + if (check_idle(&mtk_pmicspi_mst->other_busy_sta_0, SPIMST_STA)) { + printk(BIOS_ERR, "[%s] spi master busy, timeout\n", __func__); + return; + } + + /* Configure CRC of PMIC Interface */ + write32(&arb->mtk_pmif->crc_ctrl, 0x1); + write32(&arb->mtk_pmif->sig_mode, 0x0); + + /* Lock SPI Slave registers */ + arb->write(arb, DEFAULT_SLVID, PMIC_SPISLV_KEY, 0x0); + + /* Set up PMIC Siganature */ + write32(&arb->mtk_pmif->pmic_sig_addr, PMIC_DEW_CRC_VAL); + + /* Set up PMIC EINT */ + write32(&arb->mtk_pmif->pmic_eint_sta_addr, PMIC_INT_STA); + + SET32_BITFIELDS(&arb->mtk_pmif->staupd_ctrl, + STAUPD_CTRL_PRD, 5, + STAUPD_CTRL_PMIC0_SIG_STA, 1, + STAUPD_CTRL_PMIC0_EINT_STA, 1); +} + +int pmif_spi_init(struct pmif *arb) +{ + pmif_spi_config(arb); + + /* Reset spislv */ + if (reset_spislv()) + return E_SPI_INIT_RESET_SPI; + + /* Enable WRAP */ + write32(&mtk_pmicspi_mst->wrap_en, 0x1); + + /* SPI Waveform Configuration */ + init_reg_clock(arb); + + /* SPI Slave Configuration */ + init_spislv(arb); + + /* Input data calibration flow; */ + if (init_sistrobe(arb)) { + printk(BIOS_ERR, "[%s] data calibration fail\n", __func__); + return E_SPI_INIT_SIDLY; + } + + /* Lock SPISLV Registers */ + arb->write(arb, DEFAULT_SLVID, PMIC_SPISLV_KEY, 0x0); + + /* + * Status update function initialization + * 1. Check signature using CRC (CRC 0 only) + * 2. Update EINT + * 3. Read back AUXADC thermal data for GPS + */ + init_staupd(arb); + + /* Configure PMIF Timer */ + write32(&arb->mtk_pmif->timer_ctrl, 0x3); + + /* Enable interfaces and arbitration */ + write32(&arb->mtk_pmif->inf_en, PMIF_SPI_HW_INF | PMIF_SPI_MD | + PMIF_SPI_AP_SECURE | PMIF_SPI_AP); + + write32(&arb->mtk_pmif->arb_en, PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | + PMIF_SPI_AP | PMIF_SPI_STAUPD | PMIF_SPI_TSX_HW | PMIF_SPI_DCXO_HW); + + /* Enable GPS AUXADC HW 0 and 1 */ + SET32_BITFIELDS(&arb->mtk_pmif->other_inf_en, INTGPSADCINF_EN, 0x3); + + /* Set INIT_DONE */ + write32(&arb->mtk_pmif->init_done, 0x1); + + return 0; +} diff --git a/src/soc/mediatek/common/pmif_spmi.c b/src/soc/mediatek/common/pmif_spmi.c new file mode 100644 index 0000000000..5f68c23507 --- /dev/null +++ b/src/soc/mediatek/common/pmif_spmi.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#define PMIF_CMD_PER_3 (0x1 << PMIF_CMD_EXT_REG_LONG) +#define PMIF_CMD_PER_1_3 ((0x1 << PMIF_CMD_REG) | (0x1 << PMIF_CMD_EXT_REG_LONG)) + +/* SPMI_MST, SPMI_SAMPL_CTRL */ +DEFINE_BIT(SAMPL_CK_POL, 0) +DEFINE_BITFIELD(SAMPL_CK_DLY, 3, 1) + +/* PMIF, SPI_MODE_CTRL */ +DEFINE_BIT(SPI_MODE_CTRL, 7) +DEFINE_BIT(SRVOL_EN, 11) +DEFINE_BIT(SPI_MODE_EXT_CMD, 12) +DEFINE_BIT(SPI_EINT_MODE_GATING_EN, 13) + +/* PMIF, SLEEP_PROTECTION_CTRL */ +DEFINE_BITFIELD(SPM_SLEEP_REQ_SEL, 1, 0) +DEFINE_BITFIELD(SCP_SLEEP_REQ_SEL, 10, 9) + +static const struct spmi_device spmi_dev[] = { + { + .slvid = SPMI_SLAVE_6, + .type = BUCK_CPU, + .type_id = BUCK_CPU_ID, + }, + { + .slvid = SPMI_SLAVE_7, + .type = BUCK_GPU, + .type_id = BUCK_GPU_ID, + }, +}; + +static int spmi_read_check(struct pmif *pmif_arb, int slvid) +{ + u32 rdata = 0; + + pmif_arb->read(pmif_arb, slvid, MT6315_READ_TEST, &rdata); + if (rdata != MT6315_DEFAULT_VALUE_READ) { + printk(BIOS_ERR, "%s next, slvid:%d rdata = 0x%x.\n", + __func__, slvid, rdata); + return -E_NODEV; + } + + pmif_arb->read(pmif_arb, slvid, MT6315_READ_TEST_1, &rdata); + if (rdata != MT6315_DEFAULT_VALUE_READ) { + printk(BIOS_ERR, "%s next, slvid:%d rdata = 0x%x.\n", + __func__, slvid, rdata); + return -E_NODEV; + } + + return 0; +} + +static int spmi_cali_rd_clock_polarity(struct pmif *pmif_arb, const struct spmi_device *dev) +{ + int i; + bool success = false; + const struct cali cali_data[] = { + {SPMI_CK_DLY_1T, SPMI_CK_POL_POS}, + {SPMI_CK_NO_DLY, SPMI_CK_POL_POS}, + {SPMI_CK_NO_DLY, SPMI_CK_POL_NEG}, + {SPMI_CK_DLY_1T, SPMI_CK_POL_NEG}, + }; + + /* Indicate sampling clock polarity, 1: Positive 0: Negative */ + for (i = 0; i < ARRAY_SIZE(cali_data); i++) { + SET32_BITFIELDS(&mtk_spmi_mst->mst_sampl, SAMPL_CK_DLY, cali_data[i].dly, + SAMPL_CK_POL, cali_data[i].pol); + if (spmi_read_check(pmif_arb, dev->slvid) == 0) { + success = true; + break; + } + } + + if (!success) + die("ERROR - calibration fail for spmi clk"); + + return 0; +} + +static int spmi_mst_init(struct pmif *pmif_arb) +{ + int i; + + if (!pmif_arb) { + printk(BIOS_ERR, "%s: null pointer for pmif dev.\n", __func__); + return -E_INVAL; + } + + pmif_spmi_iocfg(); + spmi_config_master(); + + for (i = 0; i < ARRAY_SIZE(spmi_dev); i++) + spmi_cali_rd_clock_polarity(pmif_arb, &spmi_dev[i]); + + return 0; +} + +static void pmif_spmi_force_normal_mode(int mstid) +{ + struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); + + /* listen srclken_0 only for entering normal or sleep mode */ + SET32_BITFIELDS(&arb->mtk_pmif->spi_mode_ctrl, + SPI_MODE_CTRL, 0, + SRVOL_EN, 0, + SPI_MODE_EXT_CMD, 1, + SPI_EINT_MODE_GATING_EN, 1); + + /* enable spm/scp sleep request */ + SET32_BITFIELDS(&arb->mtk_pmif->sleep_protection_ctrl, SPM_SLEEP_REQ_SEL, 0, + SCP_SLEEP_REQ_SEL, 0); +} + +static void pmif_spmi_enable_swinf(int mstid) +{ + struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); + + write32(&arb->mtk_pmif->inf_en, PMIF_SPMI_SW_CHAN); + write32(&arb->mtk_pmif->arb_en, PMIF_SPMI_SW_CHAN); +} + +static void pmif_spmi_enable_cmdIssue(int mstid, bool en) +{ + struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); + + /* Enable cmdIssue */ + write32(&arb->mtk_pmif->cmdissue_en, en); +} + +static void pmif_spmi_enable(int mstid) +{ + struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); + u32 cmd_per; + + /* clear all cmd permission for per channel */ + write32(&arb->mtk_pmif->inf_cmd_per_0, 0); + write32(&arb->mtk_pmif->inf_cmd_per_1, 0); + write32(&arb->mtk_pmif->inf_cmd_per_2, 0); + write32(&arb->mtk_pmif->inf_cmd_per_3, 0); + + /* enable if we need cmd 0~3 permission for per channel */ + cmd_per = PMIF_CMD_PER_3 << 28 | PMIF_CMD_PER_3 << 24 | + PMIF_CMD_PER_3 << 20 | PMIF_CMD_PER_3 << 16 | + PMIF_CMD_PER_3 << 8 | PMIF_CMD_PER_3 << 4 | + PMIF_CMD_PER_1_3 << 0; + write32(&arb->mtk_pmif->inf_cmd_per_0, cmd_per); + + cmd_per = PMIF_CMD_PER_3 << 4; + write32(&arb->mtk_pmif->inf_cmd_per_1, cmd_per); + + /* + * set bytecnt max limitation. + * hw bytecnt indicate when we set 0, it can send 1 byte; + * set 1, it can send 2 byte. + */ + write32(&arb->mtk_pmif->inf_max_bytecnt_per_0, 0); + write32(&arb->mtk_pmif->inf_max_bytecnt_per_1, 0); + write32(&arb->mtk_pmif->inf_max_bytecnt_per_2, 0); + write32(&arb->mtk_pmif->inf_max_bytecnt_per_3, 0); + + /* Add latency limitation */ + write32(&arb->mtk_pmif->lat_cnter_en, PMIF_SPMI_INF); + write32(&arb->mtk_pmif->lat_limit_0, 0); + write32(&arb->mtk_pmif->lat_limit_1, 0x4); + write32(&arb->mtk_pmif->lat_limit_2, 0x8); + write32(&arb->mtk_pmif->lat_limit_4, 0x8); + write32(&arb->mtk_pmif->lat_limit_6, 0x3FF); + write32(&arb->mtk_pmif->lat_limit_9, 0x4); + write32(&arb->mtk_pmif->lat_limit_loading, PMIF_SPMI_INF); + + write32(&arb->mtk_pmif->inf_en, PMIF_SPMI_INF); + write32(&arb->mtk_pmif->arb_en, PMIF_SPMI_INF); + write32(&arb->mtk_pmif->timer_ctrl, 0x3); + write32(&arb->mtk_pmif->init_done, 1); +} + +int pmif_spmi_init(struct pmif *arb) +{ + if (arb->is_pmif_init_done(arb) != 0) { + pmif_spmi_force_normal_mode(arb->mstid); + pmif_spmi_enable_swinf(arb->mstid); + pmif_spmi_enable_cmdIssue(arb->mstid, true); + pmif_spmi_enable(arb->mstid); + if (arb->is_pmif_init_done(arb)) + return -E_NODEV; + } + + if (spmi_mst_init(arb)) { + printk(BIOS_ERR, "[%s] failed to init spmi master\n", __func__); + return -E_NODEV; + } + + return 0; +} diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc index 9512346984..865ff40b9d 100644 --- a/src/soc/mediatek/mt8192/Makefile.inc +++ b/src/soc/mediatek/mt8192/Makefile.inc @@ -35,10 +35,12 @@ romstage-y += ../common/pll.c pll.c romstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c romstage-y += ../common/timer.c romstage-y += ../common/uart.c -romstage-y += pmif.c pmif_clk.c pmif_spi.c pmif_spmi.c +romstage-y += ../common/pmif.c pmif_clk.c +romstage-y += ../common/pmif_spi.c pmif_spi.c +romstage-y += ../common/pmif_spmi.c pmif_spmi.c romstage-y += ../common/rtc.c ../common/rtc_osc_init.c rtc.c -romstage-y += mt6315.c -romstage-y += mt6359p.c +romstage-y += ../common/mt6315.c mt6315.c +romstage-y += ../common/mt6359p.c mt6359p.c ramstage-y += ../common/auxadc.c ramstage-y += ../common/ddp.c ddp.c @@ -54,7 +56,7 @@ ramstage-y += mcupm.c ramstage-y += ../common/mmu_operations.c mmu_operations.c ramstage-$(CONFIG_COMMONLIB_STORAGE_MMC) += ../common/msdc.c ramstage-y += ../common/mtcmos.c mtcmos.c -ramstage-y += pmif.c +ramstage-y += ../common/pmif.c ramstage-y += ../common/rtc.c rtc.c ramstage-y += soc.c ramstage-y += spm.c diff --git a/src/soc/mediatek/mt8192/include/soc/iocfg.h b/src/soc/mediatek/mt8192/include/soc/iocfg.h new file mode 100644 index 0000000000..6f14c6bd90 --- /dev/null +++ b/src/soc/mediatek/mt8192/include/soc/iocfg.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT8192_IOCFG_H__ +#define __SOC_MEDIATEK_MT8192_IOCFG_H__ + +#include +#include + +struct mt8192_iocfg_lm_regs { + u32 reserved[4]; + u32 drv_cfg1; +}; +check_member(mt8192_iocfg_lm_regs, drv_cfg1, 0x10); + +enum { + IO_4_MA = 0x1, +}; + +#define mtk_iocfg_lm ((struct mt8192_iocfg_lm_regs *)IOCFG_LM_BASE) + +struct mt8192_iocfg_bm_regs { + u32 reserved[8]; + u32 drv_cfg2; +}; +check_member(mt8192_iocfg_bm_regs, drv_cfg2, 0x20); + +#define mtk_iocfg_bm ((struct mt8192_iocfg_bm_regs *)IOCFG_BM_BASE) + +#endif /* __SOC_MEDIATEK_MT8192_IOCFG_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/mt6315.h b/src/soc/mediatek/mt8192/include/soc/mt6315.h deleted file mode 100644 index 4d179bed68..0000000000 --- a/src/soc/mediatek/mt8192/include/soc/mt6315.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SOC_MEDIATEK_MT6315_H__ -#define __SOC_MEDIATEK_MT6315_H__ - -#include -#include - -struct mt6315_setting { - unsigned short addr; - unsigned short val; - unsigned short mask; - unsigned char shift; -}; - -enum { - MT6315_CPU = SPMI_SLAVE_6, - MT6315_GPU = SPMI_SLAVE_7, - MT6315_MAX, -}; - -enum { - MT6315_BUCK_1 = 0, - MT6315_BUCK_2, - MT6315_BUCK_3, - MT6315_BUCK_4, - MT6315_BUCK_max, -}; - -enum { - MT6315_BUCK_TOP_ELR0 = 0x1449, - MT6315_BUCK_TOP_ELR3 = 0x144d, - MT6315_BUCK_VBUCK1_DBG0 = 0x1499, - MT6315_BUCK_VBUCK1_DBG3 = 0x1599, -}; - -void mt6315_init(void); -void mt6315_buck_set_voltage(u32 slvid, u32 buck_id, u32 buck_uv); -u32 mt6315_buck_get_voltage(u32 slvid, u32 buck_id); -#endif /* __SOC_MEDIATEK_MT6315_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/mt6359p.h b/src/soc/mediatek/mt8192/include/soc/mt6359p.h deleted file mode 100644 index 9605272d3e..0000000000 --- a/src/soc/mediatek/mt8192/include/soc/mt6359p.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SOC_MEDIATEK_MT6359P_H__ -#define __SOC_MEDIATEK_MT6359P_H__ - -#include - -enum { - PMIC_HWCID = 0x0008, - PMIC_SWCID = 0x000a, - PMIC_TOP_CKPDN_CON0 = 0x010c, - PMIC_TOP_CKHWEN_CON0 = 0x012a, - PMIC_TOP_RST_MISC_SET = 0x014c, - PMIC_TOP_RST_MISC_CLR = 0x014e, - PMIC_OTP_CON0 = 0x038a, - PMIC_OTP_CON8 = 0x039a, - PMIC_OTP_CON11 = 0x03a0, - PMIC_OTP_CON12 = 0x03a2, - PMIC_OTP_CON13 = 0x03a4, - PMIC_PWRHOLD = 0x0a08, - PMIC_VGPU11_DBG0 = 0x15a6, - PMIC_VGPU11_ELR0 = 0x15b4, - PMIC_VS2_VOTER = 0x18aa, - PMIC_VS2_VOTER_CFG = 0x18b0, - PMIC_VS2_ELR0 = 0x18b4, - PMIC_BUCK_VPA_DLC_CON0 = 0x1918, - PMIC_BUCK_VPA_DLC_CON1 = 0x191a, - PMIC_VSRAM_PROC1_ELR = 0x1b44, - PMIC_VSRAM_PROC2_ELR = 0x1b46, - PMIC_VSRAM_PROC1_VOSEL1 = 0x1e90, - PMIC_VSRAM_PROC2_VOSEL1 = 0x1eb0, - PMIC_VM18_ANA_CON0 = 0x2020, -}; - -struct pmic_setting { - unsigned short addr; - unsigned short val; - unsigned short mask; - unsigned char shift; -}; - -struct pmic_efuse { - unsigned short efuse_bit; - unsigned short addr; - unsigned short mask; - unsigned char shift; -}; - -enum { - MT6359P_GPU11 = 0, - MT6359P_SRAM_PROC1, - MT6359P_SRAM_PROC2, - MT6359P_MAX, -}; - -#define VM18_VOL_REG_SHIFT 8 -#define VM18_VOL_OFFSET 600 - -#define EFUSE_WAIT_US 5000 -#define EFUSE_BUSY 1 - -#define EFUSE_RG_VPA_OC_FT 78 - -void mt6359p_init(void); -void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv); -u32 mt6359p_buck_get_voltage(u32 buck_id); -void mt6359p_set_vm18_voltage(u32 vm18_uv); -u32 mt6359p_get_vm18_voltage(void); -#endif /* __SOC_MEDIATEK_MT6359P_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/pmif.h b/src/soc/mediatek/mt8192/include/soc/pmif.h index cfc7fe5f1e..6c92f67733 100644 --- a/src/soc/mediatek/mt8192/include/soc/pmif.h +++ b/src/soc/mediatek/mt8192/include/soc/pmif.h @@ -4,15 +4,9 @@ #define __MT8192_SOC_PMIF_H__ #include +#include #include -enum { - PMIF_CMD_REG_0, - PMIF_CMD_REG, - PMIF_CMD_EXT_REG, - PMIF_CMD_EXT_REG_LONG, -}; - struct mtk_pmif_regs { u32 init_done; u32 reserved1[5]; @@ -128,76 +122,9 @@ check_member(mtk_pmif_regs, swinf_0_acc, 0xC00); #define PMIF_SPMI_AP_CHAN (PMIF_SPMI_BASE + 0xC80) #define PMIF_SPI_AP_CHAN (PMIF_SPI_BASE + 0xC80) -struct chan_regs { - u32 ch_send; - u32 wdata; - u32 reserved12[3]; - u32 rdata; - u32 reserved13[3]; - u32 ch_rdy; - u32 ch_sta; -}; - -struct pmif { - struct mtk_pmif_regs *mtk_pmif; - struct chan_regs *ch; - u32 swinf_no; - u32 mstid; - u32 pmifid; - void (*read)(struct pmif *arb, u32 slvid, u32 reg, u32 *data); - void (*write)(struct pmif *arb, u32 slvid, u32 reg, u32 data); - u32 (*read_field)(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift); - void (*write_field)(struct pmif *arb, u32 slvid, u32 reg, u32 val, u32 mask, u32 shift); - int (*is_pmif_init_done)(struct pmif *arb); -}; - -enum { - PMIF_SPI, - PMIF_SPMI, -}; - enum { - E_IO = 1, /* I/O error */ - E_BUSY, /* Device or resource busy */ - E_NODEV, /* No such device */ - E_INVAL, /* Invalid argument */ - E_OPNOTSUPP, /* Operation not supported on transport endpoint */ - E_TIMEOUT, /* Wait for idle time out */ - E_READ_TEST_FAIL, /* SPI read fail */ - E_SPI_INIT_RESET_SPI, /* Reset SPI fail */ - E_SPI_INIT_SIDLY, /* SPI edge calibration fail */ + FREQ_260MHZ = 260, }; -enum pmic_interface { - PMIF_VLD_RDY = 0, - PMIF_SLP_REQ, -}; - -DEFINE_BIT(PMIFSPI_INF_EN_SRCLKEN_RC_HW, 4) - -DEFINE_BIT(PMIFSPI_OTHER_INF_DXCO0_EN, 0) -DEFINE_BIT(PMIFSPI_OTHER_INF_DXCO1_EN, 1) - -DEFINE_BIT(PMIFSPI_ARB_EN_SRCLKEN_RC_HW, 4) -DEFINE_BIT(PMIFSPI_ARB_EN_DCXO_CONN, 15) -DEFINE_BIT(PMIFSPI_ARB_EN_DCXO_NFC, 16) - -DEFINE_BITFIELD(PMIFSPI_SPM_SLEEP_REQ_SEL, 1, 0) -DEFINE_BITFIELD(PMIFSPI_SCP_SLEEP_REQ_SEL, 10, 9) - -DEFINE_BIT(PMIFSPI_MD_CTL_PMIF_RDY, 9) -DEFINE_BIT(PMIFSPI_MD_CTL_SRCLK_EN, 10) -DEFINE_BIT(PMIFSPI_MD_CTL_SRVOL_EN, 11) - -DEFINE_BITFIELD(PMIFSPMI_SPM_SLEEP_REQ_SEL, 1, 0) -DEFINE_BITFIELD(PMIFSPMI_SCP_SLEEP_REQ_SEL, 10, 9) - -DEFINE_BIT(PMIFSPMI_MD_CTL_PMIF_RDY, 9) -DEFINE_BIT(PMIFSPMI_MD_CTL_SRCLK_EN, 10) -DEFINE_BIT(PMIFSPMI_MD_CTL_SRVOL_EN, 11) - -/* External API */ -extern struct pmif *get_pmif_controller(int inf, int mstid); -extern void pmwrap_interface_init(void); -extern int mtk_pmif_init(void); +#define FREQ_METER_ABIST_AD_OSC_CK 37 #endif /*__MT8192_SOC_PMIF_H__*/ diff --git a/src/soc/mediatek/mt8192/include/soc/pmif_spi.h b/src/soc/mediatek/mt8192/include/soc/pmif_spi.h deleted file mode 100644 index 426aa3bf28..0000000000 --- a/src/soc/mediatek/mt8192/include/soc/pmif_spi.h +++ /dev/null @@ -1,125 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SOC_MEDIATEK_MT8192_PMIC_WRAP_H__ -#define __SOC_MEDIATEK_MT8192_PMIC_WRAP_H__ - -#include -#include - -struct mt8192_pmicspi_mst_regs { - u32 reserved1[4]; - u32 other_busy_sta_0; - u32 wrap_en; - u32 reserved2[2]; - u32 man_en; - u32 man_acc; - u32 reserved3[3]; - u32 mux_sel; - u32 reserved4[3]; - u32 dio_en; - u32 rddmy; - u32 cslext_write; - u32 cslext_read; - u32 cshext_write; - u32 cshext_read; - u32 ext_ck_write; - u32 ext_ck_read; - u32 si_sampling_ctrl; -}; - -check_member(mt8192_pmicspi_mst_regs, other_busy_sta_0, 0x10); -check_member(mt8192_pmicspi_mst_regs, man_en, 0x20); -check_member(mt8192_pmicspi_mst_regs, mux_sel, 0x34); -check_member(mt8192_pmicspi_mst_regs, dio_en, 0x44); - -static struct mt8192_pmicspi_mst_regs * const mtk_pmicspi_mst = (void *)PMICSPI_MST_BASE; - -struct mt8192_iocfg_lm_regs { - u32 reserved[4]; - u32 drv_cfg1; -}; -check_member(mt8192_iocfg_lm_regs, drv_cfg1, 0x10); - -static struct mt8192_iocfg_lm_regs * const mtk_iocfg_lm = (void *)IOCFG_LM_BASE; - -/* PMIC registers */ -enum { - PMIC_BASE = 0x0000, - PMIC_SMT_CON1 = PMIC_BASE + 0x0032, - PMIC_DRV_CON1 = PMIC_BASE + 0x003a, - PMIC_FILTER_CON0 = PMIC_BASE + 0x0042, - PMIC_GPIO_PULLEN0_CLR = PMIC_BASE + 0x0098, - PMIC_RG_SPI_CON0 = PMIC_BASE + 0x0408, - PMIC_DEW_DIO_EN = PMIC_BASE + 0x040c, - PMIC_DEW_READ_TEST = PMIC_BASE + 0x040e, - PMIC_DEW_WRITE_TEST = PMIC_BASE + 0x0410, - PMIC_DEW_CRC_EN = PMIC_BASE + 0x0414, - PMIC_DEW_CRC_VAL = PMIC_BASE + 0x0416, - PMIC_DEW_RDDMY_NO = PMIC_BASE + 0x0424, - PMIC_RG_SPI_CON2 = PMIC_BASE + 0x0426, - PMIC_SPISLV_KEY = PMIC_BASE + 0x044a, - PMIC_INT_STA = PMIC_BASE + 0x0452, - PMIC_AUXADC_ADC7 = PMIC_BASE + 0x1096, - PMIC_AUXADC_ADC10 = PMIC_BASE + 0x109c, - PMIC_AUXADC_RQST0 = PMIC_BASE + 0x1108, -}; - -#define PMIF_SPI_HW_INF 0x307F -#define PMIF_SPI_MD BIT(8) -#define PMIF_SPI_AP_SECURE BIT(9) -#define PMIF_SPI_AP BIT(10) -#define PMIF_SPI_STAUPD BIT(14) -#define PMIF_SPI_TSX_HW BIT(19) -#define PMIF_SPI_DCXO_HW BIT(20) - -#define DEFAULT_SLVID 0 - -#define PMIF_CMD_STA BIT(2) -#define SPIMST_STA BIT(9) - -enum { - SPI_CLK = 0x1, - SPI_CSN = 0x1 << 1, - SPI_MOSI = 0x1 << 2, - SPI_MISO = 0x1 << 3, - SPI_FILTER = (SPI_CLK | SPI_CSN | SPI_MOSI | SPI_MISO) << 4, - SPI_SMT = SPI_CLK | SPI_CSN | SPI_MOSI | SPI_MISO, - SPI_PULL_DISABLE = (SPI_CLK | SPI_CSN | SPI_MOSI | SPI_MISO) << 4, -}; - -enum { - IO_4_MA = 0x1, - SLV_IO_4_MA = 0x8, -}; - -enum { - SPI_CLK_SHIFT = 0, - SPI_CSN_SHIFT = 4, - SPI_MOSI_SHIFT = 8, - SPI_MISO_SHIFT = 12, - SPI_DRIVING = SLV_IO_4_MA << SPI_CLK_SHIFT | SLV_IO_4_MA << SPI_CSN_SHIFT | - SLV_IO_4_MA << SPI_MOSI_SHIFT | SLV_IO_4_MA << SPI_MISO_SHIFT, -}; - -enum { - OP_WR = 0x1, - OP_CSH = 0x0, - OP_CSL = 0x1, - OP_OUTS = 0x8, -}; - -enum { - DEFAULT_VALUE_READ_TEST = 0x5aa5, - WRITE_TEST_VALUE = 0xa55a, -}; - -enum { - DUMMY_READ_CYCLES = 0x8, -}; - -enum { - E_CLK_EDGE = 1, - E_CLK_LAST_SETTING, -}; -extern int pmif_spi_init(struct pmif *arb); -#endif /* __SOC_MEDIATEK_MT8192_PMIC_WRAP_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/pmif_spmi.h b/src/soc/mediatek/mt8192/include/soc/pmif_spmi.h deleted file mode 100644 index d599f8cc88..0000000000 --- a/src/soc/mediatek/mt8192/include/soc/pmif_spmi.h +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __PMIF_SPMI_H__ -#define __PMIF_SPMI_H__ - -#include - -#define DEFAULT_VALUE_READ_TEST (0x5a) -#define DEFAULT_VALUE_WRITE_TEST (0xa5) - -/* indicate which number SW channel start, by project */ -#define PMIF_SPMI_SW_CHAN BIT(6) -#define PMIF_SPMI_INF 0x2F7 - -struct mtk_rgu_regs { - u32 reserved[36]; - u32 wdt_swsysrst2; -}; -check_member(mtk_rgu_regs, wdt_swsysrst2, 0x90); - -struct mtk_iocfg_bm_regs { - u32 reserved[8]; - u32 drv_cfg2; -}; -check_member(mtk_iocfg_bm_regs, drv_cfg2, 0x20); - -struct mtk_spmi_mst_reg { - u32 op_st_ctrl; - u32 grp_id_en; - u32 op_st_sta; - u32 mst_sampl; - u32 mst_req_en; - u32 reserved1[11]; - u32 rec_ctrl; - u32 rec0; - u32 rec1; - u32 rec2; - u32 rec3; - u32 rec4; - u32 reserved2[41]; - u32 mst_dbg; -}; - -check_member(mtk_spmi_mst_reg, rec_ctrl, 0x40); -check_member(mtk_spmi_mst_reg, mst_dbg, 0xfc); - -#define mtk_rug ((struct mtk_rgu_regs *)RGU_BASE) -#define mtk_iocfg_bm ((struct mtk_iocfg_bm_regs *)IOCFG_BM_BASE) -#define mtk_spmi_mst ((struct mtk_spmi_mst_reg *)SPMI_MST_BASE) - -struct cali { - unsigned int dly; - unsigned int pol; -}; - -enum { - SPMI_CK_NO_DLY = 0, - SPMI_CK_DLY_1T, -}; - -enum { - SPMI_CK_POL_NEG = 0, - SPMI_CK_POL_POS, -}; - -enum spmi_regs { - SPMI_OP_ST_CTRL, - SPMI_GRP_ID_EN, - SPMI_OP_ST_STA, - SPMI_MST_SAMPL, - SPMI_MST_REQ_EN, - SPMI_REC_CTRL, - SPMI_REC0, - SPMI_REC1, - SPMI_REC2, - SPMI_REC3, - SPMI_REC4, - SPMI_MST_DBG -}; - -/* MT6315 registers */ -enum { - MT6315_BASE = 0x0, - MT6315_READ_TEST = MT6315_BASE + 0x9, - MT6315_READ_TEST_1 = MT6315_BASE + 0xb, -}; - -#define MT6315_DEFAULT_VALUE_READ 0x15 - -extern int pmif_spmi_init(struct pmif *arb); -#endif /*__PMIF_SPMI_H__*/ diff --git a/src/soc/mediatek/mt8192/include/soc/pmif_sw.h b/src/soc/mediatek/mt8192/include/soc/pmif_sw.h deleted file mode 100644 index fb4cbc967e..0000000000 --- a/src/soc/mediatek/mt8192/include/soc/pmif_sw.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __PMIF_SW_H__ -#define __PMIF_SW_H__ - -/* Read/write byte limitation, by project */ -/* hw bytecnt indicate when we set 0, it can send 1 byte; - * set 1, it can send 2 byte. - */ -#define PMIF_BYTECNT_MAX 1 - -/* macro for SWINF_FSM */ -#define SWINF_FSM_IDLE 0x00 -#define SWINF_FSM_REQ 0x02 -#define SWINF_FSM_WFDLE 0x04 -#define SWINF_FSM_WFVLDCLR 0x06 -#define SWINF_INIT_DONE 0x01 - -#define FREQ_METER_ABIST_AD_OSC_CK 37 -#define GET_SWINF_0_FSM(x) (((x) >> 1) & 0x7) - -struct pmif_mpu { - unsigned int rgn_slvid; - unsigned short rgn_s_addr; - unsigned short rgn_e_addr; - unsigned int rgn_domain_per; -}; - -enum { - PMIF_READ_US = 1000, - PMIF_WAIT_IDLE_US = 1000, -}; - -enum { - FREQ_260MHZ = 260, -}; - -/* calibation tolerance rate, unit: 0.1% */ -enum { - CAL_TOL_RATE = 40, - CAL_MAX_VAL = 0x7F, -}; - -extern int pmif_clk_init(void); -#endif /*__PMIF_SW_H__*/ diff --git a/src/soc/mediatek/mt8192/include/soc/spmi.h b/src/soc/mediatek/mt8192/include/soc/spmi.h deleted file mode 100644 index 0d44198f82..0000000000 --- a/src/soc/mediatek/mt8192/include/soc/spmi.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SPMI_H__ -#define __SPMI_H__ - -enum spmi_master { - SPMI_MASTER_0, - SPMI_MASTER_1, - SPMI_MASTER_2, - SPMI_MASTER_3, -}; - -enum spmi_slave { - SPMI_SLAVE_0, - SPMI_SLAVE_1, - SPMI_SLAVE_2, - SPMI_SLAVE_3, - SPMI_SLAVE_4, - SPMI_SLAVE_5, - SPMI_SLAVE_6, - SPMI_SLAVE_7, - SPMI_SLAVE_8, - SPMI_SLAVE_9, - SPMI_SLAVE_10, - SPMI_SLAVE_11, - SPMI_SLAVE_12, - SPMI_SLAVE_13, - SPMI_SLAVE_14, - SPMI_SLAVE_15, - SPMI_SLAVE_MAX, -}; - -enum slv_type { - BUCK_CPU, - BUCK_GPU, - SLV_TYPE_MAX, -}; - -enum slv_type_id { - BUCK_CPU_ID, - BUCK_GPU_ID, - SLV_TYPE_ID_MAX, -}; - -struct spmi_device { - u32 slvid; - enum slv_type type; - enum slv_type_id type_id; -}; -#endif /*__SPMI_H__*/ diff --git a/src/soc/mediatek/mt8192/mt6315.c b/src/soc/mediatek/mt8192/mt6315.c index efb1504d5c..6457f58993 100644 --- a/src/soc/mediatek/mt8192/mt6315.c +++ b/src/soc/mediatek/mt8192/mt6315.c @@ -1,13 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include -#include -#include #include -static struct pmif *pmif_arb = NULL; - static const struct mt6315_setting init_setting_cpu[] = { /* disable magic key protection */ {0x3A9, 0x63, 0xFF, 0}, @@ -194,35 +188,7 @@ static const struct mt6315_setting init_setting_gpu[] = { {0x3A9, 0, 0xFF, 0}, }; -static void mt6315_read(u32 slvid, u32 reg, u32 *data) -{ - pmif_arb->read(pmif_arb, slvid, reg, data); -} - -static void mt6315_write(u32 slvid, u32 reg, u32 data) -{ - pmif_arb->write(pmif_arb, slvid, reg, data); -} - -static void mt6315_write_field(u32 slvid, u32 reg, u32 val, u32 mask, u32 shift) -{ - pmif_arb->write_field(pmif_arb, slvid, reg, val, mask, shift); -} - -static void mt6315_wdt_enable(u32 slvid) -{ - mt6315_write(slvid, 0x3A9, 0x63); - mt6315_write(slvid, 0x3A8, 0x15); - mt6315_write(slvid, 0x127, 0x2); - mt6315_write(slvid, 0x127, 0x1); - mt6315_write(slvid, 0x127, 0x8); - udelay(50); - mt6315_write(slvid, 0x128, 0x8); - mt6315_write(slvid, 0x3A8, 0); - mt6315_write(slvid, 0x3A9, 0); -} - -static void mt6315_init_setting(void) +void mt6315_init_setting(void) { for (int i = 0; i < ARRAY_SIZE(init_setting_cpu); i++) mt6315_write_field(MT6315_CPU, @@ -234,69 +200,3 @@ static void mt6315_init_setting(void) init_setting_gpu[i].addr, init_setting_gpu[i].val, init_setting_gpu[i].mask, init_setting_gpu[i].shift); } - -void mt6315_buck_set_voltage(u32 slvid, u32 buck_id, u32 buck_uv) -{ - unsigned int vol_reg, vol_val; - - if (!pmif_arb) - die("ERROR: pmif_arb not initialized"); - - switch (buck_id) { - case MT6315_BUCK_1: - vol_reg = MT6315_BUCK_TOP_ELR0; - break; - case MT6315_BUCK_3: - vol_reg = MT6315_BUCK_TOP_ELR3; - break; - default: - die("ERROR: Unknown buck_id %u", buck_id); - return; - }; - - vol_val = buck_uv / 6250; - mt6315_write(slvid, vol_reg, vol_val); -} - -u32 mt6315_buck_get_voltage(u32 slvid, u32 buck_id) -{ - u32 vol_reg, vol; - - if (!pmif_arb) - die("ERROR: pmif_arb not initialized"); - - switch (buck_id) { - case MT6315_BUCK_1: - vol_reg = MT6315_BUCK_VBUCK1_DBG0; - break; - case MT6315_BUCK_3: - vol_reg = MT6315_BUCK_VBUCK1_DBG3; - break; - default: - die("ERROR: Unknown buck_id %u", buck_id); - return 0; - }; - - mt6315_read(slvid, vol_reg, &vol); - return vol * 6250; -} - -static void init_pmif_arb(void) -{ - if (!pmif_arb) { - pmif_arb = get_pmif_controller(PMIF_SPMI, 0); - if (!pmif_arb) - die("ERROR: No spmi device"); - } - - if (pmif_arb->is_pmif_init_done(pmif_arb)) - die("ERROR - Failed to initialize pmif spmi"); -} - -void mt6315_init(void) -{ - init_pmif_arb(); - mt6315_wdt_enable(MT6315_CPU); - mt6315_wdt_enable(MT6315_GPU); - mt6315_init_setting(); -} diff --git a/src/soc/mediatek/mt8192/mt6359p.c b/src/soc/mediatek/mt8192/mt6359p.c index 453481290f..7579e2db73 100644 --- a/src/soc/mediatek/mt8192/mt6359p.c +++ b/src/soc/mediatek/mt8192/mt6359p.c @@ -1,22 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include -#include -#include #include -#include - -static const struct pmic_setting key_protect_setting[] = { - {0x3A8, 0x9CA6, 0xFFFF, 0}, - {0x44A, 0xBADE, 0xFFFF, 0}, - {0xA3A, 0x4729, 0xFFFF, 0}, - {0xC58, 0x1605, 0xFFFF, 0}, - {0xC5A, 0x1706, 0xFFFF, 0}, - {0xC5C, 0x1807, 0xFFFF, 0}, - {0xFB4, 0x6359, 0xFFFF, 0}, - {0x1432, 0x5543, 0xFFFF, 0}, -}; static const struct pmic_setting init_setting[] = { {0x20, 0xA, 0xA, 0}, @@ -299,268 +283,16 @@ static const struct pmic_setting lp_setting[] = { {0x1d14, 0x1, 0x1, 0x2}, }; -static const struct pmic_efuse efuse_setting[] = { - {79, 0xa0e, 0x1, 0xf}, - {886, 0x198c, 0xf, 0x8}, - {890, 0x198e, 0xf, 0x0}, - {902, 0x1998, 0xf, 0x8}, - {906, 0x1998, 0xf, 0xc}, - {918, 0x19a2, 0xf, 0x8}, - {922, 0x19a2, 0xf, 0xc}, - {1014, 0x19ae, 0xf, 0x7}, - {1018, 0x19ae, 0xf, 0xb}, - {1158, 0x1a0a, 0xf, 0x7}, - {1162, 0x1a0a, 0xf, 0xb}, - {1206, 0x1a16, 0xf, 0x7}, - {1210, 0x1a16, 0xf, 0xb}, - {1254, 0x1a22, 0xf, 0x7}, - {1258, 0x1a22, 0xf, 0xb}, - {1304, 0x1a2c, 0x7, 0x4}, - {1307, 0x1a32, 0x7, 0x8}, - {1336, 0x1a34, 0x7, 0x4}, - {1339, 0x1a3a, 0x7, 0x8}, - {1683, 0x79c, 0xf, 0x4}, - {1688, 0xc8a, 0x1, 0x3}, - {1689, 0xc88, 0x1, 0x3}, - {1690, 0xc88, 0x7, 0x0}, -}; - -static struct pmif *pmif_arb = NULL; -static void mt6359p_write(u32 reg, u32 data) -{ - pmif_arb->write(pmif_arb, 0, reg, data); -} - -static u32 mt6359p_read_field(u32 reg, u32 mask, u32 shift) -{ - return pmif_arb->read_field(pmif_arb, 0, reg, mask, shift); -} - -static void mt6359p_write_field(u32 reg, u32 val, u32 mask, u32 shift) -{ - pmif_arb->write_field(pmif_arb, 0, reg, val, mask, shift); -} - -static void pmic_set_power_hold(void) -{ - mt6359p_write_field(PMIC_PWRHOLD, 0x1, 0x1, 0); -} - -static void pmic_wdt_set(void) -{ - /* [5]=1, RG_WDTRSTB_DEB */ - mt6359p_write_field(PMIC_TOP_RST_MISC_SET, 0x20, 0xFFFF, 0); - /* [1]=0, RG_WDTRSTB_MODE */ - mt6359p_write_field(PMIC_TOP_RST_MISC_CLR, 0x02, 0xFFFF, 0); - /* [0]=1, RG_WDTRSTB_EN */ - mt6359p_write_field(PMIC_TOP_RST_MISC_SET, 0x01, 0xFFFF, 0); -} - -static void pmic_protect_key_setting(bool lock) -{ - for (int i = 0; i < ARRAY_SIZE(key_protect_setting); i++) - mt6359p_write(key_protect_setting[i].addr, - lock ? 0 : key_protect_setting[i].val); -} - -static int check_idle(u32 timeout, u32 addr, u32 mask) -{ - if (!wait_us(timeout, !mt6359p_read_field(addr, mask, 0))) - return -1; - - return 0; -} - -static u32 pmic_read_efuse(u32 efuse_bit, u32 mask) -{ - u32 efuse_data; - int index, shift; - - index = efuse_bit / 16; - shift = efuse_bit % 16; - mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 0, 0x1, 2); - mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 0, 0x1, 4); - mt6359p_write_field(PMIC_OTP_CON11, 1, 0x1, 0); - mt6359p_write_field(PMIC_OTP_CON0, index * 2, 0xFF, 0); - if (mt6359p_read_field(PMIC_OTP_CON8, 1, 0)) - mt6359p_write_field(PMIC_OTP_CON8, 0, 1, 0); - else - mt6359p_write_field(PMIC_OTP_CON8, 1, 1, 0); - - udelay(300); - if (check_idle(EFUSE_WAIT_US, PMIC_OTP_CON13, EFUSE_BUSY)) - die("[%s] timeout after %d usecs\n", __func__, EFUSE_WAIT_US); - - udelay(100); - - efuse_data = mt6359p_read_field(PMIC_OTP_CON12, 0xFFFF, 0); - efuse_data = (efuse_data >> shift) & mask; - - mt6359p_write_field(PMIC_TOP_CKHWEN_CON0, 1, 0x1, 2); - mt6359p_write_field(PMIC_TOP_CKPDN_CON0, 1, 0x1, 4); - - return efuse_data; -} - -static void pmic_init_setting(void) +void pmic_init_setting(void) { for (int i = 0; i < ARRAY_SIZE(init_setting); i++) mt6359p_write_field(init_setting[i].addr, init_setting[i].val, init_setting[i].mask, init_setting[i].shift); } -static void pmic_lp_setting(void) +void pmic_lp_setting(void) { for (int i = 0; i < ARRAY_SIZE(lp_setting); i++) mt6359p_write_field(lp_setting[i].addr, lp_setting[i].val, lp_setting[i].mask, lp_setting[i].shift); } - -static void pmic_efuse_setting(void) -{ - u32 efuse_data; - struct stopwatch sw; - - stopwatch_init(&sw); - - for (int i = 0; i < ARRAY_SIZE(efuse_setting); i++) { - efuse_data = pmic_read_efuse(efuse_setting[i].efuse_bit, efuse_setting[i].mask); - mt6359p_write_field(efuse_setting[i].addr, efuse_data, - efuse_setting[i].mask, efuse_setting[i].shift); - } - - efuse_data = pmic_read_efuse(EFUSE_RG_VPA_OC_FT, 0x1); - if (efuse_data) { - /* restore VPA_DLC initial setting */ - mt6359p_write(PMIC_BUCK_VPA_DLC_CON0, 0x2810); - mt6359p_write(PMIC_BUCK_VPA_DLC_CON1, 0x800); - } - - printk(BIOS_DEBUG, "%s: Set efuses in %ld msecs\n", - __func__, stopwatch_duration_msecs(&sw)); -} - -static void pmic_wk_vs2_voter_setting(void) -{ - /* - * 1. Set VS2_VOTER_VOSEL = 1.35V - * 2. Clear VS2_VOTER - * 3. Set VS2_VOSEL = 1.4V - */ - mt6359p_write_field(PMIC_VS2_VOTER_CFG, 0x2C, 0x7F, 0); - mt6359p_write_field(PMIC_VS2_VOTER, 0, 0xFFF, 0); - mt6359p_write_field(PMIC_VS2_ELR0, 0x30, 0x7F, 0); -} - -void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv) -{ - u32 vol_offset, vol_reg, vol; - - if (!pmif_arb) - die("ERROR: pmif_arb not initialized"); - - switch (buck_id) { - case MT6359P_GPU11: - vol_offset = 400000; - vol_reg = PMIC_VGPU11_ELR0; - break; - case MT6359P_SRAM_PROC1: - vol_offset = 500000; - vol_reg = PMIC_VSRAM_PROC1_ELR; - break; - case MT6359P_SRAM_PROC2: - vol_offset = 500000; - vol_reg = PMIC_VSRAM_PROC2_ELR; - break; - default: - die("ERROR: Unknown buck_id %u", buck_id); - return; - }; - - vol = (buck_uv - vol_offset) / 6250; - mt6359p_write_field(vol_reg, vol, 0x7F, 0); -} - -u32 mt6359p_buck_get_voltage(u32 buck_id) -{ - u32 vol_shift, vol_offset, vol_reg, vol; - - if (!pmif_arb) - die("ERROR: pmif_arb not initialized"); - - switch (buck_id) { - case MT6359P_GPU11: - vol_shift = 0; - vol_offset = 400000; - vol_reg = PMIC_VGPU11_DBG0; - break; - case MT6359P_SRAM_PROC1: - vol_shift = 8; - vol_offset = 500000; - vol_reg = PMIC_VSRAM_PROC1_VOSEL1; - break; - case MT6359P_SRAM_PROC2: - vol_shift = 8; - vol_offset = 500000; - vol_reg = PMIC_VSRAM_PROC2_VOSEL1; - break; - default: - die("ERROR: Unknown buck_id %u", buck_id); - return 0; - }; - - vol = mt6359p_read_field(vol_reg, 0x7F, vol_shift); - return vol_offset + vol * 6250; -} - -void mt6359p_set_vm18_voltage(u32 vm18_uv) -{ - u32 reg_vol, reg_cali; - - if (!pmif_arb) - die("ERROR: pmif_arb not initialized"); - - assert(vm18_uv >= 1700000); - assert(vm18_uv < 2000000); - - reg_vol = (vm18_uv / 1000 - VM18_VOL_OFFSET) / 100; - reg_cali = ((vm18_uv / 1000) % 100) / 10; - mt6359p_write(PMIC_VM18_ANA_CON0, (reg_vol << VM18_VOL_REG_SHIFT) | reg_cali); -} - -u32 mt6359p_get_vm18_voltage(void) -{ - u32 reg_vol, reg_cali; - - if (!pmif_arb) - die("ERROR: pmif_arb not initialized"); - - reg_vol = 100 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, VM18_VOL_REG_SHIFT); - reg_cali = 10 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, 0); - return 1000 * (VM18_VOL_OFFSET + reg_vol + reg_cali); -} - -static void init_pmif_arb(void) -{ - if (!pmif_arb) { - pmif_arb = get_pmif_controller(PMIF_SPI, 0); - if (!pmif_arb) - die("ERROR: No spi device"); - } - - if (pmif_arb->is_pmif_init_done(pmif_arb)) - die("ERROR - Failed to initialize pmif spi"); -} - -void mt6359p_init(void) -{ - init_pmif_arb(); - pmic_set_power_hold(); - pmic_wdt_set(); - pmic_protect_key_setting(false); - pmic_init_setting(); - pmic_lp_setting(); - pmic_efuse_setting(); - pmic_protect_key_setting(true); - pmic_wk_vs2_voter_setting(); -} diff --git a/src/soc/mediatek/mt8192/pmif.c b/src/soc/mediatek/mt8192/pmif.c deleted file mode 100644 index a7ab4e5fa5..0000000000 --- a/src/soc/mediatek/mt8192/pmif.c +++ /dev/null @@ -1,304 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int pmif_check_swinf(struct pmif *arb, long timeout_us, u32 expected_status) -{ - u32 reg_rdata; - struct stopwatch sw; - - stopwatch_init_usecs_expire(&sw, timeout_us); - do { - reg_rdata = read32(&arb->ch->ch_sta); - if (stopwatch_expired(&sw)) - return E_TIMEOUT; - } while (GET_SWINF_0_FSM(reg_rdata) != expected_status); - - return 0; -} - -static void pmif_send_cmd(struct pmif *arb, int write, u32 opc, u32 slvid, - u32 addr, u32 *rdata, u32 wdata, u32 len) -{ - int ret; - u32 data, bc = len - 1; - - /* Wait for Software Interface FSM state to be IDLE. */ - ret = pmif_check_swinf(arb, PMIF_WAIT_IDLE_US, SWINF_FSM_IDLE); - if (ret) { - printk(BIOS_ERR, "[%s] idle timeout\n", __func__); - return; - } - - /* Set the write data */ - if (write) - write32(&arb->ch->wdata, wdata); - - /* Send the command. */ - write32(&arb->ch->ch_send, - (opc << 30) | (write << 29) | (slvid << 24) | (bc << 16) | addr); - - if (!write) { - /* - * Wait for Software Interface FSM state to be WFVLDCLR, - * read the data and clear the valid flag. - */ - ret = pmif_check_swinf(arb, PMIF_READ_US, SWINF_FSM_WFVLDCLR); - if (ret) { - printk(BIOS_ERR, "[%s] read timeout\n", __func__); - return; - } - - data = read32(&arb->ch->rdata); - *rdata = data; - write32(&arb->ch->ch_rdy, 0x1); - } -} - -static void pmif_spmi_read(struct pmif *arb, u32 slvid, u32 reg, u32 *data) -{ - *data = 0; - pmif_send_cmd(arb, 0, PMIF_CMD_EXT_REG_LONG, slvid, reg, data, 0, 1); -} - -static void pmif_spmi_write(struct pmif *arb, u32 slvid, u32 reg, u32 data) -{ - pmif_send_cmd(arb, 1, PMIF_CMD_EXT_REG_LONG, slvid, reg, NULL, data, 1); -} - -static u32 pmif_spmi_read_field(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift) -{ - u32 data; - - pmif_spmi_read(arb, slvid, reg, &data); - data &= (mask << shift); - data >>= shift; - - return data; -} - -static void pmif_spmi_write_field(struct pmif *arb, u32 slvid, u32 reg, - u32 val, u32 mask, u32 shift) -{ - u32 old, new; - - pmif_spmi_read(arb, slvid, reg, &old); - new = old & ~(mask << shift); - new |= (val << shift); - pmif_spmi_write(arb, slvid, reg, new); -} - -static void pmif_spi_read(struct pmif *arb, u32 slvid, u32 reg, u32 *data) -{ - *data = 0; - pmif_send_cmd(arb, 0, PMIF_CMD_REG_0, slvid, reg, data, 0, 1); -} - -static void pmif_spi_write(struct pmif *arb, u32 slvid, u32 reg, u32 data) -{ - pmif_send_cmd(arb, 1, PMIF_CMD_REG_0, slvid, reg, NULL, data, 1); -} - -static u32 pmif_spi_read_field(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift) -{ - u32 data; - - pmif_spi_read(arb, slvid, reg, &data); - data &= (mask << shift); - data >>= shift; - - return data; -} - -static void pmif_spi_write_field(struct pmif *arb, u32 slvid, u32 reg, - u32 val, u32 mask, u32 shift) -{ - u32 old, new; - - pmif_spi_read(arb, slvid, reg, &old); - new = old & ~(mask << shift); - new |= (val << shift); - pmif_spi_write(arb, slvid, reg, new); -} - -static int is_pmif_init_done(struct pmif *arb) -{ - if (read32(&arb->mtk_pmif->init_done) & 0x1) - return 0; - - return -E_NODEV; -} - -static const struct pmif pmif_spmi_arb[] = { - { - .mtk_pmif = (struct mtk_pmif_regs *)PMIF_SPMI_BASE, - .ch = (struct chan_regs *)PMIF_SPMI_AP_CHAN, - .mstid = SPMI_MASTER_0, - .pmifid = PMIF_SPMI, - .write = pmif_spmi_write, - .read = pmif_spmi_read, - .write_field = pmif_spmi_write_field, - .read_field = pmif_spmi_read_field, - .is_pmif_init_done = is_pmif_init_done, - }, -}; - -static const struct pmif pmif_spi_arb[] = { - { - .mtk_pmif = (struct mtk_pmif_regs *)PMIF_SPI_BASE, - .ch = (struct chan_regs *)PMIF_SPI_AP_CHAN, - .pmifid = PMIF_SPI, - .write = pmif_spi_write, - .read = pmif_spi_read, - .write_field = pmif_spi_write_field, - .read_field = pmif_spi_read_field, - .is_pmif_init_done = is_pmif_init_done, - }, -}; - -struct pmif *get_pmif_controller(int inf, int mstid) -{ - if (inf == PMIF_SPMI && mstid < ARRAY_SIZE(pmif_spmi_arb)) - return (struct pmif *)&pmif_spmi_arb[mstid]; - else if (inf == PMIF_SPI) - return (struct pmif *)&pmif_spi_arb[0]; - - die("[%s] Failed to get pmif controller: inf = %d, mstid = %d\n", __func__, inf, mstid); - return NULL; -} - -static void pmif_select(enum pmic_interface mode) -{ - unsigned int spi_spm_sleep_req, spi_scp_sleep_req, - spmi_spm_sleep_req, spmi_scp_sleep_req, - spi_md_ctl_pmif_rdy, spi_md_ctl_srclk_en, spi_md_ctl_srvol_en, - spmi_md_ctl_pmif_rdy, spmi_md_ctl_srclk_en, spmi_md_ctl_srvol_en, - spi_inf_srclken_rc_en, spi_other_inf_dcxo0_en, spi_other_inf_dcxo1_en, - spi_arb_srclken_rc_en, spi_arb_dcxo_conn_en, spi_arb_dcxo_nfc_en; - - switch (mode) { - case PMIF_VLD_RDY: - /* spm and scp sleep request disable spi and spmi */ - spi_spm_sleep_req = 1; - spi_scp_sleep_req = 1; - spmi_spm_sleep_req = 1; - spmi_scp_sleep_req = 1; - - /* - * pmic vld/rdy control spi mode enable - * srclken control spi mode disable - * vreq control spi mode disable - */ - spi_md_ctl_pmif_rdy = 1; - spi_md_ctl_srclk_en = 0; - spi_md_ctl_srvol_en = 0; - spmi_md_ctl_pmif_rdy = 1; - spmi_md_ctl_srclk_en = 0; - spmi_md_ctl_srvol_en = 0; - - /* srclken rc interface enable */ - spi_inf_srclken_rc_en = 1; - - /* dcxo interface disable */ - spi_other_inf_dcxo0_en = 0; - spi_other_inf_dcxo1_en = 0; - - /* srclken enable, dcxo0,1 disable */ - spi_arb_srclken_rc_en = 1; - spi_arb_dcxo_conn_en = 0; - spi_arb_dcxo_nfc_en = 0; - break; - - case PMIF_SLP_REQ: - /* spm and scp sleep request enable spi and spmi */ - spi_spm_sleep_req = 0; - spi_scp_sleep_req = 0; - spmi_spm_sleep_req = 0; - spmi_scp_sleep_req = 0; - - /* - * pmic vld/rdy control spi mode disable - * srclken control spi mode enable - * vreq control spi mode enable - */ - spi_md_ctl_pmif_rdy = 0; - spi_md_ctl_srclk_en = 1; - spi_md_ctl_srvol_en = 1; - spmi_md_ctl_pmif_rdy = 0; - spmi_md_ctl_srclk_en = 1; - spmi_md_ctl_srvol_en = 1; - - /* srclken rc interface disable */ - spi_inf_srclken_rc_en = 0; - - /* dcxo interface enable */ - spi_other_inf_dcxo0_en = 1; - spi_other_inf_dcxo1_en = 1; - - /* srclken disable, dcxo0,1 enable */ - spi_arb_srclken_rc_en = 0; - spi_arb_dcxo_conn_en = 1; - spi_arb_dcxo_nfc_en = 1; - break; - - default: - die("Can't support pmif mode %d\n", mode); - } - - SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->sleep_protection_ctrl, - PMIFSPI_SPM_SLEEP_REQ_SEL, spi_spm_sleep_req, - PMIFSPI_SCP_SLEEP_REQ_SEL, spi_scp_sleep_req); - SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->sleep_protection_ctrl, - PMIFSPMI_SPM_SLEEP_REQ_SEL, spmi_spm_sleep_req, - PMIFSPMI_SCP_SLEEP_REQ_SEL, spmi_scp_sleep_req); - SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->spi_mode_ctrl, - PMIFSPI_MD_CTL_PMIF_RDY, spi_md_ctl_pmif_rdy, - PMIFSPI_MD_CTL_SRCLK_EN, spi_md_ctl_srclk_en, - PMIFSPI_MD_CTL_SRVOL_EN, spi_md_ctl_srvol_en); - SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->spi_mode_ctrl, - PMIFSPMI_MD_CTL_PMIF_RDY, spmi_md_ctl_pmif_rdy, - PMIFSPMI_MD_CTL_SRCLK_EN, spmi_md_ctl_srclk_en, - PMIFSPMI_MD_CTL_SRVOL_EN, spmi_md_ctl_srvol_en); - SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->inf_en, - PMIFSPI_INF_EN_SRCLKEN_RC_HW, spi_inf_srclken_rc_en); - SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->other_inf_en, - PMIFSPI_OTHER_INF_DXCO0_EN, spi_other_inf_dcxo0_en, - PMIFSPI_OTHER_INF_DXCO1_EN, spi_other_inf_dcxo1_en); - SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->arb_en, - PMIFSPI_ARB_EN_SRCLKEN_RC_HW, spi_arb_srclken_rc_en, - PMIFSPI_ARB_EN_DCXO_CONN, spi_arb_dcxo_conn_en, - PMIFSPI_ARB_EN_DCXO_NFC, spi_arb_dcxo_nfc_en); -} - -void pmwrap_interface_init(void) -{ - if (CONFIG(SRCLKEN_RC_SUPPORT)) { - printk(BIOS_INFO, "%s: Select PMIF_VLD_RDY\n", __func__); - pmif_select(PMIF_VLD_RDY); - } else { - printk(BIOS_INFO, "%s: Select PMIF_SLP_REQ\n", __func__); - pmif_select(PMIF_SLP_REQ); - } -} - -int mtk_pmif_init(void) -{ - int ret; - - ret = pmif_clk_init(); - if (!ret) - ret = pmif_spmi_init(get_pmif_controller(PMIF_SPMI, SPMI_MASTER_0)); - if (!ret) - ret = pmif_spi_init(get_pmif_controller(PMIF_SPI, 0)); - - return ret; -} diff --git a/src/soc/mediatek/mt8192/pmif_clk.c b/src/soc/mediatek/mt8192/pmif_clk.c index cdcdacc91c..a597b6a724 100644 --- a/src/soc/mediatek/mt8192/pmif_clk.c +++ b/src/soc/mediatek/mt8192/pmif_clk.c @@ -84,7 +84,7 @@ static u32 pmif_get_ulposc_freq_mhz(u32 cali_val) return result / 1000; } -static int pmif_ulposc_cali(void) +static int pmif_ulposc_cali(u32 target_val) { u32 current_val = 0, min = 0, max = CAL_MAX_VAL, middle; int ret = 0, diff_by_min, diff_by_max, cal_result; @@ -95,16 +95,16 @@ static int pmif_ulposc_cali(void) break; current_val = pmif_get_ulposc_freq_mhz(middle); - if (current_val > FREQ_260MHZ) + if (current_val > target_val) max = middle; else min = middle; } while (min <= max); - diff_by_min = pmif_get_ulposc_freq_mhz(min) - FREQ_260MHZ; + diff_by_min = pmif_get_ulposc_freq_mhz(min) - target_val; diff_by_min = ABS(diff_by_min); - diff_by_max = pmif_get_ulposc_freq_mhz(max) - FREQ_260MHZ; + diff_by_max = pmif_get_ulposc_freq_mhz(max) - target_val; diff_by_max = ABS(diff_by_max); if (diff_by_min < diff_by_max) { @@ -116,8 +116,8 @@ static int pmif_ulposc_cali(void) } /* check if calibrated value is in the range of target value +- 15% */ - if (current_val < (FREQ_260MHZ * (1000 - CAL_TOL_RATE) / 1000) || - current_val > (FREQ_260MHZ * (1000 + CAL_TOL_RATE) / 1000)) { + if (current_val < (target_val * (1000 - CAL_TOL_RATE) / 1000) || + current_val > (target_val * (1000 + CAL_TOL_RATE) / 1000)) { printk(BIOS_ERR, "[%s] calibration fail: %dM\n", __func__, current_val); ret = 1; } @@ -140,7 +140,7 @@ static int pmif_init_ulposc(void) udelay(100); SET32_BITFIELDS(&mtk_spm->ulposc_con, ULPOSC_CG_EN, 1); - return pmif_ulposc_cali(); + return pmif_ulposc_cali(FREQ_260MHZ); } int pmif_clk_init(void) diff --git a/src/soc/mediatek/mt8192/pmif_spi.c b/src/soc/mediatek/mt8192/pmif_spi.c index 72620041bd..da8c2ad49c 100644 --- a/src/soc/mediatek/mt8192/pmif_spi.c +++ b/src/soc/mediatek/mt8192/pmif_spi.c @@ -1,332 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include #include -#include -#include -#include +#include #include -#include -#include - -/* PMIF, SPI_MODE_CTRL */ -DEFINE_BIT(SPI_MODE_CTRL_VLD_SRCLK_EN_CTRL, 5) -DEFINE_BIT(SPI_MODE_CTRL_PMIF_RDY, 9) -DEFINE_BIT(SPI_MODE_CTRL_SRCLK_EN, 10) -DEFINE_BIT(SPI_MODE_CTRL_SRVOL_EN, 11) - -/* PMIF, SLEEP_PROTECTION_CTRL */ -DEFINE_BITFIELD(SPM_SLEEP_REQ_SEL, 1, 0) -DEFINE_BITFIELD(SCP_SLEEP_REQ_SEL, 10, 9) - -/* PMIF, OTHER_INF_EN */ -DEFINE_BITFIELD(INTGPSADCINF_EN, 5, 4) - -/* PMIF, STAUPD_CTRL */ -DEFINE_BITFIELD(STAUPD_CTRL_PRD, 3, 0) -DEFINE_BIT(STAUPD_CTRL_PMIC0_SIG_STA, 4) -DEFINE_BIT(STAUPD_CTRL_PMIC0_EINT_STA, 6) - -/* SPIMST, Manual_Mode_Access */ -DEFINE_BITFIELD(MAN_ACC_SPI_OP, 12, 8) -DEFINE_BIT(MAN_ACC_SPI_RW, 13) /* IOCFG_LM, PWRAP_SPI0_DRIVING */ DEFINE_BITFIELD(PWRAP_SPI0_DRIVING, 2, 0) -static void pmif_spi_config(struct pmif *arb) -{ - /* Set srclk_en always valid regardless of ulposc_sel_for_scp */ - SET32_BITFIELDS(&arb->mtk_pmif->spi_mode_ctrl, SPI_MODE_CTRL_VLD_SRCLK_EN_CTRL, 0); - - /* Set SPI mode controlled by srclk_en and srvol_en instead of pmif_rdy */ - SET32_BITFIELDS(&arb->mtk_pmif->spi_mode_ctrl, - SPI_MODE_CTRL_SRCLK_EN, 1, - SPI_MODE_CTRL_SRVOL_EN, 1, - SPI_MODE_CTRL_PMIF_RDY, 0); - - SET32_BITFIELDS(&arb->mtk_pmif->sleep_protection_ctrl, SPM_SLEEP_REQ_SEL, 0, - SCP_SLEEP_REQ_SEL, 0); - - /* Enable SWINF for AP */ - write32(&arb->mtk_pmif->inf_en, PMIF_SPI_AP); - - /* Enable arbitration for SWINF for AP */ - write32(&arb->mtk_pmif->arb_en, PMIF_SPI_AP); - - /* Enable PMIF_SPI Command Issue */ - write32(&arb->mtk_pmif->cmdissue_en, 1); -} - -static int check_idle(void *addr, u32 expected) -{ - u32 reg_rdata; - struct stopwatch sw; - - stopwatch_init_usecs_expire(&sw, PMIF_WAIT_IDLE_US); - do { - reg_rdata = read32(addr); - if (stopwatch_expired(&sw)) - return E_TIMEOUT; - } while ((reg_rdata & expected) != 0); - - return 0; -} - -static int reset_spislv(void) -{ - u32 pmicspi_mst_dio_en_backup; - - write32(&mtk_pmicspi_mst->wrap_en, 0); - write32(&mtk_pmicspi_mst->mux_sel, 1); - write32(&mtk_pmicspi_mst->man_en, 1); - pmicspi_mst_dio_en_backup = read32(&mtk_pmicspi_mst->dio_en); - write32(&mtk_pmicspi_mst->dio_en, 0); - - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_CSL); - /* Reset counter */ - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_OUTS); - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_CSH); - /* - * In order to pull CSN signal to PMIC, - * PMIC will count it then reset spi slave - */ - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_OUTS); - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_OUTS); - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_OUTS); - SET32_BITFIELDS(&mtk_pmicspi_mst->man_acc, MAN_ACC_SPI_RW, OP_WR, - MAN_ACC_SPI_OP, OP_OUTS); - - /* Wait for PMIC SPI Master to be idle */ - if (check_idle(&mtk_pmicspi_mst->other_busy_sta_0, SPIMST_STA)) { - printk(BIOS_ERR, "[%s] spi master busy, timeout\n", __func__); - return E_TIMEOUT; - } - - write32(&mtk_pmicspi_mst->man_en, 0); - write32(&mtk_pmicspi_mst->mux_sel, 0); - write32(&mtk_pmicspi_mst->wrap_en, 1); - write32(&mtk_pmicspi_mst->dio_en, pmicspi_mst_dio_en_backup); - - return 0; -} - -static void init_reg_clock(struct pmif *arb) +void pmif_spi_iocfg(void) { /* Set SoC SPI IO driving strength to 4 mA */ SET32_BITFIELDS(&mtk_iocfg_lm->drv_cfg1, PWRAP_SPI0_DRIVING, IO_4_MA); - - /* Configure SPI protocol */ - write32(&mtk_pmicspi_mst->ext_ck_write, 1); - write32(&mtk_pmicspi_mst->ext_ck_read, 0); - write32(&mtk_pmicspi_mst->cshext_write, 0); - write32(&mtk_pmicspi_mst->cshext_read, 0); - write32(&mtk_pmicspi_mst->cslext_write, 0); - write32(&mtk_pmicspi_mst->cslext_read, 0x100); - - /* Set Read Dummy Cycle Number (Slave Clock is 18MHz) */ - arb->write(arb, DEFAULT_SLVID, PMIC_DEW_RDDMY_NO, DUMMY_READ_CYCLES); - write32(&mtk_pmicspi_mst->rddmy, DUMMY_READ_CYCLES); - - /* Enable DIO mode */ - arb->write(arb, DEFAULT_SLVID, PMIC_DEW_DIO_EN, 0x1); - - /* Wait for completion of sending the commands */ - if (check_idle(&arb->mtk_pmif->inf_busy_sta, PMIF_SPI_AP)) { - printk(BIOS_ERR, "[%s] pmif channel busy, timeout\n", __func__); - return; - } - - if (check_idle(&arb->mtk_pmif->other_busy_sta_0, PMIF_CMD_STA)) { - printk(BIOS_ERR, "[%s] pmif cmd busy, timeout\n", __func__); - return; - } - - if (check_idle(&mtk_pmicspi_mst->other_busy_sta_0, SPIMST_STA)) { - printk(BIOS_ERR, "[%s] spi master busy, timeout\n", __func__); - return; - } - - write32(&mtk_pmicspi_mst->dio_en, 1); -} - -static void init_spislv(struct pmif *arb) -{ - /* Turn on SPI IO filter function */ - arb->write(arb, DEFAULT_SLVID, PMIC_FILTER_CON0, SPI_FILTER); - /* Turn on SPI IO SMT function to improve noise immunity */ - arb->write(arb, DEFAULT_SLVID, PMIC_SMT_CON1, SPI_SMT); - /* Turn off SPI IO pull function for power saving */ - arb->write(arb, DEFAULT_SLVID, PMIC_GPIO_PULLEN0_CLR, SPI_PULL_DISABLE); - /* Enable SPI access in SODI-3.0 and Suspend modes */ - arb->write(arb, DEFAULT_SLVID, PMIC_RG_SPI_CON0, 0x2); - /* Set SPI IO driving strength to 4 mA */ - arb->write(arb, DEFAULT_SLVID, PMIC_DRV_CON1, SPI_DRIVING); -} - -static int init_sistrobe(struct pmif *arb) -{ - u32 rdata = 0; - int si_sample_ctrl; - /* Random data for testing */ - const u32 test_data[30] = { - 0x6996, 0x9669, 0x6996, 0x9669, 0x6996, 0x9669, 0x6996, - 0x9669, 0x6996, 0x9669, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, - 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x1B27, - 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, - 0x1B27, 0x1B27 - }; - - for (si_sample_ctrl = 0; si_sample_ctrl < 16; si_sample_ctrl++) { - write32(&mtk_pmicspi_mst->si_sampling_ctrl, si_sample_ctrl << 5); - - arb->read(arb, DEFAULT_SLVID, PMIC_DEW_READ_TEST, &rdata); - if (rdata == DEFAULT_VALUE_READ_TEST) - break; - } - - if (si_sample_ctrl == 16) - return E_CLK_EDGE; - - if (si_sample_ctrl == 15) - return E_CLK_LAST_SETTING; - - /* - * Add the delay time of SPI data from PMIC to align the start boundary - * to current sampling clock edge. - */ - for (int si_dly = 0; si_dly < 10; si_dly++) { - arb->write(arb, DEFAULT_SLVID, PMIC_RG_SPI_CON2, si_dly); - - int start_boundary_found = 0; - for (int i = 0; i < ARRAY_SIZE(test_data); i++) { - arb->write(arb, DEFAULT_SLVID, PMIC_DEW_WRITE_TEST, test_data[i]); - arb->read(arb, DEFAULT_SLVID, PMIC_DEW_WRITE_TEST, &rdata); - if ((rdata & 0x7fff) != (test_data[i] & 0x7fff)) { - start_boundary_found = 1; - break; - } - } - if (start_boundary_found == 1) - break; - } - - /* - * Change the sampling clock edge to the next one which is the middle - * of SPI data window. - */ - write32(&mtk_pmicspi_mst->si_sampling_ctrl, ++si_sample_ctrl << 5); - - /* Read Test */ - arb->read(arb, DEFAULT_SLVID, PMIC_DEW_READ_TEST, &rdata); - if (rdata != DEFAULT_VALUE_READ_TEST) { - printk(BIOS_ERR, "[%s] Failed for read test, data = %#x.\n", - __func__, rdata); - return E_READ_TEST_FAIL; - } - - return 0; -} - -static void init_staupd(struct pmif *arb) -{ - /* Unlock SPI Slave registers */ - arb->write(arb, DEFAULT_SLVID, PMIC_SPISLV_KEY, 0xbade); - - /* Enable CRC of PMIC 0 */ - arb->write(arb, DEFAULT_SLVID, PMIC_DEW_CRC_EN, 0x1); - - /* Wait for completion of sending the commands */ - if (check_idle(&arb->mtk_pmif->inf_busy_sta, PMIF_SPI_AP)) { - printk(BIOS_ERR, "[%s] pmif channel busy, timeout\n", __func__); - return; - } - - if (check_idle(&arb->mtk_pmif->other_busy_sta_0, PMIF_CMD_STA)) { - printk(BIOS_ERR, "[%s] pmif cmd busy, timeout\n", __func__); - return; - } - - if (check_idle(&mtk_pmicspi_mst->other_busy_sta_0, SPIMST_STA)) { - printk(BIOS_ERR, "[%s] spi master busy, timeout\n", __func__); - return; - } - - /* Configure CRC of PMIC Interface */ - write32(&arb->mtk_pmif->crc_ctrl, 0x1); - write32(&arb->mtk_pmif->sig_mode, 0x0); - - /* Lock SPI Slave registers */ - arb->write(arb, DEFAULT_SLVID, PMIC_SPISLV_KEY, 0x0); - - /* Set up PMIC Siganature */ - write32(&arb->mtk_pmif->pmic_sig_addr, PMIC_DEW_CRC_VAL); - - /* Set up PMIC EINT */ - write32(&arb->mtk_pmif->pmic_eint_sta_addr, PMIC_INT_STA); - - SET32_BITFIELDS(&arb->mtk_pmif->staupd_ctrl, - STAUPD_CTRL_PRD, 5, - STAUPD_CTRL_PMIC0_SIG_STA, 1, - STAUPD_CTRL_PMIC0_EINT_STA, 1); -} - -int pmif_spi_init(struct pmif *arb) -{ - pmif_spi_config(arb); - - /* Reset spislv */ - if (reset_spislv()) - return E_SPI_INIT_RESET_SPI; - - /* Enable WRAP */ - write32(&mtk_pmicspi_mst->wrap_en, 0x1); - - /* SPI Waveform Configuration */ - init_reg_clock(arb); - - /* SPI Slave Configuration */ - init_spislv(arb); - - /* Input data calibration flow; */ - if (init_sistrobe(arb)) { - printk(BIOS_ERR, "[%s] data calibration fail\n", __func__); - return E_SPI_INIT_SIDLY; - } - - /* Lock SPISLV Registers */ - arb->write(arb, DEFAULT_SLVID, PMIC_SPISLV_KEY, 0x0); - - /* - * Status update function initialization - * 1. Check signature using CRC (CRC 0 only) - * 2. Update EINT - * 3. Read back AUXADC thermal data for GPS - */ - init_staupd(arb); - - /* Configure PMIF Timer */ - write32(&arb->mtk_pmif->timer_ctrl, 0x3); - - /* Enable interfaces and arbitration */ - write32(&arb->mtk_pmif->inf_en, PMIF_SPI_HW_INF | PMIF_SPI_MD | - PMIF_SPI_AP_SECURE | PMIF_SPI_AP); - - write32(&arb->mtk_pmif->arb_en, PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | - PMIF_SPI_AP | PMIF_SPI_STAUPD | PMIF_SPI_TSX_HW | PMIF_SPI_DCXO_HW); - - /* Enable GPS AUXADC HW 0 and 1 */ - SET32_BITFIELDS(&arb->mtk_pmif->other_inf_en, INTGPSADCINF_EN, 0x3); - - /* Set INIT_DONE */ - write32(&arb->mtk_pmif->init_done, 0x1); - - return 0; } diff --git a/src/soc/mediatek/mt8192/pmif_spmi.c b/src/soc/mediatek/mt8192/pmif_spmi.c index 1927e5f452..a68f235382 100644 --- a/src/soc/mediatek/mt8192/pmif_spmi.c +++ b/src/soc/mediatek/mt8192/pmif_spmi.c @@ -1,17 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include -#include +#include #include -#include -#include #include -#include -#include - -#define PMIF_CMD_PER_3 (0x1 << PMIF_CMD_EXT_REG_LONG) -#define PMIF_CMD_PER_1_3 ((0x1 << PMIF_CMD_REG) | (0x1 << PMIF_CMD_EXT_REG_LONG)) /* IOCFG_BM, DRV_CFG2 */ DEFINE_BITFIELD(SPMI_SCL, 5, 3) @@ -29,34 +21,7 @@ DEFINE_BIT(PDN_SPMI_MST, 15) /* TOPCKGEN, CLK_CFG_UPDATE2 */ DEFINE_BIT(SPMI_MST_CK_UPDATE, 30) -/* SPMI_MST, SPMI_SAMPL_CTRL */ -DEFINE_BIT(SAMPL_CK_POL, 0) -DEFINE_BITFIELD(SAMPL_CK_DLY, 3, 1) - -/* PMIF, SPI_MODE_CTRL */ -DEFINE_BIT(SPI_MODE_CTRL, 7) -DEFINE_BIT(SRVOL_EN, 11) -DEFINE_BIT(SPI_MODE_EXT_CMD, 12) -DEFINE_BIT(SPI_EINT_MODE_GATING_EN, 13) - -/* PMIF, SLEEP_PROTECTION_CTRL */ -DEFINE_BITFIELD(SPM_SLEEP_REQ_SEL, 1, 0) -DEFINE_BITFIELD(SCP_SLEEP_REQ_SEL, 10, 9) - -static const struct spmi_device spmi_dev[] = { - { - .slvid = SPMI_SLAVE_6, - .type = BUCK_CPU, - .type_id = BUCK_CPU_ID, - }, - { - .slvid = SPMI_SLAVE_7, - .type = BUCK_GPU, - .type_id = BUCK_GPU_ID, - }, -}; - -static int spmi_config_master(void) +int spmi_config_master(void) { /* Software reset */ SET32_BITFIELDS(&mtk_rug->wdt_swsysrst2, SPMI_MST_RST, 1, UNLOCK_KEY, 0x85); @@ -76,166 +41,7 @@ static int spmi_config_master(void) return 0; } -static int spmi_read_check(struct pmif *pmif_arb, int slvid) -{ - u32 rdata = 0; - - pmif_arb->read(pmif_arb, slvid, MT6315_READ_TEST, &rdata); - if (rdata != MT6315_DEFAULT_VALUE_READ) { - printk(BIOS_ERR, "%s next, slvid:%d rdata = 0x%x.\n", - __func__, slvid, rdata); - return -E_NODEV; - } - - pmif_arb->read(pmif_arb, slvid, MT6315_READ_TEST_1, &rdata); - if (rdata != MT6315_DEFAULT_VALUE_READ) { - printk(BIOS_ERR, "%s next, slvid:%d rdata = 0x%x.\n", - __func__, slvid, rdata); - return -E_NODEV; - } - - return 0; -} - -static int spmi_cali_rd_clock_polarity(struct pmif *pmif_arb, const struct spmi_device *dev) -{ - int i; - bool success = false; - const struct cali cali_data[] = { - {SPMI_CK_DLY_1T, SPMI_CK_POL_POS}, - {SPMI_CK_NO_DLY, SPMI_CK_POL_POS}, - {SPMI_CK_NO_DLY, SPMI_CK_POL_NEG}, - }; - - /* Indicate sampling clock polarity, 1: Positive 0: Negative */ - for (i = 0; i < ARRAY_SIZE(cali_data); i++) { - SET32_BITFIELDS(&mtk_spmi_mst->mst_sampl, SAMPL_CK_DLY, cali_data[i].dly, - SAMPL_CK_POL, cali_data[i].pol); - if (spmi_read_check(pmif_arb, dev->slvid) == 0) { - success = true; - break; - } - } - - if (!success) - die("ERROR - calibration fail for spmi clk"); - - return 0; -} - -static int spmi_mst_init(struct pmif *pmif_arb) +void pmif_spmi_iocfg(void) { - int i; - - if (!pmif_arb) { - printk(BIOS_ERR, "%s: null pointer for pmif dev.\n", __func__); - return -E_INVAL; - } - - /* config IOCFG */ SET32_BITFIELDS(&mtk_iocfg_bm->drv_cfg2, SPMI_SCL, 0x2, SPMI_SDA, 0x2); - spmi_config_master(); - - for (i = 0; i < ARRAY_SIZE(spmi_dev); i++) - spmi_cali_rd_clock_polarity(pmif_arb, &spmi_dev[i]); - - return 0; -} - -static void pmif_spmi_force_normal_mode(int mstid) -{ - struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); - - /* listen srclken_0 only for entering normal or sleep mode */ - SET32_BITFIELDS(&arb->mtk_pmif->spi_mode_ctrl, - SPI_MODE_CTRL, 0, - SRVOL_EN, 0, - SPI_MODE_EXT_CMD, 1, - SPI_EINT_MODE_GATING_EN, 1); - - /* enable spm/scp sleep request */ - SET32_BITFIELDS(&arb->mtk_pmif->sleep_protection_ctrl, SPM_SLEEP_REQ_SEL, 0, - SCP_SLEEP_REQ_SEL, 0); -} - -static void pmif_spmi_enable_swinf(int mstid) -{ - struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); - - write32(&arb->mtk_pmif->inf_en, PMIF_SPMI_SW_CHAN); - write32(&arb->mtk_pmif->arb_en, PMIF_SPMI_SW_CHAN); -} - -static void pmif_spmi_enable_cmdIssue(int mstid, bool en) -{ - struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); - - /* Enable cmdIssue */ - write32(&arb->mtk_pmif->cmdissue_en, en); -} - -static void pmif_spmi_enable(int mstid) -{ - struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid); - u32 cmd_per; - - /* clear all cmd permission for per channel */ - write32(&arb->mtk_pmif->inf_cmd_per_0, 0); - write32(&arb->mtk_pmif->inf_cmd_per_1, 0); - write32(&arb->mtk_pmif->inf_cmd_per_2, 0); - write32(&arb->mtk_pmif->inf_cmd_per_3, 0); - - /* enable if we need cmd 0~3 permission for per channel */ - cmd_per = PMIF_CMD_PER_3 << 28 | PMIF_CMD_PER_3 << 24 | - PMIF_CMD_PER_3 << 20 | PMIF_CMD_PER_3 << 16 | - PMIF_CMD_PER_3 << 8 | PMIF_CMD_PER_3 << 4 | - PMIF_CMD_PER_1_3 << 0; - write32(&arb->mtk_pmif->inf_cmd_per_0, cmd_per); - - cmd_per = PMIF_CMD_PER_3 << 4; - write32(&arb->mtk_pmif->inf_cmd_per_1, cmd_per); - - /* - * set bytecnt max limitation. - * hw bytecnt indicate when we set 0, it can send 1 byte; - * set 1, it can send 2 byte. - */ - write32(&arb->mtk_pmif->inf_max_bytecnt_per_0, 0); - write32(&arb->mtk_pmif->inf_max_bytecnt_per_1, 0); - write32(&arb->mtk_pmif->inf_max_bytecnt_per_2, 0); - write32(&arb->mtk_pmif->inf_max_bytecnt_per_3, 0); - - /* Add latency limitation */ - write32(&arb->mtk_pmif->lat_cnter_en, PMIF_SPMI_INF); - write32(&arb->mtk_pmif->lat_limit_0, 0); - write32(&arb->mtk_pmif->lat_limit_1, 0x4); - write32(&arb->mtk_pmif->lat_limit_2, 0x8); - write32(&arb->mtk_pmif->lat_limit_4, 0x8); - write32(&arb->mtk_pmif->lat_limit_6, 0x3FF); - write32(&arb->mtk_pmif->lat_limit_9, 0x4); - write32(&arb->mtk_pmif->lat_limit_loading, PMIF_SPMI_INF); - - write32(&arb->mtk_pmif->inf_en, PMIF_SPMI_INF); - write32(&arb->mtk_pmif->arb_en, PMIF_SPMI_INF); - write32(&arb->mtk_pmif->timer_ctrl, 0x3); - write32(&arb->mtk_pmif->init_done, 1); -} - -int pmif_spmi_init(struct pmif *arb) -{ - if (arb->is_pmif_init_done(arb) != 0) { - pmif_spmi_force_normal_mode(arb->mstid); - pmif_spmi_enable_swinf(arb->mstid); - pmif_spmi_enable_cmdIssue(arb->mstid, true); - pmif_spmi_enable(arb->mstid); - if (arb->is_pmif_init_done(arb)) - return -E_NODEV; - } - - if (spmi_mst_init(arb)) { - printk(BIOS_ERR, "[%s] failed to init spmi master\n", __func__); - return -E_NODEV; - } - - return 0; } -- cgit v1.2.3