soc/mediatek/mt8189: Add MTCMOS init support

Add MTCMOS init code and APIs for controlling power domain.

BUG=b:379008996
BRANCH=none
TEST=build pass and driver init ok.

Change-Id: I39ab203da4d17b72fc5ccdbce664100d671f5e29
Signed-off-by: Irving-CH.lin <irving-ch.lin@mediatek.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87634
Reviewed-by: Yidi Lin <yidilin@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
Irving-CH.lin 2024-11-07 14:23:31 +08:00 committed by Yidi Lin
commit e4cbd9ea9f
8 changed files with 1244 additions and 5 deletions

View file

@ -1,15 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __SOC_MEDIATEK_COMMON_MTCMOS_H__
#define __SOC_MEDIATEK_COMMON_MTCMOS_H__
#ifndef __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTCMOS_H__
#define __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTCMOS_H__
struct bus_protect {
void *clr_addr;
u32 mask;
};
struct power_domain_data {
void *pwr_con;
void *pwr_status;
void *pwr_status_2nd;
u32 pwr_sta_mask;
u32 sram_pdn_mask;
u32 sram_ack_mask;
u32 ext_buck_iso_bits;
u32 caps;
size_t bp_steps;
/* Bus protection */
const struct bus_protect *bp_table;
};
#define SCPD_SRAM_ISO BIT(0)
@ -26,4 +36,4 @@ void mtcmos_protect_adsp_bus(void);
void mtcmos_protect_audio_bus(void);
void mtcmos_protect_display_bus(void);
#endif /* __SOC_MEDIATEK_COMMON_MTCMOS_H__ */
#endif /* __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTCMOS_H__ */

View file

@ -19,8 +19,19 @@ __weak void mtcmos_set_scpd_ext_buck_iso(const struct power_domain_data *pd)
/* do nothing */
}
static void release_bus_protection(const struct power_domain_data *pd)
{
int i;
for (i = 0; i < pd->bp_steps; i++)
write32(pd->bp_table[i].clr_addr, pd->bp_table[i].mask);
}
void mtcmos_power_on(const struct power_domain_data *pd)
{
u32 *pwr_status;
u32 *pwr_status_2nd;
write32(&mtk_spm->poweron_config_set,
(SPM_PROJECT_CODE << 16) | (1U << 0));
@ -30,8 +41,16 @@ void mtcmos_power_on(const struct power_domain_data *pd)
setbits32(pd->pwr_con, PWR_ON);
setbits32(pd->pwr_con, PWR_ON_2ND);
while (!(read32(&mtk_spm->pwr_status) & pd->pwr_sta_mask) ||
!(read32(&mtk_spm->pwr_status_2nd) & pd->pwr_sta_mask))
if ((pd->pwr_status != NULL) && (pd->pwr_status_2nd != NULL)) {
pwr_status = pd->pwr_status;
pwr_status_2nd = pd->pwr_status_2nd;
} else {
pwr_status = &mtk_spm->pwr_status;
pwr_status_2nd = &mtk_spm->pwr_status_2nd;
}
while (!(read32(pwr_status) & pd->pwr_sta_mask) ||
!(read32(pwr_status_2nd) & pd->pwr_sta_mask))
continue;
clrbits32(pd->pwr_con, PWR_CLK_DIS);
@ -47,6 +66,8 @@ void mtcmos_power_on(const struct power_domain_data *pd)
udelay(1);
clrbits32(pd->pwr_con, SRAM_CKISO);
}
release_bus_protection(pd);
}
void mtcmos_display_power_on(void)

View file

@ -11,6 +11,7 @@ all-y += ../common/uart.c
bootblock-y += bootblock.c
bootblock-y += ../common/mmu_operations.c
bootblock-y += ../common/mtcmos.c mtcmos.c
bootblock-y += ../common/wdt.c ../common/wdt_req.c wdt.c
romstage-y += ../common/cbmem.c
@ -25,6 +26,7 @@ ramstage-y += ../common/dramc_info.c
ramstage-y += ../common/emi.c
ramstage-y += ../common/memory.c
ramstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c
ramstage-y += ../common/mtcmos.c mtcmos.c
ramstage-y += soc.c
ramstage-y += ../common/usb.c usb.c

View file

