mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 07:15:20 +00:00
feat(mt8196): add mtcmos driver
add mtcmos driver for ufs power control Signed-off-by: Guangjie Song <guangjie.song@mediatek.com> Change-Id: I3f63d5976906aaca91a71a147497e9345339774d
This commit is contained in:
parent
e578702f71
commit
1f913a6e3a
6 changed files with 220 additions and 0 deletions
plat/mediatek
|
@ -24,3 +24,4 @@ $(eval $(call add_defined_option,CONFIG_MTK_CPU_SUSPEND_EN))
|
|||
$(eval $(call add_defined_option,CONFIG_MTK_PM_ARCH))
|
||||
$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_ARCH))
|
||||
$(eval $(call add_defined_option,CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND))
|
||||
$(eval $(call add_defined_option,CONFIG_MTK_MTCMOS))
|
||||
|
|
185
plat/mediatek/drivers/mtcmos/mt8196/mtcmos.c
Normal file
185
plat/mediatek/drivers/mtcmos/mt8196/mtcmos.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/spinlock.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <mtcmos.h>
|
||||
|
||||
#define SPM_PROJECT_CODE 0xB16
|
||||
|
||||
#define PWR_RST_B BIT(0)
|
||||
#define PWR_ISO BIT(1)
|
||||
#define PWR_ON BIT(2)
|
||||
#define PWR_ON_2ND BIT(3)
|
||||
#define PWR_CLK_DIS BIT(4)
|
||||
#define RTFF_SAVE BIT(24)
|
||||
#define RTFF_NRESTORE BIT(25)
|
||||
#define RTFF_CLK_DIS BIT(26)
|
||||
#define RTFF_SAVE_FLAG BIT(27)
|
||||
#define PWR_ACK BIT(30)
|
||||
#define PWR_ACK_2ND BIT(31)
|
||||
|
||||
#define UFS0_SRAM_PDN BIT(8)
|
||||
#define UFS0_SRAM_PDN_ACK BIT(12)
|
||||
|
||||
#define POWERON_CONFIG_EN (SPM_BASE + 0x0)
|
||||
#define UFS0_PWR_CON (SPM_BASE + 0xE2C)
|
||||
#define UFS0_PHY_PWR_CON (SPM_BASE + 0xE30)
|
||||
|
||||
#define SPM_BUS_PROTECT_EN_SET (SPM_BASE + 0x90DC)
|
||||
#define SPM_BUS_PROTECT_EN_CLR (SPM_BASE + 0x90E0)
|
||||
#define SPM_BUS_PROTECT_CG_EN_SET (SPM_BASE + 0x90F4)
|
||||
#define SPM_BUS_PROTECT_CG_EN_CLR (SPM_BASE + 0x90F8)
|
||||
#define SPM_BUS_PROTECT_RDY_STA (SPM_BASE + 0x9208)
|
||||
|
||||
#define UFS0_PROT_STEP1_MASK BIT(11)
|
||||
#define UFS0_PHY_PROT_STEP1_MASK BIT(12)
|
||||
|
||||
enum {
|
||||
RELEASE_BUS_PROTECT,
|
||||
SET_BUS_PROTECT
|
||||
};
|
||||
|
||||
#define MTCMOS_TIMEOUT_US 500
|
||||
|
||||
#define ETIMEDOUT 25
|
||||
|
||||
static spinlock_t mtcmos_ctrl_lock;
|
||||
|
||||
static int mtcmos_wait_for_state(uint32_t reg, uint32_t mask, bool is_set)
|
||||
{
|
||||
uint32_t retry = MTCMOS_TIMEOUT_US;
|
||||
uint32_t expect = is_set ? mask : 0;
|
||||
|
||||
do {
|
||||
if ((mmio_read_32(reg) & mask) == expect)
|
||||
return 0;
|
||||
udelay(1);
|
||||
retry--;
|
||||
} while (retry);
|
||||
|
||||
ERROR("%s(0x%x, 0x%x, %d) timeout, reg_val=0x%x\n",
|
||||
__func__, reg, mask, is_set, mmio_read_32(reg));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
||||
static int spm_mtcmos_ctrl_bus_prot(int state, uint32_t mask)
|
||||
{
|
||||
mmio_write_32(SPM_BUS_PROTECT_CG_EN_SET, mask);
|
||||
|
||||
if (state == SET_BUS_PROTECT) {
|
||||
mmio_write_32(SPM_BUS_PROTECT_EN_SET, mask);
|
||||
if (mtcmos_wait_for_state(SPM_BUS_PROTECT_RDY_STA, mask,
|
||||
true))
|
||||
return -ETIMEDOUT;
|
||||
} else if (state == RELEASE_BUS_PROTECT) {
|
||||
mmio_write_32(SPM_BUS_PROTECT_EN_CLR, mask);
|
||||
}
|
||||
|
||||
mmio_write_32(SPM_BUS_PROTECT_CG_EN_CLR, mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spm_mtcmos_ctrl(enum mtcmos_state state, uintptr_t reg, uint32_t mask)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&mtcmos_ctrl_lock);
|
||||
|
||||
mmio_write_32(POWERON_CONFIG_EN, (SPM_PROJECT_CODE << 16) | BIT(0));
|
||||
|
||||
if (state == STA_POWER_DOWN) {
|
||||
ret = spm_mtcmos_ctrl_bus_prot(SET_BUS_PROTECT, mask);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
if (reg == UFS0_PWR_CON) {
|
||||
mmio_setbits_32(reg, UFS0_SRAM_PDN);
|
||||
ret = mtcmos_wait_for_state(reg, UFS0_SRAM_PDN_ACK,
|
||||
true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mmio_setbits_32(reg, RTFF_CLK_DIS);
|
||||
mmio_setbits_32(reg, RTFF_SAVE);
|
||||
mmio_clrbits_32(reg, RTFF_SAVE);
|
||||
mmio_clrbits_32(reg, RTFF_CLK_DIS);
|
||||
mmio_setbits_32(reg, RTFF_SAVE_FLAG);
|
||||
|
||||
mmio_setbits_32(reg, PWR_ISO);
|
||||
mmio_setbits_32(reg, PWR_CLK_DIS);
|
||||
mmio_clrbits_32(reg, PWR_RST_B);
|
||||
|
||||
mmio_clrbits_32(reg, PWR_ON);
|
||||
ret = mtcmos_wait_for_state(reg, PWR_ACK, false);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
mmio_clrbits_32(reg, PWR_ON_2ND);
|
||||
ret = mtcmos_wait_for_state(reg, PWR_ACK_2ND, false);
|
||||
if (ret)
|
||||
goto exit;
|
||||
} else if (state == STA_POWER_ON) {
|
||||
mmio_setbits_32(reg, PWR_ON);
|
||||
ret = mtcmos_wait_for_state(reg, PWR_ACK, true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
udelay(50);
|
||||
|
||||
mmio_setbits_32(reg, PWR_ON_2ND);
|
||||
ret = mtcmos_wait_for_state(reg, PWR_ACK_2ND, true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
mmio_clrbits_32(reg, PWR_CLK_DIS);
|
||||
mmio_clrbits_32(reg, PWR_ISO);
|
||||
udelay(10);
|
||||
mmio_setbits_32(reg, PWR_RST_B);
|
||||
|
||||
if ((mmio_read_32(reg) & RTFF_SAVE_FLAG) == RTFF_SAVE_FLAG) {
|
||||
mmio_setbits_32(reg, RTFF_CLK_DIS);
|
||||
mmio_clrbits_32(reg, RTFF_NRESTORE);
|
||||
mmio_setbits_32(reg, RTFF_NRESTORE);
|
||||
mmio_clrbits_32(reg, RTFF_CLK_DIS);
|
||||
}
|
||||
|
||||
if (reg == UFS0_PWR_CON) {
|
||||
mmio_clrbits_32(UFS0_PWR_CON, UFS0_SRAM_PDN);
|
||||
ret = mtcmos_wait_for_state(UFS0_PWR_CON,
|
||||
UFS0_SRAM_PDN_ACK,
|
||||
false);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
spm_mtcmos_ctrl_bus_prot(RELEASE_BUS_PROTECT, mask);
|
||||
}
|
||||
|
||||
exit:
|
||||
spin_unlock(&mtcmos_ctrl_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spm_mtcmos_ctrl_ufs0(enum mtcmos_state state)
|
||||
{
|
||||
return spm_mtcmos_ctrl(state, UFS0_PWR_CON, UFS0_PROT_STEP1_MASK);
|
||||
}
|
||||
|
||||
int spm_mtcmos_ctrl_ufs0_phy(enum mtcmos_state state)
|
||||
{
|
||||
return spm_mtcmos_ctrl(state, UFS0_PHY_PWR_CON,
|
||||
UFS0_PHY_PROT_STEP1_MASK);
|
||||
}
|
18
plat/mediatek/drivers/mtcmos/mt8196/mtcmos.h
Normal file
18
plat/mediatek/drivers/mtcmos/mt8196/mtcmos.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLAT_MEDIATEK_DRIVERS_MTCMOS_MT8196_MTCMOS_H_
|
||||
#define PLAT_MEDIATEK_DRIVERS_MTCMOS_MT8196_MTCMOS_H_
|
||||
|
||||
enum mtcmos_state {
|
||||
STA_POWER_DOWN,
|
||||
STA_POWER_ON,
|
||||
};
|
||||
|
||||
int spm_mtcmos_ctrl_ufs0(enum mtcmos_state state);
|
||||
int spm_mtcmos_ctrl_ufs0_phy(enum mtcmos_state state);
|
||||
|
||||
#endif /* PLAT_MEDIATEK_DRIVERS_MTCMOS_MT8196_MTCMOS_H_ */
|
13
plat/mediatek/drivers/mtcmos/rules.mk
Normal file
13
plat/mediatek/drivers/mtcmos/rules.mk
Normal file
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||
|
||||
MODULE := mtcmos
|
||||
LOCAL_SRCS-y := $(LOCAL_DIR)/${MTK_SOC}/mtcmos.c
|
||||
|
||||
PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
|
||||
|
||||
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
|
@ -42,6 +42,7 @@ CONFIG_MTK_CPU_PM_SUPPORT := y
|
|||
CONFIG_MTK_CPU_PM_ARCH := 5_4
|
||||
CONFIG_MTK_SMP_EN := n
|
||||
CONFIG_MTK_CPU_SUSPEND_EN := y
|
||||
CONFIG_MTK_MTCMOS := y
|
||||
CONFIG_MTK_SPM_VERSION := mt8196
|
||||
CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
|
||||
CONFIG_MTK_TINYSYS_VCP := y
|
||||
|
|
|
@ -35,6 +35,8 @@ MODULES-y += $(MTK_PLAT)/drivers/vcp
|
|||
MODULES-y += $(MTK_PLAT)/helpers
|
||||
MODULES-y += $(MTK_PLAT)/topology
|
||||
|
||||
MODULES-$(CONFIG_MTK_MTCMOS) += $(MTK_PLAT)/drivers/mtcmos
|
||||
|
||||
ifneq ($(MTKLIB_PATH),)
|
||||
LDFLAGS += -L $(dir $(MTKLIB_PATH))
|
||||
LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(MTKLIB_PATH)))
|
||||
|
|
Loading…
Add table
Reference in a new issue