From 122b45be6e6cca0ded8c9df65cefe6043b4fcb88 Mon Sep 17 00:00:00 2001 From: Sen Chu Date: Tue, 18 Oct 2022 14:02:14 +0800 Subject: [PATCH] soc/mediatek/mt8186: Add support for PMIC MT6315 On MT8186T, the big cores are powered on by MT6315 via PMIF. This patch adds the following changes. - Add MT6315 settings. - Configure PMIC PMIF for MT6315. BUG=b:249436110 TEST=build pass. BRANCH=corsola Signed-off-by: Sen Chu Signed-off-by: Bo-Chen Chen Change-Id: Id01931e564b0b5002b8d6b9d13d4f32cdf0ae708 Reviewed-on: https://review.coreboot.org/c/coreboot/+/68620 Reviewed-by: Yu-Ping Wu Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- .../mediatek/common/include/soc/pll_common.h | 1 + src/soc/mediatek/mt8186/Makefile.inc | 3 + .../mediatek/mt8186/include/soc/addressmap.h | 7 +- src/soc/mediatek/mt8186/include/soc/pll.h | 4 +- src/soc/mediatek/mt8186/include/soc/pmif.h | 133 ++++++++++++++++++ src/soc/mediatek/mt8186/mt6315.c | 108 ++++++++++++++ src/soc/mediatek/mt8186/pll.c | 6 + src/soc/mediatek/mt8186/pmif.c | 2 +- src/soc/mediatek/mt8186/pmif_clk.c | 51 +++++++ src/soc/mediatek/mt8186/pmif_spmi.c | 62 ++++++++ 10 files changed, 374 insertions(+), 3 deletions(-) create mode 100644 src/soc/mediatek/mt8186/mt6315.c create mode 100644 src/soc/mediatek/mt8186/pmif_clk.c create mode 100644 src/soc/mediatek/mt8186/pmif_spmi.c diff --git a/src/soc/mediatek/common/include/soc/pll_common.h b/src/soc/mediatek/common/include/soc/pll_common.h index 6eac8b282a..5c73a122a1 100644 --- a/src/soc/mediatek/common/include/soc/pll_common.h +++ b/src/soc/mediatek/common/include/soc/pll_common.h @@ -72,6 +72,7 @@ void mt_pll_raise_little_cpu_freq(u32 freq); void mt_pll_raise_cci_freq(u32 freq); void mt_pll_set_tvd_pll1_freq(u32 freq); void edp_mux_set_sel(u32 sel); +void mt_pll_spmi_mux_select(void); void mt_pll_set_usb_clock(void); enum fmeter_type { diff --git a/src/soc/mediatek/mt8186/Makefile.inc b/src/soc/mediatek/mt8186/Makefile.inc index c8dbbc9593..5764634ee9 100644 --- a/src/soc/mediatek/mt8186/Makefile.inc +++ b/src/soc/mediatek/mt8186/Makefile.inc @@ -25,7 +25,10 @@ romstage-y += ../common/emi.c romstage-y += ../common/memory.c romstage-y += ../common/memory_test.c romstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c +romstage-y += ../common/mt6315.c mt6315.c romstage-y += ../common/pmic_wrap.c pmic_wrap.c pmif.c mt6366.c +romstage-y += ../common/pmif.c ../common/pmif_clk.c pmif_clk.c +romstage-y += ../common/pmif_spmi.c pmif_spmi.c romstage-y += ../common/rtc.c ../common/rtc_osc_init.c rtc.c ramstage-y += adsp.c diff --git a/src/soc/mediatek/mt8186/include/soc/addressmap.h b/src/soc/mediatek/mt8186/include/soc/addressmap.h index 33a232740a..5f0b10c5e0 100644 --- a/src/soc/mediatek/mt8186/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8186/include/soc/addressmap.h @@ -29,10 +29,14 @@ enum { EINT_BASE = IO_PHYS + 0x0000B000, APMIXED_BASE = IO_PHYS + 0x0000C000, PWRAP_BASE = IO_PHYS + 0x0000D000, + /* Add PMICSPI_MST_BASE and PMIF_SPI_BASE to solve the build error */ + PMICSPI_MST_BASE = IO_PHYS + 0x0000D000, + PMIF_SPI_BASE = IO_PHYS + 0x0000D000, DEVAPC_AO_INFRA_PERI_BASE = IO_PHYS + 0x0000E000, DEVAPC_AO_MM_BASE = IO_PHYS + 0x0000F000, - PMIF_BASE = IO_PHYS + 0x00015000, + PMIF_SPMI_BASE = IO_PHYS + 0x00015000, SYSTIMER_BASE = IO_PHYS + 0x00017000, + SPMI_MST_BASE = IO_PHYS + 0x0001B000, I2C0_DMA_BASE = IO_PHYS + 0x00200100, I2C1_DMA_BASE = IO_PHYS + 0x00200200, I2C2_DMA_BASE = IO_PHYS + 0x00200300, @@ -50,6 +54,7 @@ enum { DRAMC_CHA_AO_BASE = IO_PHYS + 0x00220000, SSPM_SRAM_BASE = IO_PHYS + 0x00400000, SSPM_CFG_BASE = IO_PHYS + 0x00440000, + SCP_CLK_BASE = IO_PHYS + 0x005C4000, AUDIODSP_BASE = IO_PHYS + 0x00680000, DEVAPC_AO_AUD_BASE = IO_PHYS + 0x0069C000, SFLASH_REG_BASE = IO_PHYS + 0x01000000, diff --git a/src/soc/mediatek/mt8186/include/soc/pll.h b/src/soc/mediatek/mt8186/include/soc/pll.h index bcd00da23c..8df7f96b7f 100644 --- a/src/soc/mediatek/mt8186/include/soc/pll.h +++ b/src/soc/mediatek/mt8186/include/soc/pll.h @@ -16,7 +16,8 @@ struct mtk_topckgen_regs { u32 clk_mode; u32 clk_cfg_update; u32 clk_cfg_update1; - u32 reserved1[13]; + u32 clk_cfg_update2; + u32 reserved1[12]; u32 clk_cfg_0; u32 clk_cfg_0_set; u32 clk_cfg_0_clr; @@ -117,6 +118,7 @@ struct mtk_topckgen_regs { check_member(mtk_topckgen_regs, clk_mode, 0x0); check_member(mtk_topckgen_regs, clk_cfg_update, 0x4); check_member(mtk_topckgen_regs, clk_cfg_update1, 0x8); +check_member(mtk_topckgen_regs, clk_cfg_update2, 0xc); check_member(mtk_topckgen_regs, clk_cfg_0, 0x40); check_member(mtk_topckgen_regs, clk_cfg_0_set, 0x44); check_member(mtk_topckgen_regs, clk_cfg_0_clr, 0x48); diff --git a/src/soc/mediatek/mt8186/include/soc/pmif.h b/src/soc/mediatek/mt8186/include/soc/pmif.h index 0e1e1a276d..2eecb26c08 100644 --- a/src/soc/mediatek/mt8186/include/soc/pmif.h +++ b/src/soc/mediatek/mt8186/include/soc/pmif.h @@ -8,9 +8,142 @@ #ifndef __SOC_MEDIATEK_MT8186_PMIF_H__ #define __SOC_MEDIATEK_MT8186_PMIF_H__ +#include #include +#include #include +/* indicate which number SW channel start, by project */ +#define PMIF_SPMI_SW_CHAN 0xFFFFFFFF +#define PMIF_SPMI_INF 0xFFFFFFFF + +struct mtk_pmif_regs { + u32 init_done; + u32 reserved1[5]; + u32 inf_busy_sta; + u32 other_busy_sta_0; + u32 other_busy_sta_1; + u32 inf_en; + u32 other_inf_en; + u32 inf_cmd_per_0; + u32 inf_cmd_per_1; + u32 inf_cmd_per_2; + u32 inf_cmd_per_3; + u32 inf_max_bytecnt_per_0; + u32 inf_max_bytecnt_per_1; + u32 inf_max_bytecnt_per_2; + u32 inf_max_bytecnt_per_3; + u32 staupd_ctrl; + u32 reserved2[48]; + u32 int_gps_auxadc_cmd_addr; + u32 int_gps_auxadc_cmd; + u32 int_gps_auxadc_rdata_addr; + u32 reserved3[13]; + u32 arb_en; + u32 reserved4[34]; + u32 lat_cnter_ctrl; + u32 lat_cnter_en; + u32 lat_limit_loading; + u32 lat_limit_0; + u32 lat_limit_1; + u32 lat_limit_2; + u32 lat_limit_3; + u32 lat_limit_4; + u32 lat_limit_5; + u32 lat_limit_6; + u32 lat_limit_7; + u32 lat_limit_8; + u32 lat_limit_9; + u32 reserved5[99]; + u32 crc_ctrl; + u32 crc_sta; + u32 sig_mode; + u32 pmic_sig_addr; + u32 pmic_sig_val; + u32 reserved6[2]; + u32 cmdissue_en; + u32 reserved7[10]; + u32 timer_ctrl; + u32 timer_sta; + u32 sleep_protection_ctrl; + u32 reserved8[6]; + u32 spi_mode_ctrl; + u32 reserved9[2]; + u32 pmic_eint_sta_addr; + u32 reserved10[2]; + u32 irq_event_en_0; + u32 irq_flag_raw_0; + u32 irq_flag_0; + u32 irq_clr_0; + u32 reserved11[244]; + u32 swinf_0_acc; + u32 swinf_0_wdata_31_0; + u32 swinf_0_wdata_63_32; + u32 reserved12[2]; + u32 swinf_0_rdata_31_0; + u32 swinf_0_rdata_63_32; + u32 reserved13[2]; + u32 swinf_0_vld_clr; + u32 swinf_0_sta; + u32 reserved14[5]; + u32 swinf_1_acc; + u32 swinf_1_wdata_31_0; + u32 swinf_1_wdata_63_32; + u32 reserved15[2]; + u32 swinf_1_rdata_31_0; + u32 swinf_1_rdata_63_32; + u32 reserved16[2]; + u32 swinf_1_vld_clr; + u32 swinf_1_sta; + u32 reserved17[5]; + u32 swinf_2_acc; + u32 swinf_2_wdata_31_0; + u32 swinf_2_wdata_63_32; + u32 reserved18[2]; + u32 swinf_2_rdata_31_0; + u32 swinf_2_rdata_63_32; + u32 reserved19[2]; + u32 swinf_2_vld_clr; + u32 swinf_2_sta; + u32 reserved20[5]; + u32 swinf_3_acc; + u32 swinf_3_wdata_31_0; + u32 swinf_3_wdata_63_32; + u32 reserved21[2]; + u32 swinf_3_rdata_31_0; + u32 swinf_3_rdata_63_32; + u32 reserved22[2]; + u32 swinf_3_vld_clr; + u32 swinf_3_sta; + u32 reserved23[133]; +}; +check_member(mtk_pmif_regs, inf_busy_sta, 0x18); +check_member(mtk_pmif_regs, int_gps_auxadc_cmd_addr, 0x110); +check_member(mtk_pmif_regs, arb_en, 0x0150); +check_member(mtk_pmif_regs, lat_cnter_en, 0x1E0); +check_member(mtk_pmif_regs, crc_ctrl, 0x39C); +check_member(mtk_pmif_regs, cmdissue_en, 0x3B8); +check_member(mtk_pmif_regs, timer_ctrl, 0x3E4); +check_member(mtk_pmif_regs, spi_mode_ctrl, 0x408); +check_member(mtk_pmif_regs, pmic_eint_sta_addr, 0x414); +check_member(mtk_pmif_regs, irq_event_en_0, 0x420); +check_member(mtk_pmif_regs, swinf_0_acc, 0x800); + +#define PMIF_SPMI_AP_CHAN (PMIF_SPMI_BASE + 0x880) +#define PMIF_SPI_AP_CHAN (PMIF_SPI_BASE + 0xC20) + +enum { + FREQ_250MHZ = 250, +}; + +struct mtk_scp_clk_regs { + u32 reserved0; + u32 scp_clk_en; +}; +check_member(mtk_scp_clk_regs, scp_clk_en, 0x4); + +#define mtk_scp_clk ((struct mtk_scp_clk_regs *)SCP_CLK_BASE) + void pmif_spmi_set_lp_mode(void); #endif /*__SOC_MEDIATEK_MT8186_PMIF_H__*/ diff --git a/src/soc/mediatek/mt8186/mt6315.c b/src/soc/mediatek/mt8186/mt6315.c new file mode 100644 index 0000000000..1e6f0357b0 --- /dev/null +++ b/src/soc/mediatek/mt8186/mt6315.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include + +/* + * These values are used by MediaTek internally. + * We can find these registers in "MT6315 datasheet v1.3.pdf". + * The setting values are provided by MeidaTek designers. + */ + +static const struct mt6315_setting init_setting_cpu[] = { + /* remove protection */ + {0x3A9, 0x63, 0xFF, 0}, + {0x3A8, 0x15, 0xFF, 0}, + {0x3A0, 0x9C, 0xFF, 0}, + {0x39F, 0xEA, 0xFF, 0}, + {0x993, 0x47, 0xFF, 0}, + {0x992, 0x29, 0xFF, 0}, + {0x1418, 0x55, 0xFF, 0}, + {0x1417, 0x43, 0xFF, 0}, + {0x3A2, 0x2A, 0xFF, 0}, + {0x3A1, 0x7C, 0xFF, 0}, + /* init settings for mt6315 */ + {0x997, 0xF, 0x7F, 0}, + {0x999, 0xF0, 0xF0, 0}, + {0x9A0, 0x0, 0x1F, 0}, + {0x9A1, 0x0, 0x1F, 0}, + {0x9A2, 0x0, 0x1F, 0}, + {0x9A3, 0x0, 0x1F, 0}, + {0x1440, 0x0, 0xE, 0}, + {0x1487, 0x58, 0xFF, 0}, + {0x148B, 0x3, 0x7F, 0}, + {0x148C, 0x3, 0x7F, 0}, + {0x1507, 0x58, 0xFF, 0}, + {0x150B, 0x3, 0x7F, 0}, + {0x150C, 0x3, 0x7F, 0}, + {0x1587, 0x58, 0xFF, 0}, + {0x158B, 0x3, 0x7F, 0}, + {0x158C, 0x3, 0x7F, 0}, + {0x1607, 0x58, 0xFF, 0}, + {0x160B, 0x3, 0x7F, 0}, + {0x160C, 0x3, 0x7F, 0}, + {0x1687, 0x22, 0x76, 0}, + {0x1688, 0xF, 0x2F, 0}, + {0x1689, 0xA1, 0xE1, 0}, + {0x168A, 0x79, 0x7F, 0}, + {0x168B, 0x12, 0x3F, 0}, + {0x168D, 0xC, 0xC, 0}, + {0x168E, 0xD7, 0xFF, 0}, + {0x168F, 0x81, 0xFF, 0}, + {0x1690, 0x3, 0x3F, 0}, + {0x1691, 0x22, 0x76, 0}, + {0x1692, 0xF, 0x2F, 0}, + {0x1693, 0xA1, 0xE1, 0}, + {0x1694, 0x79, 0x7F, 0}, + {0x1695, 0x12, 0x3F, 0}, + {0x1697, 0xC, 0xC, 0}, + {0x1698, 0xD7, 0xFF, 0}, + {0x1699, 0x81, 0xFF, 0}, + {0x169A, 0x3, 0x3F, 0}, + {0x169B, 0x22, 0x76, 0}, + {0x169C, 0xF, 0x2F, 0}, + {0x169D, 0xA1, 0xE1, 0}, + {0x169E, 0x79, 0xFF, 0}, + {0x169F, 0x12, 0x3F, 0}, + {0x16A1, 0xC, 0xC, 0}, + {0x16A2, 0xD7, 0xFF, 0}, + {0x16A3, 0x81, 0xFF, 0}, + {0x16A4, 0x3, 0x3F, 0}, + {0x16A5, 0x22, 0x76, 0}, + {0x16A6, 0xF, 0x2F, 0}, + {0x16A7, 0xA1, 0xE1, 0}, + {0x16A8, 0x79, 0xFF, 0}, + {0x16A9, 0x12, 0x3F, 0}, + {0x16AB, 0xC, 0xC, 0}, + {0x16AC, 0xD7, 0xFF, 0}, + {0x16AD, 0x81, 0xFF, 0}, + {0x16AE, 0x3, 0x3F, 0}, + {0x16CE, 0x0, 0x8, 0}, + {0x13, 0x2, 0x2, 0}, + {0x15, 0x1F, 0x1F, 0}, + {0x22, 0x12, 0x12, 0}, + {0x8A, 0x6, 0xF, 0}, + {0x10B, 0x3, 0x3, 0}, + {0x38B, 0x4, 0xFF, 0}, + {0xA07, 0x0, 0x1, 0}, + {0xA1A, 0x1F, 0x1F, 0}, + {0x1457, 0x0, 0xFF, 0}, + /* add protection */ + {0x3A1, 0x0, 0xFF, 0}, + {0x3A2, 0x0, 0xFF, 0}, + {0x1417, 0x0, 0xFF, 0}, + {0x1418, 0x0, 0xFF, 0}, + {0x992, 0x0, 0xFF, 0}, + {0x993, 0x0, 0xFF, 0}, + {0x39F, 0x0, 0xFF, 0}, + {0x3A0, 0x0, 0xFF, 0}, + {0x3A8, 0x0, 0xFF, 0}, + {0x3A9, 0x0, 0xFF, 0}, +}; + +void mt6315_init_setting(void) +{ + for (int i = 0; i < ARRAY_SIZE(init_setting_cpu); i++) + mt6315_write_field(MT6315_CPU, + init_setting_cpu[i].addr, init_setting_cpu[i].val, + init_setting_cpu[i].mask, init_setting_cpu[i].shift); +} diff --git a/src/soc/mediatek/mt8186/pll.c b/src/soc/mediatek/mt8186/pll.c index 9d8343b7ef..9ab4f9cbc2 100644 --- a/src/soc/mediatek/mt8186/pll.c +++ b/src/soc/mediatek/mt8186/pll.c @@ -525,6 +525,12 @@ void mt_pll_set_usb_clock(void) SET32_BITFIELDS(&mtk_topckgen->usb_top_cfg, USB_TOP_CFG_MACRO_CTRL, 3); } +void mt_pll_spmi_mux_select(void) +{ + /* 4: ulposc1_d10 */ + mux_set_sel(&muxes[TOP_SPMI_MST_SEL], 4); +} + u32 mt_fmeter_get_freq_khz(enum fmeter_type type, u32 id) { u32 output, count, clk_dbg_cfg, clk_misc_cfg_0, clk26cali_0, clk26cali_1; diff --git a/src/soc/mediatek/mt8186/pmif.c b/src/soc/mediatek/mt8186/pmif.c index b9096092d4..c1a9bccc5e 100644 --- a/src/soc/mediatek/mt8186/pmif.c +++ b/src/soc/mediatek/mt8186/pmif.c @@ -15,7 +15,7 @@ DEFINE_BITFIELD(SCP_SLEEP_REQ_SEL, 10, 9) void pmif_spmi_set_lp_mode(void) { - SET32_BITFIELDS((void *)(PMIF_BASE + SLEEP_PROT_CTRL), + SET32_BITFIELDS((void *)(PMIF_SPMI_BASE + SLEEP_PROT_CTRL), SPM_SLEEP_REQ_SEL, 0, SCP_SLEEP_REQ_SEL, 0); } diff --git a/src/soc/mediatek/mt8186/pmif_clk.c b/src/soc/mediatek/mt8186/pmif_clk.c new file mode 100644 index 0000000000..4cdc7106ae --- /dev/null +++ b/src/soc/mediatek/mt8186/pmif_clk.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define FREQ_METER_ABIST_AD_OSC_CK 35 + +#define SCP_CLK_SRC BIT(1) +#define SCP_CLK_CG BIT(2) + +#define ULPOSC1_RG_OSC_DIV BIT(18) + +#define ULPOSC1_CALI_HW_MODE (BIT(16) | BIT(17)) +#define ULPOSC1_ENABLE_SW_MODE (BIT(18) | BIT(19)) + +u32 pmif_get_ulposc_freq_mhz(u32 cali_val) +{ + u32 result; + + clrsetbits32(&mtk_apmixed->ap_pll_con0, ULPOSC1_CALI_HW_MODE, ULPOSC1_ENABLE_SW_MODE); + clrbits32(&mtk_apmixed->ulposc_con0, cali_val); + + /* enable ulposc1 */ + setbits32(&mtk_scp_clk->scp_clk_en, SCP_CLK_SRC); + udelay(150); + setbits32(&mtk_scp_clk->scp_clk_en, SCP_CLK_CG); + + result = mt_fmeter_get_freq_khz(FMETER_ABIST, FREQ_METER_ABIST_AD_OSC_CK); + + return result / 1000; +} + +int pmif_clk_init(void) +{ + u32 ulposc; + + /* get hardware default value */ + ulposc = pmif_get_ulposc_freq_mhz(ULPOSC1_RG_OSC_DIV); + if (pmif_ulposc_check(ulposc, FREQ_250MHZ)) + die("ERROR: failed to meet ulposc frequency\n"); + + mt_pll_spmi_mux_select(); + + return 0; +} diff --git a/src/soc/mediatek/mt8186/pmif_spmi.c b/src/soc/mediatek/mt8186/pmif_spmi.c new file mode 100644 index 0000000000..28ea739abd --- /dev/null +++ b/src/soc/mediatek/mt8186/pmif_spmi.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include + +/* IOCFG_LT, DRV_CFG2 */ +DEFINE_BITFIELD(SPMI_SCL, 14, 12) +DEFINE_BITFIELD(SPMI_SDA, 17, 15) +DEFINE_BIT(SPMI_SCL_IN, 27) +DEFINE_BIT(SPMI_SDA_IN, 28) +DEFINE_BIT(SPMI_SCL_PU, 11) +DEFINE_BIT(SPMI_SDA_PD, 12) +DEFINE_BIT(SPMI_SCL_SMT, 28) +DEFINE_BIT(SPMI_SDA_SMT, 28) +DEFINE_BITFIELD(SPMI_TD, 19, 16) +DEFINE_BITFIELD(SPMI_RD, 15, 14) +DEFINE_BITFIELD(SPMI_DRI, 5, 3) + +/* TOPRGU, WDT_SWSYSRST2 */ +DEFINE_BIT(SPMI_MST_RST, 23) +DEFINE_BITFIELD(UNLOCK_KEY, 31, 24) + +/* TOPCKGEN, CLK_CFG_17 */ +DEFINE_BITFIELD(CLK_SPMI_MST_SEL, 10, 8) +DEFINE_BIT(CLK_SPMI_MST_INT, 12) +DEFINE_BIT(PDN_SPMI_MST, 15) + +/* TOPCKGEN, CLK_CFG_UPDATE2 */ +DEFINE_BIT(SPMI_MST_CK_UPDATE, 5) + +const struct spmi_device spmi_dev[] = { + { + .slvid = SPMI_SLAVE_6, + .type = BUCK_CPU, + .type_id = BUCK_CPU_ID, + }, +}; + +const size_t spmi_dev_cnt = ARRAY_SIZE(spmi_dev); + +int spmi_config_master(void) +{ + /* Software reset */ + SET32_BITFIELDS(&mtk_rug->wdt_swsysrst2, SPMI_MST_RST, 1, UNLOCK_KEY, 0x88); + + SET32_BITFIELDS(&mtk_topckgen->clk_cfg_11, + CLK_SPMI_MST_SEL, 0x3, + CLK_SPMI_MST_INT, 0, + PDN_SPMI_MST, 0); + SET32_BITFIELDS(&mtk_topckgen->clk_cfg_update2, SPMI_MST_CK_UPDATE, 1); + + /* Software reset */ + SET32_BITFIELDS(&mtk_rug->wdt_swsysrst2, SPMI_MST_RST, 0, UNLOCK_KEY, 0x88); + + /* Enable SPMI */ + write32(&mtk_spmi_mst->mst_req_en, 1); + write32(&mtk_spmi_mst->rcs_ctrl, 0x15); + + return 0; +}