@ -2,10 +2,12 @@
#include <bootblock_common.h>
#include <soc/mmu_operations.h>
#include <soc/spm_mtcmos.h>
#include <soc/wdt.h>
void bootblock_soc_init(void)
{
mtk_mmu_init();
mtk_wdt_init();
mtcmos_init();
}

View file

@ -27,6 +27,7 @@ enum {
EMI0_BASE = IO_PHYS + 0x00219000,
EMI0_MPU_BASE = IO_PHYS + 0x00226000,
DRAMC_CHA_AO_BASE = IO_PHYS + 0x00230000,
EMICFG_AO_MEM_BASE = IO_PHYS + 0x00270000,
THERM_CTRL_BASE = IO_PHYS + 0x00315000,
DPM_PM_SRAM_BASE = IO_PHYS + 0x00900000,
DPM_DM_SRAM_BASE = IO_PHYS + 0x00920000,
@ -72,7 +73,9 @@ enum {
IOCFG_RT_BASE = IO_PHYS + 0x01F20000,
DSI0_BASE = IO_PHYS + 0x04016000,
DISP_DVO0 = IO_PHYS + 0x04019000,
SPM_BASE = IO_PHYS + 0x0C001000,
RGU_BASE = IO_PHYS + 0x0C00A000,
VLPCFG_REG_BASE = IO_PHYS + 0x0C00C000,
SPMI_MST_BASE = IO_PHYS + 0x0C013000,
DEVAPC_VLP_AO_BASE = IO_PHYS + 0x0C018000,
SPMI_MST_P_BASE = IO_PHYS + 0x0CC00000,

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_MTCMOS_H__
#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_MTCMOS_H__
#include <device/mmio.h>
#include <soc/addressmap.h>
#include <types.h>
struct mtk_reg_cfg {
u32 status;
u32 set;
u32 clr;
u32 ready;
};
struct mtk_vlpcfg_regs {
u32 reserved1;
u32 vlp_test_ck_ctrl;
u32 reserved2[130];
u32 bus_vlp_topaxi_protecten;
u32 bus_vlp_topaxi_protecten_set;
u32 bus_vlp_topaxi_protecten_clr;
u32 bus_vlp_topaxi_protecten_sta1;
};
check_member(mtk_vlpcfg_regs, vlp_test_ck_ctrl, 0x0004);
check_member(mtk_vlpcfg_regs, bus_vlp_topaxi_protecten, 0x0210);
struct mtk_infracfg_ao_regs {
u32 reserved1[28];
u32 infra_bus_dcm_ctrl;
u32 reserved2[3];
u32 infracfg_ao_module_cg_0_set;
u32 infracfg_ao_module_cg_0_clr;
u32 infracfg_ao_module_cg_1_set;
u32 infracfg_ao_module_cg_1_clr;
u32 infracfg_ao_module_cg_0;
u32 infracfg_ao_module_cg_1;
u32 reserved3[3];
u32 infracfg_ao_module_cg_2_set;
u32 infracfg_ao_module_cg_2_clr;
u32 infracfg_ao_module_cg_2;
u32 reserved4[4];
u32 infracfg_ao_module_cg_3_set;
u32 infracfg_ao_module_cg_3_clr;
u32 infracfg_ao_module_cg_3;
u32 reserved5[721];
struct mtk_reg_cfg mmsys_protect[2];
u32 reserved6[4];
struct mtk_reg_cfg infrasys_protect[2];
struct mtk_reg_cfg emisys_protect;
u32 reserved7[4];
struct mtk_reg_cfg perisys_protect;
struct mtk_reg_cfg mcu_connsys_protect;
struct mtk_reg_cfg md_mfgsys_protect;
};
check_member(mtk_infracfg_ao_regs, infra_bus_dcm_ctrl, 0x0070);
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_0_set, 0x0080);
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_1, 0x0094);
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_2_set, 0x00A4);
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_3_set, 0x00C0);
check_member(mtk_infracfg_ao_regs, mmsys_protect[0].status, 0x0C10);
check_member(mtk_infracfg_ao_regs, mmsys_protect[0].set, 0x0C14);
check_member(mtk_infracfg_ao_regs, mmsys_protect[0].clr, 0x0C18);
check_member(mtk_infracfg_ao_regs, mmsys_protect[0].ready, 0x0C1C);
check_member(mtk_infracfg_ao_regs, infrasys_protect[0].status, 0x0C40);
check_member(mtk_infracfg_ao_regs, infrasys_protect[0].set, 0x0C44);
check_member(mtk_infracfg_ao_regs, infrasys_protect[0].clr, 0x0C48);
check_member(mtk_infracfg_ao_regs, infrasys_protect[0].ready, 0x0C4C);
check_member(mtk_infracfg_ao_regs, perisys_protect.status, 0x0C80);
check_member(mtk_infracfg_ao_regs, perisys_protect.set, 0x0C84);
check_member(mtk_infracfg_ao_regs, perisys_protect.clr, 0x0C88);
check_member(mtk_infracfg_ao_regs, perisys_protect.ready, 0x0C8C);
struct mtk_emicfg_ao_mem_regs {
u32 reserved[32];
struct mtk_reg_cfg gals_slp_prot;
};
check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.status, 0x0080);
check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.set, 0x0084);
check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.clr, 0x0088);
check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.ready, 0x008C);
static struct mtk_vlpcfg_regs *const mtk_vlpcfg = (void *)VLPCFG_REG_BASE;
static struct mtk_infracfg_ao_regs *const mtk_infracfg_ao = (void *)INFRACFG_AO_BASE;
static struct mtk_emicfg_ao_mem_regs *const mtk_emicfg_ao_mem = (void *)EMICFG_AO_MEM_BASE;
void spm_power_on(void);
void mtcmos_init(void);
#endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_MTCMOS_H__ */

View file

@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
/*
* This file is created based on MT8189 Functional Specification
* Chapter number: 8.1
*/
#include <console/console.h>
#include <soc/mtcmos.h>
#include <soc/spm.h>
#include <soc/spm_mtcmos.h>
static const struct bus_protect bp_ufs[] = {
{&mtk_vlpcfg->bus_vlp_topaxi_protecten_clr, BIT(6)},
{&mtk_infracfg_ao->perisys_protect.clr, BIT(4)},
{&mtk_vlpcfg->bus_vlp_topaxi_protecten_clr, BIT(5)},
};
static const struct bus_protect bp_mminfra[] = {
{&mtk_infracfg_ao->emisys_protect.clr, BIT(20) | BIT(21)},
{&mtk_infracfg_ao->infrasys_protect[0].clr, BIT(16)},
{&mtk_infracfg_ao->mmsys_protect[1].clr,
BIT(0) | BIT(7) | BIT(8) | BIT(9) | BIT(10) |
BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15)},
{&mtk_infracfg_ao->infrasys_protect[1].clr, BIT(11)},
{&mtk_infracfg_ao->mmsys_protect[1].clr,
BIT(1) | BIT(2) | BIT(3)},
};
static const struct bus_protect bp_ssusb[] = {
{&mtk_infracfg_ao->perisys_protect.clr, BIT(7)},
};
static const struct power_domain_data pd_plat[] = {
{
/* ufs0 */
.pwr_con = &mtk_spm->ufs0_pwr_con,
.pwr_sta_mask = BIT(4),
.sram_pdn_mask = BIT(8),
.sram_ack_mask = BIT(12),
.bp_steps = ARRAY_SIZE(bp_ufs),
.bp_table = bp_ufs,
},
{
/* ufs0_phy */
.pwr_con = &mtk_spm->ufs0_phy_pwr_con,
.pwr_sta_mask = BIT(5),
},
{
/* mm_infra */
.pwr_con = &mtk_spm->mm_infra_pwr_con,
.pwr_sta_mask = BIT(30),
.sram_pdn_mask = BIT(8),
.sram_ack_mask = BIT(12),
.bp_steps = ARRAY_SIZE(bp_mminfra),
.bp_table = bp_mminfra,
},
{
/* ssusb */
.pwr_con = &mtk_spm->ssusb_pwr_con,
.pwr_status = &mtk_spm->pwr_status_msb,
.pwr_status_2nd = &mtk_spm->pwr_status_msb_2nd,
.pwr_sta_mask = BIT(10),
.sram_pdn_mask = BIT(8),
.sram_ack_mask = BIT(12),
.bp_steps = ARRAY_SIZE(bp_ssusb),
.bp_table = bp_ssusb,
},
};
void spm_power_on(void)
{
write32(&mtk_spm->poweron_config_set, SPM_REGWR_CFG_KEY | (0x1 << 0));
}
void mtcmos_init(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(pd_plat); i++)
mtcmos_power_on(&pd_plat[i]);
}